diff --git a/.gitignore b/.gitignore
index ab71a3e4..e2883f72 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,9 @@
 bin/
 testbin/
 
+catalog
+catalog.Dockerfile
+
 # Created by https://www.toptal.com/developers/gitignore/api/go,vim,visualstudiocode,git
 # Edit at https://www.toptal.com/developers/gitignore?templates=go,vim,visualstudiocode,git
 
@@ -74,6 +77,9 @@ tags
 # Local History for Visual Studio Code
 .history/
 
+### IntelliJ ###
+.idea
+
 # Built Visual Studio Code Extensions
 *.vsix
 
diff --git a/.golangci.yaml b/.golangci.yaml
index 4a0a9924..506d3dbf 100644
--- a/.golangci.yaml
+++ b/.golangci.yaml
@@ -7,12 +7,9 @@ run:
 linters:
   disable-all: true
   enable:
-    - deadcode
     - errcheck
     - gosimple
     - ineffassign
     - staticcheck
-    - structcheck
     - unused
-    - varcheck
     - revive
diff --git a/Dockerfile b/Dockerfile
index 024d341b..faa7bcdd 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -17,8 +17,6 @@ COPY controllers/ controllers/
 COPY config/ config/
 COPY pkg/ pkg/
 COPY service/ service/
-# Run tests and linting
-RUN make go-test
 
 # Build
 RUN make go-build
diff --git a/Makefile b/Makefile
index c5233a16..55ba6813 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,6 @@ include hack/make-project-vars.mk
 include hack/make-tools.mk
 include hack/make-bundle-vars.mk
 
-
 # Setting SHELL to bash allows bash commands to be executed by recipes.
 # This is a requirement for 'setup-envtest.sh' in the test target.
 # Options are set to exit when a recipe line exits non-zero or a piped command fails.
@@ -55,15 +54,15 @@ vet: ## Run go vet against code.
 	go vet ./...
 
 lint: ## Run golangci-lint against code.
-	docker run --rm -v $(PROJECT_DIR):/app:Z -w /app $(GO_LINT_IMG) golangci-lint run ./...
+	$(IMAGE_BUILD_CMD) run --rm -v $(PROJECT_DIR):/app -w /app $(GO_LINT_IMG) golangci-lint run ./...
 
 godeps-update:  ## Run go mod tidy & vendor
 	go mod tidy && go mod vendor
 
-test-setup: godeps-update generate fmt vet ## Run setup targets for tests
+test-setup: godeps-update generate fmt vet envtest ## Run setup targets for tests
 
 go-test: ## Run go test against code.
-	./hack/go-test.sh
+	KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(BIN_DIR) -p path)" go test -coverprofile cover.out `go list ./... | grep -v "e2e"`
 
 test: test-setup go-test ## Run go unit tests.
 
@@ -82,11 +81,11 @@ go-build: ## Run go build against code.
 run: manifests generate fmt vet ## Run a controller from your host.
 	go run ./main.go
 
-container-build: test-setup ## Build container image with the manager.
-	docker build -t ${IMG} .
+container-build: test ## Build container image with the manager.
+	$(IMAGE_BUILD_CMD) build --platform="linux/amd64" -t ${IMG} .
 
 container-push: ## Push container image with the manager.
-	docker push ${IMG}
+	$(IMAGE_BUILD_CMD) push ${IMG}
 
 ##@ Deployment
 
@@ -117,7 +116,8 @@ bundle: manifests kustomize operator-sdk yq ## Generate bundle manifests and met
 	rm -rf ./bundle
 	$(OPERATOR_SDK) generate kustomize manifests -q
 	cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG)
-	cd config/console && $(KUSTOMIZE) edit set image ocs-client-operator-console=$(OCS_CLIENT_CONSOLE_IMG)
+	cd config/console && $(KUSTOMIZE) edit set image ocs-client-operator-console=$(OCS_CLIENT_CONSOLE_IMG) && \
+		$(KUSTOMIZE) edit set nameprefix $(OPERATOR_NAMEPREFIX)
 	cd config/default && \
 		$(KUSTOMIZE) edit set image kube-rbac-proxy=$(RBAC_PROXY_IMG) && \
 		$(KUSTOMIZE) edit set namespace $(OPERATOR_NAMESPACE) && \
@@ -128,27 +128,27 @@ bundle: manifests kustomize operator-sdk yq ## Generate bundle manifests and met
 		--patch '[{"op": "replace", "path": "/spec/replaces", "value": "$(REPLACES)"}]'
 	$(KUSTOMIZE) build $(MANIFEST_PATH) | sed "s|STATUS_REPORTER_IMAGE_VALUE|$(IMG)|g" | awk '{print}'| \
 		$(OPERATOR_SDK) generate bundle -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS) --extra-service-accounts="$$($(KUSTOMIZE) build $(MANIFEST_PATH) | $(YQ) 'select(.kind == "ServiceAccount") | .metadata.name' -N | paste -sd "," -)"
-	sed -i "s|packageName:.*|packageName: ${CSI_ADDONS_PACKAGE_NAME}|g" "config/metadata/dependencies.yaml"
-	sed -i "s|version:.*|version: "${CSI_ADDONS_PACKAGE_VERSION}"|g" "config/metadata/dependencies.yaml"
+	yq -i '.dependencies[0].value.packageName = "'${CSI_ADDONS_PACKAGE_NAME}'"' config/metadata/dependencies.yaml
+	yq -i '.dependencies[0].value.version = "'${CSI_ADDONS_PACKAGE_VERSION}'"' config/metadata/dependencies.yaml
 	cp config/metadata/* bundle/metadata/
 	$(OPERATOR_SDK) bundle validate ./bundle
 
 .PHONY: bundle-build
 bundle-build: bundle ## Build the bundle image.
-	docker build -f bundle.Dockerfile -t $(BUNDLE_IMG) .
+	$(IMAGE_BUILD_CMD) build --platform="linux/amd64" -f bundle.Dockerfile -t $(BUNDLE_IMG) .
 
 .PHONY: bundle-push
 bundle-push: ## Push the bundle image.
-	docker push $(BUNDLE_IMG)
+	$(IMAGE_BUILD_CMD) push $(BUNDLE_IMG)
 
 # Build a catalog image by adding bundle images to an empty catalog using the operator package manager tool, 'opm'.
 # This recipe invokes 'opm' in 'semver' bundle add mode. For more information on add modes, see:
 # https://github.com/operator-framework/community-operators/blob/7f1438c/docs/packaging-operator.md#updating-your-existing-operator
 .PHONY: catalog-build
 catalog-build: opm ## Build a catalog image.
-	$(OPM) index add --permissive --container-tool docker --mode semver --tag $(CATALOG_IMG) --bundles $(BUNDLE_IMGS) $(FROM_INDEX_OPT)
+	./hack/build-catalog.sh
 
 # Push the catalog image.
 .PHONY: catalog-push
 catalog-push: ## Push a catalog image.
-	docker push $(CATALOG_IMG)
+	$(IMAGE_BUILD_CMD) push $(CATALOG_IMG)
diff --git a/PROJECT b/PROJECT
index 79f7b584..85efe3a6 100644
--- a/PROJECT
+++ b/PROJECT
@@ -20,14 +20,6 @@ resources:
   kind: StorageClient
   path: github.com/red-hat-storage/ocs-client-operator/api/v1alpha1
   version: v1alpha1
-- api:
-    crdVersion: v1
-    namespaced: true
-  domain: openshift.io
-  group: ocs
-  kind: StorageClassClaim
-  path: github.com/red-hat-storage/ocs-client-operator/api/v1alpha1
-  version: v1alpha1
 - api:
     crdVersion: v1
     namespaced: true
diff --git a/api/v1alpha1/storageclaim_types.go b/api/v1alpha1/storageclaim_types.go
index 2d52d4d4..da6687d8 100644
--- a/api/v1alpha1/storageclaim_types.go
+++ b/api/v1alpha1/storageclaim_types.go
@@ -44,18 +44,13 @@ type StorageClaimStatus struct {
 	Phase storageClaimState `json:"phase,omitempty"`
 }
 
-type StorageClientNamespacedName struct {
-	Name      string `json:"name"`
-	Namespace string `json:"namespace"`
-}
-
 // StorageClaimSpec defines the desired state of StorageClaim
 type StorageClaimSpec struct {
-	//+kubebuilder:validation:Enum=block;sharedfile
-	Type             string                       `json:"type"`
-	EncryptionMethod string                       `json:"encryptionMethod,omitempty"`
-	StorageProfile   string                       `json:"storageProfile,omitempty"`
-	StorageClient    *StorageClientNamespacedName `json:"storageClient"`
+	//+kubebuilder:validation:XValidation:rule="self.lowerAscii()=='block'||self.lowerAscii()=='sharedfile'",message="value should be either 'sharedfile' or 'block'"
+	Type             string `json:"type"`
+	EncryptionMethod string `json:"encryptionMethod,omitempty"`
+	StorageProfile   string `json:"storageProfile,omitempty"`
+	StorageClient    string `json:"storageClient"`
 }
 
 //+kubebuilder:object:root=true
@@ -63,8 +58,7 @@ type StorageClaimSpec struct {
 //+kubebuilder:resource:scope=Cluster
 //+kubebuilder:printcolumn:name="StorageType",type="string",JSONPath=".spec.type"
 //+kubebuilder:printcolumn:name="StorageProfile",type="string",JSONPath=".spec.storageProfile"
-//+kubebuilder:printcolumn:name="StorageClientName",type="string",JSONPath=".spec.storageClient.name"
-//+kubebuilder:printcolumn:name="StorageClientNamespace",type="string",JSONPath=".spec.storageClient.namespace"
+//+kubebuilder:printcolumn:name="StorageClientName",type="string",JSONPath=".spec.storageClient"
 //+kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase"
 
 // StorageClaim is the Schema for the storageclaims API
diff --git a/api/v1alpha1/storageclassclaim_types.go b/api/v1alpha1/storageclassclaim_types.go
deleted file mode 100644
index ba852852..00000000
--- a/api/v1alpha1/storageclassclaim_types.go
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
-Copyright 2022 Red Hat, Inc.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package v1alpha1
-
-import (
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-)
-
-type storageClassClaimState string
-
-const (
-	// StorageClassClaimInitializing represents Initializing state of StorageClassClaim
-	StorageClassClaimInitializing storageClassClaimState = "Initializing"
-	// StorageClassClaimValidating represents Validating state of StorageClassClaim
-	StorageClassClaimValidating storageClassClaimState = "Validating"
-	// StorageClassClaimFailed represents Failed state of StorageClassClaim
-	StorageClassClaimFailed storageClassClaimState = "Failed"
-	// StorageClassClaimCreating represents Configuring state of StorageClassClaim
-	StorageClassClaimCreating storageClassClaimState = "Creating"
-	// StorageClassClaimConfiguring represents Configuring state of StorageClassClaim
-	StorageClassClaimConfiguring storageClassClaimState = "Configuring"
-	// StorageClassClaimReady represents Ready state of StorageClassClaim
-	StorageClassClaimReady storageClassClaimState = "Ready"
-	// StorageClassClaimDeleting represents Deleting state of StorageClassClaim
-	StorageClassClaimDeleting storageClassClaimState = "Deleting"
-)
-
-// StorageClassClaimStatus defines the observed state of StorageClassClaim
-type StorageClassClaimStatus struct {
-	Phase       storageClassClaimState `json:"phase,omitempty"`
-	SecretNames []string               `json:"secretNames,omitempty"`
-}
-
-// StorageClassClaimSpec defines the desired state of StorageClassClaim
-type StorageClassClaimSpec struct {
-	//+kubebuilder:validation:Enum=blockpool;sharedfilesystem
-	Type             string                       `json:"type"`
-	EncryptionMethod string                       `json:"encryptionMethod,omitempty"`
-	StorageProfile   string                       `json:"storageProfile,omitempty"`
-	StorageClient    *StorageClientNamespacedName `json:"storageClient"`
-}
-
-//+kubebuilder:object:root=true
-//+kubebuilder:subresource:status
-//+kubebuilder:resource:scope=Cluster
-//+kubebuilder:printcolumn:name="StorageType",type="string",JSONPath=".spec.type"
-//+kubebuilder:printcolumn:name="StorageProfile",type="string",JSONPath=".spec.storageProfile"
-//+kubebuilder:printcolumn:name="StorageClientName",type="string",JSONPath=".spec.storageClient.name"
-//+kubebuilder:printcolumn:name="StorageClientNamespace",type="string",JSONPath=".spec.storageClient.namespace"
-//+kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase"
-
-// StorageClassClaim is the Schema for the storageclassclaims API
-//+kubebuilder:deprecatedversion:warning="StorageClassClaim API is deprecated and will be removed in future version, please use StorageClaim API instead."
-type StorageClassClaim struct {
-	metav1.TypeMeta   `json:",inline"`
-	metav1.ObjectMeta `json:"metadata,omitempty"`
-
-	//+kubebuilder:validation:Required
-	//+kubebuilder:validation:XValidation:rule="oldSelf == self",message="spec is immutable"
-	Spec   StorageClassClaimSpec   `json:"spec"`
-	Status StorageClassClaimStatus `json:"status,omitempty"`
-}
-
-//+kubebuilder:object:root=true
-
-// StorageClassClaimList contains a list of StorageClassClaim
-type StorageClassClaimList struct {
-	metav1.TypeMeta `json:",inline"`
-	metav1.ListMeta `json:"metadata,omitempty"`
-	Items           []StorageClassClaim `json:"items"`
-}
-
-func init() {
-	SchemeBuilder.Register(&StorageClassClaim{}, &StorageClassClaimList{})
-}
diff --git a/api/v1alpha1/storageclient_types.go b/api/v1alpha1/storageclient_types.go
index 28147c76..6ca4d7c8 100644
--- a/api/v1alpha1/storageclient_types.go
+++ b/api/v1alpha1/storageclient_types.go
@@ -56,6 +56,7 @@ type StorageClientStatus struct {
 
 //+kubebuilder:object:root=true
 //+kubebuilder:subresource:status
+//+kubebuilder:resource:scope=Cluster
 //+kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase"
 //+kubebuilder:printcolumn:name="consumer",type="string",JSONPath=".status.id"
 
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index c5b6e024..ae9507fe 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -30,7 +30,7 @@ func (in *StorageClaim) DeepCopyInto(out *StorageClaim) {
 	*out = *in
 	out.TypeMeta = in.TypeMeta
 	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
-	in.Spec.DeepCopyInto(&out.Spec)
+	out.Spec = in.Spec
 	out.Status = in.Status
 }
 
@@ -87,11 +87,6 @@ func (in *StorageClaimList) DeepCopyObject() runtime.Object {
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *StorageClaimSpec) DeepCopyInto(out *StorageClaimSpec) {
 	*out = *in
-	if in.StorageClient != nil {
-		in, out := &in.StorageClient, &out.StorageClient
-		*out = new(StorageClientNamespacedName)
-		**out = **in
-	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageClaimSpec.
@@ -119,105 +114,6 @@ func (in *StorageClaimStatus) DeepCopy() *StorageClaimStatus {
 	return out
 }
 
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *StorageClassClaim) DeepCopyInto(out *StorageClassClaim) {
-	*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 StorageClassClaim.
-func (in *StorageClassClaim) DeepCopy() *StorageClassClaim {
-	if in == nil {
-		return nil
-	}
-	out := new(StorageClassClaim)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *StorageClassClaim) 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 *StorageClassClaimList) DeepCopyInto(out *StorageClassClaimList) {
-	*out = *in
-	out.TypeMeta = in.TypeMeta
-	in.ListMeta.DeepCopyInto(&out.ListMeta)
-	if in.Items != nil {
-		in, out := &in.Items, &out.Items
-		*out = make([]StorageClassClaim, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageClassClaimList.
-func (in *StorageClassClaimList) DeepCopy() *StorageClassClaimList {
-	if in == nil {
-		return nil
-	}
-	out := new(StorageClassClaimList)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *StorageClassClaimList) 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 *StorageClassClaimSpec) DeepCopyInto(out *StorageClassClaimSpec) {
-	*out = *in
-	if in.StorageClient != nil {
-		in, out := &in.StorageClient, &out.StorageClient
-		*out = new(StorageClientNamespacedName)
-		**out = **in
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageClassClaimSpec.
-func (in *StorageClassClaimSpec) DeepCopy() *StorageClassClaimSpec {
-	if in == nil {
-		return nil
-	}
-	out := new(StorageClassClaimSpec)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *StorageClassClaimStatus) DeepCopyInto(out *StorageClassClaimStatus) {
-	*out = *in
-	if in.SecretNames != nil {
-		in, out := &in.SecretNames, &out.SecretNames
-		*out = make([]string, len(*in))
-		copy(*out, *in)
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageClassClaimStatus.
-func (in *StorageClassClaimStatus) DeepCopy() *StorageClassClaimStatus {
-	if in == nil {
-		return nil
-	}
-	out := new(StorageClassClaimStatus)
-	in.DeepCopyInto(out)
-	return out
-}
-
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *StorageClient) DeepCopyInto(out *StorageClient) {
 	*out = *in
@@ -277,21 +173,6 @@ func (in *StorageClientList) DeepCopyObject() runtime.Object {
 	return nil
 }
 
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *StorageClientNamespacedName) DeepCopyInto(out *StorageClientNamespacedName) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageClientNamespacedName.
-func (in *StorageClientNamespacedName) DeepCopy() *StorageClientNamespacedName {
-	if in == nil {
-		return nil
-	}
-	out := new(StorageClientNamespacedName)
-	in.DeepCopyInto(out)
-	return out
-}
-
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *StorageClientSpec) DeepCopyInto(out *StorageClientSpec) {
 	*out = *in
diff --git a/bundle/manifests/ocs-client-operator-config_v1_configmap.yaml b/bundle/manifests/ocs-client-operator-config_v1_configmap.yaml
new file mode 100644
index 00000000..360b979a
--- /dev/null
+++ b/bundle/manifests/ocs-client-operator-config_v1_configmap.yaml
@@ -0,0 +1,4 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: ocs-client-operator-config
diff --git a/bundle/manifests/ocs-client-operator-csi-images_v1_configmap.yaml b/bundle/manifests/ocs-client-operator-csi-images_v1_configmap.yaml
index 3bcfe663..450c34b3 100644
--- a/bundle/manifests/ocs-client-operator-csi-images_v1_configmap.yaml
+++ b/bundle/manifests/ocs-client-operator-csi-images_v1_configmap.yaml
@@ -2,25 +2,35 @@ apiVersion: v1
 data:
   csi-images.yaml: |
     ---
-    - version: v4.11
+    - version: v4.14
       containerImages:
-        provisionerImageURL: "registry.k8s.io/sig-storage/csi-provisioner:v3.3.0"
-        attacherImageURL: "registry.k8s.io/sig-storage/csi-attacher:v4.0.0"
-        resizerImageURL: "registry.k8s.io/sig-storage/csi-resizer:v1.6.0"
-        snapshotterImageURL: "registry.k8s.io/sig-storage/csi-snapshotter:v6.1.0"
-        driverRegistrarImageURL: "registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.5.1"
-        cephCSIImageURL: "quay.io/cephcsi/cephcsi:v3.7.2"
-        csiaddonsImageURL: "quay.io/csiaddons/k8s-sidecar:v0.5.0"
+        provisionerImageURL: "registry.k8s.io/sig-storage/csi-provisioner:v4.0.0"
+        attacherImageURL: "registry.k8s.io/sig-storage/csi-attacher:v4.5.0"
+        resizerImageURL: "registry.k8s.io/sig-storage/csi-resizer:v1.10.0"
+        snapshotterImageURL: "registry.k8s.io/sig-storage/csi-snapshotter:v7.0.1"
+        driverRegistrarImageURL: "registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.10.0"
+        cephCSIImageURL: "quay.io/cephcsi/cephcsi:v3.10.2"
+        csiaddonsImageURL: "quay.io/csiaddons/k8s-sidecar:v0.8.0"
 
-    - version: v4.12
+    - version: v4.15
       containerImages:
-        provisionerImageURL: "registry.k8s.io/sig-storage/csi-provisioner:v3.3.0"
-        attacherImageURL: "registry.k8s.io/sig-storage/csi-attacher:v4.0.0"
-        resizerImageURL: "registry.k8s.io/sig-storage/csi-resizer:v1.6.0"
-        snapshotterImageURL: "registry.k8s.io/sig-storage/csi-snapshotter:v6.1.0"
-        driverRegistrarImageURL: "registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.5.1"
-        cephCSIImageURL: "quay.io/cephcsi/cephcsi:v3.7.2"
-        csiaddonsImageURL: "quay.io/csiaddons/k8s-sidecar:v0.5.0"
+        provisionerImageURL: "registry.k8s.io/sig-storage/csi-provisioner:v4.0.0"
+        attacherImageURL: "registry.k8s.io/sig-storage/csi-attacher:v4.5.0"
+        resizerImageURL: "registry.k8s.io/sig-storage/csi-resizer:v1.10.0"
+        snapshotterImageURL: "registry.k8s.io/sig-storage/csi-snapshotter:v7.0.1"
+        driverRegistrarImageURL: "registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.10.0"
+        cephCSIImageURL: "quay.io/cephcsi/cephcsi:v3.10.2"
+        csiaddonsImageURL: "quay.io/csiaddons/k8s-sidecar:v0.8.0"
+
+    - version: v4.16
+      containerImages:
+        provisionerImageURL: "registry.k8s.io/sig-storage/csi-provisioner:v4.0.0"
+        attacherImageURL: "registry.k8s.io/sig-storage/csi-attacher:v4.5.0"
+        resizerImageURL: "registry.k8s.io/sig-storage/csi-resizer:v1.10.0"
+        snapshotterImageURL: "registry.k8s.io/sig-storage/csi-snapshotter:v7.0.1"
+        driverRegistrarImageURL: "registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.10.0"
+        cephCSIImageURL: "quay.io/cephcsi/cephcsi:v3.10.2"
+        csiaddonsImageURL: "quay.io/csiaddons/k8s-sidecar:v0.8.0"
 kind: ConfigMap
 metadata:
   name: ocs-client-operator-csi-images
diff --git a/bundle/manifests/ocs-client-operator-webhook-server_v1_service.yaml b/bundle/manifests/ocs-client-operator-webhook-server_v1_service.yaml
new file mode 100644
index 00000000..168e6fdd
--- /dev/null
+++ b/bundle/manifests/ocs-client-operator-webhook-server_v1_service.yaml
@@ -0,0 +1,18 @@
+apiVersion: v1
+kind: Service
+metadata:
+  annotations:
+    service.beta.openshift.io/serving-cert-secret-name: webhook-cert-secret
+  creationTimestamp: null
+  name: ocs-client-operator-webhook-server
+spec:
+  ports:
+  - name: https
+    port: 443
+    protocol: TCP
+    targetPort: 7443
+  selector:
+    app: ocs-client-operator
+  type: ClusterIP
+status:
+  loadBalancer: {}
diff --git a/bundle/manifests/ocs-client-operator.clusterserviceversion.yaml b/bundle/manifests/ocs-client-operator.clusterserviceversion.yaml
index 84a0ceb0..61c6f840 100644
--- a/bundle/manifests/ocs-client-operator.clusterserviceversion.yaml
+++ b/bundle/manifests/ocs-client-operator.clusterserviceversion.yaml
@@ -8,16 +8,16 @@ metadata:
     olm.skipRange: ""
     operators.operatorframework.io/builder: operator-sdk-v1.19.0+git
     operators.operatorframework.io/project_layout: go.kubebuilder.io/v3
-  name: ocs-client-operator.v4.12.0
+  name: ocs-client-operator.v4.16.0
   namespace: placeholder
 spec:
   apiservicedefinitions: {}
   customresourcedefinitions:
     owned:
-    - description: StorageClassClaim is the Schema for the storageclassclaims API
-      displayName: Storage Class Claim
-      kind: StorageClassClaim
-      name: storageclassclaims.ocs.openshift.io
+    - description: StorageClaim is the Schema for the storageclaims API
+      displayName: Storage Claim
+      kind: StorageClaim
+      name: storageclaims.ocs.openshift.io
       version: v1alpha1
     - description: StorageClient is the Schema for the storageclients API
       displayName: Storage Client
@@ -44,6 +44,12 @@ spec:
           - list
           - update
           - watch
+        - apiGroups:
+          - ""
+          resources:
+          - configmaps/finalizers
+          verbs:
+          - update
         - apiGroups:
           - ""
           resources:
@@ -67,6 +73,25 @@ spec:
           - patch
           - update
           - watch
+        - apiGroups:
+          - admissionregistration.k8s.io
+          resources:
+          - validatingwebhookconfigurations
+          verbs:
+          - create
+          - delete
+          - get
+          - list
+          - update
+          - watch
+        - apiGroups:
+          - apiextensions.k8s.io
+          resources:
+          - customresourcedefinitions
+          verbs:
+          - get
+          - list
+          - watch
         - apiGroups:
           - apps
           resources:
@@ -119,27 +144,9 @@ spec:
           resources:
           - clusterversions
           verbs:
-          - create
-          - delete
           - get
           - list
-          - patch
-          - update
           - watch
-        - apiGroups:
-          - config.openshift.io
-          resources:
-          - clusterversions/finalizers
-          verbs:
-          - update
-        - apiGroups:
-          - config.openshift.io
-          resources:
-          - clusterversions/status
-          verbs:
-          - get
-          - patch
-          - update
         - apiGroups:
           - console.openshift.io
           resources:
@@ -167,7 +174,7 @@ spec:
         - apiGroups:
           - ocs.openshift.io
           resources:
-          - storageclassclaims
+          - storageclaims
           verbs:
           - create
           - delete
@@ -179,13 +186,13 @@ spec:
         - apiGroups:
           - ocs.openshift.io
           resources:
-          - storageclassclaims/finalizers
+          - storageclaims/finalizers
           verbs:
           - update
         - apiGroups:
           - ocs.openshift.io
           resources:
-          - storageclassclaims/status
+          - storageclaims/status
           verbs:
           - get
           - patch
@@ -224,12 +231,22 @@ spec:
           - get
           - list
           - watch
+        - apiGroups:
+          - operators.coreos.com
+          resources:
+          - subscriptions
+          verbs:
+          - get
+          - list
+          - update
+          - watch
         - apiGroups:
           - security.openshift.io
           resources:
           - securitycontextconstraints
           verbs:
           - create
+          - delete
           - get
           - list
           - patch
@@ -245,6 +262,14 @@ spec:
           - get
           - list
           - watch
+        - apiGroups:
+          - snapshot.storage.k8s.io
+          resources:
+          - volumesnapshotcontents
+          verbs:
+          - get
+          - list
+          - watch
         - apiGroups:
           - storage.k8s.io
           resources:
@@ -598,6 +623,7 @@ spec:
           verbs:
           - get
           - list
+          - patch
         - apiGroups:
           - ""
           resources:
@@ -617,74 +643,14 @@ spec:
         serviceAccountName: ocs-client-operator-status-reporter
       deployments:
       - label:
-          app.kubernetes.io/name: ocs-client-operator-console
-        name: ocs-client-operator-console
-        spec:
-          selector:
-            matchLabels:
-              app.kubernetes.io/name: ocs-client-operator-console
-          strategy: {}
-          template:
-            metadata:
-              labels:
-                app.kubernetes.io/name: ocs-client-operator-console
-            spec:
-              containers:
-              - image: quay.io/ocs-dev/ocs-client-console:latest
-                livenessProbe:
-                  httpGet:
-                    path: /plugin-manifest.json
-                    port: 9001
-                    scheme: HTTPS
-                  initialDelaySeconds: 1000
-                  periodSeconds: 60
-                name: ocs-client-operator-console
-                ports:
-                - containerPort: 9001
-                  protocol: TCP
-                resources:
-                  limits:
-                    cpu: 100m
-                    memory: 512Mi
-                securityContext:
-                  allowPrivilegeEscalation: false
-                  capabilities:
-                    drop:
-                    - ALL
-                  readOnlyRootFilesystem: true
-                  seccompProfile:
-                    type: RuntimeDefault
-                volumeMounts:
-                - mountPath: /var/serving-cert
-                  name: ocs-client-operator-console-serving-cert
-                  readOnly: true
-                - mountPath: /etc/nginx/nginx.conf
-                  name: ocs-client-operator-console-nginx-conf
-                  subPath: nginx.conf
-                - mountPath: /var/log/nginx
-                  name: ocs-client-operator-console-nginx-log
-                - mountPath: /var/lib/nginx/tmp
-                  name: ocs-client-operator-console-nginx-tmp
-              securityContext:
-                runAsNonRoot: true
-              volumes:
-              - name: ocs-client-operator-console-serving-cert
-                secret:
-                  secretName: ocs-client-operator-console-serving-cert
-              - configMap:
-                  name: ocs-client-operator-console-nginx-conf
-                name: ocs-client-operator-console-nginx-conf
-              - emptyDir: {}
-                name: ocs-client-operator-console-nginx-log
-              - emptyDir: {}
-                name: ocs-client-operator-console-nginx-tmp
-      - label:
+          app: ocs-client-operator
           control-plane: controller-manager
         name: ocs-client-operator-controller-manager
         spec:
           replicas: 1
           selector:
             matchLabels:
+              app: ocs-client-operator
               control-plane: controller-manager
           strategy: {}
           template:
@@ -692,6 +658,7 @@ spec:
               annotations:
                 kubectl.kubernetes.io/default-container: manager
               labels:
+                app: ocs-client-operator
                 control-plane: controller-manager
             spec:
               containers:
@@ -700,7 +667,7 @@ spec:
                 - --upstream=http://127.0.0.1:8080/
                 - --logtostderr=true
                 - --v=0
-                image: gcr.io/kubebuilder/kube-rbac-proxy:v0.8.0
+                image: registry.redhat.io/openshift4/ose-kube-rbac-proxy:v4.9.0
                 name: kube-rbac-proxy
                 ports:
                 - containerPort: 8443
@@ -757,6 +724,8 @@ spec:
                 volumeMounts:
                 - mountPath: /opt/config
                   name: csi-images
+                - mountPath: /etc/tls/private
+                  name: webhook-cert-secret
               securityContext:
                 runAsNonRoot: true
               serviceAccountName: ocs-client-operator-controller-manager
@@ -765,9 +734,12 @@ spec:
               - configMap:
                   name: ocs-client-operator-csi-images
                 name: csi-images
+              - name: webhook-cert-secret
+                secret:
+                  secretName: webhook-cert-secret
       - label:
           app.kubernetes.io/name: ocs-client-operator-console
-        name: console
+        name: ocs-client-operator-console
         spec:
           selector:
             matchLabels:
@@ -934,4 +906,4 @@ spec:
   maturity: alpha
   provider:
     name: Red Hat
-  version: 4.12.0
+  version: 4.16.0
diff --git a/bundle/manifests/ocs.openshift.io_storageclassclaims.yaml b/bundle/manifests/ocs.openshift.io_storageclaims.yaml
similarity index 63%
rename from bundle/manifests/ocs.openshift.io_storageclassclaims.yaml
rename to bundle/manifests/ocs.openshift.io_storageclaims.yaml
index 82ef4ce5..23ed6f90 100644
--- a/bundle/manifests/ocs.openshift.io_storageclassclaims.yaml
+++ b/bundle/manifests/ocs.openshift.io_storageclaims.yaml
@@ -2,16 +2,16 @@ apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
   annotations:
-    controller-gen.kubebuilder.io/version: v0.4.1
+    controller-gen.kubebuilder.io/version: v0.9.2
   creationTimestamp: null
-  name: storageclassclaims.ocs.openshift.io
+  name: storageclaims.ocs.openshift.io
 spec:
   group: ocs.openshift.io
   names:
-    kind: StorageClassClaim
-    listKind: StorageClassClaimList
-    plural: storageclassclaims
-    singular: storageclassclaim
+    kind: StorageClaim
+    listKind: StorageClaimList
+    plural: storageclaims
+    singular: storageclaim
   scope: Cluster
   versions:
   - additionalPrinterColumns:
@@ -21,19 +21,16 @@ spec:
     - jsonPath: .spec.storageProfile
       name: StorageProfile
       type: string
-    - jsonPath: .spec.storageClient.name
+    - jsonPath: .spec.storageClient
       name: StorageClientName
       type: string
-    - jsonPath: .spec.storageClient.namespace
-      name: StorageClientNamespace
-      type: string
     - jsonPath: .status.phase
       name: Phase
       type: string
     name: v1alpha1
     schema:
       openAPIV3Schema:
-        description: StorageClassClaim is the Schema for the storageclassclaims API
+        description: StorageClaim is the Schema for the storageclaims API
         properties:
           apiVersion:
             description: 'APIVersion defines the versioned schema of this representation
@@ -48,40 +45,31 @@ spec:
           metadata:
             type: object
           spec:
-            description: StorageClassClaimSpec defines the desired state of StorageClassClaim
+            description: StorageClaimSpec defines the desired state of StorageClaim
             properties:
               encryptionMethod:
                 type: string
               storageClient:
-                properties:
-                  name:
-                    type: string
-                  namespace:
-                    type: string
-                required:
-                - name
-                - namespace
-                type: object
+                type: string
               storageProfile:
                 type: string
               type:
-                enum:
-                - blockpool
-                - sharedfilesystem
                 type: string
+                x-kubernetes-validations:
+                - message: value should be either 'sharedfile' or 'block'
+                  rule: self.lowerAscii()=='block'||self.lowerAscii()=='sharedfile'
             required:
             - storageClient
             - type
             type: object
+            x-kubernetes-validations:
+            - message: spec is immutable
+              rule: oldSelf == self
           status:
-            description: StorageClassClaimStatus defines the observed state of StorageClassClaim
+            description: StorageClaimStatus defines the observed state of StorageClaim
             properties:
               phase:
                 type: string
-              secretNames:
-                items:
-                  type: string
-                type: array
             type: object
         type: object
     served: true
@@ -92,5 +80,5 @@ status:
   acceptedNames:
     kind: ""
     plural: ""
-  conditions: []
-  storedVersions: []
+  conditions: null
+  storedVersions: null
diff --git a/bundle/manifests/ocs.openshift.io_storageclients.yaml b/bundle/manifests/ocs.openshift.io_storageclients.yaml
index 9b6527b7..95e22b1d 100644
--- a/bundle/manifests/ocs.openshift.io_storageclients.yaml
+++ b/bundle/manifests/ocs.openshift.io_storageclients.yaml
@@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
   annotations:
-    controller-gen.kubebuilder.io/version: v0.4.1
+    controller-gen.kubebuilder.io/version: v0.9.2
   creationTimestamp: null
   name: storageclients.ocs.openshift.io
 spec:
@@ -12,7 +12,7 @@ spec:
     listKind: StorageClientList
     plural: storageclients
     singular: storageclient
-  scope: Namespaced
+  scope: Cluster
   versions:
   - additionalPrinterColumns:
     - jsonPath: .status.phase
@@ -72,5 +72,5 @@ status:
   acceptedNames:
     kind: ""
     plural: ""
-  conditions: []
-  storedVersions: []
+  conditions: null
+  storedVersions: null
diff --git a/bundle/metadata/dependencies.yaml b/bundle/metadata/dependencies.yaml
index dcfeb21f..3a99feee 100644
--- a/bundle/metadata/dependencies.yaml
+++ b/bundle/metadata/dependencies.yaml
@@ -1,5 +1,5 @@
 dependencies:
-- type: olm.package
-  value:
-    packageName: csi-addons
-    version: 0.5.0
+  - type: olm.package
+    value:
+      packageName: csi-addons
+      version: 0.8.0
diff --git a/config/console/kustomization.yaml b/config/console/kustomization.yaml
index d8403715..a70695ea 100644
--- a/config/console/kustomization.yaml
+++ b/config/console/kustomization.yaml
@@ -12,3 +12,4 @@ images:
 - name: ocs-client-operator-console
   newName: quay.io/ocs-dev/ocs-client-console
   newTag: latest
+namePrefix: ocs-client-operator-
diff --git a/config/crd/bases/ocs.openshift.io_storageclaims.yaml b/config/crd/bases/ocs.openshift.io_storageclaims.yaml
index a10dc976..da254473 100644
--- a/config/crd/bases/ocs.openshift.io_storageclaims.yaml
+++ b/config/crd/bases/ocs.openshift.io_storageclaims.yaml
@@ -22,12 +22,9 @@ spec:
     - jsonPath: .spec.storageProfile
       name: StorageProfile
       type: string
-    - jsonPath: .spec.storageClient.name
+    - jsonPath: .spec.storageClient
       name: StorageClientName
       type: string
-    - jsonPath: .spec.storageClient.namespace
-      name: StorageClientNamespace
-      type: string
     - jsonPath: .status.phase
       name: Phase
       type: string
@@ -54,22 +51,14 @@ spec:
               encryptionMethod:
                 type: string
               storageClient:
-                properties:
-                  name:
-                    type: string
-                  namespace:
-                    type: string
-                required:
-                - name
-                - namespace
-                type: object
+                type: string
               storageProfile:
                 type: string
               type:
-                enum:
-                - block
-                - sharedfile
                 type: string
+                x-kubernetes-validations:
+                - message: value should be either 'sharedfile' or 'block'
+                  rule: self.lowerAscii()=='block'||self.lowerAscii()=='sharedfile'
             required:
             - storageClient
             - type
diff --git a/config/crd/bases/ocs.openshift.io_storageclassclaims.yaml b/config/crd/bases/ocs.openshift.io_storageclassclaims.yaml
deleted file mode 100644
index 6c4dff38..00000000
--- a/config/crd/bases/ocs.openshift.io_storageclassclaims.yaml
+++ /dev/null
@@ -1,99 +0,0 @@
----
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    controller-gen.kubebuilder.io/version: v0.9.2
-  creationTimestamp: null
-  name: storageclassclaims.ocs.openshift.io
-spec:
-  group: ocs.openshift.io
-  names:
-    kind: StorageClassClaim
-    listKind: StorageClassClaimList
-    plural: storageclassclaims
-    singular: storageclassclaim
-  scope: Cluster
-  versions:
-  - additionalPrinterColumns:
-    - jsonPath: .spec.type
-      name: StorageType
-      type: string
-    - jsonPath: .spec.storageProfile
-      name: StorageProfile
-      type: string
-    - jsonPath: .spec.storageClient.name
-      name: StorageClientName
-      type: string
-    - jsonPath: .spec.storageClient.namespace
-      name: StorageClientNamespace
-      type: string
-    - jsonPath: .status.phase
-      name: Phase
-      type: string
-    deprecated: true
-    deprecationWarning: StorageClassClaim API is deprecated and will be removed in
-      future version, please use StorageClaim API instead.
-    name: v1alpha1
-    schema:
-      openAPIV3Schema:
-        description: StorageClassClaim is the Schema for the storageclassclaims API
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: StorageClassClaimSpec defines the desired state of StorageClassClaim
-            properties:
-              encryptionMethod:
-                type: string
-              storageClient:
-                properties:
-                  name:
-                    type: string
-                  namespace:
-                    type: string
-                required:
-                - name
-                - namespace
-                type: object
-              storageProfile:
-                type: string
-              type:
-                enum:
-                - blockpool
-                - sharedfilesystem
-                type: string
-            required:
-            - storageClient
-            - type
-            type: object
-            x-kubernetes-validations:
-            - message: spec is immutable
-              rule: oldSelf == self
-          status:
-            description: StorageClassClaimStatus defines the observed state of StorageClassClaim
-            properties:
-              phase:
-                type: string
-              secretNames:
-                items:
-                  type: string
-                type: array
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/config/crd/bases/ocs.openshift.io_storageclients.yaml b/config/crd/bases/ocs.openshift.io_storageclients.yaml
index 766ae368..afcbcd44 100644
--- a/config/crd/bases/ocs.openshift.io_storageclients.yaml
+++ b/config/crd/bases/ocs.openshift.io_storageclients.yaml
@@ -13,7 +13,7 @@ spec:
     listKind: StorageClientList
     plural: storageclients
     singular: storageclient
-  scope: Namespaced
+  scope: Cluster
   versions:
   - additionalPrinterColumns:
     - jsonPath: .status.phase
diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml
index 0fabd03c..50fbe2d3 100644
--- a/config/crd/kustomization.yaml
+++ b/config/crd/kustomization.yaml
@@ -3,7 +3,6 @@
 # It should be run by config/default
 resources:
 - bases/ocs.openshift.io_storageclients.yaml
-- bases/ocs.openshift.io_storageclassclaims.yaml
 - bases/ocs.openshift.io_storageclaims.yaml
 #+kubebuilder:scaffold:crdkustomizeresource
 
@@ -11,14 +10,12 @@ patchesStrategicMerge:
 # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix.
 # patches here are for enabling the conversion webhook for each CRD
 #- patches/webhook_in_storageclients.yaml
-#- patches/webhook_in_storageclassclaims.yaml
 #- patches/webhook_in_storageclaims.yaml
 #+kubebuilder:scaffold:crdkustomizewebhookpatch
 
 # [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
 # patches here are for enabling the CA injection for each CRD
 #- patches/cainjection_in_storageclients.yaml
-#- patches/cainjection_in_storageclassclaims.yaml
 #- patches/cainjection_in_storageclaims.yaml
 #+kubebuilder:scaffold:crdkustomizecainjectionpatch
 
diff --git a/config/crd/patches/cainjection_in_storageclassclaims.yaml b/config/crd/patches/cainjection_in_storageclassclaims.yaml
deleted file mode 100644
index 261b8be3..00000000
--- a/config/crd/patches/cainjection_in_storageclassclaims.yaml
+++ /dev/null
@@ -1,7 +0,0 @@
-# The following patch adds a directive for certmanager to inject CA into the CRD
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
-  name: storageclassclaims.ocs.openshift.io
diff --git a/config/crd/patches/webhook_in_storageclassclaims.yaml b/config/crd/patches/webhook_in_storageclassclaims.yaml
deleted file mode 100644
index de537a77..00000000
--- a/config/crd/patches/webhook_in_storageclassclaims.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-# The following patch enables a conversion webhook for the CRD
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  name: storageclassclaims.ocs.openshift.io
-spec:
-  conversion:
-    strategy: Webhook
-    webhook:
-      clientConfig:
-        service:
-          namespace: system
-          name: webhook-service
-          path: /convert
-      conversionReviewVersions:
-      - v1
diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml
index 866a44ce..c6bc946b 100644
--- a/config/default/kustomization.yaml
+++ b/config/default/kustomization.yaml
@@ -46,7 +46,6 @@ resources:
 - ../rbac
 - ../manager
 - ../crd
-- ../console
 images:
 - name: kube-rbac-proxy
   newName: registry.redhat.io/openshift4/ose-kube-rbac-proxy
diff --git a/config/default/manager_auth_proxy_patch.yaml b/config/default/manager_auth_proxy_patch.yaml
index c50d4743..5ff4b693 100644
--- a/config/default/manager_auth_proxy_patch.yaml
+++ b/config/default/manager_auth_proxy_patch.yaml
@@ -10,7 +10,7 @@ spec:
     spec:
       containers:
       - name: kube-rbac-proxy
-        image: gcr.io/kubebuilder/kube-rbac-proxy:v0.8.0
+        image: kube-rbac-proxy:latest
         args:
         - "--secure-listen-address=0.0.0.0:8443"
         - "--upstream=http://127.0.0.1:8080/"
diff --git a/config/manager/webhook_service.yaml b/config/manager/webhook_service.yaml
index dd1f468b..73fd47e4 100644
--- a/config/manager/webhook_service.yaml
+++ b/config/manager/webhook_service.yaml
@@ -5,6 +5,7 @@ metadata:
     service.beta.openshift.io/serving-cert-secret-name: webhook-cert-secret
   name: webhook-server
   namespace: system
+# should be in sync with pkg/templates/webhookservice.go
 spec:
   ports:
   - name: https
diff --git a/config/manifests/bases/ocs-client-operator.clusterserviceversion.yaml b/config/manifests/bases/ocs-client-operator.clusterserviceversion.yaml
index 1f4eeb18..a3c91811 100644
--- a/config/manifests/bases/ocs-client-operator.clusterserviceversion.yaml
+++ b/config/manifests/bases/ocs-client-operator.clusterserviceversion.yaml
@@ -16,11 +16,6 @@ spec:
       kind: StorageClaim
       name: storageclaims.ocs.openshift.io
       version: v1alpha1
-    - description: StorageClassClaim is the Schema for the storageclassclaims API
-      displayName: Storage Class Claim
-      kind: StorageClassClaim
-      name: storageclassclaims.ocs.openshift.io
-      version: v1alpha1
     - description: StorageClient is the Schema for the storageclients API
       displayName: Storage Client
       kind: StorageClient
diff --git a/config/metadata/dependencies.yaml b/config/metadata/dependencies.yaml
index dcfeb21f..3a99feee 100644
--- a/config/metadata/dependencies.yaml
+++ b/config/metadata/dependencies.yaml
@@ -1,5 +1,5 @@
 dependencies:
-- type: olm.package
-  value:
-    packageName: csi-addons
-    version: 0.5.0
+  - type: olm.package
+    value:
+      packageName: csi-addons
+      version: 0.8.0
diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml
index f65a9b5d..a5055aca 100644
--- a/config/rbac/role.yaml
+++ b/config/rbac/role.yaml
@@ -16,6 +16,12 @@ rules:
   - list
   - update
   - watch
+- apiGroups:
+  - ""
+  resources:
+  - configmaps/finalizers
+  verbs:
+  - update
 - apiGroups:
   - ""
   resources:
@@ -45,6 +51,7 @@ rules:
   - validatingwebhookconfigurations
   verbs:
   - create
+  - delete
   - get
   - list
   - update
@@ -109,27 +116,9 @@ rules:
   resources:
   - clusterversions
   verbs:
-  - create
-  - delete
   - get
   - list
-  - patch
-  - update
   - watch
-- apiGroups:
-  - config.openshift.io
-  resources:
-  - clusterversions/finalizers
-  verbs:
-  - update
-- apiGroups:
-  - config.openshift.io
-  resources:
-  - clusterversions/status
-  verbs:
-  - get
-  - patch
-  - update
 - apiGroups:
   - console.openshift.io
   resources:
@@ -180,32 +169,6 @@ rules:
   - get
   - patch
   - update
-- apiGroups:
-  - ocs.openshift.io
-  resources:
-  - storageclassclaims
-  verbs:
-  - create
-  - delete
-  - get
-  - list
-  - patch
-  - update
-  - watch
-- apiGroups:
-  - ocs.openshift.io
-  resources:
-  - storageclassclaims/finalizers
-  verbs:
-  - update
-- apiGroups:
-  - ocs.openshift.io
-  resources:
-  - storageclassclaims/status
-  verbs:
-  - get
-  - patch
-  - update
 - apiGroups:
   - ocs.openshift.io
   resources:
@@ -255,6 +218,7 @@ rules:
   - securitycontextconstraints
   verbs:
   - create
+  - delete
   - get
   - list
   - patch
diff --git a/config/rbac/storageclassclaim_editor_role.yaml b/config/rbac/storageclassclaim_editor_role.yaml
deleted file mode 100644
index dd12c13d..00000000
--- a/config/rbac/storageclassclaim_editor_role.yaml
+++ /dev/null
@@ -1,31 +0,0 @@
-# permissions for end users to edit storageclassclaims.
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
-  labels:
-    app.kubernetes.io/name: clusterrole
-    app.kubernetes.io/instance: storageclassclaim-editor-role
-    app.kubernetes.io/component: rbac
-    app.kubernetes.io/created-by: ocs-client-operator
-    app.kubernetes.io/part-of: ocs-client-operator
-    app.kubernetes.io/managed-by: kustomize
-  name: storageclassclaim-editor-role
-rules:
-- apiGroups:
-  - ocs.openshift.io
-  resources:
-  - storageclassclaims
-  verbs:
-  - create
-  - delete
-  - get
-  - list
-  - patch
-  - update
-  - watch
-- apiGroups:
-  - ocs.openshift.io
-  resources:
-  - storageclassclaims/status
-  verbs:
-  - get
diff --git a/config/rbac/storageclassclaim_viewer_role.yaml b/config/rbac/storageclassclaim_viewer_role.yaml
deleted file mode 100644
index 8e1307e9..00000000
--- a/config/rbac/storageclassclaim_viewer_role.yaml
+++ /dev/null
@@ -1,27 +0,0 @@
-# permissions for end users to view storageclassclaims.
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
-  labels:
-    app.kubernetes.io/name: clusterrole
-    app.kubernetes.io/instance: storageclassclaim-viewer-role
-    app.kubernetes.io/component: rbac
-    app.kubernetes.io/created-by: ocs-client-operator
-    app.kubernetes.io/part-of: ocs-client-operator
-    app.kubernetes.io/managed-by: kustomize
-  name: storageclassclaim-viewer-role
-rules:
-- apiGroups:
-  - ocs.openshift.io
-  resources:
-  - storageclassclaims
-  verbs:
-  - get
-  - list
-  - watch
-- apiGroups:
-  - ocs.openshift.io
-  resources:
-  - storageclassclaims/status
-  verbs:
-  - get
diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml
index d1194ae9..7adceffc 100644
--- a/config/samples/kustomization.yaml
+++ b/config/samples/kustomization.yaml
@@ -1,6 +1,5 @@
 ## Append samples you want in your CSV to this file as resources ##
 resources:
 - ocs_v1alpha1_storageclient.yaml
-- ocs_v1alpha1_storageclassclaim.yaml
 - ocs_v1alpha1_storageclaim.yaml
 #+kubebuilder:scaffold:manifestskustomizesamples
diff --git a/config/samples/ocs_v1alpha1_storageclassclaim.yaml b/config/samples/ocs_v1alpha1_storageclassclaim.yaml
deleted file mode 100644
index c3bbe8f7..00000000
--- a/config/samples/ocs_v1alpha1_storageclassclaim.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-apiVersion: ocs.openshift.io/v1alpha1
-kind: StorageClassClaim
-metadata:
-  labels:
-    app.kubernetes.io/name: storageclassclaim
-    app.kubernetes.io/instance: storageclassclaim-sample
-    app.kubernetes.io/part-of: ocs-client-operator
-    app.kubernetes.io/managed-by: kustomize
-    app.kubernetes.io/created-by: ocs-client-operator
-  name: storageclassclaim-sample
-spec:
-  # TODO(user): Add fields here
diff --git a/controllers/clusterversion_controller.go b/controllers/clusterversion_controller.go
deleted file mode 100644
index 076210aa..00000000
--- a/controllers/clusterversion_controller.go
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
-Copyright 2023 Red Hat OpenShift Data Foundation.
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-    http://www.apache.org/licenses/LICENSE-2.0
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package controllers
-
-import (
-	"bytes"
-	"context"
-	"fmt"
-	"strconv"
-	"strings"
-
-	// The embed package is required for the prometheus rule files
-	_ "embed"
-
-	"github.com/red-hat-storage/ocs-client-operator/pkg/console"
-	"github.com/red-hat-storage/ocs-client-operator/pkg/csi"
-	"github.com/red-hat-storage/ocs-client-operator/pkg/templates"
-	"github.com/red-hat-storage/ocs-client-operator/pkg/utils"
-
-	"github.com/go-logr/logr"
-	configv1 "github.com/openshift/api/config/v1"
-	secv1 "github.com/openshift/api/security/v1"
-	opv1a1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
-	monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
-	admrv1 "k8s.io/api/admissionregistration/v1"
-	appsv1 "k8s.io/api/apps/v1"
-	corev1 "k8s.io/api/core/v1"
-	extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
-	kerrors "k8s.io/apimachinery/pkg/api/errors"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/runtime"
-	"k8s.io/apimachinery/pkg/types"
-	k8sYAML "k8s.io/apimachinery/pkg/util/yaml"
-	"k8s.io/klog/v2"
-	ctrl "sigs.k8s.io/controller-runtime"
-	"sigs.k8s.io/controller-runtime/pkg/builder"
-	"sigs.k8s.io/controller-runtime/pkg/client"
-	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
-	"sigs.k8s.io/controller-runtime/pkg/handler"
-	"sigs.k8s.io/controller-runtime/pkg/log"
-	"sigs.k8s.io/controller-runtime/pkg/predicate"
-	"sigs.k8s.io/controller-runtime/pkg/reconcile"
-)
-
-//go:embed pvc-rules.yaml
-var pvcPrometheusRules string
-
-const (
-	operatorConfigMapName = "ocs-client-operator-config"
-	// ClusterVersionName is the name of the ClusterVersion object in the
-	// openshift cluster.
-	clusterVersionName     = "version"
-	deployCSIKey           = "DEPLOY_CSI"
-	subscriptionLabelKey   = "managed-by"
-	subscriptionLabelValue = "webhook.subscription.ocs.openshift.io"
-)
-
-// ClusterVersionReconciler reconciles a ClusterVersion object
-type ClusterVersionReconciler struct {
-	client.Client
-	OperatorDeployment *appsv1.Deployment
-	OperatorNamespace  string
-	ConsolePort        int32
-	Scheme             *runtime.Scheme
-
-	log               logr.Logger
-	ctx               context.Context
-	consoleDeployment *appsv1.Deployment
-	cephFSDeployment  *appsv1.Deployment
-	cephFSDaemonSet   *appsv1.DaemonSet
-	rbdDeployment     *appsv1.Deployment
-	rbdDaemonSet      *appsv1.DaemonSet
-	scc               *secv1.SecurityContextConstraints
-}
-
-// SetupWithManager sets up the controller with the Manager.
-func (c *ClusterVersionReconciler) SetupWithManager(mgr ctrl.Manager) error {
-	clusterVersionPredicates := builder.WithPredicates(
-		predicate.GenerationChangedPredicate{},
-	)
-
-	configMapPredicates := builder.WithPredicates(
-		predicate.NewPredicateFuncs(
-			func(client client.Object) bool {
-				namespace := client.GetNamespace()
-				name := client.GetName()
-				return ((namespace == c.OperatorNamespace) && (name == operatorConfigMapName))
-			},
-		),
-	)
-	// Reconcile the ClusterVersion object when the operator config map is updated
-	enqueueClusterVersionRequest := handler.EnqueueRequestsFromMapFunc(
-		func(_ context.Context, _ client.Object) []reconcile.Request {
-			return []reconcile.Request{{
-				NamespacedName: types.NamespacedName{
-					Name: clusterVersionName,
-				},
-			}}
-		},
-	)
-
-	subscriptionPredicates := builder.WithPredicates(
-		predicate.NewPredicateFuncs(
-			func(client client.Object) bool {
-				return client.GetNamespace() == c.OperatorNamespace
-			},
-		),
-		predicate.LabelChangedPredicate{},
-	)
-
-	webhookPredicates := builder.WithPredicates(
-		predicate.NewPredicateFuncs(
-			func(client client.Object) bool {
-				return client.GetName() == templates.SubscriptionWebhookName
-			},
-		),
-	)
-
-	return ctrl.NewControllerManagedBy(mgr).
-		For(&configv1.ClusterVersion{}, clusterVersionPredicates).
-		Watches(&corev1.ConfigMap{}, enqueueClusterVersionRequest, configMapPredicates).
-		Watches(&extv1.CustomResourceDefinition{}, enqueueClusterVersionRequest, builder.OnlyMetadata).
-		Watches(&opv1a1.Subscription{}, enqueueClusterVersionRequest, subscriptionPredicates).
-		Watches(&admrv1.ValidatingWebhookConfiguration{}, enqueueClusterVersionRequest, webhookPredicates).
-		Complete(c)
-}
-
-//+kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions,verbs=get;list;watch
-//+kubebuilder:rbac:groups=config.openshift.io,resources=clusterversions,verbs=get;list;watch;create;update;patch;delete
-//+kubebuilder:rbac:groups=config.openshift.io,resources=clusterversions/status,verbs=get;update;patch
-//+kubebuilder:rbac:groups=config.openshift.io,resources=clusterversions/finalizers,verbs=update
-//+kubebuilder:rbac:groups="apps",resources=deployments,verbs=get;list;watch;create;update;patch;delete
-//+kubebuilder:rbac:groups="apps",resources=deployments/finalizers,verbs=update
-//+kubebuilder:rbac:groups="apps",resources=daemonsets,verbs=get;list;watch;create;update;patch;delete
-//+kubebuilder:rbac:groups="apps",resources=daemonsets/finalizers,verbs=update
-//+kubebuilder:rbac:groups="storage.k8s.io",resources=csidrivers,verbs=get;list;watch;create;update;patch;delete
-//+kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch;create;update;delete
-//+kubebuilder:rbac:groups=security.openshift.io,resources=securitycontextconstraints,verbs=get;list;watch;create;patch;update
-//+kubebuilder:rbac:groups=monitoring.coreos.com,resources=prometheusrules,verbs=get;list;watch;create;update
-//+kubebuilder:rbac:groups="",resources=services,verbs=get;list;watch;create;update;patch;delete
-//+kubebuilder:rbac:groups=console.openshift.io,resources=consoleplugins,verbs=*
-//+kubebuilder:rbac:groups=operators.coreos.com,resources=subscriptions,verbs=get;list;watch;update
-//+kubebuilder:rbac:groups=admissionregistration.k8s.io,resources=validatingwebhookconfigurations,verbs=get;list;update;create;watch
-
-// For more details, check Reconcile and its Result here:
-// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.8.3/pkg/reconcile
-func (c *ClusterVersionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
-	c.ctx = ctx
-	c.log = log.FromContext(ctx, "ClusterVersion", req)
-	c.log.Info("Reconciling ClusterVersion")
-
-	if err := c.reconcileSubscriptionValidatingWebhook(); err != nil {
-		c.log.Error(err, "unable to register subscription validating webhook")
-		return ctrl.Result{}, err
-	}
-
-	if err := labelClientOperatorSubscription(c); err != nil {
-		c.log.Error(err, "unable to label ocs client operator subscription")
-		return ctrl.Result{}, err
-	}
-
-	if err := c.ensureConsolePlugin(); err != nil {
-		c.log.Error(err, "unable to deploy client console")
-		return ctrl.Result{}, err
-	}
-
-	if deployCSI, err := c.getDeployCSIConfig(); err != nil {
-		c.log.Error(err, "failed to perform precheck for deploying CSI")
-		return ctrl.Result{}, err
-	} else if deployCSI {
-		instance := configv1.ClusterVersion{}
-		if err = c.Client.Get(context.TODO(), req.NamespacedName, &instance); err != nil {
-			return ctrl.Result{}, err
-		}
-
-		if err := csi.InitializeSidecars(c.log, instance.Status.Desired.Version); err != nil {
-			c.log.Error(err, "unable to initialize sidecars")
-			return ctrl.Result{}, err
-		}
-
-		c.scc = &secv1.SecurityContextConstraints{
-			ObjectMeta: metav1.ObjectMeta{
-				Name: csi.SCCName,
-			},
-		}
-		err = c.createOrUpdate(c.scc, func() error {
-			// TODO: this is a hack to preserve the resourceVersion of the SCC
-			resourceVersion := c.scc.ResourceVersion
-			csi.SetSecurityContextConstraintsDesiredState(c.scc, c.OperatorNamespace)
-			c.scc.ResourceVersion = resourceVersion
-			return nil
-		})
-		if err != nil {
-			c.log.Error(err, "unable to create/update SCC")
-			return ctrl.Result{}, err
-		}
-
-		// create the monitor configmap for the csi drivers but never updates it.
-		// This is because the monitor configurations are added to the configmap
-		// when user creates storageclassclaims.
-		monConfigMap := &corev1.ConfigMap{
-			ObjectMeta: metav1.ObjectMeta{
-				Name:      templates.MonConfigMapName,
-				Namespace: c.OperatorNamespace,
-			},
-			Data: map[string]string{
-				"config.json": "[]",
-			},
-		}
-		if err := c.own(monConfigMap); err != nil {
-			return ctrl.Result{}, err
-		}
-		err = c.create(monConfigMap)
-		if err != nil && !kerrors.IsAlreadyExists(err) {
-			c.log.Error(err, "failed to create monitor configmap", "name", monConfigMap.Name)
-			return ctrl.Result{}, err
-		}
-
-		// create the encryption configmap for the csi driver but never updates it.
-		// This is because the encryption configuration are added to the configmap
-		// by the users before they create the encryption storageclassclaims.
-		encConfigMap := &corev1.ConfigMap{
-			ObjectMeta: metav1.ObjectMeta{
-				Name:      templates.EncryptionConfigMapName,
-				Namespace: c.OperatorNamespace,
-			},
-			Data: map[string]string{
-				"config.json": "[]",
-			},
-		}
-		if err := c.own(encConfigMap); err != nil {
-			return ctrl.Result{}, err
-		}
-		err = c.create(encConfigMap)
-		if err != nil && !kerrors.IsAlreadyExists(err) {
-			c.log.Error(err, "failed to create monitor configmap", "name", encConfigMap.Name)
-			return ctrl.Result{}, err
-		}
-
-		c.cephFSDeployment = &appsv1.Deployment{
-			ObjectMeta: metav1.ObjectMeta{
-				Name:      csi.CephFSDeploymentName,
-				Namespace: c.OperatorNamespace,
-			},
-		}
-		err = c.createOrUpdate(c.cephFSDeployment, func() error {
-			if err := c.own(c.cephFSDeployment); err != nil {
-				return err
-			}
-			csi.SetCephFSDeploymentDesiredState(c.cephFSDeployment)
-			return nil
-		})
-		if err != nil {
-			c.log.Error(err, "failed to create/update cephfs deployment")
-			return ctrl.Result{}, err
-		}
-
-		c.cephFSDaemonSet = &appsv1.DaemonSet{
-			ObjectMeta: metav1.ObjectMeta{
-				Name:      csi.CephFSDaemonSetName,
-				Namespace: c.OperatorNamespace,
-			},
-		}
-		err = c.createOrUpdate(c.cephFSDaemonSet, func() error {
-			if err := c.own(c.cephFSDaemonSet); err != nil {
-				return err
-			}
-			csi.SetCephFSDaemonSetDesiredState(c.cephFSDaemonSet)
-			return nil
-		})
-		if err != nil {
-			c.log.Error(err, "failed to create/update cephfs daemonset")
-			return ctrl.Result{}, err
-		}
-
-		c.rbdDeployment = &appsv1.Deployment{
-			ObjectMeta: metav1.ObjectMeta{
-				Name:      csi.RBDDeploymentName,
-				Namespace: c.OperatorNamespace,
-			},
-		}
-		err = c.createOrUpdate(c.rbdDeployment, func() error {
-			if err := c.own(c.rbdDeployment); err != nil {
-				return err
-			}
-			csi.SetRBDDeploymentDesiredState(c.rbdDeployment)
-			return nil
-		})
-		if err != nil {
-			c.log.Error(err, "failed to create/update rbd deployment")
-			return ctrl.Result{}, err
-		}
-
-		c.rbdDaemonSet = &appsv1.DaemonSet{
-			ObjectMeta: metav1.ObjectMeta{
-				Name:      csi.RBDDaemonSetName,
-				Namespace: c.OperatorNamespace,
-			},
-		}
-		err = c.createOrUpdate(c.rbdDaemonSet, func() error {
-			if err := c.own(c.rbdDaemonSet); err != nil {
-				return err
-			}
-			csi.SetRBDDaemonSetDesiredState(c.rbdDaemonSet)
-			return nil
-		})
-		if err != nil {
-			c.log.Error(err, "failed to create/update rbd daemonset")
-			return ctrl.Result{}, err
-		}
-
-		// Need to handle deletion of the csiDriver object, we cannot set
-		// ownerReference on it as its cluster scoped resource
-		cephfsCSIDriver := templates.CephFSCSIDriver.DeepCopy()
-		cephfsCSIDriver.ObjectMeta.Name = csi.GetCephFSDriverName()
-		err = csi.CreateCSIDriver(c.ctx, c.Client, cephfsCSIDriver)
-		if err != nil {
-			c.log.Error(err, "unable to create cephfs CSIDriver")
-			return ctrl.Result{}, err
-		}
-
-		rbdCSIDriver := templates.RbdCSIDriver.DeepCopy()
-		rbdCSIDriver.ObjectMeta.Name = csi.GetRBDDriverName()
-		err = csi.CreateCSIDriver(c.ctx, c.Client, rbdCSIDriver)
-		if err != nil {
-			c.log.Error(err, "unable to create rbd CSIDriver")
-			return ctrl.Result{}, err
-		}
-
-		prometheusRule := &monitoringv1.PrometheusRule{}
-		err = k8sYAML.NewYAMLOrJSONDecoder(bytes.NewBufferString(string(pvcPrometheusRules)), 1000).Decode(prometheusRule)
-		if err != nil {
-			c.log.Error(err, "Unable to retrieve prometheus rules.", "prometheusRule", klog.KRef(prometheusRule.Namespace, prometheusRule.Name))
-			return ctrl.Result{}, err
-		}
-
-		operatorConfig, err := c.getOperatorConfig()
-		if err != nil {
-			return ctrl.Result{}, err
-		}
-		prometheusRule.SetNamespace(c.OperatorNamespace)
-
-		err = c.createOrUpdate(prometheusRule, func() error {
-			applyLabels(operatorConfig.Data["OCS_METRICS_LABELS"], &prometheusRule.ObjectMeta)
-			return c.own(prometheusRule)
-		})
-		if err != nil {
-			c.log.Error(err, "failed to create/update prometheus rules")
-			return ctrl.Result{}, err
-		}
-
-		c.log.Info("prometheus rules deployed", "prometheusRule", klog.KRef(prometheusRule.Namespace, prometheusRule.Name))
-	}
-
-	return ctrl.Result{}, nil
-}
-
-func (c *ClusterVersionReconciler) createOrUpdate(obj client.Object, f controllerutil.MutateFn) error {
-	result, err := controllerutil.CreateOrUpdate(c.ctx, c.Client, obj, f)
-	if err != nil {
-		return err
-	}
-	c.log.Info("successfully created or updated", "operation", result, "name", obj.GetName())
-	return nil
-}
-
-func (c *ClusterVersionReconciler) own(obj client.Object) error {
-	return controllerutil.SetControllerReference(c.OperatorDeployment, obj, c.Client.Scheme())
-}
-
-func (c *ClusterVersionReconciler) create(obj client.Object) error {
-	return c.Client.Create(c.ctx, obj)
-}
-
-// applyLabels adds labels to object meta, overwriting keys that are already defined.
-func applyLabels(label string, t *metav1.ObjectMeta) {
-	// Create a map to store the configuration
-	promLabel := make(map[string]string)
-
-	labels := strings.Split(label, "\n")
-	// Loop through the lines and extract key-value pairs
-	for _, line := range labels {
-		if len(line) == 0 {
-			continue
-		}
-		parts := strings.SplitN(line, ":", 2)
-		key := strings.TrimSpace(parts[0])
-		value := strings.TrimSpace(parts[1])
-		promLabel[key] = value
-	}
-
-	t.Labels = promLabel
-}
-
-func (c *ClusterVersionReconciler) getOperatorConfig() (*corev1.ConfigMap, error) {
-	cm := &corev1.ConfigMap{}
-	err := c.Client.Get(c.ctx, types.NamespacedName{Name: operatorConfigMapName, Namespace: c.OperatorNamespace}, cm)
-	if err != nil && !kerrors.IsNotFound(err) {
-		return nil, err
-	}
-	return cm, nil
-}
-
-func (c *ClusterVersionReconciler) ensureConsolePlugin() error {
-	c.consoleDeployment = &appsv1.Deployment{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      console.DeploymentName,
-			Namespace: c.OperatorNamespace,
-		},
-	}
-
-	err := c.Client.Get(c.ctx, types.NamespacedName{
-		Name:      console.DeploymentName,
-		Namespace: c.OperatorNamespace,
-	}, c.consoleDeployment)
-	if err != nil {
-		c.log.Error(err, "failed to get the deployment for the console")
-		return err
-	}
-
-	nginxConf := console.GetNginxConf()
-	nginxConfigMap := &corev1.ConfigMap{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      console.NginxConfigMapName,
-			Namespace: c.OperatorNamespace,
-		},
-		Data: map[string]string{
-			"nginx.conf": nginxConf,
-		},
-	}
-	err = c.createOrUpdate(nginxConfigMap, func() error {
-		if consoleConfigMapData := nginxConfigMap.Data["nginx.conf"]; consoleConfigMapData != nginxConf {
-			nginxConfigMap.Data["nginx.conf"] = nginxConf
-		}
-		return controllerutil.SetControllerReference(c.consoleDeployment, nginxConfigMap, c.Scheme)
-	})
-
-	if err != nil {
-		c.log.Error(err, "failed to create nginx config map")
-		return err
-	}
-
-	consoleService := console.GetService(c.ConsolePort, c.OperatorNamespace)
-
-	err = c.createOrUpdate(consoleService, func() error {
-		if err := controllerutil.SetControllerReference(c.consoleDeployment, consoleService, c.Scheme); err != nil {
-			return err
-		}
-		console.GetService(c.ConsolePort, c.OperatorNamespace).DeepCopyInto(consoleService)
-		return nil
-	})
-
-	if err != nil {
-		c.log.Error(err, "failed to create/update service for console")
-		return err
-	}
-
-	consolePlugin := console.GetConsolePlugin(c.ConsolePort, c.OperatorNamespace)
-	err = c.createOrUpdate(consolePlugin, func() error {
-		// preserve the resourceVersion of the consolePlugin
-		resourceVersion := consolePlugin.ResourceVersion
-		console.GetConsolePlugin(c.ConsolePort, c.OperatorNamespace).DeepCopyInto(consolePlugin)
-		consolePlugin.ResourceVersion = resourceVersion
-		return nil
-	})
-
-	if err != nil {
-		c.log.Error(err, "failed to create/update consoleplugin")
-		return err
-	}
-
-	return nil
-}
-
-func (c *ClusterVersionReconciler) getDeployCSIConfig() (bool, error) {
-	operatorConfig := &corev1.ConfigMap{}
-	operatorConfig.Name = operatorConfigMapName
-	operatorConfig.Namespace = c.OperatorNamespace
-	if err := c.get(operatorConfig); err != nil {
-		return false, fmt.Errorf("failed to get operator configmap: %v", err)
-	}
-
-	data := operatorConfig.Data
-	if data == nil {
-		data = map[string]string{}
-	}
-
-	var deployCSI bool
-	var err error
-	if value, ok := data[deployCSIKey]; ok {
-		deployCSI, err = strconv.ParseBool(value)
-		if err != nil {
-			return false, fmt.Errorf("failed to parse value for %q in operator configmap as a boolean: %v", deployCSIKey, err)
-		}
-	} else {
-		// CSI installation is not specified explicitly in the configmap and
-		// behaviour is different in case we recognize the StorageCluster API on the cluster.
-		storageClusterCRD := &metav1.PartialObjectMetadata{}
-		storageClusterCRD.SetGroupVersionKind(
-			extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"),
-		)
-		storageClusterCRD.Name = "storageclusters.ocs.openshift.io"
-		if err = c.get(storageClusterCRD); err != nil {
-			if !kerrors.IsNotFound(err) {
-				return false, fmt.Errorf("failed to verify existence of storagecluster crd: %v", err)
-			}
-			// storagecluster CRD doesn't exist
-			deployCSI = true
-		} else {
-			// storagecluster CRD exists and don't deploy CSI until explicitly mentioned in the configmap
-			deployCSI = false
-		}
-	}
-
-	return deployCSI, nil
-}
-
-func (c *ClusterVersionReconciler) get(obj client.Object, opts ...client.GetOption) error {
-	return c.Get(c.ctx, client.ObjectKeyFromObject(obj), obj, opts...)
-}
-
-func (c *ClusterVersionReconciler) reconcileSubscriptionValidatingWebhook() error {
-	whConfig := &admrv1.ValidatingWebhookConfiguration{}
-	whConfig.Name = templates.SubscriptionWebhookName
-
-	// TODO (lgangava): after change to configmap controller, need to remove webhook during deletion
-	err := c.createOrUpdate(whConfig, func() error {
-
-		// openshift fills in the ca on finding this annotation
-		whConfig.Annotations = map[string]string{
-			"service.beta.openshift.io/inject-cabundle": "true",
-		}
-
-		var caBundle []byte
-		if len(whConfig.Webhooks) == 0 {
-			whConfig.Webhooks = make([]admrv1.ValidatingWebhook, 1)
-		} else {
-			// do not mutate CA bundle that was injected by openshift
-			caBundle = whConfig.Webhooks[0].ClientConfig.CABundle
-		}
-
-		// webhook desired state
-		var wh *admrv1.ValidatingWebhook = &whConfig.Webhooks[0]
-		templates.SubscriptionValidatingWebhook.DeepCopyInto(wh)
-
-		wh.Name = whConfig.Name
-		// only send requests received from own namespace
-		wh.NamespaceSelector = &metav1.LabelSelector{
-			MatchLabels: map[string]string{
-				"kubernetes.io/metadata.name": c.OperatorNamespace,
-			},
-		}
-		// only send resources matching the label
-		wh.ObjectSelector = &metav1.LabelSelector{
-			MatchLabels: map[string]string{
-				subscriptionLabelKey: subscriptionLabelValue,
-			},
-		}
-		// preserve the existing (injected) CA bundle if any
-		wh.ClientConfig.CABundle = caBundle
-		// send request to the service running in own namespace
-		wh.ClientConfig.Service.Namespace = c.OperatorNamespace
-
-		return nil
-	})
-
-	if err != nil {
-		return err
-	}
-
-	c.log.Info("successfully registered validating webhook")
-	return nil
-}
-
-func labelClientOperatorSubscription(c *ClusterVersionReconciler) error {
-	subscriptionList := &opv1a1.SubscriptionList{}
-	err := c.List(c.ctx, subscriptionList, client.InNamespace(c.OperatorNamespace))
-	if err != nil {
-		return fmt.Errorf("failed to list subscriptions")
-	}
-
-	sub := utils.Find(subscriptionList.Items, func(sub *opv1a1.Subscription) bool {
-		return sub.Spec.Package == "ocs-client-operator"
-	})
-
-	if sub == nil {
-		return fmt.Errorf("failed to find subscription with ocs-client-operator package")
-	}
-
-	if utils.AddLabel(sub, subscriptionLabelKey, subscriptionLabelValue) {
-		if err := c.Update(c.ctx, sub); err != nil {
-			return err
-		}
-	}
-
-	c.log.Info("successfully labelled ocs-client-operator subscription")
-	return nil
-}
diff --git a/controllers/operatorconfigmap_controller.go b/controllers/operatorconfigmap_controller.go
new file mode 100644
index 00000000..93f7c356
--- /dev/null
+++ b/controllers/operatorconfigmap_controller.go
@@ -0,0 +1,770 @@
+/*
+Copyright 2023 Red Hat OpenShift Data Foundation.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package controllers
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"strconv"
+	"strings"
+
+	// The embed package is required for the prometheus rule files
+	_ "embed"
+
+	"github.com/red-hat-storage/ocs-client-operator/api/v1alpha1"
+	"github.com/red-hat-storage/ocs-client-operator/pkg/console"
+	"github.com/red-hat-storage/ocs-client-operator/pkg/csi"
+	"github.com/red-hat-storage/ocs-client-operator/pkg/templates"
+	"github.com/red-hat-storage/ocs-client-operator/pkg/utils"
+
+	"github.com/go-logr/logr"
+	configv1 "github.com/openshift/api/config/v1"
+	secv1 "github.com/openshift/api/security/v1"
+	opv1a1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
+	monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
+	admrv1 "k8s.io/api/admissionregistration/v1"
+	appsv1 "k8s.io/api/apps/v1"
+	corev1 "k8s.io/api/core/v1"
+	extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
+	kerrors "k8s.io/apimachinery/pkg/api/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/apimachinery/pkg/types"
+	k8sYAML "k8s.io/apimachinery/pkg/util/yaml"
+	"k8s.io/klog/v2"
+	ctrl "sigs.k8s.io/controller-runtime"
+	"sigs.k8s.io/controller-runtime/pkg/builder"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
+	"sigs.k8s.io/controller-runtime/pkg/handler"
+	"sigs.k8s.io/controller-runtime/pkg/log"
+	"sigs.k8s.io/controller-runtime/pkg/predicate"
+	"sigs.k8s.io/controller-runtime/pkg/reconcile"
+)
+
+//go:embed pvc-rules.yaml
+var pvcPrometheusRules string
+
+const (
+	operatorConfigMapName = "ocs-client-operator-config"
+	// ClusterVersionName is the name of the ClusterVersion object in the
+	// openshift cluster.
+	clusterVersionName     = "version"
+	deployCSIKey           = "DEPLOY_CSI"
+	subscriptionLabelKey   = "managed-by"
+	subscriptionLabelValue = "webhook.subscription.ocs.openshift.io"
+
+	operatorConfigMapFinalizer = "ocs-client-operator.ocs.openshift.io/storageused"
+)
+
+// OperatorConfigMapReconciler reconciles a ClusterVersion object
+type OperatorConfigMapReconciler struct {
+	client.Client
+	OperatorNamespace string
+	ConsolePort       int32
+	Scheme            *runtime.Scheme
+
+	log               logr.Logger
+	ctx               context.Context
+	operatorConfigMap *corev1.ConfigMap
+	consoleDeployment *appsv1.Deployment
+	cephFSDeployment  *appsv1.Deployment
+	cephFSDaemonSet   *appsv1.DaemonSet
+	rbdDeployment     *appsv1.Deployment
+	rbdDaemonSet      *appsv1.DaemonSet
+	scc               *secv1.SecurityContextConstraints
+}
+
+// SetupWithManager sets up the controller with the Manager.
+func (c *OperatorConfigMapReconciler) SetupWithManager(mgr ctrl.Manager) error {
+	clusterVersionPredicates := builder.WithPredicates(
+		predicate.GenerationChangedPredicate{},
+	)
+
+	configMapPredicates := builder.WithPredicates(
+		predicate.NewPredicateFuncs(
+			func(client client.Object) bool {
+				namespace := client.GetNamespace()
+				name := client.GetName()
+				return ((namespace == c.OperatorNamespace) && (name == operatorConfigMapName))
+			},
+		),
+	)
+	// Reconcile the OperatorConfigMap object when the cluster's version object is updated
+	enqueueConfigMapRequest := handler.EnqueueRequestsFromMapFunc(
+		func(_ context.Context, _ client.Object) []reconcile.Request {
+			return []reconcile.Request{{
+				NamespacedName: types.NamespacedName{
+					Name:      operatorConfigMapName,
+					Namespace: c.OperatorNamespace,
+				},
+			}}
+		},
+	)
+
+	subscriptionPredicates := builder.WithPredicates(
+		predicate.NewPredicateFuncs(
+			func(client client.Object) bool {
+				return client.GetNamespace() == c.OperatorNamespace
+			},
+		),
+		predicate.LabelChangedPredicate{},
+	)
+
+	webhookPredicates := builder.WithPredicates(
+		predicate.NewPredicateFuncs(
+			func(client client.Object) bool {
+				return client.GetName() == templates.SubscriptionWebhookName
+			},
+		),
+	)
+
+	servicePredicate := builder.WithPredicates(
+		predicate.NewPredicateFuncs(
+			func(obj client.Object) bool {
+				return obj.GetNamespace() == c.OperatorNamespace && obj.GetName() == templates.WebhookServiceName
+			},
+		),
+	)
+
+	return ctrl.NewControllerManagedBy(mgr).
+		For(&corev1.ConfigMap{}, configMapPredicates).
+		Owns(&corev1.Service{}, servicePredicate).
+		Watches(&configv1.ClusterVersion{}, enqueueConfigMapRequest, clusterVersionPredicates).
+		Watches(&extv1.CustomResourceDefinition{}, enqueueConfigMapRequest, builder.OnlyMetadata).
+		Watches(&opv1a1.Subscription{}, enqueueConfigMapRequest, subscriptionPredicates).
+		Watches(&admrv1.ValidatingWebhookConfiguration{}, enqueueConfigMapRequest, webhookPredicates).
+		Watches(&v1alpha1.StorageClient{}, enqueueConfigMapRequest, builder.WithPredicates(predicate.AnnotationChangedPredicate{})).
+		Complete(c)
+}
+
+//+kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions,verbs=get;list;watch
+//+kubebuilder:rbac:groups=config.openshift.io,resources=clusterversions,verbs=get;list;watch
+//+kubebuilder:rbac:groups="apps",resources=deployments,verbs=get;list;watch;create;update;patch;delete
+//+kubebuilder:rbac:groups="apps",resources=deployments/finalizers,verbs=update
+//+kubebuilder:rbac:groups="apps",resources=daemonsets,verbs=get;list;watch;create;update;patch;delete
+//+kubebuilder:rbac:groups="apps",resources=daemonsets/finalizers,verbs=update
+//+kubebuilder:rbac:groups="storage.k8s.io",resources=csidrivers,verbs=get;list;watch;create;update;patch;delete
+//+kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch;create;update;delete
+//+kubebuilder:rbac:groups="",resources=configmaps/finalizers,verbs=update
+//+kubebuilder:rbac:groups=security.openshift.io,resources=securitycontextconstraints,verbs=get;list;watch;create;patch;update;delete
+//+kubebuilder:rbac:groups=monitoring.coreos.com,resources=prometheusrules,verbs=get;list;watch;create;update
+//+kubebuilder:rbac:groups="",resources=services,verbs=get;list;watch;create;update;patch;delete
+//+kubebuilder:rbac:groups=console.openshift.io,resources=consoleplugins,verbs=*
+//+kubebuilder:rbac:groups=operators.coreos.com,resources=subscriptions,verbs=get;list;watch;update
+//+kubebuilder:rbac:groups=admissionregistration.k8s.io,resources=validatingwebhookconfigurations,verbs=get;list;update;create;watch;delete
+
+// For more details, check Reconcile and its Result here:
+// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.8.3/pkg/reconcile
+func (c *OperatorConfigMapReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
+	c.ctx = ctx
+	c.log = log.FromContext(ctx, "OperatorConfigMap", req)
+	c.log.Info("Reconciling OperatorConfigMap")
+
+	c.operatorConfigMap = &corev1.ConfigMap{}
+	c.operatorConfigMap.Name = req.Name
+	c.operatorConfigMap.Namespace = req.Namespace
+	if err := c.get(c.operatorConfigMap); err != nil {
+		if kerrors.IsNotFound(err) {
+			c.log.Info("Operator ConfigMap resource not found. Ignoring since object might be deleted.")
+			return reconcile.Result{}, nil
+		}
+		c.log.Error(err, "failed to get the operator's configMap")
+		return reconcile.Result{}, err
+	}
+
+	if c.operatorConfigMap.GetDeletionTimestamp().IsZero() {
+
+		//ensure finalizer
+		if controllerutil.AddFinalizer(c.operatorConfigMap, operatorConfigMapFinalizer) {
+			c.log.Info("finalizer missing on the operatorConfigMap resource, adding...")
+			if err := c.Client.Update(c.ctx, c.operatorConfigMap); err != nil {
+				return ctrl.Result{}, err
+			}
+		}
+
+		if err := c.reconcileWebhookService(); err != nil {
+			c.log.Error(err, "unable to reconcile webhook service")
+			return ctrl.Result{}, err
+		}
+
+		if err := c.reconcileSubscriptionValidatingWebhook(); err != nil {
+			c.log.Error(err, "unable to register subscription validating webhook")
+			return ctrl.Result{}, err
+		}
+
+		if err := c.reconcileClientOperatorSubscriptionLabel(); err != nil {
+			c.log.Error(err, "unable to label ocs client operator subscription")
+			return ctrl.Result{}, err
+		}
+
+		if err := c.reconcileSubscription(); err != nil {
+			c.log.Error(err, "unable to reconcile subscription")
+			return ctrl.Result{}, err
+		}
+
+		if err := c.ensureConsolePlugin(); err != nil {
+			c.log.Error(err, "unable to deploy client console")
+			return ctrl.Result{}, err
+		}
+
+		if deployCSI, err := c.getDeployCSIConfig(); err != nil {
+			c.log.Error(err, "failed to perform precheck for deploying CSI")
+			return ctrl.Result{}, err
+		} else if deployCSI {
+			clusterVersion := &configv1.ClusterVersion{}
+			clusterVersion.Name = clusterVersionName
+			if err := c.get(clusterVersion); err != nil {
+				c.log.Error(err, "failed to get the clusterVersion version of the OCP cluster")
+				return reconcile.Result{}, err
+			}
+
+			if err := csi.InitializeSidecars(c.log, clusterVersion.Status.Desired.Version); err != nil {
+				c.log.Error(err, "unable to initialize sidecars")
+				return ctrl.Result{}, err
+			}
+
+			c.scc = &secv1.SecurityContextConstraints{
+				ObjectMeta: metav1.ObjectMeta{
+					Name: csi.SCCName,
+				},
+			}
+			err = c.createOrUpdate(c.scc, func() error {
+				// TODO: this is a hack to preserve the resourceVersion of the SCC
+				resourceVersion := c.scc.ResourceVersion
+				csi.SetSecurityContextConstraintsDesiredState(c.scc, c.OperatorNamespace)
+				c.scc.ResourceVersion = resourceVersion
+				return nil
+			})
+			if err != nil {
+				c.log.Error(err, "unable to create/update SCC")
+				return ctrl.Result{}, err
+			}
+
+			// create the monitor configmap for the csi drivers but never updates it.
+			// This is because the monitor configurations are added to the configmap
+			// when user creates storageclassclaims.
+			monConfigMap := &corev1.ConfigMap{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      templates.MonConfigMapName,
+					Namespace: c.OperatorNamespace,
+				},
+				Data: map[string]string{
+					"config.json": "[]",
+				},
+			}
+			if err := c.own(monConfigMap); err != nil {
+				return ctrl.Result{}, err
+			}
+
+			if err := c.create(monConfigMap); err != nil && !kerrors.IsAlreadyExists(err) {
+				c.log.Error(err, "failed to create monitor configmap", "name", monConfigMap.Name)
+				return ctrl.Result{}, err
+			}
+
+			// create the encryption configmap for the csi driver but never updates it.
+			// This is because the encryption configuration are added to the configmap
+			// by the users before they create the encryption storageclassclaims.
+			encConfigMap := &corev1.ConfigMap{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      templates.EncryptionConfigMapName,
+					Namespace: c.OperatorNamespace,
+				},
+				Data: map[string]string{
+					"config.json": "[]",
+				},
+			}
+			if err := c.own(encConfigMap); err != nil {
+				return ctrl.Result{}, err
+			}
+
+			if err := c.create(encConfigMap); err != nil && !kerrors.IsAlreadyExists(err) {
+				c.log.Error(err, "failed to create monitor configmap", "name", encConfigMap.Name)
+				return ctrl.Result{}, err
+			}
+
+			c.cephFSDeployment = &appsv1.Deployment{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      csi.CephFSDeploymentName,
+					Namespace: c.OperatorNamespace,
+				},
+			}
+			err = c.createOrUpdate(c.cephFSDeployment, func() error {
+				if err := c.own(c.cephFSDeployment); err != nil {
+					return err
+				}
+				csi.SetCephFSDeploymentDesiredState(c.cephFSDeployment)
+				return nil
+			})
+			if err != nil {
+				c.log.Error(err, "failed to create/update cephfs deployment")
+				return ctrl.Result{}, err
+			}
+
+			c.cephFSDaemonSet = &appsv1.DaemonSet{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      csi.CephFSDaemonSetName,
+					Namespace: c.OperatorNamespace,
+				},
+			}
+			err = c.createOrUpdate(c.cephFSDaemonSet, func() error {
+				if err := c.own(c.cephFSDaemonSet); err != nil {
+					return err
+				}
+				csi.SetCephFSDaemonSetDesiredState(c.cephFSDaemonSet)
+				return nil
+			})
+			if err != nil {
+				c.log.Error(err, "failed to create/update cephfs daemonset")
+				return ctrl.Result{}, err
+			}
+
+			c.rbdDeployment = &appsv1.Deployment{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      csi.RBDDeploymentName,
+					Namespace: c.OperatorNamespace,
+				},
+			}
+			err = c.createOrUpdate(c.rbdDeployment, func() error {
+				if err := c.own(c.rbdDeployment); err != nil {
+					return err
+				}
+				csi.SetRBDDeploymentDesiredState(c.rbdDeployment)
+				return nil
+			})
+			if err != nil {
+				c.log.Error(err, "failed to create/update rbd deployment")
+				return ctrl.Result{}, err
+			}
+
+			c.rbdDaemonSet = &appsv1.DaemonSet{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      csi.RBDDaemonSetName,
+					Namespace: c.OperatorNamespace,
+				},
+			}
+			err = c.createOrUpdate(c.rbdDaemonSet, func() error {
+				if err := c.own(c.rbdDaemonSet); err != nil {
+					return err
+				}
+				csi.SetRBDDaemonSetDesiredState(c.rbdDaemonSet)
+				return nil
+			})
+			if err != nil {
+				c.log.Error(err, "failed to create/update rbd daemonset")
+				return ctrl.Result{}, err
+			}
+
+			// Need to handle deletion of the csiDriver object, we cannot set
+			// ownerReference on it as its cluster scoped resource
+			cephfsCSIDriver := templates.CephFSCSIDriver.DeepCopy()
+			cephfsCSIDriver.ObjectMeta.Name = csi.GetCephFSDriverName()
+			if err := csi.CreateCSIDriver(c.ctx, c.Client, cephfsCSIDriver); err != nil {
+				c.log.Error(err, "unable to create cephfs CSIDriver")
+				return ctrl.Result{}, err
+			}
+
+			rbdCSIDriver := templates.RbdCSIDriver.DeepCopy()
+			rbdCSIDriver.ObjectMeta.Name = csi.GetRBDDriverName()
+			if err := csi.CreateCSIDriver(c.ctx, c.Client, rbdCSIDriver); err != nil {
+				c.log.Error(err, "unable to create rbd CSIDriver")
+				return ctrl.Result{}, err
+			}
+
+			prometheusRule := &monitoringv1.PrometheusRule{}
+			if err := k8sYAML.NewYAMLOrJSONDecoder(bytes.NewBufferString(string(pvcPrometheusRules)), 1000).Decode(prometheusRule); err != nil {
+				c.log.Error(err, "Unable to retrieve prometheus rules.", "prometheusRule", klog.KRef(prometheusRule.Namespace, prometheusRule.Name))
+				return ctrl.Result{}, err
+			}
+
+			prometheusRule.SetNamespace(c.OperatorNamespace)
+
+			err = c.createOrUpdate(prometheusRule, func() error {
+				applyLabels(c.operatorConfigMap.Data["OCS_METRICS_LABELS"], &prometheusRule.ObjectMeta)
+				return c.own(prometheusRule)
+			})
+			if err != nil {
+				c.log.Error(err, "failed to create/update prometheus rules")
+				return ctrl.Result{}, err
+			}
+
+			c.log.Info("prometheus rules deployed", "prometheusRule", klog.KRef(prometheusRule.Namespace, prometheusRule.Name))
+		}
+	} else {
+		// deletion phase
+		if err := c.deletionPhase(); err != nil {
+			return ctrl.Result{}, err
+		}
+
+		//remove finalizer
+		if controllerutil.RemoveFinalizer(c.operatorConfigMap, operatorConfigMapFinalizer) {
+			if err := c.Client.Update(c.ctx, c.operatorConfigMap); err != nil {
+				return ctrl.Result{}, err
+			}
+			c.log.Info("finallizer removed successfully")
+		}
+	}
+	return ctrl.Result{}, nil
+}
+
+func (c *OperatorConfigMapReconciler) deletionPhase() error {
+	claimsList := &v1alpha1.StorageClaimList{}
+	if err := c.list(claimsList, client.Limit(1)); err != nil {
+		c.log.Error(err, "unable to verify StorageClaims presence prior to removal of CSI resources")
+		return err
+	} else if len(claimsList.Items) != 0 {
+		err = fmt.Errorf("failed to clean up resources: storage claims are present on the cluster")
+		c.log.Error(err, "Waiting for all storageClaims to be deleted.")
+		return err
+	}
+	if err := csi.DeleteCSIDriver(c.ctx, c.Client, csi.GetCephFSDriverName()); err != nil && !kerrors.IsNotFound(err) {
+		c.log.Error(err, "unable to delete cephfs CSIDriver")
+		return err
+	}
+	if err := csi.DeleteCSIDriver(c.ctx, c.Client, csi.GetRBDDriverName()); err != nil && !kerrors.IsNotFound(err) {
+		c.log.Error(err, "unable to delete rbd CSIDriver")
+		return err
+	}
+
+	c.scc = &secv1.SecurityContextConstraints{}
+	c.scc.Name = csi.SCCName
+	if err := c.delete(c.scc); err != nil {
+		c.log.Error(err, "unable to delete SCC")
+		return err
+	}
+
+	whConfig := &admrv1.ValidatingWebhookConfiguration{}
+	whConfig.Name = templates.SubscriptionWebhookName
+	if err := c.delete(whConfig); err != nil {
+		c.log.Error(err, "failed to delete subscription webhook")
+		return err
+	}
+
+	return nil
+}
+
+func (c *OperatorConfigMapReconciler) createOrUpdate(obj client.Object, f controllerutil.MutateFn) error {
+	result, err := controllerutil.CreateOrUpdate(c.ctx, c.Client, obj, f)
+	if err != nil {
+		return err
+	}
+	c.log.Info("successfully created or updated", "operation", result, "name", obj.GetName())
+	return nil
+}
+
+func (c *OperatorConfigMapReconciler) own(obj client.Object) error {
+	return controllerutil.SetControllerReference(c.operatorConfigMap, obj, c.Client.Scheme())
+}
+
+func (c *OperatorConfigMapReconciler) create(obj client.Object) error {
+	return c.Client.Create(c.ctx, obj)
+}
+
+// applyLabels adds labels to object meta, overwriting keys that are already defined.
+func applyLabels(label string, t *metav1.ObjectMeta) {
+	// Create a map to store the configuration
+	promLabel := make(map[string]string)
+
+	labels := strings.Split(label, "\n")
+	// Loop through the lines and extract key-value pairs
+	for _, line := range labels {
+		if len(line) == 0 {
+			continue
+		}
+		parts := strings.SplitN(line, ":", 2)
+		key := strings.TrimSpace(parts[0])
+		value := strings.TrimSpace(parts[1])
+		promLabel[key] = value
+	}
+
+	t.Labels = promLabel
+}
+
+func (c *OperatorConfigMapReconciler) ensureConsolePlugin() error {
+	c.consoleDeployment = &appsv1.Deployment{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      console.DeploymentName,
+			Namespace: c.OperatorNamespace,
+		},
+	}
+
+	err := c.get(c.consoleDeployment)
+	if err != nil {
+		c.log.Error(err, "failed to get the deployment for the console")
+		return err
+	}
+
+	nginxConf := console.GetNginxConf()
+	nginxConfigMap := &corev1.ConfigMap{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      console.NginxConfigMapName,
+			Namespace: c.OperatorNamespace,
+		},
+		Data: map[string]string{
+			"nginx.conf": nginxConf,
+		},
+	}
+	err = c.createOrUpdate(nginxConfigMap, func() error {
+		if consoleConfigMapData := nginxConfigMap.Data["nginx.conf"]; consoleConfigMapData != nginxConf {
+			nginxConfigMap.Data["nginx.conf"] = nginxConf
+		}
+		return controllerutil.SetControllerReference(c.consoleDeployment, nginxConfigMap, c.Scheme)
+	})
+
+	if err != nil {
+		c.log.Error(err, "failed to create nginx config map")
+		return err
+	}
+
+	consoleService := console.GetService(c.ConsolePort, c.OperatorNamespace)
+
+	err = c.createOrUpdate(consoleService, func() error {
+		if err := controllerutil.SetControllerReference(c.consoleDeployment, consoleService, c.Scheme); err != nil {
+			return err
+		}
+		console.GetService(c.ConsolePort, c.OperatorNamespace).DeepCopyInto(consoleService)
+		return nil
+	})
+
+	if err != nil {
+		c.log.Error(err, "failed to create/update service for console")
+		return err
+	}
+
+	consolePlugin := console.GetConsolePlugin(c.ConsolePort, c.OperatorNamespace)
+	err = c.createOrUpdate(consolePlugin, func() error {
+		// preserve the resourceVersion of the consolePlugin
+		resourceVersion := consolePlugin.ResourceVersion
+		console.GetConsolePlugin(c.ConsolePort, c.OperatorNamespace).DeepCopyInto(consolePlugin)
+		consolePlugin.ResourceVersion = resourceVersion
+		return nil
+	})
+
+	if err != nil {
+		c.log.Error(err, "failed to create/update consoleplugin")
+		return err
+	}
+
+	return nil
+}
+
+func (c *OperatorConfigMapReconciler) getDeployCSIConfig() (bool, error) {
+	data := c.operatorConfigMap.Data
+	if data == nil {
+		data = map[string]string{}
+	}
+
+	var deployCSI bool
+	var err error
+	if value, ok := data[deployCSIKey]; ok {
+		deployCSI, err = strconv.ParseBool(value)
+		if err != nil {
+			return false, fmt.Errorf("failed to parse value for %q in operator configmap as a boolean: %v", deployCSIKey, err)
+		}
+	} else {
+		// CSI installation is not specified explicitly in the configmap and
+		// behaviour is different in case we recognize the StorageCluster API on the cluster.
+		storageClusterCRD := &metav1.PartialObjectMetadata{}
+		storageClusterCRD.SetGroupVersionKind(
+			extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"),
+		)
+		storageClusterCRD.Name = "storageclusters.ocs.openshift.io"
+		if err = c.get(storageClusterCRD); err != nil {
+			if !kerrors.IsNotFound(err) {
+				return false, fmt.Errorf("failed to verify existence of storagecluster crd: %v", err)
+			}
+			// storagecluster CRD doesn't exist
+			deployCSI = true
+		} else {
+			// storagecluster CRD exists and don't deploy CSI until explicitly mentioned in the configmap
+			deployCSI = false
+		}
+	}
+
+	return deployCSI, nil
+}
+
+func (c *OperatorConfigMapReconciler) get(obj client.Object, opts ...client.GetOption) error {
+	return c.Get(c.ctx, client.ObjectKeyFromObject(obj), obj, opts...)
+}
+
+func (c *OperatorConfigMapReconciler) reconcileSubscriptionValidatingWebhook() error {
+	whConfig := &admrv1.ValidatingWebhookConfiguration{}
+	whConfig.Name = templates.SubscriptionWebhookName
+
+	// TODO (lgangava): after change to configmap controller, need to remove webhook during deletion
+	err := c.createOrUpdate(whConfig, func() error {
+
+		// openshift fills in the ca on finding this annotation
+		whConfig.Annotations = map[string]string{
+			"service.beta.openshift.io/inject-cabundle": "true",
+		}
+
+		var caBundle []byte
+		if len(whConfig.Webhooks) == 0 {
+			whConfig.Webhooks = make([]admrv1.ValidatingWebhook, 1)
+		} else {
+			// do not mutate CA bundle that was injected by openshift
+			caBundle = whConfig.Webhooks[0].ClientConfig.CABundle
+		}
+
+		// webhook desired state
+		var wh *admrv1.ValidatingWebhook = &whConfig.Webhooks[0]
+		templates.SubscriptionValidatingWebhook.DeepCopyInto(wh)
+
+		wh.Name = whConfig.Name
+		// only send requests received from own namespace
+		wh.NamespaceSelector = &metav1.LabelSelector{
+			MatchLabels: map[string]string{
+				"kubernetes.io/metadata.name": c.OperatorNamespace,
+			},
+		}
+		// only send resources matching the label
+		wh.ObjectSelector = &metav1.LabelSelector{
+			MatchLabels: map[string]string{
+				subscriptionLabelKey: subscriptionLabelValue,
+			},
+		}
+		// preserve the existing (injected) CA bundle if any
+		wh.ClientConfig.CABundle = caBundle
+		// send request to the service running in own namespace
+		wh.ClientConfig.Service.Namespace = c.OperatorNamespace
+
+		return nil
+	})
+
+	if err != nil {
+		return err
+	}
+
+	c.log.Info("successfully registered validating webhook")
+	return nil
+}
+
+func (c *OperatorConfigMapReconciler) reconcileClientOperatorSubscriptionLabel() error {
+	subscriptionList := &opv1a1.SubscriptionList{}
+	err := c.List(c.ctx, subscriptionList, client.InNamespace(c.OperatorNamespace))
+	if err != nil {
+		return fmt.Errorf("failed to list subscriptions")
+	}
+
+	sub := utils.Find(subscriptionList.Items, func(sub *opv1a1.Subscription) bool {
+		return sub.Spec.Package == "ocs-client-operator"
+	})
+
+	if sub == nil {
+		return fmt.Errorf("failed to find subscription with ocs-client-operator package")
+	}
+
+	if utils.AddLabel(sub, subscriptionLabelKey, subscriptionLabelValue) {
+		if err := c.Update(c.ctx, sub); err != nil {
+			return err
+		}
+	}
+
+	c.log.Info("successfully labelled ocs-client-operator subscription")
+	return nil
+}
+
+func (c *OperatorConfigMapReconciler) reconcileSubscription() error {
+
+	storageClients := &v1alpha1.StorageClientList{}
+	if err := c.list(storageClients); err != nil {
+		return fmt.Errorf("failed to list storageclients: %v", err)
+	}
+
+	var desiredChannel string
+	for idx := range storageClients.Items {
+		// empty if annotation doesn't exist or else gets desired channel
+		channel := storageClients.
+			Items[idx].
+			GetAnnotations()[utils.DesiredSubscriptionChannelAnnotationKey]
+		// skip clients with no/empty desired channel annotation
+		if channel != "" {
+			// check if we already established a desired channel
+			if desiredChannel == "" {
+				desiredChannel = channel
+			}
+			// check for agreement between clients
+			if channel != desiredChannel {
+				desiredChannel = ""
+				// two clients didn't agree for a same channel and no need to continue further
+				break
+			}
+		}
+	}
+
+	if desiredChannel != "" {
+		subscriptions := &opv1a1.SubscriptionList{}
+		err := c.list(
+			subscriptions,
+			client.InNamespace(c.OperatorNamespace),
+			client.MatchingLabels{subscriptionLabelKey: subscriptionLabelValue},
+			client.Limit(1),
+		)
+		if err != nil {
+			return fmt.Errorf("failed to list subscription for ocs-client-operator using labels: %v", err)
+		}
+
+		if len(subscriptions.Items) == 1 {
+			clientSubscription := &subscriptions.Items[0]
+			if desiredChannel != clientSubscription.Spec.Channel {
+				clientSubscription.Spec.Channel = desiredChannel
+				// TODO: https://github.com/red-hat-storage/ocs-client-operator/issues/130
+				// there can be a possibility that platform is behind, even then updating the channel will only make subscription to be in upgrading state
+				// without any side effects for already running workloads. However, this will be a silent failure and need to be fixed via above TODO issue.
+				if err := c.update(clientSubscription); err != nil {
+					return fmt.Errorf("failed to update subscription channel to %v: %v", desiredChannel, err)
+				}
+			}
+		}
+	}
+
+	return nil
+}
+
+func (c *OperatorConfigMapReconciler) reconcileWebhookService() error {
+	svc := &corev1.Service{}
+	svc.Name = templates.WebhookServiceName
+	svc.Namespace = c.OperatorNamespace
+	err := c.createOrUpdate(svc, func() error {
+		if err := c.own(svc); err != nil {
+			return err
+		}
+		utils.AddAnnotation(svc, "service.beta.openshift.io/serving-cert-secret-name", "webhook-cert-secret")
+		templates.WebhookService.Spec.DeepCopyInto(&svc.Spec)
+		return nil
+	})
+	if err != nil {
+		return err
+	}
+	c.log.Info("successfully reconcile webhook service")
+	return nil
+}
+
+func (c *OperatorConfigMapReconciler) list(obj client.ObjectList, opts ...client.ListOption) error {
+	return c.List(c.ctx, obj, opts...)
+}
+
+func (c *OperatorConfigMapReconciler) update(obj client.Object, opts ...client.UpdateOption) error {
+	return c.Update(c.ctx, obj, opts...)
+}
+
+func (c *OperatorConfigMapReconciler) delete(obj client.Object, opts ...client.DeleteOption) error {
+	if err := c.Delete(c.ctx, obj, opts...); err != nil && !kerrors.IsNotFound(err) {
+		return err
+	}
+	return nil
+}
diff --git a/controllers/storageclaim_controller.go b/controllers/storageclaim_controller.go
index e8460101..76346023 100644
--- a/controllers/storageclaim_controller.go
+++ b/controllers/storageclaim_controller.go
@@ -93,6 +93,7 @@ func (r *StorageClaimReconciler) SetupWithManager(mgr ctrl.Manager) error {
 		vsc := o.(*snapapi.VolumeSnapshotContent)
 		if vsc != nil &&
 			slices.Contains(csiDrivers, vsc.Spec.Driver) &&
+			vsc.Status != nil &&
 			vsc.Status.SnapshotHandle != nil {
 			parts := strings.Split(*vsc.Status.SnapshotHandle, "-")
 			if len(parts) == 9 {
@@ -152,7 +153,7 @@ func (r *StorageClaimReconciler) Reconcile(ctx context.Context, req ctrl.Request
 	r.storageClaimHash = getMD5Hash(r.storageClaim.Name)
 	r.storageClaim.Status.Phase = v1alpha1.StorageClaimInitializing
 
-	if r.storageClaim.Spec.StorageClient == nil {
+	if r.storageClaim.Spec.StorageClient == "" {
 		storageClientList := &v1alpha1.StorageClientList{}
 		if err := r.list(storageClientList); err != nil {
 			return reconcile.Result{}, err
@@ -170,8 +171,7 @@ func (r *StorageClaimReconciler) Reconcile(ctx context.Context, req ctrl.Request
 	} else {
 		// Fetch the StorageClient instance
 		r.storageClient = &v1alpha1.StorageClient{}
-		r.storageClient.Name = r.storageClaim.Spec.StorageClient.Name
-		r.storageClient.Namespace = r.storageClaim.Spec.StorageClient.Namespace
+		r.storageClient.Name = r.storageClaim.Spec.StorageClient
 		if err := r.get(r.storageClient); err != nil {
 			r.log.Error(err, "Failed to get StorageClient.")
 			return reconcile.Result{}, err
@@ -246,13 +246,14 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) {
 				Name: r.storageClaim.Name,
 			},
 		}
+		var claimType string
 		if err = r.get(existing); err == nil {
-			sccType := r.storageClaim.Spec.Type
+			claimType = strings.ToLower(r.storageClaim.Spec.Type)
 			sccEncryptionMethod := r.storageClaim.Spec.EncryptionMethod
 			_, scIsFSType := existing.Parameters["fsName"]
 			scEncryptionMethod, scHasEncryptionMethod := existing.Parameters["encryptionMethod"]
-			if !((sccType == "sharedfile" && scIsFSType && !scHasEncryptionMethod) ||
-				(sccType == "block" && !scIsFSType && sccEncryptionMethod == scEncryptionMethod)) {
+			if !((claimType == "sharedfile" && scIsFSType && !scHasEncryptionMethod) ||
+				(claimType == "block" && !scIsFSType && sccEncryptionMethod == scEncryptionMethod)) {
 				r.log.Error(fmt.Errorf("storageClaim is not compatible with existing StorageClass"),
 					"StorageClaim validation failed.")
 				r.storageClaim.Status.Phase = v1alpha1.StorageClaimFailed
@@ -265,18 +266,8 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) {
 		// Configuration phase.
 		r.storageClaim.Status.Phase = v1alpha1.StorageClaimConfiguring
 
-		updateStorageClaim := false
 		// Check if finalizers are present, if not, add them.
-		if !contains(r.storageClaim.GetFinalizers(), storageClaimFinalizer) {
-			r.log.Info("Finalizer not found for StorageClaim. Adding finalizer.", "StorageClaim", r.storageClaim.Name)
-			r.storageClaim.SetFinalizers(append(r.storageClaim.GetFinalizers(), storageClaimFinalizer))
-			updateStorageClaim = true
-		}
-		if utils.AddAnnotation(r.storageClaim, storageClientAnnotationKey, client.ObjectKeyFromObject(r.storageClient).String()) {
-			updateStorageClaim = true
-		}
-
-		if updateStorageClaim {
+		if controllerutil.AddFinalizer(r.storageClaim, storageClaimFinalizer) {
 			if err := r.update(r.storageClaim); err != nil {
 				return reconcile.Result{}, fmt.Errorf("failed to update StorageClaim %q: %v", r.storageClaim.Name, err)
 			}
@@ -284,17 +275,17 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) {
 
 		// storageClaimStorageType is the storage type of the StorageClaim
 		var storageClaimStorageType providerclient.StorageType
-		switch r.storageClaim.Spec.Type {
+		switch claimType {
 		case "block":
-			storageClaimStorageType = providerclient.StorageTypeBlockpool
+			storageClaimStorageType = providerclient.StorageTypeBlock
 		case "sharedfile":
-			storageClaimStorageType = providerclient.StorageTypeSharedfilesystem
+			storageClaimStorageType = providerclient.StorageTypeSharedFile
 		default:
-			return reconcile.Result{}, fmt.Errorf("unsupported storage type: %s", r.storageClaim.Spec.Type)
+			return reconcile.Result{}, fmt.Errorf("unsupported storage type: %s", claimType)
 		}
 
-		// Call the `FulfillStorageClassClaim` service on the provider server with StorageClaim as a request message.
-		_, err = providerClient.FulfillStorageClassClaim(
+		// Call the `FulfillStorageClaim` service on the provider server with StorageClaim as a request message.
+		_, err = providerClient.FulfillStorageClaim(
 			r.ctx,
 			r.storageClient.Status.ConsumerID,
 			r.storageClaim.Name,
@@ -306,14 +297,14 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) {
 			return reconcile.Result{}, fmt.Errorf("failed to initiate fulfillment of StorageClaim: %v", err)
 		}
 
-		// Call the `GetStorageClassClaimConfig` service on the provider server with StorageClaim as a request message.
-		response, err := providerClient.GetStorageClassClaimConfig(
+		// Call the `GetStorageClaimConfig` service on the provider server with StorageClaim as a request message.
+		response, err := providerClient.GetStorageClaimConfig(
 			r.ctx,
 			r.storageClient.Status.ConsumerID,
 			r.storageClaim.Name,
 		)
 		if err != nil {
-			return reconcile.Result{}, fmt.Errorf("failed to get StorageClassClaim config: %v", err)
+			return reconcile.Result{}, fmt.Errorf("failed to get StorageClaim config: %v", err)
 		}
 		resources := response.ExternalResource
 		if resources == nil {
@@ -339,7 +330,7 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) {
 			data := map[string]string{}
 			err = json.Unmarshal(resource.Data, &data)
 			if err != nil {
-				return reconcile.Result{}, fmt.Errorf("failed to unmarshal StorageClassClaim configuration response: %v", err)
+				return reconcile.Result{}, fmt.Errorf("failed to unmarshal StorageClaim configuration response: %v", err)
 			}
 
 			// Create the received resources, if necessary.
@@ -347,7 +338,7 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) {
 			case "Secret":
 				secret := &corev1.Secret{}
 				secret.Name = resource.Name
-				secret.Namespace = r.storageClient.Namespace
+				secret.Namespace = r.OperatorNamespace
 				_, err = controllerutil.CreateOrUpdate(r.ctx, r.Client, secret, func() error {
 					// cluster scoped resource owning namespace scoped resource which allows garbage collection
 					if err := r.own(secret); err != nil {
@@ -382,9 +373,9 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) {
 				// same name.
 				csiClusterConfigEntry.ClusterID = r.storageClaimHash
 				var storageClass *storagev1.StorageClass
-				data["csi.storage.k8s.io/provisioner-secret-namespace"] = r.storageClient.Namespace
-				data["csi.storage.k8s.io/node-stage-secret-namespace"] = r.storageClient.Namespace
-				data["csi.storage.k8s.io/controller-expand-secret-namespace"] = r.storageClient.Namespace
+				data["csi.storage.k8s.io/provisioner-secret-namespace"] = r.OperatorNamespace
+				data["csi.storage.k8s.io/node-stage-secret-namespace"] = r.OperatorNamespace
+				data["csi.storage.k8s.io/controller-expand-secret-namespace"] = r.OperatorNamespace
 				data["clusterID"] = r.storageClaimHash
 
 				if resource.Name == "cephfs" {
@@ -403,7 +394,7 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) {
 				}
 			case "VolumeSnapshotClass":
 				var volumeSnapshotClass *snapapi.VolumeSnapshotClass
-				data["csi.storage.k8s.io/snapshotter-secret-namespace"] = r.storageClient.Namespace
+				data["csi.storage.k8s.io/snapshotter-secret-namespace"] = r.OperatorNamespace
 				// generate a new clusterID for cephfs subvolumegroup, as
 				// storageclaim is clusterscoped resources using its
 				// hash as the clusterID
@@ -453,20 +444,19 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) {
 			return reconcile.Result{}, fmt.Errorf("failed to update mon configmap: %v", err)
 		}
 
-		// Call `RevokeStorageClassClaim` service on the provider server with StorageClaim as a request message.
+		// Call `RevokeStorageClaim` service on the provider server with StorageClaim as a request message.
 		// Check if StorageClaim is still exists (it might have been manually removed during the StorageClass
 		// removal above).
-		_, err = providerClient.RevokeStorageClassClaim(
+		_, err = providerClient.RevokeStorageClaim(
 			r.ctx,
 			r.storageClient.Status.ConsumerID,
 			r.storageClaim.Name,
 		)
 		if err != nil {
-			return reconcile.Result{}, fmt.Errorf("failed to revoke StorageClassClaim: %s", err)
+			return reconcile.Result{}, fmt.Errorf("failed to revoke StorageClaim: %s", err)
 		}
 
-		if contains(r.storageClaim.GetFinalizers(), storageClaimFinalizer) {
-			r.storageClaim.Finalizers = remove(r.storageClaim.Finalizers, storageClaimFinalizer)
+		if controllerutil.RemoveFinalizer(r.storageClaim, storageClaimFinalizer) {
 			if err := r.update(r.storageClaim); err != nil {
 				return ctrl.Result{}, fmt.Errorf("failed to remove finalizer from storageClaim: %s", err)
 			}
@@ -595,8 +585,7 @@ func (r *StorageClaimReconciler) delete(obj client.Object) error {
 }
 
 func (r *StorageClaimReconciler) own(resource metav1.Object) error {
-	// Ensure StorageClaim ownership on a resource
-	return controllerutil.SetOwnerReference(r.storageClaim, resource, r.Scheme)
+	return controllerutil.SetControllerReference(r.storageClaim, resource, r.Scheme)
 }
 
 func (r *StorageClaimReconciler) createOrReplaceVolumeSnapshotClass(volumeSnapshotClass *snapapi.VolumeSnapshotClass) error {
diff --git a/controllers/storageclassclaim_migration_controller.go b/controllers/storageclassclaim_migration_controller.go
deleted file mode 100644
index 35a02c33..00000000
--- a/controllers/storageclassclaim_migration_controller.go
+++ /dev/null
@@ -1,135 +0,0 @@
-package controllers
-
-import (
-	"context"
-	"fmt"
-
-	"github.com/go-logr/logr"
-	"github.com/red-hat-storage/ocs-client-operator/api/v1alpha1"
-	corev1 "k8s.io/api/core/v1"
-	kerrors "k8s.io/apimachinery/pkg/api/errors"
-	"k8s.io/apimachinery/pkg/runtime"
-	ctrl "sigs.k8s.io/controller-runtime"
-	"sigs.k8s.io/controller-runtime/pkg/builder"
-	"sigs.k8s.io/controller-runtime/pkg/client"
-	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
-	"sigs.k8s.io/controller-runtime/pkg/event"
-	"sigs.k8s.io/controller-runtime/pkg/log"
-	"sigs.k8s.io/controller-runtime/pkg/predicate"
-)
-
-const (
-	// for migration of storageclassclaims to storageclaims
-	storageClassClaimFinalizer = "storageclassclaim.ocs.openshift.io"
-)
-
-// StorageClassClaimReconcile migrates StorageClassClaim objects to StorageClaim
-type StorageClassClaimMigrationReconciler struct {
-	client.Client
-	Scheme *runtime.Scheme
-
-	log logr.Logger
-	ctx context.Context
-}
-
-func (r *StorageClassClaimMigrationReconciler) SetupWithManager(mgr ctrl.Manager) error {
-	onlyCreateEvent := predicate.Funcs{
-		CreateFunc: func(event.CreateEvent) bool {
-			return true
-		},
-		DeleteFunc: func(event.DeleteEvent) bool {
-			return false
-		},
-		UpdateFunc: func(event.UpdateEvent) bool {
-			return false
-		},
-		GenericFunc: func(event.GenericEvent) bool {
-			return false
-		},
-	}
-	return ctrl.NewControllerManagedBy(mgr).
-		For(&v1alpha1.StorageClassClaim{}, builder.WithPredicates(onlyCreateEvent)).
-		Complete(r)
-}
-
-//+kubebuilder:rbac:groups=ocs.openshift.io,resources=storageclassclaims,verbs=get;list;watch;create;update;patch;delete
-//+kubebuilder:rbac:groups=ocs.openshift.io,resources=storageclassclaims/status,verbs=get;update;patch
-//+kubebuilder:rbac:groups=ocs.openshift.io,resources=storageclassclaims/finalizers,verbs=update
-
-func (r *StorageClassClaimMigrationReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
-
-	r.log = log.FromContext(ctx)
-	r.ctx = ctx
-	r.log.Info("Starting reconcile.")
-
-	storageClassClaim := &v1alpha1.StorageClassClaim{}
-	storageClassClaim.Name = req.Name
-
-	if err := r.get(storageClassClaim); err != nil && !kerrors.IsNotFound(err) {
-		r.log.Error(err, fmt.Sprintf("failed to get storageclassclaim %q", storageClassClaim.Name))
-		return ctrl.Result{}, err
-	}
-
-	storageClaim := &v1alpha1.StorageClaim{}
-	storageClaim.Name = storageClassClaim.Name
-
-	switch storageClassClaim.Spec.Type {
-	case "blockpool":
-		storageClaim.Spec.Type = "block"
-	case "sharedfilesystem":
-		storageClaim.Spec.Type = "sharedfile"
-	}
-
-	storageClaim.Spec.EncryptionMethod = storageClassClaim.Spec.EncryptionMethod
-	storageClaim.Spec.StorageProfile = storageClassClaim.Spec.StorageProfile
-	storageClaim.Spec.StorageClient = storageClassClaim.Spec.StorageClient.DeepCopy()
-
-	r.log.Info(fmt.Sprintf("Migrating storageclassclaim %q", storageClassClaim.Name))
-	if err := r.create(storageClaim); err != nil && !kerrors.IsAlreadyExists(err) {
-		return ctrl.Result{}, fmt.Errorf("failed to create storageclaims %q: %v", storageClaim.Name, err)
-	}
-
-	for idx := range storageClassClaim.Status.SecretNames {
-		secret := &corev1.Secret{}
-		secret.Name = storageClassClaim.Status.SecretNames[idx]
-		secret.Namespace = storageClassClaim.Spec.StorageClient.Namespace
-		if err := r.delete(secret); err != nil {
-			return ctrl.Result{}, fmt.Errorf("failed to delete secret %s: %v", client.ObjectKeyFromObject(secret), err)
-		}
-	}
-
-	// remove finalizer on existing storageclassclaim
-	finalizerUpdated := controllerutil.RemoveFinalizer(storageClassClaim, storageClassClaimFinalizer)
-	if finalizerUpdated {
-		if err := r.update(storageClassClaim); err != nil {
-			return ctrl.Result{}, fmt.Errorf("failed to remove finalizer on storageclassclaim %q: %v", storageClassClaim.Name, err)
-		}
-	}
-
-	// migration is successful delete the storageclassclaim
-	if err := r.delete(storageClassClaim); err != nil {
-		return ctrl.Result{}, fmt.Errorf("failed to delete storageclassclaim %q: %v", storageClassClaim.Name, err)
-	}
-
-	r.log.Info(fmt.Sprintf("Successfully migrated storageclassclaim %q to storageclass %q", storageClassClaim.Name, storageClaim.Name))
-	return ctrl.Result{}, nil
-}
-
-func (r *StorageClassClaimMigrationReconciler) get(obj client.Object, opts ...client.GetOption) error {
-	return r.Get(r.ctx, client.ObjectKeyFromObject(obj), obj, opts...)
-}
-
-func (r *StorageClassClaimMigrationReconciler) create(obj client.Object, opts ...client.CreateOption) error {
-	return r.Create(r.ctx, obj, opts...)
-}
-
-func (r *StorageClassClaimMigrationReconciler) update(obj client.Object, opts ...client.UpdateOption) error {
-	return r.Update(r.ctx, obj, opts...)
-}
-
-func (r *StorageClassClaimMigrationReconciler) delete(obj client.Object, opts ...client.DeleteOption) error {
-	if err := r.Delete(r.ctx, obj, opts...); err != nil && !kerrors.IsNotFound(err) {
-		return err
-	}
-	return nil
-}
diff --git a/controllers/storageclient_controller.go b/controllers/storageclient_controller.go
index a36c8fbb..bf93589b 100644
--- a/controllers/storageclient_controller.go
+++ b/controllers/storageclient_controller.go
@@ -18,9 +18,6 @@ package controllers
 
 import (
 	"context"
-	"crypto/md5"
-	"encoding/hex"
-	"encoding/json"
 	"fmt"
 	"os"
 	"strings"
@@ -37,13 +34,12 @@ import (
 	batchv1 "k8s.io/api/batch/v1"
 	corev1 "k8s.io/api/core/v1"
 	kerrors "k8s.io/apimachinery/pkg/api/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
-	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/klog/v2"
 	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
-	"sigs.k8s.io/controller-runtime/pkg/handler"
 	"sigs.k8s.io/controller-runtime/pkg/log"
 	"sigs.k8s.io/controller-runtime/pkg/reconcile"
 )
@@ -55,19 +51,13 @@ const (
 	GetStorageConfig      = "GetStorageConfig"
 	AcknowledgeOnboarding = "AcknowledgeOnboarding"
 
-	storageClientAnnotationKey          = "ocs.openshift.io/storageclient"
-	storageClientNameLabel              = "ocs.openshift.io/storageclient.name"
-	storageClientNamespaceLabel         = "ocs.openshift.io/storageclient.namespace"
-	storageClientFinalizer              = "storageclient.ocs.openshift.io"
-	defaultClaimsOwnerAnnotationKey     = "ocs.openshift.io/storageclaim.owner"
-	defaultClaimsProcessedAnnotationKey = "ocs.openshift.io/storageclaim.processed"
-	defaultBlockStorageClaim            = "ocs-storagecluster-ceph-rbd"
-	defaultSharedfileStorageClaim       = "ocs-storagecluster-cephfs"
+	storageClientNameLabel             = "ocs.openshift.io/storageclient.name"
+	storageClientFinalizer             = "storageclient.ocs.openshift.io"
+	storageClaimProcessedAnnotationKey = "ocs.openshift.io/storageclaim.processed"
+	storageClientDefaultAnnotationKey  = "ocs.openshift.io/storageclient.default"
 
 	// indexes for caching
-	storageProviderEndpointIndexName = "index:storageProviderEndpoint"
-	storageClientAnnotationIndexName = "index:storageClientAnnotation"
-	defaultClaimsOwnerIndexName      = "index:defaultClaimsOwner"
+	ownerIndexName = "index:ownerUID"
 
 	csvPrefix = "ocs-client-operator"
 )
@@ -76,58 +66,34 @@ const (
 type StorageClientReconciler struct {
 	ctx context.Context
 	client.Client
-	Log      klog.Logger
-	Scheme   *runtime.Scheme
-	recorder *utils.EventReporter
+	Log           klog.Logger
+	Scheme        *runtime.Scheme
+	recorder      *utils.EventReporter
+	storageClient *v1alpha1.StorageClient
 
 	OperatorNamespace string
 }
 
 // SetupWithManager sets up the controller with the Manager.
-func (s *StorageClientReconciler) SetupWithManager(mgr ctrl.Manager) error {
+func (r *StorageClientReconciler) SetupWithManager(mgr ctrl.Manager) error {
 	ctx := context.Background()
-	// Index should be registered before cache start.
-	// IndexField is used to filter out the objects that already exists with
-	// status.phase != failed This will help in blocking
-	// the new storageclient creation if there is already with one with same
-	// provider endpoint with status.phase != failed
-	_ = mgr.GetCache().IndexField(ctx, &v1alpha1.StorageClient{}, storageProviderEndpointIndexName, func(o client.Object) []string {
-		res := []string{}
-		if o.(*v1alpha1.StorageClient).Status.Phase != v1alpha1.StorageClientFailed {
-			res = append(res, o.(*v1alpha1.StorageClient).Spec.StorageProviderEndpoint)
+	if err := mgr.GetCache().IndexField(ctx, &v1alpha1.StorageClaim{}, ownerIndexName, func(obj client.Object) []string {
+		refs := obj.GetOwnerReferences()
+		var owners []string
+		for i := range refs {
+			owners = append(owners, string(refs[i].UID))
 		}
-		return res
-	})
-
-	if err := mgr.GetCache().IndexField(ctx, &v1alpha1.StorageClaim{}, storageClientAnnotationIndexName, func(obj client.Object) []string {
-		return []string{obj.GetAnnotations()[storageClientAnnotationKey]}
-	}); err != nil {
-		return fmt.Errorf("unable to set up FieldIndexer for storageclient annotation: %v", err)
-	}
-
-	if err := mgr.GetCache().IndexField(ctx, &v1alpha1.StorageClient{}, defaultClaimsOwnerIndexName, func(obj client.Object) []string {
-		return []string{obj.GetAnnotations()[defaultClaimsOwnerAnnotationKey]}
+		return owners
 	}); err != nil {
-		return fmt.Errorf("unable to set up FieldIndexer for storageclient owner annotation: %v", err)
+		return fmt.Errorf("unable to set up FieldIndexer for StorageClaim's owner uid: %v", err)
 	}
 
-	enqueueStorageClientRequest := handler.EnqueueRequestsFromMapFunc(
-		func(_ context.Context, obj client.Object) []reconcile.Request {
-			annotations := obj.GetAnnotations()
-			if _, found := annotations[storageClaimAnnotation]; found {
-				return []reconcile.Request{{
-					NamespacedName: types.NamespacedName{
-						Name: obj.GetName(),
-					},
-				}}
-			}
-			return []reconcile.Request{}
-		})
-	s.recorder = utils.NewEventReporter(mgr.GetEventRecorderFor("controller_storageclient"))
+	r.recorder = utils.NewEventReporter(mgr.GetEventRecorderFor("controller_storageclient"))
 	return ctrl.NewControllerManagedBy(mgr).
 		For(&v1alpha1.StorageClient{}).
-		Watches(&v1alpha1.StorageClaim{}, enqueueStorageClientRequest).
-		Complete(s)
+		Owns(&v1alpha1.StorageClaim{}).
+		Owns(&batchv1.CronJob{}).
+		Complete(r)
 }
 
 //+kubebuilder:rbac:groups=ocs.openshift.io,resources=storageclients,verbs=get;list;watch;create;update;patch;delete
@@ -137,37 +103,34 @@ func (s *StorageClientReconciler) SetupWithManager(mgr ctrl.Manager) error {
 //+kubebuilder:rbac:groups=batch,resources=cronjobs,verbs=get;list;create;update;watch;delete
 //+kubebuilder:rbac:groups=operators.coreos.com,resources=clusterserviceversions,verbs=get;list;watch
 
-func (s *StorageClientReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
+func (r *StorageClientReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
 	var err error
-	s.ctx = ctx
-	s.Log = log.FromContext(ctx, "StorageClient", req)
-	s.Log.Info("Reconciling StorageClient")
+	r.ctx = ctx
+	r.Log = log.FromContext(ctx, "StorageClient", req)
+	r.Log.Info("Reconciling StorageClient")
 
-	// Fetch the StorageClient instance
-	instance := &v1alpha1.StorageClient{}
-	instance.Name = req.Name
-	instance.Namespace = req.Namespace
-
-	if err = s.Client.Get(ctx, types.NamespacedName{Name: instance.Name, Namespace: instance.Namespace}, instance); err != nil {
+	r.storageClient = &v1alpha1.StorageClient{}
+	r.storageClient.Name = req.Name
+	if err = r.get(r.storageClient); err != nil {
 		if kerrors.IsNotFound(err) {
-			s.Log.Info("StorageClient resource not found. Ignoring since object must be deleted.")
+			r.Log.Info("StorageClient resource not found. Ignoring since object must be deleted.")
 			return reconcile.Result{}, nil
 		}
-		s.Log.Error(err, "Failed to get StorageClient.")
+		r.Log.Error(err, "Failed to get StorageClient.")
 		return reconcile.Result{}, fmt.Errorf("failed to get StorageClient: %v", err)
 	}
 
 	// Dont Reconcile the StorageClient if it is in failed state
-	if instance.Status.Phase == v1alpha1.StorageClientFailed {
+	if r.storageClient.Status.Phase == v1alpha1.StorageClientFailed {
 		return reconcile.Result{}, nil
 	}
 
-	result, reconcileErr := s.reconcilePhases(instance)
+	result, reconcileErr := r.reconcilePhases()
 
 	// Apply status changes to the StorageClient
-	statusErr := s.Client.Status().Update(ctx, instance)
+	statusErr := r.Client.Status().Update(ctx, r.storageClient)
 	if statusErr != nil {
-		s.Log.Error(statusErr, "Failed to update StorageClient status.")
+		r.Log.Error(statusErr, "Failed to update StorageClient status.")
 	}
 	if reconcileErr != nil {
 		err = reconcileErr
@@ -177,110 +140,107 @@ func (s *StorageClientReconciler) Reconcile(ctx context.Context, req ctrl.Reques
 	return result, err
 }
 
-func (s *StorageClientReconciler) reconcilePhases(instance *v1alpha1.StorageClient) (ctrl.Result, error) {
-	storageClientListOption := []client.ListOption{
-		client.MatchingFields{storageProviderEndpointIndexName: instance.Spec.StorageProviderEndpoint},
-	}
-
-	storageClientList := &v1alpha1.StorageClientList{}
-	if err := s.Client.List(s.ctx, storageClientList, storageClientListOption...); err != nil {
-		s.Log.Error(err, "unable to list storage clients")
-		return ctrl.Result{}, err
-	}
+func (r *StorageClientReconciler) reconcilePhases() (ctrl.Result, error) {
 
-	if len(storageClientList.Items) > 1 {
-		s.Log.Info("one StorageClient is allowed per namespace but found more than one. Rejecting new request.")
-		instance.Status.Phase = v1alpha1.StorageClientFailed
-		// Dont Reconcile again	as there is already a StorageClient with same provider endpoint
-		return reconcile.Result{}, nil
-	}
-
-	externalClusterClient, err := s.newExternalClusterClient(instance)
+	externalClusterClient, err := r.newExternalClusterClient()
 	if err != nil {
 		return reconcile.Result{}, err
 	}
 	defer externalClusterClient.Close()
 
 	// deletion phase
-	if !instance.GetDeletionTimestamp().IsZero() {
-		return s.deletionPhase(instance, externalClusterClient)
+	if !r.storageClient.GetDeletionTimestamp().IsZero() {
+		return r.deletionPhase(externalClusterClient)
+	}
+
+	updateStorageClient := false
+	storageClients := &v1alpha1.StorageClientList{}
+	if err := r.list(storageClients); err != nil {
+		r.Log.Error(err, "unable to list storage clients")
+		return ctrl.Result{}, err
+	}
+	if len(storageClients.Items) == 1 && storageClients.Items[0].Name == r.storageClient.Name {
+		if utils.AddAnnotation(r.storageClient, storageClientDefaultAnnotationKey, "true") {
+			updateStorageClient = true
+		}
 	}
 
 	// ensure finalizer
-	if !contains(instance.GetFinalizers(), storageClientFinalizer) {
-		instance.Status.Phase = v1alpha1.StorageClientInitializing
-		s.Log.Info("Finalizer not found for StorageClient. Adding finalizer.", "StorageClient", klog.KRef(instance.Namespace, instance.Name))
-		instance.ObjectMeta.Finalizers = append(instance.ObjectMeta.Finalizers, storageClientFinalizer)
-		if err := s.Client.Update(s.ctx, instance); err != nil {
-			s.Log.Info("Failed to update StorageClient with finalizer.", "StorageClient", klog.KRef(instance.Namespace, instance.Name))
-			return reconcile.Result{}, fmt.Errorf("failed to update StorageClient with finalizer: %v", err)
+	if controllerutil.AddFinalizer(r.storageClient, storageClientFinalizer) {
+		r.storageClient.Status.Phase = v1alpha1.StorageClientInitializing
+		r.Log.Info("Finalizer not found for StorageClient. Adding finalizer.", "StorageClient", r.storageClient.Name)
+		updateStorageClient = true
+	}
+
+	if updateStorageClient {
+		if err := r.update(r.storageClient); err != nil {
+			return reconcile.Result{}, fmt.Errorf("failed to update StorageClient: %v", err)
 		}
 	}
 
-	if instance.Status.ConsumerID == "" {
-		return s.onboardConsumer(instance, externalClusterClient)
-	} else if instance.Status.Phase == v1alpha1.StorageClientOnboarding {
-		return s.acknowledgeOnboarding(instance, externalClusterClient)
+	if r.storageClient.Status.ConsumerID == "" {
+		return r.onboardConsumer(externalClusterClient)
+	} else if r.storageClient.Status.Phase == v1alpha1.StorageClientOnboarding {
+		return r.acknowledgeOnboarding(externalClusterClient)
 	}
 
-	if res, err := s.reconcileClientStatusReporterJob(instance); err != nil {
+	if res, err := r.reconcileClientStatusReporterJob(); err != nil {
 		return res, err
 	}
 
-	if err := s.reconcileDefaultStorageClaims(instance); err != nil {
-		return reconcile.Result{}, err
+	if r.storageClient.GetAnnotations()[storageClaimProcessedAnnotationKey] != "true" {
+		if err := r.reconcileBlockStorageClaim(); err != nil {
+			return reconcile.Result{}, err
+		}
+
+		if err := r.reconcileSharedfileStorageClaim(); err != nil {
+			return reconcile.Result{}, err
+		}
+
+		utils.AddAnnotation(r.storageClient, storageClaimProcessedAnnotationKey, "true")
+		if err := r.update(r.storageClient); err != nil {
+			return reconcile.Result{}, fmt.Errorf("failed to update StorageClient with claim processed annotation: %v", err)
+		}
 	}
 
 	return reconcile.Result{}, nil
 }
 
-func (s *StorageClientReconciler) deletionPhase(instance *v1alpha1.StorageClient, externalClusterClient *providerClient.OCSProviderClient) (ctrl.Result, error) {
+func (r *StorageClientReconciler) deletionPhase(externalClusterClient *providerClient.OCSProviderClient) (ctrl.Result, error) {
 	// TODO Need to take care of deleting the SCC created for this
 	// storageClient and also the default SCC created for this storageClient
-	if contains(instance.GetFinalizers(), storageClientFinalizer) {
-		instance.Status.Phase = v1alpha1.StorageClientOffboarding
-		err := s.verifyNoStorageClaimsExist(instance)
-		if err != nil {
-			s.Log.Error(err, "still storageclaims exist for this storageclient")
-			return reconcile.Result{}, fmt.Errorf("still storageclaims exist for this storageclient: %v", err)
-		}
-		if res, err := s.offboardConsumer(instance, externalClusterClient); err != nil {
-			s.Log.Error(err, "Offboarding in progress.")
-		} else if !res.IsZero() {
-			// result is not empty
-			return res, nil
-		}
+	r.storageClient.Status.Phase = v1alpha1.StorageClientOffboarding
 
-		cronJob := &batchv1.CronJob{}
-		cronJob.Name = getStatusReporterName(instance.Namespace, instance.Name)
-		cronJob.Namespace = s.OperatorNamespace
-
-		if err := s.delete(cronJob); err != nil {
-			s.Log.Error(err, "Failed to delete the status reporter job")
-			return reconcile.Result{}, fmt.Errorf("failed to delete the status reporter job: %v", err)
-		}
-
-		if err := s.deleteDefaultStorageClaims(instance); err != nil {
-			return reconcile.Result{}, fmt.Errorf("failed to delete default storageclaims: %v", err)
-		}
+	if err := r.deleteOwnedStorageClaims(); err != nil {
+		return reconcile.Result{}, fmt.Errorf("failed to delete storageclaims owned by storageclient %v: %v", r.storageClient.Name, err)
+	}
+	if err := r.verifyNoStorageClaimsExist(); err != nil {
+		r.Log.Error(err, "still storageclaims exist for this storageclient")
+		return reconcile.Result{}, fmt.Errorf("still storageclaims exist for this storageclient: %v", err)
+	}
+	if res, err := r.offboardConsumer(externalClusterClient); err != nil {
+		r.Log.Error(err, "Offboarding in progress.")
+	} else if !res.IsZero() {
+		// result is not empty
+		return res, nil
+	}
 
-		s.Log.Info("removing finalizer from StorageClient.", "StorageClient", klog.KRef(instance.Namespace, instance.Name))
-		// Once all finalizers have been removed, the object will be deleted
-		instance.ObjectMeta.Finalizers = remove(instance.ObjectMeta.Finalizers, storageClientFinalizer)
-		if err := s.Client.Update(s.ctx, instance); err != nil {
-			s.Log.Info("Failed to remove finalizer from StorageClient", "StorageClient", klog.KRef(instance.Namespace, instance.Name))
+	if controllerutil.RemoveFinalizer(r.storageClient, storageClientFinalizer) {
+		r.Log.Info("removing finalizer from StorageClient.", "StorageClient", r.storageClient.Name)
+		if err := r.update(r.storageClient); err != nil {
+			r.Log.Info("Failed to remove finalizer from StorageClient", "StorageClient", r.storageClient.Name)
 			return reconcile.Result{}, fmt.Errorf("failed to remove finalizer from StorageClient: %v", err)
 		}
 	}
-	s.Log.Info("StorageClient is offboarded", "StorageClient", klog.KRef(instance.Namespace, instance.Name))
+	r.Log.Info("StorageClient is offboarded", "StorageClient", r.storageClient.Name)
 	return reconcile.Result{}, nil
 }
 
 // newExternalClusterClient returns the *providerClient.OCSProviderClient
-func (s *StorageClientReconciler) newExternalClusterClient(instance *v1alpha1.StorageClient) (*providerClient.OCSProviderClient, error) {
+func (r *StorageClientReconciler) newExternalClusterClient() (*providerClient.OCSProviderClient, error) {
 
 	ocsProviderClient, err := providerClient.NewProviderClient(
-		s.ctx, instance.Spec.StorageProviderEndpoint, time.Second*10)
+		r.ctx, r.storageClient.Spec.StorageProviderEndpoint, time.Second*10)
 	if err != nil {
 		return nil, fmt.Errorf("failed to create a new provider client: %v", err)
 	}
@@ -289,21 +249,21 @@ func (s *StorageClientReconciler) newExternalClusterClient(instance *v1alpha1.St
 }
 
 // onboardConsumer makes an API call to the external storage provider cluster for onboarding
-func (s *StorageClientReconciler) onboardConsumer(instance *v1alpha1.StorageClient, externalClusterClient *providerClient.OCSProviderClient) (reconcile.Result, error) {
+func (r *StorageClientReconciler) onboardConsumer(externalClusterClient *providerClient.OCSProviderClient) (reconcile.Result, error) {
 
 	// TODO Need to find a way to get rid of ClusterVersion here as it is OCP
 	// specific one.
 	clusterVersion := &configv1.ClusterVersion{}
-	err := s.Client.Get(s.ctx, types.NamespacedName{Name: "version"}, clusterVersion)
-	if err != nil {
-		s.Log.Error(err, "failed to get the clusterVersion version of the OCP cluster")
+	clusterVersion.Name = "version"
+	if err := r.get(clusterVersion); err != nil {
+		r.Log.Error(err, "failed to get the clusterVersion version of the OCP cluster")
 		return reconcile.Result{}, fmt.Errorf("failed to get the clusterVersion version of the OCP cluster: %v", err)
 	}
 
 	// TODO Have a version file corresponding to the release
 	csvList := opv1a1.ClusterServiceVersionList{}
-	if err = s.list(&csvList, client.InNamespace(s.OperatorNamespace)); err != nil {
-		return reconcile.Result{}, fmt.Errorf("failed to list csv resources in ns: %v, err: %v", s.OperatorNamespace, err)
+	if err := r.list(&csvList, client.InNamespace(r.OperatorNamespace)); err != nil {
+		return reconcile.Result{}, fmt.Errorf("failed to list csv resources in ns: %v, err: %v", r.OperatorNamespace, err)
 	}
 	csv := utils.Find(csvList.Items, func(csv *opv1a1.ClusterServiceVersion) bool {
 		return strings.HasPrefix(csv.Name, csvPrefix)
@@ -314,52 +274,52 @@ func (s *StorageClientReconciler) onboardConsumer(instance *v1alpha1.StorageClie
 	name := fmt.Sprintf("storageconsumer-%s", clusterVersion.Spec.ClusterID)
 	onboardRequest := providerClient.NewOnboardConsumerRequest().
 		SetConsumerName(name).
-		SetOnboardingTicket(instance.Spec.OnboardingTicket).
+		SetOnboardingTicket(r.storageClient.Spec.OnboardingTicket).
 		SetClientOperatorVersion(csv.Spec.Version.String())
-	response, err := externalClusterClient.OnboardConsumer(s.ctx, onboardRequest)
+	response, err := externalClusterClient.OnboardConsumer(r.ctx, onboardRequest)
 	if err != nil {
 		if st, ok := status.FromError(err); ok {
-			s.logGrpcErrorAndReportEvent(instance, OnboardConsumer, err, st.Code())
+			r.logGrpcErrorAndReportEvent(OnboardConsumer, err, st.Code())
 		}
 		return reconcile.Result{}, fmt.Errorf("failed to onboard consumer: %v", err)
 	}
 
 	if response.StorageConsumerUUID == "" {
 		err = fmt.Errorf("storage provider response is empty")
-		s.Log.Error(err, "empty response")
+		r.Log.Error(err, "empty response")
 		return reconcile.Result{}, err
 	}
 
-	instance.Status.ConsumerID = response.StorageConsumerUUID
-	instance.Status.Phase = v1alpha1.StorageClientOnboarding
+	r.storageClient.Status.ConsumerID = response.StorageConsumerUUID
+	r.storageClient.Status.Phase = v1alpha1.StorageClientOnboarding
 
-	s.Log.Info("onboarding started")
+	r.Log.Info("onboarding started")
 	return reconcile.Result{Requeue: true}, nil
 }
 
-func (s *StorageClientReconciler) acknowledgeOnboarding(instance *v1alpha1.StorageClient, externalClusterClient *providerClient.OCSProviderClient) (reconcile.Result, error) {
+func (r *StorageClientReconciler) acknowledgeOnboarding(externalClusterClient *providerClient.OCSProviderClient) (reconcile.Result, error) {
 
-	_, err := externalClusterClient.AcknowledgeOnboarding(s.ctx, instance.Status.ConsumerID)
+	_, err := externalClusterClient.AcknowledgeOnboarding(r.ctx, r.storageClient.Status.ConsumerID)
 	if err != nil {
 		if st, ok := status.FromError(err); ok {
-			s.logGrpcErrorAndReportEvent(instance, AcknowledgeOnboarding, err, st.Code())
+			r.logGrpcErrorAndReportEvent(AcknowledgeOnboarding, err, st.Code())
 		}
-		s.Log.Error(err, "Failed to acknowledge onboarding.")
+		r.Log.Error(err, "Failed to acknowledge onboarding.")
 		return reconcile.Result{}, fmt.Errorf("failed to acknowledge onboarding: %v", err)
 	}
-	instance.Status.Phase = v1alpha1.StorageClientConnected
+	r.storageClient.Status.Phase = v1alpha1.StorageClientConnected
 
-	s.Log.Info("Onboarding is acknowledged successfully.")
+	r.Log.Info("Onboarding is acknowledged successfully.")
 	return reconcile.Result{Requeue: true}, nil
 }
 
 // offboardConsumer makes an API call to the external storage provider cluster for offboarding
-func (s *StorageClientReconciler) offboardConsumer(instance *v1alpha1.StorageClient, externalClusterClient *providerClient.OCSProviderClient) (reconcile.Result, error) {
+func (r *StorageClientReconciler) offboardConsumer(externalClusterClient *providerClient.OCSProviderClient) (reconcile.Result, error) {
 
-	_, err := externalClusterClient.OffboardConsumer(s.ctx, instance.Status.ConsumerID)
+	_, err := externalClusterClient.OffboardConsumer(r.ctx, r.storageClient.Status.ConsumerID)
 	if err != nil {
 		if st, ok := status.FromError(err); ok {
-			s.logGrpcErrorAndReportEvent(instance, OffboardConsumer, err, st.Code())
+			r.logGrpcErrorAndReportEvent(OffboardConsumer, err, st.Code())
 		}
 		return reconcile.Result{}, fmt.Errorf("failed to offboard consumer: %v", err)
 	}
@@ -367,29 +327,43 @@ func (s *StorageClientReconciler) offboardConsumer(instance *v1alpha1.StorageCli
 	return reconcile.Result{}, nil
 }
 
-func (s *StorageClientReconciler) verifyNoStorageClaimsExist(instance *v1alpha1.StorageClient) error {
+func (r *StorageClientReconciler) deleteOwnedStorageClaims() error {
+	storageClaims := &v1alpha1.StorageClaimList{}
+	if err := r.list(storageClaims, client.MatchingFields{ownerIndexName: string(r.storageClient.UID)}); err != nil {
+		return fmt.Errorf("failed to list storageClaims via owner reference: %v", err)
+	}
+
+	for idx := range storageClaims.Items {
+		storageClaim := &storageClaims.Items[idx]
+		if err := r.delete(storageClaim); err != nil {
+			return fmt.Errorf("failed to delete storageClaim %v: %v", storageClaim.Name, err)
+		}
+	}
+	return nil
+}
+
+func (r *StorageClientReconciler) verifyNoStorageClaimsExist() error {
 
 	storageClaims := &v1alpha1.StorageClaimList{}
-	err := s.Client.List(s.ctx,
-		storageClaims,
-		client.MatchingFields{storageClientAnnotationIndexName: client.ObjectKeyFromObject(instance).String()},
-		client.Limit(1),
-	)
-	if err != nil {
+	if err := r.list(storageClaims); err != nil {
 		return fmt.Errorf("failed to list storageClaims: %v", err)
 	}
 
-	if len(storageClaims.Items) != 0 {
-		err = fmt.Errorf("Failed to cleanup resources. storageClaims are present."+
-			"Delete all storageClaims corresponding to storageclient %q for the cleanup to proceed", client.ObjectKeyFromObject(instance))
-		s.recorder.ReportIfNotPresent(instance, corev1.EventTypeWarning, "Cleanup", err.Error())
-		s.Log.Error(err, "Waiting for all storageClaims to be deleted.")
-		return err
+	for idx := range storageClaims.Items {
+		storageClaim := &storageClaims.Items[idx]
+		if (storageClaim.Spec.StorageClient == "" && r.storageClient.Annotations[storageClientDefaultAnnotationKey] == "true") ||
+			storageClaim.Spec.StorageClient == r.storageClient.Name {
+			err := fmt.Errorf("failed to cleanup resources. storageClaims are present on the cluster")
+			r.recorder.ReportIfNotPresent(r.storageClient, corev1.EventTypeWarning, "Cleanup", err.Error())
+			r.Log.Error(err, "Waiting for all storageClaims to be deleted.")
+			return err
+		}
 	}
 
 	return nil
 }
-func (s *StorageClientReconciler) logGrpcErrorAndReportEvent(instance *v1alpha1.StorageClient, grpcCallName string, err error, errCode codes.Code) {
+
+func (r *StorageClientReconciler) logGrpcErrorAndReportEvent(grpcCallName string, err error, errCode codes.Code) {
 
 	var msg, eventReason, eventType string
 
@@ -432,51 +406,28 @@ func (s *StorageClientReconciler) logGrpcErrorAndReportEvent(instance *v1alpha1.
 	}
 
 	if msg != "" {
-		s.Log.Error(err, "StorageProvider:"+grpcCallName+":"+msg)
-		s.recorder.ReportIfNotPresent(instance, eventType, eventReason, msg)
-	}
-}
-
-func getStatusReporterName(namespace, name string) string {
-	// getStatusReporterName generates a name for a StatusReporter CronJob.
-	var s struct {
-		StorageClientName      string `json:"storageClientName"`
-		StorageClientNamespace string `json:"storageClientNamespace"`
-	}
-	s.StorageClientName = name
-	s.StorageClientNamespace = namespace
-
-	statusReporterName, err := json.Marshal(s)
-	if err != nil {
-		klog.Errorf("failed to marshal a name for a storage client based on %v. %v", s, err)
-		panic("failed to marshal storage client name")
-	}
-	reporterName := md5.Sum([]byte(statusReporterName))
-	// The name of the StorageClient is the MD5 hash of the JSON
-	// representation of the StorageClient name and namespace.
-	return fmt.Sprintf("storageclient-%s-status-reporter", hex.EncodeToString(reporterName[:8]))
-}
-
-func (s *StorageClientReconciler) delete(obj client.Object) error {
-	if err := s.Client.Delete(s.ctx, obj); err != nil && !kerrors.IsNotFound(err) {
-		return err
+		r.Log.Error(err, "StorageProvider:"+grpcCallName+":"+msg)
+		r.recorder.ReportIfNotPresent(r.storageClient, eventType, eventReason, msg)
 	}
-	return nil
 }
 
-func (s *StorageClientReconciler) reconcileClientStatusReporterJob(instance *v1alpha1.StorageClient) (reconcile.Result, error) {
-	// start the cronJob to ping the provider api server
+func (r *StorageClientReconciler) reconcileClientStatusReporterJob() (reconcile.Result, error) {
 	cronJob := &batchv1.CronJob{}
-	cronJob.Name = getStatusReporterName(instance.Namespace, instance.Name)
-	cronJob.Namespace = s.OperatorNamespace
-	utils.AddLabel(cronJob, storageClientNameLabel, instance.Name)
-	utils.AddLabel(cronJob, storageClientNamespaceLabel, instance.Namespace)
+	// maximum characters allowed for cronjob name is 52 and below interpolation creates 47 characters
+	cronJob.Name = fmt.Sprintf("storageclient-%s-status-reporter", getMD5Hash(r.storageClient.Name)[:16])
+	cronJob.Namespace = r.OperatorNamespace
+
 	var podDeadLineSeconds int64 = 120
 	jobDeadLineSeconds := podDeadLineSeconds + 35
 	var keepJobResourceSeconds int32 = 600
 	var reducedKeptSuccecsful int32 = 1
 
-	_, err := controllerutil.CreateOrUpdate(s.ctx, s.Client, cronJob, func() error {
+	_, err := controllerutil.CreateOrUpdate(r.ctx, r.Client, cronJob, func() error {
+		if err := r.own(cronJob); err != nil {
+			return fmt.Errorf("failed to own cronjob: %v", err)
+		}
+		// this helps during listing of cronjob by labels corresponding to the storageclient
+		utils.AddLabel(cronJob, storageClientNameLabel, r.storageClient.Name)
 		cronJob.Spec = batchv1.CronJobSpec{
 			Schedule:                   "* * * * *",
 			ConcurrencyPolicy:          batchv1.ForbidConcurrent,
@@ -496,17 +447,13 @@ func (s *StorageClientReconciler) reconcileClientStatusReporterJob(instance *v1a
 										"/status-reporter",
 									},
 									Env: []corev1.EnvVar{
-										{
-											Name:  utils.StorageClientNamespaceEnvVar,
-											Value: instance.Namespace,
-										},
 										{
 											Name:  utils.StorageClientNameEnvVar,
-											Value: instance.Name,
+											Value: r.storageClient.Name,
 										},
 										{
 											Name:  utils.OperatorNamespaceEnvVar,
-											Value: s.OperatorNamespace,
+											Value: r.OperatorNamespace,
 										},
 									},
 								},
@@ -526,98 +473,58 @@ func (s *StorageClientReconciler) reconcileClientStatusReporterJob(instance *v1a
 	return reconcile.Result{}, nil
 }
 
-func (s *StorageClientReconciler) list(obj client.ObjectList, listOptions ...client.ListOption) error {
-	return s.Client.List(s.ctx, obj, listOptions...)
+func (r *StorageClientReconciler) list(obj client.ObjectList, listOptions ...client.ListOption) error {
+	return r.Client.List(r.ctx, obj, listOptions...)
 }
 
-func (s *StorageClientReconciler) reconcileDefaultStorageClaims(instance *v1alpha1.StorageClient) error {
-
-	if instance.GetAnnotations()[defaultClaimsProcessedAnnotationKey] == "true" {
-		// we already processed default claims for this client
-		return nil
-	}
-
-	// try to list the default client who is the default storage claims owner
-	claimOwners := &v1alpha1.StorageClientList{}
-	if err := s.list(claimOwners, client.MatchingFields{defaultClaimsOwnerIndexName: "true"}); err != nil {
-		return fmt.Errorf("failed to list default storage claims owner: %v", err)
+func (r *StorageClientReconciler) reconcileBlockStorageClaim() error {
+	blockClaim := &v1alpha1.StorageClaim{}
+	blockClaim.Name = fmt.Sprintf("%s-ceph-rbd", r.storageClient.Name)
+	blockClaim.Spec.Type = "block"
+	blockClaim.Spec.StorageClient = r.storageClient.Name
+	if err := r.own(blockClaim); err != nil {
+		return fmt.Errorf("failed to own storageclaim of type block: %v", err)
 	}
-
-	if len(claimOwners.Items) == 0 {
-		// no other storageclient claims as an owner and take responsibility of creating the default claims by becoming owner
-		if utils.AddAnnotation(instance, defaultClaimsOwnerAnnotationKey, "true") {
-			if err := s.update(instance); err != nil {
-				return fmt.Errorf("not able to claim ownership of creating default storageclaims: %v", err)
-			}
-		}
+	if err := r.create(blockClaim); err != nil && !kerrors.IsAlreadyExists(err) {
+		return fmt.Errorf("failed to create block storageclaim: %v", err)
 	}
+	return nil
+}
 
-	// we successfully took the ownership to create a default claim from this storageclient, so create default claims if not created
-	// after claiming as an owner no other storageclient will try to take ownership for creating default storageclaims
-	annotations := instance.GetAnnotations()
-	if annotations[defaultClaimsOwnerAnnotationKey] == "true" && annotations[defaultClaimsProcessedAnnotationKey] != "true" {
-		if err := s.createDefaultBlockStorageClaim(instance); err != nil && !kerrors.IsAlreadyExists(err) {
-			return fmt.Errorf("failed to create %q storageclaim: %v", defaultBlockStorageClaim, err)
-		}
-		if err := s.createDefaultSharedfileStorageClaim(instance); err != nil && !kerrors.IsAlreadyExists(err) {
-			return fmt.Errorf("failed to create %q storageclaim: %v", defaultSharedfileStorageClaim, err)
-		}
+func (r *StorageClientReconciler) reconcileSharedfileStorageClaim() error {
+	sharedfileClaim := &v1alpha1.StorageClaim{}
+	sharedfileClaim.Name = fmt.Sprintf("%s-cephfs", r.storageClient.Name)
+	sharedfileClaim.Spec.Type = "sharedfile"
+	sharedfileClaim.Spec.StorageClient = r.storageClient.Name
+	if err := r.own(sharedfileClaim); err != nil {
+		return fmt.Errorf("failed to own storageclaim of type sharedfile: %v", err)
 	}
-
-	// annotate that we created default storageclaims successfully and will not retry
-	if utils.AddAnnotation(instance, defaultClaimsProcessedAnnotationKey, "true") {
-		if err := s.update(instance); err != nil {
-			return fmt.Errorf("not able to update annotation for creation of default storageclaims: %v", err)
-		}
+	if err := r.create(sharedfileClaim); err != nil && !kerrors.IsAlreadyExists(err) {
+		return fmt.Errorf("failed to create sharedfile storageclaim: %v", err)
 	}
-
 	return nil
 }
 
-func (s *StorageClientReconciler) createDefaultBlockStorageClaim(instance *v1alpha1.StorageClient) error {
-	storageclaim := &v1alpha1.StorageClaim{}
-	storageclaim.Name = defaultBlockStorageClaim
-	storageclaim.Spec.Type = "block"
-	storageclaim.Spec.StorageClient = &v1alpha1.StorageClientNamespacedName{
-		Name:      instance.Name,
-		Namespace: instance.Namespace,
-	}
-	return s.create(storageclaim)
+func (r *StorageClientReconciler) get(obj client.Object, opts ...client.GetOption) error {
+	key := client.ObjectKeyFromObject(obj)
+	return r.Get(r.ctx, key, obj, opts...)
 }
 
-func (s *StorageClientReconciler) createDefaultSharedfileStorageClaim(instance *v1alpha1.StorageClient) error {
-	sharedfileClaim := &v1alpha1.StorageClaim{}
-	sharedfileClaim.Name = defaultSharedfileStorageClaim
-	sharedfileClaim.Spec.Type = "sharedfile"
-	sharedfileClaim.Spec.StorageClient = &v1alpha1.StorageClientNamespacedName{
-		Name:      instance.Name,
-		Namespace: instance.Namespace,
-	}
-	return s.create(sharedfileClaim)
+func (r *StorageClientReconciler) update(obj client.Object, opts ...client.UpdateOption) error {
+	return r.Update(r.ctx, obj, opts...)
 }
 
-func (s *StorageClientReconciler) deleteDefaultStorageClaims(instance *v1alpha1.StorageClient) error {
-	if instance.GetAnnotations()[defaultClaimsOwnerAnnotationKey] == "true" {
-		blockClaim := &v1alpha1.StorageClaim{}
-		blockClaim.Name = defaultBlockStorageClaim
-		if err := s.delete(blockClaim); err != nil {
-			return fmt.Errorf("failed to remove default storageclaim %q: %v", blockClaim.Name, err)
-		}
+func (r *StorageClientReconciler) create(obj client.Object, opts ...client.CreateOption) error {
+	return r.Create(r.ctx, obj, opts...)
+}
 
-		sharedfsClaim := &v1alpha1.StorageClaim{}
-		sharedfsClaim.Name = defaultSharedfileStorageClaim
-		if err := s.delete(sharedfsClaim); err != nil {
-			return fmt.Errorf("failed to remove default storageclaim %q: %v", blockClaim.Name, err)
-		}
-		s.Log.Info("Successfully deleted default storageclaims")
+func (r *StorageClientReconciler) delete(obj client.Object, opts ...client.DeleteOption) error {
+	if err := r.Delete(r.ctx, obj, opts...); err != nil && !kerrors.IsNotFound(err) {
+		return err
 	}
 	return nil
 }
 
-func (s *StorageClientReconciler) update(obj client.Object, opts ...client.UpdateOption) error {
-	return s.Update(s.ctx, obj, opts...)
-}
-
-func (s *StorageClientReconciler) create(obj client.Object, opts ...client.CreateOption) error {
-	return s.Create(s.ctx, obj, opts...)
+func (r *StorageClientReconciler) own(dependent metav1.Object) error {
+	return controllerutil.SetOwnerReference(r.storageClient, dependent, r.Scheme)
 }
diff --git a/go.mod b/go.mod
index 68b1cce6..ee1e8512 100644
--- a/go.mod
+++ b/go.mod
@@ -13,22 +13,22 @@ require (
 	github.com/go-logr/logr v1.4.1
 	github.com/kubernetes-csi/external-snapshotter/client/v6 v6.3.0
 	github.com/onsi/ginkgo v1.16.5
-	github.com/onsi/gomega v1.30.0
-	github.com/openshift/api v0.0.0-20240301093301-ce10821dc999
-	github.com/operator-framework/api v0.20.0
+	github.com/onsi/gomega v1.32.0
+	github.com/openshift/api v0.0.0-20240323003854-2252c7adfb79
+	github.com/operator-framework/api v0.22.0
 	github.com/pkg/errors v0.9.1
-	github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.70.0
-	github.com/red-hat-storage/ocs-operator/v4 v4.0.0-20240325171742-7a2177d09b00
+	github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.72.0
+	github.com/red-hat-storage/ocs-operator/v4 v4.0.0-20240422111920-faced96485bc
 	github.com/stretchr/testify v1.9.0
-	google.golang.org/grpc v1.60.0
+	google.golang.org/grpc v1.62.1
 	gopkg.in/yaml.v2 v2.4.0
-	k8s.io/api v0.29.2
-	k8s.io/apiextensions-apiserver v0.28.4
-	k8s.io/apimachinery v0.29.2
-	k8s.io/client-go v0.29.2
+	k8s.io/api v0.29.3
+	k8s.io/apiextensions-apiserver v0.29.2
+	k8s.io/apimachinery v0.29.3
+	k8s.io/client-go v0.29.3
 	k8s.io/klog/v2 v2.120.1
-	k8s.io/utils v0.0.0-20240102154912-e7106e64919e
-	sigs.k8s.io/controller-runtime v0.16.3
+	k8s.io/utils v0.0.0-20240310230437-4693a0247e57
+	sigs.k8s.io/controller-runtime v0.17.2
 )
 
 require (
@@ -37,7 +37,7 @@ require (
 	github.com/cespare/xxhash/v2 v2.2.0 // indirect
 	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
 	github.com/emicklei/go-restful/v3 v3.11.3 // indirect
-	github.com/evanphx/json-patch/v5 v5.7.0 // indirect
+	github.com/evanphx/json-patch/v5 v5.8.0 // indirect
 	github.com/fsnotify/fsnotify v1.7.0 // indirect
 	github.com/go-logr/zapr v1.3.0 // indirect
 	github.com/go-openapi/jsonpointer v0.20.3 // indirect
@@ -45,7 +45,7 @@ require (
 	github.com/go-openapi/swag v0.22.10 // 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.3 // indirect
+	github.com/golang/protobuf v1.5.4 // indirect
 	github.com/google/gnostic-models v0.6.8 // indirect
 	github.com/google/go-cmp v0.6.0 // indirect
 	github.com/google/gofuzz v1.2.0 // indirect
@@ -60,7 +60,7 @@ require (
 	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
 	github.com/nxadm/tail v1.4.8 // indirect
 	github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
-	github.com/prometheus/client_golang v1.17.0 // indirect
+	github.com/prometheus/client_golang v1.18.0 // indirect
 	github.com/prometheus/client_model v0.5.0 // indirect
 	github.com/prometheus/common v0.45.0 // indirect
 	github.com/prometheus/procfs v0.12.0 // indirect
@@ -77,12 +77,12 @@ require (
 	golang.org/x/time v0.5.0 // indirect
 	gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
 	google.golang.org/appengine v1.6.8 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
 	google.golang.org/protobuf v1.33.0 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
-	k8s.io/component-base v0.28.4 // indirect
+	k8s.io/component-base v0.29.2 // indirect
 	k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
 	sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
 	sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
diff --git a/go.sum b/go.sum
index 128a3b21..916dd55b 100644
--- a/go.sum
+++ b/go.sum
@@ -12,8 +12,8 @@ github.com/emicklei/go-restful/v3 v3.11.3 h1:yagOQz/38xJmcNeZJtrUcKjkHRltIaIFXKW
 github.com/emicklei/go-restful/v3 v3.11.3/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
 github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls=
 github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/evanphx/json-patch/v5 v5.7.0 h1:nJqP7uwL84RJInrohHfW0Fx3awjbm8qZeFv0nW9SYGc=
-github.com/evanphx/json-patch/v5 v5.7.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ=
+github.com/evanphx/json-patch/v5 v5.8.0 h1:lRj6N9Nci7MvzrXuX6HFzU8XjmhPiXPlsKEy1u0KQro=
+github.com/evanphx/json-patch/v5 v5.8.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
 github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
@@ -44,8 +44,8 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
 github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
 github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
-github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
-github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
 github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
 github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -95,33 +95,33 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
 github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
 github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
 github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
-github.com/onsi/ginkgo/v2 v2.14.0 h1:vSmGj2Z5YPb9JwCWT6z6ihcUvDhuXLc3sJiqd3jMKAY=
-github.com/onsi/ginkgo/v2 v2.14.0/go.mod h1:JkUdW7JkN0V6rFvsHcJ478egV3XH9NxpD27Hal/PhZw=
+github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8=
+github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
 github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
 github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
-github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
-github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
-github.com/openshift/api v0.0.0-20240301093301-ce10821dc999 h1:+S998xHiJApsJZjRAO8wyedU9GfqFd8mtwWly6LqHDo=
-github.com/openshift/api v0.0.0-20240301093301-ce10821dc999/go.mod h1:CxgbWAlvu2iQB0UmKTtRu1YfepRg1/vJ64n2DlIEVz4=
-github.com/operator-framework/api v0.20.0 h1:A2YCRhr+6s0k3pRJacnwjh1Ue8BqjIGuQ2jvPg9XCB4=
-github.com/operator-framework/api v0.20.0/go.mod h1:rXPOhrQ6mMeXqCmpDgt1ALoar9ZlHL+Iy5qut9R99a4=
+github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk=
+github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg=
+github.com/openshift/api v0.0.0-20240323003854-2252c7adfb79 h1:ShXEPrqDUU9rUbvoIhOmQI8D6yHQdklMUks9ZVILTNE=
+github.com/openshift/api v0.0.0-20240323003854-2252c7adfb79/go.mod h1:CxgbWAlvu2iQB0UmKTtRu1YfepRg1/vJ64n2DlIEVz4=
+github.com/operator-framework/api v0.22.0 h1:UZSn+iaQih4rCReezOnWTTJkMyawwV5iLnIItaOzytY=
+github.com/operator-framework/api v0.22.0/go.mod h1:p/7YDbr+n4fmESfZ47yLAV1SvkfE6NU2aX8KhcfI0GA=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.70.0 h1:CFTvpkpVP4EXXZuaZuxpikAoma8xVha/IZKMDc9lw+Y=
-github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.70.0/go.mod h1:npfc20mPOAu7ViOVnATVMbI7PoXvW99EzgJVqkAomIQ=
-github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q=
-github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY=
+github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.72.0 h1:9h7PxMhT1S8lOdadEKJnBh3ELMdO60XkoDV98grYjuM=
+github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.72.0/go.mod h1:4FiLCL664L4dNGeqZewiiD0NS7hhqi/CxyM4UOq5dfM=
+github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk=
+github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA=
 github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
 github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
 github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM=
 github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY=
 github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
 github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
-github.com/red-hat-storage/ocs-operator/v4 v4.0.0-20240325171742-7a2177d09b00 h1:XNUvXtgCSvj/dOWKUXOmzX/a7+cCAhdFilxc+MhO0TY=
-github.com/red-hat-storage/ocs-operator/v4 v4.0.0-20240325171742-7a2177d09b00/go.mod h1:cE35IBM6w9KQfLbmJBR8b/jhoitTkvjPBb/Yp6QQnKI=
+github.com/red-hat-storage/ocs-operator/v4 v4.0.0-20240422111920-faced96485bc h1:bV/ttKjR3nn9jIrOSt5UOttDE6iQ6l+bzLEFPWw335M=
+github.com/red-hat-storage/ocs-operator/v4 v4.0.0-20240422111920-faced96485bc/go.mod h1:e4AElguwRgtyGEW7JtfJvphjYbcYG4hlpvwDYrQFGi8=
 github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
 github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
 github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
@@ -137,8 +137,8 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
-go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
-go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
+go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
+go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
 go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
 go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
 go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
@@ -213,10 +213,10 @@ gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw
 gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
 google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
 google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 h1:6GQBEOdGkX6MMTLT9V+TjtIRZCw9VPD5Z+yHY9wMgS0=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97/go.mod h1:v7nGkzlmW8P3n/bKmWBn2WpBjpOEx8Q6gMueudAmKfY=
-google.golang.org/grpc v1.60.0 h1:6FQAR0kM31P6MRdeluor2w2gPaS4SVNrD/DNTxrQ15k=
-google.golang.org/grpc v1.60.0/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s=
+google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk=
+google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
 google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -244,24 +244,24 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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=
-k8s.io/api v0.29.2 h1:hBC7B9+MU+ptchxEqTNW2DkUosJpp1P+Wn6YncZ474A=
-k8s.io/api v0.29.2/go.mod h1:sdIaaKuU7P44aoyyLlikSLayT6Vb7bvJNCX105xZXY0=
-k8s.io/apiextensions-apiserver v0.28.4 h1:AZpKY/7wQ8n+ZYDtNHbAJBb+N4AXXJvyZx6ww6yAJvU=
-k8s.io/apiextensions-apiserver v0.28.4/go.mod h1:pgQIZ1U8eJSMQcENew/0ShUTlePcSGFq6dxSxf2mwPM=
-k8s.io/apimachinery v0.29.2 h1:EWGpfJ856oj11C52NRCHuU7rFDwxev48z+6DSlGNsV8=
-k8s.io/apimachinery v0.29.2/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU=
-k8s.io/client-go v0.29.2 h1:FEg85el1TeZp+/vYJM7hkDlSTFZ+c5nnK44DJ4FyoRg=
-k8s.io/client-go v0.29.2/go.mod h1:knlvFZE58VpqbQpJNbCbctTVXcd35mMyAAwBdpt4jrA=
-k8s.io/component-base v0.28.4 h1:c/iQLWPdUgI90O+T9TeECg8o7N3YJTiuz2sKxILYcYo=
-k8s.io/component-base v0.28.4/go.mod h1:m9hR0uvqXDybiGL2nf/3Lf0MerAfQXzkfWhUY58JUbU=
+k8s.io/api v0.29.3 h1:2ORfZ7+bGC3YJqGpV0KSDDEVf8hdGQ6A03/50vj8pmw=
+k8s.io/api v0.29.3/go.mod h1:y2yg2NTyHUUkIoTC+phinTnEa3KFM6RZ3szxt014a80=
+k8s.io/apiextensions-apiserver v0.29.2 h1:UK3xB5lOWSnhaCk0RFZ0LUacPZz9RY4wi/yt2Iu+btg=
+k8s.io/apiextensions-apiserver v0.29.2/go.mod h1:aLfYjpA5p3OwtqNXQFkhJ56TB+spV8Gc4wfMhUA3/b8=
+k8s.io/apimachinery v0.29.3 h1:2tbx+5L7RNvqJjn7RIuIKu9XTsIZ9Z5wX2G22XAa5EU=
+k8s.io/apimachinery v0.29.3/go.mod h1:hx/S4V2PNW4OMg3WizRrHutyB5la0iCUbZym+W0EQIU=
+k8s.io/client-go v0.29.3 h1:R/zaZbEAxqComZ9FHeQwOh3Y1ZUs7FaHKZdQtIc2WZg=
+k8s.io/client-go v0.29.3/go.mod h1:tkDisCvgPfiRpxGnOORfkljmS+UrW+WtXAy2fTvXJB0=
+k8s.io/component-base v0.29.2 h1:lpiLyuvPA9yV1aQwGLENYyK7n/8t6l3nn3zAtFTJYe8=
+k8s.io/component-base v0.29.2/go.mod h1:BfB3SLrefbZXiBfbM+2H1dlat21Uewg/5qtKOl8degM=
 k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=
 k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
 k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
 k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
-k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ=
-k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
-sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4=
-sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0=
+k8s.io/utils v0.0.0-20240310230437-4693a0247e57 h1:gbqbevonBh57eILzModw6mrkbwM0gQBEuevE/AaBsHY=
+k8s.io/utils v0.0.0-20240310230437-4693a0247e57/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+sigs.k8s.io/controller-runtime v0.17.2 h1:FwHwD1CTUemg0pW2otk7/U5/i5m2ymzvOXdbeGOUvw0=
+sigs.k8s.io/controller-runtime v0.17.2/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s=
 sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
 sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
 sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
diff --git a/hack/build-catalog.sh b/hack/build-catalog.sh
new file mode 100755
index 00000000..e7a0f799
--- /dev/null
+++ b/hack/build-catalog.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+rm -rf catalog
+rm -rf catalog.Dockerfile
+
+mkdir catalog
+
+${OPM} render --output=yaml ${BUNDLE_IMG} > catalog/ocs-client-bundle.yaml
+${OPM} render --output=yaml ${CSI_ADDONS_BUNDLE_IMG} > catalog/csi-adddons-bundle.yaml
+
+cat << EOF >> catalog/index.yaml
+---
+defaultChannel: alpha
+name: $IMAGE_NAME
+schema: olm.package
+---
+schema: olm.channel
+package: ocs-client-operator
+name: alpha
+entries:
+  - name: $IMAGE_NAME.v$VERSION
+---
+defaultChannel: alpha
+name: $CSI_ADDONS_PACKAGE_NAME
+schema: olm.package
+---
+schema: olm.channel
+package: csi-addons
+name: alpha
+entries:
+  - name: $CSI_ADDONS_PACKAGE_NAME.v$CSI_ADDONS_PACKAGE_VERSION
+EOF
+
+${OPM} validate catalog
+${OPM} generate dockerfile catalog
+${IMAGE_BUILD_CMD} build --platform="linux/amd64" -t ${CATALOG_IMG} -f catalog.Dockerfile .
diff --git a/hack/go-test-setup.sh b/hack/go-test-setup.sh
deleted file mode 100755
index be146f6e..00000000
--- a/hack/go-test-setup.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash
-
-ENVTEST_ASSETS_DIR="${ENVTEST_ASSETS_DIR:-testbin}"
-SKIP_FETCH_TOOLS="${SKIP_FETCH_TOOLS:-}"
-
-mkdir -p "${ENVTEST_ASSETS_DIR}"
-
-pushd "${ENVTEST_ASSETS_DIR}" > /dev/null
-
-
-if [ ! -f setup-envtest.sh ]; then
-	curl -sSLo setup-envtest.sh https://raw.githubusercontent.com/kubernetes-sigs/controller-runtime/v0.8.3/hack/setup-envtest.sh
-fi
-
-source setup-envtest.sh
-
-fetch_envtest_tools "$(pwd)"
-setup_envtest_env "$(pwd)"
-
-popd > /dev/null
diff --git a/hack/go-test.sh b/hack/go-test.sh
deleted file mode 100755
index 7b0d08af..00000000
--- a/hack/go-test.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-
-SCRIPT_DIR="$(dirname "$(realpath "$0")")"
-
-source "${SCRIPT_DIR}/go-test-setup.sh"
-
-set -x
-
-go test -coverprofile cover.out `go list ./... | grep -v "e2e"`
diff --git a/hack/make-bundle-vars.mk b/hack/make-bundle-vars.mk
index 7102623c..0727b0e1 100644
--- a/hack/make-bundle-vars.mk
+++ b/hack/make-bundle-vars.mk
@@ -3,7 +3,7 @@
 # To re-generate a bundle for another specific version without changing the standard setup, you can:
 # - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2)
 # - use environment variables to overwrite this value (e.g export VERSION=0.0.2)
-VERSION ?= 4.12.0
+VERSION ?= 4.16.0
 
 # DEFAULT_CHANNEL defines the default channel used in the bundle.
 # Add a new line here if you would like to change its default config. (E.g DEFAULT_CHANNEL = "stable")
@@ -49,7 +49,7 @@ IMAGE_TAG ?= latest
 IMAGE_NAME ?= ocs-client-operator
 BUNDLE_IMAGE_NAME ?= $(IMAGE_NAME)-bundle
 CSI_ADDONS_BUNDLE_IMAGE_NAME ?= k8s-bundle
-CSI_ADDONS_BUNDLE_IMAGE_TAG ?= v0.5.0
+CSI_ADDONS_BUNDLE_IMAGE_TAG ?= v0.8.0
 CATALOG_IMAGE_NAME ?= $(IMAGE_NAME)-catalog
 
 OCS_CLIENT_CONSOLE_IMG_NAME ?= ocs-client-console
@@ -99,7 +99,7 @@ endif
 
 # csi-addons dependencies
 CSI_ADDONS_PACKAGE_NAME ?= csi-addons
-CSI_ADDONS_PACKAGE_VERSION ?= "0.5.0"
+CSI_ADDONS_PACKAGE_VERSION ?= 0.8.0
 
 ## CSI driver images
 # The following variables define the default CSI container images to deploy
diff --git a/hack/make-project-vars.mk b/hack/make-project-vars.mk
index b572c4a3..9e9db8ec 100644
--- a/hack/make-project-vars.mk
+++ b/hack/make-project-vars.mk
@@ -1,12 +1,21 @@
 PROJECT_DIR := $(PWD)
 BIN_DIR := $(PROJECT_DIR)/bin
-ENVTEST_ASSETS_DIR := $(PROJECT_DIR)/testbin
 
 GOROOT ?= $(shell go env GOROOT)
 GOBIN ?= $(BIN_DIR)
-GOOS ?= linux
-GOARCH ?= amd64
+GOOS ?= $(shell go env GOOS)
+GOARCH ?= $(shell go env GOARCH)
 
 GO_LINT_IMG_LOCATION ?= golangci/golangci-lint
 GO_LINT_IMG_TAG ?= v1.56.2
 GO_LINT_IMG ?= $(GO_LINT_IMG_LOCATION):$(GO_LINT_IMG_TAG)
+
+ENVTEST_K8S_VERSION?=1.26
+
+ifeq ($(IMAGE_BUILD_CMD),)
+IMAGE_BUILD_CMD := $(shell command -v docker || echo "")
+endif
+
+ifeq ($(IMAGE_BUILD_CMD),)
+IMAGE_BUILD_CMD := $(shell command -v podman || echo "")
+endif
diff --git a/hack/make-tools.mk b/hack/make-tools.mk
index 7ced7c87..31708cab 100644
--- a/hack/make-tools.mk
+++ b/hack/make-tools.mk
@@ -2,7 +2,7 @@
 define go-get-tool
 @[ -f $(1) ] || { \
 echo "Downloading $(2)" ;\
-GOBIN=$(PROJECT_DIR)/bin go install $(2) ;\
+$(shell GOBIN=$(PROJECT_DIR)/bin go install $(2)) \
 }
 endef
 
@@ -31,4 +31,8 @@ operator-sdk: ## Download operator-sdk locally if necessary.
 .PHONY: opm
 OPM = $(BIN_DIR)/opm
 opm: ## Download opm locally if necessary.
-	@./hack/get-tool.sh $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.15.1/$(GOOS)-$(GOARCH)-opm
+	@./hack/get-tool.sh $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.20.0/$(GOOS)-$(GOARCH)-opm
+
+ENVTEST ?= $(BIN_DIR)/setup-envtest
+envtest: ## Download envtest-setup locally if necessary.
+	$(call go-get-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest@latest)
diff --git a/main.go b/main.go
index 62cf1e2b..8e372553 100644
--- a/main.go
+++ b/main.go
@@ -17,7 +17,6 @@ limitations under the License.
 package main
 
 import (
-	"context"
 	"flag"
 	"os"
 
@@ -124,12 +123,6 @@ func main() {
 		os.Exit(1)
 	}
 
-	// apiclient.New() returns a client without cache.
-	// cache is not initialized before mgr.Start()
-	// we need this because we need to interact with OperatorCondition
-	apiClient, err := client.New(mgr.GetConfig(), client.Options{
-		Scheme: mgr.GetScheme(),
-	})
 	if err != nil {
 		setupLog.Error(err, "Unable to get Client")
 		os.Exit(1)
@@ -178,14 +171,6 @@ func main() {
 		os.Exit(1)
 	}
 
-	if err = (&controllers.StorageClassClaimMigrationReconciler{
-		Client: mgr.GetClient(),
-		Scheme: mgr.GetScheme(),
-	}).SetupWithManager(mgr); err != nil {
-		setupLog.Error(err, "unable to create controller", "controller", "StorageClassClaim")
-		os.Exit(1)
-	}
-
 	if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
 		setupLog.Error(err, "unable to set up health check")
 		os.Exit(1)
@@ -195,20 +180,13 @@ func main() {
 		os.Exit(1)
 	}
 
-	operatorDeployment, err := utils.GetOperatorDeployment(context.TODO(), apiClient)
-	if err != nil {
-		setupLog.Error(err, "unable to get operator deployment")
-		os.Exit(1)
-	}
-
-	if err = (&controllers.ClusterVersionReconciler{
-		Client:             mgr.GetClient(),
-		Scheme:             mgr.GetScheme(),
-		OperatorDeployment: operatorDeployment,
-		OperatorNamespace:  utils.GetOperatorNamespace(),
-		ConsolePort:        int32(consolePort),
+	if err = (&controllers.OperatorConfigMapReconciler{
+		Client:            mgr.GetClient(),
+		Scheme:            mgr.GetScheme(),
+		OperatorNamespace: utils.GetOperatorNamespace(),
+		ConsolePort:       int32(consolePort),
 	}).SetupWithManager(mgr); err != nil {
-		setupLog.Error(err, "unable to create controller", "controller", "ClusterVersionReconciler")
+		setupLog.Error(err, "unable to create controller", "controller", "OperatorConfigMapReconciler")
 		os.Exit(1)
 	}
 
diff --git a/pkg/csi/csidriver.go b/pkg/csi/csidriver.go
index 18784ab0..dad6f59e 100644
--- a/pkg/csi/csidriver.go
+++ b/pkg/csi/csidriver.go
@@ -54,9 +54,6 @@ func CreateCSIDriver(ctx context.Context, client client.Client, csiDriver *v1k8s
 	return err
 }
 
-// TODO need to check how to delete the csidriver object
-
-//nolint:deadcode,unused
 func DeleteCSIDriver(ctx context.Context, client client.Client, name string) error {
 	csiDriver := &v1k8scsi.CSIDriver{
 		ObjectMeta: metav1.ObjectMeta{
diff --git a/pkg/templates/webhookservice.go b/pkg/templates/webhookservice.go
new file mode 100644
index 00000000..ab5616af
--- /dev/null
+++ b/pkg/templates/webhookservice.go
@@ -0,0 +1,29 @@
+package templates
+
+import (
+	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/util/intstr"
+)
+
+const (
+	// should be <namePrefix from config/default/kustomization><.metadata.name from config/manager/webhook_service.yaml>
+	WebhookServiceName = "ocs-client-operator-webhook-server"
+)
+
+// should match the spec at config/manager/webhook_service.yaml
+var WebhookService = corev1.Service{
+	Spec: corev1.ServiceSpec{
+		Ports: []corev1.ServicePort{
+			{
+				Name:       "https",
+				Port:       443,
+				Protocol:   corev1.ProtocolTCP,
+				TargetPort: intstr.FromInt32(7443),
+			},
+		},
+		Selector: map[string]string{
+			"app": "ocs-client-operator",
+		},
+		Type: corev1.ServiceTypeClusterIP,
+	},
+}
diff --git a/pkg/utils/deployment.go b/pkg/utils/deployment.go
deleted file mode 100644
index 37008eec..00000000
--- a/pkg/utils/deployment.go
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-Copyright 2022 Red Hat, Inc.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package utils
-
-import (
-	"context"
-	"os"
-	"strings"
-
-	appsv1 "k8s.io/api/apps/v1"
-	"k8s.io/apimachinery/pkg/types"
-	"sigs.k8s.io/controller-runtime/pkg/client"
-)
-
-// GetOperatorDeployment returns the operator deployment object
-func GetOperatorDeployment(ctx context.Context, c client.Client) (*appsv1.Deployment, error) {
-	deployment := &appsv1.Deployment{}
-	podNameStrings := strings.Split(os.Getenv(OperatorPodNameEnvVar), "-")
-	deploymentName := strings.Join(podNameStrings[:len(podNameStrings)-2], "-")
-	err := c.Get(ctx, types.NamespacedName{Name: deploymentName, Namespace: GetOperatorNamespace()}, deployment)
-	if err != nil {
-		return nil, err
-	}
-
-	return deployment, nil
-}
diff --git a/pkg/utils/k8sutils.go b/pkg/utils/k8sutils.go
index 5d47b2c2..11dce7a8 100644
--- a/pkg/utils/k8sutils.go
+++ b/pkg/utils/k8sutils.go
@@ -34,9 +34,6 @@ const OperatorPodNameEnvVar = "OPERATOR_POD_NAME"
 // StorageClientNameEnvVar is the constant for env variable STORAGE_CLIENT_NAME
 const StorageClientNameEnvVar = "STORAGE_CLIENT_NAME"
 
-// StorageClientNamespaceEnvVar is the constant for env variable STORAGE_CLIENT_NAMESPACE
-const StorageClientNamespaceEnvVar = "STORAGE_CLIENT_NAMESPACE"
-
 const StatusReporterImageEnvVar = "STATUS_REPORTER_IMAGE"
 
 // Value corresponding to annotation key has subscription channel
diff --git a/service/status-report/main.go b/service/status-report/main.go
index 67fb3d2e..5d62f59b 100644
--- a/service/status-report/main.go
+++ b/service/status-report/main.go
@@ -18,6 +18,8 @@ package main
 
 import (
 	"context"
+	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/util/yaml"
 	"os"
 	"strings"
 	"time"
@@ -38,7 +40,9 @@ import (
 )
 
 const (
-	csvPrefix = "ocs-client-operator"
+	csvPrefix              = "ocs-client-operator"
+	clusterConfigNamespace = "kube-system"
+	clusterConfigName      = "cluster-config-v1"
 )
 
 func main() {
@@ -70,11 +74,6 @@ func main() {
 
 	ctx := context.Background()
 
-	storageClientNamespace, isSet := os.LookupEnv(utils.StorageClientNamespaceEnvVar)
-	if !isSet {
-		klog.Exitf("%s env var not set", utils.StorageClientNamespaceEnvVar)
-	}
-
 	storageClientName, isSet := os.LookupEnv(utils.StorageClientNameEnvVar)
 	if !isSet {
 		klog.Exitf("%s env var not set", utils.StorageClientNameEnvVar)
@@ -86,15 +85,14 @@ func main() {
 	}
 	storageClient := &v1alpha1.StorageClient{}
 	storageClient.Name = storageClientName
-	storageClient.Namespace = storageClientNamespace
 
-	if err = cl.Get(ctx, types.NamespacedName{Name: storageClient.Name, Namespace: storageClient.Namespace}, storageClient); err != nil {
+	if err = cl.Get(ctx, client.ObjectKeyFromObject(storageClient), storageClient); err != nil {
 		klog.Exitf("Failed to get storageClient %q/%q: %v", storageClient.Namespace, storageClient.Name, err)
 	}
 
 	var oprVersion string
 	csvList := opv1a1.ClusterServiceVersionList{}
-	if err = cl.List(ctx, &csvList, client.InNamespace(storageClientNamespace)); err != nil {
+	if err = cl.List(ctx, &csvList, client.InNamespace(operatorNamespace)); err != nil {
 		klog.Warningf("Failed to list csv resources: %v", err)
 	} else {
 		item := utils.Find(csvList.Items, func(csv *opv1a1.ClusterServiceVersion) bool {
@@ -127,9 +125,27 @@ func main() {
 		klog.Warningf("Unable to find ocp version with completed update")
 	}
 
-	namespacedName := types.NamespacedName{
-		Namespace: storageClient.Namespace,
-		Name:      storageClient.Name,
+	clusterConfig := &corev1.ConfigMap{}
+	clusterConfig.Name = clusterConfigName
+	clusterConfig.Namespace = clusterConfigNamespace
+
+	if err = cl.Get(ctx, client.ObjectKeyFromObject(clusterConfig), clusterConfig); err != nil {
+		klog.Warningf("Failed to get clusterConfig %q/%q: %v", clusterConfig.Namespace, clusterConfig.Name, err)
+	}
+
+	clusterMetadataYAML := clusterConfig.Data["install-config"]
+	clusterMetadata := struct {
+		Metadata struct {
+			Name string `yaml:"name"`
+		} `yaml:"metadata"`
+	}{}
+	err = yaml.Unmarshal([]byte(clusterMetadataYAML), &clusterMetadata)
+	if err != nil {
+		klog.Warningf("Fatal error, %v", err)
+	}
+	clusterName := ""
+	if len(clusterMetadata.Metadata.Name) > 0 {
+		clusterName = clusterMetadata.Metadata.Name
 	}
 
 	providerClient, err := providerclient.NewProviderClient(
@@ -146,7 +162,8 @@ func main() {
 		SetPlatformVersion(pltVersion).
 		SetOperatorVersion(oprVersion).
 		SetClusterID(string(clusterID)).
-		SetNamespacedName(namespacedName.String())
+		SetClusterName(clusterName).
+		SetClientName(storageClientName)
 	statusResponse, err := providerClient.ReportStatus(ctx, storageClient.Status.ConsumerID, status)
 	if err != nil {
 		klog.Exitf("Failed to report status of storageClient %v: %v", storageClient.Status.ConsumerID, err)
diff --git a/vendor/github.com/evanphx/json-patch/v5/internal/json/decode.go b/vendor/github.com/evanphx/json-patch/v5/internal/json/decode.go
new file mode 100644
index 00000000..e9bb0efe
--- /dev/null
+++ b/vendor/github.com/evanphx/json-patch/v5/internal/json/decode.go
@@ -0,0 +1,1385 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Represents JSON data structure using native Go types: booleans, floats,
+// strings, arrays, and maps.
+
+package json
+
+import (
+	"encoding"
+	"encoding/base64"
+	"fmt"
+	"reflect"
+	"strconv"
+	"strings"
+	"sync"
+	"unicode"
+	"unicode/utf16"
+	"unicode/utf8"
+)
+
+// Unmarshal parses the JSON-encoded data and stores the result
+// in the value pointed to by v. If v is nil or not a pointer,
+// Unmarshal returns an InvalidUnmarshalError.
+//
+// Unmarshal uses the inverse of the encodings that
+// Marshal uses, allocating maps, slices, and pointers as necessary,
+// with the following additional rules:
+//
+// To unmarshal JSON into a pointer, Unmarshal first handles the case of
+// the JSON being the JSON literal null. In that case, Unmarshal sets
+// the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into
+// the value pointed at by the pointer. If the pointer is nil, Unmarshal
+// allocates a new value for it to point to.
+//
+// To unmarshal JSON into a value implementing the Unmarshaler interface,
+// Unmarshal calls that value's UnmarshalJSON method, including
+// when the input is a JSON null.
+// Otherwise, if the value implements encoding.TextUnmarshaler
+// and the input is a JSON quoted string, Unmarshal calls that value's
+// UnmarshalText method with the unquoted form of the string.
+//
+// To unmarshal JSON into a struct, Unmarshal matches incoming object
+// keys to the keys used by Marshal (either the struct field name or its tag),
+// preferring an exact match but also accepting a case-insensitive match. By
+// default, object keys which don't have a corresponding struct field are
+// ignored (see Decoder.DisallowUnknownFields for an alternative).
+//
+// To unmarshal JSON into an interface value,
+// Unmarshal stores one of these in the interface value:
+//
+//	bool, for JSON booleans
+//	float64, for JSON numbers
+//	string, for JSON strings
+//	[]interface{}, for JSON arrays
+//	map[string]interface{}, for JSON objects
+//	nil for JSON null
+//
+// To unmarshal a JSON array into a slice, Unmarshal resets the slice length
+// to zero and then appends each element to the slice.
+// As a special case, to unmarshal an empty JSON array into a slice,
+// Unmarshal replaces the slice with a new empty slice.
+//
+// To unmarshal a JSON array into a Go array, Unmarshal decodes
+// JSON array elements into corresponding Go array elements.
+// If the Go array is smaller than the JSON array,
+// the additional JSON array elements are discarded.
+// If the JSON array is smaller than the Go array,
+// the additional Go array elements are set to zero values.
+//
+// To unmarshal a JSON object into a map, Unmarshal first establishes a map to
+// use. If the map is nil, Unmarshal allocates a new map. Otherwise Unmarshal
+// reuses the existing map, keeping existing entries. Unmarshal then stores
+// key-value pairs from the JSON object into the map. The map's key type must
+// either be any string type, an integer, implement json.Unmarshaler, or
+// implement encoding.TextUnmarshaler.
+//
+// If the JSON-encoded data contain a syntax error, Unmarshal returns a SyntaxError.
+//
+// If a JSON value is not appropriate for a given target type,
+// or if a JSON number overflows the target type, Unmarshal
+// skips that field and completes the unmarshaling as best it can.
+// If no more serious errors are encountered, Unmarshal returns
+// an UnmarshalTypeError describing the earliest such error. In any
+// case, it's not guaranteed that all the remaining fields following
+// the problematic one will be unmarshaled into the target object.
+//
+// The JSON null value unmarshals into an interface, map, pointer, or slice
+// by setting that Go value to nil. Because null is often used in JSON to mean
+// “not present,” unmarshaling a JSON null into any other Go type has no effect
+// on the value and produces no error.
+//
+// When unmarshaling quoted strings, invalid UTF-8 or
+// invalid UTF-16 surrogate pairs are not treated as an error.
+// Instead, they are replaced by the Unicode replacement
+// character U+FFFD.
+func Unmarshal(data []byte, v any) error {
+	// Check for well-formedness.
+	// Avoids filling out half a data structure
+	// before discovering a JSON syntax error.
+	d := ds.Get().(*decodeState)
+	defer ds.Put(d)
+	//var d decodeState
+	d.useNumber = true
+	err := checkValid(data, &d.scan)
+	if err != nil {
+		return err
+	}
+
+	d.init(data)
+	return d.unmarshal(v)
+}
+
+var ds = sync.Pool{
+	New: func() any {
+		return new(decodeState)
+	},
+}
+
+func UnmarshalWithKeys(data []byte, v any) ([]string, error) {
+	// Check for well-formedness.
+	// Avoids filling out half a data structure
+	// before discovering a JSON syntax error.
+
+	d := ds.Get().(*decodeState)
+	defer ds.Put(d)
+	//var d decodeState
+	d.useNumber = true
+	err := checkValid(data, &d.scan)
+	if err != nil {
+		return nil, err
+	}
+
+	d.init(data)
+	err = d.unmarshal(v)
+	if err != nil {
+		return nil, err
+	}
+
+	return d.lastKeys, nil
+}
+
+func UnmarshalValid(data []byte, v any) error {
+	// Check for well-formedness.
+	// Avoids filling out half a data structure
+	// before discovering a JSON syntax error.
+	d := ds.Get().(*decodeState)
+	defer ds.Put(d)
+	//var d decodeState
+	d.useNumber = true
+
+	d.init(data)
+	return d.unmarshal(v)
+}
+
+func UnmarshalValidWithKeys(data []byte, v any) ([]string, error) {
+	// Check for well-formedness.
+	// Avoids filling out half a data structure
+	// before discovering a JSON syntax error.
+
+	d := ds.Get().(*decodeState)
+	defer ds.Put(d)
+	//var d decodeState
+	d.useNumber = true
+
+	d.init(data)
+	err := d.unmarshal(v)
+	if err != nil {
+		return nil, err
+	}
+
+	return d.lastKeys, nil
+}
+
+// Unmarshaler is the interface implemented by types
+// that can unmarshal a JSON description of themselves.
+// The input can be assumed to be a valid encoding of
+// a JSON value. UnmarshalJSON must copy the JSON data
+// if it wishes to retain the data after returning.
+//
+// By convention, to approximate the behavior of Unmarshal itself,
+// Unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op.
+type Unmarshaler interface {
+	UnmarshalJSON([]byte) error
+}
+
+// An UnmarshalTypeError describes a JSON value that was
+// not appropriate for a value of a specific Go type.
+type UnmarshalTypeError struct {
+	Value  string       // description of JSON value - "bool", "array", "number -5"
+	Type   reflect.Type // type of Go value it could not be assigned to
+	Offset int64        // error occurred after reading Offset bytes
+	Struct string       // name of the struct type containing the field
+	Field  string       // the full path from root node to the field
+}
+
+func (e *UnmarshalTypeError) Error() string {
+	if e.Struct != "" || e.Field != "" {
+		return "json: cannot unmarshal " + e.Value + " into Go struct field " + e.Struct + "." + e.Field + " of type " + e.Type.String()
+	}
+	return "json: cannot unmarshal " + e.Value + " into Go value of type " + e.Type.String()
+}
+
+// An UnmarshalFieldError describes a JSON object key that
+// led to an unexported (and therefore unwritable) struct field.
+//
+// Deprecated: No longer used; kept for compatibility.
+type UnmarshalFieldError struct {
+	Key   string
+	Type  reflect.Type
+	Field reflect.StructField
+}
+
+func (e *UnmarshalFieldError) Error() string {
+	return "json: cannot unmarshal object key " + strconv.Quote(e.Key) + " into unexported field " + e.Field.Name + " of type " + e.Type.String()
+}
+
+// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal.
+// (The argument to Unmarshal must be a non-nil pointer.)
+type InvalidUnmarshalError struct {
+	Type reflect.Type
+}
+
+func (e *InvalidUnmarshalError) Error() string {
+	if e.Type == nil {
+		return "json: Unmarshal(nil)"
+	}
+
+	if e.Type.Kind() != reflect.Pointer {
+		return "json: Unmarshal(non-pointer " + e.Type.String() + ")"
+	}
+	return "json: Unmarshal(nil " + e.Type.String() + ")"
+}
+
+func (d *decodeState) unmarshal(v any) error {
+	rv := reflect.ValueOf(v)
+	if rv.Kind() != reflect.Pointer || rv.IsNil() {
+		return &InvalidUnmarshalError{reflect.TypeOf(v)}
+	}
+
+	d.scan.reset()
+	d.scanWhile(scanSkipSpace)
+	// We decode rv not rv.Elem because the Unmarshaler interface
+	// test must be applied at the top level of the value.
+	err := d.value(rv)
+	if err != nil {
+		return d.addErrorContext(err)
+	}
+	return d.savedError
+}
+
+// A Number represents a JSON number literal.
+type Number string
+
+// String returns the literal text of the number.
+func (n Number) String() string { return string(n) }
+
+// Float64 returns the number as a float64.
+func (n Number) Float64() (float64, error) {
+	return strconv.ParseFloat(string(n), 64)
+}
+
+// Int64 returns the number as an int64.
+func (n Number) Int64() (int64, error) {
+	return strconv.ParseInt(string(n), 10, 64)
+}
+
+// An errorContext provides context for type errors during decoding.
+type errorContext struct {
+	Struct     reflect.Type
+	FieldStack []string
+}
+
+// decodeState represents the state while decoding a JSON value.
+type decodeState struct {
+	data                  []byte
+	off                   int // next read offset in data
+	opcode                int // last read result
+	scan                  scanner
+	errorContext          *errorContext
+	savedError            error
+	useNumber             bool
+	disallowUnknownFields bool
+	lastKeys              []string
+}
+
+// readIndex returns the position of the last byte read.
+func (d *decodeState) readIndex() int {
+	return d.off - 1
+}
+
+// phasePanicMsg is used as a panic message when we end up with something that
+// shouldn't happen. It can indicate a bug in the JSON decoder, or that
+// something is editing the data slice while the decoder executes.
+const phasePanicMsg = "JSON decoder out of sync - data changing underfoot?"
+
+func (d *decodeState) init(data []byte) *decodeState {
+	d.data = data
+	d.off = 0
+	d.savedError = nil
+	if d.errorContext != nil {
+		d.errorContext.Struct = nil
+		// Reuse the allocated space for the FieldStack slice.
+		d.errorContext.FieldStack = d.errorContext.FieldStack[:0]
+	}
+	return d
+}
+
+// saveError saves the first err it is called with,
+// for reporting at the end of the unmarshal.
+func (d *decodeState) saveError(err error) {
+	if d.savedError == nil {
+		d.savedError = d.addErrorContext(err)
+	}
+}
+
+// addErrorContext returns a new error enhanced with information from d.errorContext
+func (d *decodeState) addErrorContext(err error) error {
+	if d.errorContext != nil && (d.errorContext.Struct != nil || len(d.errorContext.FieldStack) > 0) {
+		switch err := err.(type) {
+		case *UnmarshalTypeError:
+			err.Struct = d.errorContext.Struct.Name()
+			err.Field = strings.Join(d.errorContext.FieldStack, ".")
+		}
+	}
+	return err
+}
+
+// skip scans to the end of what was started.
+func (d *decodeState) skip() {
+	s, data, i := &d.scan, d.data, d.off
+	depth := len(s.parseState)
+	for {
+		op := s.step(s, data[i])
+		i++
+		if len(s.parseState) < depth {
+			d.off = i
+			d.opcode = op
+			return
+		}
+	}
+}
+
+// scanNext processes the byte at d.data[d.off].
+func (d *decodeState) scanNext() {
+	if d.off < len(d.data) {
+		d.opcode = d.scan.step(&d.scan, d.data[d.off])
+		d.off++
+	} else {
+		d.opcode = d.scan.eof()
+		d.off = len(d.data) + 1 // mark processed EOF with len+1
+	}
+}
+
+// scanWhile processes bytes in d.data[d.off:] until it
+// receives a scan code not equal to op.
+func (d *decodeState) scanWhile(op int) {
+	s, data, i := &d.scan, d.data, d.off
+	for i < len(data) {
+		newOp := s.step(s, data[i])
+		i++
+		if newOp != op {
+			d.opcode = newOp
+			d.off = i
+			return
+		}
+	}
+
+	d.off = len(data) + 1 // mark processed EOF with len+1
+	d.opcode = d.scan.eof()
+}
+
+// rescanLiteral is similar to scanWhile(scanContinue), but it specialises the
+// common case where we're decoding a literal. The decoder scans the input
+// twice, once for syntax errors and to check the length of the value, and the
+// second to perform the decoding.
+//
+// Only in the second step do we use decodeState to tokenize literals, so we
+// know there aren't any syntax errors. We can take advantage of that knowledge,
+// and scan a literal's bytes much more quickly.
+func (d *decodeState) rescanLiteral() {
+	data, i := d.data, d.off
+Switch:
+	switch data[i-1] {
+	case '"': // string
+		for ; i < len(data); i++ {
+			switch data[i] {
+			case '\\':
+				i++ // escaped char
+			case '"':
+				i++ // tokenize the closing quote too
+				break Switch
+			}
+		}
+	case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-': // number
+		for ; i < len(data); i++ {
+			switch data[i] {
+			case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+				'.', 'e', 'E', '+', '-':
+			default:
+				break Switch
+			}
+		}
+	case 't': // true
+		i += len("rue")
+	case 'f': // false
+		i += len("alse")
+	case 'n': // null
+		i += len("ull")
+	}
+	if i < len(data) {
+		d.opcode = stateEndValue(&d.scan, data[i])
+	} else {
+		d.opcode = scanEnd
+	}
+	d.off = i + 1
+}
+
+// value consumes a JSON value from d.data[d.off-1:], decoding into v, and
+// reads the following byte ahead. If v is invalid, the value is discarded.
+// The first byte of the value has been read already.
+func (d *decodeState) value(v reflect.Value) error {
+	switch d.opcode {
+	default:
+		panic(phasePanicMsg)
+
+	case scanBeginArray:
+		if v.IsValid() {
+			if err := d.array(v); err != nil {
+				return err
+			}
+		} else {
+			d.skip()
+		}
+		d.scanNext()
+
+	case scanBeginObject:
+		if v.IsValid() {
+			if err := d.object(v); err != nil {
+				return err
+			}
+		} else {
+			d.skip()
+		}
+		d.scanNext()
+
+	case scanBeginLiteral:
+		// All bytes inside literal return scanContinue op code.
+		start := d.readIndex()
+		d.rescanLiteral()
+
+		if v.IsValid() {
+			if err := d.literalStore(d.data[start:d.readIndex()], v, false); err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+type unquotedValue struct{}
+
+// valueQuoted is like value but decodes a
+// quoted string literal or literal null into an interface value.
+// If it finds anything other than a quoted string literal or null,
+// valueQuoted returns unquotedValue{}.
+func (d *decodeState) valueQuoted() any {
+	switch d.opcode {
+	default:
+		panic(phasePanicMsg)
+
+	case scanBeginArray, scanBeginObject:
+		d.skip()
+		d.scanNext()
+
+	case scanBeginLiteral:
+		v := d.literalInterface()
+		switch v.(type) {
+		case nil, string:
+			return v
+		}
+	}
+	return unquotedValue{}
+}
+
+// indirect walks down v allocating pointers as needed,
+// until it gets to a non-pointer.
+// If it encounters an Unmarshaler, indirect stops and returns that.
+// If decodingNull is true, indirect stops at the first settable pointer so it
+// can be set to nil.
+func indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnmarshaler, reflect.Value) {
+	// Issue #24153 indicates that it is generally not a guaranteed property
+	// that you may round-trip a reflect.Value by calling Value.Addr().Elem()
+	// and expect the value to still be settable for values derived from
+	// unexported embedded struct fields.
+	//
+	// The logic below effectively does this when it first addresses the value
+	// (to satisfy possible pointer methods) and continues to dereference
+	// subsequent pointers as necessary.
+	//
+	// After the first round-trip, we set v back to the original value to
+	// preserve the original RW flags contained in reflect.Value.
+	v0 := v
+	haveAddr := false
+
+	// If v is a named type and is addressable,
+	// start with its address, so that if the type has pointer methods,
+	// we find them.
+	if v.Kind() != reflect.Pointer && v.Type().Name() != "" && v.CanAddr() {
+		haveAddr = true
+		v = v.Addr()
+	}
+	for {
+		// Load value from interface, but only if the result will be
+		// usefully addressable.
+		if v.Kind() == reflect.Interface && !v.IsNil() {
+			e := v.Elem()
+			if e.Kind() == reflect.Pointer && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Pointer) {
+				haveAddr = false
+				v = e
+				continue
+			}
+		}
+
+		if v.Kind() != reflect.Pointer {
+			break
+		}
+
+		if decodingNull && v.CanSet() {
+			break
+		}
+
+		// Prevent infinite loop if v is an interface pointing to its own address:
+		//     var v interface{}
+		//     v = &v
+		if v.Elem().Kind() == reflect.Interface && v.Elem().Elem() == v {
+			v = v.Elem()
+			break
+		}
+		if v.IsNil() {
+			v.Set(reflect.New(v.Type().Elem()))
+		}
+		if v.Type().NumMethod() > 0 && v.CanInterface() {
+			if u, ok := v.Interface().(Unmarshaler); ok {
+				return u, nil, reflect.Value{}
+			}
+			if !decodingNull {
+				if u, ok := v.Interface().(encoding.TextUnmarshaler); ok {
+					return nil, u, reflect.Value{}
+				}
+			}
+		}
+
+		if haveAddr {
+			v = v0 // restore original value after round-trip Value.Addr().Elem()
+			haveAddr = false
+		} else {
+			v = v.Elem()
+		}
+	}
+	return nil, nil, v
+}
+
+// array consumes an array from d.data[d.off-1:], decoding into v.
+// The first byte of the array ('[') has been read already.
+func (d *decodeState) array(v reflect.Value) error {
+	// Check for unmarshaler.
+	u, ut, pv := indirect(v, false)
+	if u != nil {
+		start := d.readIndex()
+		d.skip()
+		return u.UnmarshalJSON(d.data[start:d.off])
+	}
+	if ut != nil {
+		d.saveError(&UnmarshalTypeError{Value: "array", Type: v.Type(), Offset: int64(d.off)})
+		d.skip()
+		return nil
+	}
+	v = pv
+
+	// Check type of target.
+	switch v.Kind() {
+	case reflect.Interface:
+		if v.NumMethod() == 0 {
+			// Decoding into nil interface? Switch to non-reflect code.
+			ai := d.arrayInterface()
+			v.Set(reflect.ValueOf(ai))
+			return nil
+		}
+		// Otherwise it's invalid.
+		fallthrough
+	default:
+		d.saveError(&UnmarshalTypeError{Value: "array", Type: v.Type(), Offset: int64(d.off)})
+		d.skip()
+		return nil
+	case reflect.Array, reflect.Slice:
+		break
+	}
+
+	i := 0
+	for {
+		// Look ahead for ] - can only happen on first iteration.
+		d.scanWhile(scanSkipSpace)
+		if d.opcode == scanEndArray {
+			break
+		}
+
+		// Get element of array, growing if necessary.
+		if v.Kind() == reflect.Slice {
+			// Grow slice if necessary
+			if i >= v.Cap() {
+				newcap := v.Cap() + v.Cap()/2
+				if newcap < 4 {
+					newcap = 4
+				}
+				newv := reflect.MakeSlice(v.Type(), v.Len(), newcap)
+				reflect.Copy(newv, v)
+				v.Set(newv)
+			}
+			if i >= v.Len() {
+				v.SetLen(i + 1)
+			}
+		}
+
+		if i < v.Len() {
+			// Decode into element.
+			if err := d.value(v.Index(i)); err != nil {
+				return err
+			}
+		} else {
+			// Ran out of fixed array: skip.
+			if err := d.value(reflect.Value{}); err != nil {
+				return err
+			}
+		}
+		i++
+
+		// Next token must be , or ].
+		if d.opcode == scanSkipSpace {
+			d.scanWhile(scanSkipSpace)
+		}
+		if d.opcode == scanEndArray {
+			break
+		}
+		if d.opcode != scanArrayValue {
+			panic(phasePanicMsg)
+		}
+	}
+
+	if i < v.Len() {
+		if v.Kind() == reflect.Array {
+			// Array. Zero the rest.
+			z := reflect.Zero(v.Type().Elem())
+			for ; i < v.Len(); i++ {
+				v.Index(i).Set(z)
+			}
+		} else {
+			v.SetLen(i)
+		}
+	}
+	if i == 0 && v.Kind() == reflect.Slice {
+		v.Set(reflect.MakeSlice(v.Type(), 0, 0))
+	}
+	return nil
+}
+
+var nullLiteral = []byte("null")
+var textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
+
+// object consumes an object from d.data[d.off-1:], decoding into v.
+// The first byte ('{') of the object has been read already.
+func (d *decodeState) object(v reflect.Value) error {
+	// Check for unmarshaler.
+	u, ut, pv := indirect(v, false)
+	if u != nil {
+		start := d.readIndex()
+		d.skip()
+		return u.UnmarshalJSON(d.data[start:d.off])
+	}
+	if ut != nil {
+		d.saveError(&UnmarshalTypeError{Value: "object", Type: v.Type(), Offset: int64(d.off)})
+		d.skip()
+		return nil
+	}
+	v = pv
+	t := v.Type()
+
+	// Decoding into nil interface? Switch to non-reflect code.
+	if v.Kind() == reflect.Interface && v.NumMethod() == 0 {
+		oi := d.objectInterface()
+		v.Set(reflect.ValueOf(oi))
+		return nil
+	}
+
+	var fields structFields
+
+	// Check type of target:
+	//   struct or
+	//   map[T1]T2 where T1 is string, an integer type,
+	//             or an encoding.TextUnmarshaler
+	switch v.Kind() {
+	case reflect.Map:
+		// Map key must either have string kind, have an integer kind,
+		// or be an encoding.TextUnmarshaler.
+		switch t.Key().Kind() {
+		case reflect.String,
+			reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+			reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		default:
+			if !reflect.PointerTo(t.Key()).Implements(textUnmarshalerType) {
+				d.saveError(&UnmarshalTypeError{Value: "object", Type: t, Offset: int64(d.off)})
+				d.skip()
+				return nil
+			}
+		}
+		if v.IsNil() {
+			v.Set(reflect.MakeMap(t))
+		}
+	case reflect.Struct:
+		fields = cachedTypeFields(t)
+		// ok
+	default:
+		d.saveError(&UnmarshalTypeError{Value: "object", Type: t, Offset: int64(d.off)})
+		d.skip()
+		return nil
+	}
+
+	var mapElem reflect.Value
+	var origErrorContext errorContext
+	if d.errorContext != nil {
+		origErrorContext = *d.errorContext
+	}
+
+	var keys []string
+
+	for {
+		// Read opening " of string key or closing }.
+		d.scanWhile(scanSkipSpace)
+		if d.opcode == scanEndObject {
+			// closing } - can only happen on first iteration.
+			break
+		}
+		if d.opcode != scanBeginLiteral {
+			panic(phasePanicMsg)
+		}
+
+		// Read key.
+		start := d.readIndex()
+		d.rescanLiteral()
+		item := d.data[start:d.readIndex()]
+		key, ok := unquoteBytes(item)
+		if !ok {
+			panic(phasePanicMsg)
+		}
+
+		keys = append(keys, string(key))
+
+		// Figure out field corresponding to key.
+		var subv reflect.Value
+		destring := false // whether the value is wrapped in a string to be decoded first
+
+		if v.Kind() == reflect.Map {
+			elemType := t.Elem()
+			if !mapElem.IsValid() {
+				mapElem = reflect.New(elemType).Elem()
+			} else {
+				mapElem.Set(reflect.Zero(elemType))
+			}
+			subv = mapElem
+		} else {
+			var f *field
+			if i, ok := fields.nameIndex[string(key)]; ok {
+				// Found an exact name match.
+				f = &fields.list[i]
+			} else {
+				// Fall back to the expensive case-insensitive
+				// linear search.
+				for i := range fields.list {
+					ff := &fields.list[i]
+					if ff.equalFold(ff.nameBytes, key) {
+						f = ff
+						break
+					}
+				}
+			}
+			if f != nil {
+				subv = v
+				destring = f.quoted
+				for _, i := range f.index {
+					if subv.Kind() == reflect.Pointer {
+						if subv.IsNil() {
+							// If a struct embeds a pointer to an unexported type,
+							// it is not possible to set a newly allocated value
+							// since the field is unexported.
+							//
+							// See https://golang.org/issue/21357
+							if !subv.CanSet() {
+								d.saveError(fmt.Errorf("json: cannot set embedded pointer to unexported struct: %v", subv.Type().Elem()))
+								// Invalidate subv to ensure d.value(subv) skips over
+								// the JSON value without assigning it to subv.
+								subv = reflect.Value{}
+								destring = false
+								break
+							}
+							subv.Set(reflect.New(subv.Type().Elem()))
+						}
+						subv = subv.Elem()
+					}
+					subv = subv.Field(i)
+				}
+				if d.errorContext == nil {
+					d.errorContext = new(errorContext)
+				}
+				d.errorContext.FieldStack = append(d.errorContext.FieldStack, f.name)
+				d.errorContext.Struct = t
+			} else if d.disallowUnknownFields {
+				d.saveError(fmt.Errorf("json: unknown field %q", key))
+			}
+		}
+
+		// Read : before value.
+		if d.opcode == scanSkipSpace {
+			d.scanWhile(scanSkipSpace)
+		}
+		if d.opcode != scanObjectKey {
+			panic(phasePanicMsg)
+		}
+		d.scanWhile(scanSkipSpace)
+
+		if destring {
+			switch qv := d.valueQuoted().(type) {
+			case nil:
+				if err := d.literalStore(nullLiteral, subv, false); err != nil {
+					return err
+				}
+			case string:
+				if err := d.literalStore([]byte(qv), subv, true); err != nil {
+					return err
+				}
+			default:
+				d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v", subv.Type()))
+			}
+		} else {
+			if err := d.value(subv); err != nil {
+				return err
+			}
+		}
+
+		// Write value back to map;
+		// if using struct, subv points into struct already.
+		if v.Kind() == reflect.Map {
+			kt := t.Key()
+			var kv reflect.Value
+			switch {
+			case reflect.PointerTo(kt).Implements(textUnmarshalerType):
+				kv = reflect.New(kt)
+				if err := d.literalStore(item, kv, true); err != nil {
+					return err
+				}
+				kv = kv.Elem()
+			case kt.Kind() == reflect.String:
+				kv = reflect.ValueOf(key).Convert(kt)
+			default:
+				switch kt.Kind() {
+				case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+					s := string(key)
+					n, err := strconv.ParseInt(s, 10, 64)
+					if err != nil || reflect.Zero(kt).OverflowInt(n) {
+						d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: kt, Offset: int64(start + 1)})
+						break
+					}
+					kv = reflect.ValueOf(n).Convert(kt)
+				case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+					s := string(key)
+					n, err := strconv.ParseUint(s, 10, 64)
+					if err != nil || reflect.Zero(kt).OverflowUint(n) {
+						d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: kt, Offset: int64(start + 1)})
+						break
+					}
+					kv = reflect.ValueOf(n).Convert(kt)
+				default:
+					panic("json: Unexpected key type") // should never occur
+				}
+			}
+			if kv.IsValid() {
+				v.SetMapIndex(kv, subv)
+			}
+		}
+
+		// Next token must be , or }.
+		if d.opcode == scanSkipSpace {
+			d.scanWhile(scanSkipSpace)
+		}
+		if d.errorContext != nil {
+			// Reset errorContext to its original state.
+			// Keep the same underlying array for FieldStack, to reuse the
+			// space and avoid unnecessary allocs.
+			d.errorContext.FieldStack = d.errorContext.FieldStack[:len(origErrorContext.FieldStack)]
+			d.errorContext.Struct = origErrorContext.Struct
+		}
+		if d.opcode == scanEndObject {
+			break
+		}
+		if d.opcode != scanObjectValue {
+			panic(phasePanicMsg)
+		}
+	}
+
+	if v.Kind() == reflect.Map {
+		d.lastKeys = keys
+	}
+	return nil
+}
+
+// convertNumber converts the number literal s to a float64 or a Number
+// depending on the setting of d.useNumber.
+func (d *decodeState) convertNumber(s string) (any, error) {
+	if d.useNumber {
+		return Number(s), nil
+	}
+	f, err := strconv.ParseFloat(s, 64)
+	if err != nil {
+		return nil, &UnmarshalTypeError{Value: "number " + s, Type: reflect.TypeOf(0.0), Offset: int64(d.off)}
+	}
+	return f, nil
+}
+
+var numberType = reflect.TypeOf(Number(""))
+
+// literalStore decodes a literal stored in item into v.
+//
+// fromQuoted indicates whether this literal came from unwrapping a
+// string from the ",string" struct tag option. this is used only to
+// produce more helpful error messages.
+func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool) error {
+	// Check for unmarshaler.
+	if len(item) == 0 {
+		//Empty string given
+		d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+		return nil
+	}
+	isNull := item[0] == 'n' // null
+	u, ut, pv := indirect(v, isNull)
+	if u != nil {
+		return u.UnmarshalJSON(item)
+	}
+	if ut != nil {
+		if item[0] != '"' {
+			if fromQuoted {
+				d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+				return nil
+			}
+			val := "number"
+			switch item[0] {
+			case 'n':
+				val = "null"
+			case 't', 'f':
+				val = "bool"
+			}
+			d.saveError(&UnmarshalTypeError{Value: val, Type: v.Type(), Offset: int64(d.readIndex())})
+			return nil
+		}
+		s, ok := unquoteBytes(item)
+		if !ok {
+			if fromQuoted {
+				return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())
+			}
+			panic(phasePanicMsg)
+		}
+		return ut.UnmarshalText(s)
+	}
+
+	v = pv
+
+	switch c := item[0]; c {
+	case 'n': // null
+		// The main parser checks that only true and false can reach here,
+		// but if this was a quoted string input, it could be anything.
+		if fromQuoted && string(item) != "null" {
+			d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+			break
+		}
+		switch v.Kind() {
+		case reflect.Interface, reflect.Pointer, reflect.Map, reflect.Slice:
+			v.Set(reflect.Zero(v.Type()))
+			// otherwise, ignore null for primitives/string
+		}
+	case 't', 'f': // true, false
+		value := item[0] == 't'
+		// The main parser checks that only true and false can reach here,
+		// but if this was a quoted string input, it could be anything.
+		if fromQuoted && string(item) != "true" && string(item) != "false" {
+			d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+			break
+		}
+		switch v.Kind() {
+		default:
+			if fromQuoted {
+				d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+			} else {
+				d.saveError(&UnmarshalTypeError{Value: "bool", Type: v.Type(), Offset: int64(d.readIndex())})
+			}
+		case reflect.Bool:
+			v.SetBool(value)
+		case reflect.Interface:
+			if v.NumMethod() == 0 {
+				v.Set(reflect.ValueOf(value))
+			} else {
+				d.saveError(&UnmarshalTypeError{Value: "bool", Type: v.Type(), Offset: int64(d.readIndex())})
+			}
+		}
+
+	case '"': // string
+		s, ok := unquoteBytes(item)
+		if !ok {
+			if fromQuoted {
+				return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())
+			}
+			panic(phasePanicMsg)
+		}
+		switch v.Kind() {
+		default:
+			d.saveError(&UnmarshalTypeError{Value: "string", Type: v.Type(), Offset: int64(d.readIndex())})
+		case reflect.Slice:
+			if v.Type().Elem().Kind() != reflect.Uint8 {
+				d.saveError(&UnmarshalTypeError{Value: "string", Type: v.Type(), Offset: int64(d.readIndex())})
+				break
+			}
+			b := make([]byte, base64.StdEncoding.DecodedLen(len(s)))
+			n, err := base64.StdEncoding.Decode(b, s)
+			if err != nil {
+				d.saveError(err)
+				break
+			}
+			v.SetBytes(b[:n])
+		case reflect.String:
+			if v.Type() == numberType && !isValidNumber(string(s)) {
+				return fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", item)
+			}
+			v.SetString(string(s))
+		case reflect.Interface:
+			if v.NumMethod() == 0 {
+				v.Set(reflect.ValueOf(string(s)))
+			} else {
+				d.saveError(&UnmarshalTypeError{Value: "string", Type: v.Type(), Offset: int64(d.readIndex())})
+			}
+		}
+
+	default: // number
+		if c != '-' && (c < '0' || c > '9') {
+			if fromQuoted {
+				return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())
+			}
+			panic(phasePanicMsg)
+		}
+		s := string(item)
+		switch v.Kind() {
+		default:
+			if v.Kind() == reflect.String && v.Type() == numberType {
+				// s must be a valid number, because it's
+				// already been tokenized.
+				v.SetString(s)
+				break
+			}
+			if fromQuoted {
+				return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())
+			}
+			d.saveError(&UnmarshalTypeError{Value: "number", Type: v.Type(), Offset: int64(d.readIndex())})
+		case reflect.Interface:
+			n, err := d.convertNumber(s)
+			if err != nil {
+				d.saveError(err)
+				break
+			}
+			if v.NumMethod() != 0 {
+				d.saveError(&UnmarshalTypeError{Value: "number", Type: v.Type(), Offset: int64(d.readIndex())})
+				break
+			}
+			v.Set(reflect.ValueOf(n))
+
+		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+			n, err := strconv.ParseInt(s, 10, 64)
+			if err != nil || v.OverflowInt(n) {
+				d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: v.Type(), Offset: int64(d.readIndex())})
+				break
+			}
+			v.SetInt(n)
+
+		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+			n, err := strconv.ParseUint(s, 10, 64)
+			if err != nil || v.OverflowUint(n) {
+				d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: v.Type(), Offset: int64(d.readIndex())})
+				break
+			}
+			v.SetUint(n)
+
+		case reflect.Float32, reflect.Float64:
+			n, err := strconv.ParseFloat(s, v.Type().Bits())
+			if err != nil || v.OverflowFloat(n) {
+				d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: v.Type(), Offset: int64(d.readIndex())})
+				break
+			}
+			v.SetFloat(n)
+		}
+	}
+	return nil
+}
+
+// The xxxInterface routines build up a value to be stored
+// in an empty interface. They are not strictly necessary,
+// but they avoid the weight of reflection in this common case.
+
+// valueInterface is like value but returns interface{}
+func (d *decodeState) valueInterface() (val any) {
+	switch d.opcode {
+	default:
+		panic(phasePanicMsg)
+	case scanBeginArray:
+		val = d.arrayInterface()
+		d.scanNext()
+	case scanBeginObject:
+		val = d.objectInterface()
+		d.scanNext()
+	case scanBeginLiteral:
+		val = d.literalInterface()
+	}
+	return
+}
+
+// arrayInterface is like array but returns []interface{}.
+func (d *decodeState) arrayInterface() []any {
+	var v = make([]any, 0)
+	for {
+		// Look ahead for ] - can only happen on first iteration.
+		d.scanWhile(scanSkipSpace)
+		if d.opcode == scanEndArray {
+			break
+		}
+
+		v = append(v, d.valueInterface())
+
+		// Next token must be , or ].
+		if d.opcode == scanSkipSpace {
+			d.scanWhile(scanSkipSpace)
+		}
+		if d.opcode == scanEndArray {
+			break
+		}
+		if d.opcode != scanArrayValue {
+			panic(phasePanicMsg)
+		}
+	}
+	return v
+}
+
+// objectInterface is like object but returns map[string]interface{}.
+func (d *decodeState) objectInterface() map[string]any {
+	m := make(map[string]any)
+	for {
+		// Read opening " of string key or closing }.
+		d.scanWhile(scanSkipSpace)
+		if d.opcode == scanEndObject {
+			// closing } - can only happen on first iteration.
+			break
+		}
+		if d.opcode != scanBeginLiteral {
+			panic(phasePanicMsg)
+		}
+
+		// Read string key.
+		start := d.readIndex()
+		d.rescanLiteral()
+		item := d.data[start:d.readIndex()]
+		key, ok := unquote(item)
+		if !ok {
+			panic(phasePanicMsg)
+		}
+
+		// Read : before value.
+		if d.opcode == scanSkipSpace {
+			d.scanWhile(scanSkipSpace)
+		}
+		if d.opcode != scanObjectKey {
+			panic(phasePanicMsg)
+		}
+		d.scanWhile(scanSkipSpace)
+
+		// Read value.
+		m[key] = d.valueInterface()
+
+		// Next token must be , or }.
+		if d.opcode == scanSkipSpace {
+			d.scanWhile(scanSkipSpace)
+		}
+		if d.opcode == scanEndObject {
+			break
+		}
+		if d.opcode != scanObjectValue {
+			panic(phasePanicMsg)
+		}
+	}
+	return m
+}
+
+// literalInterface consumes and returns a literal from d.data[d.off-1:] and
+// it reads the following byte ahead. The first byte of the literal has been
+// read already (that's how the caller knows it's a literal).
+func (d *decodeState) literalInterface() any {
+	// All bytes inside literal return scanContinue op code.
+	start := d.readIndex()
+	d.rescanLiteral()
+
+	item := d.data[start:d.readIndex()]
+
+	switch c := item[0]; c {
+	case 'n': // null
+		return nil
+
+	case 't', 'f': // true, false
+		return c == 't'
+
+	case '"': // string
+		s, ok := unquote(item)
+		if !ok {
+			panic(phasePanicMsg)
+		}
+		return s
+
+	default: // number
+		if c != '-' && (c < '0' || c > '9') {
+			panic(phasePanicMsg)
+		}
+		n, err := d.convertNumber(string(item))
+		if err != nil {
+			d.saveError(err)
+		}
+		return n
+	}
+}
+
+// getu4 decodes \uXXXX from the beginning of s, returning the hex value,
+// or it returns -1.
+func getu4(s []byte) rune {
+	if len(s) < 6 || s[0] != '\\' || s[1] != 'u' {
+		return -1
+	}
+	var r rune
+	for _, c := range s[2:6] {
+		switch {
+		case '0' <= c && c <= '9':
+			c = c - '0'
+		case 'a' <= c && c <= 'f':
+			c = c - 'a' + 10
+		case 'A' <= c && c <= 'F':
+			c = c - 'A' + 10
+		default:
+			return -1
+		}
+		r = r*16 + rune(c)
+	}
+	return r
+}
+
+// unquote converts a quoted JSON string literal s into an actual string t.
+// The rules are different than for Go, so cannot use strconv.Unquote.
+func unquote(s []byte) (t string, ok bool) {
+	s, ok = unquoteBytes(s)
+	t = string(s)
+	return
+}
+
+func unquoteBytes(s []byte) (t []byte, ok bool) {
+	if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' {
+		return
+	}
+	s = s[1 : len(s)-1]
+
+	// Check for unusual characters. If there are none,
+	// then no unquoting is needed, so return a slice of the
+	// original bytes.
+	r := 0
+	for r < len(s) {
+		c := s[r]
+		if c == '\\' || c == '"' || c < ' ' {
+			break
+		}
+		if c < utf8.RuneSelf {
+			r++
+			continue
+		}
+		rr, size := utf8.DecodeRune(s[r:])
+		if rr == utf8.RuneError && size == 1 {
+			break
+		}
+		r += size
+	}
+	if r == len(s) {
+		return s, true
+	}
+
+	b := make([]byte, len(s)+2*utf8.UTFMax)
+	w := copy(b, s[0:r])
+	for r < len(s) {
+		// Out of room? Can only happen if s is full of
+		// malformed UTF-8 and we're replacing each
+		// byte with RuneError.
+		if w >= len(b)-2*utf8.UTFMax {
+			nb := make([]byte, (len(b)+utf8.UTFMax)*2)
+			copy(nb, b[0:w])
+			b = nb
+		}
+		switch c := s[r]; {
+		case c == '\\':
+			r++
+			if r >= len(s) {
+				return
+			}
+			switch s[r] {
+			default:
+				return
+			case '"', '\\', '/', '\'':
+				b[w] = s[r]
+				r++
+				w++
+			case 'b':
+				b[w] = '\b'
+				r++
+				w++
+			case 'f':
+				b[w] = '\f'
+				r++
+				w++
+			case 'n':
+				b[w] = '\n'
+				r++
+				w++
+			case 'r':
+				b[w] = '\r'
+				r++
+				w++
+			case 't':
+				b[w] = '\t'
+				r++
+				w++
+			case 'u':
+				r--
+				rr := getu4(s[r:])
+				if rr < 0 {
+					return
+				}
+				r += 6
+				if utf16.IsSurrogate(rr) {
+					rr1 := getu4(s[r:])
+					if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar {
+						// A valid pair; consume.
+						r += 6
+						w += utf8.EncodeRune(b[w:], dec)
+						break
+					}
+					// Invalid surrogate; fall back to replacement rune.
+					rr = unicode.ReplacementChar
+				}
+				w += utf8.EncodeRune(b[w:], rr)
+			}
+
+		// Quote, control characters are invalid.
+		case c == '"', c < ' ':
+			return
+
+		// ASCII
+		case c < utf8.RuneSelf:
+			b[w] = c
+			r++
+			w++
+
+		// Coerce to well-formed UTF-8.
+		default:
+			rr, size := utf8.DecodeRune(s[r:])
+			r += size
+			w += utf8.EncodeRune(b[w:], rr)
+		}
+	}
+	return b[0:w], true
+}
diff --git a/vendor/github.com/evanphx/json-patch/v5/internal/json/encode.go b/vendor/github.com/evanphx/json-patch/v5/internal/json/encode.go
new file mode 100644
index 00000000..a1819b16
--- /dev/null
+++ b/vendor/github.com/evanphx/json-patch/v5/internal/json/encode.go
@@ -0,0 +1,1473 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package json implements encoding and decoding of JSON as defined in
+// RFC 7159. The mapping between JSON and Go values is described
+// in the documentation for the Marshal and Unmarshal functions.
+//
+// See "JSON and Go" for an introduction to this package:
+// https://golang.org/doc/articles/json_and_go.html
+package json
+
+import (
+	"bytes"
+	"encoding"
+	"encoding/base64"
+	"fmt"
+	"math"
+	"reflect"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"unicode"
+	"unicode/utf8"
+)
+
+// Marshal returns the JSON encoding of v.
+//
+// Marshal traverses the value v recursively.
+// If an encountered value implements the Marshaler interface
+// and is not a nil pointer, Marshal calls its MarshalJSON method
+// to produce JSON. If no MarshalJSON method is present but the
+// value implements encoding.TextMarshaler instead, Marshal calls
+// its MarshalText method and encodes the result as a JSON string.
+// The nil pointer exception is not strictly necessary
+// but mimics a similar, necessary exception in the behavior of
+// UnmarshalJSON.
+//
+// Otherwise, Marshal uses the following type-dependent default encodings:
+//
+// Boolean values encode as JSON booleans.
+//
+// Floating point, integer, and Number values encode as JSON numbers.
+//
+// String values encode as JSON strings coerced to valid UTF-8,
+// replacing invalid bytes with the Unicode replacement rune.
+// So that the JSON will be safe to embed inside HTML <script> tags,
+// the string is encoded using HTMLEscape,
+// which replaces "<", ">", "&", U+2028, and U+2029 are escaped
+// to "\u003c","\u003e", "\u0026", "\u2028", and "\u2029".
+// This replacement can be disabled when using an Encoder,
+// by calling SetEscapeHTML(false).
+//
+// Array and slice values encode as JSON arrays, except that
+// []byte encodes as a base64-encoded string, and a nil slice
+// encodes as the null JSON value.
+//
+// Struct values encode as JSON objects.
+// Each exported struct field becomes a member of the object, using the
+// field name as the object key, unless the field is omitted for one of the
+// reasons given below.
+//
+// The encoding of each struct field can be customized by the format string
+// stored under the "json" key in the struct field's tag.
+// The format string gives the name of the field, possibly followed by a
+// comma-separated list of options. The name may be empty in order to
+// specify options without overriding the default field name.
+//
+// The "omitempty" option specifies that the field should be omitted
+// from the encoding if the field has an empty value, defined as
+// false, 0, a nil pointer, a nil interface value, and any empty array,
+// slice, map, or string.
+//
+// As a special case, if the field tag is "-", the field is always omitted.
+// Note that a field with name "-" can still be generated using the tag "-,".
+//
+// Examples of struct field tags and their meanings:
+//
+//	// Field appears in JSON as key "myName".
+//	Field int `json:"myName"`
+//
+//	// Field appears in JSON as key "myName" and
+//	// the field is omitted from the object if its value is empty,
+//	// as defined above.
+//	Field int `json:"myName,omitempty"`
+//
+//	// Field appears in JSON as key "Field" (the default), but
+//	// the field is skipped if empty.
+//	// Note the leading comma.
+//	Field int `json:",omitempty"`
+//
+//	// Field is ignored by this package.
+//	Field int `json:"-"`
+//
+//	// Field appears in JSON as key "-".
+//	Field int `json:"-,"`
+//
+// The "string" option signals that a field is stored as JSON inside a
+// JSON-encoded string. It applies only to fields of string, floating point,
+// integer, or boolean types. This extra level of encoding is sometimes used
+// when communicating with JavaScript programs:
+//
+//	Int64String int64 `json:",string"`
+//
+// The key name will be used if it's a non-empty string consisting of
+// only Unicode letters, digits, and ASCII punctuation except quotation
+// marks, backslash, and comma.
+//
+// Anonymous struct fields are usually marshaled as if their inner exported fields
+// were fields in the outer struct, subject to the usual Go visibility rules amended
+// as described in the next paragraph.
+// An anonymous struct field with a name given in its JSON tag is treated as
+// having that name, rather than being anonymous.
+// An anonymous struct field of interface type is treated the same as having
+// that type as its name, rather than being anonymous.
+//
+// The Go visibility rules for struct fields are amended for JSON when
+// deciding which field to marshal or unmarshal. If there are
+// multiple fields at the same level, and that level is the least
+// nested (and would therefore be the nesting level selected by the
+// usual Go rules), the following extra rules apply:
+//
+// 1) Of those fields, if any are JSON-tagged, only tagged fields are considered,
+// even if there are multiple untagged fields that would otherwise conflict.
+//
+// 2) If there is exactly one field (tagged or not according to the first rule), that is selected.
+//
+// 3) Otherwise there are multiple fields, and all are ignored; no error occurs.
+//
+// Handling of anonymous struct fields is new in Go 1.1.
+// Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of
+// an anonymous struct field in both current and earlier versions, give the field
+// a JSON tag of "-".
+//
+// Map values encode as JSON objects. The map's key type must either be a
+// string, an integer type, or implement encoding.TextMarshaler. The map keys
+// are sorted and used as JSON object keys by applying the following rules,
+// subject to the UTF-8 coercion described for string values above:
+//   - keys of any string type are used directly
+//   - encoding.TextMarshalers are marshaled
+//   - integer keys are converted to strings
+//
+// Pointer values encode as the value pointed to.
+// A nil pointer encodes as the null JSON value.
+//
+// Interface values encode as the value contained in the interface.
+// A nil interface value encodes as the null JSON value.
+//
+// Channel, complex, and function values cannot be encoded in JSON.
+// Attempting to encode such a value causes Marshal to return
+// an UnsupportedTypeError.
+//
+// JSON cannot represent cyclic data structures and Marshal does not
+// handle them. Passing cyclic structures to Marshal will result in
+// an error.
+func Marshal(v any) ([]byte, error) {
+	e := newEncodeState()
+	defer encodeStatePool.Put(e)
+
+	err := e.marshal(v, encOpts{escapeHTML: true})
+	if err != nil {
+		return nil, err
+	}
+	buf := append([]byte(nil), e.Bytes()...)
+
+	return buf, nil
+}
+
+// MarshalIndent is like Marshal but applies Indent to format the output.
+// Each JSON element in the output will begin on a new line beginning with prefix
+// followed by one or more copies of indent according to the indentation nesting.
+func MarshalIndent(v any, prefix, indent string) ([]byte, error) {
+	b, err := Marshal(v)
+	if err != nil {
+		return nil, err
+	}
+	var buf bytes.Buffer
+	err = Indent(&buf, b, prefix, indent)
+	if err != nil {
+		return nil, err
+	}
+	return buf.Bytes(), nil
+}
+
+// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029
+// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029
+// so that the JSON will be safe to embed inside HTML <script> tags.
+// For historical reasons, web browsers don't honor standard HTML
+// escaping within <script> tags, so an alternative JSON encoding must
+// be used.
+func HTMLEscape(dst *bytes.Buffer, src []byte) {
+	// The characters can only appear in string literals,
+	// so just scan the string one byte at a time.
+	start := 0
+	for i, c := range src {
+		if c == '<' || c == '>' || c == '&' {
+			if start < i {
+				dst.Write(src[start:i])
+			}
+			dst.WriteString(`\u00`)
+			dst.WriteByte(hex[c>>4])
+			dst.WriteByte(hex[c&0xF])
+			start = i + 1
+		}
+		// Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).
+		if c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {
+			if start < i {
+				dst.Write(src[start:i])
+			}
+			dst.WriteString(`\u202`)
+			dst.WriteByte(hex[src[i+2]&0xF])
+			start = i + 3
+		}
+	}
+	if start < len(src) {
+		dst.Write(src[start:])
+	}
+}
+
+// Marshaler is the interface implemented by types that
+// can marshal themselves into valid JSON.
+type Marshaler interface {
+	MarshalJSON() ([]byte, error)
+}
+
+type RedirectMarshaler interface {
+	RedirectMarshalJSON() (any, error)
+}
+
+type TrustMarshaler interface {
+	TrustMarshalJSON(b *bytes.Buffer) error
+}
+
+// An UnsupportedTypeError is returned by Marshal when attempting
+// to encode an unsupported value type.
+type UnsupportedTypeError struct {
+	Type reflect.Type
+}
+
+func (e *UnsupportedTypeError) Error() string {
+	return "json: unsupported type: " + e.Type.String()
+}
+
+// An UnsupportedValueError is returned by Marshal when attempting
+// to encode an unsupported value.
+type UnsupportedValueError struct {
+	Value reflect.Value
+	Str   string
+}
+
+func (e *UnsupportedValueError) Error() string {
+	return "json: unsupported value: " + e.Str
+}
+
+// Before Go 1.2, an InvalidUTF8Error was returned by Marshal when
+// attempting to encode a string value with invalid UTF-8 sequences.
+// As of Go 1.2, Marshal instead coerces the string to valid UTF-8 by
+// replacing invalid bytes with the Unicode replacement rune U+FFFD.
+//
+// Deprecated: No longer used; kept for compatibility.
+type InvalidUTF8Error struct {
+	S string // the whole string value that caused the error
+}
+
+func (e *InvalidUTF8Error) Error() string {
+	return "json: invalid UTF-8 in string: " + strconv.Quote(e.S)
+}
+
+// A MarshalerError represents an error from calling a MarshalJSON or MarshalText method.
+type MarshalerError struct {
+	Type       reflect.Type
+	Err        error
+	sourceFunc string
+}
+
+func (e *MarshalerError) Error() string {
+	srcFunc := e.sourceFunc
+	if srcFunc == "" {
+		srcFunc = "MarshalJSON"
+	}
+	return "json: error calling " + srcFunc +
+		" for type " + e.Type.String() +
+		": " + e.Err.Error()
+}
+
+// Unwrap returns the underlying error.
+func (e *MarshalerError) Unwrap() error { return e.Err }
+
+var hex = "0123456789abcdef"
+
+// An encodeState encodes JSON into a bytes.Buffer.
+type encodeState struct {
+	bytes.Buffer // accumulated output
+	scratch      [64]byte
+
+	// Keep track of what pointers we've seen in the current recursive call
+	// path, to avoid cycles that could lead to a stack overflow. Only do
+	// the relatively expensive map operations if ptrLevel is larger than
+	// startDetectingCyclesAfter, so that we skip the work if we're within a
+	// reasonable amount of nested pointers deep.
+	ptrLevel uint
+	ptrSeen  map[any]struct{}
+}
+
+const startDetectingCyclesAfter = 1000
+
+var encodeStatePool sync.Pool
+
+func newEncodeState() *encodeState {
+	if v := encodeStatePool.Get(); v != nil {
+		e := v.(*encodeState)
+		e.Reset()
+		if len(e.ptrSeen) > 0 {
+			panic("ptrEncoder.encode should have emptied ptrSeen via defers")
+		}
+		e.ptrLevel = 0
+		return e
+	}
+	return &encodeState{ptrSeen: make(map[any]struct{})}
+}
+
+// jsonError is an error wrapper type for internal use only.
+// Panics with errors are wrapped in jsonError so that the top-level recover
+// can distinguish intentional panics from this package.
+type jsonError struct{ error }
+
+func (e *encodeState) marshal(v any, opts encOpts) (err error) {
+	defer func() {
+		if r := recover(); r != nil {
+			if je, ok := r.(jsonError); ok {
+				err = je.error
+			} else {
+				panic(r)
+			}
+		}
+	}()
+	e.reflectValue(reflect.ValueOf(v), opts)
+	return nil
+}
+
+// error aborts the encoding by panicking with err wrapped in jsonError.
+func (e *encodeState) error(err error) {
+	panic(jsonError{err})
+}
+
+func isEmptyValue(v reflect.Value) bool {
+	switch v.Kind() {
+	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
+		return v.Len() == 0
+	case reflect.Bool:
+		return !v.Bool()
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return v.Int() == 0
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return v.Uint() == 0
+	case reflect.Float32, reflect.Float64:
+		return v.Float() == 0
+	case reflect.Interface, reflect.Pointer:
+		return v.IsNil()
+	}
+	return false
+}
+
+func (e *encodeState) reflectValue(v reflect.Value, opts encOpts) {
+	valueEncoder(v)(e, v, opts)
+}
+
+type encOpts struct {
+	// quoted causes primitive fields to be encoded inside JSON strings.
+	quoted bool
+	// escapeHTML causes '<', '>', and '&' to be escaped in JSON strings.
+	escapeHTML bool
+}
+
+type encoderFunc func(e *encodeState, v reflect.Value, opts encOpts)
+
+var encoderCache sync.Map // map[reflect.Type]encoderFunc
+
+func valueEncoder(v reflect.Value) encoderFunc {
+	if !v.IsValid() {
+		return invalidValueEncoder
+	}
+	return typeEncoder(v.Type())
+}
+
+func typeEncoder(t reflect.Type) encoderFunc {
+	if fi, ok := encoderCache.Load(t); ok {
+		return fi.(encoderFunc)
+	}
+
+	// To deal with recursive types, populate the map with an
+	// indirect func before we build it. This type waits on the
+	// real func (f) to be ready and then calls it. This indirect
+	// func is only used for recursive types.
+	var (
+		wg sync.WaitGroup
+		f  encoderFunc
+	)
+	wg.Add(1)
+	fi, loaded := encoderCache.LoadOrStore(t, encoderFunc(func(e *encodeState, v reflect.Value, opts encOpts) {
+		wg.Wait()
+		f(e, v, opts)
+	}))
+	if loaded {
+		return fi.(encoderFunc)
+	}
+
+	// Compute the real encoder and replace the indirect func with it.
+	f = newTypeEncoder(t, true)
+	wg.Done()
+	encoderCache.Store(t, f)
+	return f
+}
+
+var (
+	marshalerType      = reflect.TypeOf((*Marshaler)(nil)).Elem()
+	redirMarshalerType = reflect.TypeOf((*RedirectMarshaler)(nil)).Elem()
+	trustMarshalerType = reflect.TypeOf((*TrustMarshaler)(nil)).Elem()
+	textMarshalerType  = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
+)
+
+// newTypeEncoder constructs an encoderFunc for a type.
+// The returned encoder only checks CanAddr when allowAddr is true.
+func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc {
+	if t.Implements(redirMarshalerType) {
+		return redirMarshalerEncoder
+	}
+	if t.Implements(trustMarshalerType) {
+		return marshalerTrustEncoder
+	}
+	// If we have a non-pointer value whose type implements
+	// Marshaler with a value receiver, then we're better off taking
+	// the address of the value - otherwise we end up with an
+	// allocation as we cast the value to an interface.
+	if t.Kind() != reflect.Pointer && allowAddr && reflect.PointerTo(t).Implements(marshalerType) {
+		return newCondAddrEncoder(addrMarshalerEncoder, newTypeEncoder(t, false))
+	}
+	if t.Implements(marshalerType) {
+		return marshalerEncoder
+	}
+	if t.Kind() != reflect.Pointer && allowAddr && reflect.PointerTo(t).Implements(textMarshalerType) {
+		return newCondAddrEncoder(addrTextMarshalerEncoder, newTypeEncoder(t, false))
+	}
+	if t.Implements(textMarshalerType) {
+		return textMarshalerEncoder
+	}
+
+	switch t.Kind() {
+	case reflect.Bool:
+		return boolEncoder
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return intEncoder
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return uintEncoder
+	case reflect.Float32:
+		return float32Encoder
+	case reflect.Float64:
+		return float64Encoder
+	case reflect.String:
+		return stringEncoder
+	case reflect.Interface:
+		return interfaceEncoder
+	case reflect.Struct:
+		return newStructEncoder(t)
+	case reflect.Map:
+		return newMapEncoder(t)
+	case reflect.Slice:
+		return newSliceEncoder(t)
+	case reflect.Array:
+		return newArrayEncoder(t)
+	case reflect.Pointer:
+		return newPtrEncoder(t)
+	default:
+		return unsupportedTypeEncoder
+	}
+}
+
+func invalidValueEncoder(e *encodeState, v reflect.Value, _ encOpts) {
+	e.WriteString("null")
+}
+
+func redirMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
+	if v.Kind() == reflect.Pointer && v.IsNil() {
+		e.WriteString("null")
+		return
+	}
+	m, ok := v.Interface().(RedirectMarshaler)
+	if !ok {
+		e.WriteString("null")
+		return
+	}
+
+	iv, err := m.RedirectMarshalJSON()
+	if err != nil {
+		e.error(&MarshalerError{v.Type(), err, "RedirectMarshalJSON"})
+		return
+	}
+
+	e.marshal(iv, opts)
+}
+
+func marshalerTrustEncoder(e *encodeState, v reflect.Value, opts encOpts) {
+	if v.Kind() == reflect.Pointer && v.IsNil() {
+		e.WriteString("null")
+		return
+	}
+	m, ok := v.Interface().(TrustMarshaler)
+	if !ok {
+		e.WriteString("null")
+		return
+	}
+	err := m.TrustMarshalJSON(&e.Buffer)
+	if err == nil {
+		//_, err = e.Buffer.Write(b)
+		// copy JSON into buffer, checking validity.
+		//err = compact(&e.Buffer, b, opts.escapeHTML)
+	}
+	if err != nil {
+		e.error(&MarshalerError{v.Type(), err, "MarshalJSON"})
+	}
+}
+func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
+	if v.Kind() == reflect.Pointer && v.IsNil() {
+		e.WriteString("null")
+		return
+	}
+	m, ok := v.Interface().(Marshaler)
+	if !ok {
+		e.WriteString("null")
+		return
+	}
+	b, err := m.MarshalJSON()
+	if err == nil {
+		// copy JSON into buffer, checking validity.
+		err = compact(&e.Buffer, b, opts.escapeHTML)
+	}
+	if err != nil {
+		e.error(&MarshalerError{v.Type(), err, "MarshalJSON"})
+	}
+}
+
+func addrMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
+	va := v.Addr()
+	if va.IsNil() {
+		e.WriteString("null")
+		return
+	}
+	m := va.Interface().(Marshaler)
+	b, err := m.MarshalJSON()
+	if err == nil {
+		// copy JSON into buffer, checking validity.
+		err = compact(&e.Buffer, b, opts.escapeHTML)
+	}
+	if err != nil {
+		e.error(&MarshalerError{v.Type(), err, "MarshalJSON"})
+	}
+}
+
+func textMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
+	if v.Kind() == reflect.Pointer && v.IsNil() {
+		e.WriteString("null")
+		return
+	}
+	m, ok := v.Interface().(encoding.TextMarshaler)
+	if !ok {
+		e.WriteString("null")
+		return
+	}
+	b, err := m.MarshalText()
+	if err != nil {
+		e.error(&MarshalerError{v.Type(), err, "MarshalText"})
+	}
+	e.stringBytes(b, opts.escapeHTML)
+}
+
+func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
+	va := v.Addr()
+	if va.IsNil() {
+		e.WriteString("null")
+		return
+	}
+	m := va.Interface().(encoding.TextMarshaler)
+	b, err := m.MarshalText()
+	if err != nil {
+		e.error(&MarshalerError{v.Type(), err, "MarshalText"})
+	}
+	e.stringBytes(b, opts.escapeHTML)
+}
+
+func boolEncoder(e *encodeState, v reflect.Value, opts encOpts) {
+	if opts.quoted {
+		e.WriteByte('"')
+	}
+	if v.Bool() {
+		e.WriteString("true")
+	} else {
+		e.WriteString("false")
+	}
+	if opts.quoted {
+		e.WriteByte('"')
+	}
+}
+
+func intEncoder(e *encodeState, v reflect.Value, opts encOpts) {
+	b := strconv.AppendInt(e.scratch[:0], v.Int(), 10)
+	if opts.quoted {
+		e.WriteByte('"')
+	}
+	e.Write(b)
+	if opts.quoted {
+		e.WriteByte('"')
+	}
+}
+
+func uintEncoder(e *encodeState, v reflect.Value, opts encOpts) {
+	b := strconv.AppendUint(e.scratch[:0], v.Uint(), 10)
+	if opts.quoted {
+		e.WriteByte('"')
+	}
+	e.Write(b)
+	if opts.quoted {
+		e.WriteByte('"')
+	}
+}
+
+type floatEncoder int // number of bits
+
+func (bits floatEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
+	f := v.Float()
+	if math.IsInf(f, 0) || math.IsNaN(f) {
+		e.error(&UnsupportedValueError{v, strconv.FormatFloat(f, 'g', -1, int(bits))})
+	}
+
+	// Convert as if by ES6 number to string conversion.
+	// This matches most other JSON generators.
+	// See golang.org/issue/6384 and golang.org/issue/14135.
+	// Like fmt %g, but the exponent cutoffs are different
+	// and exponents themselves are not padded to two digits.
+	b := e.scratch[:0]
+	abs := math.Abs(f)
+	fmt := byte('f')
+	// Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
+	if abs != 0 {
+		if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) {
+			fmt = 'e'
+		}
+	}
+	b = strconv.AppendFloat(b, f, fmt, -1, int(bits))
+	if fmt == 'e' {
+		// clean up e-09 to e-9
+		n := len(b)
+		if n >= 4 && b[n-4] == 'e' && b[n-3] == '-' && b[n-2] == '0' {
+			b[n-2] = b[n-1]
+			b = b[:n-1]
+		}
+	}
+
+	if opts.quoted {
+		e.WriteByte('"')
+	}
+	e.Write(b)
+	if opts.quoted {
+		e.WriteByte('"')
+	}
+}
+
+var (
+	float32Encoder = (floatEncoder(32)).encode
+	float64Encoder = (floatEncoder(64)).encode
+)
+
+func stringEncoder(e *encodeState, v reflect.Value, opts encOpts) {
+	if v.Type() == numberType {
+		numStr := v.String()
+		// In Go1.5 the empty string encodes to "0", while this is not a valid number literal
+		// we keep compatibility so check validity after this.
+		if numStr == "" {
+			numStr = "0" // Number's zero-val
+		}
+		if !isValidNumber(numStr) {
+			e.error(fmt.Errorf("json: invalid number literal %q", numStr))
+		}
+		if opts.quoted {
+			e.WriteByte('"')
+		}
+		e.WriteString(numStr)
+		if opts.quoted {
+			e.WriteByte('"')
+		}
+		return
+	}
+	if opts.quoted {
+		e2 := newEncodeState()
+		// Since we encode the string twice, we only need to escape HTML
+		// the first time.
+		e2.string(v.String(), opts.escapeHTML)
+		e.stringBytes(e2.Bytes(), false)
+		encodeStatePool.Put(e2)
+	} else {
+		e.string(v.String(), opts.escapeHTML)
+	}
+}
+
+// isValidNumber reports whether s is a valid JSON number literal.
+func isValidNumber(s string) bool {
+	// This function implements the JSON numbers grammar.
+	// See https://tools.ietf.org/html/rfc7159#section-6
+	// and https://www.json.org/img/number.png
+
+	if s == "" {
+		return false
+	}
+
+	// Optional -
+	if s[0] == '-' {
+		s = s[1:]
+		if s == "" {
+			return false
+		}
+	}
+
+	// Digits
+	switch {
+	default:
+		return false
+
+	case s[0] == '0':
+		s = s[1:]
+
+	case '1' <= s[0] && s[0] <= '9':
+		s = s[1:]
+		for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
+			s = s[1:]
+		}
+	}
+
+	// . followed by 1 or more digits.
+	if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' {
+		s = s[2:]
+		for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
+			s = s[1:]
+		}
+	}
+
+	// e or E followed by an optional - or + and
+	// 1 or more digits.
+	if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') {
+		s = s[1:]
+		if s[0] == '+' || s[0] == '-' {
+			s = s[1:]
+			if s == "" {
+				return false
+			}
+		}
+		for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
+			s = s[1:]
+		}
+	}
+
+	// Make sure we are at the end.
+	return s == ""
+}
+
+func interfaceEncoder(e *encodeState, v reflect.Value, opts encOpts) {
+	if v.IsNil() {
+		e.WriteString("null")
+		return
+	}
+	e.reflectValue(v.Elem(), opts)
+}
+
+func unsupportedTypeEncoder(e *encodeState, v reflect.Value, _ encOpts) {
+	e.error(&UnsupportedTypeError{v.Type()})
+}
+
+type structEncoder struct {
+	fields structFields
+}
+
+type structFields struct {
+	list      []field
+	nameIndex map[string]int
+}
+
+func (se structEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
+	next := byte('{')
+FieldLoop:
+	for i := range se.fields.list {
+		f := &se.fields.list[i]
+
+		// Find the nested struct field by following f.index.
+		fv := v
+		for _, i := range f.index {
+			if fv.Kind() == reflect.Pointer {
+				if fv.IsNil() {
+					continue FieldLoop
+				}
+				fv = fv.Elem()
+			}
+			fv = fv.Field(i)
+		}
+
+		if f.omitEmpty && isEmptyValue(fv) {
+			continue
+		}
+		e.WriteByte(next)
+		next = ','
+		if opts.escapeHTML {
+			e.WriteString(f.nameEscHTML)
+		} else {
+			e.WriteString(f.nameNonEsc)
+		}
+		opts.quoted = f.quoted
+		f.encoder(e, fv, opts)
+	}
+	if next == '{' {
+		e.WriteString("{}")
+	} else {
+		e.WriteByte('}')
+	}
+}
+
+func newStructEncoder(t reflect.Type) encoderFunc {
+	se := structEncoder{fields: cachedTypeFields(t)}
+	return se.encode
+}
+
+type mapEncoder struct {
+	elemEnc encoderFunc
+}
+
+func (me mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
+	if v.IsNil() {
+		e.WriteString("null")
+		return
+	}
+	if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter {
+		// We're a large number of nested ptrEncoder.encode calls deep;
+		// start checking if we've run into a pointer cycle.
+		ptr := v.UnsafePointer()
+		if _, ok := e.ptrSeen[ptr]; ok {
+			e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())})
+		}
+		e.ptrSeen[ptr] = struct{}{}
+		defer delete(e.ptrSeen, ptr)
+	}
+	e.WriteByte('{')
+
+	// Extract and sort the keys.
+	sv := make([]reflectWithString, v.Len())
+	mi := v.MapRange()
+	for i := 0; mi.Next(); i++ {
+		sv[i].k = mi.Key()
+		sv[i].v = mi.Value()
+		if err := sv[i].resolve(); err != nil {
+			e.error(fmt.Errorf("json: encoding error for type %q: %q", v.Type().String(), err.Error()))
+		}
+	}
+	sort.Slice(sv, func(i, j int) bool { return sv[i].ks < sv[j].ks })
+
+	for i, kv := range sv {
+		if i > 0 {
+			e.WriteByte(',')
+		}
+		e.string(kv.ks, opts.escapeHTML)
+		e.WriteByte(':')
+		me.elemEnc(e, kv.v, opts)
+	}
+	e.WriteByte('}')
+	e.ptrLevel--
+}
+
+func newMapEncoder(t reflect.Type) encoderFunc {
+	switch t.Key().Kind() {
+	case reflect.String,
+		reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+	default:
+		if !t.Key().Implements(textMarshalerType) {
+			return unsupportedTypeEncoder
+		}
+	}
+	me := mapEncoder{typeEncoder(t.Elem())}
+	return me.encode
+}
+
+func encodeByteSlice(e *encodeState, v reflect.Value, _ encOpts) {
+	if v.IsNil() {
+		e.WriteString("null")
+		return
+	}
+	s := v.Bytes()
+	e.WriteByte('"')
+	encodedLen := base64.StdEncoding.EncodedLen(len(s))
+	if encodedLen <= len(e.scratch) {
+		// If the encoded bytes fit in e.scratch, avoid an extra
+		// allocation and use the cheaper Encoding.Encode.
+		dst := e.scratch[:encodedLen]
+		base64.StdEncoding.Encode(dst, s)
+		e.Write(dst)
+	} else if encodedLen <= 1024 {
+		// The encoded bytes are short enough to allocate for, and
+		// Encoding.Encode is still cheaper.
+		dst := make([]byte, encodedLen)
+		base64.StdEncoding.Encode(dst, s)
+		e.Write(dst)
+	} else {
+		// The encoded bytes are too long to cheaply allocate, and
+		// Encoding.Encode is no longer noticeably cheaper.
+		enc := base64.NewEncoder(base64.StdEncoding, e)
+		enc.Write(s)
+		enc.Close()
+	}
+	e.WriteByte('"')
+}
+
+// sliceEncoder just wraps an arrayEncoder, checking to make sure the value isn't nil.
+type sliceEncoder struct {
+	arrayEnc encoderFunc
+}
+
+func (se sliceEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
+	if v.IsNil() {
+		e.WriteString("null")
+		return
+	}
+	if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter {
+		// We're a large number of nested ptrEncoder.encode calls deep;
+		// start checking if we've run into a pointer cycle.
+		// Here we use a struct to memorize the pointer to the first element of the slice
+		// and its length.
+		ptr := struct {
+			ptr interface{} // always an unsafe.Pointer, but avoids a dependency on package unsafe
+			len int
+		}{v.UnsafePointer(), v.Len()}
+		if _, ok := e.ptrSeen[ptr]; ok {
+			e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())})
+		}
+		e.ptrSeen[ptr] = struct{}{}
+		defer delete(e.ptrSeen, ptr)
+	}
+	se.arrayEnc(e, v, opts)
+	e.ptrLevel--
+}
+
+func newSliceEncoder(t reflect.Type) encoderFunc {
+	// Byte slices get special treatment; arrays don't.
+	if t.Elem().Kind() == reflect.Uint8 {
+		p := reflect.PointerTo(t.Elem())
+		if !p.Implements(marshalerType) && !p.Implements(textMarshalerType) {
+			return encodeByteSlice
+		}
+	}
+	enc := sliceEncoder{newArrayEncoder(t)}
+	return enc.encode
+}
+
+type arrayEncoder struct {
+	elemEnc encoderFunc
+}
+
+func (ae arrayEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
+	e.WriteByte('[')
+	n := v.Len()
+	for i := 0; i < n; i++ {
+		if i > 0 {
+			e.WriteByte(',')
+		}
+		ae.elemEnc(e, v.Index(i), opts)
+	}
+	e.WriteByte(']')
+}
+
+func newArrayEncoder(t reflect.Type) encoderFunc {
+	enc := arrayEncoder{typeEncoder(t.Elem())}
+	return enc.encode
+}
+
+type ptrEncoder struct {
+	elemEnc encoderFunc
+}
+
+func (pe ptrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
+	if v.IsNil() {
+		e.WriteString("null")
+		return
+	}
+	if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter {
+		// We're a large number of nested ptrEncoder.encode calls deep;
+		// start checking if we've run into a pointer cycle.
+		ptr := v.Interface()
+		if _, ok := e.ptrSeen[ptr]; ok {
+			e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())})
+		}
+		e.ptrSeen[ptr] = struct{}{}
+		defer delete(e.ptrSeen, ptr)
+	}
+	pe.elemEnc(e, v.Elem(), opts)
+	e.ptrLevel--
+}
+
+func newPtrEncoder(t reflect.Type) encoderFunc {
+	enc := ptrEncoder{typeEncoder(t.Elem())}
+	return enc.encode
+}
+
+type condAddrEncoder struct {
+	canAddrEnc, elseEnc encoderFunc
+}
+
+func (ce condAddrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
+	if v.CanAddr() {
+		ce.canAddrEnc(e, v, opts)
+	} else {
+		ce.elseEnc(e, v, opts)
+	}
+}
+
+// newCondAddrEncoder returns an encoder that checks whether its value
+// CanAddr and delegates to canAddrEnc if so, else to elseEnc.
+func newCondAddrEncoder(canAddrEnc, elseEnc encoderFunc) encoderFunc {
+	enc := condAddrEncoder{canAddrEnc: canAddrEnc, elseEnc: elseEnc}
+	return enc.encode
+}
+
+func isValidTag(s string) bool {
+	if s == "" {
+		return false
+	}
+	for _, c := range s {
+		switch {
+		case strings.ContainsRune("!#$%&()*+-./:;<=>?@[]^_{|}~ ", c):
+			// Backslash and quote chars are reserved, but
+			// otherwise any punctuation chars are allowed
+			// in a tag name.
+		case !unicode.IsLetter(c) && !unicode.IsDigit(c):
+			return false
+		}
+	}
+	return true
+}
+
+func typeByIndex(t reflect.Type, index []int) reflect.Type {
+	for _, i := range index {
+		if t.Kind() == reflect.Pointer {
+			t = t.Elem()
+		}
+		t = t.Field(i).Type
+	}
+	return t
+}
+
+type reflectWithString struct {
+	k  reflect.Value
+	v  reflect.Value
+	ks string
+}
+
+func (w *reflectWithString) resolve() error {
+	if w.k.Kind() == reflect.String {
+		w.ks = w.k.String()
+		return nil
+	}
+	if tm, ok := w.k.Interface().(encoding.TextMarshaler); ok {
+		if w.k.Kind() == reflect.Pointer && w.k.IsNil() {
+			return nil
+		}
+		buf, err := tm.MarshalText()
+		w.ks = string(buf)
+		return err
+	}
+	switch w.k.Kind() {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		w.ks = strconv.FormatInt(w.k.Int(), 10)
+		return nil
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		w.ks = strconv.FormatUint(w.k.Uint(), 10)
+		return nil
+	}
+	panic("unexpected map key type")
+}
+
+// NOTE: keep in sync with stringBytes below.
+func (e *encodeState) string(s string, escapeHTML bool) {
+	e.WriteByte('"')
+	start := 0
+	for i := 0; i < len(s); {
+		if b := s[i]; b < utf8.RuneSelf {
+			if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) {
+				i++
+				continue
+			}
+			if start < i {
+				e.WriteString(s[start:i])
+			}
+			e.WriteByte('\\')
+			switch b {
+			case '\\', '"':
+				e.WriteByte(b)
+			case '\n':
+				e.WriteByte('n')
+			case '\r':
+				e.WriteByte('r')
+			case '\t':
+				e.WriteByte('t')
+			default:
+				// This encodes bytes < 0x20 except for \t, \n and \r.
+				// If escapeHTML is set, it also escapes <, >, and &
+				// because they can lead to security holes when
+				// user-controlled strings are rendered into JSON
+				// and served to some browsers.
+				e.WriteString(`u00`)
+				e.WriteByte(hex[b>>4])
+				e.WriteByte(hex[b&0xF])
+			}
+			i++
+			start = i
+			continue
+		}
+		c, size := utf8.DecodeRuneInString(s[i:])
+		if c == utf8.RuneError && size == 1 {
+			if start < i {
+				e.WriteString(s[start:i])
+			}
+			e.WriteString(`\ufffd`)
+			i += size
+			start = i
+			continue
+		}
+		// U+2028 is LINE SEPARATOR.
+		// U+2029 is PARAGRAPH SEPARATOR.
+		// They are both technically valid characters in JSON strings,
+		// but don't work in JSONP, which has to be evaluated as JavaScript,
+		// and can lead to security holes there. It is valid JSON to
+		// escape them, so we do so unconditionally.
+		// See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
+		if c == '\u2028' || c == '\u2029' {
+			if start < i {
+				e.WriteString(s[start:i])
+			}
+			e.WriteString(`\u202`)
+			e.WriteByte(hex[c&0xF])
+			i += size
+			start = i
+			continue
+		}
+		i += size
+	}
+	if start < len(s) {
+		e.WriteString(s[start:])
+	}
+	e.WriteByte('"')
+}
+
+// NOTE: keep in sync with string above.
+func (e *encodeState) stringBytes(s []byte, escapeHTML bool) {
+	e.WriteByte('"')
+	start := 0
+	for i := 0; i < len(s); {
+		if b := s[i]; b < utf8.RuneSelf {
+			if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) {
+				i++
+				continue
+			}
+			if start < i {
+				e.Write(s[start:i])
+			}
+			e.WriteByte('\\')
+			switch b {
+			case '\\', '"':
+				e.WriteByte(b)
+			case '\n':
+				e.WriteByte('n')
+			case '\r':
+				e.WriteByte('r')
+			case '\t':
+				e.WriteByte('t')
+			default:
+				// This encodes bytes < 0x20 except for \t, \n and \r.
+				// If escapeHTML is set, it also escapes <, >, and &
+				// because they can lead to security holes when
+				// user-controlled strings are rendered into JSON
+				// and served to some browsers.
+				e.WriteString(`u00`)
+				e.WriteByte(hex[b>>4])
+				e.WriteByte(hex[b&0xF])
+			}
+			i++
+			start = i
+			continue
+		}
+		c, size := utf8.DecodeRune(s[i:])
+		if c == utf8.RuneError && size == 1 {
+			if start < i {
+				e.Write(s[start:i])
+			}
+			e.WriteString(`\ufffd`)
+			i += size
+			start = i
+			continue
+		}
+		// U+2028 is LINE SEPARATOR.
+		// U+2029 is PARAGRAPH SEPARATOR.
+		// They are both technically valid characters in JSON strings,
+		// but don't work in JSONP, which has to be evaluated as JavaScript,
+		// and can lead to security holes there. It is valid JSON to
+		// escape them, so we do so unconditionally.
+		// See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
+		if c == '\u2028' || c == '\u2029' {
+			if start < i {
+				e.Write(s[start:i])
+			}
+			e.WriteString(`\u202`)
+			e.WriteByte(hex[c&0xF])
+			i += size
+			start = i
+			continue
+		}
+		i += size
+	}
+	if start < len(s) {
+		e.Write(s[start:])
+	}
+	e.WriteByte('"')
+}
+
+// A field represents a single field found in a struct.
+type field struct {
+	name      string
+	nameBytes []byte                 // []byte(name)
+	equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent
+
+	nameNonEsc  string // `"` + name + `":`
+	nameEscHTML string // `"` + HTMLEscape(name) + `":`
+
+	tag       bool
+	index     []int
+	typ       reflect.Type
+	omitEmpty bool
+	quoted    bool
+
+	encoder encoderFunc
+}
+
+// byIndex sorts field by index sequence.
+type byIndex []field
+
+func (x byIndex) Len() int { return len(x) }
+
+func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+
+func (x byIndex) Less(i, j int) bool {
+	for k, xik := range x[i].index {
+		if k >= len(x[j].index) {
+			return false
+		}
+		if xik != x[j].index[k] {
+			return xik < x[j].index[k]
+		}
+	}
+	return len(x[i].index) < len(x[j].index)
+}
+
+// typeFields returns a list of fields that JSON should recognize for the given type.
+// The algorithm is breadth-first search over the set of structs to include - the top struct
+// and then any reachable anonymous structs.
+func typeFields(t reflect.Type) structFields {
+	// Anonymous fields to explore at the current level and the next.
+	current := []field{}
+	next := []field{{typ: t}}
+
+	// Count of queued names for current level and the next.
+	var count, nextCount map[reflect.Type]int
+
+	// Types already visited at an earlier level.
+	visited := map[reflect.Type]bool{}
+
+	// Fields found.
+	var fields []field
+
+	// Buffer to run HTMLEscape on field names.
+	var nameEscBuf bytes.Buffer
+
+	for len(next) > 0 {
+		current, next = next, current[:0]
+		count, nextCount = nextCount, map[reflect.Type]int{}
+
+		for _, f := range current {
+			if visited[f.typ] {
+				continue
+			}
+			visited[f.typ] = true
+
+			// Scan f.typ for fields to include.
+			for i := 0; i < f.typ.NumField(); i++ {
+				sf := f.typ.Field(i)
+				if sf.Anonymous {
+					t := sf.Type
+					if t.Kind() == reflect.Pointer {
+						t = t.Elem()
+					}
+					if !sf.IsExported() && t.Kind() != reflect.Struct {
+						// Ignore embedded fields of unexported non-struct types.
+						continue
+					}
+					// Do not ignore embedded fields of unexported struct types
+					// since they may have exported fields.
+				} else if !sf.IsExported() {
+					// Ignore unexported non-embedded fields.
+					continue
+				}
+				tag := sf.Tag.Get("json")
+				if tag == "-" {
+					continue
+				}
+				name, opts := parseTag(tag)
+				if !isValidTag(name) {
+					name = ""
+				}
+				index := make([]int, len(f.index)+1)
+				copy(index, f.index)
+				index[len(f.index)] = i
+
+				ft := sf.Type
+				if ft.Name() == "" && ft.Kind() == reflect.Pointer {
+					// Follow pointer.
+					ft = ft.Elem()
+				}
+
+				// Only strings, floats, integers, and booleans can be quoted.
+				quoted := false
+				if opts.Contains("string") {
+					switch ft.Kind() {
+					case reflect.Bool,
+						reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+						reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
+						reflect.Float32, reflect.Float64,
+						reflect.String:
+						quoted = true
+					}
+				}
+
+				// Record found field and index sequence.
+				if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
+					tagged := name != ""
+					if name == "" {
+						name = sf.Name
+					}
+					field := field{
+						name:      name,
+						tag:       tagged,
+						index:     index,
+						typ:       ft,
+						omitEmpty: opts.Contains("omitempty"),
+						quoted:    quoted,
+					}
+					field.nameBytes = []byte(field.name)
+					field.equalFold = foldFunc(field.nameBytes)
+
+					// Build nameEscHTML and nameNonEsc ahead of time.
+					nameEscBuf.Reset()
+					nameEscBuf.WriteString(`"`)
+					HTMLEscape(&nameEscBuf, field.nameBytes)
+					nameEscBuf.WriteString(`":`)
+					field.nameEscHTML = nameEscBuf.String()
+					field.nameNonEsc = `"` + field.name + `":`
+
+					fields = append(fields, field)
+					if count[f.typ] > 1 {
+						// If there were multiple instances, add a second,
+						// so that the annihilation code will see a duplicate.
+						// It only cares about the distinction between 1 or 2,
+						// so don't bother generating any more copies.
+						fields = append(fields, fields[len(fields)-1])
+					}
+					continue
+				}
+
+				// Record new anonymous struct to explore in next round.
+				nextCount[ft]++
+				if nextCount[ft] == 1 {
+					next = append(next, field{name: ft.Name(), index: index, typ: ft})
+				}
+			}
+		}
+	}
+
+	sort.Slice(fields, func(i, j int) bool {
+		x := fields
+		// sort field by name, breaking ties with depth, then
+		// breaking ties with "name came from json tag", then
+		// breaking ties with index sequence.
+		if x[i].name != x[j].name {
+			return x[i].name < x[j].name
+		}
+		if len(x[i].index) != len(x[j].index) {
+			return len(x[i].index) < len(x[j].index)
+		}
+		if x[i].tag != x[j].tag {
+			return x[i].tag
+		}
+		return byIndex(x).Less(i, j)
+	})
+
+	// Delete all fields that are hidden by the Go rules for embedded fields,
+	// except that fields with JSON tags are promoted.
+
+	// The fields are sorted in primary order of name, secondary order
+	// of field index length. Loop over names; for each name, delete
+	// hidden fields by choosing the one dominant field that survives.
+	out := fields[:0]
+	for advance, i := 0, 0; i < len(fields); i += advance {
+		// One iteration per name.
+		// Find the sequence of fields with the name of this first field.
+		fi := fields[i]
+		name := fi.name
+		for advance = 1; i+advance < len(fields); advance++ {
+			fj := fields[i+advance]
+			if fj.name != name {
+				break
+			}
+		}
+		if advance == 1 { // Only one field with this name
+			out = append(out, fi)
+			continue
+		}
+		dominant, ok := dominantField(fields[i : i+advance])
+		if ok {
+			out = append(out, dominant)
+		}
+	}
+
+	fields = out
+	sort.Sort(byIndex(fields))
+
+	for i := range fields {
+		f := &fields[i]
+		f.encoder = typeEncoder(typeByIndex(t, f.index))
+	}
+	nameIndex := make(map[string]int, len(fields))
+	for i, field := range fields {
+		nameIndex[field.name] = i
+	}
+	return structFields{fields, nameIndex}
+}
+
+// dominantField looks through the fields, all of which are known to
+// have the same name, to find the single field that dominates the
+// others using Go's embedding rules, modified by the presence of
+// JSON tags. If there are multiple top-level fields, the boolean
+// will be false: This condition is an error in Go and we skip all
+// the fields.
+func dominantField(fields []field) (field, bool) {
+	// The fields are sorted in increasing index-length order, then by presence of tag.
+	// That means that the first field is the dominant one. We need only check
+	// for error cases: two fields at top level, either both tagged or neither tagged.
+	if len(fields) > 1 && len(fields[0].index) == len(fields[1].index) && fields[0].tag == fields[1].tag {
+		return field{}, false
+	}
+	return fields[0], true
+}
+
+var fieldCache sync.Map // map[reflect.Type]structFields
+
+// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.
+func cachedTypeFields(t reflect.Type) structFields {
+	if f, ok := fieldCache.Load(t); ok {
+		return f.(structFields)
+	}
+	f, _ := fieldCache.LoadOrStore(t, typeFields(t))
+	return f.(structFields)
+}
diff --git a/vendor/github.com/evanphx/json-patch/v5/internal/json/fold.go b/vendor/github.com/evanphx/json-patch/v5/internal/json/fold.go
new file mode 100644
index 00000000..0f9b09d7
--- /dev/null
+++ b/vendor/github.com/evanphx/json-patch/v5/internal/json/fold.go
@@ -0,0 +1,141 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package json
+
+import (
+	"bytes"
+	"unicode/utf8"
+)
+
+const (
+	caseMask     = ^byte(0x20) // Mask to ignore case in ASCII.
+	kelvin       = '\u212a'
+	smallLongEss = '\u017f'
+)
+
+// foldFunc returns one of four different case folding equivalence
+// functions, from most general (and slow) to fastest:
+//
+// 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8
+// 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S')
+// 3) asciiEqualFold, no special, but includes non-letters (including _)
+// 4) simpleLetterEqualFold, no specials, no non-letters.
+//
+// The letters S and K are special because they map to 3 runes, not just 2:
+//   - S maps to s and to U+017F 'ſ' Latin small letter long s
+//   - k maps to K and to U+212A 'K' Kelvin sign
+//
+// See https://play.golang.org/p/tTxjOc0OGo
+//
+// The returned function is specialized for matching against s and
+// should only be given s. It's not curried for performance reasons.
+func foldFunc(s []byte) func(s, t []byte) bool {
+	nonLetter := false
+	special := false // special letter
+	for _, b := range s {
+		if b >= utf8.RuneSelf {
+			return bytes.EqualFold
+		}
+		upper := b & caseMask
+		if upper < 'A' || upper > 'Z' {
+			nonLetter = true
+		} else if upper == 'K' || upper == 'S' {
+			// See above for why these letters are special.
+			special = true
+		}
+	}
+	if special {
+		return equalFoldRight
+	}
+	if nonLetter {
+		return asciiEqualFold
+	}
+	return simpleLetterEqualFold
+}
+
+// equalFoldRight is a specialization of bytes.EqualFold when s is
+// known to be all ASCII (including punctuation), but contains an 's',
+// 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t.
+// See comments on foldFunc.
+func equalFoldRight(s, t []byte) bool {
+	for _, sb := range s {
+		if len(t) == 0 {
+			return false
+		}
+		tb := t[0]
+		if tb < utf8.RuneSelf {
+			if sb != tb {
+				sbUpper := sb & caseMask
+				if 'A' <= sbUpper && sbUpper <= 'Z' {
+					if sbUpper != tb&caseMask {
+						return false
+					}
+				} else {
+					return false
+				}
+			}
+			t = t[1:]
+			continue
+		}
+		// sb is ASCII and t is not. t must be either kelvin
+		// sign or long s; sb must be s, S, k, or K.
+		tr, size := utf8.DecodeRune(t)
+		switch sb {
+		case 's', 'S':
+			if tr != smallLongEss {
+				return false
+			}
+		case 'k', 'K':
+			if tr != kelvin {
+				return false
+			}
+		default:
+			return false
+		}
+		t = t[size:]
+
+	}
+	return len(t) == 0
+}
+
+// asciiEqualFold is a specialization of bytes.EqualFold for use when
+// s is all ASCII (but may contain non-letters) and contains no
+// special-folding letters.
+// See comments on foldFunc.
+func asciiEqualFold(s, t []byte) bool {
+	if len(s) != len(t) {
+		return false
+	}
+	for i, sb := range s {
+		tb := t[i]
+		if sb == tb {
+			continue
+		}
+		if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') {
+			if sb&caseMask != tb&caseMask {
+				return false
+			}
+		} else {
+			return false
+		}
+	}
+	return true
+}
+
+// simpleLetterEqualFold is a specialization of bytes.EqualFold for
+// use when s is all ASCII letters (no underscores, etc) and also
+// doesn't contain 'k', 'K', 's', or 'S'.
+// See comments on foldFunc.
+func simpleLetterEqualFold(s, t []byte) bool {
+	if len(s) != len(t) {
+		return false
+	}
+	for i, b := range s {
+		if b&caseMask != t[i]&caseMask {
+			return false
+		}
+	}
+	return true
+}
diff --git a/vendor/github.com/evanphx/json-patch/v5/internal/json/fuzz.go b/vendor/github.com/evanphx/json-patch/v5/internal/json/fuzz.go
new file mode 100644
index 00000000..b8f4ff2c
--- /dev/null
+++ b/vendor/github.com/evanphx/json-patch/v5/internal/json/fuzz.go
@@ -0,0 +1,42 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build gofuzz
+
+package json
+
+import (
+	"fmt"
+)
+
+func Fuzz(data []byte) (score int) {
+	for _, ctor := range []func() any{
+		func() any { return new(any) },
+		func() any { return new(map[string]any) },
+		func() any { return new([]any) },
+	} {
+		v := ctor()
+		err := Unmarshal(data, v)
+		if err != nil {
+			continue
+		}
+		score = 1
+
+		m, err := Marshal(v)
+		if err != nil {
+			fmt.Printf("v=%#v\n", v)
+			panic(err)
+		}
+
+		u := ctor()
+		err = Unmarshal(m, u)
+		if err != nil {
+			fmt.Printf("v=%#v\n", v)
+			fmt.Printf("m=%s\n", m)
+			panic(err)
+		}
+	}
+
+	return
+}
diff --git a/vendor/github.com/evanphx/json-patch/v5/internal/json/indent.go b/vendor/github.com/evanphx/json-patch/v5/internal/json/indent.go
new file mode 100644
index 00000000..2924d3b4
--- /dev/null
+++ b/vendor/github.com/evanphx/json-patch/v5/internal/json/indent.go
@@ -0,0 +1,143 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package json
+
+import (
+	"bytes"
+)
+
+// Compact appends to dst the JSON-encoded src with
+// insignificant space characters elided.
+func Compact(dst *bytes.Buffer, src []byte) error {
+	return compact(dst, src, false)
+}
+
+func compact(dst *bytes.Buffer, src []byte, escape bool) error {
+	origLen := dst.Len()
+	scan := newScanner()
+	defer freeScanner(scan)
+	start := 0
+	for i, c := range src {
+		if escape && (c == '<' || c == '>' || c == '&') {
+			if start < i {
+				dst.Write(src[start:i])
+			}
+			dst.WriteString(`\u00`)
+			dst.WriteByte(hex[c>>4])
+			dst.WriteByte(hex[c&0xF])
+			start = i + 1
+		}
+		// Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).
+		if escape && c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {
+			if start < i {
+				dst.Write(src[start:i])
+			}
+			dst.WriteString(`\u202`)
+			dst.WriteByte(hex[src[i+2]&0xF])
+			start = i + 3
+		}
+		v := scan.step(scan, c)
+		if v >= scanSkipSpace {
+			if v == scanError {
+				break
+			}
+			if start < i {
+				dst.Write(src[start:i])
+			}
+			start = i + 1
+		}
+	}
+	if scan.eof() == scanError {
+		dst.Truncate(origLen)
+		return scan.err
+	}
+	if start < len(src) {
+		dst.Write(src[start:])
+	}
+	return nil
+}
+
+func newline(dst *bytes.Buffer, prefix, indent string, depth int) {
+	dst.WriteByte('\n')
+	dst.WriteString(prefix)
+	for i := 0; i < depth; i++ {
+		dst.WriteString(indent)
+	}
+}
+
+// Indent appends to dst an indented form of the JSON-encoded src.
+// Each element in a JSON object or array begins on a new,
+// indented line beginning with prefix followed by one or more
+// copies of indent according to the indentation nesting.
+// The data appended to dst does not begin with the prefix nor
+// any indentation, to make it easier to embed inside other formatted JSON data.
+// Although leading space characters (space, tab, carriage return, newline)
+// at the beginning of src are dropped, trailing space characters
+// at the end of src are preserved and copied to dst.
+// For example, if src has no trailing spaces, neither will dst;
+// if src ends in a trailing newline, so will dst.
+func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {
+	origLen := dst.Len()
+	scan := newScanner()
+	defer freeScanner(scan)
+	needIndent := false
+	depth := 0
+	for _, c := range src {
+		scan.bytes++
+		v := scan.step(scan, c)
+		if v == scanSkipSpace {
+			continue
+		}
+		if v == scanError {
+			break
+		}
+		if needIndent && v != scanEndObject && v != scanEndArray {
+			needIndent = false
+			depth++
+			newline(dst, prefix, indent, depth)
+		}
+
+		// Emit semantically uninteresting bytes
+		// (in particular, punctuation in strings) unmodified.
+		if v == scanContinue {
+			dst.WriteByte(c)
+			continue
+		}
+
+		// Add spacing around real punctuation.
+		switch c {
+		case '{', '[':
+			// delay indent so that empty object and array are formatted as {} and [].
+			needIndent = true
+			dst.WriteByte(c)
+
+		case ',':
+			dst.WriteByte(c)
+			newline(dst, prefix, indent, depth)
+
+		case ':':
+			dst.WriteByte(c)
+			dst.WriteByte(' ')
+
+		case '}', ']':
+			if needIndent {
+				// suppress indent in empty object/array
+				needIndent = false
+			} else {
+				depth--
+				newline(dst, prefix, indent, depth)
+			}
+			dst.WriteByte(c)
+
+		default:
+			dst.WriteByte(c)
+		}
+	}
+	if scan.eof() == scanError {
+		dst.Truncate(origLen)
+		return scan.err
+	}
+	return nil
+}
diff --git a/vendor/github.com/evanphx/json-patch/v5/internal/json/scanner.go b/vendor/github.com/evanphx/json-patch/v5/internal/json/scanner.go
new file mode 100644
index 00000000..4c43f5f9
--- /dev/null
+++ b/vendor/github.com/evanphx/json-patch/v5/internal/json/scanner.go
@@ -0,0 +1,610 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package json
+
+// JSON value parser state machine.
+// Just about at the limit of what is reasonable to write by hand.
+// Some parts are a bit tedious, but overall it nicely factors out the
+// otherwise common code from the multiple scanning functions
+// in this package (Compact, Indent, checkValid, etc).
+//
+// This file starts with two simple examples using the scanner
+// before diving into the scanner itself.
+
+import (
+	"strconv"
+	"sync"
+)
+
+// Valid reports whether data is a valid JSON encoding.
+func Valid(data []byte) bool {
+	scan := newScanner()
+	defer freeScanner(scan)
+	return checkValid(data, scan) == nil
+}
+
+// checkValid verifies that data is valid JSON-encoded data.
+// scan is passed in for use by checkValid to avoid an allocation.
+// checkValid returns nil or a SyntaxError.
+func checkValid(data []byte, scan *scanner) error {
+	scan.reset()
+	for _, c := range data {
+		scan.bytes++
+		if scan.step(scan, c) == scanError {
+			return scan.err
+		}
+	}
+	if scan.eof() == scanError {
+		return scan.err
+	}
+	return nil
+}
+
+// A SyntaxError is a description of a JSON syntax error.
+// Unmarshal will return a SyntaxError if the JSON can't be parsed.
+type SyntaxError struct {
+	msg    string // description of error
+	Offset int64  // error occurred after reading Offset bytes
+}
+
+func (e *SyntaxError) Error() string { return e.msg }
+
+// A scanner is a JSON scanning state machine.
+// Callers call scan.reset and then pass bytes in one at a time
+// by calling scan.step(&scan, c) for each byte.
+// The return value, referred to as an opcode, tells the
+// caller about significant parsing events like beginning
+// and ending literals, objects, and arrays, so that the
+// caller can follow along if it wishes.
+// The return value scanEnd indicates that a single top-level
+// JSON value has been completed, *before* the byte that
+// just got passed in.  (The indication must be delayed in order
+// to recognize the end of numbers: is 123 a whole value or
+// the beginning of 12345e+6?).
+type scanner struct {
+	// The step is a func to be called to execute the next transition.
+	// Also tried using an integer constant and a single func
+	// with a switch, but using the func directly was 10% faster
+	// on a 64-bit Mac Mini, and it's nicer to read.
+	step func(*scanner, byte) int
+
+	// Reached end of top-level value.
+	endTop bool
+
+	// Stack of what we're in the middle of - array values, object keys, object values.
+	parseState []int
+
+	// Error that happened, if any.
+	err error
+
+	// total bytes consumed, updated by decoder.Decode (and deliberately
+	// not set to zero by scan.reset)
+	bytes int64
+}
+
+var scannerPool = sync.Pool{
+	New: func() any {
+		return &scanner{}
+	},
+}
+
+func newScanner() *scanner {
+	scan := scannerPool.Get().(*scanner)
+	// scan.reset by design doesn't set bytes to zero
+	scan.bytes = 0
+	scan.reset()
+	return scan
+}
+
+func freeScanner(scan *scanner) {
+	// Avoid hanging on to too much memory in extreme cases.
+	if len(scan.parseState) > 1024 {
+		scan.parseState = nil
+	}
+	scannerPool.Put(scan)
+}
+
+// These values are returned by the state transition functions
+// assigned to scanner.state and the method scanner.eof.
+// They give details about the current state of the scan that
+// callers might be interested to know about.
+// It is okay to ignore the return value of any particular
+// call to scanner.state: if one call returns scanError,
+// every subsequent call will return scanError too.
+const (
+	// Continue.
+	scanContinue     = iota // uninteresting byte
+	scanBeginLiteral        // end implied by next result != scanContinue
+	scanBeginObject         // begin object
+	scanObjectKey           // just finished object key (string)
+	scanObjectValue         // just finished non-last object value
+	scanEndObject           // end object (implies scanObjectValue if possible)
+	scanBeginArray          // begin array
+	scanArrayValue          // just finished array value
+	scanEndArray            // end array (implies scanArrayValue if possible)
+	scanSkipSpace           // space byte; can skip; known to be last "continue" result
+
+	// Stop.
+	scanEnd   // top-level value ended *before* this byte; known to be first "stop" result
+	scanError // hit an error, scanner.err.
+)
+
+// These values are stored in the parseState stack.
+// They give the current state of a composite value
+// being scanned. If the parser is inside a nested value
+// the parseState describes the nested state, outermost at entry 0.
+const (
+	parseObjectKey   = iota // parsing object key (before colon)
+	parseObjectValue        // parsing object value (after colon)
+	parseArrayValue         // parsing array value
+)
+
+// This limits the max nesting depth to prevent stack overflow.
+// This is permitted by https://tools.ietf.org/html/rfc7159#section-9
+const maxNestingDepth = 10000
+
+// reset prepares the scanner for use.
+// It must be called before calling s.step.
+func (s *scanner) reset() {
+	s.step = stateBeginValue
+	s.parseState = s.parseState[0:0]
+	s.err = nil
+	s.endTop = false
+}
+
+// eof tells the scanner that the end of input has been reached.
+// It returns a scan status just as s.step does.
+func (s *scanner) eof() int {
+	if s.err != nil {
+		return scanError
+	}
+	if s.endTop {
+		return scanEnd
+	}
+	s.step(s, ' ')
+	if s.endTop {
+		return scanEnd
+	}
+	if s.err == nil {
+		s.err = &SyntaxError{"unexpected end of JSON input", s.bytes}
+	}
+	return scanError
+}
+
+// pushParseState pushes a new parse state p onto the parse stack.
+// an error state is returned if maxNestingDepth was exceeded, otherwise successState is returned.
+func (s *scanner) pushParseState(c byte, newParseState int, successState int) int {
+	s.parseState = append(s.parseState, newParseState)
+	if len(s.parseState) <= maxNestingDepth {
+		return successState
+	}
+	return s.error(c, "exceeded max depth")
+}
+
+// popParseState pops a parse state (already obtained) off the stack
+// and updates s.step accordingly.
+func (s *scanner) popParseState() {
+	n := len(s.parseState) - 1
+	s.parseState = s.parseState[0:n]
+	if n == 0 {
+		s.step = stateEndTop
+		s.endTop = true
+	} else {
+		s.step = stateEndValue
+	}
+}
+
+func isSpace(c byte) bool {
+	return c <= ' ' && (c == ' ' || c == '\t' || c == '\r' || c == '\n')
+}
+
+// stateBeginValueOrEmpty is the state after reading `[`.
+func stateBeginValueOrEmpty(s *scanner, c byte) int {
+	if isSpace(c) {
+		return scanSkipSpace
+	}
+	if c == ']' {
+		return stateEndValue(s, c)
+	}
+	return stateBeginValue(s, c)
+}
+
+// stateBeginValue is the state at the beginning of the input.
+func stateBeginValue(s *scanner, c byte) int {
+	if isSpace(c) {
+		return scanSkipSpace
+	}
+	switch c {
+	case '{':
+		s.step = stateBeginStringOrEmpty
+		return s.pushParseState(c, parseObjectKey, scanBeginObject)
+	case '[':
+		s.step = stateBeginValueOrEmpty
+		return s.pushParseState(c, parseArrayValue, scanBeginArray)
+	case '"':
+		s.step = stateInString
+		return scanBeginLiteral
+	case '-':
+		s.step = stateNeg
+		return scanBeginLiteral
+	case '0': // beginning of 0.123
+		s.step = state0
+		return scanBeginLiteral
+	case 't': // beginning of true
+		s.step = stateT
+		return scanBeginLiteral
+	case 'f': // beginning of false
+		s.step = stateF
+		return scanBeginLiteral
+	case 'n': // beginning of null
+		s.step = stateN
+		return scanBeginLiteral
+	}
+	if '1' <= c && c <= '9' { // beginning of 1234.5
+		s.step = state1
+		return scanBeginLiteral
+	}
+	return s.error(c, "looking for beginning of value")
+}
+
+// stateBeginStringOrEmpty is the state after reading `{`.
+func stateBeginStringOrEmpty(s *scanner, c byte) int {
+	if isSpace(c) {
+		return scanSkipSpace
+	}
+	if c == '}' {
+		n := len(s.parseState)
+		s.parseState[n-1] = parseObjectValue
+		return stateEndValue(s, c)
+	}
+	return stateBeginString(s, c)
+}
+
+// stateBeginString is the state after reading `{"key": value,`.
+func stateBeginString(s *scanner, c byte) int {
+	if isSpace(c) {
+		return scanSkipSpace
+	}
+	if c == '"' {
+		s.step = stateInString
+		return scanBeginLiteral
+	}
+	return s.error(c, "looking for beginning of object key string")
+}
+
+// stateEndValue is the state after completing a value,
+// such as after reading `{}` or `true` or `["x"`.
+func stateEndValue(s *scanner, c byte) int {
+	n := len(s.parseState)
+	if n == 0 {
+		// Completed top-level before the current byte.
+		s.step = stateEndTop
+		s.endTop = true
+		return stateEndTop(s, c)
+	}
+	if isSpace(c) {
+		s.step = stateEndValue
+		return scanSkipSpace
+	}
+	ps := s.parseState[n-1]
+	switch ps {
+	case parseObjectKey:
+		if c == ':' {
+			s.parseState[n-1] = parseObjectValue
+			s.step = stateBeginValue
+			return scanObjectKey
+		}
+		return s.error(c, "after object key")
+	case parseObjectValue:
+		if c == ',' {
+			s.parseState[n-1] = parseObjectKey
+			s.step = stateBeginString
+			return scanObjectValue
+		}
+		if c == '}' {
+			s.popParseState()
+			return scanEndObject
+		}
+		return s.error(c, "after object key:value pair")
+	case parseArrayValue:
+		if c == ',' {
+			s.step = stateBeginValue
+			return scanArrayValue
+		}
+		if c == ']' {
+			s.popParseState()
+			return scanEndArray
+		}
+		return s.error(c, "after array element")
+	}
+	return s.error(c, "")
+}
+
+// stateEndTop is the state after finishing the top-level value,
+// such as after reading `{}` or `[1,2,3]`.
+// Only space characters should be seen now.
+func stateEndTop(s *scanner, c byte) int {
+	if !isSpace(c) {
+		// Complain about non-space byte on next call.
+		s.error(c, "after top-level value")
+	}
+	return scanEnd
+}
+
+// stateInString is the state after reading `"`.
+func stateInString(s *scanner, c byte) int {
+	if c == '"' {
+		s.step = stateEndValue
+		return scanContinue
+	}
+	if c == '\\' {
+		s.step = stateInStringEsc
+		return scanContinue
+	}
+	if c < 0x20 {
+		return s.error(c, "in string literal")
+	}
+	return scanContinue
+}
+
+// stateInStringEsc is the state after reading `"\` during a quoted string.
+func stateInStringEsc(s *scanner, c byte) int {
+	switch c {
+	case 'b', 'f', 'n', 'r', 't', '\\', '/', '"':
+		s.step = stateInString
+		return scanContinue
+	case 'u':
+		s.step = stateInStringEscU
+		return scanContinue
+	}
+	return s.error(c, "in string escape code")
+}
+
+// stateInStringEscU is the state after reading `"\u` during a quoted string.
+func stateInStringEscU(s *scanner, c byte) int {
+	if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
+		s.step = stateInStringEscU1
+		return scanContinue
+	}
+	// numbers
+	return s.error(c, "in \\u hexadecimal character escape")
+}
+
+// stateInStringEscU1 is the state after reading `"\u1` during a quoted string.
+func stateInStringEscU1(s *scanner, c byte) int {
+	if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
+		s.step = stateInStringEscU12
+		return scanContinue
+	}
+	// numbers
+	return s.error(c, "in \\u hexadecimal character escape")
+}
+
+// stateInStringEscU12 is the state after reading `"\u12` during a quoted string.
+func stateInStringEscU12(s *scanner, c byte) int {
+	if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
+		s.step = stateInStringEscU123
+		return scanContinue
+	}
+	// numbers
+	return s.error(c, "in \\u hexadecimal character escape")
+}
+
+// stateInStringEscU123 is the state after reading `"\u123` during a quoted string.
+func stateInStringEscU123(s *scanner, c byte) int {
+	if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
+		s.step = stateInString
+		return scanContinue
+	}
+	// numbers
+	return s.error(c, "in \\u hexadecimal character escape")
+}
+
+// stateNeg is the state after reading `-` during a number.
+func stateNeg(s *scanner, c byte) int {
+	if c == '0' {
+		s.step = state0
+		return scanContinue
+	}
+	if '1' <= c && c <= '9' {
+		s.step = state1
+		return scanContinue
+	}
+	return s.error(c, "in numeric literal")
+}
+
+// state1 is the state after reading a non-zero integer during a number,
+// such as after reading `1` or `100` but not `0`.
+func state1(s *scanner, c byte) int {
+	if '0' <= c && c <= '9' {
+		s.step = state1
+		return scanContinue
+	}
+	return state0(s, c)
+}
+
+// state0 is the state after reading `0` during a number.
+func state0(s *scanner, c byte) int {
+	if c == '.' {
+		s.step = stateDot
+		return scanContinue
+	}
+	if c == 'e' || c == 'E' {
+		s.step = stateE
+		return scanContinue
+	}
+	return stateEndValue(s, c)
+}
+
+// stateDot is the state after reading the integer and decimal point in a number,
+// such as after reading `1.`.
+func stateDot(s *scanner, c byte) int {
+	if '0' <= c && c <= '9' {
+		s.step = stateDot0
+		return scanContinue
+	}
+	return s.error(c, "after decimal point in numeric literal")
+}
+
+// stateDot0 is the state after reading the integer, decimal point, and subsequent
+// digits of a number, such as after reading `3.14`.
+func stateDot0(s *scanner, c byte) int {
+	if '0' <= c && c <= '9' {
+		return scanContinue
+	}
+	if c == 'e' || c == 'E' {
+		s.step = stateE
+		return scanContinue
+	}
+	return stateEndValue(s, c)
+}
+
+// stateE is the state after reading the mantissa and e in a number,
+// such as after reading `314e` or `0.314e`.
+func stateE(s *scanner, c byte) int {
+	if c == '+' || c == '-' {
+		s.step = stateESign
+		return scanContinue
+	}
+	return stateESign(s, c)
+}
+
+// stateESign is the state after reading the mantissa, e, and sign in a number,
+// such as after reading `314e-` or `0.314e+`.
+func stateESign(s *scanner, c byte) int {
+	if '0' <= c && c <= '9' {
+		s.step = stateE0
+		return scanContinue
+	}
+	return s.error(c, "in exponent of numeric literal")
+}
+
+// stateE0 is the state after reading the mantissa, e, optional sign,
+// and at least one digit of the exponent in a number,
+// such as after reading `314e-2` or `0.314e+1` or `3.14e0`.
+func stateE0(s *scanner, c byte) int {
+	if '0' <= c && c <= '9' {
+		return scanContinue
+	}
+	return stateEndValue(s, c)
+}
+
+// stateT is the state after reading `t`.
+func stateT(s *scanner, c byte) int {
+	if c == 'r' {
+		s.step = stateTr
+		return scanContinue
+	}
+	return s.error(c, "in literal true (expecting 'r')")
+}
+
+// stateTr is the state after reading `tr`.
+func stateTr(s *scanner, c byte) int {
+	if c == 'u' {
+		s.step = stateTru
+		return scanContinue
+	}
+	return s.error(c, "in literal true (expecting 'u')")
+}
+
+// stateTru is the state after reading `tru`.
+func stateTru(s *scanner, c byte) int {
+	if c == 'e' {
+		s.step = stateEndValue
+		return scanContinue
+	}
+	return s.error(c, "in literal true (expecting 'e')")
+}
+
+// stateF is the state after reading `f`.
+func stateF(s *scanner, c byte) int {
+	if c == 'a' {
+		s.step = stateFa
+		return scanContinue
+	}
+	return s.error(c, "in literal false (expecting 'a')")
+}
+
+// stateFa is the state after reading `fa`.
+func stateFa(s *scanner, c byte) int {
+	if c == 'l' {
+		s.step = stateFal
+		return scanContinue
+	}
+	return s.error(c, "in literal false (expecting 'l')")
+}
+
+// stateFal is the state after reading `fal`.
+func stateFal(s *scanner, c byte) int {
+	if c == 's' {
+		s.step = stateFals
+		return scanContinue
+	}
+	return s.error(c, "in literal false (expecting 's')")
+}
+
+// stateFals is the state after reading `fals`.
+func stateFals(s *scanner, c byte) int {
+	if c == 'e' {
+		s.step = stateEndValue
+		return scanContinue
+	}
+	return s.error(c, "in literal false (expecting 'e')")
+}
+
+// stateN is the state after reading `n`.
+func stateN(s *scanner, c byte) int {
+	if c == 'u' {
+		s.step = stateNu
+		return scanContinue
+	}
+	return s.error(c, "in literal null (expecting 'u')")
+}
+
+// stateNu is the state after reading `nu`.
+func stateNu(s *scanner, c byte) int {
+	if c == 'l' {
+		s.step = stateNul
+		return scanContinue
+	}
+	return s.error(c, "in literal null (expecting 'l')")
+}
+
+// stateNul is the state after reading `nul`.
+func stateNul(s *scanner, c byte) int {
+	if c == 'l' {
+		s.step = stateEndValue
+		return scanContinue
+	}
+	return s.error(c, "in literal null (expecting 'l')")
+}
+
+// stateError is the state after reaching a syntax error,
+// such as after reading `[1}` or `5.1.2`.
+func stateError(s *scanner, c byte) int {
+	return scanError
+}
+
+// error records an error and switches to the error state.
+func (s *scanner) error(c byte, context string) int {
+	s.step = stateError
+	s.err = &SyntaxError{"invalid character " + quoteChar(c) + " " + context, s.bytes}
+	return scanError
+}
+
+// quoteChar formats c as a quoted character literal.
+func quoteChar(c byte) string {
+	// special cases - different from quoted strings
+	if c == '\'' {
+		return `'\''`
+	}
+	if c == '"' {
+		return `'"'`
+	}
+
+	// use quoted string with different quotation marks
+	s := strconv.Quote(string(c))
+	return "'" + s[1:len(s)-1] + "'"
+}
diff --git a/vendor/github.com/evanphx/json-patch/v5/internal/json/stream.go b/vendor/github.com/evanphx/json-patch/v5/internal/json/stream.go
new file mode 100644
index 00000000..1442ef29
--- /dev/null
+++ b/vendor/github.com/evanphx/json-patch/v5/internal/json/stream.go
@@ -0,0 +1,515 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package json
+
+import (
+	"bytes"
+	"errors"
+	"io"
+)
+
+// A Decoder reads and decodes JSON values from an input stream.
+type Decoder struct {
+	r       io.Reader
+	buf     []byte
+	d       decodeState
+	scanp   int   // start of unread data in buf
+	scanned int64 // amount of data already scanned
+	scan    scanner
+	err     error
+
+	tokenState int
+	tokenStack []int
+}
+
+// NewDecoder returns a new decoder that reads from r.
+//
+// The decoder introduces its own buffering and may
+// read data from r beyond the JSON values requested.
+func NewDecoder(r io.Reader) *Decoder {
+	return &Decoder{r: r}
+}
+
+// UseNumber causes the Decoder to unmarshal a number into an interface{} as a
+// Number instead of as a float64.
+func (dec *Decoder) UseNumber() { dec.d.useNumber = true }
+
+// DisallowUnknownFields causes the Decoder to return an error when the destination
+// is a struct and the input contains object keys which do not match any
+// non-ignored, exported fields in the destination.
+func (dec *Decoder) DisallowUnknownFields() { dec.d.disallowUnknownFields = true }
+
+// Decode reads the next JSON-encoded value from its
+// input and stores it in the value pointed to by v.
+//
+// See the documentation for Unmarshal for details about
+// the conversion of JSON into a Go value.
+func (dec *Decoder) Decode(v any) error {
+	if dec.err != nil {
+		return dec.err
+	}
+
+	if err := dec.tokenPrepareForDecode(); err != nil {
+		return err
+	}
+
+	if !dec.tokenValueAllowed() {
+		return &SyntaxError{msg: "not at beginning of value", Offset: dec.InputOffset()}
+	}
+
+	// Read whole value into buffer.
+	n, err := dec.readValue()
+	if err != nil {
+		return err
+	}
+	dec.d.init(dec.buf[dec.scanp : dec.scanp+n])
+	dec.scanp += n
+
+	// Don't save err from unmarshal into dec.err:
+	// the connection is still usable since we read a complete JSON
+	// object from it before the error happened.
+	err = dec.d.unmarshal(v)
+
+	// fixup token streaming state
+	dec.tokenValueEnd()
+
+	return err
+}
+
+// Buffered returns a reader of the data remaining in the Decoder's
+// buffer. The reader is valid until the next call to Decode.
+func (dec *Decoder) Buffered() io.Reader {
+	return bytes.NewReader(dec.buf[dec.scanp:])
+}
+
+// readValue reads a JSON value into dec.buf.
+// It returns the length of the encoding.
+func (dec *Decoder) readValue() (int, error) {
+	dec.scan.reset()
+
+	scanp := dec.scanp
+	var err error
+Input:
+	// help the compiler see that scanp is never negative, so it can remove
+	// some bounds checks below.
+	for scanp >= 0 {
+
+		// Look in the buffer for a new value.
+		for ; scanp < len(dec.buf); scanp++ {
+			c := dec.buf[scanp]
+			dec.scan.bytes++
+			switch dec.scan.step(&dec.scan, c) {
+			case scanEnd:
+				// scanEnd is delayed one byte so we decrement
+				// the scanner bytes count by 1 to ensure that
+				// this value is correct in the next call of Decode.
+				dec.scan.bytes--
+				break Input
+			case scanEndObject, scanEndArray:
+				// scanEnd is delayed one byte.
+				// We might block trying to get that byte from src,
+				// so instead invent a space byte.
+				if stateEndValue(&dec.scan, ' ') == scanEnd {
+					scanp++
+					break Input
+				}
+			case scanError:
+				dec.err = dec.scan.err
+				return 0, dec.scan.err
+			}
+		}
+
+		// Did the last read have an error?
+		// Delayed until now to allow buffer scan.
+		if err != nil {
+			if err == io.EOF {
+				if dec.scan.step(&dec.scan, ' ') == scanEnd {
+					break Input
+				}
+				if nonSpace(dec.buf) {
+					err = io.ErrUnexpectedEOF
+				}
+			}
+			dec.err = err
+			return 0, err
+		}
+
+		n := scanp - dec.scanp
+		err = dec.refill()
+		scanp = dec.scanp + n
+	}
+	return scanp - dec.scanp, nil
+}
+
+func (dec *Decoder) refill() error {
+	// Make room to read more into the buffer.
+	// First slide down data already consumed.
+	if dec.scanp > 0 {
+		dec.scanned += int64(dec.scanp)
+		n := copy(dec.buf, dec.buf[dec.scanp:])
+		dec.buf = dec.buf[:n]
+		dec.scanp = 0
+	}
+
+	// Grow buffer if not large enough.
+	const minRead = 512
+	if cap(dec.buf)-len(dec.buf) < minRead {
+		newBuf := make([]byte, len(dec.buf), 2*cap(dec.buf)+minRead)
+		copy(newBuf, dec.buf)
+		dec.buf = newBuf
+	}
+
+	// Read. Delay error for next iteration (after scan).
+	n, err := dec.r.Read(dec.buf[len(dec.buf):cap(dec.buf)])
+	dec.buf = dec.buf[0 : len(dec.buf)+n]
+
+	return err
+}
+
+func nonSpace(b []byte) bool {
+	for _, c := range b {
+		if !isSpace(c) {
+			return true
+		}
+	}
+	return false
+}
+
+// An Encoder writes JSON values to an output stream.
+type Encoder struct {
+	w          io.Writer
+	err        error
+	escapeHTML bool
+
+	indentBuf    *bytes.Buffer
+	indentPrefix string
+	indentValue  string
+}
+
+// NewEncoder returns a new encoder that writes to w.
+func NewEncoder(w io.Writer) *Encoder {
+	return &Encoder{w: w, escapeHTML: true}
+}
+
+// Encode writes the JSON encoding of v to the stream,
+// followed by a newline character.
+//
+// See the documentation for Marshal for details about the
+// conversion of Go values to JSON.
+func (enc *Encoder) Encode(v any) error {
+	if enc.err != nil {
+		return enc.err
+	}
+
+	e := newEncodeState()
+	defer encodeStatePool.Put(e)
+
+	err := e.marshal(v, encOpts{escapeHTML: enc.escapeHTML})
+	if err != nil {
+		return err
+	}
+
+	// Terminate each value with a newline.
+	// This makes the output look a little nicer
+	// when debugging, and some kind of space
+	// is required if the encoded value was a number,
+	// so that the reader knows there aren't more
+	// digits coming.
+	e.WriteByte('\n')
+
+	b := e.Bytes()
+	if enc.indentPrefix != "" || enc.indentValue != "" {
+		if enc.indentBuf == nil {
+			enc.indentBuf = new(bytes.Buffer)
+		}
+		enc.indentBuf.Reset()
+		err = Indent(enc.indentBuf, b, enc.indentPrefix, enc.indentValue)
+		if err != nil {
+			return err
+		}
+		b = enc.indentBuf.Bytes()
+	}
+	if _, err = enc.w.Write(b); err != nil {
+		enc.err = err
+	}
+	return err
+}
+
+// SetIndent instructs the encoder to format each subsequent encoded
+// value as if indented by the package-level function Indent(dst, src, prefix, indent).
+// Calling SetIndent("", "") disables indentation.
+func (enc *Encoder) SetIndent(prefix, indent string) {
+	enc.indentPrefix = prefix
+	enc.indentValue = indent
+}
+
+// SetEscapeHTML specifies whether problematic HTML characters
+// should be escaped inside JSON quoted strings.
+// The default behavior is to escape &, <, and > to \u0026, \u003c, and \u003e
+// to avoid certain safety problems that can arise when embedding JSON in HTML.
+//
+// In non-HTML settings where the escaping interferes with the readability
+// of the output, SetEscapeHTML(false) disables this behavior.
+func (enc *Encoder) SetEscapeHTML(on bool) {
+	enc.escapeHTML = on
+}
+
+// RawMessage is a raw encoded JSON value.
+// It implements Marshaler and Unmarshaler and can
+// be used to delay JSON decoding or precompute a JSON encoding.
+type RawMessage []byte
+
+// MarshalJSON returns m as the JSON encoding of m.
+func (m RawMessage) MarshalJSON() ([]byte, error) {
+	if m == nil {
+		return []byte("null"), nil
+	}
+	return m, nil
+}
+
+// UnmarshalJSON sets *m to a copy of data.
+func (m *RawMessage) UnmarshalJSON(data []byte) error {
+	if m == nil {
+		return errors.New("json.RawMessage: UnmarshalJSON on nil pointer")
+	}
+	*m = append((*m)[0:0], data...)
+	return nil
+}
+
+var _ Marshaler = (*RawMessage)(nil)
+var _ Unmarshaler = (*RawMessage)(nil)
+
+// A Token holds a value of one of these types:
+//
+//	Delim, for the four JSON delimiters [ ] { }
+//	bool, for JSON booleans
+//	float64, for JSON numbers
+//	Number, for JSON numbers
+//	string, for JSON string literals
+//	nil, for JSON null
+type Token any
+
+const (
+	tokenTopValue = iota
+	tokenArrayStart
+	tokenArrayValue
+	tokenArrayComma
+	tokenObjectStart
+	tokenObjectKey
+	tokenObjectColon
+	tokenObjectValue
+	tokenObjectComma
+)
+
+// advance tokenstate from a separator state to a value state
+func (dec *Decoder) tokenPrepareForDecode() error {
+	// Note: Not calling peek before switch, to avoid
+	// putting peek into the standard Decode path.
+	// peek is only called when using the Token API.
+	switch dec.tokenState {
+	case tokenArrayComma:
+		c, err := dec.peek()
+		if err != nil {
+			return err
+		}
+		if c != ',' {
+			return &SyntaxError{"expected comma after array element", dec.InputOffset()}
+		}
+		dec.scanp++
+		dec.tokenState = tokenArrayValue
+	case tokenObjectColon:
+		c, err := dec.peek()
+		if err != nil {
+			return err
+		}
+		if c != ':' {
+			return &SyntaxError{"expected colon after object key", dec.InputOffset()}
+		}
+		dec.scanp++
+		dec.tokenState = tokenObjectValue
+	}
+	return nil
+}
+
+func (dec *Decoder) tokenValueAllowed() bool {
+	switch dec.tokenState {
+	case tokenTopValue, tokenArrayStart, tokenArrayValue, tokenObjectValue:
+		return true
+	}
+	return false
+}
+
+func (dec *Decoder) tokenValueEnd() {
+	switch dec.tokenState {
+	case tokenArrayStart, tokenArrayValue:
+		dec.tokenState = tokenArrayComma
+	case tokenObjectValue:
+		dec.tokenState = tokenObjectComma
+	}
+}
+
+// A Delim is a JSON array or object delimiter, one of [ ] { or }.
+type Delim rune
+
+func (d Delim) String() string {
+	return string(d)
+}
+
+// Token returns the next JSON token in the input stream.
+// At the end of the input stream, Token returns nil, io.EOF.
+//
+// Token guarantees that the delimiters [ ] { } it returns are
+// properly nested and matched: if Token encounters an unexpected
+// delimiter in the input, it will return an error.
+//
+// The input stream consists of basic JSON values—bool, string,
+// number, and null—along with delimiters [ ] { } of type Delim
+// to mark the start and end of arrays and objects.
+// Commas and colons are elided.
+func (dec *Decoder) Token() (Token, error) {
+	for {
+		c, err := dec.peek()
+		if err != nil {
+			return nil, err
+		}
+		switch c {
+		case '[':
+			if !dec.tokenValueAllowed() {
+				return dec.tokenError(c)
+			}
+			dec.scanp++
+			dec.tokenStack = append(dec.tokenStack, dec.tokenState)
+			dec.tokenState = tokenArrayStart
+			return Delim('['), nil
+
+		case ']':
+			if dec.tokenState != tokenArrayStart && dec.tokenState != tokenArrayComma {
+				return dec.tokenError(c)
+			}
+			dec.scanp++
+			dec.tokenState = dec.tokenStack[len(dec.tokenStack)-1]
+			dec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1]
+			dec.tokenValueEnd()
+			return Delim(']'), nil
+
+		case '{':
+			if !dec.tokenValueAllowed() {
+				return dec.tokenError(c)
+			}
+			dec.scanp++
+			dec.tokenStack = append(dec.tokenStack, dec.tokenState)
+			dec.tokenState = tokenObjectStart
+			return Delim('{'), nil
+
+		case '}':
+			if dec.tokenState != tokenObjectStart && dec.tokenState != tokenObjectComma {
+				return dec.tokenError(c)
+			}
+			dec.scanp++
+			dec.tokenState = dec.tokenStack[len(dec.tokenStack)-1]
+			dec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1]
+			dec.tokenValueEnd()
+			return Delim('}'), nil
+
+		case ':':
+			if dec.tokenState != tokenObjectColon {
+				return dec.tokenError(c)
+			}
+			dec.scanp++
+			dec.tokenState = tokenObjectValue
+			continue
+
+		case ',':
+			if dec.tokenState == tokenArrayComma {
+				dec.scanp++
+				dec.tokenState = tokenArrayValue
+				continue
+			}
+			if dec.tokenState == tokenObjectComma {
+				dec.scanp++
+				dec.tokenState = tokenObjectKey
+				continue
+			}
+			return dec.tokenError(c)
+
+		case '"':
+			if dec.tokenState == tokenObjectStart || dec.tokenState == tokenObjectKey {
+				var x string
+				old := dec.tokenState
+				dec.tokenState = tokenTopValue
+				err := dec.Decode(&x)
+				dec.tokenState = old
+				if err != nil {
+					return nil, err
+				}
+				dec.tokenState = tokenObjectColon
+				return x, nil
+			}
+			fallthrough
+
+		default:
+			if !dec.tokenValueAllowed() {
+				return dec.tokenError(c)
+			}
+			var x any
+			if err := dec.Decode(&x); err != nil {
+				return nil, err
+			}
+			return x, nil
+		}
+	}
+}
+
+func (dec *Decoder) tokenError(c byte) (Token, error) {
+	var context string
+	switch dec.tokenState {
+	case tokenTopValue:
+		context = " looking for beginning of value"
+	case tokenArrayStart, tokenArrayValue, tokenObjectValue:
+		context = " looking for beginning of value"
+	case tokenArrayComma:
+		context = " after array element"
+	case tokenObjectKey:
+		context = " looking for beginning of object key string"
+	case tokenObjectColon:
+		context = " after object key"
+	case tokenObjectComma:
+		context = " after object key:value pair"
+	}
+	return nil, &SyntaxError{"invalid character " + quoteChar(c) + context, dec.InputOffset()}
+}
+
+// More reports whether there is another element in the
+// current array or object being parsed.
+func (dec *Decoder) More() bool {
+	c, err := dec.peek()
+	return err == nil && c != ']' && c != '}'
+}
+
+func (dec *Decoder) peek() (byte, error) {
+	var err error
+	for {
+		for i := dec.scanp; i < len(dec.buf); i++ {
+			c := dec.buf[i]
+			if isSpace(c) {
+				continue
+			}
+			dec.scanp = i
+			return c, nil
+		}
+		// buffer has been scanned, now report any error
+		if err != nil {
+			return 0, err
+		}
+		err = dec.refill()
+	}
+}
+
+// InputOffset returns the input stream byte offset of the current decoder position.
+// The offset gives the location of the end of the most recently returned token
+// and the beginning of the next token.
+func (dec *Decoder) InputOffset() int64 {
+	return dec.scanned + int64(dec.scanp)
+}
diff --git a/vendor/github.com/evanphx/json-patch/v5/internal/json/tables.go b/vendor/github.com/evanphx/json-patch/v5/internal/json/tables.go
new file mode 100644
index 00000000..10acdc18
--- /dev/null
+++ b/vendor/github.com/evanphx/json-patch/v5/internal/json/tables.go
@@ -0,0 +1,218 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package json
+
+import "unicode/utf8"
+
+// safeSet holds the value true if the ASCII character with the given array
+// position can be represented inside a JSON string without any further
+// escaping.
+//
+// All values are true except for the ASCII control characters (0-31), the
+// double quote ("), and the backslash character ("\").
+var safeSet = [utf8.RuneSelf]bool{
+	' ':      true,
+	'!':      true,
+	'"':      false,
+	'#':      true,
+	'$':      true,
+	'%':      true,
+	'&':      true,
+	'\'':     true,
+	'(':      true,
+	')':      true,
+	'*':      true,
+	'+':      true,
+	',':      true,
+	'-':      true,
+	'.':      true,
+	'/':      true,
+	'0':      true,
+	'1':      true,
+	'2':      true,
+	'3':      true,
+	'4':      true,
+	'5':      true,
+	'6':      true,
+	'7':      true,
+	'8':      true,
+	'9':      true,
+	':':      true,
+	';':      true,
+	'<':      true,
+	'=':      true,
+	'>':      true,
+	'?':      true,
+	'@':      true,
+	'A':      true,
+	'B':      true,
+	'C':      true,
+	'D':      true,
+	'E':      true,
+	'F':      true,
+	'G':      true,
+	'H':      true,
+	'I':      true,
+	'J':      true,
+	'K':      true,
+	'L':      true,
+	'M':      true,
+	'N':      true,
+	'O':      true,
+	'P':      true,
+	'Q':      true,
+	'R':      true,
+	'S':      true,
+	'T':      true,
+	'U':      true,
+	'V':      true,
+	'W':      true,
+	'X':      true,
+	'Y':      true,
+	'Z':      true,
+	'[':      true,
+	'\\':     false,
+	']':      true,
+	'^':      true,
+	'_':      true,
+	'`':      true,
+	'a':      true,
+	'b':      true,
+	'c':      true,
+	'd':      true,
+	'e':      true,
+	'f':      true,
+	'g':      true,
+	'h':      true,
+	'i':      true,
+	'j':      true,
+	'k':      true,
+	'l':      true,
+	'm':      true,
+	'n':      true,
+	'o':      true,
+	'p':      true,
+	'q':      true,
+	'r':      true,
+	's':      true,
+	't':      true,
+	'u':      true,
+	'v':      true,
+	'w':      true,
+	'x':      true,
+	'y':      true,
+	'z':      true,
+	'{':      true,
+	'|':      true,
+	'}':      true,
+	'~':      true,
+	'\u007f': true,
+}
+
+// htmlSafeSet holds the value true if the ASCII character with the given
+// array position can be safely represented inside a JSON string, embedded
+// inside of HTML <script> tags, without any additional escaping.
+//
+// All values are true except for the ASCII control characters (0-31), the
+// double quote ("), the backslash character ("\"), HTML opening and closing
+// tags ("<" and ">"), and the ampersand ("&").
+var htmlSafeSet = [utf8.RuneSelf]bool{
+	' ':      true,
+	'!':      true,
+	'"':      false,
+	'#':      true,
+	'$':      true,
+	'%':      true,
+	'&':      false,
+	'\'':     true,
+	'(':      true,
+	')':      true,
+	'*':      true,
+	'+':      true,
+	',':      true,
+	'-':      true,
+	'.':      true,
+	'/':      true,
+	'0':      true,
+	'1':      true,
+	'2':      true,
+	'3':      true,
+	'4':      true,
+	'5':      true,
+	'6':      true,
+	'7':      true,
+	'8':      true,
+	'9':      true,
+	':':      true,
+	';':      true,
+	'<':      false,
+	'=':      true,
+	'>':      false,
+	'?':      true,
+	'@':      true,
+	'A':      true,
+	'B':      true,
+	'C':      true,
+	'D':      true,
+	'E':      true,
+	'F':      true,
+	'G':      true,
+	'H':      true,
+	'I':      true,
+	'J':      true,
+	'K':      true,
+	'L':      true,
+	'M':      true,
+	'N':      true,
+	'O':      true,
+	'P':      true,
+	'Q':      true,
+	'R':      true,
+	'S':      true,
+	'T':      true,
+	'U':      true,
+	'V':      true,
+	'W':      true,
+	'X':      true,
+	'Y':      true,
+	'Z':      true,
+	'[':      true,
+	'\\':     false,
+	']':      true,
+	'^':      true,
+	'_':      true,
+	'`':      true,
+	'a':      true,
+	'b':      true,
+	'c':      true,
+	'd':      true,
+	'e':      true,
+	'f':      true,
+	'g':      true,
+	'h':      true,
+	'i':      true,
+	'j':      true,
+	'k':      true,
+	'l':      true,
+	'm':      true,
+	'n':      true,
+	'o':      true,
+	'p':      true,
+	'q':      true,
+	'r':      true,
+	's':      true,
+	't':      true,
+	'u':      true,
+	'v':      true,
+	'w':      true,
+	'x':      true,
+	'y':      true,
+	'z':      true,
+	'{':      true,
+	'|':      true,
+	'}':      true,
+	'~':      true,
+	'\u007f': true,
+}
diff --git a/vendor/github.com/evanphx/json-patch/v5/internal/json/tags.go b/vendor/github.com/evanphx/json-patch/v5/internal/json/tags.go
new file mode 100644
index 00000000..b490328f
--- /dev/null
+++ b/vendor/github.com/evanphx/json-patch/v5/internal/json/tags.go
@@ -0,0 +1,38 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package json
+
+import (
+	"strings"
+)
+
+// tagOptions is the string following a comma in a struct field's "json"
+// tag, or the empty string. It does not include the leading comma.
+type tagOptions string
+
+// parseTag splits a struct field's json tag into its name and
+// comma-separated options.
+func parseTag(tag string) (string, tagOptions) {
+	tag, opt, _ := strings.Cut(tag, ",")
+	return tag, tagOptions(opt)
+}
+
+// Contains reports whether a comma-separated list of options
+// contains a particular substr flag. substr must be surrounded by a
+// string boundary or commas.
+func (o tagOptions) Contains(optionName string) bool {
+	if len(o) == 0 {
+		return false
+	}
+	s := string(o)
+	for s != "" {
+		var name string
+		name, s, _ = strings.Cut(s, ",")
+		if name == optionName {
+			return true
+		}
+	}
+	return false
+}
diff --git a/vendor/github.com/evanphx/json-patch/v5/merge.go b/vendor/github.com/evanphx/json-patch/v5/merge.go
index a7c45734..bbe9f85f 100644
--- a/vendor/github.com/evanphx/json-patch/v5/merge.go
+++ b/vendor/github.com/evanphx/json-patch/v5/merge.go
@@ -2,9 +2,12 @@ package jsonpatch
 
 import (
 	"bytes"
-	"encoding/json"
+	"errors"
 	"fmt"
+	"io"
 	"reflect"
+
+	"github.com/evanphx/json-patch/v5/internal/json"
 )
 
 func merge(cur, patch *lazyNode, mergeMerge bool) *lazyNode {
@@ -88,14 +91,14 @@ func pruneDocNulls(doc *partialDoc) *partialDoc {
 func pruneAryNulls(ary *partialArray) *partialArray {
 	newAry := []*lazyNode{}
 
-	for _, v := range *ary {
+	for _, v := range ary.nodes {
 		if v != nil {
 			pruneNulls(v)
 		}
 		newAry = append(newAry, v)
 	}
 
-	*ary = newAry
+	ary.nodes = newAry
 
 	return ary
 }
@@ -117,20 +120,28 @@ func MergePatch(docData, patchData []byte) ([]byte, error) {
 }
 
 func doMergePatch(docData, patchData []byte, mergeMerge bool) ([]byte, error) {
+	if !json.Valid(docData) {
+		return nil, errBadJSONDoc
+	}
+
+	if !json.Valid(patchData) {
+		return nil, errBadJSONPatch
+	}
+
 	doc := &partialDoc{}
 
-	docErr := json.Unmarshal(docData, doc)
+	docErr := doc.UnmarshalJSON(docData)
 
 	patch := &partialDoc{}
 
-	patchErr := json.Unmarshal(patchData, patch)
+	patchErr := patch.UnmarshalJSON(patchData)
 
 	if isSyntaxError(docErr) {
 		return nil, errBadJSONDoc
 	}
 
 	if isSyntaxError(patchErr) {
-		return nil, errBadJSONPatch
+		return patchData, nil
 	}
 
 	if docErr == nil && doc.obj == nil {
@@ -138,7 +149,7 @@ func doMergePatch(docData, patchData []byte, mergeMerge bool) ([]byte, error) {
 	}
 
 	if patchErr == nil && patch.obj == nil {
-		return nil, errBadJSONPatch
+		return patchData, nil
 	}
 
 	if docErr != nil || patchErr != nil {
@@ -151,15 +162,19 @@ func doMergePatch(docData, patchData []byte, mergeMerge bool) ([]byte, error) {
 			}
 		} else {
 			patchAry := &partialArray{}
-			patchErr = json.Unmarshal(patchData, patchAry)
+			patchErr = unmarshal(patchData, &patchAry.nodes)
 
 			if patchErr != nil {
+				// Not an array either, a literal is the result directly.
+				if json.Valid(patchData) {
+					return patchData, nil
+				}
 				return nil, errBadJSONPatch
 			}
 
 			pruneAryNulls(patchAry)
 
-			out, patchErr := json.Marshal(patchAry)
+			out, patchErr := json.Marshal(patchAry.nodes)
 
 			if patchErr != nil {
 				return nil, errBadJSONPatch
@@ -175,6 +190,12 @@ func doMergePatch(docData, patchData []byte, mergeMerge bool) ([]byte, error) {
 }
 
 func isSyntaxError(err error) bool {
+	if errors.Is(err, io.EOF) {
+		return true
+	}
+	if errors.Is(err, io.ErrUnexpectedEOF) {
+		return true
+	}
 	if _, ok := err.(*json.SyntaxError); ok {
 		return true
 	}
@@ -227,12 +248,12 @@ func createObjectMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) {
 	originalDoc := map[string]interface{}{}
 	modifiedDoc := map[string]interface{}{}
 
-	err := json.Unmarshal(originalJSON, &originalDoc)
+	err := unmarshal(originalJSON, &originalDoc)
 	if err != nil {
 		return nil, errBadJSONDoc
 	}
 
-	err = json.Unmarshal(modifiedJSON, &modifiedDoc)
+	err = unmarshal(modifiedJSON, &modifiedDoc)
 	if err != nil {
 		return nil, errBadJSONDoc
 	}
@@ -245,6 +266,10 @@ func createObjectMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) {
 	return json.Marshal(dest)
 }
 
+func unmarshal(data []byte, into interface{}) error {
+	return json.UnmarshalValid(data, into)
+}
+
 // createArrayMergePatch will return an array of merge-patch documents capable
 // of converting the original document to the modified document for each
 // pair of JSON documents provided in the arrays.
@@ -253,12 +278,12 @@ func createArrayMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) {
 	originalDocs := []json.RawMessage{}
 	modifiedDocs := []json.RawMessage{}
 
-	err := json.Unmarshal(originalJSON, &originalDocs)
+	err := unmarshal(originalJSON, &originalDocs)
 	if err != nil {
 		return nil, errBadJSONDoc
 	}
 
-	err = json.Unmarshal(modifiedJSON, &modifiedDocs)
+	err = unmarshal(modifiedJSON, &modifiedDocs)
 	if err != nil {
 		return nil, errBadJSONDoc
 	}
@@ -314,6 +339,11 @@ func matchesValue(av, bv interface{}) bool {
 		if bt == at {
 			return true
 		}
+	case json.Number:
+		bt := bv.(json.Number)
+		if bt == at {
+			return true
+		}
 	case float64:
 		bt := bv.(float64)
 		if bt == at {
@@ -377,7 +407,7 @@ func getDiff(a, b map[string]interface{}) (map[string]interface{}, error) {
 			if len(dst) > 0 {
 				into[key] = dst
 			}
-		case string, float64, bool:
+		case string, float64, bool, json.Number:
 			if !matchesValue(av, bv) {
 				into[key] = bv
 			}
diff --git a/vendor/github.com/evanphx/json-patch/v5/patch.go b/vendor/github.com/evanphx/json-patch/v5/patch.go
index 73ff2c51..a3bbf1c7 100644
--- a/vendor/github.com/evanphx/json-patch/v5/patch.go
+++ b/vendor/github.com/evanphx/json-patch/v5/patch.go
@@ -2,11 +2,12 @@ package jsonpatch
 
 import (
 	"bytes"
-	"encoding/json"
 	"fmt"
 	"strconv"
 	"strings"
+	"unicode"
 
+	"github.com/evanphx/json-patch/v5/internal/json"
 	"github.com/pkg/errors"
 )
 
@@ -45,7 +46,7 @@ var (
 type lazyNode struct {
 	raw   *json.RawMessage
 	doc   *partialDoc
-	ary   partialArray
+	ary   *partialArray
 	which int
 }
 
@@ -56,11 +57,15 @@ type Operation map[string]*json.RawMessage
 type Patch []Operation
 
 type partialDoc struct {
+	self *lazyNode
 	keys []string
 	obj  map[string]*lazyNode
 }
 
-type partialArray []*lazyNode
+type partialArray struct {
+	self  *lazyNode
+	nodes []*lazyNode
+}
 
 type container interface {
 	get(key string, options *ApplyOptions) (*lazyNode, error)
@@ -107,14 +112,14 @@ func newRawMessage(buf []byte) *json.RawMessage {
 	return &ra
 }
 
-func (n *lazyNode) MarshalJSON() ([]byte, error) {
+func (n *lazyNode) RedirectMarshalJSON() (any, error) {
 	switch n.which {
 	case eRaw:
-		return json.Marshal(n.raw)
+		return n.raw, nil
 	case eDoc:
-		return json.Marshal(n.doc)
+		return n.doc, nil
 	case eAry:
-		return json.Marshal(n.ary)
+		return n.ary.nodes, nil
 	default:
 		return nil, ErrUnknownType
 	}
@@ -128,39 +133,38 @@ func (n *lazyNode) UnmarshalJSON(data []byte) error {
 	return nil
 }
 
-func (n *partialDoc) MarshalJSON() ([]byte, error) {
-	var buf bytes.Buffer
-	if _, err := buf.WriteString("{"); err != nil {
-		return nil, err
+func (n *partialDoc) TrustMarshalJSON(buf *bytes.Buffer) error {
+	if err := buf.WriteByte('{'); err != nil {
+		return err
 	}
 	for i, k := range n.keys {
 		if i > 0 {
-			if _, err := buf.WriteString(", "); err != nil {
-				return nil, err
+			if err := buf.WriteByte(','); err != nil {
+				return err
 			}
 		}
 		key, err := json.Marshal(k)
 		if err != nil {
-			return nil, err
+			return err
 		}
 		if _, err := buf.Write(key); err != nil {
-			return nil, err
+			return err
 		}
-		if _, err := buf.WriteString(": "); err != nil {
-			return nil, err
+		if err := buf.WriteByte(':'); err != nil {
+			return err
 		}
 		value, err := json.Marshal(n.obj[k])
 		if err != nil {
-			return nil, err
+			return err
 		}
 		if _, err := buf.Write(value); err != nil {
-			return nil, err
+			return err
 		}
 	}
-	if _, err := buf.WriteString("}"); err != nil {
-		return nil, err
+	if err := buf.WriteByte('}'); err != nil {
+		return err
 	}
-	return buf.Bytes(), nil
+	return nil
 }
 
 type syntaxError struct {
@@ -172,70 +176,29 @@ func (err *syntaxError) Error() string {
 }
 
 func (n *partialDoc) UnmarshalJSON(data []byte) error {
-	if err := json.Unmarshal(data, &n.obj); err != nil {
-		return err
-	}
-	buffer := bytes.NewBuffer(data)
-	d := json.NewDecoder(buffer)
-	if t, err := d.Token(); err != nil {
+	keys, err := json.UnmarshalValidWithKeys(data, &n.obj)
+	if err != nil {
 		return err
-	} else if t != startObject {
-		return &syntaxError{fmt.Sprintf("unexpected JSON token in document node: %v", t)}
-	}
-	for d.More() {
-		k, err := d.Token()
-		if err != nil {
-			return err
-		}
-		key, ok := k.(string)
-		if !ok {
-			return &syntaxError{fmt.Sprintf("unexpected JSON token as document node key: %s", k)}
-		}
-		if err := skipValue(d); err != nil {
-			return err
-		}
-		n.keys = append(n.keys, key)
 	}
+
+	n.keys = keys
+
 	return nil
 }
 
-func skipValue(d *json.Decoder) error {
-	t, err := d.Token()
-	if err != nil {
-		return err
-	}
-	if t != startObject && t != startArray {
-		return nil
-	}
-	for d.More() {
-		if t == startObject {
-			// consume key token
-			if _, err := d.Token(); err != nil {
-				return err
-			}
-		}
-		if err := skipValue(d); err != nil {
-			return err
-		}
-	}
-	end, err := d.Token()
-	if err != nil {
-		return err
-	}
-	if t == startObject && end != endObject {
-		return &syntaxError{msg: "expected close object token"}
-	}
-	if t == startArray && end != endArray {
-		return &syntaxError{msg: "expected close object token"}
-	}
-	return nil
+func (n *partialArray) UnmarshalJSON(data []byte) error {
+	return json.UnmarshalValid(data, &n.nodes)
+}
+
+func (n *partialArray) RedirectMarshalJSON() (interface{}, error) {
+	return n.nodes, nil
 }
 
 func deepCopy(src *lazyNode) (*lazyNode, int, error) {
 	if src == nil {
 		return nil, 0, nil
 	}
-	a, err := src.MarshalJSON()
+	a, err := json.Marshal(src)
 	if err != nil {
 		return nil, 0, err
 	}
@@ -243,6 +206,16 @@ func deepCopy(src *lazyNode) (*lazyNode, int, error) {
 	return newLazyNode(newRawMessage(a)), sz, nil
 }
 
+func (n *lazyNode) nextByte() byte {
+	s := []byte(*n.raw)
+
+	for unicode.IsSpace(rune(s[0])) {
+		s = s[1:]
+	}
+
+	return s[0]
+}
+
 func (n *lazyNode) intoDoc() (*partialDoc, error) {
 	if n.which == eDoc {
 		return n.doc, nil
@@ -252,7 +225,15 @@ func (n *lazyNode) intoDoc() (*partialDoc, error) {
 		return nil, ErrInvalid
 	}
 
-	err := json.Unmarshal(*n.raw, &n.doc)
+	if n.nextByte() != '{' {
+		return nil, ErrInvalid
+	}
+
+	err := unmarshal(*n.raw, &n.doc)
+
+	if n.doc == nil {
+		return nil, ErrInvalid
+	}
 
 	if err != nil {
 		return nil, err
@@ -264,21 +245,21 @@ func (n *lazyNode) intoDoc() (*partialDoc, error) {
 
 func (n *lazyNode) intoAry() (*partialArray, error) {
 	if n.which == eAry {
-		return &n.ary, nil
+		return n.ary, nil
 	}
 
 	if n.raw == nil {
 		return nil, ErrInvalid
 	}
 
-	err := json.Unmarshal(*n.raw, &n.ary)
+	err := unmarshal(*n.raw, &n.ary)
 
 	if err != nil {
 		return nil, err
 	}
 
 	n.which = eAry
-	return &n.ary, nil
+	return n.ary, nil
 }
 
 func (n *lazyNode) compact() []byte {
@@ -302,12 +283,16 @@ func (n *lazyNode) tryDoc() bool {
 		return false
 	}
 
-	err := json.Unmarshal(*n.raw, &n.doc)
+	err := unmarshal(*n.raw, &n.doc)
 
 	if err != nil {
 		return false
 	}
 
+	if n.doc == nil {
+		return false
+	}
+
 	n.which = eDoc
 	return true
 }
@@ -317,7 +302,7 @@ func (n *lazyNode) tryAry() bool {
 		return false
 	}
 
-	err := json.Unmarshal(*n.raw, &n.ary)
+	err := unmarshal(*n.raw, &n.ary)
 
 	if err != nil {
 		return false
@@ -327,6 +312,18 @@ func (n *lazyNode) tryAry() bool {
 	return true
 }
 
+func (n *lazyNode) isNull() bool {
+	if n == nil {
+		return true
+	}
+
+	if n.raw == nil {
+		return true
+	}
+
+	return bytes.Equal(n.compact(), rawJSONNull)
+}
+
 func (n *lazyNode) equal(o *lazyNode) bool {
 	if n.which == eRaw {
 		if !n.tryDoc() && !n.tryAry() {
@@ -334,7 +331,27 @@ func (n *lazyNode) equal(o *lazyNode) bool {
 				return false
 			}
 
-			return bytes.Equal(n.compact(), o.compact())
+			nc := n.compact()
+			oc := o.compact()
+
+			if nc[0] == '"' && oc[0] == '"' {
+				// ok, 2 strings
+
+				var ns, os string
+
+				err := json.UnmarshalValid(nc, &ns)
+				if err != nil {
+					return false
+				}
+				err = json.UnmarshalValid(oc, &os)
+				if err != nil {
+					return false
+				}
+
+				return ns == os
+			}
+
+			return bytes.Equal(nc, oc)
 		}
 	}
 
@@ -380,12 +397,12 @@ func (n *lazyNode) equal(o *lazyNode) bool {
 		return false
 	}
 
-	if len(n.ary) != len(o.ary) {
+	if len(n.ary.nodes) != len(o.ary.nodes) {
 		return false
 	}
 
-	for idx, val := range n.ary {
-		if !val.equal(o.ary[idx]) {
+	for idx, val := range n.ary.nodes {
+		if !val.equal(o.ary.nodes[idx]) {
 			return false
 		}
 	}
@@ -398,7 +415,7 @@ func (o Operation) Kind() string {
 	if obj, ok := o["op"]; ok && obj != nil {
 		var op string
 
-		err := json.Unmarshal(*obj, &op)
+		err := unmarshal(*obj, &op)
 
 		if err != nil {
 			return "unknown"
@@ -415,7 +432,7 @@ func (o Operation) Path() (string, error) {
 	if obj, ok := o["path"]; ok && obj != nil {
 		var op string
 
-		err := json.Unmarshal(*obj, &op)
+		err := unmarshal(*obj, &op)
 
 		if err != nil {
 			return "unknown", err
@@ -432,7 +449,7 @@ func (o Operation) From() (string, error) {
 	if obj, ok := o["from"]; ok && obj != nil {
 		var op string
 
-		err := json.Unmarshal(*obj, &op)
+		err := unmarshal(*obj, &op)
 
 		if err != nil {
 			return "unknown", err
@@ -446,6 +463,10 @@ func (o Operation) From() (string, error) {
 
 func (o Operation) value() *lazyNode {
 	if obj, ok := o["value"]; ok {
+		// A `null` gets decoded as a nil RawMessage, so let's fix it up here.
+		if obj == nil {
+			return newLazyNode(newRawMessage(rawJSONNull))
+		}
 		return newLazyNode(obj)
 	}
 
@@ -461,7 +482,7 @@ func (o Operation) ValueInterface() (interface{}, error) {
 
 		var v interface{}
 
-		err := json.Unmarshal(*obj, &v)
+		err := unmarshal(*obj, &v)
 
 		if err != nil {
 			return nil, err
@@ -497,6 +518,9 @@ func findObject(pd *container, path string, options *ApplyOptions) (container, s
 	split := strings.Split(path, "/")
 
 	if len(split) < 2 {
+		if path == "" {
+			return doc, ""
+		}
 		return nil, ""
 	}
 
@@ -552,6 +576,9 @@ func (d *partialDoc) add(key string, val *lazyNode, options *ApplyOptions) error
 }
 
 func (d *partialDoc) get(key string, options *ApplyOptions) (*lazyNode, error) {
+	if key == "" {
+		return d.self, nil
+	}
 	v, ok := d.obj[key]
 	if !ok {
 		return v, errors.Wrapf(ErrMissing, "unable to get nonexistent key: %s", key)
@@ -591,19 +618,19 @@ func (d *partialArray) set(key string, val *lazyNode, options *ApplyOptions) err
 		if !options.SupportNegativeIndices {
 			return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
 		}
-		if idx < -len(*d) {
+		if idx < -len(d.nodes) {
 			return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
 		}
-		idx += len(*d)
+		idx += len(d.nodes)
 	}
 
-	(*d)[idx] = val
+	d.nodes[idx] = val
 	return nil
 }
 
 func (d *partialArray) add(key string, val *lazyNode, options *ApplyOptions) error {
 	if key == "-" {
-		*d = append(*d, val)
+		d.nodes = append(d.nodes, val)
 		return nil
 	}
 
@@ -612,11 +639,11 @@ func (d *partialArray) add(key string, val *lazyNode, options *ApplyOptions) err
 		return errors.Wrapf(err, "value was not a proper array index: '%s'", key)
 	}
 
-	sz := len(*d) + 1
+	sz := len(d.nodes) + 1
 
 	ary := make([]*lazyNode, sz)
 
-	cur := *d
+	cur := d
 
 	if idx >= len(ary) {
 		return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
@@ -632,15 +659,19 @@ func (d *partialArray) add(key string, val *lazyNode, options *ApplyOptions) err
 		idx += len(ary)
 	}
 
-	copy(ary[0:idx], cur[0:idx])
+	copy(ary[0:idx], cur.nodes[0:idx])
 	ary[idx] = val
-	copy(ary[idx+1:], cur[idx:])
+	copy(ary[idx+1:], cur.nodes[idx:])
 
-	*d = ary
+	d.nodes = ary
 	return nil
 }
 
 func (d *partialArray) get(key string, options *ApplyOptions) (*lazyNode, error) {
+	if key == "" {
+		return d.self, nil
+	}
+
 	idx, err := strconv.Atoi(key)
 
 	if err != nil {
@@ -651,17 +682,17 @@ func (d *partialArray) get(key string, options *ApplyOptions) (*lazyNode, error)
 		if !options.SupportNegativeIndices {
 			return nil, errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
 		}
-		if idx < -len(*d) {
+		if idx < -len(d.nodes) {
 			return nil, errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
 		}
-		idx += len(*d)
+		idx += len(d.nodes)
 	}
 
-	if idx >= len(*d) {
+	if idx >= len(d.nodes) {
 		return nil, errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
 	}
 
-	return (*d)[idx], nil
+	return d.nodes[idx], nil
 }
 
 func (d *partialArray) remove(key string, options *ApplyOptions) error {
@@ -670,9 +701,9 @@ func (d *partialArray) remove(key string, options *ApplyOptions) error {
 		return err
 	}
 
-	cur := *d
+	cur := d
 
-	if idx >= len(cur) {
+	if idx >= len(cur.nodes) {
 		if options.AllowMissingPathOnRemove {
 			return nil
 		}
@@ -683,21 +714,21 @@ func (d *partialArray) remove(key string, options *ApplyOptions) error {
 		if !options.SupportNegativeIndices {
 			return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
 		}
-		if idx < -len(cur) {
+		if idx < -len(cur.nodes) {
 			if options.AllowMissingPathOnRemove {
 				return nil
 			}
 			return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
 		}
-		idx += len(cur)
+		idx += len(cur.nodes)
 	}
 
-	ary := make([]*lazyNode, len(cur)-1)
+	ary := make([]*lazyNode, len(cur.nodes)-1)
 
-	copy(ary[0:idx], cur[0:idx])
-	copy(ary[idx:], cur[idx+1:])
+	copy(ary[0:idx], cur.nodes[0:idx])
+	copy(ary[idx:], cur.nodes[idx+1:])
 
-	*d = ary
+	d.nodes = ary
 	return nil
 }
 
@@ -707,6 +738,32 @@ func (p Patch) add(doc *container, op Operation, options *ApplyOptions) error {
 		return errors.Wrapf(ErrMissing, "add operation failed to decode path")
 	}
 
+	// special case, adding to empty means replacing the container with the value given
+	if path == "" {
+		val := op.value()
+
+		var pd container
+		if (*val.raw)[0] == '[' {
+			pd = &partialArray{
+				self: val,
+			}
+		} else {
+			pd = &partialDoc{
+				self: val,
+			}
+		}
+
+		err := json.UnmarshalValid(*val.raw, pd)
+
+		if err != nil {
+			return err
+		}
+
+		*doc = pd
+
+		return nil
+	}
+
 	if options.EnsurePathExistsOnAdd {
 		err = ensurePathExists(doc, path, options)
 
@@ -762,9 +819,9 @@ func ensurePathExists(pd *container, path string, options *ApplyOptions) error {
 			if arrIndex, err = strconv.Atoi(part); err == nil {
 				pa, ok := doc.(*partialArray)
 
-				if ok && arrIndex >= len(*pa)+1 {
+				if ok && arrIndex >= len(pa.nodes)+1 {
 					// Pad the array with null values up to the required index.
-					for i := len(*pa); i <= arrIndex-1; i++ {
+					for i := len(pa.nodes); i <= arrIndex-1; i++ {
 						doc.add(strconv.Itoa(i), newLazyNode(newRawMessage(rawJSONNull)), options)
 					}
 				}
@@ -798,7 +855,10 @@ func ensurePathExists(pd *container, path string, options *ApplyOptions) error {
 				newNode := newLazyNode(newRawMessage(rawJSONObject))
 
 				doc.add(part, newNode, options)
-				doc, _ = newNode.intoDoc()
+				doc, err = newNode.intoDoc()
+				if err != nil {
+					return err
+				}
 			}
 		} else {
 			if isArray(*target.raw) {
@@ -899,7 +959,7 @@ func (p Patch) replace(doc *container, op Operation, options *ApplyOptions) erro
 
 		switch val.which {
 		case eAry:
-			*doc = &val.ary
+			*doc = val.ary
 		case eDoc:
 			*doc = val.doc
 		case eRaw:
@@ -934,6 +994,10 @@ func (p Patch) move(doc *container, op Operation, options *ApplyOptions) error {
 		return errors.Wrapf(err, "move operation failed to decode from")
 	}
 
+	if from == "" {
+		return errors.Wrapf(ErrInvalid, "unable to move entire document to another path")
+	}
+
 	con, key := findObject(doc, from, options)
 
 	if con == nil {
@@ -983,7 +1047,7 @@ func (p Patch) test(doc *container, op Operation, options *ApplyOptions) error {
 			self.doc = sv
 			self.which = eDoc
 		case *partialArray:
-			self.ary = *sv
+			self.ary = sv
 			self.which = eAry
 		}
 
@@ -1005,12 +1069,14 @@ func (p Patch) test(doc *container, op Operation, options *ApplyOptions) error {
 		return errors.Wrapf(err, "error in test for path: '%s'", path)
 	}
 
+	ov := op.value()
+
 	if val == nil {
-		if op.value() == nil || op.value().raw == nil {
+		if ov.isNull() {
 			return nil
 		}
 		return errors.Wrapf(ErrTestFailed, "testing value %s failed", path)
-	} else if op.value() == nil {
+	} else if ov.isNull() {
 		return errors.Wrapf(ErrTestFailed, "testing value %s failed", path)
 	}
 
@@ -1030,7 +1096,7 @@ func (p Patch) copy(doc *container, op Operation, accumulatedCopySize *int64, op
 	con, key := findObject(doc, from, options)
 
 	if con == nil {
-		return errors.Wrapf(ErrMissing, "copy operation does not apply: doc is missing from path: %s", from)
+		return errors.Wrapf(ErrMissing, "copy operation does not apply: doc is missing from path: \"%s\"", from)
 	}
 
 	val, err := con.get(key, options)
@@ -1077,9 +1143,13 @@ func Equal(a, b []byte) bool {
 
 // DecodePatch decodes the passed JSON document as an RFC 6902 patch.
 func DecodePatch(buf []byte) (Patch, error) {
+	if !json.Valid(buf) {
+		return nil, ErrInvalid
+	}
+
 	var p Patch
 
-	err := json.Unmarshal(buf, &p)
+	err := unmarshal(buf, &p)
 
 	if err != nil {
 		return nil, err
@@ -1117,14 +1187,25 @@ func (p Patch) ApplyIndentWithOptions(doc []byte, indent string, options *ApplyO
 		return doc, nil
 	}
 
+	if !json.Valid(doc) {
+		return nil, ErrInvalid
+	}
+
+	raw := json.RawMessage(doc)
+	self := newLazyNode(&raw)
+
 	var pd container
 	if doc[0] == '[' {
-		pd = &partialArray{}
+		pd = &partialArray{
+			self: self,
+		}
 	} else {
-		pd = &partialDoc{}
+		pd = &partialDoc{
+			self: self,
+		}
 	}
 
-	err := json.Unmarshal(doc, pd)
+	err := unmarshal(doc, pd)
 
 	if err != nil {
 		return nil, err
diff --git a/vendor/github.com/golang/protobuf/jsonpb/decode.go b/vendor/github.com/golang/protobuf/jsonpb/decode.go
deleted file mode 100644
index 6c16c255..00000000
--- a/vendor/github.com/golang/protobuf/jsonpb/decode.go
+++ /dev/null
@@ -1,530 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package jsonpb
-
-import (
-	"encoding/json"
-	"errors"
-	"fmt"
-	"io"
-	"math"
-	"reflect"
-	"strconv"
-	"strings"
-	"time"
-
-	"github.com/golang/protobuf/proto"
-	"google.golang.org/protobuf/encoding/protojson"
-	protoV2 "google.golang.org/protobuf/proto"
-	"google.golang.org/protobuf/reflect/protoreflect"
-	"google.golang.org/protobuf/reflect/protoregistry"
-)
-
-const wrapJSONUnmarshalV2 = false
-
-// UnmarshalNext unmarshals the next JSON object from d into m.
-func UnmarshalNext(d *json.Decoder, m proto.Message) error {
-	return new(Unmarshaler).UnmarshalNext(d, m)
-}
-
-// Unmarshal unmarshals a JSON object from r into m.
-func Unmarshal(r io.Reader, m proto.Message) error {
-	return new(Unmarshaler).Unmarshal(r, m)
-}
-
-// UnmarshalString unmarshals a JSON object from s into m.
-func UnmarshalString(s string, m proto.Message) error {
-	return new(Unmarshaler).Unmarshal(strings.NewReader(s), m)
-}
-
-// Unmarshaler is a configurable object for converting from a JSON
-// representation to a protocol buffer object.
-type Unmarshaler struct {
-	// AllowUnknownFields specifies whether to allow messages to contain
-	// unknown JSON fields, as opposed to failing to unmarshal.
-	AllowUnknownFields bool
-
-	// AnyResolver is used to resolve the google.protobuf.Any well-known type.
-	// If unset, the global registry is used by default.
-	AnyResolver AnyResolver
-}
-
-// JSONPBUnmarshaler is implemented by protobuf messages that customize the way
-// they are unmarshaled from JSON. Messages that implement this should also
-// implement JSONPBMarshaler so that the custom format can be produced.
-//
-// The JSON unmarshaling must follow the JSON to proto specification:
-//	https://developers.google.com/protocol-buffers/docs/proto3#json
-//
-// Deprecated: Custom types should implement protobuf reflection instead.
-type JSONPBUnmarshaler interface {
-	UnmarshalJSONPB(*Unmarshaler, []byte) error
-}
-
-// Unmarshal unmarshals a JSON object from r into m.
-func (u *Unmarshaler) Unmarshal(r io.Reader, m proto.Message) error {
-	return u.UnmarshalNext(json.NewDecoder(r), m)
-}
-
-// UnmarshalNext unmarshals the next JSON object from d into m.
-func (u *Unmarshaler) UnmarshalNext(d *json.Decoder, m proto.Message) error {
-	if m == nil {
-		return errors.New("invalid nil message")
-	}
-
-	// Parse the next JSON object from the stream.
-	raw := json.RawMessage{}
-	if err := d.Decode(&raw); err != nil {
-		return err
-	}
-
-	// Check for custom unmarshalers first since they may not properly
-	// implement protobuf reflection that the logic below relies on.
-	if jsu, ok := m.(JSONPBUnmarshaler); ok {
-		return jsu.UnmarshalJSONPB(u, raw)
-	}
-
-	mr := proto.MessageReflect(m)
-
-	// NOTE: For historical reasons, a top-level null is treated as a noop.
-	// This is incorrect, but kept for compatibility.
-	if string(raw) == "null" && mr.Descriptor().FullName() != "google.protobuf.Value" {
-		return nil
-	}
-
-	if wrapJSONUnmarshalV2 {
-		// NOTE: If input message is non-empty, we need to preserve merge semantics
-		// of the old jsonpb implementation. These semantics are not supported by
-		// the protobuf JSON specification.
-		isEmpty := true
-		mr.Range(func(protoreflect.FieldDescriptor, protoreflect.Value) bool {
-			isEmpty = false // at least one iteration implies non-empty
-			return false
-		})
-		if !isEmpty {
-			// Perform unmarshaling into a newly allocated, empty message.
-			mr = mr.New()
-
-			// Use a defer to copy all unmarshaled fields into the original message.
-			dst := proto.MessageReflect(m)
-			defer mr.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
-				dst.Set(fd, v)
-				return true
-			})
-		}
-
-		// Unmarshal using the v2 JSON unmarshaler.
-		opts := protojson.UnmarshalOptions{
-			DiscardUnknown: u.AllowUnknownFields,
-		}
-		if u.AnyResolver != nil {
-			opts.Resolver = anyResolver{u.AnyResolver}
-		}
-		return opts.Unmarshal(raw, mr.Interface())
-	} else {
-		if err := u.unmarshalMessage(mr, raw); err != nil {
-			return err
-		}
-		return protoV2.CheckInitialized(mr.Interface())
-	}
-}
-
-func (u *Unmarshaler) unmarshalMessage(m protoreflect.Message, in []byte) error {
-	md := m.Descriptor()
-	fds := md.Fields()
-
-	if jsu, ok := proto.MessageV1(m.Interface()).(JSONPBUnmarshaler); ok {
-		return jsu.UnmarshalJSONPB(u, in)
-	}
-
-	if string(in) == "null" && md.FullName() != "google.protobuf.Value" {
-		return nil
-	}
-
-	switch wellKnownType(md.FullName()) {
-	case "Any":
-		var jsonObject map[string]json.RawMessage
-		if err := json.Unmarshal(in, &jsonObject); err != nil {
-			return err
-		}
-
-		rawTypeURL, ok := jsonObject["@type"]
-		if !ok {
-			return errors.New("Any JSON doesn't have '@type'")
-		}
-		typeURL, err := unquoteString(string(rawTypeURL))
-		if err != nil {
-			return fmt.Errorf("can't unmarshal Any's '@type': %q", rawTypeURL)
-		}
-		m.Set(fds.ByNumber(1), protoreflect.ValueOfString(typeURL))
-
-		var m2 protoreflect.Message
-		if u.AnyResolver != nil {
-			mi, err := u.AnyResolver.Resolve(typeURL)
-			if err != nil {
-				return err
-			}
-			m2 = proto.MessageReflect(mi)
-		} else {
-			mt, err := protoregistry.GlobalTypes.FindMessageByURL(typeURL)
-			if err != nil {
-				if err == protoregistry.NotFound {
-					return fmt.Errorf("could not resolve Any message type: %v", typeURL)
-				}
-				return err
-			}
-			m2 = mt.New()
-		}
-
-		if wellKnownType(m2.Descriptor().FullName()) != "" {
-			rawValue, ok := jsonObject["value"]
-			if !ok {
-				return errors.New("Any JSON doesn't have 'value'")
-			}
-			if err := u.unmarshalMessage(m2, rawValue); err != nil {
-				return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err)
-			}
-		} else {
-			delete(jsonObject, "@type")
-			rawJSON, err := json.Marshal(jsonObject)
-			if err != nil {
-				return fmt.Errorf("can't generate JSON for Any's nested proto to be unmarshaled: %v", err)
-			}
-			if err = u.unmarshalMessage(m2, rawJSON); err != nil {
-				return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err)
-			}
-		}
-
-		rawWire, err := protoV2.Marshal(m2.Interface())
-		if err != nil {
-			return fmt.Errorf("can't marshal proto %v into Any.Value: %v", typeURL, err)
-		}
-		m.Set(fds.ByNumber(2), protoreflect.ValueOfBytes(rawWire))
-		return nil
-	case "BoolValue", "BytesValue", "StringValue",
-		"Int32Value", "UInt32Value", "FloatValue",
-		"Int64Value", "UInt64Value", "DoubleValue":
-		fd := fds.ByNumber(1)
-		v, err := u.unmarshalValue(m.NewField(fd), in, fd)
-		if err != nil {
-			return err
-		}
-		m.Set(fd, v)
-		return nil
-	case "Duration":
-		v, err := unquoteString(string(in))
-		if err != nil {
-			return err
-		}
-		d, err := time.ParseDuration(v)
-		if err != nil {
-			return fmt.Errorf("bad Duration: %v", err)
-		}
-
-		sec := d.Nanoseconds() / 1e9
-		nsec := d.Nanoseconds() % 1e9
-		m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec)))
-		m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec)))
-		return nil
-	case "Timestamp":
-		v, err := unquoteString(string(in))
-		if err != nil {
-			return err
-		}
-		t, err := time.Parse(time.RFC3339Nano, v)
-		if err != nil {
-			return fmt.Errorf("bad Timestamp: %v", err)
-		}
-
-		sec := t.Unix()
-		nsec := t.Nanosecond()
-		m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec)))
-		m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec)))
-		return nil
-	case "Value":
-		switch {
-		case string(in) == "null":
-			m.Set(fds.ByNumber(1), protoreflect.ValueOfEnum(0))
-		case string(in) == "true":
-			m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(true))
-		case string(in) == "false":
-			m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(false))
-		case hasPrefixAndSuffix('"', in, '"'):
-			s, err := unquoteString(string(in))
-			if err != nil {
-				return fmt.Errorf("unrecognized type for Value %q", in)
-			}
-			m.Set(fds.ByNumber(3), protoreflect.ValueOfString(s))
-		case hasPrefixAndSuffix('[', in, ']'):
-			v := m.Mutable(fds.ByNumber(6))
-			return u.unmarshalMessage(v.Message(), in)
-		case hasPrefixAndSuffix('{', in, '}'):
-			v := m.Mutable(fds.ByNumber(5))
-			return u.unmarshalMessage(v.Message(), in)
-		default:
-			f, err := strconv.ParseFloat(string(in), 0)
-			if err != nil {
-				return fmt.Errorf("unrecognized type for Value %q", in)
-			}
-			m.Set(fds.ByNumber(2), protoreflect.ValueOfFloat64(f))
-		}
-		return nil
-	case "ListValue":
-		var jsonArray []json.RawMessage
-		if err := json.Unmarshal(in, &jsonArray); err != nil {
-			return fmt.Errorf("bad ListValue: %v", err)
-		}
-
-		lv := m.Mutable(fds.ByNumber(1)).List()
-		for _, raw := range jsonArray {
-			ve := lv.NewElement()
-			if err := u.unmarshalMessage(ve.Message(), raw); err != nil {
-				return err
-			}
-			lv.Append(ve)
-		}
-		return nil
-	case "Struct":
-		var jsonObject map[string]json.RawMessage
-		if err := json.Unmarshal(in, &jsonObject); err != nil {
-			return fmt.Errorf("bad StructValue: %v", err)
-		}
-
-		mv := m.Mutable(fds.ByNumber(1)).Map()
-		for key, raw := range jsonObject {
-			kv := protoreflect.ValueOf(key).MapKey()
-			vv := mv.NewValue()
-			if err := u.unmarshalMessage(vv.Message(), raw); err != nil {
-				return fmt.Errorf("bad value in StructValue for key %q: %v", key, err)
-			}
-			mv.Set(kv, vv)
-		}
-		return nil
-	}
-
-	var jsonObject map[string]json.RawMessage
-	if err := json.Unmarshal(in, &jsonObject); err != nil {
-		return err
-	}
-
-	// Handle known fields.
-	for i := 0; i < fds.Len(); i++ {
-		fd := fds.Get(i)
-		if fd.IsWeak() && fd.Message().IsPlaceholder() {
-			continue //  weak reference is not linked in
-		}
-
-		// Search for any raw JSON value associated with this field.
-		var raw json.RawMessage
-		name := string(fd.Name())
-		if fd.Kind() == protoreflect.GroupKind {
-			name = string(fd.Message().Name())
-		}
-		if v, ok := jsonObject[name]; ok {
-			delete(jsonObject, name)
-			raw = v
-		}
-		name = string(fd.JSONName())
-		if v, ok := jsonObject[name]; ok {
-			delete(jsonObject, name)
-			raw = v
-		}
-
-		field := m.NewField(fd)
-		// Unmarshal the field value.
-		if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) {
-			continue
-		}
-		v, err := u.unmarshalValue(field, raw, fd)
-		if err != nil {
-			return err
-		}
-		m.Set(fd, v)
-	}
-
-	// Handle extension fields.
-	for name, raw := range jsonObject {
-		if !strings.HasPrefix(name, "[") || !strings.HasSuffix(name, "]") {
-			continue
-		}
-
-		// Resolve the extension field by name.
-		xname := protoreflect.FullName(name[len("[") : len(name)-len("]")])
-		xt, _ := protoregistry.GlobalTypes.FindExtensionByName(xname)
-		if xt == nil && isMessageSet(md) {
-			xt, _ = protoregistry.GlobalTypes.FindExtensionByName(xname.Append("message_set_extension"))
-		}
-		if xt == nil {
-			continue
-		}
-		delete(jsonObject, name)
-		fd := xt.TypeDescriptor()
-		if fd.ContainingMessage().FullName() != m.Descriptor().FullName() {
-			return fmt.Errorf("extension field %q does not extend message %q", xname, m.Descriptor().FullName())
-		}
-
-		field := m.NewField(fd)
-		// Unmarshal the field value.
-		if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) {
-			continue
-		}
-		v, err := u.unmarshalValue(field, raw, fd)
-		if err != nil {
-			return err
-		}
-		m.Set(fd, v)
-	}
-
-	if !u.AllowUnknownFields && len(jsonObject) > 0 {
-		for name := range jsonObject {
-			return fmt.Errorf("unknown field %q in %v", name, md.FullName())
-		}
-	}
-	return nil
-}
-
-func isSingularWellKnownValue(fd protoreflect.FieldDescriptor) bool {
-	if fd.Cardinality() == protoreflect.Repeated {
-		return false
-	}
-	if md := fd.Message(); md != nil {
-		return md.FullName() == "google.protobuf.Value"
-	}
-	if ed := fd.Enum(); ed != nil {
-		return ed.FullName() == "google.protobuf.NullValue"
-	}
-	return false
-}
-
-func isSingularJSONPBUnmarshaler(v protoreflect.Value, fd protoreflect.FieldDescriptor) bool {
-	if fd.Message() != nil && fd.Cardinality() != protoreflect.Repeated {
-		_, ok := proto.MessageV1(v.Interface()).(JSONPBUnmarshaler)
-		return ok
-	}
-	return false
-}
-
-func (u *Unmarshaler) unmarshalValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {
-	switch {
-	case fd.IsList():
-		var jsonArray []json.RawMessage
-		if err := json.Unmarshal(in, &jsonArray); err != nil {
-			return v, err
-		}
-		lv := v.List()
-		for _, raw := range jsonArray {
-			ve, err := u.unmarshalSingularValue(lv.NewElement(), raw, fd)
-			if err != nil {
-				return v, err
-			}
-			lv.Append(ve)
-		}
-		return v, nil
-	case fd.IsMap():
-		var jsonObject map[string]json.RawMessage
-		if err := json.Unmarshal(in, &jsonObject); err != nil {
-			return v, err
-		}
-		kfd := fd.MapKey()
-		vfd := fd.MapValue()
-		mv := v.Map()
-		for key, raw := range jsonObject {
-			var kv protoreflect.MapKey
-			if kfd.Kind() == protoreflect.StringKind {
-				kv = protoreflect.ValueOf(key).MapKey()
-			} else {
-				v, err := u.unmarshalSingularValue(kfd.Default(), []byte(key), kfd)
-				if err != nil {
-					return v, err
-				}
-				kv = v.MapKey()
-			}
-
-			vv, err := u.unmarshalSingularValue(mv.NewValue(), raw, vfd)
-			if err != nil {
-				return v, err
-			}
-			mv.Set(kv, vv)
-		}
-		return v, nil
-	default:
-		return u.unmarshalSingularValue(v, in, fd)
-	}
-}
-
-var nonFinite = map[string]float64{
-	`"NaN"`:       math.NaN(),
-	`"Infinity"`:  math.Inf(+1),
-	`"-Infinity"`: math.Inf(-1),
-}
-
-func (u *Unmarshaler) unmarshalSingularValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {
-	switch fd.Kind() {
-	case protoreflect.BoolKind:
-		return unmarshalValue(in, new(bool))
-	case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
-		return unmarshalValue(trimQuote(in), new(int32))
-	case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
-		return unmarshalValue(trimQuote(in), new(int64))
-	case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
-		return unmarshalValue(trimQuote(in), new(uint32))
-	case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
-		return unmarshalValue(trimQuote(in), new(uint64))
-	case protoreflect.FloatKind:
-		if f, ok := nonFinite[string(in)]; ok {
-			return protoreflect.ValueOfFloat32(float32(f)), nil
-		}
-		return unmarshalValue(trimQuote(in), new(float32))
-	case protoreflect.DoubleKind:
-		if f, ok := nonFinite[string(in)]; ok {
-			return protoreflect.ValueOfFloat64(float64(f)), nil
-		}
-		return unmarshalValue(trimQuote(in), new(float64))
-	case protoreflect.StringKind:
-		return unmarshalValue(in, new(string))
-	case protoreflect.BytesKind:
-		return unmarshalValue(in, new([]byte))
-	case protoreflect.EnumKind:
-		if hasPrefixAndSuffix('"', in, '"') {
-			vd := fd.Enum().Values().ByName(protoreflect.Name(trimQuote(in)))
-			if vd == nil {
-				return v, fmt.Errorf("unknown value %q for enum %s", in, fd.Enum().FullName())
-			}
-			return protoreflect.ValueOfEnum(vd.Number()), nil
-		}
-		return unmarshalValue(in, new(protoreflect.EnumNumber))
-	case protoreflect.MessageKind, protoreflect.GroupKind:
-		err := u.unmarshalMessage(v.Message(), in)
-		return v, err
-	default:
-		panic(fmt.Sprintf("invalid kind %v", fd.Kind()))
-	}
-}
-
-func unmarshalValue(in []byte, v interface{}) (protoreflect.Value, error) {
-	err := json.Unmarshal(in, v)
-	return protoreflect.ValueOf(reflect.ValueOf(v).Elem().Interface()), err
-}
-
-func unquoteString(in string) (out string, err error) {
-	err = json.Unmarshal([]byte(in), &out)
-	return out, err
-}
-
-func hasPrefixAndSuffix(prefix byte, in []byte, suffix byte) bool {
-	if len(in) >= 2 && in[0] == prefix && in[len(in)-1] == suffix {
-		return true
-	}
-	return false
-}
-
-// trimQuote is like unquoteString but simply strips surrounding quotes.
-// This is incorrect, but is behavior done by the legacy implementation.
-func trimQuote(in []byte) []byte {
-	if len(in) >= 2 && in[0] == '"' && in[len(in)-1] == '"' {
-		in = in[1 : len(in)-1]
-	}
-	return in
-}
diff --git a/vendor/github.com/golang/protobuf/jsonpb/encode.go b/vendor/github.com/golang/protobuf/jsonpb/encode.go
deleted file mode 100644
index 685c80a6..00000000
--- a/vendor/github.com/golang/protobuf/jsonpb/encode.go
+++ /dev/null
@@ -1,559 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package jsonpb
-
-import (
-	"encoding/json"
-	"errors"
-	"fmt"
-	"io"
-	"math"
-	"reflect"
-	"sort"
-	"strconv"
-	"strings"
-	"time"
-
-	"github.com/golang/protobuf/proto"
-	"google.golang.org/protobuf/encoding/protojson"
-	protoV2 "google.golang.org/protobuf/proto"
-	"google.golang.org/protobuf/reflect/protoreflect"
-	"google.golang.org/protobuf/reflect/protoregistry"
-)
-
-const wrapJSONMarshalV2 = false
-
-// Marshaler is a configurable object for marshaling protocol buffer messages
-// to the specified JSON representation.
-type Marshaler struct {
-	// OrigName specifies whether to use the original protobuf name for fields.
-	OrigName bool
-
-	// EnumsAsInts specifies whether to render enum values as integers,
-	// as opposed to string values.
-	EnumsAsInts bool
-
-	// EmitDefaults specifies whether to render fields with zero values.
-	EmitDefaults bool
-
-	// Indent controls whether the output is compact or not.
-	// If empty, the output is compact JSON. Otherwise, every JSON object
-	// entry and JSON array value will be on its own line.
-	// Each line will be preceded by repeated copies of Indent, where the
-	// number of copies is the current indentation depth.
-	Indent string
-
-	// AnyResolver is used to resolve the google.protobuf.Any well-known type.
-	// If unset, the global registry is used by default.
-	AnyResolver AnyResolver
-}
-
-// JSONPBMarshaler is implemented by protobuf messages that customize the
-// way they are marshaled to JSON. Messages that implement this should also
-// implement JSONPBUnmarshaler so that the custom format can be parsed.
-//
-// The JSON marshaling must follow the proto to JSON specification:
-//	https://developers.google.com/protocol-buffers/docs/proto3#json
-//
-// Deprecated: Custom types should implement protobuf reflection instead.
-type JSONPBMarshaler interface {
-	MarshalJSONPB(*Marshaler) ([]byte, error)
-}
-
-// Marshal serializes a protobuf message as JSON into w.
-func (jm *Marshaler) Marshal(w io.Writer, m proto.Message) error {
-	b, err := jm.marshal(m)
-	if len(b) > 0 {
-		if _, err := w.Write(b); err != nil {
-			return err
-		}
-	}
-	return err
-}
-
-// MarshalToString serializes a protobuf message as JSON in string form.
-func (jm *Marshaler) MarshalToString(m proto.Message) (string, error) {
-	b, err := jm.marshal(m)
-	if err != nil {
-		return "", err
-	}
-	return string(b), nil
-}
-
-func (jm *Marshaler) marshal(m proto.Message) ([]byte, error) {
-	v := reflect.ValueOf(m)
-	if m == nil || (v.Kind() == reflect.Ptr && v.IsNil()) {
-		return nil, errors.New("Marshal called with nil")
-	}
-
-	// Check for custom marshalers first since they may not properly
-	// implement protobuf reflection that the logic below relies on.
-	if jsm, ok := m.(JSONPBMarshaler); ok {
-		return jsm.MarshalJSONPB(jm)
-	}
-
-	if wrapJSONMarshalV2 {
-		opts := protojson.MarshalOptions{
-			UseProtoNames:   jm.OrigName,
-			UseEnumNumbers:  jm.EnumsAsInts,
-			EmitUnpopulated: jm.EmitDefaults,
-			Indent:          jm.Indent,
-		}
-		if jm.AnyResolver != nil {
-			opts.Resolver = anyResolver{jm.AnyResolver}
-		}
-		return opts.Marshal(proto.MessageReflect(m).Interface())
-	} else {
-		// Check for unpopulated required fields first.
-		m2 := proto.MessageReflect(m)
-		if err := protoV2.CheckInitialized(m2.Interface()); err != nil {
-			return nil, err
-		}
-
-		w := jsonWriter{Marshaler: jm}
-		err := w.marshalMessage(m2, "", "")
-		return w.buf, err
-	}
-}
-
-type jsonWriter struct {
-	*Marshaler
-	buf []byte
-}
-
-func (w *jsonWriter) write(s string) {
-	w.buf = append(w.buf, s...)
-}
-
-func (w *jsonWriter) marshalMessage(m protoreflect.Message, indent, typeURL string) error {
-	if jsm, ok := proto.MessageV1(m.Interface()).(JSONPBMarshaler); ok {
-		b, err := jsm.MarshalJSONPB(w.Marshaler)
-		if err != nil {
-			return err
-		}
-		if typeURL != "" {
-			// we are marshaling this object to an Any type
-			var js map[string]*json.RawMessage
-			if err = json.Unmarshal(b, &js); err != nil {
-				return fmt.Errorf("type %T produced invalid JSON: %v", m.Interface(), err)
-			}
-			turl, err := json.Marshal(typeURL)
-			if err != nil {
-				return fmt.Errorf("failed to marshal type URL %q to JSON: %v", typeURL, err)
-			}
-			js["@type"] = (*json.RawMessage)(&turl)
-			if b, err = json.Marshal(js); err != nil {
-				return err
-			}
-		}
-		w.write(string(b))
-		return nil
-	}
-
-	md := m.Descriptor()
-	fds := md.Fields()
-
-	// Handle well-known types.
-	const secondInNanos = int64(time.Second / time.Nanosecond)
-	switch wellKnownType(md.FullName()) {
-	case "Any":
-		return w.marshalAny(m, indent)
-	case "BoolValue", "BytesValue", "StringValue",
-		"Int32Value", "UInt32Value", "FloatValue",
-		"Int64Value", "UInt64Value", "DoubleValue":
-		fd := fds.ByNumber(1)
-		return w.marshalValue(fd, m.Get(fd), indent)
-	case "Duration":
-		const maxSecondsInDuration = 315576000000
-		// "Generated output always contains 0, 3, 6, or 9 fractional digits,
-		//  depending on required precision."
-		s := m.Get(fds.ByNumber(1)).Int()
-		ns := m.Get(fds.ByNumber(2)).Int()
-		if s < -maxSecondsInDuration || s > maxSecondsInDuration {
-			return fmt.Errorf("seconds out of range %v", s)
-		}
-		if ns <= -secondInNanos || ns >= secondInNanos {
-			return fmt.Errorf("ns out of range (%v, %v)", -secondInNanos, secondInNanos)
-		}
-		if (s > 0 && ns < 0) || (s < 0 && ns > 0) {
-			return errors.New("signs of seconds and nanos do not match")
-		}
-		var sign string
-		if s < 0 || ns < 0 {
-			sign, s, ns = "-", -1*s, -1*ns
-		}
-		x := fmt.Sprintf("%s%d.%09d", sign, s, ns)
-		x = strings.TrimSuffix(x, "000")
-		x = strings.TrimSuffix(x, "000")
-		x = strings.TrimSuffix(x, ".000")
-		w.write(fmt.Sprintf(`"%vs"`, x))
-		return nil
-	case "Timestamp":
-		// "RFC 3339, where generated output will always be Z-normalized
-		//  and uses 0, 3, 6 or 9 fractional digits."
-		s := m.Get(fds.ByNumber(1)).Int()
-		ns := m.Get(fds.ByNumber(2)).Int()
-		if ns < 0 || ns >= secondInNanos {
-			return fmt.Errorf("ns out of range [0, %v)", secondInNanos)
-		}
-		t := time.Unix(s, ns).UTC()
-		// time.RFC3339Nano isn't exactly right (we need to get 3/6/9 fractional digits).
-		x := t.Format("2006-01-02T15:04:05.000000000")
-		x = strings.TrimSuffix(x, "000")
-		x = strings.TrimSuffix(x, "000")
-		x = strings.TrimSuffix(x, ".000")
-		w.write(fmt.Sprintf(`"%vZ"`, x))
-		return nil
-	case "Value":
-		// JSON value; which is a null, number, string, bool, object, or array.
-		od := md.Oneofs().Get(0)
-		fd := m.WhichOneof(od)
-		if fd == nil {
-			return errors.New("nil Value")
-		}
-		return w.marshalValue(fd, m.Get(fd), indent)
-	case "Struct", "ListValue":
-		// JSON object or array.
-		fd := fds.ByNumber(1)
-		return w.marshalValue(fd, m.Get(fd), indent)
-	}
-
-	w.write("{")
-	if w.Indent != "" {
-		w.write("\n")
-	}
-
-	firstField := true
-	if typeURL != "" {
-		if err := w.marshalTypeURL(indent, typeURL); err != nil {
-			return err
-		}
-		firstField = false
-	}
-
-	for i := 0; i < fds.Len(); {
-		fd := fds.Get(i)
-		if od := fd.ContainingOneof(); od != nil {
-			fd = m.WhichOneof(od)
-			i += od.Fields().Len()
-			if fd == nil {
-				continue
-			}
-		} else {
-			i++
-		}
-
-		v := m.Get(fd)
-
-		if !m.Has(fd) {
-			if !w.EmitDefaults || fd.ContainingOneof() != nil {
-				continue
-			}
-			if fd.Cardinality() != protoreflect.Repeated && (fd.Message() != nil || fd.Syntax() == protoreflect.Proto2) {
-				v = protoreflect.Value{} // use "null" for singular messages or proto2 scalars
-			}
-		}
-
-		if !firstField {
-			w.writeComma()
-		}
-		if err := w.marshalField(fd, v, indent); err != nil {
-			return err
-		}
-		firstField = false
-	}
-
-	// Handle proto2 extensions.
-	if md.ExtensionRanges().Len() > 0 {
-		// Collect a sorted list of all extension descriptor and values.
-		type ext struct {
-			desc protoreflect.FieldDescriptor
-			val  protoreflect.Value
-		}
-		var exts []ext
-		m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
-			if fd.IsExtension() {
-				exts = append(exts, ext{fd, v})
-			}
-			return true
-		})
-		sort.Slice(exts, func(i, j int) bool {
-			return exts[i].desc.Number() < exts[j].desc.Number()
-		})
-
-		for _, ext := range exts {
-			if !firstField {
-				w.writeComma()
-			}
-			if err := w.marshalField(ext.desc, ext.val, indent); err != nil {
-				return err
-			}
-			firstField = false
-		}
-	}
-
-	if w.Indent != "" {
-		w.write("\n")
-		w.write(indent)
-	}
-	w.write("}")
-	return nil
-}
-
-func (w *jsonWriter) writeComma() {
-	if w.Indent != "" {
-		w.write(",\n")
-	} else {
-		w.write(",")
-	}
-}
-
-func (w *jsonWriter) marshalAny(m protoreflect.Message, indent string) error {
-	// "If the Any contains a value that has a special JSON mapping,
-	//  it will be converted as follows: {"@type": xxx, "value": yyy}.
-	//  Otherwise, the value will be converted into a JSON object,
-	//  and the "@type" field will be inserted to indicate the actual data type."
-	md := m.Descriptor()
-	typeURL := m.Get(md.Fields().ByNumber(1)).String()
-	rawVal := m.Get(md.Fields().ByNumber(2)).Bytes()
-
-	var m2 protoreflect.Message
-	if w.AnyResolver != nil {
-		mi, err := w.AnyResolver.Resolve(typeURL)
-		if err != nil {
-			return err
-		}
-		m2 = proto.MessageReflect(mi)
-	} else {
-		mt, err := protoregistry.GlobalTypes.FindMessageByURL(typeURL)
-		if err != nil {
-			return err
-		}
-		m2 = mt.New()
-	}
-
-	if err := protoV2.Unmarshal(rawVal, m2.Interface()); err != nil {
-		return err
-	}
-
-	if wellKnownType(m2.Descriptor().FullName()) == "" {
-		return w.marshalMessage(m2, indent, typeURL)
-	}
-
-	w.write("{")
-	if w.Indent != "" {
-		w.write("\n")
-	}
-	if err := w.marshalTypeURL(indent, typeURL); err != nil {
-		return err
-	}
-	w.writeComma()
-	if w.Indent != "" {
-		w.write(indent)
-		w.write(w.Indent)
-		w.write(`"value": `)
-	} else {
-		w.write(`"value":`)
-	}
-	if err := w.marshalMessage(m2, indent+w.Indent, ""); err != nil {
-		return err
-	}
-	if w.Indent != "" {
-		w.write("\n")
-		w.write(indent)
-	}
-	w.write("}")
-	return nil
-}
-
-func (w *jsonWriter) marshalTypeURL(indent, typeURL string) error {
-	if w.Indent != "" {
-		w.write(indent)
-		w.write(w.Indent)
-	}
-	w.write(`"@type":`)
-	if w.Indent != "" {
-		w.write(" ")
-	}
-	b, err := json.Marshal(typeURL)
-	if err != nil {
-		return err
-	}
-	w.write(string(b))
-	return nil
-}
-
-// marshalField writes field description and value to the Writer.
-func (w *jsonWriter) marshalField(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error {
-	if w.Indent != "" {
-		w.write(indent)
-		w.write(w.Indent)
-	}
-	w.write(`"`)
-	switch {
-	case fd.IsExtension():
-		// For message set, use the fname of the message as the extension name.
-		name := string(fd.FullName())
-		if isMessageSet(fd.ContainingMessage()) {
-			name = strings.TrimSuffix(name, ".message_set_extension")
-		}
-
-		w.write("[" + name + "]")
-	case w.OrigName:
-		name := string(fd.Name())
-		if fd.Kind() == protoreflect.GroupKind {
-			name = string(fd.Message().Name())
-		}
-		w.write(name)
-	default:
-		w.write(string(fd.JSONName()))
-	}
-	w.write(`":`)
-	if w.Indent != "" {
-		w.write(" ")
-	}
-	return w.marshalValue(fd, v, indent)
-}
-
-func (w *jsonWriter) marshalValue(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error {
-	switch {
-	case fd.IsList():
-		w.write("[")
-		comma := ""
-		lv := v.List()
-		for i := 0; i < lv.Len(); i++ {
-			w.write(comma)
-			if w.Indent != "" {
-				w.write("\n")
-				w.write(indent)
-				w.write(w.Indent)
-				w.write(w.Indent)
-			}
-			if err := w.marshalSingularValue(fd, lv.Get(i), indent+w.Indent); err != nil {
-				return err
-			}
-			comma = ","
-		}
-		if w.Indent != "" {
-			w.write("\n")
-			w.write(indent)
-			w.write(w.Indent)
-		}
-		w.write("]")
-		return nil
-	case fd.IsMap():
-		kfd := fd.MapKey()
-		vfd := fd.MapValue()
-		mv := v.Map()
-
-		// Collect a sorted list of all map keys and values.
-		type entry struct{ key, val protoreflect.Value }
-		var entries []entry
-		mv.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool {
-			entries = append(entries, entry{k.Value(), v})
-			return true
-		})
-		sort.Slice(entries, func(i, j int) bool {
-			switch kfd.Kind() {
-			case protoreflect.BoolKind:
-				return !entries[i].key.Bool() && entries[j].key.Bool()
-			case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind, protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
-				return entries[i].key.Int() < entries[j].key.Int()
-			case protoreflect.Uint32Kind, protoreflect.Fixed32Kind, protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
-				return entries[i].key.Uint() < entries[j].key.Uint()
-			case protoreflect.StringKind:
-				return entries[i].key.String() < entries[j].key.String()
-			default:
-				panic("invalid kind")
-			}
-		})
-
-		w.write(`{`)
-		comma := ""
-		for _, entry := range entries {
-			w.write(comma)
-			if w.Indent != "" {
-				w.write("\n")
-				w.write(indent)
-				w.write(w.Indent)
-				w.write(w.Indent)
-			}
-
-			s := fmt.Sprint(entry.key.Interface())
-			b, err := json.Marshal(s)
-			if err != nil {
-				return err
-			}
-			w.write(string(b))
-
-			w.write(`:`)
-			if w.Indent != "" {
-				w.write(` `)
-			}
-
-			if err := w.marshalSingularValue(vfd, entry.val, indent+w.Indent); err != nil {
-				return err
-			}
-			comma = ","
-		}
-		if w.Indent != "" {
-			w.write("\n")
-			w.write(indent)
-			w.write(w.Indent)
-		}
-		w.write(`}`)
-		return nil
-	default:
-		return w.marshalSingularValue(fd, v, indent)
-	}
-}
-
-func (w *jsonWriter) marshalSingularValue(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error {
-	switch {
-	case !v.IsValid():
-		w.write("null")
-		return nil
-	case fd.Message() != nil:
-		return w.marshalMessage(v.Message(), indent+w.Indent, "")
-	case fd.Enum() != nil:
-		if fd.Enum().FullName() == "google.protobuf.NullValue" {
-			w.write("null")
-			return nil
-		}
-
-		vd := fd.Enum().Values().ByNumber(v.Enum())
-		if vd == nil || w.EnumsAsInts {
-			w.write(strconv.Itoa(int(v.Enum())))
-		} else {
-			w.write(`"` + string(vd.Name()) + `"`)
-		}
-		return nil
-	default:
-		switch v.Interface().(type) {
-		case float32, float64:
-			switch {
-			case math.IsInf(v.Float(), +1):
-				w.write(`"Infinity"`)
-				return nil
-			case math.IsInf(v.Float(), -1):
-				w.write(`"-Infinity"`)
-				return nil
-			case math.IsNaN(v.Float()):
-				w.write(`"NaN"`)
-				return nil
-			}
-		case int64, uint64:
-			w.write(fmt.Sprintf(`"%d"`, v.Interface()))
-			return nil
-		}
-
-		b, err := json.Marshal(v.Interface())
-		if err != nil {
-			return err
-		}
-		w.write(string(b))
-		return nil
-	}
-}
diff --git a/vendor/github.com/golang/protobuf/jsonpb/json.go b/vendor/github.com/golang/protobuf/jsonpb/json.go
deleted file mode 100644
index 480e2448..00000000
--- a/vendor/github.com/golang/protobuf/jsonpb/json.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package jsonpb provides functionality to marshal and unmarshal between a
-// protocol buffer message and JSON. It follows the specification at
-// https://developers.google.com/protocol-buffers/docs/proto3#json.
-//
-// Do not rely on the default behavior of the standard encoding/json package
-// when called on generated message types as it does not operate correctly.
-//
-// Deprecated: Use the "google.golang.org/protobuf/encoding/protojson"
-// package instead.
-package jsonpb
-
-import (
-	"github.com/golang/protobuf/proto"
-	"google.golang.org/protobuf/reflect/protoreflect"
-	"google.golang.org/protobuf/reflect/protoregistry"
-	"google.golang.org/protobuf/runtime/protoimpl"
-)
-
-// AnyResolver takes a type URL, present in an Any message,
-// and resolves it into an instance of the associated message.
-type AnyResolver interface {
-	Resolve(typeURL string) (proto.Message, error)
-}
-
-type anyResolver struct{ AnyResolver }
-
-func (r anyResolver) FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error) {
-	return r.FindMessageByURL(string(message))
-}
-
-func (r anyResolver) FindMessageByURL(url string) (protoreflect.MessageType, error) {
-	m, err := r.Resolve(url)
-	if err != nil {
-		return nil, err
-	}
-	return protoimpl.X.MessageTypeOf(m), nil
-}
-
-func (r anyResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) {
-	return protoregistry.GlobalTypes.FindExtensionByName(field)
-}
-
-func (r anyResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) {
-	return protoregistry.GlobalTypes.FindExtensionByNumber(message, field)
-}
-
-func wellKnownType(s protoreflect.FullName) string {
-	if s.Parent() == "google.protobuf" {
-		switch s.Name() {
-		case "Empty", "Any",
-			"BoolValue", "BytesValue", "StringValue",
-			"Int32Value", "UInt32Value", "FloatValue",
-			"Int64Value", "UInt64Value", "DoubleValue",
-			"Duration", "Timestamp",
-			"NullValue", "Struct", "Value", "ListValue":
-			return string(s.Name())
-		}
-	}
-	return ""
-}
-
-func isMessageSet(md protoreflect.MessageDescriptor) bool {
-	ms, ok := md.(interface{ IsMessageSet() bool })
-	return ok && ms.IsMessageSet()
-}
diff --git a/vendor/github.com/golang/protobuf/ptypes/any.go b/vendor/github.com/golang/protobuf/ptypes/any.go
index 85f9f573..fdff3fdb 100644
--- a/vendor/github.com/golang/protobuf/ptypes/any.go
+++ b/vendor/github.com/golang/protobuf/ptypes/any.go
@@ -127,9 +127,10 @@ func Is(any *anypb.Any, m proto.Message) bool {
 // The allocated message is stored in the embedded proto.Message.
 //
 // Example:
-//   var x ptypes.DynamicAny
-//   if err := ptypes.UnmarshalAny(a, &x); err != nil { ... }
-//   fmt.Printf("unmarshaled message: %v", x.Message)
+//
+//	var x ptypes.DynamicAny
+//	if err := ptypes.UnmarshalAny(a, &x); err != nil { ... }
+//	fmt.Printf("unmarshaled message: %v", x.Message)
 //
 // Deprecated: Use the any.UnmarshalNew method instead to unmarshal
 // the any message contents into a new instance of the underlying message.
diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md
index fe72a7b1..01ec5245 100644
--- a/vendor/github.com/onsi/gomega/CHANGELOG.md
+++ b/vendor/github.com/onsi/gomega/CHANGELOG.md
@@ -1,3 +1,41 @@
+## 1.32.0
+
+### Maintenance
+- Migrate github.com/golang/protobuf to google.golang.org/protobuf [436a197]
+  
+  This release drops the deprecated github.com/golang/protobuf and adopts google.golang.org/protobuf.  Care was taken to ensure the release is backwards compatible (thanks @jbduncan !).  Please open an issue if you run into one.
+
+- chore: test with Go 1.22 (#733) [32ef35e]
+- Bump golang.org/x/net from 0.19.0 to 0.20.0 (#717) [a0d0387]
+- Bump github-pages and jekyll-feed in /docs (#732) [b71e477]
+- docs: fix typo and broken anchor link to gstruct [f460154]
+- docs: fix HaveEach matcher signature [a2862e4]
+
+## 1.31.1
+
+### Fixes
+- Inverted arguments order of FailureMessage of BeComparableToMatcher [e0dd999]
+- Update test in case keeping msg is desired [ad1a367]
+
+### Maintenance
+- Show how to import the format sub package [24e958d]
+- tidy up go.sum [26661b8]
+- bump dependencies [bde8f7a]
+
+## 1.31.0
+
+### Features
+- Async assertions include context cancellation cause if present [121c37f]
+
+### Maintenance
+- Bump minimum go version [dee1e3c]
+- docs: fix typo in example usage "occured" -> "occurred" [49005fe]
+- Bump actions/setup-go from 4 to 5 (#714) [f1c8757]
+- Bump github/codeql-action from 2 to 3 (#715) [9836e76]
+- Bump github.com/onsi/ginkgo/v2 from 2.13.0 to 2.13.2 (#713) [54726f0]
+- Bump golang.org/x/net from 0.17.0 to 0.19.0 (#711) [df97ecc]
+- docs: fix `HaveExactElement` typo (#712) [a672c86]
+
 ## 1.30.0
 
 ### Features
diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go
index c271a366..ffb81b1f 100644
--- a/vendor/github.com/onsi/gomega/gomega_dsl.go
+++ b/vendor/github.com/onsi/gomega/gomega_dsl.go
@@ -22,7 +22,7 @@ import (
 	"github.com/onsi/gomega/types"
 )
 
-const GOMEGA_VERSION = "1.30.0"
+const GOMEGA_VERSION = "1.32.0"
 
 const nilGomegaPanic = `You are trying to make an assertion, but haven't registered Gomega's fail handler.
 If you're using Ginkgo then you probably forgot to put your assertion in an It().
diff --git a/vendor/github.com/onsi/gomega/internal/async_assertion.go b/vendor/github.com/onsi/gomega/internal/async_assertion.go
index 1188b0bc..cde9e2ec 100644
--- a/vendor/github.com/onsi/gomega/internal/async_assertion.go
+++ b/vendor/github.com/onsi/gomega/internal/async_assertion.go
@@ -553,7 +553,12 @@ func (assertion *AsyncAssertion) match(matcher types.GomegaMatcher, desiredMatch
 				lock.Unlock()
 			}
 		case <-contextDone:
-			fail("Context was cancelled")
+			err := context.Cause(assertion.ctx)
+			if err != nil && err != context.Canceled {
+				fail(fmt.Sprintf("Context was cancelled (cause: %s)", err))
+			} else {
+				fail("Context was cancelled")
+			}
 			return false
 		case <-timeout:
 			if assertion.asyncType == AsyncAssertionTypeEventually {
diff --git a/vendor/github.com/onsi/gomega/matchers.go b/vendor/github.com/onsi/gomega/matchers.go
index 43f99437..8860d677 100644
--- a/vendor/github.com/onsi/gomega/matchers.go
+++ b/vendor/github.com/onsi/gomega/matchers.go
@@ -394,7 +394,7 @@ func ConsistOf(elements ...interface{}) types.GomegaMatcher {
 	}
 }
 
-// HaveExactElemets succeeds if actual contains elements that precisely match the elemets passed into the matcher. The ordering of the elements does matter.
+// HaveExactElements succeeds if actual contains elements that precisely match the elemets passed into the matcher. The ordering of the elements does matter.
 // By default HaveExactElements() uses Equal() to match the elements, however custom matchers can be passed in instead.  Here are some examples:
 //
 //	Expect([]string{"Foo", "FooBar"}).Should(HaveExactElements("Foo", "FooBar"))
diff --git a/vendor/github.com/onsi/gomega/matchers/be_comparable_to_matcher.go b/vendor/github.com/onsi/gomega/matchers/be_comparable_to_matcher.go
index 8ab4bb91..4e389785 100644
--- a/vendor/github.com/onsi/gomega/matchers/be_comparable_to_matcher.go
+++ b/vendor/github.com/onsi/gomega/matchers/be_comparable_to_matcher.go
@@ -41,9 +41,9 @@ func (matcher *BeComparableToMatcher) Match(actual interface{}) (success bool, m
 }
 
 func (matcher *BeComparableToMatcher) FailureMessage(actual interface{}) (message string) {
-	return cmp.Diff(matcher.Expected, actual, matcher.Options)
+	return fmt.Sprint("Expected object to be comparable, diff: ", cmp.Diff(actual, matcher.Expected, matcher.Options...))
 }
 
 func (matcher *BeComparableToMatcher) NegatedFailureMessage(actual interface{}) (message string) {
-	return format.Message(actual, "not to equal", matcher.Expected)
+	return format.Message(actual, "not to be comparable to", matcher.Expected)
 }
diff --git a/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusteroperator.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusteroperator.crd.yaml
deleted file mode 100644
index 3baf5a45..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusteroperator.crd.yaml
+++ /dev/null
@@ -1,167 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/497
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-  name: clusteroperators.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: ClusterOperator
-    listKind: ClusterOperatorList
-    plural: clusteroperators
-    shortNames:
-    - co
-    singular: clusteroperator
-  scope: Cluster
-  versions:
-  - additionalPrinterColumns:
-    - description: The version the operator is at.
-      jsonPath: .status.versions[?(@.name=="operator")].version
-      name: Version
-      type: string
-    - description: Whether the operator is running and stable.
-      jsonPath: .status.conditions[?(@.type=="Available")].status
-      name: Available
-      type: string
-    - description: Whether the operator is processing changes.
-      jsonPath: .status.conditions[?(@.type=="Progressing")].status
-      name: Progressing
-      type: string
-    - description: Whether the operator is degraded.
-      jsonPath: .status.conditions[?(@.type=="Degraded")].status
-      name: Degraded
-      type: string
-    - description: The time the operator's Available status last changed.
-      jsonPath: .status.conditions[?(@.type=="Available")].lastTransitionTime
-      name: Since
-      type: date
-    name: v1
-    schema:
-      openAPIV3Schema:
-        description: "ClusterOperator is the Custom Resource object which holds the
-          current state of an operator. This object is used by operators to convey
-          their state to the rest of the cluster. \n Compatibility level 1: Stable
-          within a major release for a minimum of 12 months or 3 minor releases (whichever
-          is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds configuration that could apply to any operator.
-            type: object
-          status:
-            description: status holds the information about the state of an operator.  It
-              is consistent with status information across the Kubernetes ecosystem.
-            properties:
-              conditions:
-                description: conditions describes the state of the operator's managed
-                  and monitored components.
-                items:
-                  description: ClusterOperatorStatusCondition represents the state
-                    of the operator's managed and monitored components.
-                  properties:
-                    lastTransitionTime:
-                      description: lastTransitionTime is the time of the last update
-                        to the current status property.
-                      format: date-time
-                      type: string
-                    message:
-                      description: message provides additional information about the
-                        current condition. This is only to be consumed by humans.  It
-                        may contain Line Feed characters (U+000A), which should be
-                        rendered as new lines.
-                      type: string
-                    reason:
-                      description: reason is the CamelCase reason for the condition's
-                        current status.
-                      type: string
-                    status:
-                      description: status of the condition, one of True, False, Unknown.
-                      type: string
-                    type:
-                      description: type specifies the aspect reported by this condition.
-                      type: string
-                  required:
-                  - lastTransitionTime
-                  - status
-                  - type
-                  type: object
-                type: array
-              extension:
-                description: extension contains any additional status information
-                  specific to the operator which owns this status object.
-                nullable: true
-                type: object
-                x-kubernetes-preserve-unknown-fields: true
-              relatedObjects:
-                description: 'relatedObjects is a list of objects that are "interesting"
-                  or related to this operator.  Common uses are: 1. the detailed resource
-                  driving the operator 2. operator namespaces 3. operand namespaces'
-                items:
-                  description: ObjectReference contains enough information to let
-                    you inspect or modify the referred object.
-                  properties:
-                    group:
-                      description: group of the referent.
-                      type: string
-                    name:
-                      description: name of the referent.
-                      type: string
-                    namespace:
-                      description: namespace of the referent.
-                      type: string
-                    resource:
-                      description: resource of the referent.
-                      type: string
-                  required:
-                  - group
-                  - name
-                  - resource
-                  type: object
-                type: array
-              versions:
-                description: versions is a slice of operator and operand version tuples.  Operators
-                  which manage multiple operands will have multiple operand entries
-                  in the array.  Available operators must report the version of the
-                  operator itself with the name "operator". An operator reports a
-                  new "operator" version when it has rolled out the new version to
-                  all of its operands.
-                items:
-                  properties:
-                    name:
-                      description: name is the name of the particular operand this
-                        version is for.  It usually matches container images, not
-                        operators.
-                      type: string
-                    version:
-                      description: version indicates which version of a particular
-                        operand is currently being managed.  It must always match
-                        the Available operand.  If 1.0.0 is Available, then this must
-                        indicate 1.0.0 even if the operator is trying to rollout 1.1.0
-                      type: string
-                  required:
-                  - name
-                  - version
-                  type: object
-                type: array
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion-CustomNoUpgrade.crd.yaml
deleted file mode 100644
index dcb871ee..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion-CustomNoUpgrade.crd.yaml
+++ /dev/null
@@ -1,780 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/495
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    release.openshift.io/feature-set: CustomNoUpgrade
-  name: clusterversions.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: ClusterVersion
-    plural: clusterversions
-    singular: clusterversion
-  scope: Cluster
-  versions:
-  - additionalPrinterColumns:
-    - jsonPath: .status.history[?(@.state=="Completed")].version
-      name: Version
-      type: string
-    - jsonPath: .status.conditions[?(@.type=="Available")].status
-      name: Available
-      type: string
-    - jsonPath: .status.conditions[?(@.type=="Progressing")].status
-      name: Progressing
-      type: string
-    - jsonPath: .status.conditions[?(@.type=="Progressing")].lastTransitionTime
-      name: Since
-      type: date
-    - jsonPath: .status.conditions[?(@.type=="Progressing")].message
-      name: Status
-      type: string
-    name: v1
-    schema:
-      openAPIV3Schema:
-        description: "ClusterVersion is the configuration for the ClusterVersionOperator.
-          This is where parameters related to automatic updates can be set. \n Compatibility
-          level 1: Stable within a major release for a minimum of 12 months or 3 minor
-          releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec is the desired state of the cluster version - the operator
-              will work to ensure that the desired version is applied to the cluster.
-            properties:
-              capabilities:
-                description: capabilities configures the installation of optional,
-                  core cluster components.  A null value here is identical to an empty
-                  object; see the child properties for default semantics.
-                properties:
-                  additionalEnabledCapabilities:
-                    description: additionalEnabledCapabilities extends the set of
-                      managed capabilities beyond the baseline defined in baselineCapabilitySet.  The
-                      default is an empty set.
-                    items:
-                      description: ClusterVersionCapability enumerates optional, core
-                        cluster components.
-                      enum:
-                      - openshift-samples
-                      - baremetal
-                      - marketplace
-                      - Console
-                      - Insights
-                      - Storage
-                      - CSISnapshot
-                      - NodeTuning
-                      - MachineAPI
-                      - Build
-                      - DeploymentConfig
-                      - ImageRegistry
-                      - OperatorLifecycleManager
-                      - CloudCredential
-                      - Ingress
-                      - CloudControllerManager
-                      type: string
-                    type: array
-                    x-kubernetes-list-type: atomic
-                  baselineCapabilitySet:
-                    description: baselineCapabilitySet selects an initial set of optional
-                      capabilities to enable, which can be extended via additionalEnabledCapabilities.  If
-                      unset, the cluster will choose a default, and the default may
-                      change over time. The current default is vCurrent.
-                    enum:
-                    - None
-                    - v4.11
-                    - v4.12
-                    - v4.13
-                    - v4.14
-                    - v4.15
-                    - v4.16
-                    - vCurrent
-                    type: string
-                type: object
-              channel:
-                description: channel is an identifier for explicitly requesting that
-                  a non-default set of updates be applied to this cluster. The default
-                  channel will be contain stable updates that are appropriate for
-                  production clusters.
-                type: string
-              clusterID:
-                description: clusterID uniquely identifies this cluster. This is expected
-                  to be an RFC4122 UUID value (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
-                  in hexadecimal values). This is a required field.
-                type: string
-              desiredUpdate:
-                description: "desiredUpdate is an optional field that indicates the
-                  desired value of the cluster version. Setting this value will trigger
-                  an upgrade (if the current version does not match the desired version).
-                  The set of recommended update values is listed as part of available
-                  updates in status, and setting values outside that range may cause
-                  the upgrade to fail. \n Some of the fields are inter-related with
-                  restrictions and meanings described here. 1. image is specified,
-                  version is specified, architecture is specified. API validation
-                  error. 2. image is specified, version is specified, architecture
-                  is not specified. You should not do this. version is silently ignored
-                  and image is used. 3. image is specified, version is not specified,
-                  architecture is specified. API validation error. 4. image is specified,
-                  version is not specified, architecture is not specified. image is
-                  used. 5. image is not specified, version is specified, architecture
-                  is specified. version and desired architecture are used to select
-                  an image. 6. image is not specified, version is specified, architecture
-                  is not specified. version and current architecture are used to select
-                  an image. 7. image is not specified, version is not specified, architecture
-                  is specified. API validation error. 8. image is not specified, version
-                  is not specified, architecture is not specified. API validation
-                  error. \n If an upgrade fails the operator will halt and report
-                  status about the failing component. Setting the desired update value
-                  back to the previous version will cause a rollback to be attempted.
-                  Not all rollbacks will succeed."
-                properties:
-                  architecture:
-                    description: architecture is an optional field that indicates
-                      the desired value of the cluster architecture. In this context
-                      cluster architecture means either a single architecture or a
-                      multi architecture. architecture can only be set to Multi thereby
-                      only allowing updates from single to multi architecture. If
-                      architecture is set, image cannot be set and version must be
-                      set. Valid values are 'Multi' and empty.
-                    enum:
-                    - Multi
-                    - ""
-                    type: string
-                  force:
-                    description: force allows an administrator to update to an image
-                      that has failed verification or upgradeable checks. This option
-                      should only be used when the authenticity of the provided image
-                      has been verified out of band because the provided image will
-                      run with full administrative access to the cluster. Do not use
-                      this flag with images that comes from unknown or potentially
-                      malicious sources.
-                    type: boolean
-                  image:
-                    description: image is a container image location that contains
-                      the update. image should be used when the desired version does
-                      not exist in availableUpdates or history. When image is set,
-                      version is ignored. When image is set, version should be empty.
-                      When image is set, architecture cannot be specified.
-                    type: string
-                  version:
-                    description: version is a semantic version identifying the update
-                      version. version is ignored if image is specified and required
-                      if architecture is specified.
-                    type: string
-                type: object
-                x-kubernetes-validations:
-                - message: cannot set both Architecture and Image
-                  rule: 'has(self.architecture) && has(self.image) ? (self.architecture
-                    == '''' || self.image == '''') : true'
-                - message: Version must be set if Architecture is set
-                  rule: 'has(self.architecture) && self.architecture != '''' ? self.version
-                    != '''' : true'
-              overrides:
-                description: overrides is list of overides for components that are
-                  managed by cluster version operator. Marking a component unmanaged
-                  will prevent the operator from creating or updating the object.
-                items:
-                  description: ComponentOverride allows overriding cluster version
-                    operator's behavior for a component.
-                  properties:
-                    group:
-                      description: group identifies the API group that the kind is
-                        in.
-                      type: string
-                    kind:
-                      description: kind indentifies which object to override.
-                      type: string
-                    name:
-                      description: name is the component's name.
-                      type: string
-                    namespace:
-                      description: namespace is the component's namespace. If the
-                        resource is cluster scoped, the namespace should be empty.
-                      type: string
-                    unmanaged:
-                      description: 'unmanaged controls if cluster version operator
-                        should stop managing the resources in this cluster. Default:
-                        false'
-                      type: boolean
-                  required:
-                  - group
-                  - kind
-                  - name
-                  - namespace
-                  - unmanaged
-                  type: object
-                type: array
-                x-kubernetes-list-map-keys:
-                - kind
-                - group
-                - namespace
-                - name
-                x-kubernetes-list-type: map
-              signatureStores:
-                description: "signatureStores contains the upstream URIs to verify
-                  release signatures and optional reference to a config map by name
-                  containing the PEM-encoded CA bundle. \n By default, CVO will use
-                  existing signature stores if this property is empty. The CVO will
-                  check the release signatures in the local ConfigMaps first. It will
-                  search for a valid signature in these stores in parallel only when
-                  local ConfigMaps did not include a valid signature. Validation will
-                  fail if none of the signature stores reply with valid signature
-                  before timeout. Setting signatureStores will replace the default
-                  signature stores with custom signature stores. Default stores can
-                  be used with custom signature stores by adding them manually. \n
-                  A maximum of 32 signature stores may be configured."
-                items:
-                  description: SignatureStore represents the URL of custom Signature
-                    Store
-                  properties:
-                    ca:
-                      description: ca is an optional reference to a config map by
-                        name containing the PEM-encoded CA bundle. It is used as a
-                        trust anchor to validate the TLS certificate presented by
-                        the remote server. The key "ca.crt" is used to locate the
-                        data. If specified and the config map or expected key is not
-                        found, the signature store is not honored. If the specified
-                        ca data is not valid, the signature store is not honored.
-                        If empty, we fall back to the CA configured via Proxy, which
-                        is appended to the default system roots. The namespace for
-                        this config map is openshift-config.
-                      properties:
-                        name:
-                          description: name is the metadata.name of the referenced
-                            config map
-                          type: string
-                      required:
-                      - name
-                      type: object
-                    url:
-                      description: url contains the upstream custom signature store
-                        URL. url should be a valid absolute http/https URI of an upstream
-                        signature store as per rfc1738. This must be provided and
-                        cannot be empty.
-                      type: string
-                      x-kubernetes-validations:
-                      - message: url must be a valid absolute URL
-                        rule: isURL(self)
-                  required:
-                  - url
-                  type: object
-                maxItems: 32
-                type: array
-                x-kubernetes-list-map-keys:
-                - url
-                x-kubernetes-list-type: map
-              upstream:
-                description: upstream may be used to specify the preferred update
-                  server. By default it will use the appropriate update server for
-                  the cluster and region.
-                type: string
-            required:
-            - clusterID
-            type: object
-          status:
-            description: status contains information about the available updates and
-              any in-progress updates.
-            properties:
-              availableUpdates:
-                description: availableUpdates contains updates recommended for this
-                  cluster. Updates which appear in conditionalUpdates but not in availableUpdates
-                  may expose this cluster to known issues. This list may be empty
-                  if no updates are recommended, if the update service is unavailable,
-                  or if an invalid channel has been specified.
-                items:
-                  description: Release represents an OpenShift release image and associated
-                    metadata.
-                  properties:
-                    channels:
-                      description: channels is the set of Cincinnati channels to which
-                        the release currently belongs.
-                      items:
-                        type: string
-                      type: array
-                      x-kubernetes-list-type: set
-                    image:
-                      description: image is a container image location that contains
-                        the update. When this field is part of spec, image is optional
-                        if version is specified and the availableUpdates field contains
-                        a matching version.
-                      type: string
-                    url:
-                      description: url contains information about this release. This
-                        URL is set by the 'url' metadata property on a release or
-                        the metadata returned by the update API and should be displayed
-                        as a link in user interfaces. The URL field may not be set
-                        for test or nightly releases.
-                      type: string
-                    version:
-                      description: version is a semantic version identifying the update
-                        version. When this field is part of spec, version is optional
-                        if image is specified.
-                      type: string
-                  type: object
-                nullable: true
-                type: array
-                x-kubernetes-list-type: atomic
-              capabilities:
-                description: capabilities describes the state of optional, core cluster
-                  components.
-                properties:
-                  enabledCapabilities:
-                    description: enabledCapabilities lists all the capabilities that
-                      are currently managed.
-                    items:
-                      description: ClusterVersionCapability enumerates optional, core
-                        cluster components.
-                      enum:
-                      - openshift-samples
-                      - baremetal
-                      - marketplace
-                      - Console
-                      - Insights
-                      - Storage
-                      - CSISnapshot
-                      - NodeTuning
-                      - MachineAPI
-                      - Build
-                      - DeploymentConfig
-                      - ImageRegistry
-                      - OperatorLifecycleManager
-                      - CloudCredential
-                      - Ingress
-                      - CloudControllerManager
-                      type: string
-                    type: array
-                    x-kubernetes-list-type: atomic
-                  knownCapabilities:
-                    description: knownCapabilities lists all the capabilities known
-                      to the current cluster.
-                    items:
-                      description: ClusterVersionCapability enumerates optional, core
-                        cluster components.
-                      enum:
-                      - openshift-samples
-                      - baremetal
-                      - marketplace
-                      - Console
-                      - Insights
-                      - Storage
-                      - CSISnapshot
-                      - NodeTuning
-                      - MachineAPI
-                      - Build
-                      - DeploymentConfig
-                      - ImageRegistry
-                      - OperatorLifecycleManager
-                      - CloudCredential
-                      - Ingress
-                      - CloudControllerManager
-                      type: string
-                    type: array
-                    x-kubernetes-list-type: atomic
-                type: object
-              conditionalUpdates:
-                description: conditionalUpdates contains the list of updates that
-                  may be recommended for this cluster if it meets specific required
-                  conditions. Consumers interested in the set of updates that are
-                  actually recommended for this cluster should use availableUpdates.
-                  This list may be empty if no updates are recommended, if the update
-                  service is unavailable, or if an empty or invalid channel has been
-                  specified.
-                items:
-                  description: ConditionalUpdate represents an update which is recommended
-                    to some clusters on the version the current cluster is reconciling,
-                    but which may not be recommended for the current cluster.
-                  properties:
-                    conditions:
-                      description: 'conditions represents the observations of the
-                        conditional update''s current status. Known types are: * Recommended,
-                        for whether the update is recommended for the current cluster.'
-                      items:
-                        description: "Condition contains details for one aspect of
-                          the current state of this API Resource. --- This struct
-                          is intended for direct use as an array at the field path
-                          .status.conditions.  For example, \n type FooStatus struct{
-                          // Represents the observations of a foo's current state.
-                          // Known .status.conditions.type are: \"Available\", \"Progressing\",
-                          and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
-                          // +listType=map // +listMapKey=type Conditions []metav1.Condition
-                          `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
-                          protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields
-                          }"
-                        properties:
-                          lastTransitionTime:
-                            description: lastTransitionTime is the last time the condition
-                              transitioned from one status to another. This should
-                              be when the underlying condition changed.  If that is
-                              not known, then using the time when the API field changed
-                              is acceptable.
-                            format: date-time
-                            type: string
-                          message:
-                            description: message is a human readable message indicating
-                              details about the transition. This may be an empty string.
-                            maxLength: 32768
-                            type: string
-                          observedGeneration:
-                            description: observedGeneration represents the .metadata.generation
-                              that the condition was set based upon. For instance,
-                              if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration
-                              is 9, the condition is out of date with respect to the
-                              current state of the instance.
-                            format: int64
-                            minimum: 0
-                            type: integer
-                          reason:
-                            description: reason contains a programmatic identifier
-                              indicating the reason for the condition's last transition.
-                              Producers of specific condition types may define expected
-                              values and meanings for this field, and whether the
-                              values are considered a guaranteed API. The value should
-                              be a CamelCase string. This field may not be empty.
-                            maxLength: 1024
-                            minLength: 1
-                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
-                            type: string
-                          status:
-                            description: status of the condition, one of True, False,
-                              Unknown.
-                            enum:
-                            - "True"
-                            - "False"
-                            - Unknown
-                            type: string
-                          type:
-                            description: type of condition in CamelCase or in foo.example.com/CamelCase.
-                              --- Many .condition.type values are consistent across
-                              resources like Available, but because arbitrary conditions
-                              can be useful (see .node.status.conditions), the ability
-                              to deconflict is important. The regex it matches is
-                              (dns1123SubdomainFmt/)?(qualifiedNameFmt)
-                            maxLength: 316
-                            pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
-                            type: string
-                        required:
-                        - lastTransitionTime
-                        - message
-                        - reason
-                        - status
-                        - type
-                        type: object
-                      type: array
-                      x-kubernetes-list-map-keys:
-                      - type
-                      x-kubernetes-list-type: map
-                    release:
-                      description: release is the target of the update.
-                      properties:
-                        channels:
-                          description: channels is the set of Cincinnati channels
-                            to which the release currently belongs.
-                          items:
-                            type: string
-                          type: array
-                          x-kubernetes-list-type: set
-                        image:
-                          description: image is a container image location that contains
-                            the update. When this field is part of spec, image is
-                            optional if version is specified and the availableUpdates
-                            field contains a matching version.
-                          type: string
-                        url:
-                          description: url contains information about this release.
-                            This URL is set by the 'url' metadata property on a release
-                            or the metadata returned by the update API and should
-                            be displayed as a link in user interfaces. The URL field
-                            may not be set for test or nightly releases.
-                          type: string
-                        version:
-                          description: version is a semantic version identifying the
-                            update version. When this field is part of spec, version
-                            is optional if image is specified.
-                          type: string
-                      type: object
-                    risks:
-                      description: risks represents the range of issues associated
-                        with updating to the target release. The cluster-version operator
-                        will evaluate all entries, and only recommend the update if
-                        there is at least one entry and all entries recommend the
-                        update.
-                      items:
-                        description: ConditionalUpdateRisk represents a reason and
-                          cluster-state for not recommending a conditional update.
-                        properties:
-                          matchingRules:
-                            description: matchingRules is a slice of conditions for
-                              deciding which clusters match the risk and which do
-                              not. The slice is ordered by decreasing precedence.
-                              The cluster-version operator will walk the slice in
-                              order, and stop after the first it can successfully
-                              evaluate. If no condition can be successfully evaluated,
-                              the update will not be recommended.
-                            items:
-                              description: ClusterCondition is a union of typed cluster
-                                conditions.  The 'type' property determines which
-                                of the type-specific properties are relevant. When
-                                evaluated on a cluster, the condition may match, not
-                                match, or fail to evaluate.
-                              properties:
-                                promql:
-                                  description: promQL represents a cluster condition
-                                    based on PromQL.
-                                  properties:
-                                    promql:
-                                      description: PromQL is a PromQL query classifying
-                                        clusters. This query query should return a
-                                        1 in the match case and a 0 in the does-not-match
-                                        case. Queries which return no time series,
-                                        or which return values besides 0 or 1, are
-                                        evaluation failures.
-                                      type: string
-                                  required:
-                                  - promql
-                                  type: object
-                                type:
-                                  description: type represents the cluster-condition
-                                    type. This defines the members and semantics of
-                                    any additional properties.
-                                  enum:
-                                  - Always
-                                  - PromQL
-                                  type: string
-                              required:
-                              - type
-                              type: object
-                            minItems: 1
-                            type: array
-                            x-kubernetes-list-type: atomic
-                          message:
-                            description: message provides additional information about
-                              the risk of updating, in the event that matchingRules
-                              match the cluster state. This is only to be consumed
-                              by humans. It may contain Line Feed characters (U+000A),
-                              which should be rendered as new lines.
-                            minLength: 1
-                            type: string
-                          name:
-                            description: name is the CamelCase reason for not recommending
-                              a conditional update, in the event that matchingRules
-                              match the cluster state.
-                            minLength: 1
-                            type: string
-                          url:
-                            description: url contains information about this risk.
-                            format: uri
-                            minLength: 1
-                            type: string
-                        required:
-                        - matchingRules
-                        - message
-                        - name
-                        - url
-                        type: object
-                      minItems: 1
-                      type: array
-                      x-kubernetes-list-map-keys:
-                      - name
-                      x-kubernetes-list-type: map
-                  required:
-                  - release
-                  - risks
-                  type: object
-                type: array
-                x-kubernetes-list-type: atomic
-              conditions:
-                description: conditions provides information about the cluster version.
-                  The condition "Available" is set to true if the desiredUpdate has
-                  been reached. The condition "Progressing" is set to true if an update
-                  is being applied. The condition "Degraded" is set to true if an
-                  update is currently blocked by a temporary or permanent error. Conditions
-                  are only valid for the current desiredUpdate when metadata.generation
-                  is equal to status.generation.
-                items:
-                  description: ClusterOperatorStatusCondition represents the state
-                    of the operator's managed and monitored components.
-                  properties:
-                    lastTransitionTime:
-                      description: lastTransitionTime is the time of the last update
-                        to the current status property.
-                      format: date-time
-                      type: string
-                    message:
-                      description: message provides additional information about the
-                        current condition. This is only to be consumed by humans.  It
-                        may contain Line Feed characters (U+000A), which should be
-                        rendered as new lines.
-                      type: string
-                    reason:
-                      description: reason is the CamelCase reason for the condition's
-                        current status.
-                      type: string
-                    status:
-                      description: status of the condition, one of True, False, Unknown.
-                      type: string
-                    type:
-                      description: type specifies the aspect reported by this condition.
-                      type: string
-                  required:
-                  - lastTransitionTime
-                  - status
-                  - type
-                  type: object
-                type: array
-                x-kubernetes-list-map-keys:
-                - type
-                x-kubernetes-list-type: map
-              desired:
-                description: desired is the version that the cluster is reconciling
-                  towards. If the cluster is not yet fully initialized desired will
-                  be set with the information available, which may be an image or
-                  a tag.
-                properties:
-                  channels:
-                    description: channels is the set of Cincinnati channels to which
-                      the release currently belongs.
-                    items:
-                      type: string
-                    type: array
-                    x-kubernetes-list-type: set
-                  image:
-                    description: image is a container image location that contains
-                      the update. When this field is part of spec, image is optional
-                      if version is specified and the availableUpdates field contains
-                      a matching version.
-                    type: string
-                  url:
-                    description: url contains information about this release. This
-                      URL is set by the 'url' metadata property on a release or the
-                      metadata returned by the update API and should be displayed
-                      as a link in user interfaces. The URL field may not be set for
-                      test or nightly releases.
-                    type: string
-                  version:
-                    description: version is a semantic version identifying the update
-                      version. When this field is part of spec, version is optional
-                      if image is specified.
-                    type: string
-                type: object
-              history:
-                description: history contains a list of the most recent versions applied
-                  to the cluster. This value may be empty during cluster startup,
-                  and then will be updated when a new update is being applied. The
-                  newest update is first in the list and it is ordered by recency.
-                  Updates in the history have state Completed if the rollout completed
-                  - if an update was failing or halfway applied the state will be
-                  Partial. Only a limited amount of update history is preserved.
-                items:
-                  description: UpdateHistory is a single attempted update to the cluster.
-                  properties:
-                    acceptedRisks:
-                      description: acceptedRisks records risks which were accepted
-                        to initiate the update. For example, it may menition an Upgradeable=False
-                        or missing signature that was overriden via desiredUpdate.force,
-                        or an update that was initiated despite not being in the availableUpdates
-                        set of recommended update targets.
-                      type: string
-                    completionTime:
-                      description: completionTime, if set, is when the update was
-                        fully applied. The update that is currently being applied
-                        will have a null completion time. Completion time will always
-                        be set for entries that are not the current update (usually
-                        to the started time of the next update).
-                      format: date-time
-                      nullable: true
-                      type: string
-                    image:
-                      description: image is a container image location that contains
-                        the update. This value is always populated.
-                      type: string
-                    startedTime:
-                      description: startedTime is the time at which the update was
-                        started.
-                      format: date-time
-                      type: string
-                    state:
-                      description: state reflects whether the update was fully applied.
-                        The Partial state indicates the update is not fully applied,
-                        while the Completed state indicates the update was successfully
-                        rolled out at least once (all parts of the update successfully
-                        applied).
-                      type: string
-                    verified:
-                      description: verified indicates whether the provided update
-                        was properly verified before it was installed. If this is
-                        false the cluster may not be trusted. Verified does not cover
-                        upgradeable checks that depend on the cluster state at the
-                        time when the update target was accepted.
-                      type: boolean
-                    version:
-                      description: version is a semantic version identifying the update
-                        version. If the requested image does not define a version,
-                        or if a failure occurs retrieving the image, this value may
-                        be empty.
-                      type: string
-                  required:
-                  - completionTime
-                  - image
-                  - startedTime
-                  - state
-                  - verified
-                  type: object
-                type: array
-                x-kubernetes-list-type: atomic
-              observedGeneration:
-                description: observedGeneration reports which version of the spec
-                  is being synced. If this value is not equal to metadata.generation,
-                  then the desired and conditions fields may represent a previous
-                  version.
-                format: int64
-                type: integer
-              versionHash:
-                description: versionHash is a fingerprint of the content that the
-                  cluster will be updated with. It is used by the operator to avoid
-                  unnecessary work and is for internal use only.
-                type: string
-            required:
-            - availableUpdates
-            - desired
-            - observedGeneration
-            - versionHash
-            type: object
-        required:
-        - spec
-        type: object
-        x-kubernetes-validations:
-        - message: the `baremetal` capability requires the `MachineAPI` capability,
-            which is neither explicitly or implicitly enabled in this cluster, please
-            enable the `MachineAPI` capability
-          rule: 'has(self.spec.capabilities) && has(self.spec.capabilities.additionalEnabledCapabilities)
-            && self.spec.capabilities.baselineCapabilitySet == ''None'' && ''baremetal''
-            in self.spec.capabilities.additionalEnabledCapabilities ? ''MachineAPI''
-            in self.spec.capabilities.additionalEnabledCapabilities || (has(self.status)
-            && has(self.status.capabilities) && has(self.status.capabilities.enabledCapabilities)
-            && ''MachineAPI'' in self.status.capabilities.enabledCapabilities) : true'
-        - message: the `marketplace` capability requires the `OperatorLifecycleManager`
-            capability, which is neither explicitly or implicitly enabled in this
-            cluster, please enable the `OperatorLifecycleManager` capability
-          rule: 'has(self.spec.capabilities) && has(self.spec.capabilities.additionalEnabledCapabilities)
-            && self.spec.capabilities.baselineCapabilitySet == ''None'' && ''marketplace''
-            in self.spec.capabilities.additionalEnabledCapabilities ? ''OperatorLifecycleManager''
-            in self.spec.capabilities.additionalEnabledCapabilities || (has(self.status)
-            && has(self.status.capabilities) && has(self.status.capabilities.enabledCapabilities)
-            && ''OperatorLifecycleManager'' in self.status.capabilities.enabledCapabilities)
-            : true'
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion-Default.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion-Default.crd.yaml
deleted file mode 100644
index 371177aa..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion-Default.crd.yaml
+++ /dev/null
@@ -1,727 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/495
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    release.openshift.io/feature-set: Default
-  name: clusterversions.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: ClusterVersion
-    plural: clusterversions
-    singular: clusterversion
-  scope: Cluster
-  versions:
-  - additionalPrinterColumns:
-    - jsonPath: .status.history[?(@.state=="Completed")].version
-      name: Version
-      type: string
-    - jsonPath: .status.conditions[?(@.type=="Available")].status
-      name: Available
-      type: string
-    - jsonPath: .status.conditions[?(@.type=="Progressing")].status
-      name: Progressing
-      type: string
-    - jsonPath: .status.conditions[?(@.type=="Progressing")].lastTransitionTime
-      name: Since
-      type: date
-    - jsonPath: .status.conditions[?(@.type=="Progressing")].message
-      name: Status
-      type: string
-    name: v1
-    schema:
-      openAPIV3Schema:
-        description: "ClusterVersion is the configuration for the ClusterVersionOperator.
-          This is where parameters related to automatic updates can be set. \n Compatibility
-          level 1: Stable within a major release for a minimum of 12 months or 3 minor
-          releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec is the desired state of the cluster version - the operator
-              will work to ensure that the desired version is applied to the cluster.
-            properties:
-              capabilities:
-                description: capabilities configures the installation of optional,
-                  core cluster components.  A null value here is identical to an empty
-                  object; see the child properties for default semantics.
-                properties:
-                  additionalEnabledCapabilities:
-                    description: additionalEnabledCapabilities extends the set of
-                      managed capabilities beyond the baseline defined in baselineCapabilitySet.  The
-                      default is an empty set.
-                    items:
-                      description: ClusterVersionCapability enumerates optional, core
-                        cluster components.
-                      enum:
-                      - openshift-samples
-                      - baremetal
-                      - marketplace
-                      - Console
-                      - Insights
-                      - Storage
-                      - CSISnapshot
-                      - NodeTuning
-                      - MachineAPI
-                      - Build
-                      - DeploymentConfig
-                      - ImageRegistry
-                      - OperatorLifecycleManager
-                      - CloudCredential
-                      - Ingress
-                      - CloudControllerManager
-                      type: string
-                    type: array
-                    x-kubernetes-list-type: atomic
-                  baselineCapabilitySet:
-                    description: baselineCapabilitySet selects an initial set of optional
-                      capabilities to enable, which can be extended via additionalEnabledCapabilities.  If
-                      unset, the cluster will choose a default, and the default may
-                      change over time. The current default is vCurrent.
-                    enum:
-                    - None
-                    - v4.11
-                    - v4.12
-                    - v4.13
-                    - v4.14
-                    - v4.15
-                    - v4.16
-                    - vCurrent
-                    type: string
-                type: object
-              channel:
-                description: channel is an identifier for explicitly requesting that
-                  a non-default set of updates be applied to this cluster. The default
-                  channel will be contain stable updates that are appropriate for
-                  production clusters.
-                type: string
-              clusterID:
-                description: clusterID uniquely identifies this cluster. This is expected
-                  to be an RFC4122 UUID value (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
-                  in hexadecimal values). This is a required field.
-                type: string
-              desiredUpdate:
-                description: "desiredUpdate is an optional field that indicates the
-                  desired value of the cluster version. Setting this value will trigger
-                  an upgrade (if the current version does not match the desired version).
-                  The set of recommended update values is listed as part of available
-                  updates in status, and setting values outside that range may cause
-                  the upgrade to fail. \n Some of the fields are inter-related with
-                  restrictions and meanings described here. 1. image is specified,
-                  version is specified, architecture is specified. API validation
-                  error. 2. image is specified, version is specified, architecture
-                  is not specified. You should not do this. version is silently ignored
-                  and image is used. 3. image is specified, version is not specified,
-                  architecture is specified. API validation error. 4. image is specified,
-                  version is not specified, architecture is not specified. image is
-                  used. 5. image is not specified, version is specified, architecture
-                  is specified. version and desired architecture are used to select
-                  an image. 6. image is not specified, version is specified, architecture
-                  is not specified. version and current architecture are used to select
-                  an image. 7. image is not specified, version is not specified, architecture
-                  is specified. API validation error. 8. image is not specified, version
-                  is not specified, architecture is not specified. API validation
-                  error. \n If an upgrade fails the operator will halt and report
-                  status about the failing component. Setting the desired update value
-                  back to the previous version will cause a rollback to be attempted.
-                  Not all rollbacks will succeed."
-                properties:
-                  architecture:
-                    description: architecture is an optional field that indicates
-                      the desired value of the cluster architecture. In this context
-                      cluster architecture means either a single architecture or a
-                      multi architecture. architecture can only be set to Multi thereby
-                      only allowing updates from single to multi architecture. If
-                      architecture is set, image cannot be set and version must be
-                      set. Valid values are 'Multi' and empty.
-                    enum:
-                    - Multi
-                    - ""
-                    type: string
-                  force:
-                    description: force allows an administrator to update to an image
-                      that has failed verification or upgradeable checks. This option
-                      should only be used when the authenticity of the provided image
-                      has been verified out of band because the provided image will
-                      run with full administrative access to the cluster. Do not use
-                      this flag with images that comes from unknown or potentially
-                      malicious sources.
-                    type: boolean
-                  image:
-                    description: image is a container image location that contains
-                      the update. image should be used when the desired version does
-                      not exist in availableUpdates or history. When image is set,
-                      version is ignored. When image is set, version should be empty.
-                      When image is set, architecture cannot be specified.
-                    type: string
-                  version:
-                    description: version is a semantic version identifying the update
-                      version. version is ignored if image is specified and required
-                      if architecture is specified.
-                    type: string
-                type: object
-                x-kubernetes-validations:
-                - message: cannot set both Architecture and Image
-                  rule: 'has(self.architecture) && has(self.image) ? (self.architecture
-                    == '''' || self.image == '''') : true'
-                - message: Version must be set if Architecture is set
-                  rule: 'has(self.architecture) && self.architecture != '''' ? self.version
-                    != '''' : true'
-              overrides:
-                description: overrides is list of overides for components that are
-                  managed by cluster version operator. Marking a component unmanaged
-                  will prevent the operator from creating or updating the object.
-                items:
-                  description: ComponentOverride allows overriding cluster version
-                    operator's behavior for a component.
-                  properties:
-                    group:
-                      description: group identifies the API group that the kind is
-                        in.
-                      type: string
-                    kind:
-                      description: kind indentifies which object to override.
-                      type: string
-                    name:
-                      description: name is the component's name.
-                      type: string
-                    namespace:
-                      description: namespace is the component's namespace. If the
-                        resource is cluster scoped, the namespace should be empty.
-                      type: string
-                    unmanaged:
-                      description: 'unmanaged controls if cluster version operator
-                        should stop managing the resources in this cluster. Default:
-                        false'
-                      type: boolean
-                  required:
-                  - group
-                  - kind
-                  - name
-                  - namespace
-                  - unmanaged
-                  type: object
-                type: array
-                x-kubernetes-list-map-keys:
-                - kind
-                - group
-                - namespace
-                - name
-                x-kubernetes-list-type: map
-              upstream:
-                description: upstream may be used to specify the preferred update
-                  server. By default it will use the appropriate update server for
-                  the cluster and region.
-                type: string
-            required:
-            - clusterID
-            type: object
-          status:
-            description: status contains information about the available updates and
-              any in-progress updates.
-            properties:
-              availableUpdates:
-                description: availableUpdates contains updates recommended for this
-                  cluster. Updates which appear in conditionalUpdates but not in availableUpdates
-                  may expose this cluster to known issues. This list may be empty
-                  if no updates are recommended, if the update service is unavailable,
-                  or if an invalid channel has been specified.
-                items:
-                  description: Release represents an OpenShift release image and associated
-                    metadata.
-                  properties:
-                    channels:
-                      description: channels is the set of Cincinnati channels to which
-                        the release currently belongs.
-                      items:
-                        type: string
-                      type: array
-                      x-kubernetes-list-type: set
-                    image:
-                      description: image is a container image location that contains
-                        the update. When this field is part of spec, image is optional
-                        if version is specified and the availableUpdates field contains
-                        a matching version.
-                      type: string
-                    url:
-                      description: url contains information about this release. This
-                        URL is set by the 'url' metadata property on a release or
-                        the metadata returned by the update API and should be displayed
-                        as a link in user interfaces. The URL field may not be set
-                        for test or nightly releases.
-                      type: string
-                    version:
-                      description: version is a semantic version identifying the update
-                        version. When this field is part of spec, version is optional
-                        if image is specified.
-                      type: string
-                  type: object
-                nullable: true
-                type: array
-                x-kubernetes-list-type: atomic
-              capabilities:
-                description: capabilities describes the state of optional, core cluster
-                  components.
-                properties:
-                  enabledCapabilities:
-                    description: enabledCapabilities lists all the capabilities that
-                      are currently managed.
-                    items:
-                      description: ClusterVersionCapability enumerates optional, core
-                        cluster components.
-                      enum:
-                      - openshift-samples
-                      - baremetal
-                      - marketplace
-                      - Console
-                      - Insights
-                      - Storage
-                      - CSISnapshot
-                      - NodeTuning
-                      - MachineAPI
-                      - Build
-                      - DeploymentConfig
-                      - ImageRegistry
-                      - OperatorLifecycleManager
-                      - CloudCredential
-                      - Ingress
-                      - CloudControllerManager
-                      type: string
-                    type: array
-                    x-kubernetes-list-type: atomic
-                  knownCapabilities:
-                    description: knownCapabilities lists all the capabilities known
-                      to the current cluster.
-                    items:
-                      description: ClusterVersionCapability enumerates optional, core
-                        cluster components.
-                      enum:
-                      - openshift-samples
-                      - baremetal
-                      - marketplace
-                      - Console
-                      - Insights
-                      - Storage
-                      - CSISnapshot
-                      - NodeTuning
-                      - MachineAPI
-                      - Build
-                      - DeploymentConfig
-                      - ImageRegistry
-                      - OperatorLifecycleManager
-                      - CloudCredential
-                      - Ingress
-                      - CloudControllerManager
-                      type: string
-                    type: array
-                    x-kubernetes-list-type: atomic
-                type: object
-              conditionalUpdates:
-                description: conditionalUpdates contains the list of updates that
-                  may be recommended for this cluster if it meets specific required
-                  conditions. Consumers interested in the set of updates that are
-                  actually recommended for this cluster should use availableUpdates.
-                  This list may be empty if no updates are recommended, if the update
-                  service is unavailable, or if an empty or invalid channel has been
-                  specified.
-                items:
-                  description: ConditionalUpdate represents an update which is recommended
-                    to some clusters on the version the current cluster is reconciling,
-                    but which may not be recommended for the current cluster.
-                  properties:
-                    conditions:
-                      description: 'conditions represents the observations of the
-                        conditional update''s current status. Known types are: * Recommended,
-                        for whether the update is recommended for the current cluster.'
-                      items:
-                        description: "Condition contains details for one aspect of
-                          the current state of this API Resource. --- This struct
-                          is intended for direct use as an array at the field path
-                          .status.conditions.  For example, \n type FooStatus struct{
-                          // Represents the observations of a foo's current state.
-                          // Known .status.conditions.type are: \"Available\", \"Progressing\",
-                          and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
-                          // +listType=map // +listMapKey=type Conditions []metav1.Condition
-                          `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
-                          protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields
-                          }"
-                        properties:
-                          lastTransitionTime:
-                            description: lastTransitionTime is the last time the condition
-                              transitioned from one status to another. This should
-                              be when the underlying condition changed.  If that is
-                              not known, then using the time when the API field changed
-                              is acceptable.
-                            format: date-time
-                            type: string
-                          message:
-                            description: message is a human readable message indicating
-                              details about the transition. This may be an empty string.
-                            maxLength: 32768
-                            type: string
-                          observedGeneration:
-                            description: observedGeneration represents the .metadata.generation
-                              that the condition was set based upon. For instance,
-                              if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration
-                              is 9, the condition is out of date with respect to the
-                              current state of the instance.
-                            format: int64
-                            minimum: 0
-                            type: integer
-                          reason:
-                            description: reason contains a programmatic identifier
-                              indicating the reason for the condition's last transition.
-                              Producers of specific condition types may define expected
-                              values and meanings for this field, and whether the
-                              values are considered a guaranteed API. The value should
-                              be a CamelCase string. This field may not be empty.
-                            maxLength: 1024
-                            minLength: 1
-                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
-                            type: string
-                          status:
-                            description: status of the condition, one of True, False,
-                              Unknown.
-                            enum:
-                            - "True"
-                            - "False"
-                            - Unknown
-                            type: string
-                          type:
-                            description: type of condition in CamelCase or in foo.example.com/CamelCase.
-                              --- Many .condition.type values are consistent across
-                              resources like Available, but because arbitrary conditions
-                              can be useful (see .node.status.conditions), the ability
-                              to deconflict is important. The regex it matches is
-                              (dns1123SubdomainFmt/)?(qualifiedNameFmt)
-                            maxLength: 316
-                            pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
-                            type: string
-                        required:
-                        - lastTransitionTime
-                        - message
-                        - reason
-                        - status
-                        - type
-                        type: object
-                      type: array
-                      x-kubernetes-list-map-keys:
-                      - type
-                      x-kubernetes-list-type: map
-                    release:
-                      description: release is the target of the update.
-                      properties:
-                        channels:
-                          description: channels is the set of Cincinnati channels
-                            to which the release currently belongs.
-                          items:
-                            type: string
-                          type: array
-                          x-kubernetes-list-type: set
-                        image:
-                          description: image is a container image location that contains
-                            the update. When this field is part of spec, image is
-                            optional if version is specified and the availableUpdates
-                            field contains a matching version.
-                          type: string
-                        url:
-                          description: url contains information about this release.
-                            This URL is set by the 'url' metadata property on a release
-                            or the metadata returned by the update API and should
-                            be displayed as a link in user interfaces. The URL field
-                            may not be set for test or nightly releases.
-                          type: string
-                        version:
-                          description: version is a semantic version identifying the
-                            update version. When this field is part of spec, version
-                            is optional if image is specified.
-                          type: string
-                      type: object
-                    risks:
-                      description: risks represents the range of issues associated
-                        with updating to the target release. The cluster-version operator
-                        will evaluate all entries, and only recommend the update if
-                        there is at least one entry and all entries recommend the
-                        update.
-                      items:
-                        description: ConditionalUpdateRisk represents a reason and
-                          cluster-state for not recommending a conditional update.
-                        properties:
-                          matchingRules:
-                            description: matchingRules is a slice of conditions for
-                              deciding which clusters match the risk and which do
-                              not. The slice is ordered by decreasing precedence.
-                              The cluster-version operator will walk the slice in
-                              order, and stop after the first it can successfully
-                              evaluate. If no condition can be successfully evaluated,
-                              the update will not be recommended.
-                            items:
-                              description: ClusterCondition is a union of typed cluster
-                                conditions.  The 'type' property determines which
-                                of the type-specific properties are relevant. When
-                                evaluated on a cluster, the condition may match, not
-                                match, or fail to evaluate.
-                              properties:
-                                promql:
-                                  description: promQL represents a cluster condition
-                                    based on PromQL.
-                                  properties:
-                                    promql:
-                                      description: PromQL is a PromQL query classifying
-                                        clusters. This query query should return a
-                                        1 in the match case and a 0 in the does-not-match
-                                        case. Queries which return no time series,
-                                        or which return values besides 0 or 1, are
-                                        evaluation failures.
-                                      type: string
-                                  required:
-                                  - promql
-                                  type: object
-                                type:
-                                  description: type represents the cluster-condition
-                                    type. This defines the members and semantics of
-                                    any additional properties.
-                                  enum:
-                                  - Always
-                                  - PromQL
-                                  type: string
-                              required:
-                              - type
-                              type: object
-                            minItems: 1
-                            type: array
-                            x-kubernetes-list-type: atomic
-                          message:
-                            description: message provides additional information about
-                              the risk of updating, in the event that matchingRules
-                              match the cluster state. This is only to be consumed
-                              by humans. It may contain Line Feed characters (U+000A),
-                              which should be rendered as new lines.
-                            minLength: 1
-                            type: string
-                          name:
-                            description: name is the CamelCase reason for not recommending
-                              a conditional update, in the event that matchingRules
-                              match the cluster state.
-                            minLength: 1
-                            type: string
-                          url:
-                            description: url contains information about this risk.
-                            format: uri
-                            minLength: 1
-                            type: string
-                        required:
-                        - matchingRules
-                        - message
-                        - name
-                        - url
-                        type: object
-                      minItems: 1
-                      type: array
-                      x-kubernetes-list-map-keys:
-                      - name
-                      x-kubernetes-list-type: map
-                  required:
-                  - release
-                  - risks
-                  type: object
-                type: array
-                x-kubernetes-list-type: atomic
-              conditions:
-                description: conditions provides information about the cluster version.
-                  The condition "Available" is set to true if the desiredUpdate has
-                  been reached. The condition "Progressing" is set to true if an update
-                  is being applied. The condition "Degraded" is set to true if an
-                  update is currently blocked by a temporary or permanent error. Conditions
-                  are only valid for the current desiredUpdate when metadata.generation
-                  is equal to status.generation.
-                items:
-                  description: ClusterOperatorStatusCondition represents the state
-                    of the operator's managed and monitored components.
-                  properties:
-                    lastTransitionTime:
-                      description: lastTransitionTime is the time of the last update
-                        to the current status property.
-                      format: date-time
-                      type: string
-                    message:
-                      description: message provides additional information about the
-                        current condition. This is only to be consumed by humans.  It
-                        may contain Line Feed characters (U+000A), which should be
-                        rendered as new lines.
-                      type: string
-                    reason:
-                      description: reason is the CamelCase reason for the condition's
-                        current status.
-                      type: string
-                    status:
-                      description: status of the condition, one of True, False, Unknown.
-                      type: string
-                    type:
-                      description: type specifies the aspect reported by this condition.
-                      type: string
-                  required:
-                  - lastTransitionTime
-                  - status
-                  - type
-                  type: object
-                type: array
-                x-kubernetes-list-map-keys:
-                - type
-                x-kubernetes-list-type: map
-              desired:
-                description: desired is the version that the cluster is reconciling
-                  towards. If the cluster is not yet fully initialized desired will
-                  be set with the information available, which may be an image or
-                  a tag.
-                properties:
-                  channels:
-                    description: channels is the set of Cincinnati channels to which
-                      the release currently belongs.
-                    items:
-                      type: string
-                    type: array
-                    x-kubernetes-list-type: set
-                  image:
-                    description: image is a container image location that contains
-                      the update. When this field is part of spec, image is optional
-                      if version is specified and the availableUpdates field contains
-                      a matching version.
-                    type: string
-                  url:
-                    description: url contains information about this release. This
-                      URL is set by the 'url' metadata property on a release or the
-                      metadata returned by the update API and should be displayed
-                      as a link in user interfaces. The URL field may not be set for
-                      test or nightly releases.
-                    type: string
-                  version:
-                    description: version is a semantic version identifying the update
-                      version. When this field is part of spec, version is optional
-                      if image is specified.
-                    type: string
-                type: object
-              history:
-                description: history contains a list of the most recent versions applied
-                  to the cluster. This value may be empty during cluster startup,
-                  and then will be updated when a new update is being applied. The
-                  newest update is first in the list and it is ordered by recency.
-                  Updates in the history have state Completed if the rollout completed
-                  - if an update was failing or halfway applied the state will be
-                  Partial. Only a limited amount of update history is preserved.
-                items:
-                  description: UpdateHistory is a single attempted update to the cluster.
-                  properties:
-                    acceptedRisks:
-                      description: acceptedRisks records risks which were accepted
-                        to initiate the update. For example, it may menition an Upgradeable=False
-                        or missing signature that was overriden via desiredUpdate.force,
-                        or an update that was initiated despite not being in the availableUpdates
-                        set of recommended update targets.
-                      type: string
-                    completionTime:
-                      description: completionTime, if set, is when the update was
-                        fully applied. The update that is currently being applied
-                        will have a null completion time. Completion time will always
-                        be set for entries that are not the current update (usually
-                        to the started time of the next update).
-                      format: date-time
-                      nullable: true
-                      type: string
-                    image:
-                      description: image is a container image location that contains
-                        the update. This value is always populated.
-                      type: string
-                    startedTime:
-                      description: startedTime is the time at which the update was
-                        started.
-                      format: date-time
-                      type: string
-                    state:
-                      description: state reflects whether the update was fully applied.
-                        The Partial state indicates the update is not fully applied,
-                        while the Completed state indicates the update was successfully
-                        rolled out at least once (all parts of the update successfully
-                        applied).
-                      type: string
-                    verified:
-                      description: verified indicates whether the provided update
-                        was properly verified before it was installed. If this is
-                        false the cluster may not be trusted. Verified does not cover
-                        upgradeable checks that depend on the cluster state at the
-                        time when the update target was accepted.
-                      type: boolean
-                    version:
-                      description: version is a semantic version identifying the update
-                        version. If the requested image does not define a version,
-                        or if a failure occurs retrieving the image, this value may
-                        be empty.
-                      type: string
-                  required:
-                  - completionTime
-                  - image
-                  - startedTime
-                  - state
-                  - verified
-                  type: object
-                type: array
-                x-kubernetes-list-type: atomic
-              observedGeneration:
-                description: observedGeneration reports which version of the spec
-                  is being synced. If this value is not equal to metadata.generation,
-                  then the desired and conditions fields may represent a previous
-                  version.
-                format: int64
-                type: integer
-              versionHash:
-                description: versionHash is a fingerprint of the content that the
-                  cluster will be updated with. It is used by the operator to avoid
-                  unnecessary work and is for internal use only.
-                type: string
-            required:
-            - availableUpdates
-            - desired
-            - observedGeneration
-            - versionHash
-            type: object
-        required:
-        - spec
-        type: object
-        x-kubernetes-validations:
-        - message: the `baremetal` capability requires the `MachineAPI` capability,
-            which is neither explicitly or implicitly enabled in this cluster, please
-            enable the `MachineAPI` capability
-          rule: 'has(self.spec.capabilities) && has(self.spec.capabilities.additionalEnabledCapabilities)
-            && self.spec.capabilities.baselineCapabilitySet == ''None'' && ''baremetal''
-            in self.spec.capabilities.additionalEnabledCapabilities ? ''MachineAPI''
-            in self.spec.capabilities.additionalEnabledCapabilities || (has(self.status)
-            && has(self.status.capabilities) && has(self.status.capabilities.enabledCapabilities)
-            && ''MachineAPI'' in self.status.capabilities.enabledCapabilities) : true'
-        - message: the `marketplace` capability requires the `OperatorLifecycleManager`
-            capability, which is neither explicitly or implicitly enabled in this
-            cluster, please enable the `OperatorLifecycleManager` capability
-          rule: 'has(self.spec.capabilities) && has(self.spec.capabilities.additionalEnabledCapabilities)
-            && self.spec.capabilities.baselineCapabilitySet == ''None'' && ''marketplace''
-            in self.spec.capabilities.additionalEnabledCapabilities ? ''OperatorLifecycleManager''
-            in self.spec.capabilities.additionalEnabledCapabilities || (has(self.status)
-            && has(self.status.capabilities) && has(self.status.capabilities.enabledCapabilities)
-            && ''OperatorLifecycleManager'' in self.status.capabilities.enabledCapabilities)
-            : true'
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion-TechPreviewNoUpgrade.crd.yaml
deleted file mode 100644
index fcaf456a..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion-TechPreviewNoUpgrade.crd.yaml
+++ /dev/null
@@ -1,780 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/495
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    release.openshift.io/feature-set: TechPreviewNoUpgrade
-  name: clusterversions.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: ClusterVersion
-    plural: clusterversions
-    singular: clusterversion
-  scope: Cluster
-  versions:
-  - additionalPrinterColumns:
-    - jsonPath: .status.history[?(@.state=="Completed")].version
-      name: Version
-      type: string
-    - jsonPath: .status.conditions[?(@.type=="Available")].status
-      name: Available
-      type: string
-    - jsonPath: .status.conditions[?(@.type=="Progressing")].status
-      name: Progressing
-      type: string
-    - jsonPath: .status.conditions[?(@.type=="Progressing")].lastTransitionTime
-      name: Since
-      type: date
-    - jsonPath: .status.conditions[?(@.type=="Progressing")].message
-      name: Status
-      type: string
-    name: v1
-    schema:
-      openAPIV3Schema:
-        description: "ClusterVersion is the configuration for the ClusterVersionOperator.
-          This is where parameters related to automatic updates can be set. \n Compatibility
-          level 1: Stable within a major release for a minimum of 12 months or 3 minor
-          releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec is the desired state of the cluster version - the operator
-              will work to ensure that the desired version is applied to the cluster.
-            properties:
-              capabilities:
-                description: capabilities configures the installation of optional,
-                  core cluster components.  A null value here is identical to an empty
-                  object; see the child properties for default semantics.
-                properties:
-                  additionalEnabledCapabilities:
-                    description: additionalEnabledCapabilities extends the set of
-                      managed capabilities beyond the baseline defined in baselineCapabilitySet.  The
-                      default is an empty set.
-                    items:
-                      description: ClusterVersionCapability enumerates optional, core
-                        cluster components.
-                      enum:
-                      - openshift-samples
-                      - baremetal
-                      - marketplace
-                      - Console
-                      - Insights
-                      - Storage
-                      - CSISnapshot
-                      - NodeTuning
-                      - MachineAPI
-                      - Build
-                      - DeploymentConfig
-                      - ImageRegistry
-                      - OperatorLifecycleManager
-                      - CloudCredential
-                      - Ingress
-                      - CloudControllerManager
-                      type: string
-                    type: array
-                    x-kubernetes-list-type: atomic
-                  baselineCapabilitySet:
-                    description: baselineCapabilitySet selects an initial set of optional
-                      capabilities to enable, which can be extended via additionalEnabledCapabilities.  If
-                      unset, the cluster will choose a default, and the default may
-                      change over time. The current default is vCurrent.
-                    enum:
-                    - None
-                    - v4.11
-                    - v4.12
-                    - v4.13
-                    - v4.14
-                    - v4.15
-                    - v4.16
-                    - vCurrent
-                    type: string
-                type: object
-              channel:
-                description: channel is an identifier for explicitly requesting that
-                  a non-default set of updates be applied to this cluster. The default
-                  channel will be contain stable updates that are appropriate for
-                  production clusters.
-                type: string
-              clusterID:
-                description: clusterID uniquely identifies this cluster. This is expected
-                  to be an RFC4122 UUID value (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
-                  in hexadecimal values). This is a required field.
-                type: string
-              desiredUpdate:
-                description: "desiredUpdate is an optional field that indicates the
-                  desired value of the cluster version. Setting this value will trigger
-                  an upgrade (if the current version does not match the desired version).
-                  The set of recommended update values is listed as part of available
-                  updates in status, and setting values outside that range may cause
-                  the upgrade to fail. \n Some of the fields are inter-related with
-                  restrictions and meanings described here. 1. image is specified,
-                  version is specified, architecture is specified. API validation
-                  error. 2. image is specified, version is specified, architecture
-                  is not specified. You should not do this. version is silently ignored
-                  and image is used. 3. image is specified, version is not specified,
-                  architecture is specified. API validation error. 4. image is specified,
-                  version is not specified, architecture is not specified. image is
-                  used. 5. image is not specified, version is specified, architecture
-                  is specified. version and desired architecture are used to select
-                  an image. 6. image is not specified, version is specified, architecture
-                  is not specified. version and current architecture are used to select
-                  an image. 7. image is not specified, version is not specified, architecture
-                  is specified. API validation error. 8. image is not specified, version
-                  is not specified, architecture is not specified. API validation
-                  error. \n If an upgrade fails the operator will halt and report
-                  status about the failing component. Setting the desired update value
-                  back to the previous version will cause a rollback to be attempted.
-                  Not all rollbacks will succeed."
-                properties:
-                  architecture:
-                    description: architecture is an optional field that indicates
-                      the desired value of the cluster architecture. In this context
-                      cluster architecture means either a single architecture or a
-                      multi architecture. architecture can only be set to Multi thereby
-                      only allowing updates from single to multi architecture. If
-                      architecture is set, image cannot be set and version must be
-                      set. Valid values are 'Multi' and empty.
-                    enum:
-                    - Multi
-                    - ""
-                    type: string
-                  force:
-                    description: force allows an administrator to update to an image
-                      that has failed verification or upgradeable checks. This option
-                      should only be used when the authenticity of the provided image
-                      has been verified out of band because the provided image will
-                      run with full administrative access to the cluster. Do not use
-                      this flag with images that comes from unknown or potentially
-                      malicious sources.
-                    type: boolean
-                  image:
-                    description: image is a container image location that contains
-                      the update. image should be used when the desired version does
-                      not exist in availableUpdates or history. When image is set,
-                      version is ignored. When image is set, version should be empty.
-                      When image is set, architecture cannot be specified.
-                    type: string
-                  version:
-                    description: version is a semantic version identifying the update
-                      version. version is ignored if image is specified and required
-                      if architecture is specified.
-                    type: string
-                type: object
-                x-kubernetes-validations:
-                - message: cannot set both Architecture and Image
-                  rule: 'has(self.architecture) && has(self.image) ? (self.architecture
-                    == '''' || self.image == '''') : true'
-                - message: Version must be set if Architecture is set
-                  rule: 'has(self.architecture) && self.architecture != '''' ? self.version
-                    != '''' : true'
-              overrides:
-                description: overrides is list of overides for components that are
-                  managed by cluster version operator. Marking a component unmanaged
-                  will prevent the operator from creating or updating the object.
-                items:
-                  description: ComponentOverride allows overriding cluster version
-                    operator's behavior for a component.
-                  properties:
-                    group:
-                      description: group identifies the API group that the kind is
-                        in.
-                      type: string
-                    kind:
-                      description: kind indentifies which object to override.
-                      type: string
-                    name:
-                      description: name is the component's name.
-                      type: string
-                    namespace:
-                      description: namespace is the component's namespace. If the
-                        resource is cluster scoped, the namespace should be empty.
-                      type: string
-                    unmanaged:
-                      description: 'unmanaged controls if cluster version operator
-                        should stop managing the resources in this cluster. Default:
-                        false'
-                      type: boolean
-                  required:
-                  - group
-                  - kind
-                  - name
-                  - namespace
-                  - unmanaged
-                  type: object
-                type: array
-                x-kubernetes-list-map-keys:
-                - kind
-                - group
-                - namespace
-                - name
-                x-kubernetes-list-type: map
-              signatureStores:
-                description: "signatureStores contains the upstream URIs to verify
-                  release signatures and optional reference to a config map by name
-                  containing the PEM-encoded CA bundle. \n By default, CVO will use
-                  existing signature stores if this property is empty. The CVO will
-                  check the release signatures in the local ConfigMaps first. It will
-                  search for a valid signature in these stores in parallel only when
-                  local ConfigMaps did not include a valid signature. Validation will
-                  fail if none of the signature stores reply with valid signature
-                  before timeout. Setting signatureStores will replace the default
-                  signature stores with custom signature stores. Default stores can
-                  be used with custom signature stores by adding them manually. \n
-                  A maximum of 32 signature stores may be configured."
-                items:
-                  description: SignatureStore represents the URL of custom Signature
-                    Store
-                  properties:
-                    ca:
-                      description: ca is an optional reference to a config map by
-                        name containing the PEM-encoded CA bundle. It is used as a
-                        trust anchor to validate the TLS certificate presented by
-                        the remote server. The key "ca.crt" is used to locate the
-                        data. If specified and the config map or expected key is not
-                        found, the signature store is not honored. If the specified
-                        ca data is not valid, the signature store is not honored.
-                        If empty, we fall back to the CA configured via Proxy, which
-                        is appended to the default system roots. The namespace for
-                        this config map is openshift-config.
-                      properties:
-                        name:
-                          description: name is the metadata.name of the referenced
-                            config map
-                          type: string
-                      required:
-                      - name
-                      type: object
-                    url:
-                      description: url contains the upstream custom signature store
-                        URL. url should be a valid absolute http/https URI of an upstream
-                        signature store as per rfc1738. This must be provided and
-                        cannot be empty.
-                      type: string
-                      x-kubernetes-validations:
-                      - message: url must be a valid absolute URL
-                        rule: isURL(self)
-                  required:
-                  - url
-                  type: object
-                maxItems: 32
-                type: array
-                x-kubernetes-list-map-keys:
-                - url
-                x-kubernetes-list-type: map
-              upstream:
-                description: upstream may be used to specify the preferred update
-                  server. By default it will use the appropriate update server for
-                  the cluster and region.
-                type: string
-            required:
-            - clusterID
-            type: object
-          status:
-            description: status contains information about the available updates and
-              any in-progress updates.
-            properties:
-              availableUpdates:
-                description: availableUpdates contains updates recommended for this
-                  cluster. Updates which appear in conditionalUpdates but not in availableUpdates
-                  may expose this cluster to known issues. This list may be empty
-                  if no updates are recommended, if the update service is unavailable,
-                  or if an invalid channel has been specified.
-                items:
-                  description: Release represents an OpenShift release image and associated
-                    metadata.
-                  properties:
-                    channels:
-                      description: channels is the set of Cincinnati channels to which
-                        the release currently belongs.
-                      items:
-                        type: string
-                      type: array
-                      x-kubernetes-list-type: set
-                    image:
-                      description: image is a container image location that contains
-                        the update. When this field is part of spec, image is optional
-                        if version is specified and the availableUpdates field contains
-                        a matching version.
-                      type: string
-                    url:
-                      description: url contains information about this release. This
-                        URL is set by the 'url' metadata property on a release or
-                        the metadata returned by the update API and should be displayed
-                        as a link in user interfaces. The URL field may not be set
-                        for test or nightly releases.
-                      type: string
-                    version:
-                      description: version is a semantic version identifying the update
-                        version. When this field is part of spec, version is optional
-                        if image is specified.
-                      type: string
-                  type: object
-                nullable: true
-                type: array
-                x-kubernetes-list-type: atomic
-              capabilities:
-                description: capabilities describes the state of optional, core cluster
-                  components.
-                properties:
-                  enabledCapabilities:
-                    description: enabledCapabilities lists all the capabilities that
-                      are currently managed.
-                    items:
-                      description: ClusterVersionCapability enumerates optional, core
-                        cluster components.
-                      enum:
-                      - openshift-samples
-                      - baremetal
-                      - marketplace
-                      - Console
-                      - Insights
-                      - Storage
-                      - CSISnapshot
-                      - NodeTuning
-                      - MachineAPI
-                      - Build
-                      - DeploymentConfig
-                      - ImageRegistry
-                      - OperatorLifecycleManager
-                      - CloudCredential
-                      - Ingress
-                      - CloudControllerManager
-                      type: string
-                    type: array
-                    x-kubernetes-list-type: atomic
-                  knownCapabilities:
-                    description: knownCapabilities lists all the capabilities known
-                      to the current cluster.
-                    items:
-                      description: ClusterVersionCapability enumerates optional, core
-                        cluster components.
-                      enum:
-                      - openshift-samples
-                      - baremetal
-                      - marketplace
-                      - Console
-                      - Insights
-                      - Storage
-                      - CSISnapshot
-                      - NodeTuning
-                      - MachineAPI
-                      - Build
-                      - DeploymentConfig
-                      - ImageRegistry
-                      - OperatorLifecycleManager
-                      - CloudCredential
-                      - Ingress
-                      - CloudControllerManager
-                      type: string
-                    type: array
-                    x-kubernetes-list-type: atomic
-                type: object
-              conditionalUpdates:
-                description: conditionalUpdates contains the list of updates that
-                  may be recommended for this cluster if it meets specific required
-                  conditions. Consumers interested in the set of updates that are
-                  actually recommended for this cluster should use availableUpdates.
-                  This list may be empty if no updates are recommended, if the update
-                  service is unavailable, or if an empty or invalid channel has been
-                  specified.
-                items:
-                  description: ConditionalUpdate represents an update which is recommended
-                    to some clusters on the version the current cluster is reconciling,
-                    but which may not be recommended for the current cluster.
-                  properties:
-                    conditions:
-                      description: 'conditions represents the observations of the
-                        conditional update''s current status. Known types are: * Recommended,
-                        for whether the update is recommended for the current cluster.'
-                      items:
-                        description: "Condition contains details for one aspect of
-                          the current state of this API Resource. --- This struct
-                          is intended for direct use as an array at the field path
-                          .status.conditions.  For example, \n type FooStatus struct{
-                          // Represents the observations of a foo's current state.
-                          // Known .status.conditions.type are: \"Available\", \"Progressing\",
-                          and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
-                          // +listType=map // +listMapKey=type Conditions []metav1.Condition
-                          `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
-                          protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields
-                          }"
-                        properties:
-                          lastTransitionTime:
-                            description: lastTransitionTime is the last time the condition
-                              transitioned from one status to another. This should
-                              be when the underlying condition changed.  If that is
-                              not known, then using the time when the API field changed
-                              is acceptable.
-                            format: date-time
-                            type: string
-                          message:
-                            description: message is a human readable message indicating
-                              details about the transition. This may be an empty string.
-                            maxLength: 32768
-                            type: string
-                          observedGeneration:
-                            description: observedGeneration represents the .metadata.generation
-                              that the condition was set based upon. For instance,
-                              if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration
-                              is 9, the condition is out of date with respect to the
-                              current state of the instance.
-                            format: int64
-                            minimum: 0
-                            type: integer
-                          reason:
-                            description: reason contains a programmatic identifier
-                              indicating the reason for the condition's last transition.
-                              Producers of specific condition types may define expected
-                              values and meanings for this field, and whether the
-                              values are considered a guaranteed API. The value should
-                              be a CamelCase string. This field may not be empty.
-                            maxLength: 1024
-                            minLength: 1
-                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
-                            type: string
-                          status:
-                            description: status of the condition, one of True, False,
-                              Unknown.
-                            enum:
-                            - "True"
-                            - "False"
-                            - Unknown
-                            type: string
-                          type:
-                            description: type of condition in CamelCase or in foo.example.com/CamelCase.
-                              --- Many .condition.type values are consistent across
-                              resources like Available, but because arbitrary conditions
-                              can be useful (see .node.status.conditions), the ability
-                              to deconflict is important. The regex it matches is
-                              (dns1123SubdomainFmt/)?(qualifiedNameFmt)
-                            maxLength: 316
-                            pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
-                            type: string
-                        required:
-                        - lastTransitionTime
-                        - message
-                        - reason
-                        - status
-                        - type
-                        type: object
-                      type: array
-                      x-kubernetes-list-map-keys:
-                      - type
-                      x-kubernetes-list-type: map
-                    release:
-                      description: release is the target of the update.
-                      properties:
-                        channels:
-                          description: channels is the set of Cincinnati channels
-                            to which the release currently belongs.
-                          items:
-                            type: string
-                          type: array
-                          x-kubernetes-list-type: set
-                        image:
-                          description: image is a container image location that contains
-                            the update. When this field is part of spec, image is
-                            optional if version is specified and the availableUpdates
-                            field contains a matching version.
-                          type: string
-                        url:
-                          description: url contains information about this release.
-                            This URL is set by the 'url' metadata property on a release
-                            or the metadata returned by the update API and should
-                            be displayed as a link in user interfaces. The URL field
-                            may not be set for test or nightly releases.
-                          type: string
-                        version:
-                          description: version is a semantic version identifying the
-                            update version. When this field is part of spec, version
-                            is optional if image is specified.
-                          type: string
-                      type: object
-                    risks:
-                      description: risks represents the range of issues associated
-                        with updating to the target release. The cluster-version operator
-                        will evaluate all entries, and only recommend the update if
-                        there is at least one entry and all entries recommend the
-                        update.
-                      items:
-                        description: ConditionalUpdateRisk represents a reason and
-                          cluster-state for not recommending a conditional update.
-                        properties:
-                          matchingRules:
-                            description: matchingRules is a slice of conditions for
-                              deciding which clusters match the risk and which do
-                              not. The slice is ordered by decreasing precedence.
-                              The cluster-version operator will walk the slice in
-                              order, and stop after the first it can successfully
-                              evaluate. If no condition can be successfully evaluated,
-                              the update will not be recommended.
-                            items:
-                              description: ClusterCondition is a union of typed cluster
-                                conditions.  The 'type' property determines which
-                                of the type-specific properties are relevant. When
-                                evaluated on a cluster, the condition may match, not
-                                match, or fail to evaluate.
-                              properties:
-                                promql:
-                                  description: promQL represents a cluster condition
-                                    based on PromQL.
-                                  properties:
-                                    promql:
-                                      description: PromQL is a PromQL query classifying
-                                        clusters. This query query should return a
-                                        1 in the match case and a 0 in the does-not-match
-                                        case. Queries which return no time series,
-                                        or which return values besides 0 or 1, are
-                                        evaluation failures.
-                                      type: string
-                                  required:
-                                  - promql
-                                  type: object
-                                type:
-                                  description: type represents the cluster-condition
-                                    type. This defines the members and semantics of
-                                    any additional properties.
-                                  enum:
-                                  - Always
-                                  - PromQL
-                                  type: string
-                              required:
-                              - type
-                              type: object
-                            minItems: 1
-                            type: array
-                            x-kubernetes-list-type: atomic
-                          message:
-                            description: message provides additional information about
-                              the risk of updating, in the event that matchingRules
-                              match the cluster state. This is only to be consumed
-                              by humans. It may contain Line Feed characters (U+000A),
-                              which should be rendered as new lines.
-                            minLength: 1
-                            type: string
-                          name:
-                            description: name is the CamelCase reason for not recommending
-                              a conditional update, in the event that matchingRules
-                              match the cluster state.
-                            minLength: 1
-                            type: string
-                          url:
-                            description: url contains information about this risk.
-                            format: uri
-                            minLength: 1
-                            type: string
-                        required:
-                        - matchingRules
-                        - message
-                        - name
-                        - url
-                        type: object
-                      minItems: 1
-                      type: array
-                      x-kubernetes-list-map-keys:
-                      - name
-                      x-kubernetes-list-type: map
-                  required:
-                  - release
-                  - risks
-                  type: object
-                type: array
-                x-kubernetes-list-type: atomic
-              conditions:
-                description: conditions provides information about the cluster version.
-                  The condition "Available" is set to true if the desiredUpdate has
-                  been reached. The condition "Progressing" is set to true if an update
-                  is being applied. The condition "Degraded" is set to true if an
-                  update is currently blocked by a temporary or permanent error. Conditions
-                  are only valid for the current desiredUpdate when metadata.generation
-                  is equal to status.generation.
-                items:
-                  description: ClusterOperatorStatusCondition represents the state
-                    of the operator's managed and monitored components.
-                  properties:
-                    lastTransitionTime:
-                      description: lastTransitionTime is the time of the last update
-                        to the current status property.
-                      format: date-time
-                      type: string
-                    message:
-                      description: message provides additional information about the
-                        current condition. This is only to be consumed by humans.  It
-                        may contain Line Feed characters (U+000A), which should be
-                        rendered as new lines.
-                      type: string
-                    reason:
-                      description: reason is the CamelCase reason for the condition's
-                        current status.
-                      type: string
-                    status:
-                      description: status of the condition, one of True, False, Unknown.
-                      type: string
-                    type:
-                      description: type specifies the aspect reported by this condition.
-                      type: string
-                  required:
-                  - lastTransitionTime
-                  - status
-                  - type
-                  type: object
-                type: array
-                x-kubernetes-list-map-keys:
-                - type
-                x-kubernetes-list-type: map
-              desired:
-                description: desired is the version that the cluster is reconciling
-                  towards. If the cluster is not yet fully initialized desired will
-                  be set with the information available, which may be an image or
-                  a tag.
-                properties:
-                  channels:
-                    description: channels is the set of Cincinnati channels to which
-                      the release currently belongs.
-                    items:
-                      type: string
-                    type: array
-                    x-kubernetes-list-type: set
-                  image:
-                    description: image is a container image location that contains
-                      the update. When this field is part of spec, image is optional
-                      if version is specified and the availableUpdates field contains
-                      a matching version.
-                    type: string
-                  url:
-                    description: url contains information about this release. This
-                      URL is set by the 'url' metadata property on a release or the
-                      metadata returned by the update API and should be displayed
-                      as a link in user interfaces. The URL field may not be set for
-                      test or nightly releases.
-                    type: string
-                  version:
-                    description: version is a semantic version identifying the update
-                      version. When this field is part of spec, version is optional
-                      if image is specified.
-                    type: string
-                type: object
-              history:
-                description: history contains a list of the most recent versions applied
-                  to the cluster. This value may be empty during cluster startup,
-                  and then will be updated when a new update is being applied. The
-                  newest update is first in the list and it is ordered by recency.
-                  Updates in the history have state Completed if the rollout completed
-                  - if an update was failing or halfway applied the state will be
-                  Partial. Only a limited amount of update history is preserved.
-                items:
-                  description: UpdateHistory is a single attempted update to the cluster.
-                  properties:
-                    acceptedRisks:
-                      description: acceptedRisks records risks which were accepted
-                        to initiate the update. For example, it may menition an Upgradeable=False
-                        or missing signature that was overriden via desiredUpdate.force,
-                        or an update that was initiated despite not being in the availableUpdates
-                        set of recommended update targets.
-                      type: string
-                    completionTime:
-                      description: completionTime, if set, is when the update was
-                        fully applied. The update that is currently being applied
-                        will have a null completion time. Completion time will always
-                        be set for entries that are not the current update (usually
-                        to the started time of the next update).
-                      format: date-time
-                      nullable: true
-                      type: string
-                    image:
-                      description: image is a container image location that contains
-                        the update. This value is always populated.
-                      type: string
-                    startedTime:
-                      description: startedTime is the time at which the update was
-                        started.
-                      format: date-time
-                      type: string
-                    state:
-                      description: state reflects whether the update was fully applied.
-                        The Partial state indicates the update is not fully applied,
-                        while the Completed state indicates the update was successfully
-                        rolled out at least once (all parts of the update successfully
-                        applied).
-                      type: string
-                    verified:
-                      description: verified indicates whether the provided update
-                        was properly verified before it was installed. If this is
-                        false the cluster may not be trusted. Verified does not cover
-                        upgradeable checks that depend on the cluster state at the
-                        time when the update target was accepted.
-                      type: boolean
-                    version:
-                      description: version is a semantic version identifying the update
-                        version. If the requested image does not define a version,
-                        or if a failure occurs retrieving the image, this value may
-                        be empty.
-                      type: string
-                  required:
-                  - completionTime
-                  - image
-                  - startedTime
-                  - state
-                  - verified
-                  type: object
-                type: array
-                x-kubernetes-list-type: atomic
-              observedGeneration:
-                description: observedGeneration reports which version of the spec
-                  is being synced. If this value is not equal to metadata.generation,
-                  then the desired and conditions fields may represent a previous
-                  version.
-                format: int64
-                type: integer
-              versionHash:
-                description: versionHash is a fingerprint of the content that the
-                  cluster will be updated with. It is used by the operator to avoid
-                  unnecessary work and is for internal use only.
-                type: string
-            required:
-            - availableUpdates
-            - desired
-            - observedGeneration
-            - versionHash
-            type: object
-        required:
-        - spec
-        type: object
-        x-kubernetes-validations:
-        - message: the `baremetal` capability requires the `MachineAPI` capability,
-            which is neither explicitly or implicitly enabled in this cluster, please
-            enable the `MachineAPI` capability
-          rule: 'has(self.spec.capabilities) && has(self.spec.capabilities.additionalEnabledCapabilities)
-            && self.spec.capabilities.baselineCapabilitySet == ''None'' && ''baremetal''
-            in self.spec.capabilities.additionalEnabledCapabilities ? ''MachineAPI''
-            in self.spec.capabilities.additionalEnabledCapabilities || (has(self.status)
-            && has(self.status.capabilities) && has(self.status.capabilities.enabledCapabilities)
-            && ''MachineAPI'' in self.status.capabilities.enabledCapabilities) : true'
-        - message: the `marketplace` capability requires the `OperatorLifecycleManager`
-            capability, which is neither explicitly or implicitly enabled in this
-            cluster, please enable the `OperatorLifecycleManager` capability
-          rule: 'has(self.spec.capabilities) && has(self.spec.capabilities.additionalEnabledCapabilities)
-            && self.spec.capabilities.baselineCapabilitySet == ''None'' && ''marketplace''
-            in self.spec.capabilities.additionalEnabledCapabilities ? ''OperatorLifecycleManager''
-            in self.spec.capabilities.additionalEnabledCapabilities || (has(self.status)
-            && has(self.status.capabilities) && has(self.status.capabilities.enabledCapabilities)
-            && ''OperatorLifecycleManager'' in self.status.capabilities.enabledCapabilities)
-            : true'
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_03_config-operator_01_proxy.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_03_config-operator_01_proxy.crd.yaml
deleted file mode 100644
index b9cf439c..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_03_config-operator_01_proxy.crd.yaml
+++ /dev/null
@@ -1,106 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-  name: proxies.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: Proxy
-    listKind: ProxyList
-    plural: proxies
-    singular: proxy
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "Proxy holds cluster-wide information on how to configure default
-          proxies for the cluster. The canonical name is `cluster` \n Compatibility
-          level 1: Stable within a major release for a minimum of 12 months or 3 minor
-          releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: Spec holds user-settable values for the proxy configuration
-            properties:
-              httpProxy:
-                description: httpProxy is the URL of the proxy for HTTP requests.  Empty
-                  means unset and will not result in an env var.
-                type: string
-              httpsProxy:
-                description: httpsProxy is the URL of the proxy for HTTPS requests.  Empty
-                  means unset and will not result in an env var.
-                type: string
-              noProxy:
-                description: noProxy is a comma-separated list of hostnames and/or
-                  CIDRs and/or IPs for which the proxy should not be used. Empty means
-                  unset and will not result in an env var.
-                type: string
-              readinessEndpoints:
-                description: readinessEndpoints is a list of endpoints used to verify
-                  readiness of the proxy.
-                items:
-                  type: string
-                type: array
-              trustedCA:
-                description: "trustedCA is a reference to a ConfigMap containing a
-                  CA certificate bundle. The trustedCA field should only be consumed
-                  by a proxy validator. The validator is responsible for reading the
-                  certificate bundle from the required key \"ca-bundle.crt\", merging
-                  it with the system default trust bundle, and writing the merged
-                  trust bundle to a ConfigMap named \"trusted-ca-bundle\" in the \"openshift-config-managed\"
-                  namespace. Clients that expect to make proxy connections must use
-                  the trusted-ca-bundle for all HTTPS requests to the proxy, and may
-                  use the trusted-ca-bundle for non-proxy HTTPS requests as well.
-                  \n The namespace for the ConfigMap referenced by trustedCA is \"openshift-config\".
-                  Here is an example ConfigMap (in yaml): \n apiVersion: v1 kind:
-                  ConfigMap metadata: name: user-ca-bundle namespace: openshift-config
-                  data: ca-bundle.crt: | -----BEGIN CERTIFICATE----- Custom CA certificate
-                  bundle. -----END CERTIFICATE-----"
-                properties:
-                  name:
-                    description: name is the metadata.name of the referenced config
-                      map
-                    type: string
-                required:
-                - name
-                type: object
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            properties:
-              httpProxy:
-                description: httpProxy is the URL of the proxy for HTTP requests.
-                type: string
-              httpsProxy:
-                description: httpsProxy is the URL of the proxy for HTTPS requests.
-                type: string
-              noProxy:
-                description: noProxy is a comma-separated list of hostnames and/or
-                  CIDRs for which the proxy should not be used.
-                type: string
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_03_marketplace-operator_01_operatorhub.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_03_marketplace-operator_01_operatorhub.crd.yaml
deleted file mode 100644
index cc42ea29..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_03_marketplace-operator_01_operatorhub.crd.yaml
+++ /dev/null
@@ -1,109 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    capability.openshift.io/name: marketplace
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-  name: operatorhubs.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: OperatorHub
-    listKind: OperatorHubList
-    plural: operatorhubs
-    singular: operatorhub
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "OperatorHub is the Schema for the operatorhubs API. It can be
-          used to change the state of the default hub sources for OperatorHub on the
-          cluster from enabled to disabled and vice versa. \n Compatibility level
-          1: Stable within a major release for a minimum of 12 months or 3 minor releases
-          (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: OperatorHubSpec defines the desired state of OperatorHub
-            properties:
-              disableAllDefaultSources:
-                description: disableAllDefaultSources allows you to disable all the
-                  default hub sources. If this is true, a specific entry in sources
-                  can be used to enable a default source. If this is false, a specific
-                  entry in sources can be used to disable or enable a default source.
-                type: boolean
-              sources:
-                description: sources is the list of default hub sources and their
-                  configuration. If the list is empty, it implies that the default
-                  hub sources are enabled on the cluster unless disableAllDefaultSources
-                  is true. If disableAllDefaultSources is true and sources is not
-                  empty, the configuration present in sources will take precedence.
-                  The list of default hub sources and their current state will always
-                  be reflected in the status block.
-                items:
-                  description: HubSource is used to specify the hub source and its
-                    configuration
-                  properties:
-                    disabled:
-                      description: disabled is used to disable a default hub source
-                        on cluster
-                      type: boolean
-                    name:
-                      description: name is the name of one of the default hub sources
-                      maxLength: 253
-                      minLength: 1
-                      type: string
-                  type: object
-                type: array
-            type: object
-          status:
-            description: OperatorHubStatus defines the observed state of OperatorHub.
-              The current state of the default hub sources will always be reflected
-              here.
-            properties:
-              sources:
-                description: sources encapsulates the result of applying the configuration
-                  for each hub source
-                items:
-                  description: HubSourceStatus is used to reflect the current state
-                    of applying the configuration to a default source
-                  properties:
-                    disabled:
-                      description: disabled is used to disable a default hub source
-                        on cluster
-                      type: boolean
-                    message:
-                      description: message provides more information regarding failures
-                      type: string
-                    name:
-                      description: name is the name of one of the default hub sources
-                      maxLength: 253
-                      minLength: 1
-                      type: string
-                    status:
-                      description: status indicates success or failure in applying
-                        the configuration
-                      type: string
-                  type: object
-                type: array
-            type: object
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_apiserver-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_apiserver-CustomNoUpgrade.crd.yaml
deleted file mode 100644
index 127d8f90..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_apiserver-CustomNoUpgrade.crd.yaml
+++ /dev/null
@@ -1,312 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    release.openshift.io/feature-set: CustomNoUpgrade
-  name: apiservers.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: APIServer
-    listKind: APIServerList
-    plural: apiservers
-    singular: apiserver
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "APIServer holds configuration (like serving certificates, client
-          CA and CORS domains) shared by all API servers in the system, among them
-          especially kube-apiserver and openshift-apiserver. The canonical name of
-          an instance is 'cluster'. \n Compatibility level 1: Stable within a major
-          release for a minimum of 12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              additionalCORSAllowedOrigins:
-                description: additionalCORSAllowedOrigins lists additional, user-defined
-                  regular expressions describing hosts for which the API server allows
-                  access using the CORS headers. This may be needed to access the
-                  API and the integrated OAuth server from JavaScript applications.
-                  The values are regular expressions that correspond to the Golang
-                  regular expression language.
-                items:
-                  type: string
-                type: array
-              audit:
-                default:
-                  profile: Default
-                description: audit specifies the settings for audit configuration
-                  to be applied to all OpenShift-provided API servers in the cluster.
-                properties:
-                  customRules:
-                    description: customRules specify profiles per group. These profile
-                      take precedence over the top-level profile field if they apply.
-                      They are evaluation from top to bottom and the first one that
-                      matches, applies.
-                    items:
-                      description: AuditCustomRule describes a custom rule for an
-                        audit profile that takes precedence over the top-level profile.
-                      properties:
-                        group:
-                          description: group is a name of group a request user must
-                            be member of in order to this profile to apply.
-                          minLength: 1
-                          type: string
-                        profile:
-                          description: "profile specifies the name of the desired
-                            audit policy configuration to be deployed to all OpenShift-provided
-                            API servers in the cluster. \n The following profiles
-                            are provided: - Default: the existing default policy.
-                            - WriteRequestBodies: like 'Default', but logs request
-                            and response HTTP payloads for write requests (create,
-                            update, patch). - AllRequestBodies: like 'WriteRequestBodies',
-                            but also logs request and response HTTP payloads for read
-                            requests (get, list). - None: no requests are logged at
-                            all, not even oauthaccesstokens and oauthauthorizetokens.
-                            \n If unset, the 'Default' profile is used as the default."
-                          enum:
-                          - Default
-                          - WriteRequestBodies
-                          - AllRequestBodies
-                          - None
-                          type: string
-                      required:
-                      - group
-                      - profile
-                      type: object
-                    type: array
-                    x-kubernetes-list-map-keys:
-                    - group
-                    x-kubernetes-list-type: map
-                  profile:
-                    default: Default
-                    description: "profile specifies the name of the desired top-level
-                      audit profile to be applied to all requests sent to any of the
-                      OpenShift-provided API servers in the cluster (kube-apiserver,
-                      openshift-apiserver and oauth-apiserver), with the exception
-                      of those requests that match one or more of the customRules.
-                      \n The following profiles are provided: - Default: default policy
-                      which means MetaData level logging with the exception of events
-                      (not logged at all), oauthaccesstokens and oauthauthorizetokens
-                      (both logged at RequestBody level). - WriteRequestBodies: like
-                      'Default', but logs request and response HTTP payloads for write
-                      requests (create, update, patch). - AllRequestBodies: like 'WriteRequestBodies',
-                      but also logs request and response HTTP payloads for read requests
-                      (get, list). - None: no requests are logged at all, not even
-                      oauthaccesstokens and oauthauthorizetokens. \n Warning: It is
-                      not recommended to disable audit logging by using the `None`
-                      profile unless you are fully aware of the risks of not logging
-                      data that can be beneficial when troubleshooting issues. If
-                      you disable audit logging and a support situation arises, you
-                      might need to enable audit logging and reproduce the issue in
-                      order to troubleshoot properly. \n If unset, the 'Default' profile
-                      is used as the default."
-                    enum:
-                    - Default
-                    - WriteRequestBodies
-                    - AllRequestBodies
-                    - None
-                    type: string
-                type: object
-              clientCA:
-                description: 'clientCA references a ConfigMap containing a certificate
-                  bundle for the signers that will be recognized for incoming client
-                  certificates in addition to the operator managed signers. If this
-                  is empty, then only operator managed signers are valid. You usually
-                  only have to set this if you have your own PKI you wish to honor
-                  client certificates from. The ConfigMap must exist in the openshift-config
-                  namespace and contain the following required fields: - ConfigMap.Data["ca-bundle.crt"]
-                  - CA bundle.'
-                properties:
-                  name:
-                    description: name is the metadata.name of the referenced config
-                      map
-                    type: string
-                required:
-                - name
-                type: object
-              encryption:
-                description: encryption allows the configuration of encryption of
-                  resources at the datastore layer.
-                properties:
-                  type:
-                    description: "type defines what encryption type should be used
-                      to encrypt resources at the datastore layer. When this field
-                      is unset (i.e. when it is set to the empty string), identity
-                      is implied. The behavior of unset can and will change over time.
-                      \ Even if encryption is enabled by default, the meaning of unset
-                      may change to a different encryption type based on changes in
-                      best practices. \n When encryption is enabled, all sensitive
-                      resources shipped with the platform are encrypted. This list
-                      of sensitive resources can and will change over time.  The current
-                      authoritative list is: \n 1. secrets 2. configmaps 3. routes.route.openshift.io
-                      4. oauthaccesstokens.oauth.openshift.io 5. oauthauthorizetokens.oauth.openshift.io"
-                    enum:
-                    - ""
-                    - identity
-                    - aescbc
-                    - aesgcm
-                    type: string
-                type: object
-              servingCerts:
-                description: servingCert is the TLS cert info for serving secure traffic.
-                  If not specified, operator managed certificates will be used for
-                  serving secure traffic.
-                properties:
-                  namedCertificates:
-                    description: namedCertificates references secrets containing the
-                      TLS cert info for serving secure traffic to specific hostnames.
-                      If no named certificates are provided, or no named certificates
-                      match the server name as understood by a client, the defaultServingCertificate
-                      will be used.
-                    items:
-                      description: APIServerNamedServingCert maps a server DNS name,
-                        as understood by a client, to a certificate.
-                      properties:
-                        names:
-                          description: names is a optional list of explicit DNS names
-                            (leading wildcards allowed) that should use this certificate
-                            to serve secure traffic. If no names are provided, the
-                            implicit names will be extracted from the certificates.
-                            Exact names trump over wildcard names. Explicit names
-                            defined here trump over extracted implicit names.
-                          items:
-                            type: string
-                          type: array
-                        servingCertificate:
-                          description: 'servingCertificate references a kubernetes.io/tls
-                            type secret containing the TLS cert info for serving secure
-                            traffic. The secret must exist in the openshift-config
-                            namespace and contain the following required fields: -
-                            Secret.Data["tls.key"] - TLS private key. - Secret.Data["tls.crt"]
-                            - TLS certificate.'
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                secret
-                              type: string
-                          required:
-                          - name
-                          type: object
-                      type: object
-                    type: array
-                type: object
-              tlsSecurityProfile:
-                description: "tlsSecurityProfile specifies settings for TLS connections
-                  for externally exposed servers. \n If unset, a default (which may
-                  change between releases) is chosen. Note that only Old, Intermediate
-                  and Custom profiles are currently supported, and the maximum available
-                  minTLSVersion is VersionTLS12."
-                properties:
-                  custom:
-                    description: "custom is a user-defined TLS security profile. Be
-                      extremely careful using a custom profile as invalid configurations
-                      can be catastrophic. An example custom profile looks like this:
-                      \n ciphers: - ECDHE-ECDSA-CHACHA20-POLY1305 - ECDHE-RSA-CHACHA20-POLY1305
-                      - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES128-GCM-SHA256
-                      minTLSVersion: VersionTLS11"
-                    nullable: true
-                    properties:
-                      ciphers:
-                        description: "ciphers is used to specify the cipher algorithms
-                          that are negotiated during the TLS handshake.  Operators
-                          may remove entries their operands do not support.  For example,
-                          to use DES-CBC3-SHA  (yaml): \n ciphers: - DES-CBC3-SHA"
-                        items:
-                          type: string
-                        type: array
-                      minTLSVersion:
-                        description: "minTLSVersion is used to specify the minimal
-                          version of the TLS protocol that is negotiated during the
-                          TLS handshake. For example, to use TLS versions 1.1, 1.2
-                          and 1.3 (yaml): \n minTLSVersion: VersionTLS11 \n NOTE:
-                          currently the highest minTLSVersion allowed is VersionTLS12"
-                        enum:
-                        - VersionTLS10
-                        - VersionTLS11
-                        - VersionTLS12
-                        - VersionTLS13
-                        type: string
-                    type: object
-                  intermediate:
-                    description: "intermediate is a TLS security profile based on:
-                      \n https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29
-                      \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256
-                      - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 - ECDHE-ECDSA-AES128-GCM-SHA256
-                      - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES256-GCM-SHA384
-                      - ECDHE-RSA-AES256-GCM-SHA384 - ECDHE-ECDSA-CHACHA20-POLY1305
-                      - ECDHE-RSA-CHACHA20-POLY1305 - DHE-RSA-AES128-GCM-SHA256 -
-                      DHE-RSA-AES256-GCM-SHA384 minTLSVersion: VersionTLS12"
-                    nullable: true
-                    type: object
-                  modern:
-                    description: "modern is a TLS security profile based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility
-                      \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256
-                      - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 minTLSVersion:
-                      VersionTLS13 \n NOTE: Currently unsupported."
-                    nullable: true
-                    type: object
-                  old:
-                    description: "old is a TLS security profile based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Old_backward_compatibility
-                      \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256
-                      - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 - ECDHE-ECDSA-AES128-GCM-SHA256
-                      - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES256-GCM-SHA384
-                      - ECDHE-RSA-AES256-GCM-SHA384 - ECDHE-ECDSA-CHACHA20-POLY1305
-                      - ECDHE-RSA-CHACHA20-POLY1305 - DHE-RSA-AES128-GCM-SHA256 -
-                      DHE-RSA-AES256-GCM-SHA384 - DHE-RSA-CHACHA20-POLY1305 - ECDHE-ECDSA-AES128-SHA256
-                      - ECDHE-RSA-AES128-SHA256 - ECDHE-ECDSA-AES128-SHA - ECDHE-RSA-AES128-SHA
-                      - ECDHE-ECDSA-AES256-SHA384 - ECDHE-RSA-AES256-SHA384 - ECDHE-ECDSA-AES256-SHA
-                      - ECDHE-RSA-AES256-SHA - DHE-RSA-AES128-SHA256 - DHE-RSA-AES256-SHA256
-                      - AES128-GCM-SHA256 - AES256-GCM-SHA384 - AES128-SHA256 - AES256-SHA256
-                      - AES128-SHA - AES256-SHA - DES-CBC3-SHA minTLSVersion: VersionTLS10"
-                    nullable: true
-                    type: object
-                  type:
-                    description: "type is one of Old, Intermediate, Modern or Custom.
-                      Custom provides the ability to specify individual TLS security
-                      profile parameters. Old, Intermediate and Modern are TLS security
-                      profiles based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations
-                      \n The profiles are intent based, so they may change over time
-                      as new ciphers are developed and existing ciphers are found
-                      to be insecure.  Depending on precisely which ciphers are available
-                      to a process, the list may be reduced. \n Note that the Modern
-                      profile is currently not supported because it is not yet well
-                      adopted by common software libraries."
-                    enum:
-                    - Old
-                    - Intermediate
-                    - Modern
-                    - Custom
-                    type: string
-                type: object
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_apiserver-Default.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_apiserver-Default.crd.yaml
deleted file mode 100644
index 2265fd96..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_apiserver-Default.crd.yaml
+++ /dev/null
@@ -1,312 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    release.openshift.io/feature-set: Default
-  name: apiservers.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: APIServer
-    listKind: APIServerList
-    plural: apiservers
-    singular: apiserver
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "APIServer holds configuration (like serving certificates, client
-          CA and CORS domains) shared by all API servers in the system, among them
-          especially kube-apiserver and openshift-apiserver. The canonical name of
-          an instance is 'cluster'. \n Compatibility level 1: Stable within a major
-          release for a minimum of 12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              additionalCORSAllowedOrigins:
-                description: additionalCORSAllowedOrigins lists additional, user-defined
-                  regular expressions describing hosts for which the API server allows
-                  access using the CORS headers. This may be needed to access the
-                  API and the integrated OAuth server from JavaScript applications.
-                  The values are regular expressions that correspond to the Golang
-                  regular expression language.
-                items:
-                  type: string
-                type: array
-              audit:
-                default:
-                  profile: Default
-                description: audit specifies the settings for audit configuration
-                  to be applied to all OpenShift-provided API servers in the cluster.
-                properties:
-                  customRules:
-                    description: customRules specify profiles per group. These profile
-                      take precedence over the top-level profile field if they apply.
-                      They are evaluation from top to bottom and the first one that
-                      matches, applies.
-                    items:
-                      description: AuditCustomRule describes a custom rule for an
-                        audit profile that takes precedence over the top-level profile.
-                      properties:
-                        group:
-                          description: group is a name of group a request user must
-                            be member of in order to this profile to apply.
-                          minLength: 1
-                          type: string
-                        profile:
-                          description: "profile specifies the name of the desired
-                            audit policy configuration to be deployed to all OpenShift-provided
-                            API servers in the cluster. \n The following profiles
-                            are provided: - Default: the existing default policy.
-                            - WriteRequestBodies: like 'Default', but logs request
-                            and response HTTP payloads for write requests (create,
-                            update, patch). - AllRequestBodies: like 'WriteRequestBodies',
-                            but also logs request and response HTTP payloads for read
-                            requests (get, list). - None: no requests are logged at
-                            all, not even oauthaccesstokens and oauthauthorizetokens.
-                            \n If unset, the 'Default' profile is used as the default."
-                          enum:
-                          - Default
-                          - WriteRequestBodies
-                          - AllRequestBodies
-                          - None
-                          type: string
-                      required:
-                      - group
-                      - profile
-                      type: object
-                    type: array
-                    x-kubernetes-list-map-keys:
-                    - group
-                    x-kubernetes-list-type: map
-                  profile:
-                    default: Default
-                    description: "profile specifies the name of the desired top-level
-                      audit profile to be applied to all requests sent to any of the
-                      OpenShift-provided API servers in the cluster (kube-apiserver,
-                      openshift-apiserver and oauth-apiserver), with the exception
-                      of those requests that match one or more of the customRules.
-                      \n The following profiles are provided: - Default: default policy
-                      which means MetaData level logging with the exception of events
-                      (not logged at all), oauthaccesstokens and oauthauthorizetokens
-                      (both logged at RequestBody level). - WriteRequestBodies: like
-                      'Default', but logs request and response HTTP payloads for write
-                      requests (create, update, patch). - AllRequestBodies: like 'WriteRequestBodies',
-                      but also logs request and response HTTP payloads for read requests
-                      (get, list). - None: no requests are logged at all, not even
-                      oauthaccesstokens and oauthauthorizetokens. \n Warning: It is
-                      not recommended to disable audit logging by using the `None`
-                      profile unless you are fully aware of the risks of not logging
-                      data that can be beneficial when troubleshooting issues. If
-                      you disable audit logging and a support situation arises, you
-                      might need to enable audit logging and reproduce the issue in
-                      order to troubleshoot properly. \n If unset, the 'Default' profile
-                      is used as the default."
-                    enum:
-                    - Default
-                    - WriteRequestBodies
-                    - AllRequestBodies
-                    - None
-                    type: string
-                type: object
-              clientCA:
-                description: 'clientCA references a ConfigMap containing a certificate
-                  bundle for the signers that will be recognized for incoming client
-                  certificates in addition to the operator managed signers. If this
-                  is empty, then only operator managed signers are valid. You usually
-                  only have to set this if you have your own PKI you wish to honor
-                  client certificates from. The ConfigMap must exist in the openshift-config
-                  namespace and contain the following required fields: - ConfigMap.Data["ca-bundle.crt"]
-                  - CA bundle.'
-                properties:
-                  name:
-                    description: name is the metadata.name of the referenced config
-                      map
-                    type: string
-                required:
-                - name
-                type: object
-              encryption:
-                description: encryption allows the configuration of encryption of
-                  resources at the datastore layer.
-                properties:
-                  type:
-                    description: "type defines what encryption type should be used
-                      to encrypt resources at the datastore layer. When this field
-                      is unset (i.e. when it is set to the empty string), identity
-                      is implied. The behavior of unset can and will change over time.
-                      \ Even if encryption is enabled by default, the meaning of unset
-                      may change to a different encryption type based on changes in
-                      best practices. \n When encryption is enabled, all sensitive
-                      resources shipped with the platform are encrypted. This list
-                      of sensitive resources can and will change over time.  The current
-                      authoritative list is: \n 1. secrets 2. configmaps 3. routes.route.openshift.io
-                      4. oauthaccesstokens.oauth.openshift.io 5. oauthauthorizetokens.oauth.openshift.io"
-                    enum:
-                    - ""
-                    - identity
-                    - aescbc
-                    - aesgcm
-                    type: string
-                type: object
-              servingCerts:
-                description: servingCert is the TLS cert info for serving secure traffic.
-                  If not specified, operator managed certificates will be used for
-                  serving secure traffic.
-                properties:
-                  namedCertificates:
-                    description: namedCertificates references secrets containing the
-                      TLS cert info for serving secure traffic to specific hostnames.
-                      If no named certificates are provided, or no named certificates
-                      match the server name as understood by a client, the defaultServingCertificate
-                      will be used.
-                    items:
-                      description: APIServerNamedServingCert maps a server DNS name,
-                        as understood by a client, to a certificate.
-                      properties:
-                        names:
-                          description: names is a optional list of explicit DNS names
-                            (leading wildcards allowed) that should use this certificate
-                            to serve secure traffic. If no names are provided, the
-                            implicit names will be extracted from the certificates.
-                            Exact names trump over wildcard names. Explicit names
-                            defined here trump over extracted implicit names.
-                          items:
-                            type: string
-                          type: array
-                        servingCertificate:
-                          description: 'servingCertificate references a kubernetes.io/tls
-                            type secret containing the TLS cert info for serving secure
-                            traffic. The secret must exist in the openshift-config
-                            namespace and contain the following required fields: -
-                            Secret.Data["tls.key"] - TLS private key. - Secret.Data["tls.crt"]
-                            - TLS certificate.'
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                secret
-                              type: string
-                          required:
-                          - name
-                          type: object
-                      type: object
-                    type: array
-                type: object
-              tlsSecurityProfile:
-                description: "tlsSecurityProfile specifies settings for TLS connections
-                  for externally exposed servers. \n If unset, a default (which may
-                  change between releases) is chosen. Note that only Old, Intermediate
-                  and Custom profiles are currently supported, and the maximum available
-                  minTLSVersion is VersionTLS12."
-                properties:
-                  custom:
-                    description: "custom is a user-defined TLS security profile. Be
-                      extremely careful using a custom profile as invalid configurations
-                      can be catastrophic. An example custom profile looks like this:
-                      \n ciphers: - ECDHE-ECDSA-CHACHA20-POLY1305 - ECDHE-RSA-CHACHA20-POLY1305
-                      - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES128-GCM-SHA256
-                      minTLSVersion: VersionTLS11"
-                    nullable: true
-                    properties:
-                      ciphers:
-                        description: "ciphers is used to specify the cipher algorithms
-                          that are negotiated during the TLS handshake.  Operators
-                          may remove entries their operands do not support.  For example,
-                          to use DES-CBC3-SHA  (yaml): \n ciphers: - DES-CBC3-SHA"
-                        items:
-                          type: string
-                        type: array
-                      minTLSVersion:
-                        description: "minTLSVersion is used to specify the minimal
-                          version of the TLS protocol that is negotiated during the
-                          TLS handshake. For example, to use TLS versions 1.1, 1.2
-                          and 1.3 (yaml): \n minTLSVersion: VersionTLS11 \n NOTE:
-                          currently the highest minTLSVersion allowed is VersionTLS12"
-                        enum:
-                        - VersionTLS10
-                        - VersionTLS11
-                        - VersionTLS12
-                        - VersionTLS13
-                        type: string
-                    type: object
-                  intermediate:
-                    description: "intermediate is a TLS security profile based on:
-                      \n https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29
-                      \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256
-                      - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 - ECDHE-ECDSA-AES128-GCM-SHA256
-                      - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES256-GCM-SHA384
-                      - ECDHE-RSA-AES256-GCM-SHA384 - ECDHE-ECDSA-CHACHA20-POLY1305
-                      - ECDHE-RSA-CHACHA20-POLY1305 - DHE-RSA-AES128-GCM-SHA256 -
-                      DHE-RSA-AES256-GCM-SHA384 minTLSVersion: VersionTLS12"
-                    nullable: true
-                    type: object
-                  modern:
-                    description: "modern is a TLS security profile based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility
-                      \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256
-                      - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 minTLSVersion:
-                      VersionTLS13 \n NOTE: Currently unsupported."
-                    nullable: true
-                    type: object
-                  old:
-                    description: "old is a TLS security profile based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Old_backward_compatibility
-                      \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256
-                      - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 - ECDHE-ECDSA-AES128-GCM-SHA256
-                      - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES256-GCM-SHA384
-                      - ECDHE-RSA-AES256-GCM-SHA384 - ECDHE-ECDSA-CHACHA20-POLY1305
-                      - ECDHE-RSA-CHACHA20-POLY1305 - DHE-RSA-AES128-GCM-SHA256 -
-                      DHE-RSA-AES256-GCM-SHA384 - DHE-RSA-CHACHA20-POLY1305 - ECDHE-ECDSA-AES128-SHA256
-                      - ECDHE-RSA-AES128-SHA256 - ECDHE-ECDSA-AES128-SHA - ECDHE-RSA-AES128-SHA
-                      - ECDHE-ECDSA-AES256-SHA384 - ECDHE-RSA-AES256-SHA384 - ECDHE-ECDSA-AES256-SHA
-                      - ECDHE-RSA-AES256-SHA - DHE-RSA-AES128-SHA256 - DHE-RSA-AES256-SHA256
-                      - AES128-GCM-SHA256 - AES256-GCM-SHA384 - AES128-SHA256 - AES256-SHA256
-                      - AES128-SHA - AES256-SHA - DES-CBC3-SHA minTLSVersion: VersionTLS10"
-                    nullable: true
-                    type: object
-                  type:
-                    description: "type is one of Old, Intermediate, Modern or Custom.
-                      Custom provides the ability to specify individual TLS security
-                      profile parameters. Old, Intermediate and Modern are TLS security
-                      profiles based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations
-                      \n The profiles are intent based, so they may change over time
-                      as new ciphers are developed and existing ciphers are found
-                      to be insecure.  Depending on precisely which ciphers are available
-                      to a process, the list may be reduced. \n Note that the Modern
-                      profile is currently not supported because it is not yet well
-                      adopted by common software libraries."
-                    enum:
-                    - Old
-                    - Intermediate
-                    - Modern
-                    - Custom
-                    type: string
-                type: object
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_apiserver-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_apiserver-TechPreviewNoUpgrade.crd.yaml
deleted file mode 100644
index 1e6c9d5f..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_apiserver-TechPreviewNoUpgrade.crd.yaml
+++ /dev/null
@@ -1,312 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    release.openshift.io/feature-set: TechPreviewNoUpgrade
-  name: apiservers.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: APIServer
-    listKind: APIServerList
-    plural: apiservers
-    singular: apiserver
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "APIServer holds configuration (like serving certificates, client
-          CA and CORS domains) shared by all API servers in the system, among them
-          especially kube-apiserver and openshift-apiserver. The canonical name of
-          an instance is 'cluster'. \n Compatibility level 1: Stable within a major
-          release for a minimum of 12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              additionalCORSAllowedOrigins:
-                description: additionalCORSAllowedOrigins lists additional, user-defined
-                  regular expressions describing hosts for which the API server allows
-                  access using the CORS headers. This may be needed to access the
-                  API and the integrated OAuth server from JavaScript applications.
-                  The values are regular expressions that correspond to the Golang
-                  regular expression language.
-                items:
-                  type: string
-                type: array
-              audit:
-                default:
-                  profile: Default
-                description: audit specifies the settings for audit configuration
-                  to be applied to all OpenShift-provided API servers in the cluster.
-                properties:
-                  customRules:
-                    description: customRules specify profiles per group. These profile
-                      take precedence over the top-level profile field if they apply.
-                      They are evaluation from top to bottom and the first one that
-                      matches, applies.
-                    items:
-                      description: AuditCustomRule describes a custom rule for an
-                        audit profile that takes precedence over the top-level profile.
-                      properties:
-                        group:
-                          description: group is a name of group a request user must
-                            be member of in order to this profile to apply.
-                          minLength: 1
-                          type: string
-                        profile:
-                          description: "profile specifies the name of the desired
-                            audit policy configuration to be deployed to all OpenShift-provided
-                            API servers in the cluster. \n The following profiles
-                            are provided: - Default: the existing default policy.
-                            - WriteRequestBodies: like 'Default', but logs request
-                            and response HTTP payloads for write requests (create,
-                            update, patch). - AllRequestBodies: like 'WriteRequestBodies',
-                            but also logs request and response HTTP payloads for read
-                            requests (get, list). - None: no requests are logged at
-                            all, not even oauthaccesstokens and oauthauthorizetokens.
-                            \n If unset, the 'Default' profile is used as the default."
-                          enum:
-                          - Default
-                          - WriteRequestBodies
-                          - AllRequestBodies
-                          - None
-                          type: string
-                      required:
-                      - group
-                      - profile
-                      type: object
-                    type: array
-                    x-kubernetes-list-map-keys:
-                    - group
-                    x-kubernetes-list-type: map
-                  profile:
-                    default: Default
-                    description: "profile specifies the name of the desired top-level
-                      audit profile to be applied to all requests sent to any of the
-                      OpenShift-provided API servers in the cluster (kube-apiserver,
-                      openshift-apiserver and oauth-apiserver), with the exception
-                      of those requests that match one or more of the customRules.
-                      \n The following profiles are provided: - Default: default policy
-                      which means MetaData level logging with the exception of events
-                      (not logged at all), oauthaccesstokens and oauthauthorizetokens
-                      (both logged at RequestBody level). - WriteRequestBodies: like
-                      'Default', but logs request and response HTTP payloads for write
-                      requests (create, update, patch). - AllRequestBodies: like 'WriteRequestBodies',
-                      but also logs request and response HTTP payloads for read requests
-                      (get, list). - None: no requests are logged at all, not even
-                      oauthaccesstokens and oauthauthorizetokens. \n Warning: It is
-                      not recommended to disable audit logging by using the `None`
-                      profile unless you are fully aware of the risks of not logging
-                      data that can be beneficial when troubleshooting issues. If
-                      you disable audit logging and a support situation arises, you
-                      might need to enable audit logging and reproduce the issue in
-                      order to troubleshoot properly. \n If unset, the 'Default' profile
-                      is used as the default."
-                    enum:
-                    - Default
-                    - WriteRequestBodies
-                    - AllRequestBodies
-                    - None
-                    type: string
-                type: object
-              clientCA:
-                description: 'clientCA references a ConfigMap containing a certificate
-                  bundle for the signers that will be recognized for incoming client
-                  certificates in addition to the operator managed signers. If this
-                  is empty, then only operator managed signers are valid. You usually
-                  only have to set this if you have your own PKI you wish to honor
-                  client certificates from. The ConfigMap must exist in the openshift-config
-                  namespace and contain the following required fields: - ConfigMap.Data["ca-bundle.crt"]
-                  - CA bundle.'
-                properties:
-                  name:
-                    description: name is the metadata.name of the referenced config
-                      map
-                    type: string
-                required:
-                - name
-                type: object
-              encryption:
-                description: encryption allows the configuration of encryption of
-                  resources at the datastore layer.
-                properties:
-                  type:
-                    description: "type defines what encryption type should be used
-                      to encrypt resources at the datastore layer. When this field
-                      is unset (i.e. when it is set to the empty string), identity
-                      is implied. The behavior of unset can and will change over time.
-                      \ Even if encryption is enabled by default, the meaning of unset
-                      may change to a different encryption type based on changes in
-                      best practices. \n When encryption is enabled, all sensitive
-                      resources shipped with the platform are encrypted. This list
-                      of sensitive resources can and will change over time.  The current
-                      authoritative list is: \n 1. secrets 2. configmaps 3. routes.route.openshift.io
-                      4. oauthaccesstokens.oauth.openshift.io 5. oauthauthorizetokens.oauth.openshift.io"
-                    enum:
-                    - ""
-                    - identity
-                    - aescbc
-                    - aesgcm
-                    type: string
-                type: object
-              servingCerts:
-                description: servingCert is the TLS cert info for serving secure traffic.
-                  If not specified, operator managed certificates will be used for
-                  serving secure traffic.
-                properties:
-                  namedCertificates:
-                    description: namedCertificates references secrets containing the
-                      TLS cert info for serving secure traffic to specific hostnames.
-                      If no named certificates are provided, or no named certificates
-                      match the server name as understood by a client, the defaultServingCertificate
-                      will be used.
-                    items:
-                      description: APIServerNamedServingCert maps a server DNS name,
-                        as understood by a client, to a certificate.
-                      properties:
-                        names:
-                          description: names is a optional list of explicit DNS names
-                            (leading wildcards allowed) that should use this certificate
-                            to serve secure traffic. If no names are provided, the
-                            implicit names will be extracted from the certificates.
-                            Exact names trump over wildcard names. Explicit names
-                            defined here trump over extracted implicit names.
-                          items:
-                            type: string
-                          type: array
-                        servingCertificate:
-                          description: 'servingCertificate references a kubernetes.io/tls
-                            type secret containing the TLS cert info for serving secure
-                            traffic. The secret must exist in the openshift-config
-                            namespace and contain the following required fields: -
-                            Secret.Data["tls.key"] - TLS private key. - Secret.Data["tls.crt"]
-                            - TLS certificate.'
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                secret
-                              type: string
-                          required:
-                          - name
-                          type: object
-                      type: object
-                    type: array
-                type: object
-              tlsSecurityProfile:
-                description: "tlsSecurityProfile specifies settings for TLS connections
-                  for externally exposed servers. \n If unset, a default (which may
-                  change between releases) is chosen. Note that only Old, Intermediate
-                  and Custom profiles are currently supported, and the maximum available
-                  minTLSVersion is VersionTLS12."
-                properties:
-                  custom:
-                    description: "custom is a user-defined TLS security profile. Be
-                      extremely careful using a custom profile as invalid configurations
-                      can be catastrophic. An example custom profile looks like this:
-                      \n ciphers: - ECDHE-ECDSA-CHACHA20-POLY1305 - ECDHE-RSA-CHACHA20-POLY1305
-                      - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES128-GCM-SHA256
-                      minTLSVersion: VersionTLS11"
-                    nullable: true
-                    properties:
-                      ciphers:
-                        description: "ciphers is used to specify the cipher algorithms
-                          that are negotiated during the TLS handshake.  Operators
-                          may remove entries their operands do not support.  For example,
-                          to use DES-CBC3-SHA  (yaml): \n ciphers: - DES-CBC3-SHA"
-                        items:
-                          type: string
-                        type: array
-                      minTLSVersion:
-                        description: "minTLSVersion is used to specify the minimal
-                          version of the TLS protocol that is negotiated during the
-                          TLS handshake. For example, to use TLS versions 1.1, 1.2
-                          and 1.3 (yaml): \n minTLSVersion: VersionTLS11 \n NOTE:
-                          currently the highest minTLSVersion allowed is VersionTLS12"
-                        enum:
-                        - VersionTLS10
-                        - VersionTLS11
-                        - VersionTLS12
-                        - VersionTLS13
-                        type: string
-                    type: object
-                  intermediate:
-                    description: "intermediate is a TLS security profile based on:
-                      \n https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29
-                      \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256
-                      - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 - ECDHE-ECDSA-AES128-GCM-SHA256
-                      - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES256-GCM-SHA384
-                      - ECDHE-RSA-AES256-GCM-SHA384 - ECDHE-ECDSA-CHACHA20-POLY1305
-                      - ECDHE-RSA-CHACHA20-POLY1305 - DHE-RSA-AES128-GCM-SHA256 -
-                      DHE-RSA-AES256-GCM-SHA384 minTLSVersion: VersionTLS12"
-                    nullable: true
-                    type: object
-                  modern:
-                    description: "modern is a TLS security profile based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility
-                      \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256
-                      - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 minTLSVersion:
-                      VersionTLS13 \n NOTE: Currently unsupported."
-                    nullable: true
-                    type: object
-                  old:
-                    description: "old is a TLS security profile based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Old_backward_compatibility
-                      \n and looks like this (yaml): \n ciphers: - TLS_AES_128_GCM_SHA256
-                      - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 - ECDHE-ECDSA-AES128-GCM-SHA256
-                      - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES256-GCM-SHA384
-                      - ECDHE-RSA-AES256-GCM-SHA384 - ECDHE-ECDSA-CHACHA20-POLY1305
-                      - ECDHE-RSA-CHACHA20-POLY1305 - DHE-RSA-AES128-GCM-SHA256 -
-                      DHE-RSA-AES256-GCM-SHA384 - DHE-RSA-CHACHA20-POLY1305 - ECDHE-ECDSA-AES128-SHA256
-                      - ECDHE-RSA-AES128-SHA256 - ECDHE-ECDSA-AES128-SHA - ECDHE-RSA-AES128-SHA
-                      - ECDHE-ECDSA-AES256-SHA384 - ECDHE-RSA-AES256-SHA384 - ECDHE-ECDSA-AES256-SHA
-                      - ECDHE-RSA-AES256-SHA - DHE-RSA-AES128-SHA256 - DHE-RSA-AES256-SHA256
-                      - AES128-GCM-SHA256 - AES256-GCM-SHA384 - AES128-SHA256 - AES256-SHA256
-                      - AES128-SHA - AES256-SHA - DES-CBC3-SHA minTLSVersion: VersionTLS10"
-                    nullable: true
-                    type: object
-                  type:
-                    description: "type is one of Old, Intermediate, Modern or Custom.
-                      Custom provides the ability to specify individual TLS security
-                      profile parameters. Old, Intermediate and Modern are TLS security
-                      profiles based on: \n https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations
-                      \n The profiles are intent based, so they may change over time
-                      as new ciphers are developed and existing ciphers are found
-                      to be insecure.  Depending on precisely which ciphers are available
-                      to a process, the list may be reduced. \n Note that the Modern
-                      profile is currently not supported because it is not yet well
-                      adopted by common software libraries."
-                    enum:
-                    - Old
-                    - Intermediate
-                    - Modern
-                    - Custom
-                    type: string
-                type: object
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-CustomNoUpgrade.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-CustomNoUpgrade.yaml
deleted file mode 100644
index 6d8a5da7..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-CustomNoUpgrade.yaml
+++ /dev/null
@@ -1,554 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    release.openshift.io/feature-set: CustomNoUpgrade
-  name: authentications.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: Authentication
-    listKind: AuthenticationList
-    plural: authentications
-    singular: authentication
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "Authentication specifies cluster-wide settings for authentication
-          (like OAuth and webhook token authenticators). The canonical name of an
-          instance is `cluster`. \n Compatibility level 1: Stable within a major release
-          for a minimum of 12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              oauthMetadata:
-                description: 'oauthMetadata contains the discovery endpoint data for
-                  OAuth 2.0 Authorization Server Metadata for an external OAuth server.
-                  This discovery document can be viewed from its served location:
-                  oc get --raw ''/.well-known/oauth-authorization-server'' For further
-                  details, see the IETF Draft: https://tools.ietf.org/html/draft-ietf-oauth-discovery-04#section-2
-                  If oauthMetadata.name is non-empty, this value has precedence over
-                  any metadata reference stored in status. The key "oauthMetadata"
-                  is used to locate the data. If specified and the config map or expected
-                  key is not found, no metadata is served. If the specified metadata
-                  is not valid, no metadata is served. The namespace for this config
-                  map is openshift-config.'
-                properties:
-                  name:
-                    description: name is the metadata.name of the referenced config
-                      map
-                    type: string
-                required:
-                - name
-                type: object
-              oidcProviders:
-                description: "OIDCProviders are OIDC identity providers that can issue
-                  tokens for this cluster Can only be set if \"Type\" is set to \"OIDC\".
-                  \n At most one provider can be configured."
-                items:
-                  properties:
-                    claimMappings:
-                      description: ClaimMappings describes rules on how to transform
-                        information from an ID token into a cluster identity
-                      properties:
-                        groups:
-                          description: Groups is a name of the claim that should be
-                            used to construct groups for the cluster identity. The
-                            referenced claim must use array of strings values.
-                          properties:
-                            claim:
-                              description: Claim is a JWT token claim to be used in
-                                the mapping
-                              type: string
-                            prefix:
-                              description: "Prefix is a string to prefix the value
-                                from the token in the result of the claim mapping.
-                                \n By default, no prefixing occurs. \n Example: if
-                                `prefix` is set to \"myoidc:\"\" and the `claim` in
-                                JWT contains an array of strings \"a\", \"b\" and
-                                \ \"c\", the mapping will result in an array of string
-                                \"myoidc:a\", \"myoidc:b\" and \"myoidc:c\"."
-                              type: string
-                          required:
-                          - claim
-                          type: object
-                        username:
-                          description: "Username is a name of the claim that should
-                            be used to construct usernames for the cluster identity.
-                            \n Default value: \"sub\""
-                          properties:
-                            claim:
-                              description: Claim is a JWT token claim to be used in
-                                the mapping
-                              type: string
-                            prefix:
-                              properties:
-                                prefixString:
-                                  minLength: 1
-                                  type: string
-                              required:
-                              - prefixString
-                              type: object
-                            prefixPolicy:
-                              description: "PrefixPolicy specifies how a prefix should
-                                apply. \n By default, claims other than `email` will
-                                be prefixed with the issuer URL to prevent naming
-                                clashes with other plugins. \n Set to \"NoPrefix\"
-                                to disable prefixing. \n Example: (1) `prefix` is
-                                set to \"myoidc:\" and `claim` is set to \"username\".
-                                If the JWT claim `username` contains value `userA`,
-                                the resulting mapped value will be \"myoidc:userA\".
-                                (2) `prefix` is set to \"myoidc:\" and `claim` is
-                                set to \"email\". If the JWT `email` claim contains
-                                value \"userA@myoidc.tld\", the resulting mapped value
-                                will be \"myoidc:userA@myoidc.tld\". (3) `prefix`
-                                is unset, `issuerURL` is set to `https://myoidc.tld`,
-                                the JWT claims include \"username\":\"userA\" and
-                                \"email\":\"userA@myoidc.tld\", and `claim` is set
-                                to: (a) \"username\": the mapped value will be \"https://myoidc.tld#userA\"
-                                (b) \"email\": the mapped value will be \"userA@myoidc.tld\""
-                              enum:
-                              - ""
-                              - NoPrefix
-                              - Prefix
-                              type: string
-                          required:
-                          - claim
-                          type: object
-                          x-kubernetes-validations:
-                          - message: prefix must be set if prefixPolicy is 'Prefix',
-                              but must remain unset otherwise
-                            rule: 'has(self.prefixPolicy) && self.prefixPolicy ==
-                              ''Prefix'' ? (has(self.prefix) && size(self.prefix.prefixString)
-                              > 0) : !has(self.prefix)'
-                      type: object
-                    claimValidationRules:
-                      description: ClaimValidationRules are rules that are applied
-                        to validate token claims to authenticate users.
-                      items:
-                        properties:
-                          requiredClaim:
-                            description: RequiredClaim allows configuring a required
-                              claim name and its expected value
-                            properties:
-                              claim:
-                                description: Claim is a name of a required claim.
-                                  Only claims with string values are supported.
-                                minLength: 1
-                                type: string
-                              requiredValue:
-                                description: RequiredValue is the required value for
-                                  the claim.
-                                minLength: 1
-                                type: string
-                            required:
-                            - claim
-                            - requiredValue
-                            type: object
-                          type:
-                            default: RequiredClaim
-                            description: Type sets the type of the validation rule
-                            enum:
-                            - RequiredClaim
-                            type: string
-                        type: object
-                      type: array
-                      x-kubernetes-list-type: atomic
-                    issuer:
-                      description: Issuer describes atributes of the OIDC token issuer
-                      properties:
-                        audiences:
-                          description: Audiences is an array of audiences that the
-                            token was issued for. Valid tokens must include at least
-                            one of these values in their "aud" claim. Must be set
-                            to exactly one value.
-                          items:
-                            minLength: 1
-                            type: string
-                          maxItems: 10
-                          minItems: 1
-                          type: array
-                          x-kubernetes-list-type: set
-                        issuerCertificateAuthority:
-                          description: CertificateAuthority is a reference to a config
-                            map in the configuration namespace. The .data of the configMap
-                            must contain the "ca-bundle.crt" key. If unset, system
-                            trust is used instead.
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                config map
-                              type: string
-                          required:
-                          - name
-                          type: object
-                        issuerURL:
-                          description: URL is the serving URL of the token issuer.
-                            Must use the https:// scheme.
-                          pattern: ^https:\/\/[^\s]
-                          type: string
-                      required:
-                      - audiences
-                      - issuerURL
-                      type: object
-                    name:
-                      description: Name of the OIDC provider
-                      minLength: 1
-                      type: string
-                    oidcClients:
-                      description: OIDCClients contains configuration for the platform's
-                        clients that need to request tokens from the issuer
-                      items:
-                        properties:
-                          clientID:
-                            description: ClientID is the identifier of the OIDC client
-                              from the OIDC provider
-                            minLength: 1
-                            type: string
-                          clientSecret:
-                            description: ClientSecret refers to a secret in the `openshift-config`
-                              namespace that contains the client secret in the `clientSecret`
-                              key of the `.data` field
-                            properties:
-                              name:
-                                description: name is the metadata.name of the referenced
-                                  secret
-                                type: string
-                            required:
-                            - name
-                            type: object
-                          componentName:
-                            description: ComponentName is the name of the component
-                              that is supposed to consume this client configuration
-                            maxLength: 256
-                            minLength: 1
-                            type: string
-                          componentNamespace:
-                            description: ComponentNamespace is the namespace of the
-                              component that is supposed to consume this client configuration
-                            maxLength: 63
-                            minLength: 1
-                            type: string
-                          extraScopes:
-                            description: ExtraScopes is an optional set of scopes
-                              to request tokens with.
-                            items:
-                              type: string
-                            type: array
-                            x-kubernetes-list-type: set
-                        required:
-                        - clientID
-                        - componentName
-                        - componentNamespace
-                        type: object
-                      maxItems: 20
-                      type: array
-                      x-kubernetes-list-map-keys:
-                      - componentNamespace
-                      - componentName
-                      x-kubernetes-list-type: map
-                  required:
-                  - issuer
-                  - name
-                  type: object
-                maxItems: 1
-                type: array
-                x-kubernetes-list-map-keys:
-                - name
-                x-kubernetes-list-type: map
-              serviceAccountIssuer:
-                description: 'serviceAccountIssuer is the identifier of the bound
-                  service account token issuer. The default is https://kubernetes.default.svc
-                  WARNING: Updating this field will not result in immediate invalidation
-                  of all bound tokens with the previous issuer value. Instead, the
-                  tokens issued by previous service account issuer will continue to
-                  be trusted for a time period chosen by the platform (currently set
-                  to 24h). This time period is subject to change over time. This allows
-                  internal components to transition to use new service account issuer
-                  without service distruption.'
-                type: string
-              type:
-                description: type identifies the cluster managed, user facing authentication
-                  mode in use. Specifically, it manages the component that responds
-                  to login attempts. The default is IntegratedOAuth.
-                enum:
-                - ""
-                - None
-                - IntegratedOAuth
-                - OIDC
-                type: string
-              webhookTokenAuthenticator:
-                description: "webhookTokenAuthenticator configures a remote token
-                  reviewer. These remote authentication webhooks can be used to verify
-                  bearer tokens via the tokenreviews.authentication.k8s.io REST API.
-                  This is required to honor bearer tokens that are provisioned by
-                  an external authentication service. \n Can only be set if \"Type\"
-                  is set to \"None\"."
-                properties:
-                  kubeConfig:
-                    description: "kubeConfig references a secret that contains kube
-                      config file data which describes how to access the remote webhook
-                      service. The namespace for the referenced secret is openshift-config.
-                      \n For further details, see: \n https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication
-                      \n The key \"kubeConfig\" is used to locate the data. If the
-                      secret or expected key is not found, the webhook is not honored.
-                      If the specified kube config data is not valid, the webhook
-                      is not honored."
-                    properties:
-                      name:
-                        description: name is the metadata.name of the referenced secret
-                        type: string
-                    required:
-                    - name
-                    type: object
-                required:
-                - kubeConfig
-                type: object
-              webhookTokenAuthenticators:
-                description: webhookTokenAuthenticators is DEPRECATED, setting it
-                  has no effect.
-                items:
-                  description: deprecatedWebhookTokenAuthenticator holds the necessary
-                    configuration options for a remote token authenticator. It's the
-                    same as WebhookTokenAuthenticator but it's missing the 'required'
-                    validation on KubeConfig field.
-                  properties:
-                    kubeConfig:
-                      description: 'kubeConfig contains kube config file data which
-                        describes how to access the remote webhook service. For further
-                        details, see: https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication
-                        The key "kubeConfig" is used to locate the data. If the secret
-                        or expected key is not found, the webhook is not honored.
-                        If the specified kube config data is not valid, the webhook
-                        is not honored. The namespace for this secret is determined
-                        by the point of use.'
-                      properties:
-                        name:
-                          description: name is the metadata.name of the referenced
-                            secret
-                          type: string
-                      required:
-                      - name
-                      type: object
-                  type: object
-                type: array
-                x-kubernetes-list-type: atomic
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            properties:
-              integratedOAuthMetadata:
-                description: 'integratedOAuthMetadata contains the discovery endpoint
-                  data for OAuth 2.0 Authorization Server Metadata for the in-cluster
-                  integrated OAuth server. This discovery document can be viewed from
-                  its served location: oc get --raw ''/.well-known/oauth-authorization-server''
-                  For further details, see the IETF Draft: https://tools.ietf.org/html/draft-ietf-oauth-discovery-04#section-2
-                  This contains the observed value based on cluster state. An explicitly
-                  set value in spec.oauthMetadata has precedence over this field.
-                  This field has no meaning if authentication spec.type is not set
-                  to IntegratedOAuth. The key "oauthMetadata" is used to locate the
-                  data. If the config map or expected key is not found, no metadata
-                  is served. If the specified metadata is not valid, no metadata is
-                  served. The namespace for this config map is openshift-config-managed.'
-                properties:
-                  name:
-                    description: name is the metadata.name of the referenced config
-                      map
-                    type: string
-                required:
-                - name
-                type: object
-              oidcClients:
-                description: OIDCClients is where participating operators place the
-                  current OIDC client status for OIDC clients that can be customized
-                  by the cluster-admin.
-                items:
-                  properties:
-                    componentName:
-                      description: ComponentName is the name of the component that
-                        will consume a client configuration.
-                      maxLength: 256
-                      minLength: 1
-                      type: string
-                    componentNamespace:
-                      description: ComponentNamespace is the namespace of the component
-                        that will consume a client configuration.
-                      maxLength: 63
-                      minLength: 1
-                      type: string
-                    conditions:
-                      description: "Conditions are used to communicate the state of
-                        the `oidcClients` entry. \n Supported conditions include Available,
-                        Degraded and Progressing. \n If Available is true, the component
-                        is successfully using the configured client. If Degraded is
-                        true, that means something has gone wrong trying to handle
-                        the client configuration. If Progressing is true, that means
-                        the component is taking some action related to the `oidcClients`
-                        entry."
-                      items:
-                        description: "Condition contains details for one aspect of
-                          the current state of this API Resource. --- This struct
-                          is intended for direct use as an array at the field path
-                          .status.conditions.  For example, \n type FooStatus struct{
-                          // Represents the observations of a foo's current state.
-                          // Known .status.conditions.type are: \"Available\", \"Progressing\",
-                          and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
-                          // +listType=map // +listMapKey=type Conditions []metav1.Condition
-                          `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
-                          protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields
-                          }"
-                        properties:
-                          lastTransitionTime:
-                            description: lastTransitionTime is the last time the condition
-                              transitioned from one status to another. This should
-                              be when the underlying condition changed.  If that is
-                              not known, then using the time when the API field changed
-                              is acceptable.
-                            format: date-time
-                            type: string
-                          message:
-                            description: message is a human readable message indicating
-                              details about the transition. This may be an empty string.
-                            maxLength: 32768
-                            type: string
-                          observedGeneration:
-                            description: observedGeneration represents the .metadata.generation
-                              that the condition was set based upon. For instance,
-                              if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration
-                              is 9, the condition is out of date with respect to the
-                              current state of the instance.
-                            format: int64
-                            minimum: 0
-                            type: integer
-                          reason:
-                            description: reason contains a programmatic identifier
-                              indicating the reason for the condition's last transition.
-                              Producers of specific condition types may define expected
-                              values and meanings for this field, and whether the
-                              values are considered a guaranteed API. The value should
-                              be a CamelCase string. This field may not be empty.
-                            maxLength: 1024
-                            minLength: 1
-                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
-                            type: string
-                          status:
-                            description: status of the condition, one of True, False,
-                              Unknown.
-                            enum:
-                            - "True"
-                            - "False"
-                            - Unknown
-                            type: string
-                          type:
-                            description: type of condition in CamelCase or in foo.example.com/CamelCase.
-                              --- Many .condition.type values are consistent across
-                              resources like Available, but because arbitrary conditions
-                              can be useful (see .node.status.conditions), the ability
-                              to deconflict is important. The regex it matches is
-                              (dns1123SubdomainFmt/)?(qualifiedNameFmt)
-                            maxLength: 316
-                            pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
-                            type: string
-                        required:
-                        - lastTransitionTime
-                        - message
-                        - reason
-                        - status
-                        - type
-                        type: object
-                      type: array
-                      x-kubernetes-list-map-keys:
-                      - type
-                      x-kubernetes-list-type: map
-                    consumingUsers:
-                      description: ConsumingUsers is a slice of ServiceAccounts that
-                        need to have read permission on the `clientSecret` secret.
-                      items:
-                        description: ConsumingUser is an alias for string which we
-                          add validation to. Currently only service accounts are supported.
-                        maxLength: 512
-                        minLength: 1
-                        pattern: ^system:serviceaccount:[a-z0-9]([-a-z0-9]*[a-z0-9])?:[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
-                        type: string
-                      maxItems: 5
-                      type: array
-                      x-kubernetes-list-type: set
-                    currentOIDCClients:
-                      description: CurrentOIDCClients is a list of clients that the
-                        component is currently using.
-                      items:
-                        properties:
-                          clientID:
-                            description: ClientID is the identifier of the OIDC client
-                              from the OIDC provider
-                            minLength: 1
-                            type: string
-                          issuerURL:
-                            description: URL is the serving URL of the token issuer.
-                              Must use the https:// scheme.
-                            pattern: ^https:\/\/[^\s]
-                            type: string
-                          oidcProviderName:
-                            description: OIDCName refers to the `name` of the provider
-                              from `oidcProviders`
-                            minLength: 1
-                            type: string
-                        required:
-                        - clientID
-                        - issuerURL
-                        - oidcProviderName
-                        type: object
-                      type: array
-                      x-kubernetes-list-map-keys:
-                      - issuerURL
-                      - clientID
-                      x-kubernetes-list-type: map
-                  required:
-                  - componentName
-                  - componentNamespace
-                  type: object
-                maxItems: 20
-                type: array
-                x-kubernetes-list-map-keys:
-                - componentNamespace
-                - componentName
-                x-kubernetes-list-type: map
-            type: object
-        required:
-        - spec
-        type: object
-        x-kubernetes-validations:
-        - message: all oidcClients in the oidcProviders must match their componentName
-            and componentNamespace to either a previously configured oidcClient or
-            they must exist in the status.oidcClients
-          rule: '!has(self.spec.oidcProviders) || self.spec.oidcProviders.all(p, !has(p.oidcClients)
-            || p.oidcClients.all(specC, self.status.oidcClients.exists(statusC, statusC.componentNamespace
-            == specC.componentNamespace && statusC.componentName == specC.componentName)
-            || (has(oldSelf.spec.oidcProviders) && oldSelf.spec.oidcProviders.exists(oldP,
-            oldP.name == p.name && has(oldP.oidcClients) && oldP.oidcClients.exists(oldC,
-            oldC.componentNamespace == specC.componentNamespace && oldC.componentName
-            == specC.componentName)))))'
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-Default-Hypershift.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-Default-Hypershift.yaml
deleted file mode 100644
index 2cabddac..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-Default-Hypershift.yaml
+++ /dev/null
@@ -1,552 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    release.openshift.io/feature-set: Default
-  name: authentications.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: Authentication
-    listKind: AuthenticationList
-    plural: authentications
-    singular: authentication
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "Authentication specifies cluster-wide settings for authentication
-          (like OAuth and webhook token authenticators). The canonical name of an
-          instance is `cluster`. \n Compatibility level 1: Stable within a major release
-          for a minimum of 12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              oauthMetadata:
-                description: 'oauthMetadata contains the discovery endpoint data for
-                  OAuth 2.0 Authorization Server Metadata for an external OAuth server.
-                  This discovery document can be viewed from its served location:
-                  oc get --raw ''/.well-known/oauth-authorization-server'' For further
-                  details, see the IETF Draft: https://tools.ietf.org/html/draft-ietf-oauth-discovery-04#section-2
-                  If oauthMetadata.name is non-empty, this value has precedence over
-                  any metadata reference stored in status. The key "oauthMetadata"
-                  is used to locate the data. If specified and the config map or expected
-                  key is not found, no metadata is served. If the specified metadata
-                  is not valid, no metadata is served. The namespace for this config
-                  map is openshift-config.'
-                properties:
-                  name:
-                    description: name is the metadata.name of the referenced config
-                      map
-                    type: string
-                required:
-                - name
-                type: object
-              oidcProviders:
-                description: "OIDCProviders are OIDC identity providers that can issue
-                  tokens for this cluster Can only be set if \"Type\" is set to \"OIDC\".
-                  \n At most one provider can be configured."
-                items:
-                  properties:
-                    claimMappings:
-                      description: ClaimMappings describes rules on how to transform
-                        information from an ID token into a cluster identity
-                      properties:
-                        groups:
-                          description: Groups is a name of the claim that should be
-                            used to construct groups for the cluster identity. The
-                            referenced claim must use array of strings values.
-                          properties:
-                            claim:
-                              description: Claim is a JWT token claim to be used in
-                                the mapping
-                              type: string
-                            prefix:
-                              description: "Prefix is a string to prefix the value
-                                from the token in the result of the claim mapping.
-                                \n By default, no prefixing occurs. \n Example: if
-                                `prefix` is set to \"myoidc:\"\" and the `claim` in
-                                JWT contains an array of strings \"a\", \"b\" and
-                                \ \"c\", the mapping will result in an array of string
-                                \"myoidc:a\", \"myoidc:b\" and \"myoidc:c\"."
-                              type: string
-                          required:
-                          - claim
-                          type: object
-                        username:
-                          description: "Username is a name of the claim that should
-                            be used to construct usernames for the cluster identity.
-                            \n Default value: \"sub\""
-                          properties:
-                            claim:
-                              description: Claim is a JWT token claim to be used in
-                                the mapping
-                              type: string
-                            prefix:
-                              properties:
-                                prefixString:
-                                  minLength: 1
-                                  type: string
-                              required:
-                              - prefixString
-                              type: object
-                            prefixPolicy:
-                              description: "PrefixPolicy specifies how a prefix should
-                                apply. \n By default, claims other than `email` will
-                                be prefixed with the issuer URL to prevent naming
-                                clashes with other plugins. \n Set to \"NoPrefix\"
-                                to disable prefixing. \n Example: (1) `prefix` is
-                                set to \"myoidc:\" and `claim` is set to \"username\".
-                                If the JWT claim `username` contains value `userA`,
-                                the resulting mapped value will be \"myoidc:userA\".
-                                (2) `prefix` is set to \"myoidc:\" and `claim` is
-                                set to \"email\". If the JWT `email` claim contains
-                                value \"userA@myoidc.tld\", the resulting mapped value
-                                will be \"myoidc:userA@myoidc.tld\". (3) `prefix`
-                                is unset, `issuerURL` is set to `https://myoidc.tld`,
-                                the JWT claims include \"username\":\"userA\" and
-                                \"email\":\"userA@myoidc.tld\", and `claim` is set
-                                to: (a) \"username\": the mapped value will be \"https://myoidc.tld#userA\"
-                                (b) \"email\": the mapped value will be \"userA@myoidc.tld\""
-                              enum:
-                              - ""
-                              - NoPrefix
-                              - Prefix
-                              type: string
-                          required:
-                          - claim
-                          type: object
-                          x-kubernetes-validations:
-                          - message: prefix must be set if prefixPolicy is 'Prefix',
-                              but must remain unset otherwise
-                            rule: 'has(self.prefixPolicy) && self.prefixPolicy ==
-                              ''Prefix'' ? (has(self.prefix) && size(self.prefix.prefixString)
-                              > 0) : !has(self.prefix)'
-                      type: object
-                    claimValidationRules:
-                      description: ClaimValidationRules are rules that are applied
-                        to validate token claims to authenticate users.
-                      items:
-                        properties:
-                          requiredClaim:
-                            description: RequiredClaim allows configuring a required
-                              claim name and its expected value
-                            properties:
-                              claim:
-                                description: Claim is a name of a required claim.
-                                  Only claims with string values are supported.
-                                minLength: 1
-                                type: string
-                              requiredValue:
-                                description: RequiredValue is the required value for
-                                  the claim.
-                                minLength: 1
-                                type: string
-                            required:
-                            - claim
-                            - requiredValue
-                            type: object
-                          type:
-                            default: RequiredClaim
-                            description: Type sets the type of the validation rule
-                            enum:
-                            - RequiredClaim
-                            type: string
-                        type: object
-                      type: array
-                      x-kubernetes-list-type: atomic
-                    issuer:
-                      description: Issuer describes atributes of the OIDC token issuer
-                      properties:
-                        audiences:
-                          description: Audiences is an array of audiences that the
-                            token was issued for. Valid tokens must include at least
-                            one of these values in their "aud" claim. Must be set
-                            to exactly one value.
-                          items:
-                            minLength: 1
-                            type: string
-                          maxItems: 10
-                          minItems: 1
-                          type: array
-                          x-kubernetes-list-type: set
-                        issuerCertificateAuthority:
-                          description: CertificateAuthority is a reference to a config
-                            map in the configuration namespace. The .data of the configMap
-                            must contain the "ca-bundle.crt" key. If unset, system
-                            trust is used instead.
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                config map
-                              type: string
-                          required:
-                          - name
-                          type: object
-                        issuerURL:
-                          description: URL is the serving URL of the token issuer.
-                            Must use the https:// scheme.
-                          pattern: ^https:\/\/[^\s]
-                          type: string
-                      required:
-                      - audiences
-                      - issuerURL
-                      type: object
-                    name:
-                      description: Name of the OIDC provider
-                      minLength: 1
-                      type: string
-                    oidcClients:
-                      description: OIDCClients contains configuration for the platform's
-                        clients that need to request tokens from the issuer
-                      items:
-                        properties:
-                          clientID:
-                            description: ClientID is the identifier of the OIDC client
-                              from the OIDC provider
-                            minLength: 1
-                            type: string
-                          clientSecret:
-                            description: ClientSecret refers to a secret in the `openshift-config`
-                              namespace that contains the client secret in the `clientSecret`
-                              key of the `.data` field
-                            properties:
-                              name:
-                                description: name is the metadata.name of the referenced
-                                  secret
-                                type: string
-                            required:
-                            - name
-                            type: object
-                          componentName:
-                            description: ComponentName is the name of the component
-                              that is supposed to consume this client configuration
-                            maxLength: 256
-                            minLength: 1
-                            type: string
-                          componentNamespace:
-                            description: ComponentNamespace is the namespace of the
-                              component that is supposed to consume this client configuration
-                            maxLength: 63
-                            minLength: 1
-                            type: string
-                          extraScopes:
-                            description: ExtraScopes is an optional set of scopes
-                              to request tokens with.
-                            items:
-                              type: string
-                            type: array
-                            x-kubernetes-list-type: set
-                        required:
-                        - clientID
-                        - componentName
-                        - componentNamespace
-                        type: object
-                      maxItems: 20
-                      type: array
-                      x-kubernetes-list-map-keys:
-                      - componentNamespace
-                      - componentName
-                      x-kubernetes-list-type: map
-                  required:
-                  - issuer
-                  - name
-                  type: object
-                maxItems: 1
-                type: array
-                x-kubernetes-list-map-keys:
-                - name
-                x-kubernetes-list-type: map
-              serviceAccountIssuer:
-                description: 'serviceAccountIssuer is the identifier of the bound
-                  service account token issuer. The default is https://kubernetes.default.svc
-                  WARNING: Updating this field will not result in immediate invalidation
-                  of all bound tokens with the previous issuer value. Instead, the
-                  tokens issued by previous service account issuer will continue to
-                  be trusted for a time period chosen by the platform (currently set
-                  to 24h). This time period is subject to change over time. This allows
-                  internal components to transition to use new service account issuer
-                  without service distruption.'
-                type: string
-              type:
-                description: type identifies the cluster managed, user facing authentication
-                  mode in use. Specifically, it manages the component that responds
-                  to login attempts. The default is IntegratedOAuth.
-                enum:
-                - ""
-                - None
-                - IntegratedOAuth
-                - OIDC
-                type: string
-              webhookTokenAuthenticator:
-                description: "webhookTokenAuthenticator configures a remote token
-                  reviewer. These remote authentication webhooks can be used to verify
-                  bearer tokens via the tokenreviews.authentication.k8s.io REST API.
-                  This is required to honor bearer tokens that are provisioned by
-                  an external authentication service. \n Can only be set if \"Type\"
-                  is set to \"None\"."
-                properties:
-                  kubeConfig:
-                    description: "kubeConfig references a secret that contains kube
-                      config file data which describes how to access the remote webhook
-                      service. The namespace for the referenced secret is openshift-config.
-                      \n For further details, see: \n https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication
-                      \n The key \"kubeConfig\" is used to locate the data. If the
-                      secret or expected key is not found, the webhook is not honored.
-                      If the specified kube config data is not valid, the webhook
-                      is not honored."
-                    properties:
-                      name:
-                        description: name is the metadata.name of the referenced secret
-                        type: string
-                    required:
-                    - name
-                    type: object
-                required:
-                - kubeConfig
-                type: object
-              webhookTokenAuthenticators:
-                description: webhookTokenAuthenticators is DEPRECATED, setting it
-                  has no effect.
-                items:
-                  description: deprecatedWebhookTokenAuthenticator holds the necessary
-                    configuration options for a remote token authenticator. It's the
-                    same as WebhookTokenAuthenticator but it's missing the 'required'
-                    validation on KubeConfig field.
-                  properties:
-                    kubeConfig:
-                      description: 'kubeConfig contains kube config file data which
-                        describes how to access the remote webhook service. For further
-                        details, see: https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication
-                        The key "kubeConfig" is used to locate the data. If the secret
-                        or expected key is not found, the webhook is not honored.
-                        If the specified kube config data is not valid, the webhook
-                        is not honored. The namespace for this secret is determined
-                        by the point of use.'
-                      properties:
-                        name:
-                          description: name is the metadata.name of the referenced
-                            secret
-                          type: string
-                      required:
-                      - name
-                      type: object
-                  type: object
-                type: array
-                x-kubernetes-list-type: atomic
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            properties:
-              integratedOAuthMetadata:
-                description: 'integratedOAuthMetadata contains the discovery endpoint
-                  data for OAuth 2.0 Authorization Server Metadata for the in-cluster
-                  integrated OAuth server. This discovery document can be viewed from
-                  its served location: oc get --raw ''/.well-known/oauth-authorization-server''
-                  For further details, see the IETF Draft: https://tools.ietf.org/html/draft-ietf-oauth-discovery-04#section-2
-                  This contains the observed value based on cluster state. An explicitly
-                  set value in spec.oauthMetadata has precedence over this field.
-                  This field has no meaning if authentication spec.type is not set
-                  to IntegratedOAuth. The key "oauthMetadata" is used to locate the
-                  data. If the config map or expected key is not found, no metadata
-                  is served. If the specified metadata is not valid, no metadata is
-                  served. The namespace for this config map is openshift-config-managed.'
-                properties:
-                  name:
-                    description: name is the metadata.name of the referenced config
-                      map
-                    type: string
-                required:
-                - name
-                type: object
-              oidcClients:
-                description: OIDCClients is where participating operators place the
-                  current OIDC client status for OIDC clients that can be customized
-                  by the cluster-admin.
-                items:
-                  properties:
-                    componentName:
-                      description: ComponentName is the name of the component that
-                        will consume a client configuration.
-                      maxLength: 256
-                      minLength: 1
-                      type: string
-                    componentNamespace:
-                      description: ComponentNamespace is the namespace of the component
-                        that will consume a client configuration.
-                      maxLength: 63
-                      minLength: 1
-                      type: string
-                    conditions:
-                      description: "Conditions are used to communicate the state of
-                        the `oidcClients` entry. \n Supported conditions include Available,
-                        Degraded and Progressing. \n If Available is true, the component
-                        is successfully using the configured client. If Degraded is
-                        true, that means something has gone wrong trying to handle
-                        the client configuration. If Progressing is true, that means
-                        the component is taking some action related to the `oidcClients`
-                        entry."
-                      items:
-                        description: "Condition contains details for one aspect of
-                          the current state of this API Resource. --- This struct
-                          is intended for direct use as an array at the field path
-                          .status.conditions.  For example, \n type FooStatus struct{
-                          // Represents the observations of a foo's current state.
-                          // Known .status.conditions.type are: \"Available\", \"Progressing\",
-                          and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
-                          // +listType=map // +listMapKey=type Conditions []metav1.Condition
-                          `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
-                          protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields
-                          }"
-                        properties:
-                          lastTransitionTime:
-                            description: lastTransitionTime is the last time the condition
-                              transitioned from one status to another. This should
-                              be when the underlying condition changed.  If that is
-                              not known, then using the time when the API field changed
-                              is acceptable.
-                            format: date-time
-                            type: string
-                          message:
-                            description: message is a human readable message indicating
-                              details about the transition. This may be an empty string.
-                            maxLength: 32768
-                            type: string
-                          observedGeneration:
-                            description: observedGeneration represents the .metadata.generation
-                              that the condition was set based upon. For instance,
-                              if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration
-                              is 9, the condition is out of date with respect to the
-                              current state of the instance.
-                            format: int64
-                            minimum: 0
-                            type: integer
-                          reason:
-                            description: reason contains a programmatic identifier
-                              indicating the reason for the condition's last transition.
-                              Producers of specific condition types may define expected
-                              values and meanings for this field, and whether the
-                              values are considered a guaranteed API. The value should
-                              be a CamelCase string. This field may not be empty.
-                            maxLength: 1024
-                            minLength: 1
-                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
-                            type: string
-                          status:
-                            description: status of the condition, one of True, False,
-                              Unknown.
-                            enum:
-                            - "True"
-                            - "False"
-                            - Unknown
-                            type: string
-                          type:
-                            description: type of condition in CamelCase or in foo.example.com/CamelCase.
-                              --- Many .condition.type values are consistent across
-                              resources like Available, but because arbitrary conditions
-                              can be useful (see .node.status.conditions), the ability
-                              to deconflict is important. The regex it matches is
-                              (dns1123SubdomainFmt/)?(qualifiedNameFmt)
-                            maxLength: 316
-                            pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
-                            type: string
-                        required:
-                        - lastTransitionTime
-                        - message
-                        - reason
-                        - status
-                        - type
-                        type: object
-                      type: array
-                      x-kubernetes-list-map-keys:
-                      - type
-                      x-kubernetes-list-type: map
-                    consumingUsers:
-                      description: ConsumingUsers is a slice of ServiceAccounts that
-                        need to have read permission on the `clientSecret` secret.
-                      items:
-                        description: ConsumingUser is an alias for string which we
-                          add validation to. Currently only service accounts are supported.
-                        maxLength: 512
-                        minLength: 1
-                        pattern: ^system:serviceaccount:[a-z0-9]([-a-z0-9]*[a-z0-9])?:[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
-                        type: string
-                      maxItems: 5
-                      type: array
-                      x-kubernetes-list-type: set
-                    currentOIDCClients:
-                      description: CurrentOIDCClients is a list of clients that the
-                        component is currently using.
-                      items:
-                        properties:
-                          clientID:
-                            description: ClientID is the identifier of the OIDC client
-                              from the OIDC provider
-                            minLength: 1
-                            type: string
-                          issuerURL:
-                            description: URL is the serving URL of the token issuer.
-                              Must use the https:// scheme.
-                            pattern: ^https:\/\/[^\s]
-                            type: string
-                          oidcProviderName:
-                            description: OIDCName refers to the `name` of the provider
-                              from `oidcProviders`
-                            minLength: 1
-                            type: string
-                        required:
-                        - clientID
-                        - issuerURL
-                        - oidcProviderName
-                        type: object
-                      type: array
-                      x-kubernetes-list-map-keys:
-                      - issuerURL
-                      - clientID
-                      x-kubernetes-list-type: map
-                  required:
-                  - componentName
-                  - componentNamespace
-                  type: object
-                maxItems: 20
-                type: array
-                x-kubernetes-list-map-keys:
-                - componentNamespace
-                - componentName
-                x-kubernetes-list-type: map
-            type: object
-        required:
-        - spec
-        type: object
-        x-kubernetes-validations:
-        - message: all oidcClients in the oidcProviders must match their componentName
-            and componentNamespace to either a previously configured oidcClient or
-            they must exist in the status.oidcClients
-          rule: '!has(self.spec.oidcProviders) || self.spec.oidcProviders.all(p, !has(p.oidcClients)
-            || p.oidcClients.all(specC, self.status.oidcClients.exists(statusC, statusC.componentNamespace
-            == specC.componentNamespace && statusC.componentName == specC.componentName)
-            || (has(oldSelf.spec.oidcProviders) && oldSelf.spec.oidcProviders.exists(oldP,
-            oldP.name == p.name && has(oldP.oidcClients) && oldP.oidcClients.exists(oldC,
-            oldC.componentNamespace == specC.componentNamespace && oldC.componentName
-            == specC.componentName)))))'
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-Default-Hypershift.yaml-patch b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-Default-Hypershift.yaml-patch
deleted file mode 100644
index dcc254fb..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-Default-Hypershift.yaml-patch
+++ /dev/null
@@ -1,285 +0,0 @@
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/oidcProviders
-  value:
-    description: "OIDCProviders are OIDC identity providers that can issue tokens for this cluster Can only be set if \"Type\" is set to \"OIDC\". \n At most one provider can be configured."
-    type: array
-    maxItems: 1
-    items:
-      type: object
-      required:
-        - issuer
-        - name
-      properties:
-        claimMappings:
-          description: ClaimMappings describes rules on how to transform information from an ID token into a cluster identity
-          type: object
-          properties:
-            groups:
-              description: Groups is a name of the claim that should be used to construct groups for the cluster identity. The referenced claim must use array of strings values.
-              type: object
-              required:
-                - claim
-              properties:
-                claim:
-                  description: Claim is a JWT token claim to be used in the mapping
-                  type: string
-                prefix:
-                  description: "Prefix is a string to prefix the value from the token in the result of the claim mapping. \n By default, no prefixing occurs. \n Example: if `prefix` is set to \"myoidc:\"\" and the `claim` in JWT contains an array of strings \"a\", \"b\" and  \"c\", the mapping will result in an array of string \"myoidc:a\", \"myoidc:b\" and \"myoidc:c\"."
-                  type: string
-            username:
-              description: "Username is a name of the claim that should be used to construct usernames for the cluster identity. \n Default value: \"sub\""
-              type: object
-              required:
-                - claim
-              properties:
-                claim:
-                  description: Claim is a JWT token claim to be used in the mapping
-                  type: string
-                prefix:
-                  type: object
-                  required:
-                    - prefixString
-                  properties:
-                    prefixString:
-                      type: string
-                      minLength: 1
-                prefixPolicy:
-                  description: "PrefixPolicy specifies how a prefix should apply. \n By default, claims other than `email` will be prefixed with the issuer URL to prevent naming clashes with other plugins. \n Set to \"NoPrefix\" to disable prefixing. \n Example: (1) `prefix` is set to \"myoidc:\" and `claim` is set to \"username\". If the JWT claim `username` contains value `userA`, the resulting mapped value will be \"myoidc:userA\". (2) `prefix` is set to \"myoidc:\" and `claim` is set to \"email\". If the JWT `email` claim contains value \"userA@myoidc.tld\", the resulting mapped value will be \"myoidc:userA@myoidc.tld\". (3) `prefix` is unset, `issuerURL` is set to `https://myoidc.tld`, the JWT claims include \"username\":\"userA\" and \"email\":\"userA@myoidc.tld\", and `claim` is set to: (a) \"username\": the mapped value will be \"https://myoidc.tld#userA\" (b) \"email\": the mapped value will be \"userA@myoidc.tld\""
-                  type: string
-                  enum:
-                    - ""
-                    - NoPrefix
-                    - Prefix
-              x-kubernetes-validations:
-                - rule: 'has(self.prefixPolicy) && self.prefixPolicy == ''Prefix'' ? (has(self.prefix) && size(self.prefix.prefixString) > 0) : !has(self.prefix)'
-                  message: prefix must be set if prefixPolicy is 'Prefix', but must remain unset otherwise
-        claimValidationRules:
-          description: ClaimValidationRules are rules that are applied to validate token claims to authenticate users.
-          type: array
-          items:
-            type: object
-            properties:
-              requiredClaim:
-                description: RequiredClaim allows configuring a required claim name and its expected value
-                type: object
-                required:
-                  - claim
-                  - requiredValue
-                properties:
-                  claim:
-                    description: Claim is a name of a required claim. Only claims with string values are supported.
-                    type: string
-                    minLength: 1
-                  requiredValue:
-                    description: RequiredValue is the required value for the claim.
-                    type: string
-                    minLength: 1
-              type:
-                description: Type sets the type of the validation rule
-                type: string
-                default: RequiredClaim
-                enum:
-                  - RequiredClaim
-          x-kubernetes-list-type: atomic
-        issuer:
-          description: Issuer describes atributes of the OIDC token issuer
-          type: object
-          required:
-            - audiences
-            - issuerURL
-          properties:
-            audiences:
-              description: Audiences is an array of audiences that the token was issued for. Valid tokens must include at least one of these values in their "aud" claim. Must be set to exactly one value.
-              type: array
-              maxItems: 10
-              minItems: 1
-              items:
-                type: string
-                minLength: 1
-              x-kubernetes-list-type: set
-            issuerCertificateAuthority:
-              description: CertificateAuthority is a reference to a config map in the configuration namespace. The .data of the configMap must contain the "ca-bundle.crt" key. If unset, system trust is used instead.
-              type: object
-              required:
-                - name
-              properties:
-                name:
-                  description: name is the metadata.name of the referenced config map
-                  type: string
-            issuerURL:
-              description: URL is the serving URL of the token issuer. Must use the https:// scheme.
-              type: string
-              pattern: ^https:\/\/[^\s]
-        name:
-          description: Name of the OIDC provider
-          type: string
-          minLength: 1
-        oidcClients:
-          description: OIDCClients contains configuration for the platform's clients that need to request tokens from the issuer
-          type: array
-          maxItems: 20
-          items:
-            type: object
-            required:
-              - clientID
-              - componentName
-              - componentNamespace
-            properties:
-              clientID:
-                description: ClientID is the identifier of the OIDC client from the OIDC provider
-                type: string
-                minLength: 1
-              clientSecret:
-                description: ClientSecret refers to a secret in the `openshift-config` namespace that contains the client secret in the `clientSecret` key of the `.data` field
-                type: object
-                required:
-                  - name
-                properties:
-                  name:
-                    description: name is the metadata.name of the referenced secret
-                    type: string
-              componentName:
-                description: ComponentName is the name of the component that is supposed to consume this client configuration
-                type: string
-                maxLength: 256
-                minLength: 1
-              componentNamespace:
-                description: ComponentNamespace is the namespace of the component that is supposed to consume this client configuration
-                type: string
-                maxLength: 63
-                minLength: 1
-              extraScopes:
-                description: ExtraScopes is an optional set of scopes to request tokens with.
-                type: array
-                items:
-                  type: string
-                x-kubernetes-list-type: set
-          x-kubernetes-list-map-keys:
-            - componentNamespace
-            - componentName
-          x-kubernetes-list-type: map
-    x-kubernetes-list-map-keys:
-      - name
-    x-kubernetes-list-type: map
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/status/properties/oidcClients
-  value:
-    description: OIDCClients is where participating operators place the current OIDC client status for OIDC clients that can be customized by the cluster-admin.
-    items:
-      properties:
-        componentName:
-          description: ComponentName is the name of the component that will consume a client configuration.
-          maxLength: 256
-          minLength: 1
-          type: string
-        componentNamespace:
-          description: ComponentNamespace is the namespace of the component that will consume a client configuration.
-          maxLength: 63
-          minLength: 1
-          type: string
-        conditions:
-          description: "Conditions are used to communicate the state of the `oidcClients` entry. \n Supported conditions include Available, Degraded and Progressing. \n If Available is true, the component is successfully using the configured client. If Degraded is true, that means something has gone wrong trying to handle the client configuration. If Progressing is true, that means the component is taking some action related to the `oidcClients` entry."
-          items:
-            description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions.  For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
-            properties:
-              lastTransitionTime:
-                description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.
-                format: date-time
-                type: string
-              message:
-                description: message is a human readable message indicating details about the transition. This may be an empty string.
-                maxLength: 32768
-                type: string
-              observedGeneration:
-                description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.
-                format: int64
-                minimum: 0
-                type: integer
-              reason:
-                description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
-                maxLength: 1024
-                minLength: 1
-                pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
-                type: string
-              status:
-                description: status of the condition, one of True, False, Unknown.
-                enum:
-                  - "True"
-                  - "False"
-                  - Unknown
-                type: string
-              type:
-                description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
-                maxLength: 316
-                pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
-                type: string
-            required:
-              - lastTransitionTime
-              - message
-              - reason
-              - status
-              - type
-            type: object
-          type: array
-          x-kubernetes-list-map-keys:
-            - type
-          x-kubernetes-list-type: map
-        consumingUsers:
-          description: ConsumingUsers is a slice of ServiceAccounts that need to have read permission on the `clientSecret` secret.
-          items:
-            description: ConsumingUser is an alias for string which we add validation to. Currently only service accounts are supported.
-            maxLength: 512
-            minLength: 1
-            pattern: ^system:serviceaccount:[a-z0-9]([-a-z0-9]*[a-z0-9])?:[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
-            type: string
-          maxItems: 5
-          type: array
-          x-kubernetes-list-type: set
-        currentOIDCClients:
-          description: CurrentOIDCClients is a list of clients that the component is currently using.
-          items:
-            properties:
-              clientID:
-                description: ClientID is the identifier of the OIDC client from the OIDC provider
-                minLength: 1
-                type: string
-              issuerURL:
-                description: URL is the serving URL of the token issuer. Must use the https:// scheme.
-                pattern: ^https:\/\/[^\s]
-                type: string
-              oidcProviderName:
-                description: OIDCName refers to the `name` of the provider from `oidcProviders`
-                minLength: 1
-                type: string
-            required:
-              - clientID
-              - issuerURL
-              - oidcProviderName
-            type: object
-          type: array
-          x-kubernetes-list-map-keys:
-            - issuerURL
-            - clientID
-          x-kubernetes-list-type: map
-      required:
-        - componentName
-        - componentNamespace
-      type: object
-    maxItems: 20
-    type: array
-    x-kubernetes-list-map-keys:
-      - componentNamespace
-      - componentName
-    x-kubernetes-list-type: map
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/x-kubernetes-validations
-  value:
-    - message: all oidcClients in the oidcProviders must match their componentName and componentNamespace to either a previously configured oidcClient or they must exist in the status.oidcClients
-      rule: '!has(self.spec.oidcProviders) || self.spec.oidcProviders.all(p, !has(p.oidcClients) || p.oidcClients.all(specC, self.status.oidcClients.exists(statusC, statusC.componentNamespace == specC.componentNamespace && statusC.componentName == specC.componentName) || (has(oldSelf.spec.oidcProviders) && oldSelf.spec.oidcProviders.exists(oldP, oldP.name == p.name && has(oldP.oidcClients) && oldP.oidcClients.exists(oldC, oldC.componentNamespace == specC.componentNamespace && oldC.componentName == specC.componentName)))))'
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/type/enum
-  value:
-    - ""
-    - None
-    - IntegratedOAuth
-    - OIDC
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-Default.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-Default.yaml
deleted file mode 100644
index 87e2434d..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-Default.yaml
+++ /dev/null
@@ -1,171 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    release.openshift.io/feature-set: Default
-  name: authentications.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: Authentication
-    listKind: AuthenticationList
-    plural: authentications
-    singular: authentication
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "Authentication specifies cluster-wide settings for authentication
-          (like OAuth and webhook token authenticators). The canonical name of an
-          instance is `cluster`. \n Compatibility level 1: Stable within a major release
-          for a minimum of 12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              oauthMetadata:
-                description: 'oauthMetadata contains the discovery endpoint data for
-                  OAuth 2.0 Authorization Server Metadata for an external OAuth server.
-                  This discovery document can be viewed from its served location:
-                  oc get --raw ''/.well-known/oauth-authorization-server'' For further
-                  details, see the IETF Draft: https://tools.ietf.org/html/draft-ietf-oauth-discovery-04#section-2
-                  If oauthMetadata.name is non-empty, this value has precedence over
-                  any metadata reference stored in status. The key "oauthMetadata"
-                  is used to locate the data. If specified and the config map or expected
-                  key is not found, no metadata is served. If the specified metadata
-                  is not valid, no metadata is served. The namespace for this config
-                  map is openshift-config.'
-                properties:
-                  name:
-                    description: name is the metadata.name of the referenced config
-                      map
-                    type: string
-                required:
-                - name
-                type: object
-              serviceAccountIssuer:
-                description: 'serviceAccountIssuer is the identifier of the bound
-                  service account token issuer. The default is https://kubernetes.default.svc
-                  WARNING: Updating this field will not result in immediate invalidation
-                  of all bound tokens with the previous issuer value. Instead, the
-                  tokens issued by previous service account issuer will continue to
-                  be trusted for a time period chosen by the platform (currently set
-                  to 24h). This time period is subject to change over time. This allows
-                  internal components to transition to use new service account issuer
-                  without service distruption.'
-                type: string
-              type:
-                description: type identifies the cluster managed, user facing authentication
-                  mode in use. Specifically, it manages the component that responds
-                  to login attempts. The default is IntegratedOAuth.
-                enum:
-                - ""
-                - None
-                - IntegratedOAuth
-                type: string
-              webhookTokenAuthenticator:
-                description: "webhookTokenAuthenticator configures a remote token
-                  reviewer. These remote authentication webhooks can be used to verify
-                  bearer tokens via the tokenreviews.authentication.k8s.io REST API.
-                  This is required to honor bearer tokens that are provisioned by
-                  an external authentication service. \n Can only be set if \"Type\"
-                  is set to \"None\"."
-                properties:
-                  kubeConfig:
-                    description: "kubeConfig references a secret that contains kube
-                      config file data which describes how to access the remote webhook
-                      service. The namespace for the referenced secret is openshift-config.
-                      \n For further details, see: \n https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication
-                      \n The key \"kubeConfig\" is used to locate the data. If the
-                      secret or expected key is not found, the webhook is not honored.
-                      If the specified kube config data is not valid, the webhook
-                      is not honored."
-                    properties:
-                      name:
-                        description: name is the metadata.name of the referenced secret
-                        type: string
-                    required:
-                    - name
-                    type: object
-                required:
-                - kubeConfig
-                type: object
-              webhookTokenAuthenticators:
-                description: webhookTokenAuthenticators is DEPRECATED, setting it
-                  has no effect.
-                items:
-                  description: deprecatedWebhookTokenAuthenticator holds the necessary
-                    configuration options for a remote token authenticator. It's the
-                    same as WebhookTokenAuthenticator but it's missing the 'required'
-                    validation on KubeConfig field.
-                  properties:
-                    kubeConfig:
-                      description: 'kubeConfig contains kube config file data which
-                        describes how to access the remote webhook service. For further
-                        details, see: https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication
-                        The key "kubeConfig" is used to locate the data. If the secret
-                        or expected key is not found, the webhook is not honored.
-                        If the specified kube config data is not valid, the webhook
-                        is not honored. The namespace for this secret is determined
-                        by the point of use.'
-                      properties:
-                        name:
-                          description: name is the metadata.name of the referenced
-                            secret
-                          type: string
-                      required:
-                      - name
-                      type: object
-                  type: object
-                type: array
-                x-kubernetes-list-type: atomic
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            properties:
-              integratedOAuthMetadata:
-                description: 'integratedOAuthMetadata contains the discovery endpoint
-                  data for OAuth 2.0 Authorization Server Metadata for the in-cluster
-                  integrated OAuth server. This discovery document can be viewed from
-                  its served location: oc get --raw ''/.well-known/oauth-authorization-server''
-                  For further details, see the IETF Draft: https://tools.ietf.org/html/draft-ietf-oauth-discovery-04#section-2
-                  This contains the observed value based on cluster state. An explicitly
-                  set value in spec.oauthMetadata has precedence over this field.
-                  This field has no meaning if authentication spec.type is not set
-                  to IntegratedOAuth. The key "oauthMetadata" is used to locate the
-                  data. If the config map or expected key is not found, no metadata
-                  is served. If the specified metadata is not valid, no metadata is
-                  served. The namespace for this config map is openshift-config-managed.'
-                properties:
-                  name:
-                    description: name is the metadata.name of the referenced config
-                      map
-                    type: string
-                required:
-                - name
-                type: object
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-TechPreviewNoUpgrade.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-TechPreviewNoUpgrade.yaml
deleted file mode 100644
index cf6913a8..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-TechPreviewNoUpgrade.yaml
+++ /dev/null
@@ -1,555 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    formatted: "true"
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    release.openshift.io/feature-set: TechPreviewNoUpgrade
-  name: authentications.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: Authentication
-    listKind: AuthenticationList
-    plural: authentications
-    singular: authentication
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "Authentication specifies cluster-wide settings for authentication
-          (like OAuth and webhook token authenticators). The canonical name of an
-          instance is `cluster`. \n Compatibility level 1: Stable within a major release
-          for a minimum of 12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              oauthMetadata:
-                description: 'oauthMetadata contains the discovery endpoint data for
-                  OAuth 2.0 Authorization Server Metadata for an external OAuth server.
-                  This discovery document can be viewed from its served location:
-                  oc get --raw ''/.well-known/oauth-authorization-server'' For further
-                  details, see the IETF Draft: https://tools.ietf.org/html/draft-ietf-oauth-discovery-04#section-2
-                  If oauthMetadata.name is non-empty, this value has precedence over
-                  any metadata reference stored in status. The key "oauthMetadata"
-                  is used to locate the data. If specified and the config map or expected
-                  key is not found, no metadata is served. If the specified metadata
-                  is not valid, no metadata is served. The namespace for this config
-                  map is openshift-config.'
-                properties:
-                  name:
-                    description: name is the metadata.name of the referenced config
-                      map
-                    type: string
-                required:
-                - name
-                type: object
-              oidcProviders:
-                description: "OIDCProviders are OIDC identity providers that can issue
-                  tokens for this cluster Can only be set if \"Type\" is set to \"OIDC\".
-                  \n At most one provider can be configured."
-                items:
-                  properties:
-                    claimMappings:
-                      description: ClaimMappings describes rules on how to transform
-                        information from an ID token into a cluster identity
-                      properties:
-                        groups:
-                          description: Groups is a name of the claim that should be
-                            used to construct groups for the cluster identity. The
-                            referenced claim must use array of strings values.
-                          properties:
-                            claim:
-                              description: Claim is a JWT token claim to be used in
-                                the mapping
-                              type: string
-                            prefix:
-                              description: "Prefix is a string to prefix the value
-                                from the token in the result of the claim mapping.
-                                \n By default, no prefixing occurs. \n Example: if
-                                `prefix` is set to \"myoidc:\"\" and the `claim` in
-                                JWT contains an array of strings \"a\", \"b\" and
-                                \ \"c\", the mapping will result in an array of string
-                                \"myoidc:a\", \"myoidc:b\" and \"myoidc:c\"."
-                              type: string
-                          required:
-                          - claim
-                          type: object
-                        username:
-                          description: "Username is a name of the claim that should
-                            be used to construct usernames for the cluster identity.
-                            \n Default value: \"sub\""
-                          properties:
-                            claim:
-                              description: Claim is a JWT token claim to be used in
-                                the mapping
-                              type: string
-                            prefix:
-                              properties:
-                                prefixString:
-                                  minLength: 1
-                                  type: string
-                              required:
-                              - prefixString
-                              type: object
-                            prefixPolicy:
-                              description: "PrefixPolicy specifies how a prefix should
-                                apply. \n By default, claims other than `email` will
-                                be prefixed with the issuer URL to prevent naming
-                                clashes with other plugins. \n Set to \"NoPrefix\"
-                                to disable prefixing. \n Example: (1) `prefix` is
-                                set to \"myoidc:\" and `claim` is set to \"username\".
-                                If the JWT claim `username` contains value `userA`,
-                                the resulting mapped value will be \"myoidc:userA\".
-                                (2) `prefix` is set to \"myoidc:\" and `claim` is
-                                set to \"email\". If the JWT `email` claim contains
-                                value \"userA@myoidc.tld\", the resulting mapped value
-                                will be \"myoidc:userA@myoidc.tld\". (3) `prefix`
-                                is unset, `issuerURL` is set to `https://myoidc.tld`,
-                                the JWT claims include \"username\":\"userA\" and
-                                \"email\":\"userA@myoidc.tld\", and `claim` is set
-                                to: (a) \"username\": the mapped value will be \"https://myoidc.tld#userA\"
-                                (b) \"email\": the mapped value will be \"userA@myoidc.tld\""
-                              enum:
-                              - ""
-                              - NoPrefix
-                              - Prefix
-                              type: string
-                          required:
-                          - claim
-                          type: object
-                          x-kubernetes-validations:
-                          - message: prefix must be set if prefixPolicy is 'Prefix',
-                              but must remain unset otherwise
-                            rule: 'has(self.prefixPolicy) && self.prefixPolicy ==
-                              ''Prefix'' ? (has(self.prefix) && size(self.prefix.prefixString)
-                              > 0) : !has(self.prefix)'
-                      type: object
-                    claimValidationRules:
-                      description: ClaimValidationRules are rules that are applied
-                        to validate token claims to authenticate users.
-                      items:
-                        properties:
-                          requiredClaim:
-                            description: RequiredClaim allows configuring a required
-                              claim name and its expected value
-                            properties:
-                              claim:
-                                description: Claim is a name of a required claim.
-                                  Only claims with string values are supported.
-                                minLength: 1
-                                type: string
-                              requiredValue:
-                                description: RequiredValue is the required value for
-                                  the claim.
-                                minLength: 1
-                                type: string
-                            required:
-                            - claim
-                            - requiredValue
-                            type: object
-                          type:
-                            default: RequiredClaim
-                            description: Type sets the type of the validation rule
-                            enum:
-                            - RequiredClaim
-                            type: string
-                        type: object
-                      type: array
-                      x-kubernetes-list-type: atomic
-                    issuer:
-                      description: Issuer describes atributes of the OIDC token issuer
-                      properties:
-                        audiences:
-                          description: Audiences is an array of audiences that the
-                            token was issued for. Valid tokens must include at least
-                            one of these values in their "aud" claim. Must be set
-                            to exactly one value.
-                          items:
-                            minLength: 1
-                            type: string
-                          maxItems: 10
-                          minItems: 1
-                          type: array
-                          x-kubernetes-list-type: set
-                        issuerCertificateAuthority:
-                          description: CertificateAuthority is a reference to a config
-                            map in the configuration namespace. The .data of the configMap
-                            must contain the "ca-bundle.crt" key. If unset, system
-                            trust is used instead.
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                config map
-                              type: string
-                          required:
-                          - name
-                          type: object
-                        issuerURL:
-                          description: URL is the serving URL of the token issuer.
-                            Must use the https:// scheme.
-                          pattern: ^https:\/\/[^\s]
-                          type: string
-                      required:
-                      - audiences
-                      - issuerURL
-                      type: object
-                    name:
-                      description: Name of the OIDC provider
-                      minLength: 1
-                      type: string
-                    oidcClients:
-                      description: OIDCClients contains configuration for the platform's
-                        clients that need to request tokens from the issuer
-                      items:
-                        properties:
-                          clientID:
-                            description: ClientID is the identifier of the OIDC client
-                              from the OIDC provider
-                            minLength: 1
-                            type: string
-                          clientSecret:
-                            description: ClientSecret refers to a secret in the `openshift-config`
-                              namespace that contains the client secret in the `clientSecret`
-                              key of the `.data` field
-                            properties:
-                              name:
-                                description: name is the metadata.name of the referenced
-                                  secret
-                                type: string
-                            required:
-                            - name
-                            type: object
-                          componentName:
-                            description: ComponentName is the name of the component
-                              that is supposed to consume this client configuration
-                            maxLength: 256
-                            minLength: 1
-                            type: string
-                          componentNamespace:
-                            description: ComponentNamespace is the namespace of the
-                              component that is supposed to consume this client configuration
-                            maxLength: 63
-                            minLength: 1
-                            type: string
-                          extraScopes:
-                            description: ExtraScopes is an optional set of scopes
-                              to request tokens with.
-                            items:
-                              type: string
-                            type: array
-                            x-kubernetes-list-type: set
-                        required:
-                        - clientID
-                        - componentName
-                        - componentNamespace
-                        type: object
-                      maxItems: 20
-                      type: array
-                      x-kubernetes-list-map-keys:
-                      - componentNamespace
-                      - componentName
-                      x-kubernetes-list-type: map
-                  required:
-                  - issuer
-                  - name
-                  type: object
-                maxItems: 1
-                type: array
-                x-kubernetes-list-map-keys:
-                - name
-                x-kubernetes-list-type: map
-              serviceAccountIssuer:
-                description: 'serviceAccountIssuer is the identifier of the bound
-                  service account token issuer. The default is https://kubernetes.default.svc
-                  WARNING: Updating this field will not result in immediate invalidation
-                  of all bound tokens with the previous issuer value. Instead, the
-                  tokens issued by previous service account issuer will continue to
-                  be trusted for a time period chosen by the platform (currently set
-                  to 24h). This time period is subject to change over time. This allows
-                  internal components to transition to use new service account issuer
-                  without service distruption.'
-                type: string
-              type:
-                description: type identifies the cluster managed, user facing authentication
-                  mode in use. Specifically, it manages the component that responds
-                  to login attempts. The default is IntegratedOAuth.
-                enum:
-                - ""
-                - None
-                - IntegratedOAuth
-                - OIDC
-                type: string
-              webhookTokenAuthenticator:
-                description: "webhookTokenAuthenticator configures a remote token
-                  reviewer. These remote authentication webhooks can be used to verify
-                  bearer tokens via the tokenreviews.authentication.k8s.io REST API.
-                  This is required to honor bearer tokens that are provisioned by
-                  an external authentication service. \n Can only be set if \"Type\"
-                  is set to \"None\"."
-                properties:
-                  kubeConfig:
-                    description: "kubeConfig references a secret that contains kube
-                      config file data which describes how to access the remote webhook
-                      service. The namespace for the referenced secret is openshift-config.
-                      \n For further details, see: \n https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication
-                      \n The key \"kubeConfig\" is used to locate the data. If the
-                      secret or expected key is not found, the webhook is not honored.
-                      If the specified kube config data is not valid, the webhook
-                      is not honored."
-                    properties:
-                      name:
-                        description: name is the metadata.name of the referenced secret
-                        type: string
-                    required:
-                    - name
-                    type: object
-                required:
-                - kubeConfig
-                type: object
-              webhookTokenAuthenticators:
-                description: webhookTokenAuthenticators is DEPRECATED, setting it
-                  has no effect.
-                items:
-                  description: deprecatedWebhookTokenAuthenticator holds the necessary
-                    configuration options for a remote token authenticator. It's the
-                    same as WebhookTokenAuthenticator but it's missing the 'required'
-                    validation on KubeConfig field.
-                  properties:
-                    kubeConfig:
-                      description: 'kubeConfig contains kube config file data which
-                        describes how to access the remote webhook service. For further
-                        details, see: https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication
-                        The key "kubeConfig" is used to locate the data. If the secret
-                        or expected key is not found, the webhook is not honored.
-                        If the specified kube config data is not valid, the webhook
-                        is not honored. The namespace for this secret is determined
-                        by the point of use.'
-                      properties:
-                        name:
-                          description: name is the metadata.name of the referenced
-                            secret
-                          type: string
-                      required:
-                      - name
-                      type: object
-                  type: object
-                type: array
-                x-kubernetes-list-type: atomic
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            properties:
-              integratedOAuthMetadata:
-                description: 'integratedOAuthMetadata contains the discovery endpoint
-                  data for OAuth 2.0 Authorization Server Metadata for the in-cluster
-                  integrated OAuth server. This discovery document can be viewed from
-                  its served location: oc get --raw ''/.well-known/oauth-authorization-server''
-                  For further details, see the IETF Draft: https://tools.ietf.org/html/draft-ietf-oauth-discovery-04#section-2
-                  This contains the observed value based on cluster state. An explicitly
-                  set value in spec.oauthMetadata has precedence over this field.
-                  This field has no meaning if authentication spec.type is not set
-                  to IntegratedOAuth. The key "oauthMetadata" is used to locate the
-                  data. If the config map or expected key is not found, no metadata
-                  is served. If the specified metadata is not valid, no metadata is
-                  served. The namespace for this config map is openshift-config-managed.'
-                properties:
-                  name:
-                    description: name is the metadata.name of the referenced config
-                      map
-                    type: string
-                required:
-                - name
-                type: object
-              oidcClients:
-                description: OIDCClients is where participating operators place the
-                  current OIDC client status for OIDC clients that can be customized
-                  by the cluster-admin.
-                items:
-                  properties:
-                    componentName:
-                      description: ComponentName is the name of the component that
-                        will consume a client configuration.
-                      maxLength: 256
-                      minLength: 1
-                      type: string
-                    componentNamespace:
-                      description: ComponentNamespace is the namespace of the component
-                        that will consume a client configuration.
-                      maxLength: 63
-                      minLength: 1
-                      type: string
-                    conditions:
-                      description: "Conditions are used to communicate the state of
-                        the `oidcClients` entry. \n Supported conditions include Available,
-                        Degraded and Progressing. \n If Available is true, the component
-                        is successfully using the configured client. If Degraded is
-                        true, that means something has gone wrong trying to handle
-                        the client configuration. If Progressing is true, that means
-                        the component is taking some action related to the `oidcClients`
-                        entry."
-                      items:
-                        description: "Condition contains details for one aspect of
-                          the current state of this API Resource. --- This struct
-                          is intended for direct use as an array at the field path
-                          .status.conditions.  For example, \n type FooStatus struct{
-                          // Represents the observations of a foo's current state.
-                          // Known .status.conditions.type are: \"Available\", \"Progressing\",
-                          and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
-                          // +listType=map // +listMapKey=type Conditions []metav1.Condition
-                          `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
-                          protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields
-                          }"
-                        properties:
-                          lastTransitionTime:
-                            description: lastTransitionTime is the last time the condition
-                              transitioned from one status to another. This should
-                              be when the underlying condition changed.  If that is
-                              not known, then using the time when the API field changed
-                              is acceptable.
-                            format: date-time
-                            type: string
-                          message:
-                            description: message is a human readable message indicating
-                              details about the transition. This may be an empty string.
-                            maxLength: 32768
-                            type: string
-                          observedGeneration:
-                            description: observedGeneration represents the .metadata.generation
-                              that the condition was set based upon. For instance,
-                              if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration
-                              is 9, the condition is out of date with respect to the
-                              current state of the instance.
-                            format: int64
-                            minimum: 0
-                            type: integer
-                          reason:
-                            description: reason contains a programmatic identifier
-                              indicating the reason for the condition's last transition.
-                              Producers of specific condition types may define expected
-                              values and meanings for this field, and whether the
-                              values are considered a guaranteed API. The value should
-                              be a CamelCase string. This field may not be empty.
-                            maxLength: 1024
-                            minLength: 1
-                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
-                            type: string
-                          status:
-                            description: status of the condition, one of True, False,
-                              Unknown.
-                            enum:
-                            - "True"
-                            - "False"
-                            - Unknown
-                            type: string
-                          type:
-                            description: type of condition in CamelCase or in foo.example.com/CamelCase.
-                              --- Many .condition.type values are consistent across
-                              resources like Available, but because arbitrary conditions
-                              can be useful (see .node.status.conditions), the ability
-                              to deconflict is important. The regex it matches is
-                              (dns1123SubdomainFmt/)?(qualifiedNameFmt)
-                            maxLength: 316
-                            pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
-                            type: string
-                        required:
-                        - lastTransitionTime
-                        - message
-                        - reason
-                        - status
-                        - type
-                        type: object
-                      type: array
-                      x-kubernetes-list-map-keys:
-                      - type
-                      x-kubernetes-list-type: map
-                    consumingUsers:
-                      description: ConsumingUsers is a slice of ServiceAccounts that
-                        need to have read permission on the `clientSecret` secret.
-                      items:
-                        description: ConsumingUser is an alias for string which we
-                          add validation to. Currently only service accounts are supported.
-                        maxLength: 512
-                        minLength: 1
-                        pattern: ^system:serviceaccount:[a-z0-9]([-a-z0-9]*[a-z0-9])?:[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
-                        type: string
-                      maxItems: 5
-                      type: array
-                      x-kubernetes-list-type: set
-                    currentOIDCClients:
-                      description: CurrentOIDCClients is a list of clients that the
-                        component is currently using.
-                      items:
-                        properties:
-                          clientID:
-                            description: ClientID is the identifier of the OIDC client
-                              from the OIDC provider
-                            minLength: 1
-                            type: string
-                          issuerURL:
-                            description: URL is the serving URL of the token issuer.
-                              Must use the https:// scheme.
-                            pattern: ^https:\/\/[^\s]
-                            type: string
-                          oidcProviderName:
-                            description: OIDCName refers to the `name` of the provider
-                              from `oidcProviders`
-                            minLength: 1
-                            type: string
-                        required:
-                        - clientID
-                        - issuerURL
-                        - oidcProviderName
-                        type: object
-                      type: array
-                      x-kubernetes-list-map-keys:
-                      - issuerURL
-                      - clientID
-                      x-kubernetes-list-type: map
-                  required:
-                  - componentName
-                  - componentNamespace
-                  type: object
-                maxItems: 20
-                type: array
-                x-kubernetes-list-map-keys:
-                - componentNamespace
-                - componentName
-                x-kubernetes-list-type: map
-            type: object
-        required:
-        - spec
-        type: object
-        x-kubernetes-validations:
-        - message: all oidcClients in the oidcProviders must match their componentName
-            and componentNamespace to either a previously configured oidcClient or
-            they must exist in the status.oidcClients
-          rule: '!has(self.spec.oidcProviders) || self.spec.oidcProviders.all(p, !has(p.oidcClients)
-            || p.oidcClients.all(specC, self.status.oidcClients.exists(statusC, statusC.componentNamespace
-            == specC.componentNamespace && statusC.componentName == specC.componentName)
-            || (has(oldSelf.spec.oidcProviders) && oldSelf.spec.oidcProviders.exists(oldP,
-            oldP.name == p.name && has(oldP.oidcClients) && oldP.oidcClients.exists(oldC,
-            oldC.componentNamespace == specC.componentNamespace && oldC.componentName
-            == specC.componentName)))))'
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_console.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_console.crd.yaml
deleted file mode 100644
index ce7f789d..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_console.crd.yaml
+++ /dev/null
@@ -1,75 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-  name: consoles.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: Console
-    listKind: ConsoleList
-    plural: consoles
-    singular: console
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "Console holds cluster-wide configuration for the web console,
-          including the logout URL, and reports the public URL of the console. The
-          canonical name is `cluster`. \n Compatibility level 1: Stable within a major
-          release for a minimum of 12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              authentication:
-                description: ConsoleAuthentication defines a list of optional configuration
-                  for console authentication.
-                properties:
-                  logoutRedirect:
-                    description: 'An optional, absolute URL to redirect web browsers
-                      to after logging out of the console. If not specified, it will
-                      redirect to the default login page. This is required when using
-                      an identity provider that supports single sign-on (SSO) such
-                      as: - OpenID (Keycloak, Azure) - RequestHeader (GSSAPI, SSPI,
-                      SAML) - OAuth (GitHub, GitLab, Google) Logging out of the console
-                      will destroy the user''s token. The logoutRedirect provides
-                      the user the option to perform single logout (SLO) through the
-                      identity provider to destroy their single sign-on session.'
-                    pattern: ^$|^((https):\/\/?)[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|\/?))$
-                    type: string
-                type: object
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            properties:
-              consoleURL:
-                description: The URL for the console. This will be derived from the
-                  host for the route that is created for the console.
-                type: string
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns-CustomNoUpgrade.crd.yaml
deleted file mode 100644
index 7b1bee40..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns-CustomNoUpgrade.crd.yaml
+++ /dev/null
@@ -1,159 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    release.openshift.io/feature-set: CustomNoUpgrade
-  name: dnses.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: DNS
-    listKind: DNSList
-    plural: dnses
-    singular: dns
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "DNS holds cluster-wide information about DNS. The canonical
-          name is `cluster` \n Compatibility level 1: Stable within a major release
-          for a minimum of 12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              baseDomain:
-                description: "baseDomain is the base domain of the cluster. All managed
-                  DNS records will be sub-domains of this base. \n For example, given
-                  the base domain `openshift.example.com`, an API server DNS record
-                  may be created for `cluster-api.openshift.example.com`. \n Once
-                  set, this field cannot be changed."
-                type: string
-              platform:
-                description: platform holds configuration specific to the underlying
-                  infrastructure provider for DNS. When omitted, this means the user
-                  has no opinion and the platform is left to choose reasonable defaults.
-                  These defaults are subject to change over time.
-                properties:
-                  aws:
-                    description: aws contains DNS configuration specific to the Amazon
-                      Web Services cloud provider.
-                    properties:
-                      privateZoneIAMRole:
-                        description: privateZoneIAMRole contains the ARN of an IAM
-                          role that should be assumed when performing operations on
-                          the cluster's private hosted zone specified in the cluster
-                          DNS config. When left empty, no role should be assumed.
-                        pattern: ^arn:(aws|aws-cn|aws-us-gov):iam::[0-9]{12}:role\/.*$
-                        type: string
-                    type: object
-                  type:
-                    description: "type is the underlying infrastructure provider for
-                      the cluster. Allowed values: \"\", \"AWS\". \n Individual components
-                      may not support all platforms, and must handle unrecognized
-                      platforms with best-effort defaults."
-                    enum:
-                    - ""
-                    - AWS
-                    - Azure
-                    - BareMetal
-                    - GCP
-                    - Libvirt
-                    - OpenStack
-                    - None
-                    - VSphere
-                    - oVirt
-                    - IBMCloud
-                    - KubeVirt
-                    - EquinixMetal
-                    - PowerVS
-                    - AlibabaCloud
-                    - Nutanix
-                    - External
-                    type: string
-                    x-kubernetes-validations:
-                    - message: allowed values are '' and 'AWS'
-                      rule: self in ['','AWS']
-                required:
-                - type
-                type: object
-                x-kubernetes-validations:
-                - message: aws configuration is required when platform is AWS, and
-                    forbidden otherwise
-                  rule: 'has(self.type) && self.type == ''AWS'' ?  has(self.aws) :
-                    !has(self.aws)'
-              privateZone:
-                description: "privateZone is the location where all the DNS records
-                  that are only available internally to the cluster exist. \n If this
-                  field is nil, no private records should be created. \n Once set,
-                  this field cannot be changed."
-                properties:
-                  id:
-                    description: "id is the identifier that can be used to find the
-                      DNS hosted zone. \n on AWS zone can be fetched using `ID` as
-                      id in [1] on Azure zone can be fetched using `ID` as a pre-determined
-                      name in [2], on GCP zone can be fetched using `ID` as a pre-determined
-                      name in [3]. \n [1]: https://docs.aws.amazon.com/cli/latest/reference/route53/get-hosted-zone.html#options
-                      [2]: https://docs.microsoft.com/en-us/cli/azure/network/dns/zone?view=azure-cli-latest#az-network-dns-zone-show
-                      [3]: https://cloud.google.com/dns/docs/reference/v1/managedZones/get"
-                    type: string
-                  tags:
-                    additionalProperties:
-                      type: string
-                    description: "tags can be used to query the DNS hosted zone. \n
-                      on AWS, resourcegroupstaggingapi [1] can be used to fetch a
-                      zone using `Tags` as tag-filters, \n [1]: https://docs.aws.amazon.com/cli/latest/reference/resourcegroupstaggingapi/get-resources.html#options"
-                    type: object
-                type: object
-              publicZone:
-                description: "publicZone is the location where all the DNS records
-                  that are publicly accessible to the internet exist. \n If this field
-                  is nil, no public records should be created. \n Once set, this field
-                  cannot be changed."
-                properties:
-                  id:
-                    description: "id is the identifier that can be used to find the
-                      DNS hosted zone. \n on AWS zone can be fetched using `ID` as
-                      id in [1] on Azure zone can be fetched using `ID` as a pre-determined
-                      name in [2], on GCP zone can be fetched using `ID` as a pre-determined
-                      name in [3]. \n [1]: https://docs.aws.amazon.com/cli/latest/reference/route53/get-hosted-zone.html#options
-                      [2]: https://docs.microsoft.com/en-us/cli/azure/network/dns/zone?view=azure-cli-latest#az-network-dns-zone-show
-                      [3]: https://cloud.google.com/dns/docs/reference/v1/managedZones/get"
-                    type: string
-                  tags:
-                    additionalProperties:
-                      type: string
-                    description: "tags can be used to query the DNS hosted zone. \n
-                      on AWS, resourcegroupstaggingapi [1] can be used to fetch a
-                      zone using `Tags` as tag-filters, \n [1]: https://docs.aws.amazon.com/cli/latest/reference/resourcegroupstaggingapi/get-resources.html#options"
-                    type: object
-                type: object
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns-Default.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns-Default.crd.yaml
deleted file mode 100644
index d2a3e7dc..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns-Default.crd.yaml
+++ /dev/null
@@ -1,159 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    release.openshift.io/feature-set: Default
-  name: dnses.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: DNS
-    listKind: DNSList
-    plural: dnses
-    singular: dns
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "DNS holds cluster-wide information about DNS. The canonical
-          name is `cluster` \n Compatibility level 1: Stable within a major release
-          for a minimum of 12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              baseDomain:
-                description: "baseDomain is the base domain of the cluster. All managed
-                  DNS records will be sub-domains of this base. \n For example, given
-                  the base domain `openshift.example.com`, an API server DNS record
-                  may be created for `cluster-api.openshift.example.com`. \n Once
-                  set, this field cannot be changed."
-                type: string
-              platform:
-                description: platform holds configuration specific to the underlying
-                  infrastructure provider for DNS. When omitted, this means the user
-                  has no opinion and the platform is left to choose reasonable defaults.
-                  These defaults are subject to change over time.
-                properties:
-                  aws:
-                    description: aws contains DNS configuration specific to the Amazon
-                      Web Services cloud provider.
-                    properties:
-                      privateZoneIAMRole:
-                        description: privateZoneIAMRole contains the ARN of an IAM
-                          role that should be assumed when performing operations on
-                          the cluster's private hosted zone specified in the cluster
-                          DNS config. When left empty, no role should be assumed.
-                        pattern: ^arn:(aws|aws-cn|aws-us-gov):iam::[0-9]{12}:role\/.*$
-                        type: string
-                    type: object
-                  type:
-                    description: "type is the underlying infrastructure provider for
-                      the cluster. Allowed values: \"\", \"AWS\". \n Individual components
-                      may not support all platforms, and must handle unrecognized
-                      platforms with best-effort defaults."
-                    enum:
-                    - ""
-                    - AWS
-                    - Azure
-                    - BareMetal
-                    - GCP
-                    - Libvirt
-                    - OpenStack
-                    - None
-                    - VSphere
-                    - oVirt
-                    - IBMCloud
-                    - KubeVirt
-                    - EquinixMetal
-                    - PowerVS
-                    - AlibabaCloud
-                    - Nutanix
-                    - External
-                    type: string
-                    x-kubernetes-validations:
-                    - message: allowed values are '' and 'AWS'
-                      rule: self in ['','AWS']
-                required:
-                - type
-                type: object
-                x-kubernetes-validations:
-                - message: aws configuration is required when platform is AWS, and
-                    forbidden otherwise
-                  rule: 'has(self.type) && self.type == ''AWS'' ?  has(self.aws) :
-                    !has(self.aws)'
-              privateZone:
-                description: "privateZone is the location where all the DNS records
-                  that are only available internally to the cluster exist. \n If this
-                  field is nil, no private records should be created. \n Once set,
-                  this field cannot be changed."
-                properties:
-                  id:
-                    description: "id is the identifier that can be used to find the
-                      DNS hosted zone. \n on AWS zone can be fetched using `ID` as
-                      id in [1] on Azure zone can be fetched using `ID` as a pre-determined
-                      name in [2], on GCP zone can be fetched using `ID` as a pre-determined
-                      name in [3]. \n [1]: https://docs.aws.amazon.com/cli/latest/reference/route53/get-hosted-zone.html#options
-                      [2]: https://docs.microsoft.com/en-us/cli/azure/network/dns/zone?view=azure-cli-latest#az-network-dns-zone-show
-                      [3]: https://cloud.google.com/dns/docs/reference/v1/managedZones/get"
-                    type: string
-                  tags:
-                    additionalProperties:
-                      type: string
-                    description: "tags can be used to query the DNS hosted zone. \n
-                      on AWS, resourcegroupstaggingapi [1] can be used to fetch a
-                      zone using `Tags` as tag-filters, \n [1]: https://docs.aws.amazon.com/cli/latest/reference/resourcegroupstaggingapi/get-resources.html#options"
-                    type: object
-                type: object
-              publicZone:
-                description: "publicZone is the location where all the DNS records
-                  that are publicly accessible to the internet exist. \n If this field
-                  is nil, no public records should be created. \n Once set, this field
-                  cannot be changed."
-                properties:
-                  id:
-                    description: "id is the identifier that can be used to find the
-                      DNS hosted zone. \n on AWS zone can be fetched using `ID` as
-                      id in [1] on Azure zone can be fetched using `ID` as a pre-determined
-                      name in [2], on GCP zone can be fetched using `ID` as a pre-determined
-                      name in [3]. \n [1]: https://docs.aws.amazon.com/cli/latest/reference/route53/get-hosted-zone.html#options
-                      [2]: https://docs.microsoft.com/en-us/cli/azure/network/dns/zone?view=azure-cli-latest#az-network-dns-zone-show
-                      [3]: https://cloud.google.com/dns/docs/reference/v1/managedZones/get"
-                    type: string
-                  tags:
-                    additionalProperties:
-                      type: string
-                    description: "tags can be used to query the DNS hosted zone. \n
-                      on AWS, resourcegroupstaggingapi [1] can be used to fetch a
-                      zone using `Tags` as tag-filters, \n [1]: https://docs.aws.amazon.com/cli/latest/reference/resourcegroupstaggingapi/get-resources.html#options"
-                    type: object
-                type: object
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns-TechPreviewNoUpgrade.crd.yaml
deleted file mode 100644
index b5fe2407..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_dns-TechPreviewNoUpgrade.crd.yaml
+++ /dev/null
@@ -1,159 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    release.openshift.io/feature-set: TechPreviewNoUpgrade
-  name: dnses.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: DNS
-    listKind: DNSList
-    plural: dnses
-    singular: dns
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "DNS holds cluster-wide information about DNS. The canonical
-          name is `cluster` \n Compatibility level 1: Stable within a major release
-          for a minimum of 12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              baseDomain:
-                description: "baseDomain is the base domain of the cluster. All managed
-                  DNS records will be sub-domains of this base. \n For example, given
-                  the base domain `openshift.example.com`, an API server DNS record
-                  may be created for `cluster-api.openshift.example.com`. \n Once
-                  set, this field cannot be changed."
-                type: string
-              platform:
-                description: platform holds configuration specific to the underlying
-                  infrastructure provider for DNS. When omitted, this means the user
-                  has no opinion and the platform is left to choose reasonable defaults.
-                  These defaults are subject to change over time.
-                properties:
-                  aws:
-                    description: aws contains DNS configuration specific to the Amazon
-                      Web Services cloud provider.
-                    properties:
-                      privateZoneIAMRole:
-                        description: privateZoneIAMRole contains the ARN of an IAM
-                          role that should be assumed when performing operations on
-                          the cluster's private hosted zone specified in the cluster
-                          DNS config. When left empty, no role should be assumed.
-                        pattern: ^arn:(aws|aws-cn|aws-us-gov):iam::[0-9]{12}:role\/.*$
-                        type: string
-                    type: object
-                  type:
-                    description: "type is the underlying infrastructure provider for
-                      the cluster. Allowed values: \"\", \"AWS\". \n Individual components
-                      may not support all platforms, and must handle unrecognized
-                      platforms with best-effort defaults."
-                    enum:
-                    - ""
-                    - AWS
-                    - Azure
-                    - BareMetal
-                    - GCP
-                    - Libvirt
-                    - OpenStack
-                    - None
-                    - VSphere
-                    - oVirt
-                    - IBMCloud
-                    - KubeVirt
-                    - EquinixMetal
-                    - PowerVS
-                    - AlibabaCloud
-                    - Nutanix
-                    - External
-                    type: string
-                    x-kubernetes-validations:
-                    - message: allowed values are '' and 'AWS'
-                      rule: self in ['','AWS']
-                required:
-                - type
-                type: object
-                x-kubernetes-validations:
-                - message: aws configuration is required when platform is AWS, and
-                    forbidden otherwise
-                  rule: 'has(self.type) && self.type == ''AWS'' ?  has(self.aws) :
-                    !has(self.aws)'
-              privateZone:
-                description: "privateZone is the location where all the DNS records
-                  that are only available internally to the cluster exist. \n If this
-                  field is nil, no private records should be created. \n Once set,
-                  this field cannot be changed."
-                properties:
-                  id:
-                    description: "id is the identifier that can be used to find the
-                      DNS hosted zone. \n on AWS zone can be fetched using `ID` as
-                      id in [1] on Azure zone can be fetched using `ID` as a pre-determined
-                      name in [2], on GCP zone can be fetched using `ID` as a pre-determined
-                      name in [3]. \n [1]: https://docs.aws.amazon.com/cli/latest/reference/route53/get-hosted-zone.html#options
-                      [2]: https://docs.microsoft.com/en-us/cli/azure/network/dns/zone?view=azure-cli-latest#az-network-dns-zone-show
-                      [3]: https://cloud.google.com/dns/docs/reference/v1/managedZones/get"
-                    type: string
-                  tags:
-                    additionalProperties:
-                      type: string
-                    description: "tags can be used to query the DNS hosted zone. \n
-                      on AWS, resourcegroupstaggingapi [1] can be used to fetch a
-                      zone using `Tags` as tag-filters, \n [1]: https://docs.aws.amazon.com/cli/latest/reference/resourcegroupstaggingapi/get-resources.html#options"
-                    type: object
-                type: object
-              publicZone:
-                description: "publicZone is the location where all the DNS records
-                  that are publicly accessible to the internet exist. \n If this field
-                  is nil, no public records should be created. \n Once set, this field
-                  cannot be changed."
-                properties:
-                  id:
-                    description: "id is the identifier that can be used to find the
-                      DNS hosted zone. \n on AWS zone can be fetched using `ID` as
-                      id in [1] on Azure zone can be fetched using `ID` as a pre-determined
-                      name in [2], on GCP zone can be fetched using `ID` as a pre-determined
-                      name in [3]. \n [1]: https://docs.aws.amazon.com/cli/latest/reference/route53/get-hosted-zone.html#options
-                      [2]: https://docs.microsoft.com/en-us/cli/azure/network/dns/zone?view=azure-cli-latest#az-network-dns-zone-show
-                      [3]: https://cloud.google.com/dns/docs/reference/v1/managedZones/get"
-                    type: string
-                  tags:
-                    additionalProperties:
-                      type: string
-                    description: "tags can be used to query the DNS hosted zone. \n
-                      on AWS, resourcegroupstaggingapi [1] can be used to fetch a
-                      zone using `Tags` as tag-filters, \n [1]: https://docs.aws.amazon.com/cli/latest/reference/resourcegroupstaggingapi/get-resources.html#options"
-                    type: object
-                type: object
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_featuregate.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_featuregate.crd.yaml
deleted file mode 100644
index 159260e6..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_featuregate.crd.yaml
+++ /dev/null
@@ -1,213 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-  name: featuregates.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: FeatureGate
-    listKind: FeatureGateList
-    plural: featuregates
-    singular: featuregate
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "Feature holds cluster-wide information about feature gates.
-          \ The canonical name is `cluster` \n Compatibility level 1: Stable within
-          a major release for a minimum of 12 months or 3 minor releases (whichever
-          is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              customNoUpgrade:
-                description: customNoUpgrade allows the enabling or disabling of any
-                  feature. Turning this feature set on IS NOT SUPPORTED, CANNOT BE
-                  UNDONE, and PREVENTS UPGRADES. Because of its nature, this setting
-                  cannot be validated.  If you have any typos or accidentally apply
-                  invalid combinations your cluster may fail in an unrecoverable way.  featureSet
-                  must equal "CustomNoUpgrade" must be set to use this field.
-                nullable: true
-                properties:
-                  disabled:
-                    description: disabled is a list of all feature gates that you
-                      want to force off
-                    items:
-                      description: FeatureGateName is a string to enforce patterns
-                        on the name of a FeatureGate
-                      pattern: ^([A-Za-z0-9-]+\.)*[A-Za-z0-9-]+\.?$
-                      type: string
-                    type: array
-                  enabled:
-                    description: enabled is a list of all feature gates that you want
-                      to force on
-                    items:
-                      description: FeatureGateName is a string to enforce patterns
-                        on the name of a FeatureGate
-                      pattern: ^([A-Za-z0-9-]+\.)*[A-Za-z0-9-]+\.?$
-                      type: string
-                    type: array
-                type: object
-              featureSet:
-                description: featureSet changes the list of features in the cluster.  The
-                  default is empty.  Be very careful adjusting this setting. Turning
-                  on or off features may cause irreversible changes in your cluster
-                  which cannot be undone.
-                type: string
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            properties:
-              conditions:
-                description: 'conditions represent the observations of the current
-                  state. Known .status.conditions.type are: "DeterminationDegraded"'
-                items:
-                  description: "Condition contains details for one aspect of the current
-                    state of this API Resource. --- This struct is intended for direct
-                    use as an array at the field path .status.conditions.  For example,
-                    \n type FooStatus struct{ // Represents the observations of a
-                    foo's current state. // Known .status.conditions.type are: \"Available\",
-                    \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
-                    // +listType=map // +listMapKey=type Conditions []metav1.Condition
-                    `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
-                    protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
-                  properties:
-                    lastTransitionTime:
-                      description: lastTransitionTime is the last time the condition
-                        transitioned from one status to another. This should be when
-                        the underlying condition changed.  If that is not known, then
-                        using the time when the API field changed is acceptable.
-                      format: date-time
-                      type: string
-                    message:
-                      description: message is a human readable message indicating
-                        details about the transition. This may be an empty string.
-                      maxLength: 32768
-                      type: string
-                    observedGeneration:
-                      description: observedGeneration represents the .metadata.generation
-                        that the condition was set based upon. For instance, if .metadata.generation
-                        is currently 12, but the .status.conditions[x].observedGeneration
-                        is 9, the condition is out of date with respect to the current
-                        state of the instance.
-                      format: int64
-                      minimum: 0
-                      type: integer
-                    reason:
-                      description: reason contains a programmatic identifier indicating
-                        the reason for the condition's last transition. Producers
-                        of specific condition types may define expected values and
-                        meanings for this field, and whether the values are considered
-                        a guaranteed API. The value should be a CamelCase string.
-                        This field may not be empty.
-                      maxLength: 1024
-                      minLength: 1
-                      pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
-                      type: string
-                    status:
-                      description: status of the condition, one of True, False, Unknown.
-                      enum:
-                      - "True"
-                      - "False"
-                      - Unknown
-                      type: string
-                    type:
-                      description: type of condition in CamelCase or in foo.example.com/CamelCase.
-                        --- Many .condition.type values are consistent across resources
-                        like Available, but because arbitrary conditions can be useful
-                        (see .node.status.conditions), the ability to deconflict is
-                        important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
-                      maxLength: 316
-                      pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
-                      type: string
-                  required:
-                  - lastTransitionTime
-                  - message
-                  - reason
-                  - status
-                  - type
-                  type: object
-                type: array
-                x-kubernetes-list-map-keys:
-                - type
-                x-kubernetes-list-type: map
-              featureGates:
-                description: featureGates contains a list of enabled and disabled
-                  featureGates that are keyed by payloadVersion. Operators other than
-                  the CVO and cluster-config-operator, must read the .status.featureGates,
-                  locate the version they are managing, find the enabled/disabled
-                  featuregates and make the operand and operator match. The enabled/disabled
-                  values for a particular version may change during the life of the
-                  cluster as various .spec.featureSet values are selected. Operators
-                  may choose to restart their processes to pick up these changes,
-                  but remembering past enable/disable lists is beyond the scope of
-                  this API and is the responsibility of individual operators. Only
-                  featureGates with .version in the ClusterVersion.status will be
-                  present in this list.
-                items:
-                  properties:
-                    disabled:
-                      description: disabled is a list of all feature gates that are
-                        disabled in the cluster for the named version.
-                      items:
-                        properties:
-                          name:
-                            description: name is the name of the FeatureGate.
-                            pattern: ^([A-Za-z0-9-]+\.)*[A-Za-z0-9-]+\.?$
-                            type: string
-                        required:
-                        - name
-                        type: object
-                      type: array
-                    enabled:
-                      description: enabled is a list of all feature gates that are
-                        enabled in the cluster for the named version.
-                      items:
-                        properties:
-                          name:
-                            description: name is the name of the FeatureGate.
-                            pattern: ^([A-Za-z0-9-]+\.)*[A-Za-z0-9-]+\.?$
-                            type: string
-                        required:
-                        - name
-                        type: object
-                      type: array
-                    version:
-                      description: version matches the version provided by the ClusterVersion
-                        and in the ClusterOperator.Status.Versions field.
-                      type: string
-                  required:
-                  - version
-                  type: object
-                type: array
-                x-kubernetes-list-map-keys:
-                - version
-                x-kubernetes-list-type: map
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_image.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_image.crd.yaml
deleted file mode 100644
index f53396ae..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_image.crd.yaml
+++ /dev/null
@@ -1,162 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-  name: images.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: Image
-    listKind: ImageList
-    plural: images
-    singular: image
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "Image governs policies related to imagestream imports and runtime
-          configuration for external registries. It allows cluster admins to configure
-          which registries OpenShift is allowed to import images from, extra CA trust
-          bundles for external registries, and policies to block or allow registry
-          hostnames. When exposing OpenShift's image registry to the public, this
-          also lets cluster admins specify the external hostname. \n Compatibility
-          level 1: Stable within a major release for a minimum of 12 months or 3 minor
-          releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              additionalTrustedCA:
-                description: additionalTrustedCA is a reference to a ConfigMap containing
-                  additional CAs that should be trusted during imagestream import,
-                  pod image pull, build image pull, and imageregistry pullthrough.
-                  The namespace for this config map is openshift-config.
-                properties:
-                  name:
-                    description: name is the metadata.name of the referenced config
-                      map
-                    type: string
-                required:
-                - name
-                type: object
-              allowedRegistriesForImport:
-                description: allowedRegistriesForImport limits the container image
-                  registries that normal users may import images from. Set this list
-                  to the registries that you trust to contain valid Docker images
-                  and that you want applications to be able to import from. Users
-                  with permission to create Images or ImageStreamMappings via the
-                  API are not affected by this policy - typically only administrators
-                  or system integrations will have those permissions.
-                items:
-                  description: RegistryLocation contains a location of the registry
-                    specified by the registry domain name. The domain name might include
-                    wildcards, like '*' or '??'.
-                  properties:
-                    domainName:
-                      description: domainName specifies a domain name for the registry
-                        In case the registry use non-standard (80 or 443) port, the
-                        port should be included in the domain name as well.
-                      type: string
-                    insecure:
-                      description: insecure indicates whether the registry is secure
-                        (https) or insecure (http) By default (if not specified) the
-                        registry is assumed as secure.
-                      type: boolean
-                  type: object
-                type: array
-              externalRegistryHostnames:
-                description: externalRegistryHostnames provides the hostnames for
-                  the default external image registry. The external hostname should
-                  be set only when the image registry is exposed externally. The first
-                  value is used in 'publicDockerImageRepository' field in ImageStreams.
-                  The value must be in "hostname[:port]" format.
-                items:
-                  type: string
-                type: array
-              registrySources:
-                description: registrySources contains configuration that determines
-                  how the container runtime should treat individual registries when
-                  accessing images for builds+pods. (e.g. whether or not to allow
-                  insecure access).  It does not contain configuration for the internal
-                  cluster registry.
-                properties:
-                  allowedRegistries:
-                    description: "allowedRegistries are the only registries permitted
-                      for image pull and push actions. All other registries are denied.
-                      \n Only one of BlockedRegistries or AllowedRegistries may be
-                      set."
-                    items:
-                      type: string
-                    type: array
-                  blockedRegistries:
-                    description: "blockedRegistries cannot be used for image pull
-                      and push actions. All other registries are permitted. \n Only
-                      one of BlockedRegistries or AllowedRegistries may be set."
-                    items:
-                      type: string
-                    type: array
-                  containerRuntimeSearchRegistries:
-                    description: 'containerRuntimeSearchRegistries are registries
-                      that will be searched when pulling images that do not have fully
-                      qualified domains in their pull specs. Registries will be searched
-                      in the order provided in the list. Note: this search list only
-                      works with the container runtime, i.e CRI-O. Will NOT work with
-                      builds or imagestream imports.'
-                    format: hostname
-                    items:
-                      type: string
-                    minItems: 1
-                    type: array
-                    x-kubernetes-list-type: set
-                  insecureRegistries:
-                    description: insecureRegistries are registries which do not have
-                      a valid TLS certificates or only support HTTP connections.
-                    items:
-                      type: string
-                    type: array
-                type: object
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            properties:
-              externalRegistryHostnames:
-                description: externalRegistryHostnames provides the hostnames for
-                  the default external image registry. The external hostname should
-                  be set only when the image registry is exposed externally. The first
-                  value is used in 'publicDockerImageRepository' field in ImageStreams.
-                  The value must be in "hostname[:port]" format.
-                items:
-                  type: string
-                type: array
-              internalRegistryHostname:
-                description: internalRegistryHostname sets the hostname for the default
-                  internal image registry. The value must be in "hostname[:port]"
-                  format. This value is set by the image registry operator which controls
-                  the internal registry hostname.
-                type: string
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_imagecontentpolicy.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_imagecontentpolicy.crd.yaml
deleted file mode 100644
index 2e30bc55..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_imagecontentpolicy.crd.yaml
+++ /dev/null
@@ -1,112 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/874
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-  name: imagecontentpolicies.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: ImageContentPolicy
-    listKind: ImageContentPolicyList
-    plural: imagecontentpolicies
-    singular: imagecontentpolicy
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "ImageContentPolicy holds cluster-wide information about how
-          to handle registry mirror rules. When multiple policies are defined, the
-          outcome of the behavior is defined on each field. \n Compatibility level
-          1: Stable within a major release for a minimum of 12 months or 3 minor releases
-          (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              repositoryDigestMirrors:
-                description: "repositoryDigestMirrors allows images referenced by
-                  image digests in pods to be pulled from alternative mirrored repository
-                  locations. The image pull specification provided to the pod will
-                  be compared to the source locations described in RepositoryDigestMirrors
-                  and the image may be pulled down from any of the mirrors in the
-                  list instead of the specified repository allowing administrators
-                  to choose a potentially faster mirror. To pull image from mirrors
-                  by tags, should set the \"allowMirrorByTags\". \n Each “source”
-                  repository is treated independently; configurations for different
-                  “source” repositories don’t interact. \n If the \"mirrors\" is not
-                  specified, the image will continue to be pulled from the specified
-                  repository in the pull spec. \n When multiple policies are defined
-                  for the same “source” repository, the sets of defined mirrors will
-                  be merged together, preserving the relative order of the mirrors,
-                  if possible. For example, if policy A has mirrors `a, b, c` and
-                  policy B has mirrors `c, d, e`, the mirrors will be used in the
-                  order `a, b, c, d, e`.  If the orders of mirror entries conflict
-                  (e.g. `a, b` vs. `b, a`) the configuration is not rejected but the
-                  resulting order is unspecified."
-                items:
-                  description: RepositoryDigestMirrors holds cluster-wide information
-                    about how to handle mirrors in the registries config.
-                  properties:
-                    allowMirrorByTags:
-                      description: allowMirrorByTags if true, the mirrors can be used
-                        to pull the images that are referenced by their tags. Default
-                        is false, the mirrors only work when pulling the images that
-                        are referenced by their digests. Pulling images by tag can
-                        potentially yield different images, depending on which endpoint
-                        we pull from. Forcing digest-pulls for mirrors avoids that
-                        issue.
-                      type: boolean
-                    mirrors:
-                      description: mirrors is zero or more repositories that may also
-                        contain the same images. If the "mirrors" is not specified,
-                        the image will continue to be pulled from the specified repository
-                        in the pull spec. No mirror will be configured. The order
-                        of mirrors in this list is treated as the user's desired priority,
-                        while source is by default considered lower priority than
-                        all mirrors. Other cluster configuration, including (but not
-                        limited to) other repositoryDigestMirrors objects, may impact
-                        the exact order mirrors are contacted in, or some mirrors
-                        may be contacted in parallel, so this should be considered
-                        a preference rather than a guarantee of ordering.
-                      items:
-                        pattern: ^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])(:[0-9]+)?(\/[^\/:\n]+)*(\/[^\/:\n]+((:[^\/:\n]+)|(@[^\n]+)))?$
-                        type: string
-                      type: array
-                      x-kubernetes-list-type: set
-                    source:
-                      description: source is the repository that users refer to, e.g.
-                        in image pull specifications.
-                      pattern: ^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])(:[0-9]+)?(\/[^\/:\n]+)*(\/[^\/:\n]+((:[^\/:\n]+)|(@[^\n]+)))?$
-                      type: string
-                  required:
-                  - source
-                  type: object
-                type: array
-                x-kubernetes-list-map-keys:
-                - source
-                x-kubernetes-list-type: map
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_imagedigestmirrorset.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_imagedigestmirrorset.crd.yaml
deleted file mode 100644
index 422e46d4..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_imagedigestmirrorset.crd.yaml
+++ /dev/null
@@ -1,141 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/1126
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-  name: imagedigestmirrorsets.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: ImageDigestMirrorSet
-    listKind: ImageDigestMirrorSetList
-    plural: imagedigestmirrorsets
-    shortNames:
-    - idms
-    singular: imagedigestmirrorset
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "ImageDigestMirrorSet holds cluster-wide information about how
-          to handle registry mirror rules on using digest pull specification. When
-          multiple policies are defined, the outcome of the behavior is defined on
-          each field. \n Compatibility level 1: Stable within a major release for
-          a minimum of 12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              imageDigestMirrors:
-                description: "imageDigestMirrors allows images referenced by image
-                  digests in pods to be pulled from alternative mirrored repository
-                  locations. The image pull specification provided to the pod will
-                  be compared to the source locations described in imageDigestMirrors
-                  and the image may be pulled down from any of the mirrors in the
-                  list instead of the specified repository allowing administrators
-                  to choose a potentially faster mirror. To use mirrors to pull images
-                  using tag specification, users should configure a list of mirrors
-                  using \"ImageTagMirrorSet\" CRD. \n If the image pull specification
-                  matches the repository of \"source\" in multiple imagedigestmirrorset
-                  objects, only the objects which define the most specific namespace
-                  match will be used. For example, if there are objects using quay.io/libpod
-                  and quay.io/libpod/busybox as the \"source\", only the objects using
-                  quay.io/libpod/busybox are going to apply for pull specification
-                  quay.io/libpod/busybox. Each “source” repository is treated independently;
-                  configurations for different “source” repositories don’t interact.
-                  \n If the \"mirrors\" is not specified, the image will continue
-                  to be pulled from the specified repository in the pull spec. \n
-                  When multiple policies are defined for the same “source” repository,
-                  the sets of defined mirrors will be merged together, preserving
-                  the relative order of the mirrors, if possible. For example, if
-                  policy A has mirrors `a, b, c` and policy B has mirrors `c, d, e`,
-                  the mirrors will be used in the order `a, b, c, d, e`.  If the orders
-                  of mirror entries conflict (e.g. `a, b` vs. `b, a`) the configuration
-                  is not rejected but the resulting order is unspecified. Users who
-                  want to use a specific order of mirrors, should configure them into
-                  one list of mirrors using the expected order."
-                items:
-                  description: ImageDigestMirrors holds cluster-wide information about
-                    how to handle mirrors in the registries config.
-                  properties:
-                    mirrorSourcePolicy:
-                      description: mirrorSourcePolicy defines the fallback policy
-                        if fails to pull image from the mirrors. If unset, the image
-                        will continue to be pulled from the the repository in the
-                        pull spec. sourcePolicy is valid configuration only when one
-                        or more mirrors are in the mirror list.
-                      enum:
-                      - NeverContactSource
-                      - AllowContactingSource
-                      type: string
-                    mirrors:
-                      description: 'mirrors is zero or more locations that may also
-                        contain the same images. No mirror will be configured if not
-                        specified. Images can be pulled from these mirrors only if
-                        they are referenced by their digests. The mirrored location
-                        is obtained by replacing the part of the input reference that
-                        matches source by the mirrors entry, e.g. for registry.redhat.io/product/repo
-                        reference, a (source, mirror) pair *.redhat.io, mirror.local/redhat
-                        causes a mirror.local/redhat/product/repo repository to be
-                        used. The order of mirrors in this list is treated as the
-                        user''s desired priority, while source is by default considered
-                        lower priority than all mirrors. If no mirror is specified
-                        or all image pulls from the mirror list fail, the image will
-                        continue to be pulled from the repository in the pull spec
-                        unless explicitly prohibited by "mirrorSourcePolicy" Other
-                        cluster configuration, including (but not limited to) other
-                        imageDigestMirrors objects, may impact the exact order mirrors
-                        are contacted in, or some mirrors may be contacted in parallel,
-                        so this should be considered a preference rather than a guarantee
-                        of ordering. "mirrors" uses one of the following formats:
-                        host[:port] host[:port]/namespace[/namespace…] host[:port]/namespace[/namespace…]/repo
-                        for more information about the format, see the document about
-                        the location field: https://github.com/containers/image/blob/main/docs/containers-registries.conf.5.md#choosing-a-registry-toml-table'
-                      items:
-                        pattern: ^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$
-                        type: string
-                      type: array
-                      x-kubernetes-list-type: set
-                    source:
-                      description: 'source matches the repository that users refer
-                        to, e.g. in image pull specifications. Setting source to a
-                        registry hostname e.g. docker.io. quay.io, or registry.redhat.io,
-                        will match the image pull specification of corressponding
-                        registry. "source" uses one of the following formats: host[:port]
-                        host[:port]/namespace[/namespace…] host[:port]/namespace[/namespace…]/repo
-                        [*.]host for more information about the format, see the document
-                        about the location field: https://github.com/containers/image/blob/main/docs/containers-registries.conf.5.md#choosing-a-registry-toml-table'
-                      pattern: ^\*(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$
-                      type: string
-                  required:
-                  - source
-                  type: object
-                type: array
-                x-kubernetes-list-type: atomic
-            type: object
-          status:
-            description: status contains the observed state of the resource.
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_imagetagmirrorset.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_imagetagmirrorset.crd.yaml
deleted file mode 100644
index abcab016..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_imagetagmirrorset.crd.yaml
+++ /dev/null
@@ -1,144 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/1126
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-  name: imagetagmirrorsets.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: ImageTagMirrorSet
-    listKind: ImageTagMirrorSetList
-    plural: imagetagmirrorsets
-    shortNames:
-    - itms
-    singular: imagetagmirrorset
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "ImageTagMirrorSet holds cluster-wide information about how to
-          handle registry mirror rules on using tag pull specification. When multiple
-          policies are defined, the outcome of the behavior is defined on each field.
-          \n Compatibility level 1: Stable within a major release for a minimum of
-          12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              imageTagMirrors:
-                description: "imageTagMirrors allows images referenced by image tags
-                  in pods to be pulled from alternative mirrored repository locations.
-                  The image pull specification provided to the pod will be compared
-                  to the source locations described in imageTagMirrors and the image
-                  may be pulled down from any of the mirrors in the list instead of
-                  the specified repository allowing administrators to choose a potentially
-                  faster mirror. To use mirrors to pull images using digest specification
-                  only, users should configure a list of mirrors using \"ImageDigestMirrorSet\"
-                  CRD. \n If the image pull specification matches the repository of
-                  \"source\" in multiple imagetagmirrorset objects, only the objects
-                  which define the most specific namespace match will be used. For
-                  example, if there are objects using quay.io/libpod and quay.io/libpod/busybox
-                  as the \"source\", only the objects using quay.io/libpod/busybox
-                  are going to apply for pull specification quay.io/libpod/busybox.
-                  Each “source” repository is treated independently; configurations
-                  for different “source” repositories don’t interact. \n If the \"mirrors\"
-                  is not specified, the image will continue to be pulled from the
-                  specified repository in the pull spec. \n When multiple policies
-                  are defined for the same “source” repository, the sets of defined
-                  mirrors will be merged together, preserving the relative order of
-                  the mirrors, if possible. For example, if policy A has mirrors `a,
-                  b, c` and policy B has mirrors `c, d, e`, the mirrors will be used
-                  in the order `a, b, c, d, e`.  If the orders of mirror entries conflict
-                  (e.g. `a, b` vs. `b, a`) the configuration is not rejected but the
-                  resulting order is unspecified. Users who want to use a deterministic
-                  order of mirrors, should configure them into one list of mirrors
-                  using the expected order."
-                items:
-                  description: ImageTagMirrors holds cluster-wide information about
-                    how to handle mirrors in the registries config.
-                  properties:
-                    mirrorSourcePolicy:
-                      description: mirrorSourcePolicy defines the fallback policy
-                        if fails to pull image from the mirrors. If unset, the image
-                        will continue to be pulled from the repository in the pull
-                        spec. sourcePolicy is valid configuration only when one or
-                        more mirrors are in the mirror list.
-                      enum:
-                      - NeverContactSource
-                      - AllowContactingSource
-                      type: string
-                    mirrors:
-                      description: 'mirrors is zero or more locations that may also
-                        contain the same images. No mirror will be configured if not
-                        specified. Images can be pulled from these mirrors only if
-                        they are referenced by their tags. The mirrored location is
-                        obtained by replacing the part of the input reference that
-                        matches source by the mirrors entry, e.g. for registry.redhat.io/product/repo
-                        reference, a (source, mirror) pair *.redhat.io, mirror.local/redhat
-                        causes a mirror.local/redhat/product/repo repository to be
-                        used. Pulling images by tag can potentially yield different
-                        images, depending on which endpoint we pull from. Configuring
-                        a list of mirrors using "ImageDigestMirrorSet" CRD and forcing
-                        digest-pulls for mirrors avoids that issue. The order of mirrors
-                        in this list is treated as the user''s desired priority, while
-                        source is by default considered lower priority than all mirrors.
-                        If no mirror is specified or all image pulls from the mirror
-                        list fail, the image will continue to be pulled from the repository
-                        in the pull spec unless explicitly prohibited by "mirrorSourcePolicy".
-                        Other cluster configuration, including (but not limited to)
-                        other imageTagMirrors objects, may impact the exact order
-                        mirrors are contacted in, or some mirrors may be contacted
-                        in parallel, so this should be considered a preference rather
-                        than a guarantee of ordering. "mirrors" uses one of the following
-                        formats: host[:port] host[:port]/namespace[/namespace…] host[:port]/namespace[/namespace…]/repo
-                        for more information about the format, see the document about
-                        the location field: https://github.com/containers/image/blob/main/docs/containers-registries.conf.5.md#choosing-a-registry-toml-table'
-                      items:
-                        pattern: ^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$
-                        type: string
-                      type: array
-                      x-kubernetes-list-type: set
-                    source:
-                      description: 'source matches the repository that users refer
-                        to, e.g. in image pull specifications. Setting source to a
-                        registry hostname e.g. docker.io. quay.io, or registry.redhat.io,
-                        will match the image pull specification of corressponding
-                        registry. "source" uses one of the following formats: host[:port]
-                        host[:port]/namespace[/namespace…] host[:port]/namespace[/namespace…]/repo
-                        [*.]host for more information about the format, see the document
-                        about the location field: https://github.com/containers/image/blob/main/docs/containers-registries.conf.5.md#choosing-a-registry-toml-table'
-                      pattern: ^\*(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$
-                      type: string
-                  required:
-                  - source
-                  type: object
-                type: array
-                x-kubernetes-list-type: atomic
-            type: object
-          status:
-            description: status contains the observed state of the resource.
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-CustomNoUpgrade.crd.yaml
deleted file mode 100644
index 975def7c..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-CustomNoUpgrade.crd.yaml
+++ /dev/null
@@ -1,2089 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    release.openshift.io/feature-set: CustomNoUpgrade
-  name: infrastructures.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: Infrastructure
-    listKind: InfrastructureList
-    plural: infrastructures
-    singular: infrastructure
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "Infrastructure holds cluster-wide information about Infrastructure.
-          \ The canonical name is `cluster` \n Compatibility level 1: Stable within
-          a major release for a minimum of 12 months or 3 minor releases (whichever
-          is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              cloudConfig:
-                description: "cloudConfig is a reference to a ConfigMap containing
-                  the cloud provider configuration file. This configuration file is
-                  used to configure the Kubernetes cloud provider integration when
-                  using the built-in cloud provider integration or the external cloud
-                  controller manager. The namespace for this config map is openshift-config.
-                  \n cloudConfig should only be consumed by the kube_cloud_config
-                  controller. The controller is responsible for using the user configuration
-                  in the spec for various platforms and combining that with the user
-                  provided ConfigMap in this field to create a stitched kube cloud
-                  config. The controller generates a ConfigMap `kube-cloud-config`
-                  in `openshift-config-managed` namespace with the kube cloud config
-                  is stored in `cloud.conf` key. All the clients are expected to use
-                  the generated ConfigMap only."
-                properties:
-                  key:
-                    description: Key allows pointing to a specific key/value inside
-                      of the configmap.  This is useful for logical file references.
-                    type: string
-                  name:
-                    type: string
-                type: object
-              platformSpec:
-                description: platformSpec holds desired information specific to the
-                  underlying infrastructure provider.
-                properties:
-                  alibabaCloud:
-                    description: AlibabaCloud contains settings specific to the Alibaba
-                      Cloud infrastructure provider.
-                    type: object
-                  aws:
-                    description: AWS contains settings specific to the Amazon Web
-                      Services infrastructure provider.
-                    properties:
-                      serviceEndpoints:
-                        description: serviceEndpoints list contains custom endpoints
-                          which will override default service endpoint of AWS Services.
-                          There must be only one ServiceEndpoint for a service.
-                        items:
-                          description: AWSServiceEndpoint store the configuration
-                            of a custom url to override existing defaults of AWS Services.
-                          properties:
-                            name:
-                              description: name is the name of the AWS service. The
-                                list of all the service names can be found at https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html
-                                This must be provided and cannot be empty.
-                              pattern: ^[a-z0-9-]+$
-                              type: string
-                            url:
-                              description: url is fully qualified URI with scheme
-                                https, that overrides the default generated endpoint
-                                for a client. This must be provided and cannot be
-                                empty.
-                              pattern: ^https://
-                              type: string
-                          type: object
-                        type: array
-                        x-kubernetes-list-type: atomic
-                    type: object
-                  azure:
-                    description: Azure contains settings specific to the Azure infrastructure
-                      provider.
-                    type: object
-                  baremetal:
-                    description: BareMetal contains settings specific to the BareMetal
-                      platform.
-                    properties:
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IP addresses,
-                          one from IPv4 family and one from IPv6. In single stack
-                          clusters a single IP address is expected. When omitted,
-                          values from the status.apiServerInternalIPs will be used.
-                          Once set, the list cannot be completely removed (but its
-                          second entry can).
-                        items:
-                          description: IP is an IP address (for example, "10.0.0.0"
-                            or "fd00::").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                        x-kubernetes-validations:
-                        - message: apiServerInternalIPs must contain at most one IPv4
-                            address and at most one IPv6 address
-                          rule: 'size(self) == 2 ? self.exists_one(x, x.contains('':''))
-                            : true'
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IP
-                          addresses, one from IPv4 family and one from IPv6. In single
-                          stack clusters a single IP address is expected. When omitted,
-                          values from the status.ingressIPs will be used. Once set,
-                          the list cannot be completely removed (but its second entry
-                          can).
-                        items:
-                          description: IP is an IP address (for example, "10.0.0.0"
-                            or "fd00::").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                        x-kubernetes-validations:
-                        - message: ingressIPs must contain at most one IPv4 address
-                            and at most one IPv6 address
-                          rule: 'size(self) == 2 ? self.exists_one(x, x.contains('':''))
-                            : true'
-                      machineNetworks:
-                        description: machineNetworks are IP networks used to connect
-                          all the OpenShift cluster nodes. Each network is provided
-                          in the CIDR format and should be IPv4 or IPv6, for example
-                          "10.0.0.0/8" or "fd00::/8".
-                        items:
-                          description: CIDR is an IP address range in CIDR notation
-                            (for example, "10.0.0.0/8" or "fd00::/8").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[0-9]))$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))$)
-                          type: string
-                        maxItems: 32
-                        type: array
-                        x-kubernetes-list-type: set
-                    type: object
-                    x-kubernetes-validations:
-                    - message: apiServerInternalIPs list is required once set
-                      rule: '!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)'
-                    - message: ingressIPs list is required once set
-                      rule: '!has(oldSelf.ingressIPs) || has(self.ingressIPs)'
-                  equinixMetal:
-                    description: EquinixMetal contains settings specific to the Equinix
-                      Metal infrastructure provider.
-                    type: object
-                  external:
-                    description: ExternalPlatformType represents generic infrastructure
-                      provider. Platform-specific components should be supplemented
-                      separately.
-                    properties:
-                      platformName:
-                        default: Unknown
-                        description: PlatformName holds the arbitrary string representing
-                          the infrastructure provider name, expected to be set at
-                          the installation time. This field is solely for informational
-                          and reporting purposes and is not expected to be used for
-                          decision-making.
-                        type: string
-                        x-kubernetes-validations:
-                        - message: platform name cannot be changed once set
-                          rule: oldSelf == 'Unknown' || self == oldSelf
-                    type: object
-                  gcp:
-                    description: GCP contains settings specific to the Google Cloud
-                      Platform infrastructure provider.
-                    type: object
-                  ibmcloud:
-                    description: IBMCloud contains settings specific to the IBMCloud
-                      infrastructure provider.
-                    type: object
-                  kubevirt:
-                    description: Kubevirt contains settings specific to the kubevirt
-                      infrastructure provider.
-                    type: object
-                  nutanix:
-                    description: Nutanix contains settings specific to the Nutanix
-                      infrastructure provider.
-                    properties:
-                      failureDomains:
-                        description: failureDomains configures failure domains information
-                          for the Nutanix platform. When set, the failure domains
-                          defined here may be used to spread Machines across prism
-                          element clusters to improve fault tolerance of the cluster.
-                        items:
-                          description: NutanixFailureDomain configures failure domain
-                            information for the Nutanix platform.
-                          properties:
-                            cluster:
-                              description: cluster is to identify the cluster (the
-                                Prism Element under management of the Prism Central),
-                                in which the Machine's VM will be created. The cluster
-                                identifier (uuid or name) can be obtained from the
-                                Prism Central console or using the prism_central API.
-                              properties:
-                                name:
-                                  description: name is the resource name in the PC.
-                                    It cannot be empty if the type is Name.
-                                  type: string
-                                type:
-                                  description: type is the identifier type to use
-                                    for this resource.
-                                  enum:
-                                  - UUID
-                                  - Name
-                                  type: string
-                                uuid:
-                                  description: uuid is the UUID of the resource in
-                                    the PC. It cannot be empty if the type is UUID.
-                                  type: string
-                              required:
-                              - type
-                              type: object
-                              x-kubernetes-validations:
-                              - message: uuid configuration is required when type
-                                  is UUID, and forbidden otherwise
-                                rule: 'has(self.type) && self.type == ''UUID'' ?  has(self.uuid)
-                                  : !has(self.uuid)'
-                              - message: name configuration is required when type
-                                  is Name, and forbidden otherwise
-                                rule: 'has(self.type) && self.type == ''Name'' ?  has(self.name)
-                                  : !has(self.name)'
-                            name:
-                              description: name defines the unique name of a failure
-                                domain. Name is required and must be at most 64 characters
-                                in length. It must consist of only lower case alphanumeric
-                                characters and hyphens (-). It must start and end
-                                with an alphanumeric character. This value is arbitrary
-                                and is used to identify the failure domain within
-                                the platform.
-                              maxLength: 64
-                              minLength: 1
-                              pattern: '[a-z0-9]([-a-z0-9]*[a-z0-9])?'
-                              type: string
-                            subnets:
-                              description: subnets holds a list of identifiers (one
-                                or more) of the cluster's network subnets for the
-                                Machine's VM to connect to. The subnet identifiers
-                                (uuid or name) can be obtained from the Prism Central
-                                console or using the prism_central API.
-                              items:
-                                description: NutanixResourceIdentifier holds the identity
-                                  of a Nutanix PC resource (cluster, image, subnet,
-                                  etc.)
-                                properties:
-                                  name:
-                                    description: name is the resource name in the
-                                      PC. It cannot be empty if the type is Name.
-                                    type: string
-                                  type:
-                                    description: type is the identifier type to use
-                                      for this resource.
-                                    enum:
-                                    - UUID
-                                    - Name
-                                    type: string
-                                  uuid:
-                                    description: uuid is the UUID of the resource
-                                      in the PC. It cannot be empty if the type is
-                                      UUID.
-                                    type: string
-                                required:
-                                - type
-                                type: object
-                                x-kubernetes-validations:
-                                - message: uuid configuration is required when type
-                                    is UUID, and forbidden otherwise
-                                  rule: 'has(self.type) && self.type == ''UUID'' ?  has(self.uuid)
-                                    : !has(self.uuid)'
-                                - message: name configuration is required when type
-                                    is Name, and forbidden otherwise
-                                  rule: 'has(self.type) && self.type == ''Name'' ?  has(self.name)
-                                    : !has(self.name)'
-                              maxItems: 1
-                              minItems: 1
-                              type: array
-                              x-kubernetes-list-map-keys:
-                              - type
-                              x-kubernetes-list-type: map
-                          required:
-                          - cluster
-                          - name
-                          - subnets
-                          type: object
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - name
-                        x-kubernetes-list-type: map
-                      prismCentral:
-                        description: prismCentral holds the endpoint address and port
-                          to access the Nutanix Prism Central. When a cluster-wide
-                          proxy is installed, by default, this endpoint will be accessed
-                          via the proxy. Should you wish for communication with this
-                          endpoint not to be proxied, please add the endpoint to the
-                          proxy spec.noProxy list.
-                        properties:
-                          address:
-                            description: address is the endpoint address (DNS name
-                              or IP address) of the Nutanix Prism Central or Element
-                              (cluster)
-                            maxLength: 256
-                            type: string
-                          port:
-                            description: port is the port number to access the Nutanix
-                              Prism Central or Element (cluster)
-                            format: int32
-                            maximum: 65535
-                            minimum: 1
-                            type: integer
-                        required:
-                        - address
-                        - port
-                        type: object
-                      prismElements:
-                        description: prismElements holds one or more endpoint address
-                          and port data to access the Nutanix Prism Elements (clusters)
-                          of the Nutanix Prism Central. Currently we only support
-                          one Prism Element (cluster) for an OpenShift cluster, where
-                          all the Nutanix resources (VMs, subnets, volumes, etc.)
-                          used in the OpenShift cluster are located. In the future,
-                          we may support Nutanix resources (VMs, etc.) spread over
-                          multiple Prism Elements (clusters) of the Prism Central.
-                        items:
-                          description: NutanixPrismElementEndpoint holds the name
-                            and endpoint data for a Prism Element (cluster)
-                          properties:
-                            endpoint:
-                              description: endpoint holds the endpoint address and
-                                port data of the Prism Element (cluster). When a cluster-wide
-                                proxy is installed, by default, this endpoint will
-                                be accessed via the proxy. Should you wish for communication
-                                with this endpoint not to be proxied, please add the
-                                endpoint to the proxy spec.noProxy list.
-                              properties:
-                                address:
-                                  description: address is the endpoint address (DNS
-                                    name or IP address) of the Nutanix Prism Central
-                                    or Element (cluster)
-                                  maxLength: 256
-                                  type: string
-                                port:
-                                  description: port is the port number to access the
-                                    Nutanix Prism Central or Element (cluster)
-                                  format: int32
-                                  maximum: 65535
-                                  minimum: 1
-                                  type: integer
-                              required:
-                              - address
-                              - port
-                              type: object
-                            name:
-                              description: name is the name of the Prism Element (cluster).
-                                This value will correspond with the cluster field
-                                configured on other resources (eg Machines, PVCs,
-                                etc).
-                              maxLength: 256
-                              type: string
-                          required:
-                          - endpoint
-                          - name
-                          type: object
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - name
-                        x-kubernetes-list-type: map
-                    required:
-                    - prismCentral
-                    - prismElements
-                    type: object
-                  openstack:
-                    description: OpenStack contains settings specific to the OpenStack
-                      infrastructure provider.
-                    properties:
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IP addresses,
-                          one from IPv4 family and one from IPv6. In single stack
-                          clusters a single IP address is expected. When omitted,
-                          values from the status.apiServerInternalIPs will be used.
-                          Once set, the list cannot be completely removed (but its
-                          second entry can).
-                        items:
-                          description: IP is an IP address (for example, "10.0.0.0"
-                            or "fd00::").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                        x-kubernetes-validations:
-                        - message: apiServerInternalIPs must contain at most one IPv4
-                            address and at most one IPv6 address
-                          rule: 'size(self) == 2 ? self.exists_one(x, x.contains('':''))
-                            : true'
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IP
-                          addresses, one from IPv4 family and one from IPv6. In single
-                          stack clusters a single IP address is expected. When omitted,
-                          values from the status.ingressIPs will be used. Once set,
-                          the list cannot be completely removed (but its second entry
-                          can).
-                        items:
-                          description: IP is an IP address (for example, "10.0.0.0"
-                            or "fd00::").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                        x-kubernetes-validations:
-                        - message: ingressIPs must contain at most one IPv4 address
-                            and at most one IPv6 address
-                          rule: 'size(self) == 2 ? self.exists_one(x, x.contains('':''))
-                            : true'
-                      machineNetworks:
-                        description: machineNetworks are IP networks used to connect
-                          all the OpenShift cluster nodes. Each network is provided
-                          in the CIDR format and should be IPv4 or IPv6, for example
-                          "10.0.0.0/8" or "fd00::/8".
-                        items:
-                          description: CIDR is an IP address range in CIDR notation
-                            (for example, "10.0.0.0/8" or "fd00::/8").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[0-9]))$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))$)
-                          type: string
-                        maxItems: 32
-                        type: array
-                        x-kubernetes-list-type: set
-                    type: object
-                    x-kubernetes-validations:
-                    - message: apiServerInternalIPs list is required once set
-                      rule: '!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)'
-                    - message: ingressIPs list is required once set
-                      rule: '!has(oldSelf.ingressIPs) || has(self.ingressIPs)'
-                  ovirt:
-                    description: Ovirt contains settings specific to the oVirt infrastructure
-                      provider.
-                    type: object
-                  powervs:
-                    description: PowerVS contains settings specific to the IBM Power
-                      Systems Virtual Servers infrastructure provider.
-                    properties:
-                      serviceEndpoints:
-                        description: serviceEndpoints is a list of custom endpoints
-                          which will override the default service endpoints of a Power
-                          VS service.
-                        items:
-                          description: PowervsServiceEndpoint stores the configuration
-                            of a custom url to override existing defaults of PowerVS
-                            Services.
-                          properties:
-                            name:
-                              description: name is the name of the Power VS service.
-                                Few of the services are IAM - https://cloud.ibm.com/apidocs/iam-identity-token-api
-                                ResourceController - https://cloud.ibm.com/apidocs/resource-controller/resource-controller
-                                Power Cloud - https://cloud.ibm.com/apidocs/power-cloud
-                              pattern: ^[a-z0-9-]+$
-                              type: string
-                            url:
-                              description: url is fully qualified URI with scheme
-                                https, that overrides the default generated endpoint
-                                for a client. This must be provided and cannot be
-                                empty.
-                              format: uri
-                              pattern: ^https://
-                              type: string
-                          required:
-                          - name
-                          - url
-                          type: object
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - name
-                        x-kubernetes-list-type: map
-                    type: object
-                  type:
-                    description: type is the underlying infrastructure provider for
-                      the cluster. This value controls whether infrastructure automation
-                      such as service load balancers, dynamic volume provisioning,
-                      machine creation and deletion, and other integrations are enabled.
-                      If None, no infrastructure automation is enabled. Allowed values
-                      are "AWS", "Azure", "BareMetal", "GCP", "Libvirt", "OpenStack",
-                      "VSphere", "oVirt", "KubeVirt", "EquinixMetal", "PowerVS", "AlibabaCloud",
-                      "Nutanix" and "None". Individual components may not support
-                      all platforms, and must handle unrecognized platforms as None
-                      if they do not support that platform.
-                    enum:
-                    - ""
-                    - AWS
-                    - Azure
-                    - BareMetal
-                    - GCP
-                    - Libvirt
-                    - OpenStack
-                    - None
-                    - VSphere
-                    - oVirt
-                    - IBMCloud
-                    - KubeVirt
-                    - EquinixMetal
-                    - PowerVS
-                    - AlibabaCloud
-                    - Nutanix
-                    - External
-                    type: string
-                  vsphere:
-                    description: VSphere contains settings specific to the VSphere
-                      infrastructure provider.
-                    properties:
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IP addresses,
-                          one from IPv4 family and one from IPv6. In single stack
-                          clusters a single IP address is expected. When omitted,
-                          values from the status.apiServerInternalIPs will be used.
-                          Once set, the list cannot be completely removed (but its
-                          second entry can).
-                        items:
-                          description: IP is an IP address (for example, "10.0.0.0"
-                            or "fd00::").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                        x-kubernetes-validations:
-                        - message: apiServerInternalIPs must contain at most one IPv4
-                            address and at most one IPv6 address
-                          rule: 'size(self) == 2 ? self.exists_one(x, x.contains('':''))
-                            : true'
-                      failureDomains:
-                        description: failureDomains contains the definition of region,
-                          zone and the vCenter topology. If this is omitted failure
-                          domains (regions and zones) will not be used.
-                        items:
-                          description: VSpherePlatformFailureDomainSpec holds the
-                            region and zone failure domain and the vCenter topology
-                            of that failure domain.
-                          properties:
-                            name:
-                              description: name defines the arbitrary but unique name
-                                of a failure domain.
-                              maxLength: 256
-                              minLength: 1
-                              type: string
-                            region:
-                              description: region defines the name of a region tag
-                                that will be attached to a vCenter datacenter. The
-                                tag category in vCenter must be named openshift-region.
-                              maxLength: 80
-                              minLength: 1
-                              type: string
-                            server:
-                              anyOf:
-                              - format: ipv4
-                              - format: ipv6
-                              - format: hostname
-                              description: server is the fully-qualified domain name
-                                or the IP address of the vCenter server. ---
-                              maxLength: 255
-                              minLength: 1
-                              type: string
-                            topology:
-                              description: Topology describes a given failure domain
-                                using vSphere constructs
-                              properties:
-                                computeCluster:
-                                  description: computeCluster the absolute path of
-                                    the vCenter cluster in which virtual machine will
-                                    be located. The absolute path is of the form /<datacenter>/host/<cluster>.
-                                    The maximum length of the path is 2048 characters.
-                                  maxLength: 2048
-                                  pattern: ^/.*?/host/.*?
-                                  type: string
-                                datacenter:
-                                  description: datacenter is the name of vCenter datacenter
-                                    in which virtual machines will be located. The
-                                    maximum length of the datacenter name is 80 characters.
-                                  maxLength: 80
-                                  type: string
-                                datastore:
-                                  description: datastore is the absolute path of the
-                                    datastore in which the virtual machine is located.
-                                    The absolute path is of the form /<datacenter>/datastore/<datastore>
-                                    The maximum length of the path is 2048 characters.
-                                  maxLength: 2048
-                                  pattern: ^/.*?/datastore/.*?
-                                  type: string
-                                folder:
-                                  description: folder is the absolute path of the
-                                    folder where virtual machines are located. The
-                                    absolute path is of the form /<datacenter>/vm/<folder>.
-                                    The maximum length of the path is 2048 characters.
-                                  maxLength: 2048
-                                  pattern: ^/.*?/vm/.*?
-                                  type: string
-                                networks:
-                                  description: networks is the list of port group
-                                    network names within this failure domain. Currently,
-                                    we only support a single interface per RHCOS virtual
-                                    machine. The available networks (port groups)
-                                    can be listed using `govc ls 'network/*'` The
-                                    single interface should be the absolute path of
-                                    the form /<datacenter>/network/<portgroup>.
-                                  items:
-                                    type: string
-                                  maxItems: 1
-                                  minItems: 1
-                                  type: array
-                                  x-kubernetes-list-type: atomic
-                                resourcePool:
-                                  description: resourcePool is the absolute path of
-                                    the resource pool where virtual machines will
-                                    be created. The absolute path is of the form /<datacenter>/host/<cluster>/Resources/<resourcepool>.
-                                    The maximum length of the path is 2048 characters.
-                                  maxLength: 2048
-                                  pattern: ^/.*?/host/.*?/Resources.*
-                                  type: string
-                                template:
-                                  description: "template is the full inventory path
-                                    of the virtual machine or template that will be
-                                    cloned when creating new machines in this failure
-                                    domain. The maximum length of the path is 2048
-                                    characters. \n When omitted, the template will
-                                    be calculated by the control plane machineset
-                                    operator based on the region and zone defined
-                                    in VSpherePlatformFailureDomainSpec. For example,
-                                    for zone=zonea, region=region1, and infrastructure
-                                    name=test, the template path would be calculated
-                                    as /<datacenter>/vm/test-rhcos-region1-zonea."
-                                  maxLength: 2048
-                                  minLength: 1
-                                  pattern: ^/.*?/vm/.*?
-                                  type: string
-                              required:
-                              - computeCluster
-                              - datacenter
-                              - datastore
-                              - networks
-                              type: object
-                            zone:
-                              description: zone defines the name of a zone tag that
-                                will be attached to a vCenter cluster. The tag category
-                                in vCenter must be named openshift-zone.
-                              maxLength: 80
-                              minLength: 1
-                              type: string
-                          required:
-                          - name
-                          - region
-                          - server
-                          - topology
-                          - zone
-                          type: object
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - name
-                        x-kubernetes-list-type: map
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IP
-                          addresses, one from IPv4 family and one from IPv6. In single
-                          stack clusters a single IP address is expected. When omitted,
-                          values from the status.ingressIPs will be used. Once set,
-                          the list cannot be completely removed (but its second entry
-                          can).
-                        items:
-                          description: IP is an IP address (for example, "10.0.0.0"
-                            or "fd00::").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                        x-kubernetes-validations:
-                        - message: ingressIPs must contain at most one IPv4 address
-                            and at most one IPv6 address
-                          rule: 'size(self) == 2 ? self.exists_one(x, x.contains('':''))
-                            : true'
-                      machineNetworks:
-                        description: machineNetworks are IP networks used to connect
-                          all the OpenShift cluster nodes. Each network is provided
-                          in the CIDR format and should be IPv4 or IPv6, for example
-                          "10.0.0.0/8" or "fd00::/8".
-                        items:
-                          description: CIDR is an IP address range in CIDR notation
-                            (for example, "10.0.0.0/8" or "fd00::/8").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[0-9]))$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))$)
-                          type: string
-                        maxItems: 32
-                        type: array
-                        x-kubernetes-list-type: set
-                      nodeNetworking:
-                        description: nodeNetworking contains the definition of internal
-                          and external network constraints for assigning the node's
-                          networking. If this field is omitted, networking defaults
-                          to the legacy address selection behavior which is to only
-                          support a single address and return the first one found.
-                        properties:
-                          external:
-                            description: external represents the network configuration
-                              of the node that is externally routable.
-                            properties:
-                              excludeNetworkSubnetCidr:
-                                description: excludeNetworkSubnetCidr IP addresses
-                                  in subnet ranges will be excluded when selecting
-                                  the IP address from the VirtualMachine's VM for
-                                  use in the status.addresses fields. ---
-                                items:
-                                  format: cidr
-                                  type: string
-                                type: array
-                                x-kubernetes-list-type: atomic
-                              network:
-                                description: network VirtualMachine's VM Network names
-                                  that will be used to when searching for status.addresses
-                                  fields. Note that if internal.networkSubnetCIDR
-                                  and external.networkSubnetCIDR are not set, then
-                                  the vNIC associated to this network must only have
-                                  a single IP address assigned to it. The available
-                                  networks (port groups) can be listed using `govc
-                                  ls 'network/*'`
-                                type: string
-                              networkSubnetCidr:
-                                description: networkSubnetCidr IP address on VirtualMachine's
-                                  network interfaces included in the fields' CIDRs
-                                  that will be used in respective status.addresses
-                                  fields. ---
-                                items:
-                                  format: cidr
-                                  type: string
-                                type: array
-                                x-kubernetes-list-type: set
-                            type: object
-                          internal:
-                            description: internal represents the network configuration
-                              of the node that is routable only within the cluster.
-                            properties:
-                              excludeNetworkSubnetCidr:
-                                description: excludeNetworkSubnetCidr IP addresses
-                                  in subnet ranges will be excluded when selecting
-                                  the IP address from the VirtualMachine's VM for
-                                  use in the status.addresses fields. ---
-                                items:
-                                  format: cidr
-                                  type: string
-                                type: array
-                                x-kubernetes-list-type: atomic
-                              network:
-                                description: network VirtualMachine's VM Network names
-                                  that will be used to when searching for status.addresses
-                                  fields. Note that if internal.networkSubnetCIDR
-                                  and external.networkSubnetCIDR are not set, then
-                                  the vNIC associated to this network must only have
-                                  a single IP address assigned to it. The available
-                                  networks (port groups) can be listed using `govc
-                                  ls 'network/*'`
-                                type: string
-                              networkSubnetCidr:
-                                description: networkSubnetCidr IP address on VirtualMachine's
-                                  network interfaces included in the fields' CIDRs
-                                  that will be used in respective status.addresses
-                                  fields. ---
-                                items:
-                                  format: cidr
-                                  type: string
-                                type: array
-                                x-kubernetes-list-type: set
-                            type: object
-                        type: object
-                      vcenters:
-                        description: vcenters holds the connection details for services
-                          to communicate with vCenter. Currently, only a single vCenter
-                          is supported. ---
-                        items:
-                          description: VSpherePlatformVCenterSpec stores the vCenter
-                            connection fields. This is used by the vSphere CCM.
-                          properties:
-                            datacenters:
-                              description: The vCenter Datacenters in which the RHCOS
-                                vm guests are located. This field will be used by
-                                the Cloud Controller Manager. Each datacenter listed
-                                here should be used within a topology.
-                              items:
-                                type: string
-                              minItems: 1
-                              type: array
-                              x-kubernetes-list-type: set
-                            port:
-                              description: port is the TCP port that will be used
-                                to communicate to the vCenter endpoint. When omitted,
-                                this means the user has no opinion and it is up to
-                                the platform to choose a sensible default, which is
-                                subject to change over time.
-                              format: int32
-                              maximum: 32767
-                              minimum: 1
-                              type: integer
-                            server:
-                              anyOf:
-                              - format: ipv4
-                              - format: ipv6
-                              - format: hostname
-                              description: server is the fully-qualified domain name
-                                or the IP address of the vCenter server. ---
-                              maxLength: 255
-                              type: string
-                          required:
-                          - datacenters
-                          - server
-                          type: object
-                        maxItems: 1
-                        minItems: 0
-                        type: array
-                        x-kubernetes-list-type: atomic
-                    type: object
-                    x-kubernetes-validations:
-                    - message: apiServerInternalIPs list is required once set
-                      rule: '!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)'
-                    - message: ingressIPs list is required once set
-                      rule: '!has(oldSelf.ingressIPs) || has(self.ingressIPs)'
-                type: object
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            properties:
-              apiServerInternalURI:
-                description: apiServerInternalURL is a valid URI with scheme 'https',
-                  address and optionally a port (defaulting to 443).  apiServerInternalURL
-                  can be used by components like kubelets, to contact the Kubernetes
-                  API server using the infrastructure provider rather than Kubernetes
-                  networking.
-                type: string
-              apiServerURL:
-                description: apiServerURL is a valid URI with scheme 'https', address
-                  and optionally a port (defaulting to 443).  apiServerURL can be
-                  used by components like the web console to tell users where to find
-                  the Kubernetes API.
-                type: string
-              controlPlaneTopology:
-                default: HighlyAvailable
-                description: controlPlaneTopology expresses the expectations for operands
-                  that normally run on control nodes. The default is 'HighlyAvailable',
-                  which represents the behavior operators have in a "normal" cluster.
-                  The 'SingleReplica' mode will be used in single-node deployments
-                  and the operators should not configure the operand for highly-available
-                  operation The 'External' mode indicates that the control plane is
-                  hosted externally to the cluster and that its components are not
-                  visible within the cluster.
-                enum:
-                - HighlyAvailable
-                - SingleReplica
-                - External
-                type: string
-              cpuPartitioning:
-                default: None
-                description: cpuPartitioning expresses if CPU partitioning is a currently
-                  enabled feature in the cluster. CPU Partitioning means that this
-                  cluster can support partitioning workloads to specific CPU Sets.
-                  Valid values are "None" and "AllNodes". When omitted, the default
-                  value is "None". The default value of "None" indicates that no nodes
-                  will be setup with CPU partitioning. The "AllNodes" value indicates
-                  that all nodes have been setup with CPU partitioning, and can then
-                  be further configured via the PerformanceProfile API.
-                enum:
-                - None
-                - AllNodes
-                type: string
-              etcdDiscoveryDomain:
-                description: 'etcdDiscoveryDomain is the domain used to fetch the
-                  SRV records for discovering etcd servers and clients. For more info:
-                  https://github.com/etcd-io/etcd/blob/329be66e8b3f9e2e6af83c123ff89297e49ebd15/Documentation/op-guide/clustering.md#dns-discovery
-                  deprecated: as of 4.7, this field is no longer set or honored.  It
-                  will be removed in a future release.'
-                type: string
-              infrastructureName:
-                description: infrastructureName uniquely identifies a cluster with
-                  a human friendly name. Once set it should not be changed. Must be
-                  of max length 27 and must have only alphanumeric or hyphen characters.
-                type: string
-              infrastructureTopology:
-                default: HighlyAvailable
-                description: 'infrastructureTopology expresses the expectations for
-                  infrastructure services that do not run on control plane nodes,
-                  usually indicated by a node selector for a `role` value other than
-                  `master`. The default is ''HighlyAvailable'', which represents the
-                  behavior operators have in a "normal" cluster. The ''SingleReplica''
-                  mode will be used in single-node deployments and the operators should
-                  not configure the operand for highly-available operation NOTE: External
-                  topology mode is not applicable for this field.'
-                enum:
-                - HighlyAvailable
-                - SingleReplica
-                type: string
-              platform:
-                description: "platform is the underlying infrastructure provider for
-                  the cluster. \n Deprecated: Use platformStatus.type instead."
-                enum:
-                - ""
-                - AWS
-                - Azure
-                - BareMetal
-                - GCP
-                - Libvirt
-                - OpenStack
-                - None
-                - VSphere
-                - oVirt
-                - IBMCloud
-                - KubeVirt
-                - EquinixMetal
-                - PowerVS
-                - AlibabaCloud
-                - Nutanix
-                - External
-                type: string
-              platformStatus:
-                description: platformStatus holds status information specific to the
-                  underlying infrastructure provider.
-                properties:
-                  alibabaCloud:
-                    description: AlibabaCloud contains settings specific to the Alibaba
-                      Cloud infrastructure provider.
-                    properties:
-                      region:
-                        description: region specifies the region for Alibaba Cloud
-                          resources created for the cluster.
-                        pattern: ^[0-9A-Za-z-]+$
-                        type: string
-                      resourceGroupID:
-                        description: resourceGroupID is the ID of the resource group
-                          for the cluster.
-                        pattern: ^(rg-[0-9A-Za-z]+)?$
-                        type: string
-                      resourceTags:
-                        description: resourceTags is a list of additional tags to
-                          apply to Alibaba Cloud resources created for the cluster.
-                        items:
-                          description: AlibabaCloudResourceTag is the set of tags
-                            to add to apply to resources.
-                          properties:
-                            key:
-                              description: key is the key of the tag.
-                              maxLength: 128
-                              minLength: 1
-                              type: string
-                            value:
-                              description: value is the value of the tag.
-                              maxLength: 128
-                              minLength: 1
-                              type: string
-                          required:
-                          - key
-                          - value
-                          type: object
-                        maxItems: 20
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - key
-                        x-kubernetes-list-type: map
-                    required:
-                    - region
-                    type: object
-                  aws:
-                    description: AWS contains settings specific to the Amazon Web
-                      Services infrastructure provider.
-                    properties:
-                      region:
-                        description: region holds the default AWS region for new AWS
-                          resources created by the cluster.
-                        type: string
-                      resourceTags:
-                        description: resourceTags is a list of additional tags to
-                          apply to AWS resources created for the cluster. See https://docs.aws.amazon.com/general/latest/gr/aws_tagging.html
-                          for information on tagging AWS resources. AWS supports a
-                          maximum of 50 tags per resource. OpenShift reserves 25 tags
-                          for its use, leaving 25 tags available for the user.
-                        items:
-                          description: AWSResourceTag is a tag to apply to AWS resources
-                            created for the cluster.
-                          properties:
-                            key:
-                              description: key is the key of the tag
-                              maxLength: 128
-                              minLength: 1
-                              pattern: ^[0-9A-Za-z_.:/=+-@]+$
-                              type: string
-                            value:
-                              description: value is the value of the tag. Some AWS
-                                service do not support empty values. Since tags are
-                                added to resources in many services, the length of
-                                the tag value must meet the requirements of all services.
-                              maxLength: 256
-                              minLength: 1
-                              pattern: ^[0-9A-Za-z_.:/=+-@]+$
-                              type: string
-                          required:
-                          - key
-                          - value
-                          type: object
-                        maxItems: 25
-                        type: array
-                        x-kubernetes-list-type: atomic
-                      serviceEndpoints:
-                        description: ServiceEndpoints list contains custom endpoints
-                          which will override default service endpoint of AWS Services.
-                          There must be only one ServiceEndpoint for a service.
-                        items:
-                          description: AWSServiceEndpoint store the configuration
-                            of a custom url to override existing defaults of AWS Services.
-                          properties:
-                            name:
-                              description: name is the name of the AWS service. The
-                                list of all the service names can be found at https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html
-                                This must be provided and cannot be empty.
-                              pattern: ^[a-z0-9-]+$
-                              type: string
-                            url:
-                              description: url is fully qualified URI with scheme
-                                https, that overrides the default generated endpoint
-                                for a client. This must be provided and cannot be
-                                empty.
-                              pattern: ^https://
-                              type: string
-                          type: object
-                        type: array
-                        x-kubernetes-list-type: atomic
-                    type: object
-                  azure:
-                    description: Azure contains settings specific to the Azure infrastructure
-                      provider.
-                    properties:
-                      armEndpoint:
-                        description: armEndpoint specifies a URL to use for resource
-                          management in non-soverign clouds such as Azure Stack.
-                        type: string
-                      cloudName:
-                        description: cloudName is the name of the Azure cloud environment
-                          which can be used to configure the Azure SDK with the appropriate
-                          Azure API endpoints. If empty, the value is equal to `AzurePublicCloud`.
-                        enum:
-                        - ""
-                        - AzurePublicCloud
-                        - AzureUSGovernmentCloud
-                        - AzureChinaCloud
-                        - AzureGermanCloud
-                        - AzureStackCloud
-                        type: string
-                      networkResourceGroupName:
-                        description: networkResourceGroupName is the Resource Group
-                          for network resources like the Virtual Network and Subnets
-                          used by the cluster. If empty, the value is same as ResourceGroupName.
-                        type: string
-                      resourceGroupName:
-                        description: resourceGroupName is the Resource Group for new
-                          Azure resources created for the cluster.
-                        type: string
-                      resourceTags:
-                        description: resourceTags is a list of additional tags to
-                          apply to Azure resources created for the cluster. See https://docs.microsoft.com/en-us/rest/api/resources/tags
-                          for information on tagging Azure resources. Due to limitations
-                          on Automation, Content Delivery Network, DNS Azure resources,
-                          a maximum of 15 tags may be applied. OpenShift reserves
-                          5 tags for internal use, allowing 10 tags for user configuration.
-                        items:
-                          description: AzureResourceTag is a tag to apply to Azure
-                            resources created for the cluster.
-                          properties:
-                            key:
-                              description: key is the key part of the tag. A tag key
-                                can have a maximum of 128 characters and cannot be
-                                empty. Key must begin with a letter, end with a letter,
-                                number or underscore, and must contain only alphanumeric
-                                characters and the following special characters `_
-                                . -`.
-                              maxLength: 128
-                              minLength: 1
-                              pattern: ^[a-zA-Z]([0-9A-Za-z_.-]*[0-9A-Za-z_])?$
-                              type: string
-                            value:
-                              description: 'value is the value part of the tag. A
-                                tag value can have a maximum of 256 characters and
-                                cannot be empty. Value must contain only alphanumeric
-                                characters and the following special characters `_
-                                + , - . / : ; < = > ? @`.'
-                              maxLength: 256
-                              minLength: 1
-                              pattern: ^[0-9A-Za-z_.=+-@]+$
-                              type: string
-                          required:
-                          - key
-                          - value
-                          type: object
-                        maxItems: 10
-                        type: array
-                        x-kubernetes-list-type: atomic
-                        x-kubernetes-validations:
-                        - message: resourceTags are immutable and may only be configured
-                            during installation
-                          rule: self.all(x, x in oldSelf) && oldSelf.all(x, x in self)
-                    type: object
-                    x-kubernetes-validations:
-                    - message: resourceTags may only be configured during installation
-                      rule: '!has(oldSelf.resourceTags) && !has(self.resourceTags)
-                        || has(oldSelf.resourceTags) && has(self.resourceTags)'
-                  baremetal:
-                    description: BareMetal contains settings specific to the BareMetal
-                      platform.
-                    properties:
-                      apiServerInternalIP:
-                        description: "apiServerInternalIP is an IP address to contact
-                          the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. It is the IP that the
-                          Infrastructure.status.apiServerInternalURI points to. It
-                          is the IP for a self-hosted load balancer in front of the
-                          API servers. \n Deprecated: Use APIServerInternalIPs instead."
-                        type: string
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IPs otherwise
-                          only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      ingressIP:
-                        description: "ingressIP is an external IP which routes to
-                          the default ingress controller. The IP is a suitable target
-                          of a wildcard DNS record used to resolve default route host
-                          names. \n Deprecated: Use IngressIPs instead."
-                        type: string
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IPs
-                          otherwise only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      loadBalancer:
-                        default:
-                          type: OpenShiftManagedDefault
-                        description: loadBalancer defines how the load balancer used
-                          by the cluster is configured.
-                        properties:
-                          type:
-                            default: OpenShiftManagedDefault
-                            description: type defines the type of load balancer used
-                              by the cluster on BareMetal platform which can be a
-                              user-managed or openshift-managed load balancer that
-                              is to be used for the OpenShift API and Ingress endpoints.
-                              When set to OpenShiftManagedDefault the static pods
-                              in charge of API and Ingress traffic load-balancing
-                              defined in the machine config operator will be deployed.
-                              When set to UserManaged these static pods will not be
-                              deployed and it is expected that the load balancer is
-                              configured out of band by the deployer. When omitted,
-                              this means no opinion and the platform is left to choose
-                              a reasonable default. The default value is OpenShiftManagedDefault.
-                            enum:
-                            - OpenShiftManagedDefault
-                            - UserManaged
-                            type: string
-                            x-kubernetes-validations:
-                            - message: type is immutable once set
-                              rule: oldSelf == '' || self == oldSelf
-                        type: object
-                      machineNetworks:
-                        description: machineNetworks are IP networks used to connect
-                          all the OpenShift cluster nodes.
-                        items:
-                          description: CIDR is an IP address range in CIDR notation
-                            (for example, "10.0.0.0/8" or "fd00::/8").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[0-9]))$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))$)
-                          type: string
-                        maxItems: 32
-                        type: array
-                        x-kubernetes-list-type: set
-                      nodeDNSIP:
-                        description: nodeDNSIP is the IP address for the internal
-                          DNS used by the nodes. Unlike the one managed by the DNS
-                          operator, `NodeDNSIP` provides name resolution for the nodes
-                          themselves. There is no DNS-as-a-service for BareMetal deployments.
-                          In order to minimize necessary changes to the datacenter
-                          DNS, a DNS service is hosted as a static pod to serve those
-                          hostnames to the nodes in the cluster.
-                        type: string
-                    type: object
-                  equinixMetal:
-                    description: EquinixMetal contains settings specific to the Equinix
-                      Metal infrastructure provider.
-                    properties:
-                      apiServerInternalIP:
-                        description: apiServerInternalIP is an IP address to contact
-                          the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. It is the IP that the
-                          Infrastructure.status.apiServerInternalURI points to. It
-                          is the IP for a self-hosted load balancer in front of the
-                          API servers.
-                        type: string
-                      ingressIP:
-                        description: ingressIP is an external IP which routes to the
-                          default ingress controller. The IP is a suitable target
-                          of a wildcard DNS record used to resolve default route host
-                          names.
-                        type: string
-                    type: object
-                  external:
-                    description: External contains settings specific to the generic
-                      External infrastructure provider.
-                    properties:
-                      cloudControllerManager:
-                        description: cloudControllerManager contains settings specific
-                          to the external Cloud Controller Manager (a.k.a. CCM or
-                          CPI). When omitted, new nodes will be not tainted and no
-                          extra initialization from the cloud controller manager is
-                          expected.
-                        properties:
-                          state:
-                            description: "state determines whether or not an external
-                              Cloud Controller Manager is expected to be installed
-                              within the cluster. https://kubernetes.io/docs/tasks/administer-cluster/running-cloud-controller/#running-cloud-controller-manager
-                              \n Valid values are \"External\", \"None\" and omitted.
-                              When set to \"External\", new nodes will be tainted
-                              as uninitialized when created, preventing them from
-                              running workloads until they are initialized by the
-                              cloud controller manager. When omitted or set to \"None\",
-                              new nodes will be not tainted and no extra initialization
-                              from the cloud controller manager is expected."
-                            enum:
-                            - ""
-                            - External
-                            - None
-                            type: string
-                            x-kubernetes-validations:
-                            - message: state is immutable once set
-                              rule: self == oldSelf
-                        type: object
-                        x-kubernetes-validations:
-                        - message: state may not be added or removed once set
-                          rule: (has(self.state) == has(oldSelf.state)) || (!has(oldSelf.state)
-                            && self.state != "External")
-                    type: object
-                    x-kubernetes-validations:
-                    - message: cloudControllerManager may not be added or removed
-                        once set
-                      rule: has(self.cloudControllerManager) == has(oldSelf.cloudControllerManager)
-                  gcp:
-                    description: GCP contains settings specific to the Google Cloud
-                      Platform infrastructure provider.
-                    properties:
-                      cloudLoadBalancerConfig:
-                        default:
-                          dnsType: PlatformDefault
-                        description: cloudLoadBalancerConfig is a union that contains
-                          the IP addresses of API, API-Int and Ingress Load Balancers
-                          created on the cloud platform. These values would not be
-                          populated on on-prem platforms. These Load Balancer IPs
-                          are used to configure the in-cluster DNS instances for API,
-                          API-Int and Ingress services. `dnsType` is expected to be
-                          set to `ClusterHosted` when these Load Balancer IP addresses
-                          are populated and used.
-                        nullable: true
-                        properties:
-                          clusterHosted:
-                            description: clusterHosted holds the IP addresses of API,
-                              API-Int and Ingress Load Balancers on Cloud Platforms.
-                              The DNS solution hosted within the cluster use these
-                              IP addresses to provide resolution for API, API-Int
-                              and Ingress services.
-                            properties:
-                              apiIntLoadBalancerIPs:
-                                description: apiIntLoadBalancerIPs holds Load Balancer
-                                  IPs for the internal API service. These Load Balancer
-                                  IP addresses can be IPv4 and/or IPv6 addresses.
-                                  Entries in the apiIntLoadBalancerIPs must be unique.
-                                  A maximum of 16 IP addresses are permitted.
-                                format: ip
-                                items:
-                                  description: IP is an IP address (for example, "10.0.0.0"
-                                    or "fd00::").
-                                  pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                                  type: string
-                                maxItems: 16
-                                type: array
-                                x-kubernetes-list-type: set
-                              apiLoadBalancerIPs:
-                                description: apiLoadBalancerIPs holds Load Balancer
-                                  IPs for the API service. These Load Balancer IP
-                                  addresses can be IPv4 and/or IPv6 addresses. Could
-                                  be empty for private clusters. Entries in the apiLoadBalancerIPs
-                                  must be unique. A maximum of 16 IP addresses are
-                                  permitted.
-                                format: ip
-                                items:
-                                  description: IP is an IP address (for example, "10.0.0.0"
-                                    or "fd00::").
-                                  pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                                  type: string
-                                maxItems: 16
-                                type: array
-                                x-kubernetes-list-type: set
-                              ingressLoadBalancerIPs:
-                                description: ingressLoadBalancerIPs holds IPs for
-                                  Ingress Load Balancers. These Load Balancer IP addresses
-                                  can be IPv4 and/or IPv6 addresses. Entries in the
-                                  ingressLoadBalancerIPs must be unique. A maximum
-                                  of 16 IP addresses are permitted.
-                                format: ip
-                                items:
-                                  description: IP is an IP address (for example, "10.0.0.0"
-                                    or "fd00::").
-                                  pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                                  type: string
-                                maxItems: 16
-                                type: array
-                                x-kubernetes-list-type: set
-                            type: object
-                          dnsType:
-                            default: PlatformDefault
-                            description: dnsType indicates the type of DNS solution
-                              in use within the cluster. Its default value of `PlatformDefault`
-                              indicates that the cluster's DNS is the default provided
-                              by the cloud platform. It can be set to `ClusterHosted`
-                              to bypass the configuration of the cloud default DNS.
-                              In this mode, the cluster needs to provide a self-hosted
-                              DNS solution for the cluster's installation to succeed.
-                              The cluster's use of the cloud's Load Balancers is unaffected
-                              by this setting. The value is immutable after it has
-                              been set at install time. Currently, there is no way
-                              for the customer to add additional DNS entries into
-                              the cluster hosted DNS. Enabling this functionality
-                              allows the user to start their own DNS solution outside
-                              the cluster after installation is complete. The customer
-                              would be responsible for configuring this custom DNS
-                              solution, and it can be run in addition to the in-cluster
-                              DNS solution.
-                            enum:
-                            - ClusterHosted
-                            - PlatformDefault
-                            type: string
-                            x-kubernetes-validations:
-                            - message: dnsType is immutable
-                              rule: oldSelf == '' || self == oldSelf
-                        type: object
-                        x-kubernetes-validations:
-                        - message: clusterHosted is permitted only when dnsType is
-                            ClusterHosted
-                          rule: 'has(self.dnsType) && self.dnsType != ''ClusterHosted''
-                            ? !has(self.clusterHosted) : true'
-                      projectID:
-                        description: resourceGroupName is the Project ID for new GCP
-                          resources created for the cluster.
-                        type: string
-                      region:
-                        description: region holds the region for new GCP resources
-                          created for the cluster.
-                        type: string
-                      resourceLabels:
-                        description: resourceLabels is a list of additional labels
-                          to apply to GCP resources created for the cluster. See https://cloud.google.com/compute/docs/labeling-resources
-                          for information on labeling GCP resources. GCP supports
-                          a maximum of 64 labels per resource. OpenShift reserves
-                          32 labels for internal use, allowing 32 labels for user
-                          configuration.
-                        items:
-                          description: GCPResourceLabel is a label to apply to GCP
-                            resources created for the cluster.
-                          properties:
-                            key:
-                              description: key is the key part of the label. A label
-                                key can have a maximum of 63 characters and cannot
-                                be empty. Label key must begin with a lowercase letter,
-                                and must contain only lowercase letters, numeric characters,
-                                and the following special characters `_-`. Label key
-                                must not have the reserved prefixes `kubernetes-io`
-                                and `openshift-io`.
-                              maxLength: 63
-                              minLength: 1
-                              pattern: ^[a-z][0-9a-z_-]{0,62}$
-                              type: string
-                              x-kubernetes-validations:
-                              - message: label keys must not start with either `openshift-io`
-                                  or `kubernetes-io`
-                                rule: '!self.startsWith(''openshift-io'') && !self.startsWith(''kubernetes-io'')'
-                            value:
-                              description: value is the value part of the label. A
-                                label value can have a maximum of 63 characters and
-                                cannot be empty. Value must contain only lowercase
-                                letters, numeric characters, and the following special
-                                characters `_-`.
-                              maxLength: 63
-                              minLength: 1
-                              pattern: ^[0-9a-z_-]{1,63}$
-                              type: string
-                          required:
-                          - key
-                          - value
-                          type: object
-                        maxItems: 32
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - key
-                        x-kubernetes-list-type: map
-                        x-kubernetes-validations:
-                        - message: resourceLabels are immutable and may only be configured
-                            during installation
-                          rule: self.all(x, x in oldSelf) && oldSelf.all(x, x in self)
-                      resourceTags:
-                        description: resourceTags is a list of additional tags to
-                          apply to GCP resources created for the cluster. See https://cloud.google.com/resource-manager/docs/tags/tags-overview
-                          for information on tagging GCP resources. GCP supports a
-                          maximum of 50 tags per resource.
-                        items:
-                          description: GCPResourceTag is a tag to apply to GCP resources
-                            created for the cluster.
-                          properties:
-                            key:
-                              description: key is the key part of the tag. A tag key
-                                can have a maximum of 63 characters and cannot be
-                                empty. Tag key must begin and end with an alphanumeric
-                                character, and must contain only uppercase, lowercase
-                                alphanumeric characters, and the following special
-                                characters `._-`.
-                              maxLength: 63
-                              minLength: 1
-                              pattern: ^[a-zA-Z0-9]([0-9A-Za-z_.-]{0,61}[a-zA-Z0-9])?$
-                              type: string
-                            parentID:
-                              description: 'parentID is the ID of the hierarchical
-                                resource where the tags are defined, e.g. at the Organization
-                                or the Project level. To find the Organization or
-                                Project ID refer to the following pages: https://cloud.google.com/resource-manager/docs/creating-managing-organization#retrieving_your_organization_id,
-                                https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects.
-                                An OrganizationID must consist of decimal numbers,
-                                and cannot have leading zeroes. A ProjectID must be
-                                6 to 30 characters in length, can only contain lowercase
-                                letters, numbers, and hyphens, and must start with
-                                a letter, and cannot end with a hyphen.'
-                              maxLength: 32
-                              minLength: 1
-                              pattern: (^[1-9][0-9]{0,31}$)|(^[a-z][a-z0-9-]{4,28}[a-z0-9]$)
-                              type: string
-                            value:
-                              description: value is the value part of the tag. A tag
-                                value can have a maximum of 63 characters and cannot
-                                be empty. Tag value must begin and end with an alphanumeric
-                                character, and must contain only uppercase, lowercase
-                                alphanumeric characters, and the following special
-                                characters `_-.@%=+:,*#&(){}[]` and spaces.
-                              maxLength: 63
-                              minLength: 1
-                              pattern: ^[a-zA-Z0-9]([0-9A-Za-z_.@%=+:,*#&()\[\]{}\-\s]{0,61}[a-zA-Z0-9])?$
-                              type: string
-                          required:
-                          - key
-                          - parentID
-                          - value
-                          type: object
-                        maxItems: 50
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - key
-                        x-kubernetes-list-type: map
-                        x-kubernetes-validations:
-                        - message: resourceTags are immutable and may only be configured
-                            during installation
-                          rule: self.all(x, x in oldSelf) && oldSelf.all(x, x in self)
-                    type: object
-                    x-kubernetes-validations:
-                    - message: resourceLabels may only be configured during installation
-                      rule: '!has(oldSelf.resourceLabels) && !has(self.resourceLabels)
-                        || has(oldSelf.resourceLabels) && has(self.resourceLabels)'
-                    - message: resourceTags may only be configured during installation
-                      rule: '!has(oldSelf.resourceTags) && !has(self.resourceTags)
-                        || has(oldSelf.resourceTags) && has(self.resourceTags)'
-                  ibmcloud:
-                    description: IBMCloud contains settings specific to the IBMCloud
-                      infrastructure provider.
-                    properties:
-                      cisInstanceCRN:
-                        description: CISInstanceCRN is the CRN of the Cloud Internet
-                          Services instance managing the DNS zone for the cluster's
-                          base domain
-                        type: string
-                      dnsInstanceCRN:
-                        description: DNSInstanceCRN is the CRN of the DNS Services
-                          instance managing the DNS zone for the cluster's base domain
-                        type: string
-                      location:
-                        description: Location is where the cluster has been deployed
-                        type: string
-                      providerType:
-                        description: ProviderType indicates the type of cluster that
-                          was created
-                        type: string
-                      resourceGroupName:
-                        description: ResourceGroupName is the Resource Group for new
-                          IBMCloud resources created for the cluster.
-                        type: string
-                      serviceEndpoints:
-                        description: serviceEndpoints is a list of custom endpoints
-                          which will override the default service endpoints of an
-                          IBM Cloud service. These endpoints are consumed by components
-                          within the cluster to reach the respective IBM Cloud Services.
-                        items:
-                          description: IBMCloudServiceEndpoint stores the configuration
-                            of a custom url to override existing defaults of IBM Cloud
-                            Services.
-                          properties:
-                            name:
-                              description: 'name is the name of the IBM Cloud service.
-                                Possible values are: CIS, COS, DNSServices, GlobalSearch,
-                                GlobalTagging, HyperProtect, IAM, KeyProtect, ResourceController,
-                                ResourceManager, or VPC. For example, the IBM Cloud
-                                Private IAM service could be configured with the service
-                                `name` of `IAM` and `url` of `https://private.iam.cloud.ibm.com`
-                                Whereas the IBM Cloud Private VPC service for US South
-                                (Dallas) could be configured with the service `name`
-                                of `VPC` and `url` of `https://us.south.private.iaas.cloud.ibm.com`'
-                              enum:
-                              - CIS
-                              - COS
-                              - DNSServices
-                              - GlobalSearch
-                              - GlobalTagging
-                              - HyperProtect
-                              - IAM
-                              - KeyProtect
-                              - ResourceController
-                              - ResourceManager
-                              - VPC
-                              type: string
-                            url:
-                              description: url is fully qualified URI with scheme
-                                https, that overrides the default generated endpoint
-                                for a client. This must be provided and cannot be
-                                empty.
-                              type: string
-                              x-kubernetes-validations:
-                              - message: url must be a valid absolute URL
-                                rule: isURL(self)
-                          required:
-                          - name
-                          - url
-                          type: object
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - name
-                        x-kubernetes-list-type: map
-                    type: object
-                  kubevirt:
-                    description: Kubevirt contains settings specific to the kubevirt
-                      infrastructure provider.
-                    properties:
-                      apiServerInternalIP:
-                        description: apiServerInternalIP is an IP address to contact
-                          the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. It is the IP that the
-                          Infrastructure.status.apiServerInternalURI points to. It
-                          is the IP for a self-hosted load balancer in front of the
-                          API servers.
-                        type: string
-                      ingressIP:
-                        description: ingressIP is an external IP which routes to the
-                          default ingress controller. The IP is a suitable target
-                          of a wildcard DNS record used to resolve default route host
-                          names.
-                        type: string
-                    type: object
-                  nutanix:
-                    description: Nutanix contains settings specific to the Nutanix
-                      infrastructure provider.
-                    properties:
-                      apiServerInternalIP:
-                        description: "apiServerInternalIP is an IP address to contact
-                          the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. It is the IP that the
-                          Infrastructure.status.apiServerInternalURI points to. It
-                          is the IP for a self-hosted load balancer in front of the
-                          API servers. \n Deprecated: Use APIServerInternalIPs instead."
-                        type: string
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IPs otherwise
-                          only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      ingressIP:
-                        description: "ingressIP is an external IP which routes to
-                          the default ingress controller. The IP is a suitable target
-                          of a wildcard DNS record used to resolve default route host
-                          names. \n Deprecated: Use IngressIPs instead."
-                        type: string
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IPs
-                          otherwise only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      loadBalancer:
-                        default:
-                          type: OpenShiftManagedDefault
-                        description: loadBalancer defines how the load balancer used
-                          by the cluster is configured.
-                        properties:
-                          type:
-                            default: OpenShiftManagedDefault
-                            description: type defines the type of load balancer used
-                              by the cluster on Nutanix platform which can be a user-managed
-                              or openshift-managed load balancer that is to be used
-                              for the OpenShift API and Ingress endpoints. When set
-                              to OpenShiftManagedDefault the static pods in charge
-                              of API and Ingress traffic load-balancing defined in
-                              the machine config operator will be deployed. When set
-                              to UserManaged these static pods will not be deployed
-                              and it is expected that the load balancer is configured
-                              out of band by the deployer. When omitted, this means
-                              no opinion and the platform is left to choose a reasonable
-                              default. The default value is OpenShiftManagedDefault.
-                            enum:
-                            - OpenShiftManagedDefault
-                            - UserManaged
-                            type: string
-                            x-kubernetes-validations:
-                            - message: type is immutable once set
-                              rule: oldSelf == '' || self == oldSelf
-                        type: object
-                    type: object
-                  openstack:
-                    description: OpenStack contains settings specific to the OpenStack
-                      infrastructure provider.
-                    properties:
-                      apiServerInternalIP:
-                        description: "apiServerInternalIP is an IP address to contact
-                          the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. It is the IP that the
-                          Infrastructure.status.apiServerInternalURI points to. It
-                          is the IP for a self-hosted load balancer in front of the
-                          API servers. \n Deprecated: Use APIServerInternalIPs instead."
-                        type: string
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IPs otherwise
-                          only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      cloudName:
-                        description: cloudName is the name of the desired OpenStack
-                          cloud in the client configuration file (`clouds.yaml`).
-                        type: string
-                      ingressIP:
-                        description: "ingressIP is an external IP which routes to
-                          the default ingress controller. The IP is a suitable target
-                          of a wildcard DNS record used to resolve default route host
-                          names. \n Deprecated: Use IngressIPs instead."
-                        type: string
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IPs
-                          otherwise only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      loadBalancer:
-                        default:
-                          type: OpenShiftManagedDefault
-                        description: loadBalancer defines how the load balancer used
-                          by the cluster is configured.
-                        properties:
-                          type:
-                            default: OpenShiftManagedDefault
-                            description: type defines the type of load balancer used
-                              by the cluster on OpenStack platform which can be a
-                              user-managed or openshift-managed load balancer that
-                              is to be used for the OpenShift API and Ingress endpoints.
-                              When set to OpenShiftManagedDefault the static pods
-                              in charge of API and Ingress traffic load-balancing
-                              defined in the machine config operator will be deployed.
-                              When set to UserManaged these static pods will not be
-                              deployed and it is expected that the load balancer is
-                              configured out of band by the deployer. When omitted,
-                              this means no opinion and the platform is left to choose
-                              a reasonable default. The default value is OpenShiftManagedDefault.
-                            enum:
-                            - OpenShiftManagedDefault
-                            - UserManaged
-                            type: string
-                            x-kubernetes-validations:
-                            - message: type is immutable once set
-                              rule: oldSelf == '' || self == oldSelf
-                        type: object
-                      machineNetworks:
-                        description: machineNetworks are IP networks used to connect
-                          all the OpenShift cluster nodes.
-                        items:
-                          description: CIDR is an IP address range in CIDR notation
-                            (for example, "10.0.0.0/8" or "fd00::/8").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[0-9]))$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))$)
-                          type: string
-                        maxItems: 32
-                        type: array
-                        x-kubernetes-list-type: set
-                      nodeDNSIP:
-                        description: nodeDNSIP is the IP address for the internal
-                          DNS used by the nodes. Unlike the one managed by the DNS
-                          operator, `NodeDNSIP` provides name resolution for the nodes
-                          themselves. There is no DNS-as-a-service for OpenStack deployments.
-                          In order to minimize necessary changes to the datacenter
-                          DNS, a DNS service is hosted as a static pod to serve those
-                          hostnames to the nodes in the cluster.
-                        type: string
-                    type: object
-                  ovirt:
-                    description: Ovirt contains settings specific to the oVirt infrastructure
-                      provider.
-                    properties:
-                      apiServerInternalIP:
-                        description: "apiServerInternalIP is an IP address to contact
-                          the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. It is the IP that the
-                          Infrastructure.status.apiServerInternalURI points to. It
-                          is the IP for a self-hosted load balancer in front of the
-                          API servers. \n Deprecated: Use APIServerInternalIPs instead."
-                        type: string
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IPs otherwise
-                          only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      ingressIP:
-                        description: "ingressIP is an external IP which routes to
-                          the default ingress controller. The IP is a suitable target
-                          of a wildcard DNS record used to resolve default route host
-                          names. \n Deprecated: Use IngressIPs instead."
-                        type: string
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IPs
-                          otherwise only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      loadBalancer:
-                        default:
-                          type: OpenShiftManagedDefault
-                        description: loadBalancer defines how the load balancer used
-                          by the cluster is configured.
-                        properties:
-                          type:
-                            default: OpenShiftManagedDefault
-                            description: type defines the type of load balancer used
-                              by the cluster on Ovirt platform which can be a user-managed
-                              or openshift-managed load balancer that is to be used
-                              for the OpenShift API and Ingress endpoints. When set
-                              to OpenShiftManagedDefault the static pods in charge
-                              of API and Ingress traffic load-balancing defined in
-                              the machine config operator will be deployed. When set
-                              to UserManaged these static pods will not be deployed
-                              and it is expected that the load balancer is configured
-                              out of band by the deployer. When omitted, this means
-                              no opinion and the platform is left to choose a reasonable
-                              default. The default value is OpenShiftManagedDefault.
-                            enum:
-                            - OpenShiftManagedDefault
-                            - UserManaged
-                            type: string
-                            x-kubernetes-validations:
-                            - message: type is immutable once set
-                              rule: oldSelf == '' || self == oldSelf
-                        type: object
-                      nodeDNSIP:
-                        description: 'deprecated: as of 4.6, this field is no longer
-                          set or honored.  It will be removed in a future release.'
-                        type: string
-                    type: object
-                  powervs:
-                    description: PowerVS contains settings specific to the Power Systems
-                      Virtual Servers infrastructure provider.
-                    properties:
-                      cisInstanceCRN:
-                        description: CISInstanceCRN is the CRN of the Cloud Internet
-                          Services instance managing the DNS zone for the cluster's
-                          base domain
-                        type: string
-                      dnsInstanceCRN:
-                        description: DNSInstanceCRN is the CRN of the DNS Services
-                          instance managing the DNS zone for the cluster's base domain
-                        type: string
-                      region:
-                        description: region holds the default Power VS region for
-                          new Power VS resources created by the cluster.
-                        type: string
-                      resourceGroup:
-                        description: 'resourceGroup is the resource group name for
-                          new IBMCloud resources created for a cluster. The resource
-                          group specified here will be used by cluster-image-registry-operator
-                          to set up a COS Instance in IBMCloud for the cluster registry.
-                          More about resource groups can be found here: https://cloud.ibm.com/docs/account?topic=account-rgs.
-                          When omitted, the image registry operator won''t be able
-                          to configure storage, which results in the image registry
-                          cluster operator not being in an available state.'
-                        maxLength: 40
-                        pattern: ^[a-zA-Z0-9-_ ]+$
-                        type: string
-                        x-kubernetes-validations:
-                        - message: resourceGroup is immutable once set
-                          rule: oldSelf == '' || self == oldSelf
-                      serviceEndpoints:
-                        description: serviceEndpoints is a list of custom endpoints
-                          which will override the default service endpoints of a Power
-                          VS service.
-                        items:
-                          description: PowervsServiceEndpoint stores the configuration
-                            of a custom url to override existing defaults of PowerVS
-                            Services.
-                          properties:
-                            name:
-                              description: name is the name of the Power VS service.
-                                Few of the services are IAM - https://cloud.ibm.com/apidocs/iam-identity-token-api
-                                ResourceController - https://cloud.ibm.com/apidocs/resource-controller/resource-controller
-                                Power Cloud - https://cloud.ibm.com/apidocs/power-cloud
-                              pattern: ^[a-z0-9-]+$
-                              type: string
-                            url:
-                              description: url is fully qualified URI with scheme
-                                https, that overrides the default generated endpoint
-                                for a client. This must be provided and cannot be
-                                empty.
-                              format: uri
-                              pattern: ^https://
-                              type: string
-                          required:
-                          - name
-                          - url
-                          type: object
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - name
-                        x-kubernetes-list-type: map
-                      zone:
-                        description: 'zone holds the default zone for the new Power
-                          VS resources created by the cluster. Note: Currently only
-                          single-zone OCP clusters are supported'
-                        type: string
-                    type: object
-                    x-kubernetes-validations:
-                    - message: cannot unset resourceGroup once set
-                      rule: '!has(oldSelf.resourceGroup) || has(self.resourceGroup)'
-                  type:
-                    description: "type is the underlying infrastructure provider for
-                      the cluster. This value controls whether infrastructure automation
-                      such as service load balancers, dynamic volume provisioning,
-                      machine creation and deletion, and other integrations are enabled.
-                      If None, no infrastructure automation is enabled. Allowed values
-                      are \"AWS\", \"Azure\", \"BareMetal\", \"GCP\", \"Libvirt\",
-                      \"OpenStack\", \"VSphere\", \"oVirt\", \"EquinixMetal\", \"PowerVS\",
-                      \"AlibabaCloud\", \"Nutanix\" and \"None\". Individual components
-                      may not support all platforms, and must handle unrecognized
-                      platforms as None if they do not support that platform. \n This
-                      value will be synced with to the `status.platform` and `status.platformStatus.type`.
-                      Currently this value cannot be changed once set."
-                    enum:
-                    - ""
-                    - AWS
-                    - Azure
-                    - BareMetal
-                    - GCP
-                    - Libvirt
-                    - OpenStack
-                    - None
-                    - VSphere
-                    - oVirt
-                    - IBMCloud
-                    - KubeVirt
-                    - EquinixMetal
-                    - PowerVS
-                    - AlibabaCloud
-                    - Nutanix
-                    - External
-                    type: string
-                  vsphere:
-                    description: VSphere contains settings specific to the VSphere
-                      infrastructure provider.
-                    properties:
-                      apiServerInternalIP:
-                        description: "apiServerInternalIP is an IP address to contact
-                          the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. It is the IP that the
-                          Infrastructure.status.apiServerInternalURI points to. It
-                          is the IP for a self-hosted load balancer in front of the
-                          API servers. \n Deprecated: Use APIServerInternalIPs instead."
-                        type: string
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IPs otherwise
-                          only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      ingressIP:
-                        description: "ingressIP is an external IP which routes to
-                          the default ingress controller. The IP is a suitable target
-                          of a wildcard DNS record used to resolve default route host
-                          names. \n Deprecated: Use IngressIPs instead."
-                        type: string
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IPs
-                          otherwise only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      loadBalancer:
-                        default:
-                          type: OpenShiftManagedDefault
-                        description: loadBalancer defines how the load balancer used
-                          by the cluster is configured.
-                        properties:
-                          type:
-                            default: OpenShiftManagedDefault
-                            description: type defines the type of load balancer used
-                              by the cluster on VSphere platform which can be a user-managed
-                              or openshift-managed load balancer that is to be used
-                              for the OpenShift API and Ingress endpoints. When set
-                              to OpenShiftManagedDefault the static pods in charge
-                              of API and Ingress traffic load-balancing defined in
-                              the machine config operator will be deployed. When set
-                              to UserManaged these static pods will not be deployed
-                              and it is expected that the load balancer is configured
-                              out of band by the deployer. When omitted, this means
-                              no opinion and the platform is left to choose a reasonable
-                              default. The default value is OpenShiftManagedDefault.
-                            enum:
-                            - OpenShiftManagedDefault
-                            - UserManaged
-                            type: string
-                            x-kubernetes-validations:
-                            - message: type is immutable once set
-                              rule: oldSelf == '' || self == oldSelf
-                        type: object
-                      machineNetworks:
-                        description: machineNetworks are IP networks used to connect
-                          all the OpenShift cluster nodes.
-                        items:
-                          description: CIDR is an IP address range in CIDR notation
-                            (for example, "10.0.0.0/8" or "fd00::/8").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[0-9]))$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))$)
-                          type: string
-                        maxItems: 32
-                        type: array
-                        x-kubernetes-list-type: set
-                      nodeDNSIP:
-                        description: nodeDNSIP is the IP address for the internal
-                          DNS used by the nodes. Unlike the one managed by the DNS
-                          operator, `NodeDNSIP` provides name resolution for the nodes
-                          themselves. There is no DNS-as-a-service for vSphere deployments.
-                          In order to minimize necessary changes to the datacenter
-                          DNS, a DNS service is hosted as a static pod to serve those
-                          hostnames to the nodes in the cluster.
-                        type: string
-                    type: object
-                type: object
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-CustomNoUpgrade.crd.yaml-patch b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-CustomNoUpgrade.crd.yaml-patch
deleted file mode 100644
index d127130a..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-CustomNoUpgrade.crd.yaml-patch
+++ /dev/null
@@ -1,24 +0,0 @@
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/vcenters/items/properties/server/anyOf
-  value:
-    - format: ipv4
-    - format: ipv6
-    - format: hostname
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/failureDomains/items/properties/server/anyOf
-  value:
-    - format: ipv4
-    - format: ipv6
-    - format: hostname
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/nodeNetworking/properties/external/properties/excludeNetworkSubnetCidr/items/format
-  value: cidr
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/nodeNetworking/properties/external/properties/networkSubnetCidr/items/format
-  value: cidr
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/nodeNetworking/properties/internal/properties/excludeNetworkSubnetCidr/items/format
-  value: cidr
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/nodeNetworking/properties/internal/properties/networkSubnetCidr/items/format
-  value: cidr
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-Default.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-Default.crd.yaml
deleted file mode 100644
index a3eb6efe..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-Default.crd.yaml
+++ /dev/null
@@ -1,1761 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    release.openshift.io/feature-set: Default
-  name: infrastructures.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: Infrastructure
-    listKind: InfrastructureList
-    plural: infrastructures
-    singular: infrastructure
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "Infrastructure holds cluster-wide information about Infrastructure.
-          \ The canonical name is `cluster` \n Compatibility level 1: Stable within
-          a major release for a minimum of 12 months or 3 minor releases (whichever
-          is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              cloudConfig:
-                description: "cloudConfig is a reference to a ConfigMap containing
-                  the cloud provider configuration file. This configuration file is
-                  used to configure the Kubernetes cloud provider integration when
-                  using the built-in cloud provider integration or the external cloud
-                  controller manager. The namespace for this config map is openshift-config.
-                  \n cloudConfig should only be consumed by the kube_cloud_config
-                  controller. The controller is responsible for using the user configuration
-                  in the spec for various platforms and combining that with the user
-                  provided ConfigMap in this field to create a stitched kube cloud
-                  config. The controller generates a ConfigMap `kube-cloud-config`
-                  in `openshift-config-managed` namespace with the kube cloud config
-                  is stored in `cloud.conf` key. All the clients are expected to use
-                  the generated ConfigMap only."
-                properties:
-                  key:
-                    description: Key allows pointing to a specific key/value inside
-                      of the configmap.  This is useful for logical file references.
-                    type: string
-                  name:
-                    type: string
-                type: object
-              platformSpec:
-                description: platformSpec holds desired information specific to the
-                  underlying infrastructure provider.
-                properties:
-                  alibabaCloud:
-                    description: AlibabaCloud contains settings specific to the Alibaba
-                      Cloud infrastructure provider.
-                    type: object
-                  aws:
-                    description: AWS contains settings specific to the Amazon Web
-                      Services infrastructure provider.
-                    properties:
-                      serviceEndpoints:
-                        description: serviceEndpoints list contains custom endpoints
-                          which will override default service endpoint of AWS Services.
-                          There must be only one ServiceEndpoint for a service.
-                        items:
-                          description: AWSServiceEndpoint store the configuration
-                            of a custom url to override existing defaults of AWS Services.
-                          properties:
-                            name:
-                              description: name is the name of the AWS service. The
-                                list of all the service names can be found at https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html
-                                This must be provided and cannot be empty.
-                              pattern: ^[a-z0-9-]+$
-                              type: string
-                            url:
-                              description: url is fully qualified URI with scheme
-                                https, that overrides the default generated endpoint
-                                for a client. This must be provided and cannot be
-                                empty.
-                              pattern: ^https://
-                              type: string
-                          type: object
-                        type: array
-                        x-kubernetes-list-type: atomic
-                    type: object
-                  azure:
-                    description: Azure contains settings specific to the Azure infrastructure
-                      provider.
-                    type: object
-                  baremetal:
-                    description: BareMetal contains settings specific to the BareMetal
-                      platform.
-                    properties:
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IP addresses,
-                          one from IPv4 family and one from IPv6. In single stack
-                          clusters a single IP address is expected. When omitted,
-                          values from the status.apiServerInternalIPs will be used.
-                          Once set, the list cannot be completely removed (but its
-                          second entry can).
-                        items:
-                          description: IP is an IP address (for example, "10.0.0.0"
-                            or "fd00::").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                        x-kubernetes-validations:
-                        - message: apiServerInternalIPs must contain at most one IPv4
-                            address and at most one IPv6 address
-                          rule: 'size(self) == 2 ? self.exists_one(x, x.contains('':''))
-                            : true'
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IP
-                          addresses, one from IPv4 family and one from IPv6. In single
-                          stack clusters a single IP address is expected. When omitted,
-                          values from the status.ingressIPs will be used. Once set,
-                          the list cannot be completely removed (but its second entry
-                          can).
-                        items:
-                          description: IP is an IP address (for example, "10.0.0.0"
-                            or "fd00::").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                        x-kubernetes-validations:
-                        - message: ingressIPs must contain at most one IPv4 address
-                            and at most one IPv6 address
-                          rule: 'size(self) == 2 ? self.exists_one(x, x.contains('':''))
-                            : true'
-                      machineNetworks:
-                        description: machineNetworks are IP networks used to connect
-                          all the OpenShift cluster nodes. Each network is provided
-                          in the CIDR format and should be IPv4 or IPv6, for example
-                          "10.0.0.0/8" or "fd00::/8".
-                        items:
-                          description: CIDR is an IP address range in CIDR notation
-                            (for example, "10.0.0.0/8" or "fd00::/8").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[0-9]))$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))$)
-                          type: string
-                        maxItems: 32
-                        type: array
-                        x-kubernetes-list-type: set
-                    type: object
-                    x-kubernetes-validations:
-                    - message: apiServerInternalIPs list is required once set
-                      rule: '!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)'
-                    - message: ingressIPs list is required once set
-                      rule: '!has(oldSelf.ingressIPs) || has(self.ingressIPs)'
-                  equinixMetal:
-                    description: EquinixMetal contains settings specific to the Equinix
-                      Metal infrastructure provider.
-                    type: object
-                  external:
-                    description: ExternalPlatformType represents generic infrastructure
-                      provider. Platform-specific components should be supplemented
-                      separately.
-                    properties:
-                      platformName:
-                        default: Unknown
-                        description: PlatformName holds the arbitrary string representing
-                          the infrastructure provider name, expected to be set at
-                          the installation time. This field is solely for informational
-                          and reporting purposes and is not expected to be used for
-                          decision-making.
-                        type: string
-                        x-kubernetes-validations:
-                        - message: platform name cannot be changed once set
-                          rule: oldSelf == 'Unknown' || self == oldSelf
-                    type: object
-                  gcp:
-                    description: GCP contains settings specific to the Google Cloud
-                      Platform infrastructure provider.
-                    type: object
-                  ibmcloud:
-                    description: IBMCloud contains settings specific to the IBMCloud
-                      infrastructure provider.
-                    type: object
-                  kubevirt:
-                    description: Kubevirt contains settings specific to the kubevirt
-                      infrastructure provider.
-                    type: object
-                  nutanix:
-                    description: Nutanix contains settings specific to the Nutanix
-                      infrastructure provider.
-                    properties:
-                      failureDomains:
-                        description: failureDomains configures failure domains information
-                          for the Nutanix platform. When set, the failure domains
-                          defined here may be used to spread Machines across prism
-                          element clusters to improve fault tolerance of the cluster.
-                        items:
-                          description: NutanixFailureDomain configures failure domain
-                            information for the Nutanix platform.
-                          properties:
-                            cluster:
-                              description: cluster is to identify the cluster (the
-                                Prism Element under management of the Prism Central),
-                                in which the Machine's VM will be created. The cluster
-                                identifier (uuid or name) can be obtained from the
-                                Prism Central console or using the prism_central API.
-                              properties:
-                                name:
-                                  description: name is the resource name in the PC.
-                                    It cannot be empty if the type is Name.
-                                  type: string
-                                type:
-                                  description: type is the identifier type to use
-                                    for this resource.
-                                  enum:
-                                  - UUID
-                                  - Name
-                                  type: string
-                                uuid:
-                                  description: uuid is the UUID of the resource in
-                                    the PC. It cannot be empty if the type is UUID.
-                                  type: string
-                              required:
-                              - type
-                              type: object
-                              x-kubernetes-validations:
-                              - message: uuid configuration is required when type
-                                  is UUID, and forbidden otherwise
-                                rule: 'has(self.type) && self.type == ''UUID'' ?  has(self.uuid)
-                                  : !has(self.uuid)'
-                              - message: name configuration is required when type
-                                  is Name, and forbidden otherwise
-                                rule: 'has(self.type) && self.type == ''Name'' ?  has(self.name)
-                                  : !has(self.name)'
-                            name:
-                              description: name defines the unique name of a failure
-                                domain. Name is required and must be at most 64 characters
-                                in length. It must consist of only lower case alphanumeric
-                                characters and hyphens (-). It must start and end
-                                with an alphanumeric character. This value is arbitrary
-                                and is used to identify the failure domain within
-                                the platform.
-                              maxLength: 64
-                              minLength: 1
-                              pattern: '[a-z0-9]([-a-z0-9]*[a-z0-9])?'
-                              type: string
-                            subnets:
-                              description: subnets holds a list of identifiers (one
-                                or more) of the cluster's network subnets for the
-                                Machine's VM to connect to. The subnet identifiers
-                                (uuid or name) can be obtained from the Prism Central
-                                console or using the prism_central API.
-                              items:
-                                description: NutanixResourceIdentifier holds the identity
-                                  of a Nutanix PC resource (cluster, image, subnet,
-                                  etc.)
-                                properties:
-                                  name:
-                                    description: name is the resource name in the
-                                      PC. It cannot be empty if the type is Name.
-                                    type: string
-                                  type:
-                                    description: type is the identifier type to use
-                                      for this resource.
-                                    enum:
-                                    - UUID
-                                    - Name
-                                    type: string
-                                  uuid:
-                                    description: uuid is the UUID of the resource
-                                      in the PC. It cannot be empty if the type is
-                                      UUID.
-                                    type: string
-                                required:
-                                - type
-                                type: object
-                                x-kubernetes-validations:
-                                - message: uuid configuration is required when type
-                                    is UUID, and forbidden otherwise
-                                  rule: 'has(self.type) && self.type == ''UUID'' ?  has(self.uuid)
-                                    : !has(self.uuid)'
-                                - message: name configuration is required when type
-                                    is Name, and forbidden otherwise
-                                  rule: 'has(self.type) && self.type == ''Name'' ?  has(self.name)
-                                    : !has(self.name)'
-                              maxItems: 1
-                              minItems: 1
-                              type: array
-                              x-kubernetes-list-map-keys:
-                              - type
-                              x-kubernetes-list-type: map
-                          required:
-                          - cluster
-                          - name
-                          - subnets
-                          type: object
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - name
-                        x-kubernetes-list-type: map
-                      prismCentral:
-                        description: prismCentral holds the endpoint address and port
-                          to access the Nutanix Prism Central. When a cluster-wide
-                          proxy is installed, by default, this endpoint will be accessed
-                          via the proxy. Should you wish for communication with this
-                          endpoint not to be proxied, please add the endpoint to the
-                          proxy spec.noProxy list.
-                        properties:
-                          address:
-                            description: address is the endpoint address (DNS name
-                              or IP address) of the Nutanix Prism Central or Element
-                              (cluster)
-                            maxLength: 256
-                            type: string
-                          port:
-                            description: port is the port number to access the Nutanix
-                              Prism Central or Element (cluster)
-                            format: int32
-                            maximum: 65535
-                            minimum: 1
-                            type: integer
-                        required:
-                        - address
-                        - port
-                        type: object
-                      prismElements:
-                        description: prismElements holds one or more endpoint address
-                          and port data to access the Nutanix Prism Elements (clusters)
-                          of the Nutanix Prism Central. Currently we only support
-                          one Prism Element (cluster) for an OpenShift cluster, where
-                          all the Nutanix resources (VMs, subnets, volumes, etc.)
-                          used in the OpenShift cluster are located. In the future,
-                          we may support Nutanix resources (VMs, etc.) spread over
-                          multiple Prism Elements (clusters) of the Prism Central.
-                        items:
-                          description: NutanixPrismElementEndpoint holds the name
-                            and endpoint data for a Prism Element (cluster)
-                          properties:
-                            endpoint:
-                              description: endpoint holds the endpoint address and
-                                port data of the Prism Element (cluster). When a cluster-wide
-                                proxy is installed, by default, this endpoint will
-                                be accessed via the proxy. Should you wish for communication
-                                with this endpoint not to be proxied, please add the
-                                endpoint to the proxy spec.noProxy list.
-                              properties:
-                                address:
-                                  description: address is the endpoint address (DNS
-                                    name or IP address) of the Nutanix Prism Central
-                                    or Element (cluster)
-                                  maxLength: 256
-                                  type: string
-                                port:
-                                  description: port is the port number to access the
-                                    Nutanix Prism Central or Element (cluster)
-                                  format: int32
-                                  maximum: 65535
-                                  minimum: 1
-                                  type: integer
-                              required:
-                              - address
-                              - port
-                              type: object
-                            name:
-                              description: name is the name of the Prism Element (cluster).
-                                This value will correspond with the cluster field
-                                configured on other resources (eg Machines, PVCs,
-                                etc).
-                              maxLength: 256
-                              type: string
-                          required:
-                          - endpoint
-                          - name
-                          type: object
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - name
-                        x-kubernetes-list-type: map
-                    required:
-                    - prismCentral
-                    - prismElements
-                    type: object
-                  openstack:
-                    description: OpenStack contains settings specific to the OpenStack
-                      infrastructure provider.
-                    properties:
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IP addresses,
-                          one from IPv4 family and one from IPv6. In single stack
-                          clusters a single IP address is expected. When omitted,
-                          values from the status.apiServerInternalIPs will be used.
-                          Once set, the list cannot be completely removed (but its
-                          second entry can).
-                        items:
-                          description: IP is an IP address (for example, "10.0.0.0"
-                            or "fd00::").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                        x-kubernetes-validations:
-                        - message: apiServerInternalIPs must contain at most one IPv4
-                            address and at most one IPv6 address
-                          rule: 'size(self) == 2 ? self.exists_one(x, x.contains('':''))
-                            : true'
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IP
-                          addresses, one from IPv4 family and one from IPv6. In single
-                          stack clusters a single IP address is expected. When omitted,
-                          values from the status.ingressIPs will be used. Once set,
-                          the list cannot be completely removed (but its second entry
-                          can).
-                        items:
-                          description: IP is an IP address (for example, "10.0.0.0"
-                            or "fd00::").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                        x-kubernetes-validations:
-                        - message: ingressIPs must contain at most one IPv4 address
-                            and at most one IPv6 address
-                          rule: 'size(self) == 2 ? self.exists_one(x, x.contains('':''))
-                            : true'
-                      machineNetworks:
-                        description: machineNetworks are IP networks used to connect
-                          all the OpenShift cluster nodes. Each network is provided
-                          in the CIDR format and should be IPv4 or IPv6, for example
-                          "10.0.0.0/8" or "fd00::/8".
-                        items:
-                          description: CIDR is an IP address range in CIDR notation
-                            (for example, "10.0.0.0/8" or "fd00::/8").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[0-9]))$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))$)
-                          type: string
-                        maxItems: 32
-                        type: array
-                        x-kubernetes-list-type: set
-                    type: object
-                    x-kubernetes-validations:
-                    - message: apiServerInternalIPs list is required once set
-                      rule: '!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)'
-                    - message: ingressIPs list is required once set
-                      rule: '!has(oldSelf.ingressIPs) || has(self.ingressIPs)'
-                  ovirt:
-                    description: Ovirt contains settings specific to the oVirt infrastructure
-                      provider.
-                    type: object
-                  powervs:
-                    description: PowerVS contains settings specific to the IBM Power
-                      Systems Virtual Servers infrastructure provider.
-                    properties:
-                      serviceEndpoints:
-                        description: serviceEndpoints is a list of custom endpoints
-                          which will override the default service endpoints of a Power
-                          VS service.
-                        items:
-                          description: PowervsServiceEndpoint stores the configuration
-                            of a custom url to override existing defaults of PowerVS
-                            Services.
-                          properties:
-                            name:
-                              description: name is the name of the Power VS service.
-                                Few of the services are IAM - https://cloud.ibm.com/apidocs/iam-identity-token-api
-                                ResourceController - https://cloud.ibm.com/apidocs/resource-controller/resource-controller
-                                Power Cloud - https://cloud.ibm.com/apidocs/power-cloud
-                              pattern: ^[a-z0-9-]+$
-                              type: string
-                            url:
-                              description: url is fully qualified URI with scheme
-                                https, that overrides the default generated endpoint
-                                for a client. This must be provided and cannot be
-                                empty.
-                              format: uri
-                              pattern: ^https://
-                              type: string
-                          required:
-                          - name
-                          - url
-                          type: object
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - name
-                        x-kubernetes-list-type: map
-                    type: object
-                  type:
-                    description: type is the underlying infrastructure provider for
-                      the cluster. This value controls whether infrastructure automation
-                      such as service load balancers, dynamic volume provisioning,
-                      machine creation and deletion, and other integrations are enabled.
-                      If None, no infrastructure automation is enabled. Allowed values
-                      are "AWS", "Azure", "BareMetal", "GCP", "Libvirt", "OpenStack",
-                      "VSphere", "oVirt", "KubeVirt", "EquinixMetal", "PowerVS", "AlibabaCloud",
-                      "Nutanix" and "None". Individual components may not support
-                      all platforms, and must handle unrecognized platforms as None
-                      if they do not support that platform.
-                    enum:
-                    - ""
-                    - AWS
-                    - Azure
-                    - BareMetal
-                    - GCP
-                    - Libvirt
-                    - OpenStack
-                    - None
-                    - VSphere
-                    - oVirt
-                    - IBMCloud
-                    - KubeVirt
-                    - EquinixMetal
-                    - PowerVS
-                    - AlibabaCloud
-                    - Nutanix
-                    - External
-                    type: string
-                  vsphere:
-                    description: VSphere contains settings specific to the VSphere
-                      infrastructure provider.
-                    properties:
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IP addresses,
-                          one from IPv4 family and one from IPv6. In single stack
-                          clusters a single IP address is expected. When omitted,
-                          values from the status.apiServerInternalIPs will be used.
-                          Once set, the list cannot be completely removed (but its
-                          second entry can).
-                        items:
-                          description: IP is an IP address (for example, "10.0.0.0"
-                            or "fd00::").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                        x-kubernetes-validations:
-                        - message: apiServerInternalIPs must contain at most one IPv4
-                            address and at most one IPv6 address
-                          rule: 'size(self) == 2 ? self.exists_one(x, x.contains('':''))
-                            : true'
-                      failureDomains:
-                        description: failureDomains contains the definition of region,
-                          zone and the vCenter topology. If this is omitted failure
-                          domains (regions and zones) will not be used.
-                        items:
-                          description: VSpherePlatformFailureDomainSpec holds the
-                            region and zone failure domain and the vCenter topology
-                            of that failure domain.
-                          properties:
-                            name:
-                              description: name defines the arbitrary but unique name
-                                of a failure domain.
-                              maxLength: 256
-                              minLength: 1
-                              type: string
-                            region:
-                              description: region defines the name of a region tag
-                                that will be attached to a vCenter datacenter. The
-                                tag category in vCenter must be named openshift-region.
-                              maxLength: 80
-                              minLength: 1
-                              type: string
-                            server:
-                              anyOf:
-                              - format: ipv4
-                              - format: ipv6
-                              - format: hostname
-                              description: server is the fully-qualified domain name
-                                or the IP address of the vCenter server. ---
-                              maxLength: 255
-                              minLength: 1
-                              type: string
-                            topology:
-                              description: Topology describes a given failure domain
-                                using vSphere constructs
-                              properties:
-                                computeCluster:
-                                  description: computeCluster the absolute path of
-                                    the vCenter cluster in which virtual machine will
-                                    be located. The absolute path is of the form /<datacenter>/host/<cluster>.
-                                    The maximum length of the path is 2048 characters.
-                                  maxLength: 2048
-                                  pattern: ^/.*?/host/.*?
-                                  type: string
-                                datacenter:
-                                  description: datacenter is the name of vCenter datacenter
-                                    in which virtual machines will be located. The
-                                    maximum length of the datacenter name is 80 characters.
-                                  maxLength: 80
-                                  type: string
-                                datastore:
-                                  description: datastore is the absolute path of the
-                                    datastore in which the virtual machine is located.
-                                    The absolute path is of the form /<datacenter>/datastore/<datastore>
-                                    The maximum length of the path is 2048 characters.
-                                  maxLength: 2048
-                                  pattern: ^/.*?/datastore/.*?
-                                  type: string
-                                folder:
-                                  description: folder is the absolute path of the
-                                    folder where virtual machines are located. The
-                                    absolute path is of the form /<datacenter>/vm/<folder>.
-                                    The maximum length of the path is 2048 characters.
-                                  maxLength: 2048
-                                  pattern: ^/.*?/vm/.*?
-                                  type: string
-                                networks:
-                                  description: networks is the list of port group
-                                    network names within this failure domain. Currently,
-                                    we only support a single interface per RHCOS virtual
-                                    machine. The available networks (port groups)
-                                    can be listed using `govc ls 'network/*'` The
-                                    single interface should be the absolute path of
-                                    the form /<datacenter>/network/<portgroup>.
-                                  items:
-                                    type: string
-                                  maxItems: 1
-                                  minItems: 1
-                                  type: array
-                                  x-kubernetes-list-type: atomic
-                                resourcePool:
-                                  description: resourcePool is the absolute path of
-                                    the resource pool where virtual machines will
-                                    be created. The absolute path is of the form /<datacenter>/host/<cluster>/Resources/<resourcepool>.
-                                    The maximum length of the path is 2048 characters.
-                                  maxLength: 2048
-                                  pattern: ^/.*?/host/.*?/Resources.*
-                                  type: string
-                                template:
-                                  description: "template is the full inventory path
-                                    of the virtual machine or template that will be
-                                    cloned when creating new machines in this failure
-                                    domain. The maximum length of the path is 2048
-                                    characters. \n When omitted, the template will
-                                    be calculated by the control plane machineset
-                                    operator based on the region and zone defined
-                                    in VSpherePlatformFailureDomainSpec. For example,
-                                    for zone=zonea, region=region1, and infrastructure
-                                    name=test, the template path would be calculated
-                                    as /<datacenter>/vm/test-rhcos-region1-zonea."
-                                  maxLength: 2048
-                                  minLength: 1
-                                  pattern: ^/.*?/vm/.*?
-                                  type: string
-                              required:
-                              - computeCluster
-                              - datacenter
-                              - datastore
-                              - networks
-                              type: object
-                            zone:
-                              description: zone defines the name of a zone tag that
-                                will be attached to a vCenter cluster. The tag category
-                                in vCenter must be named openshift-zone.
-                              maxLength: 80
-                              minLength: 1
-                              type: string
-                          required:
-                          - name
-                          - region
-                          - server
-                          - topology
-                          - zone
-                          type: object
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - name
-                        x-kubernetes-list-type: map
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IP
-                          addresses, one from IPv4 family and one from IPv6. In single
-                          stack clusters a single IP address is expected. When omitted,
-                          values from the status.ingressIPs will be used. Once set,
-                          the list cannot be completely removed (but its second entry
-                          can).
-                        items:
-                          description: IP is an IP address (for example, "10.0.0.0"
-                            or "fd00::").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                        x-kubernetes-validations:
-                        - message: ingressIPs must contain at most one IPv4 address
-                            and at most one IPv6 address
-                          rule: 'size(self) == 2 ? self.exists_one(x, x.contains('':''))
-                            : true'
-                      machineNetworks:
-                        description: machineNetworks are IP networks used to connect
-                          all the OpenShift cluster nodes. Each network is provided
-                          in the CIDR format and should be IPv4 or IPv6, for example
-                          "10.0.0.0/8" or "fd00::/8".
-                        items:
-                          description: CIDR is an IP address range in CIDR notation
-                            (for example, "10.0.0.0/8" or "fd00::/8").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[0-9]))$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))$)
-                          type: string
-                        maxItems: 32
-                        type: array
-                        x-kubernetes-list-type: set
-                      nodeNetworking:
-                        description: nodeNetworking contains the definition of internal
-                          and external network constraints for assigning the node's
-                          networking. If this field is omitted, networking defaults
-                          to the legacy address selection behavior which is to only
-                          support a single address and return the first one found.
-                        properties:
-                          external:
-                            description: external represents the network configuration
-                              of the node that is externally routable.
-                            properties:
-                              excludeNetworkSubnetCidr:
-                                description: excludeNetworkSubnetCidr IP addresses
-                                  in subnet ranges will be excluded when selecting
-                                  the IP address from the VirtualMachine's VM for
-                                  use in the status.addresses fields. ---
-                                items:
-                                  format: cidr
-                                  type: string
-                                type: array
-                                x-kubernetes-list-type: atomic
-                              network:
-                                description: network VirtualMachine's VM Network names
-                                  that will be used to when searching for status.addresses
-                                  fields. Note that if internal.networkSubnetCIDR
-                                  and external.networkSubnetCIDR are not set, then
-                                  the vNIC associated to this network must only have
-                                  a single IP address assigned to it. The available
-                                  networks (port groups) can be listed using `govc
-                                  ls 'network/*'`
-                                type: string
-                              networkSubnetCidr:
-                                description: networkSubnetCidr IP address on VirtualMachine's
-                                  network interfaces included in the fields' CIDRs
-                                  that will be used in respective status.addresses
-                                  fields. ---
-                                items:
-                                  format: cidr
-                                  type: string
-                                type: array
-                                x-kubernetes-list-type: set
-                            type: object
-                          internal:
-                            description: internal represents the network configuration
-                              of the node that is routable only within the cluster.
-                            properties:
-                              excludeNetworkSubnetCidr:
-                                description: excludeNetworkSubnetCidr IP addresses
-                                  in subnet ranges will be excluded when selecting
-                                  the IP address from the VirtualMachine's VM for
-                                  use in the status.addresses fields. ---
-                                items:
-                                  format: cidr
-                                  type: string
-                                type: array
-                                x-kubernetes-list-type: atomic
-                              network:
-                                description: network VirtualMachine's VM Network names
-                                  that will be used to when searching for status.addresses
-                                  fields. Note that if internal.networkSubnetCIDR
-                                  and external.networkSubnetCIDR are not set, then
-                                  the vNIC associated to this network must only have
-                                  a single IP address assigned to it. The available
-                                  networks (port groups) can be listed using `govc
-                                  ls 'network/*'`
-                                type: string
-                              networkSubnetCidr:
-                                description: networkSubnetCidr IP address on VirtualMachine's
-                                  network interfaces included in the fields' CIDRs
-                                  that will be used in respective status.addresses
-                                  fields. ---
-                                items:
-                                  format: cidr
-                                  type: string
-                                type: array
-                                x-kubernetes-list-type: set
-                            type: object
-                        type: object
-                      vcenters:
-                        description: vcenters holds the connection details for services
-                          to communicate with vCenter. Currently, only a single vCenter
-                          is supported. ---
-                        items:
-                          description: VSpherePlatformVCenterSpec stores the vCenter
-                            connection fields. This is used by the vSphere CCM.
-                          properties:
-                            datacenters:
-                              description: The vCenter Datacenters in which the RHCOS
-                                vm guests are located. This field will be used by
-                                the Cloud Controller Manager. Each datacenter listed
-                                here should be used within a topology.
-                              items:
-                                type: string
-                              minItems: 1
-                              type: array
-                              x-kubernetes-list-type: set
-                            port:
-                              description: port is the TCP port that will be used
-                                to communicate to the vCenter endpoint. When omitted,
-                                this means the user has no opinion and it is up to
-                                the platform to choose a sensible default, which is
-                                subject to change over time.
-                              format: int32
-                              maximum: 32767
-                              minimum: 1
-                              type: integer
-                            server:
-                              anyOf:
-                              - format: ipv4
-                              - format: ipv6
-                              - format: hostname
-                              description: server is the fully-qualified domain name
-                                or the IP address of the vCenter server. ---
-                              maxLength: 255
-                              type: string
-                          required:
-                          - datacenters
-                          - server
-                          type: object
-                        maxItems: 1
-                        minItems: 0
-                        type: array
-                        x-kubernetes-list-type: atomic
-                    type: object
-                    x-kubernetes-validations:
-                    - message: apiServerInternalIPs list is required once set
-                      rule: '!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)'
-                    - message: ingressIPs list is required once set
-                      rule: '!has(oldSelf.ingressIPs) || has(self.ingressIPs)'
-                type: object
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            properties:
-              apiServerInternalURI:
-                description: apiServerInternalURL is a valid URI with scheme 'https',
-                  address and optionally a port (defaulting to 443).  apiServerInternalURL
-                  can be used by components like kubelets, to contact the Kubernetes
-                  API server using the infrastructure provider rather than Kubernetes
-                  networking.
-                type: string
-              apiServerURL:
-                description: apiServerURL is a valid URI with scheme 'https', address
-                  and optionally a port (defaulting to 443).  apiServerURL can be
-                  used by components like the web console to tell users where to find
-                  the Kubernetes API.
-                type: string
-              controlPlaneTopology:
-                default: HighlyAvailable
-                description: controlPlaneTopology expresses the expectations for operands
-                  that normally run on control nodes. The default is 'HighlyAvailable',
-                  which represents the behavior operators have in a "normal" cluster.
-                  The 'SingleReplica' mode will be used in single-node deployments
-                  and the operators should not configure the operand for highly-available
-                  operation The 'External' mode indicates that the control plane is
-                  hosted externally to the cluster and that its components are not
-                  visible within the cluster.
-                enum:
-                - HighlyAvailable
-                - SingleReplica
-                - External
-                type: string
-              cpuPartitioning:
-                default: None
-                description: cpuPartitioning expresses if CPU partitioning is a currently
-                  enabled feature in the cluster. CPU Partitioning means that this
-                  cluster can support partitioning workloads to specific CPU Sets.
-                  Valid values are "None" and "AllNodes". When omitted, the default
-                  value is "None". The default value of "None" indicates that no nodes
-                  will be setup with CPU partitioning. The "AllNodes" value indicates
-                  that all nodes have been setup with CPU partitioning, and can then
-                  be further configured via the PerformanceProfile API.
-                enum:
-                - None
-                - AllNodes
-                type: string
-              etcdDiscoveryDomain:
-                description: 'etcdDiscoveryDomain is the domain used to fetch the
-                  SRV records for discovering etcd servers and clients. For more info:
-                  https://github.com/etcd-io/etcd/blob/329be66e8b3f9e2e6af83c123ff89297e49ebd15/Documentation/op-guide/clustering.md#dns-discovery
-                  deprecated: as of 4.7, this field is no longer set or honored.  It
-                  will be removed in a future release.'
-                type: string
-              infrastructureName:
-                description: infrastructureName uniquely identifies a cluster with
-                  a human friendly name. Once set it should not be changed. Must be
-                  of max length 27 and must have only alphanumeric or hyphen characters.
-                type: string
-              infrastructureTopology:
-                default: HighlyAvailable
-                description: 'infrastructureTopology expresses the expectations for
-                  infrastructure services that do not run on control plane nodes,
-                  usually indicated by a node selector for a `role` value other than
-                  `master`. The default is ''HighlyAvailable'', which represents the
-                  behavior operators have in a "normal" cluster. The ''SingleReplica''
-                  mode will be used in single-node deployments and the operators should
-                  not configure the operand for highly-available operation NOTE: External
-                  topology mode is not applicable for this field.'
-                enum:
-                - HighlyAvailable
-                - SingleReplica
-                type: string
-              platform:
-                description: "platform is the underlying infrastructure provider for
-                  the cluster. \n Deprecated: Use platformStatus.type instead."
-                enum:
-                - ""
-                - AWS
-                - Azure
-                - BareMetal
-                - GCP
-                - Libvirt
-                - OpenStack
-                - None
-                - VSphere
-                - oVirt
-                - IBMCloud
-                - KubeVirt
-                - EquinixMetal
-                - PowerVS
-                - AlibabaCloud
-                - Nutanix
-                - External
-                type: string
-              platformStatus:
-                description: platformStatus holds status information specific to the
-                  underlying infrastructure provider.
-                properties:
-                  alibabaCloud:
-                    description: AlibabaCloud contains settings specific to the Alibaba
-                      Cloud infrastructure provider.
-                    properties:
-                      region:
-                        description: region specifies the region for Alibaba Cloud
-                          resources created for the cluster.
-                        pattern: ^[0-9A-Za-z-]+$
-                        type: string
-                      resourceGroupID:
-                        description: resourceGroupID is the ID of the resource group
-                          for the cluster.
-                        pattern: ^(rg-[0-9A-Za-z]+)?$
-                        type: string
-                      resourceTags:
-                        description: resourceTags is a list of additional tags to
-                          apply to Alibaba Cloud resources created for the cluster.
-                        items:
-                          description: AlibabaCloudResourceTag is the set of tags
-                            to add to apply to resources.
-                          properties:
-                            key:
-                              description: key is the key of the tag.
-                              maxLength: 128
-                              minLength: 1
-                              type: string
-                            value:
-                              description: value is the value of the tag.
-                              maxLength: 128
-                              minLength: 1
-                              type: string
-                          required:
-                          - key
-                          - value
-                          type: object
-                        maxItems: 20
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - key
-                        x-kubernetes-list-type: map
-                    required:
-                    - region
-                    type: object
-                  aws:
-                    description: AWS contains settings specific to the Amazon Web
-                      Services infrastructure provider.
-                    properties:
-                      region:
-                        description: region holds the default AWS region for new AWS
-                          resources created by the cluster.
-                        type: string
-                      resourceTags:
-                        description: resourceTags is a list of additional tags to
-                          apply to AWS resources created for the cluster. See https://docs.aws.amazon.com/general/latest/gr/aws_tagging.html
-                          for information on tagging AWS resources. AWS supports a
-                          maximum of 50 tags per resource. OpenShift reserves 25 tags
-                          for its use, leaving 25 tags available for the user.
-                        items:
-                          description: AWSResourceTag is a tag to apply to AWS resources
-                            created for the cluster.
-                          properties:
-                            key:
-                              description: key is the key of the tag
-                              maxLength: 128
-                              minLength: 1
-                              pattern: ^[0-9A-Za-z_.:/=+-@]+$
-                              type: string
-                            value:
-                              description: value is the value of the tag. Some AWS
-                                service do not support empty values. Since tags are
-                                added to resources in many services, the length of
-                                the tag value must meet the requirements of all services.
-                              maxLength: 256
-                              minLength: 1
-                              pattern: ^[0-9A-Za-z_.:/=+-@]+$
-                              type: string
-                          required:
-                          - key
-                          - value
-                          type: object
-                        maxItems: 25
-                        type: array
-                        x-kubernetes-list-type: atomic
-                      serviceEndpoints:
-                        description: ServiceEndpoints list contains custom endpoints
-                          which will override default service endpoint of AWS Services.
-                          There must be only one ServiceEndpoint for a service.
-                        items:
-                          description: AWSServiceEndpoint store the configuration
-                            of a custom url to override existing defaults of AWS Services.
-                          properties:
-                            name:
-                              description: name is the name of the AWS service. The
-                                list of all the service names can be found at https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html
-                                This must be provided and cannot be empty.
-                              pattern: ^[a-z0-9-]+$
-                              type: string
-                            url:
-                              description: url is fully qualified URI with scheme
-                                https, that overrides the default generated endpoint
-                                for a client. This must be provided and cannot be
-                                empty.
-                              pattern: ^https://
-                              type: string
-                          type: object
-                        type: array
-                        x-kubernetes-list-type: atomic
-                    type: object
-                  azure:
-                    description: Azure contains settings specific to the Azure infrastructure
-                      provider.
-                    properties:
-                      armEndpoint:
-                        description: armEndpoint specifies a URL to use for resource
-                          management in non-soverign clouds such as Azure Stack.
-                        type: string
-                      cloudName:
-                        description: cloudName is the name of the Azure cloud environment
-                          which can be used to configure the Azure SDK with the appropriate
-                          Azure API endpoints. If empty, the value is equal to `AzurePublicCloud`.
-                        enum:
-                        - ""
-                        - AzurePublicCloud
-                        - AzureUSGovernmentCloud
-                        - AzureChinaCloud
-                        - AzureGermanCloud
-                        - AzureStackCloud
-                        type: string
-                      networkResourceGroupName:
-                        description: networkResourceGroupName is the Resource Group
-                          for network resources like the Virtual Network and Subnets
-                          used by the cluster. If empty, the value is same as ResourceGroupName.
-                        type: string
-                      resourceGroupName:
-                        description: resourceGroupName is the Resource Group for new
-                          Azure resources created for the cluster.
-                        type: string
-                      resourceTags:
-                        description: resourceTags is a list of additional tags to
-                          apply to Azure resources created for the cluster. See https://docs.microsoft.com/en-us/rest/api/resources/tags
-                          for information on tagging Azure resources. Due to limitations
-                          on Automation, Content Delivery Network, DNS Azure resources,
-                          a maximum of 15 tags may be applied. OpenShift reserves
-                          5 tags for internal use, allowing 10 tags for user configuration.
-                        items:
-                          description: AzureResourceTag is a tag to apply to Azure
-                            resources created for the cluster.
-                          properties:
-                            key:
-                              description: key is the key part of the tag. A tag key
-                                can have a maximum of 128 characters and cannot be
-                                empty. Key must begin with a letter, end with a letter,
-                                number or underscore, and must contain only alphanumeric
-                                characters and the following special characters `_
-                                . -`.
-                              maxLength: 128
-                              minLength: 1
-                              pattern: ^[a-zA-Z]([0-9A-Za-z_.-]*[0-9A-Za-z_])?$
-                              type: string
-                            value:
-                              description: 'value is the value part of the tag. A
-                                tag value can have a maximum of 256 characters and
-                                cannot be empty. Value must contain only alphanumeric
-                                characters and the following special characters `_
-                                + , - . / : ; < = > ? @`.'
-                              maxLength: 256
-                              minLength: 1
-                              pattern: ^[0-9A-Za-z_.=+-@]+$
-                              type: string
-                          required:
-                          - key
-                          - value
-                          type: object
-                        maxItems: 10
-                        type: array
-                        x-kubernetes-list-type: atomic
-                        x-kubernetes-validations:
-                        - message: resourceTags are immutable and may only be configured
-                            during installation
-                          rule: self.all(x, x in oldSelf) && oldSelf.all(x, x in self)
-                    type: object
-                    x-kubernetes-validations:
-                    - message: resourceTags may only be configured during installation
-                      rule: '!has(oldSelf.resourceTags) && !has(self.resourceTags)
-                        || has(oldSelf.resourceTags) && has(self.resourceTags)'
-                  baremetal:
-                    description: BareMetal contains settings specific to the BareMetal
-                      platform.
-                    properties:
-                      apiServerInternalIP:
-                        description: "apiServerInternalIP is an IP address to contact
-                          the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. It is the IP that the
-                          Infrastructure.status.apiServerInternalURI points to. It
-                          is the IP for a self-hosted load balancer in front of the
-                          API servers. \n Deprecated: Use APIServerInternalIPs instead."
-                        type: string
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IPs otherwise
-                          only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      ingressIP:
-                        description: "ingressIP is an external IP which routes to
-                          the default ingress controller. The IP is a suitable target
-                          of a wildcard DNS record used to resolve default route host
-                          names. \n Deprecated: Use IngressIPs instead."
-                        type: string
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IPs
-                          otherwise only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      machineNetworks:
-                        description: machineNetworks are IP networks used to connect
-                          all the OpenShift cluster nodes.
-                        items:
-                          description: CIDR is an IP address range in CIDR notation
-                            (for example, "10.0.0.0/8" or "fd00::/8").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[0-9]))$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))$)
-                          type: string
-                        maxItems: 32
-                        type: array
-                        x-kubernetes-list-type: set
-                      nodeDNSIP:
-                        description: nodeDNSIP is the IP address for the internal
-                          DNS used by the nodes. Unlike the one managed by the DNS
-                          operator, `NodeDNSIP` provides name resolution for the nodes
-                          themselves. There is no DNS-as-a-service for BareMetal deployments.
-                          In order to minimize necessary changes to the datacenter
-                          DNS, a DNS service is hosted as a static pod to serve those
-                          hostnames to the nodes in the cluster.
-                        type: string
-                    type: object
-                  equinixMetal:
-                    description: EquinixMetal contains settings specific to the Equinix
-                      Metal infrastructure provider.
-                    properties:
-                      apiServerInternalIP:
-                        description: apiServerInternalIP is an IP address to contact
-                          the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. It is the IP that the
-                          Infrastructure.status.apiServerInternalURI points to. It
-                          is the IP for a self-hosted load balancer in front of the
-                          API servers.
-                        type: string
-                      ingressIP:
-                        description: ingressIP is an external IP which routes to the
-                          default ingress controller. The IP is a suitable target
-                          of a wildcard DNS record used to resolve default route host
-                          names.
-                        type: string
-                    type: object
-                  external:
-                    description: External contains settings specific to the generic
-                      External infrastructure provider.
-                    properties:
-                      cloudControllerManager:
-                        description: cloudControllerManager contains settings specific
-                          to the external Cloud Controller Manager (a.k.a. CCM or
-                          CPI). When omitted, new nodes will be not tainted and no
-                          extra initialization from the cloud controller manager is
-                          expected.
-                        properties:
-                          state:
-                            description: "state determines whether or not an external
-                              Cloud Controller Manager is expected to be installed
-                              within the cluster. https://kubernetes.io/docs/tasks/administer-cluster/running-cloud-controller/#running-cloud-controller-manager
-                              \n Valid values are \"External\", \"None\" and omitted.
-                              When set to \"External\", new nodes will be tainted
-                              as uninitialized when created, preventing them from
-                              running workloads until they are initialized by the
-                              cloud controller manager. When omitted or set to \"None\",
-                              new nodes will be not tainted and no extra initialization
-                              from the cloud controller manager is expected."
-                            enum:
-                            - ""
-                            - External
-                            - None
-                            type: string
-                            x-kubernetes-validations:
-                            - message: state is immutable once set
-                              rule: self == oldSelf
-                        type: object
-                        x-kubernetes-validations:
-                        - message: state may not be added or removed once set
-                          rule: (has(self.state) == has(oldSelf.state)) || (!has(oldSelf.state)
-                            && self.state != "External")
-                    type: object
-                    x-kubernetes-validations:
-                    - message: cloudControllerManager may not be added or removed
-                        once set
-                      rule: has(self.cloudControllerManager) == has(oldSelf.cloudControllerManager)
-                  gcp:
-                    description: GCP contains settings specific to the Google Cloud
-                      Platform infrastructure provider.
-                    properties:
-                      projectID:
-                        description: resourceGroupName is the Project ID for new GCP
-                          resources created for the cluster.
-                        type: string
-                      region:
-                        description: region holds the region for new GCP resources
-                          created for the cluster.
-                        type: string
-                    type: object
-                  ibmcloud:
-                    description: IBMCloud contains settings specific to the IBMCloud
-                      infrastructure provider.
-                    properties:
-                      cisInstanceCRN:
-                        description: CISInstanceCRN is the CRN of the Cloud Internet
-                          Services instance managing the DNS zone for the cluster's
-                          base domain
-                        type: string
-                      dnsInstanceCRN:
-                        description: DNSInstanceCRN is the CRN of the DNS Services
-                          instance managing the DNS zone for the cluster's base domain
-                        type: string
-                      location:
-                        description: Location is where the cluster has been deployed
-                        type: string
-                      providerType:
-                        description: ProviderType indicates the type of cluster that
-                          was created
-                        type: string
-                      resourceGroupName:
-                        description: ResourceGroupName is the Resource Group for new
-                          IBMCloud resources created for the cluster.
-                        type: string
-                      serviceEndpoints:
-                        description: serviceEndpoints is a list of custom endpoints
-                          which will override the default service endpoints of an
-                          IBM Cloud service. These endpoints are consumed by components
-                          within the cluster to reach the respective IBM Cloud Services.
-                        items:
-                          description: IBMCloudServiceEndpoint stores the configuration
-                            of a custom url to override existing defaults of IBM Cloud
-                            Services.
-                          properties:
-                            name:
-                              description: 'name is the name of the IBM Cloud service.
-                                Possible values are: CIS, COS, DNSServices, GlobalSearch,
-                                GlobalTagging, HyperProtect, IAM, KeyProtect, ResourceController,
-                                ResourceManager, or VPC. For example, the IBM Cloud
-                                Private IAM service could be configured with the service
-                                `name` of `IAM` and `url` of `https://private.iam.cloud.ibm.com`
-                                Whereas the IBM Cloud Private VPC service for US South
-                                (Dallas) could be configured with the service `name`
-                                of `VPC` and `url` of `https://us.south.private.iaas.cloud.ibm.com`'
-                              enum:
-                              - CIS
-                              - COS
-                              - DNSServices
-                              - GlobalSearch
-                              - GlobalTagging
-                              - HyperProtect
-                              - IAM
-                              - KeyProtect
-                              - ResourceController
-                              - ResourceManager
-                              - VPC
-                              type: string
-                            url:
-                              description: url is fully qualified URI with scheme
-                                https, that overrides the default generated endpoint
-                                for a client. This must be provided and cannot be
-                                empty.
-                              type: string
-                              x-kubernetes-validations:
-                              - message: url must be a valid absolute URL
-                                rule: isURL(self)
-                          required:
-                          - name
-                          - url
-                          type: object
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - name
-                        x-kubernetes-list-type: map
-                    type: object
-                  kubevirt:
-                    description: Kubevirt contains settings specific to the kubevirt
-                      infrastructure provider.
-                    properties:
-                      apiServerInternalIP:
-                        description: apiServerInternalIP is an IP address to contact
-                          the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. It is the IP that the
-                          Infrastructure.status.apiServerInternalURI points to. It
-                          is the IP for a self-hosted load balancer in front of the
-                          API servers.
-                        type: string
-                      ingressIP:
-                        description: ingressIP is an external IP which routes to the
-                          default ingress controller. The IP is a suitable target
-                          of a wildcard DNS record used to resolve default route host
-                          names.
-                        type: string
-                    type: object
-                  nutanix:
-                    description: Nutanix contains settings specific to the Nutanix
-                      infrastructure provider.
-                    properties:
-                      apiServerInternalIP:
-                        description: "apiServerInternalIP is an IP address to contact
-                          the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. It is the IP that the
-                          Infrastructure.status.apiServerInternalURI points to. It
-                          is the IP for a self-hosted load balancer in front of the
-                          API servers. \n Deprecated: Use APIServerInternalIPs instead."
-                        type: string
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IPs otherwise
-                          only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      ingressIP:
-                        description: "ingressIP is an external IP which routes to
-                          the default ingress controller. The IP is a suitable target
-                          of a wildcard DNS record used to resolve default route host
-                          names. \n Deprecated: Use IngressIPs instead."
-                        type: string
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IPs
-                          otherwise only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                    type: object
-                  openstack:
-                    description: OpenStack contains settings specific to the OpenStack
-                      infrastructure provider.
-                    properties:
-                      apiServerInternalIP:
-                        description: "apiServerInternalIP is an IP address to contact
-                          the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. It is the IP that the
-                          Infrastructure.status.apiServerInternalURI points to. It
-                          is the IP for a self-hosted load balancer in front of the
-                          API servers. \n Deprecated: Use APIServerInternalIPs instead."
-                        type: string
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IPs otherwise
-                          only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      cloudName:
-                        description: cloudName is the name of the desired OpenStack
-                          cloud in the client configuration file (`clouds.yaml`).
-                        type: string
-                      ingressIP:
-                        description: "ingressIP is an external IP which routes to
-                          the default ingress controller. The IP is a suitable target
-                          of a wildcard DNS record used to resolve default route host
-                          names. \n Deprecated: Use IngressIPs instead."
-                        type: string
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IPs
-                          otherwise only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      loadBalancer:
-                        default:
-                          type: OpenShiftManagedDefault
-                        description: loadBalancer defines how the load balancer used
-                          by the cluster is configured.
-                        properties:
-                          type:
-                            default: OpenShiftManagedDefault
-                            description: type defines the type of load balancer used
-                              by the cluster on OpenStack platform which can be a
-                              user-managed or openshift-managed load balancer that
-                              is to be used for the OpenShift API and Ingress endpoints.
-                              When set to OpenShiftManagedDefault the static pods
-                              in charge of API and Ingress traffic load-balancing
-                              defined in the machine config operator will be deployed.
-                              When set to UserManaged these static pods will not be
-                              deployed and it is expected that the load balancer is
-                              configured out of band by the deployer. When omitted,
-                              this means no opinion and the platform is left to choose
-                              a reasonable default. The default value is OpenShiftManagedDefault.
-                            enum:
-                            - OpenShiftManagedDefault
-                            - UserManaged
-                            type: string
-                            x-kubernetes-validations:
-                            - message: type is immutable once set
-                              rule: oldSelf == '' || self == oldSelf
-                        type: object
-                      machineNetworks:
-                        description: machineNetworks are IP networks used to connect
-                          all the OpenShift cluster nodes.
-                        items:
-                          description: CIDR is an IP address range in CIDR notation
-                            (for example, "10.0.0.0/8" or "fd00::/8").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[0-9]))$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))$)
-                          type: string
-                        maxItems: 32
-                        type: array
-                        x-kubernetes-list-type: set
-                      nodeDNSIP:
-                        description: nodeDNSIP is the IP address for the internal
-                          DNS used by the nodes. Unlike the one managed by the DNS
-                          operator, `NodeDNSIP` provides name resolution for the nodes
-                          themselves. There is no DNS-as-a-service for OpenStack deployments.
-                          In order to minimize necessary changes to the datacenter
-                          DNS, a DNS service is hosted as a static pod to serve those
-                          hostnames to the nodes in the cluster.
-                        type: string
-                    type: object
-                  ovirt:
-                    description: Ovirt contains settings specific to the oVirt infrastructure
-                      provider.
-                    properties:
-                      apiServerInternalIP:
-                        description: "apiServerInternalIP is an IP address to contact
-                          the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. It is the IP that the
-                          Infrastructure.status.apiServerInternalURI points to. It
-                          is the IP for a self-hosted load balancer in front of the
-                          API servers. \n Deprecated: Use APIServerInternalIPs instead."
-                        type: string
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IPs otherwise
-                          only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      ingressIP:
-                        description: "ingressIP is an external IP which routes to
-                          the default ingress controller. The IP is a suitable target
-                          of a wildcard DNS record used to resolve default route host
-                          names. \n Deprecated: Use IngressIPs instead."
-                        type: string
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IPs
-                          otherwise only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      nodeDNSIP:
-                        description: 'deprecated: as of 4.6, this field is no longer
-                          set or honored.  It will be removed in a future release.'
-                        type: string
-                    type: object
-                  powervs:
-                    description: PowerVS contains settings specific to the Power Systems
-                      Virtual Servers infrastructure provider.
-                    properties:
-                      cisInstanceCRN:
-                        description: CISInstanceCRN is the CRN of the Cloud Internet
-                          Services instance managing the DNS zone for the cluster's
-                          base domain
-                        type: string
-                      dnsInstanceCRN:
-                        description: DNSInstanceCRN is the CRN of the DNS Services
-                          instance managing the DNS zone for the cluster's base domain
-                        type: string
-                      region:
-                        description: region holds the default Power VS region for
-                          new Power VS resources created by the cluster.
-                        type: string
-                      resourceGroup:
-                        description: 'resourceGroup is the resource group name for
-                          new IBMCloud resources created for a cluster. The resource
-                          group specified here will be used by cluster-image-registry-operator
-                          to set up a COS Instance in IBMCloud for the cluster registry.
-                          More about resource groups can be found here: https://cloud.ibm.com/docs/account?topic=account-rgs.
-                          When omitted, the image registry operator won''t be able
-                          to configure storage, which results in the image registry
-                          cluster operator not being in an available state.'
-                        maxLength: 40
-                        pattern: ^[a-zA-Z0-9-_ ]+$
-                        type: string
-                        x-kubernetes-validations:
-                        - message: resourceGroup is immutable once set
-                          rule: oldSelf == '' || self == oldSelf
-                      serviceEndpoints:
-                        description: serviceEndpoints is a list of custom endpoints
-                          which will override the default service endpoints of a Power
-                          VS service.
-                        items:
-                          description: PowervsServiceEndpoint stores the configuration
-                            of a custom url to override existing defaults of PowerVS
-                            Services.
-                          properties:
-                            name:
-                              description: name is the name of the Power VS service.
-                                Few of the services are IAM - https://cloud.ibm.com/apidocs/iam-identity-token-api
-                                ResourceController - https://cloud.ibm.com/apidocs/resource-controller/resource-controller
-                                Power Cloud - https://cloud.ibm.com/apidocs/power-cloud
-                              pattern: ^[a-z0-9-]+$
-                              type: string
-                            url:
-                              description: url is fully qualified URI with scheme
-                                https, that overrides the default generated endpoint
-                                for a client. This must be provided and cannot be
-                                empty.
-                              format: uri
-                              pattern: ^https://
-                              type: string
-                          required:
-                          - name
-                          - url
-                          type: object
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - name
-                        x-kubernetes-list-type: map
-                      zone:
-                        description: 'zone holds the default zone for the new Power
-                          VS resources created by the cluster. Note: Currently only
-                          single-zone OCP clusters are supported'
-                        type: string
-                    type: object
-                    x-kubernetes-validations:
-                    - message: cannot unset resourceGroup once set
-                      rule: '!has(oldSelf.resourceGroup) || has(self.resourceGroup)'
-                  type:
-                    description: "type is the underlying infrastructure provider for
-                      the cluster. This value controls whether infrastructure automation
-                      such as service load balancers, dynamic volume provisioning,
-                      machine creation and deletion, and other integrations are enabled.
-                      If None, no infrastructure automation is enabled. Allowed values
-                      are \"AWS\", \"Azure\", \"BareMetal\", \"GCP\", \"Libvirt\",
-                      \"OpenStack\", \"VSphere\", \"oVirt\", \"EquinixMetal\", \"PowerVS\",
-                      \"AlibabaCloud\", \"Nutanix\" and \"None\". Individual components
-                      may not support all platforms, and must handle unrecognized
-                      platforms as None if they do not support that platform. \n This
-                      value will be synced with to the `status.platform` and `status.platformStatus.type`.
-                      Currently this value cannot be changed once set."
-                    enum:
-                    - ""
-                    - AWS
-                    - Azure
-                    - BareMetal
-                    - GCP
-                    - Libvirt
-                    - OpenStack
-                    - None
-                    - VSphere
-                    - oVirt
-                    - IBMCloud
-                    - KubeVirt
-                    - EquinixMetal
-                    - PowerVS
-                    - AlibabaCloud
-                    - Nutanix
-                    - External
-                    type: string
-                  vsphere:
-                    description: VSphere contains settings specific to the VSphere
-                      infrastructure provider.
-                    properties:
-                      apiServerInternalIP:
-                        description: "apiServerInternalIP is an IP address to contact
-                          the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. It is the IP that the
-                          Infrastructure.status.apiServerInternalURI points to. It
-                          is the IP for a self-hosted load balancer in front of the
-                          API servers. \n Deprecated: Use APIServerInternalIPs instead."
-                        type: string
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IPs otherwise
-                          only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      ingressIP:
-                        description: "ingressIP is an external IP which routes to
-                          the default ingress controller. The IP is a suitable target
-                          of a wildcard DNS record used to resolve default route host
-                          names. \n Deprecated: Use IngressIPs instead."
-                        type: string
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IPs
-                          otherwise only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      machineNetworks:
-                        description: machineNetworks are IP networks used to connect
-                          all the OpenShift cluster nodes.
-                        items:
-                          description: CIDR is an IP address range in CIDR notation
-                            (for example, "10.0.0.0/8" or "fd00::/8").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[0-9]))$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))$)
-                          type: string
-                        maxItems: 32
-                        type: array
-                        x-kubernetes-list-type: set
-                      nodeDNSIP:
-                        description: nodeDNSIP is the IP address for the internal
-                          DNS used by the nodes. Unlike the one managed by the DNS
-                          operator, `NodeDNSIP` provides name resolution for the nodes
-                          themselves. There is no DNS-as-a-service for vSphere deployments.
-                          In order to minimize necessary changes to the datacenter
-                          DNS, a DNS service is hosted as a static pod to serve those
-                          hostnames to the nodes in the cluster.
-                        type: string
-                    type: object
-                type: object
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-Default.crd.yaml-patch b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-Default.crd.yaml-patch
deleted file mode 100644
index d127130a..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-Default.crd.yaml-patch
+++ /dev/null
@@ -1,24 +0,0 @@
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/vcenters/items/properties/server/anyOf
-  value:
-    - format: ipv4
-    - format: ipv6
-    - format: hostname
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/failureDomains/items/properties/server/anyOf
-  value:
-    - format: ipv4
-    - format: ipv6
-    - format: hostname
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/nodeNetworking/properties/external/properties/excludeNetworkSubnetCidr/items/format
-  value: cidr
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/nodeNetworking/properties/external/properties/networkSubnetCidr/items/format
-  value: cidr
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/nodeNetworking/properties/internal/properties/excludeNetworkSubnetCidr/items/format
-  value: cidr
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/nodeNetworking/properties/internal/properties/networkSubnetCidr/items/format
-  value: cidr
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-TechPreviewNoUpgrade.crd.yaml
deleted file mode 100644
index 73205cfa..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-TechPreviewNoUpgrade.crd.yaml
+++ /dev/null
@@ -1,2089 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    release.openshift.io/feature-set: TechPreviewNoUpgrade
-  name: infrastructures.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: Infrastructure
-    listKind: InfrastructureList
-    plural: infrastructures
-    singular: infrastructure
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "Infrastructure holds cluster-wide information about Infrastructure.
-          \ The canonical name is `cluster` \n Compatibility level 1: Stable within
-          a major release for a minimum of 12 months or 3 minor releases (whichever
-          is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              cloudConfig:
-                description: "cloudConfig is a reference to a ConfigMap containing
-                  the cloud provider configuration file. This configuration file is
-                  used to configure the Kubernetes cloud provider integration when
-                  using the built-in cloud provider integration or the external cloud
-                  controller manager. The namespace for this config map is openshift-config.
-                  \n cloudConfig should only be consumed by the kube_cloud_config
-                  controller. The controller is responsible for using the user configuration
-                  in the spec for various platforms and combining that with the user
-                  provided ConfigMap in this field to create a stitched kube cloud
-                  config. The controller generates a ConfigMap `kube-cloud-config`
-                  in `openshift-config-managed` namespace with the kube cloud config
-                  is stored in `cloud.conf` key. All the clients are expected to use
-                  the generated ConfigMap only."
-                properties:
-                  key:
-                    description: Key allows pointing to a specific key/value inside
-                      of the configmap.  This is useful for logical file references.
-                    type: string
-                  name:
-                    type: string
-                type: object
-              platformSpec:
-                description: platformSpec holds desired information specific to the
-                  underlying infrastructure provider.
-                properties:
-                  alibabaCloud:
-                    description: AlibabaCloud contains settings specific to the Alibaba
-                      Cloud infrastructure provider.
-                    type: object
-                  aws:
-                    description: AWS contains settings specific to the Amazon Web
-                      Services infrastructure provider.
-                    properties:
-                      serviceEndpoints:
-                        description: serviceEndpoints list contains custom endpoints
-                          which will override default service endpoint of AWS Services.
-                          There must be only one ServiceEndpoint for a service.
-                        items:
-                          description: AWSServiceEndpoint store the configuration
-                            of a custom url to override existing defaults of AWS Services.
-                          properties:
-                            name:
-                              description: name is the name of the AWS service. The
-                                list of all the service names can be found at https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html
-                                This must be provided and cannot be empty.
-                              pattern: ^[a-z0-9-]+$
-                              type: string
-                            url:
-                              description: url is fully qualified URI with scheme
-                                https, that overrides the default generated endpoint
-                                for a client. This must be provided and cannot be
-                                empty.
-                              pattern: ^https://
-                              type: string
-                          type: object
-                        type: array
-                        x-kubernetes-list-type: atomic
-                    type: object
-                  azure:
-                    description: Azure contains settings specific to the Azure infrastructure
-                      provider.
-                    type: object
-                  baremetal:
-                    description: BareMetal contains settings specific to the BareMetal
-                      platform.
-                    properties:
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IP addresses,
-                          one from IPv4 family and one from IPv6. In single stack
-                          clusters a single IP address is expected. When omitted,
-                          values from the status.apiServerInternalIPs will be used.
-                          Once set, the list cannot be completely removed (but its
-                          second entry can).
-                        items:
-                          description: IP is an IP address (for example, "10.0.0.0"
-                            or "fd00::").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                        x-kubernetes-validations:
-                        - message: apiServerInternalIPs must contain at most one IPv4
-                            address and at most one IPv6 address
-                          rule: 'size(self) == 2 ? self.exists_one(x, x.contains('':''))
-                            : true'
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IP
-                          addresses, one from IPv4 family and one from IPv6. In single
-                          stack clusters a single IP address is expected. When omitted,
-                          values from the status.ingressIPs will be used. Once set,
-                          the list cannot be completely removed (but its second entry
-                          can).
-                        items:
-                          description: IP is an IP address (for example, "10.0.0.0"
-                            or "fd00::").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                        x-kubernetes-validations:
-                        - message: ingressIPs must contain at most one IPv4 address
-                            and at most one IPv6 address
-                          rule: 'size(self) == 2 ? self.exists_one(x, x.contains('':''))
-                            : true'
-                      machineNetworks:
-                        description: machineNetworks are IP networks used to connect
-                          all the OpenShift cluster nodes. Each network is provided
-                          in the CIDR format and should be IPv4 or IPv6, for example
-                          "10.0.0.0/8" or "fd00::/8".
-                        items:
-                          description: CIDR is an IP address range in CIDR notation
-                            (for example, "10.0.0.0/8" or "fd00::/8").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[0-9]))$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))$)
-                          type: string
-                        maxItems: 32
-                        type: array
-                        x-kubernetes-list-type: set
-                    type: object
-                    x-kubernetes-validations:
-                    - message: apiServerInternalIPs list is required once set
-                      rule: '!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)'
-                    - message: ingressIPs list is required once set
-                      rule: '!has(oldSelf.ingressIPs) || has(self.ingressIPs)'
-                  equinixMetal:
-                    description: EquinixMetal contains settings specific to the Equinix
-                      Metal infrastructure provider.
-                    type: object
-                  external:
-                    description: ExternalPlatformType represents generic infrastructure
-                      provider. Platform-specific components should be supplemented
-                      separately.
-                    properties:
-                      platformName:
-                        default: Unknown
-                        description: PlatformName holds the arbitrary string representing
-                          the infrastructure provider name, expected to be set at
-                          the installation time. This field is solely for informational
-                          and reporting purposes and is not expected to be used for
-                          decision-making.
-                        type: string
-                        x-kubernetes-validations:
-                        - message: platform name cannot be changed once set
-                          rule: oldSelf == 'Unknown' || self == oldSelf
-                    type: object
-                  gcp:
-                    description: GCP contains settings specific to the Google Cloud
-                      Platform infrastructure provider.
-                    type: object
-                  ibmcloud:
-                    description: IBMCloud contains settings specific to the IBMCloud
-                      infrastructure provider.
-                    type: object
-                  kubevirt:
-                    description: Kubevirt contains settings specific to the kubevirt
-                      infrastructure provider.
-                    type: object
-                  nutanix:
-                    description: Nutanix contains settings specific to the Nutanix
-                      infrastructure provider.
-                    properties:
-                      failureDomains:
-                        description: failureDomains configures failure domains information
-                          for the Nutanix platform. When set, the failure domains
-                          defined here may be used to spread Machines across prism
-                          element clusters to improve fault tolerance of the cluster.
-                        items:
-                          description: NutanixFailureDomain configures failure domain
-                            information for the Nutanix platform.
-                          properties:
-                            cluster:
-                              description: cluster is to identify the cluster (the
-                                Prism Element under management of the Prism Central),
-                                in which the Machine's VM will be created. The cluster
-                                identifier (uuid or name) can be obtained from the
-                                Prism Central console or using the prism_central API.
-                              properties:
-                                name:
-                                  description: name is the resource name in the PC.
-                                    It cannot be empty if the type is Name.
-                                  type: string
-                                type:
-                                  description: type is the identifier type to use
-                                    for this resource.
-                                  enum:
-                                  - UUID
-                                  - Name
-                                  type: string
-                                uuid:
-                                  description: uuid is the UUID of the resource in
-                                    the PC. It cannot be empty if the type is UUID.
-                                  type: string
-                              required:
-                              - type
-                              type: object
-                              x-kubernetes-validations:
-                              - message: uuid configuration is required when type
-                                  is UUID, and forbidden otherwise
-                                rule: 'has(self.type) && self.type == ''UUID'' ?  has(self.uuid)
-                                  : !has(self.uuid)'
-                              - message: name configuration is required when type
-                                  is Name, and forbidden otherwise
-                                rule: 'has(self.type) && self.type == ''Name'' ?  has(self.name)
-                                  : !has(self.name)'
-                            name:
-                              description: name defines the unique name of a failure
-                                domain. Name is required and must be at most 64 characters
-                                in length. It must consist of only lower case alphanumeric
-                                characters and hyphens (-). It must start and end
-                                with an alphanumeric character. This value is arbitrary
-                                and is used to identify the failure domain within
-                                the platform.
-                              maxLength: 64
-                              minLength: 1
-                              pattern: '[a-z0-9]([-a-z0-9]*[a-z0-9])?'
-                              type: string
-                            subnets:
-                              description: subnets holds a list of identifiers (one
-                                or more) of the cluster's network subnets for the
-                                Machine's VM to connect to. The subnet identifiers
-                                (uuid or name) can be obtained from the Prism Central
-                                console or using the prism_central API.
-                              items:
-                                description: NutanixResourceIdentifier holds the identity
-                                  of a Nutanix PC resource (cluster, image, subnet,
-                                  etc.)
-                                properties:
-                                  name:
-                                    description: name is the resource name in the
-                                      PC. It cannot be empty if the type is Name.
-                                    type: string
-                                  type:
-                                    description: type is the identifier type to use
-                                      for this resource.
-                                    enum:
-                                    - UUID
-                                    - Name
-                                    type: string
-                                  uuid:
-                                    description: uuid is the UUID of the resource
-                                      in the PC. It cannot be empty if the type is
-                                      UUID.
-                                    type: string
-                                required:
-                                - type
-                                type: object
-                                x-kubernetes-validations:
-                                - message: uuid configuration is required when type
-                                    is UUID, and forbidden otherwise
-                                  rule: 'has(self.type) && self.type == ''UUID'' ?  has(self.uuid)
-                                    : !has(self.uuid)'
-                                - message: name configuration is required when type
-                                    is Name, and forbidden otherwise
-                                  rule: 'has(self.type) && self.type == ''Name'' ?  has(self.name)
-                                    : !has(self.name)'
-                              maxItems: 1
-                              minItems: 1
-                              type: array
-                              x-kubernetes-list-map-keys:
-                              - type
-                              x-kubernetes-list-type: map
-                          required:
-                          - cluster
-                          - name
-                          - subnets
-                          type: object
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - name
-                        x-kubernetes-list-type: map
-                      prismCentral:
-                        description: prismCentral holds the endpoint address and port
-                          to access the Nutanix Prism Central. When a cluster-wide
-                          proxy is installed, by default, this endpoint will be accessed
-                          via the proxy. Should you wish for communication with this
-                          endpoint not to be proxied, please add the endpoint to the
-                          proxy spec.noProxy list.
-                        properties:
-                          address:
-                            description: address is the endpoint address (DNS name
-                              or IP address) of the Nutanix Prism Central or Element
-                              (cluster)
-                            maxLength: 256
-                            type: string
-                          port:
-                            description: port is the port number to access the Nutanix
-                              Prism Central or Element (cluster)
-                            format: int32
-                            maximum: 65535
-                            minimum: 1
-                            type: integer
-                        required:
-                        - address
-                        - port
-                        type: object
-                      prismElements:
-                        description: prismElements holds one or more endpoint address
-                          and port data to access the Nutanix Prism Elements (clusters)
-                          of the Nutanix Prism Central. Currently we only support
-                          one Prism Element (cluster) for an OpenShift cluster, where
-                          all the Nutanix resources (VMs, subnets, volumes, etc.)
-                          used in the OpenShift cluster are located. In the future,
-                          we may support Nutanix resources (VMs, etc.) spread over
-                          multiple Prism Elements (clusters) of the Prism Central.
-                        items:
-                          description: NutanixPrismElementEndpoint holds the name
-                            and endpoint data for a Prism Element (cluster)
-                          properties:
-                            endpoint:
-                              description: endpoint holds the endpoint address and
-                                port data of the Prism Element (cluster). When a cluster-wide
-                                proxy is installed, by default, this endpoint will
-                                be accessed via the proxy. Should you wish for communication
-                                with this endpoint not to be proxied, please add the
-                                endpoint to the proxy spec.noProxy list.
-                              properties:
-                                address:
-                                  description: address is the endpoint address (DNS
-                                    name or IP address) of the Nutanix Prism Central
-                                    or Element (cluster)
-                                  maxLength: 256
-                                  type: string
-                                port:
-                                  description: port is the port number to access the
-                                    Nutanix Prism Central or Element (cluster)
-                                  format: int32
-                                  maximum: 65535
-                                  minimum: 1
-                                  type: integer
-                              required:
-                              - address
-                              - port
-                              type: object
-                            name:
-                              description: name is the name of the Prism Element (cluster).
-                                This value will correspond with the cluster field
-                                configured on other resources (eg Machines, PVCs,
-                                etc).
-                              maxLength: 256
-                              type: string
-                          required:
-                          - endpoint
-                          - name
-                          type: object
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - name
-                        x-kubernetes-list-type: map
-                    required:
-                    - prismCentral
-                    - prismElements
-                    type: object
-                  openstack:
-                    description: OpenStack contains settings specific to the OpenStack
-                      infrastructure provider.
-                    properties:
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IP addresses,
-                          one from IPv4 family and one from IPv6. In single stack
-                          clusters a single IP address is expected. When omitted,
-                          values from the status.apiServerInternalIPs will be used.
-                          Once set, the list cannot be completely removed (but its
-                          second entry can).
-                        items:
-                          description: IP is an IP address (for example, "10.0.0.0"
-                            or "fd00::").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                        x-kubernetes-validations:
-                        - message: apiServerInternalIPs must contain at most one IPv4
-                            address and at most one IPv6 address
-                          rule: 'size(self) == 2 ? self.exists_one(x, x.contains('':''))
-                            : true'
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IP
-                          addresses, one from IPv4 family and one from IPv6. In single
-                          stack clusters a single IP address is expected. When omitted,
-                          values from the status.ingressIPs will be used. Once set,
-                          the list cannot be completely removed (but its second entry
-                          can).
-                        items:
-                          description: IP is an IP address (for example, "10.0.0.0"
-                            or "fd00::").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                        x-kubernetes-validations:
-                        - message: ingressIPs must contain at most one IPv4 address
-                            and at most one IPv6 address
-                          rule: 'size(self) == 2 ? self.exists_one(x, x.contains('':''))
-                            : true'
-                      machineNetworks:
-                        description: machineNetworks are IP networks used to connect
-                          all the OpenShift cluster nodes. Each network is provided
-                          in the CIDR format and should be IPv4 or IPv6, for example
-                          "10.0.0.0/8" or "fd00::/8".
-                        items:
-                          description: CIDR is an IP address range in CIDR notation
-                            (for example, "10.0.0.0/8" or "fd00::/8").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[0-9]))$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))$)
-                          type: string
-                        maxItems: 32
-                        type: array
-                        x-kubernetes-list-type: set
-                    type: object
-                    x-kubernetes-validations:
-                    - message: apiServerInternalIPs list is required once set
-                      rule: '!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)'
-                    - message: ingressIPs list is required once set
-                      rule: '!has(oldSelf.ingressIPs) || has(self.ingressIPs)'
-                  ovirt:
-                    description: Ovirt contains settings specific to the oVirt infrastructure
-                      provider.
-                    type: object
-                  powervs:
-                    description: PowerVS contains settings specific to the IBM Power
-                      Systems Virtual Servers infrastructure provider.
-                    properties:
-                      serviceEndpoints:
-                        description: serviceEndpoints is a list of custom endpoints
-                          which will override the default service endpoints of a Power
-                          VS service.
-                        items:
-                          description: PowervsServiceEndpoint stores the configuration
-                            of a custom url to override existing defaults of PowerVS
-                            Services.
-                          properties:
-                            name:
-                              description: name is the name of the Power VS service.
-                                Few of the services are IAM - https://cloud.ibm.com/apidocs/iam-identity-token-api
-                                ResourceController - https://cloud.ibm.com/apidocs/resource-controller/resource-controller
-                                Power Cloud - https://cloud.ibm.com/apidocs/power-cloud
-                              pattern: ^[a-z0-9-]+$
-                              type: string
-                            url:
-                              description: url is fully qualified URI with scheme
-                                https, that overrides the default generated endpoint
-                                for a client. This must be provided and cannot be
-                                empty.
-                              format: uri
-                              pattern: ^https://
-                              type: string
-                          required:
-                          - name
-                          - url
-                          type: object
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - name
-                        x-kubernetes-list-type: map
-                    type: object
-                  type:
-                    description: type is the underlying infrastructure provider for
-                      the cluster. This value controls whether infrastructure automation
-                      such as service load balancers, dynamic volume provisioning,
-                      machine creation and deletion, and other integrations are enabled.
-                      If None, no infrastructure automation is enabled. Allowed values
-                      are "AWS", "Azure", "BareMetal", "GCP", "Libvirt", "OpenStack",
-                      "VSphere", "oVirt", "KubeVirt", "EquinixMetal", "PowerVS", "AlibabaCloud",
-                      "Nutanix" and "None". Individual components may not support
-                      all platforms, and must handle unrecognized platforms as None
-                      if they do not support that platform.
-                    enum:
-                    - ""
-                    - AWS
-                    - Azure
-                    - BareMetal
-                    - GCP
-                    - Libvirt
-                    - OpenStack
-                    - None
-                    - VSphere
-                    - oVirt
-                    - IBMCloud
-                    - KubeVirt
-                    - EquinixMetal
-                    - PowerVS
-                    - AlibabaCloud
-                    - Nutanix
-                    - External
-                    type: string
-                  vsphere:
-                    description: VSphere contains settings specific to the VSphere
-                      infrastructure provider.
-                    properties:
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IP addresses,
-                          one from IPv4 family and one from IPv6. In single stack
-                          clusters a single IP address is expected. When omitted,
-                          values from the status.apiServerInternalIPs will be used.
-                          Once set, the list cannot be completely removed (but its
-                          second entry can).
-                        items:
-                          description: IP is an IP address (for example, "10.0.0.0"
-                            or "fd00::").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                        x-kubernetes-validations:
-                        - message: apiServerInternalIPs must contain at most one IPv4
-                            address and at most one IPv6 address
-                          rule: 'size(self) == 2 ? self.exists_one(x, x.contains('':''))
-                            : true'
-                      failureDomains:
-                        description: failureDomains contains the definition of region,
-                          zone and the vCenter topology. If this is omitted failure
-                          domains (regions and zones) will not be used.
-                        items:
-                          description: VSpherePlatformFailureDomainSpec holds the
-                            region and zone failure domain and the vCenter topology
-                            of that failure domain.
-                          properties:
-                            name:
-                              description: name defines the arbitrary but unique name
-                                of a failure domain.
-                              maxLength: 256
-                              minLength: 1
-                              type: string
-                            region:
-                              description: region defines the name of a region tag
-                                that will be attached to a vCenter datacenter. The
-                                tag category in vCenter must be named openshift-region.
-                              maxLength: 80
-                              minLength: 1
-                              type: string
-                            server:
-                              anyOf:
-                              - format: ipv4
-                              - format: ipv6
-                              - format: hostname
-                              description: server is the fully-qualified domain name
-                                or the IP address of the vCenter server. ---
-                              maxLength: 255
-                              minLength: 1
-                              type: string
-                            topology:
-                              description: Topology describes a given failure domain
-                                using vSphere constructs
-                              properties:
-                                computeCluster:
-                                  description: computeCluster the absolute path of
-                                    the vCenter cluster in which virtual machine will
-                                    be located. The absolute path is of the form /<datacenter>/host/<cluster>.
-                                    The maximum length of the path is 2048 characters.
-                                  maxLength: 2048
-                                  pattern: ^/.*?/host/.*?
-                                  type: string
-                                datacenter:
-                                  description: datacenter is the name of vCenter datacenter
-                                    in which virtual machines will be located. The
-                                    maximum length of the datacenter name is 80 characters.
-                                  maxLength: 80
-                                  type: string
-                                datastore:
-                                  description: datastore is the absolute path of the
-                                    datastore in which the virtual machine is located.
-                                    The absolute path is of the form /<datacenter>/datastore/<datastore>
-                                    The maximum length of the path is 2048 characters.
-                                  maxLength: 2048
-                                  pattern: ^/.*?/datastore/.*?
-                                  type: string
-                                folder:
-                                  description: folder is the absolute path of the
-                                    folder where virtual machines are located. The
-                                    absolute path is of the form /<datacenter>/vm/<folder>.
-                                    The maximum length of the path is 2048 characters.
-                                  maxLength: 2048
-                                  pattern: ^/.*?/vm/.*?
-                                  type: string
-                                networks:
-                                  description: networks is the list of port group
-                                    network names within this failure domain. Currently,
-                                    we only support a single interface per RHCOS virtual
-                                    machine. The available networks (port groups)
-                                    can be listed using `govc ls 'network/*'` The
-                                    single interface should be the absolute path of
-                                    the form /<datacenter>/network/<portgroup>.
-                                  items:
-                                    type: string
-                                  maxItems: 1
-                                  minItems: 1
-                                  type: array
-                                  x-kubernetes-list-type: atomic
-                                resourcePool:
-                                  description: resourcePool is the absolute path of
-                                    the resource pool where virtual machines will
-                                    be created. The absolute path is of the form /<datacenter>/host/<cluster>/Resources/<resourcepool>.
-                                    The maximum length of the path is 2048 characters.
-                                  maxLength: 2048
-                                  pattern: ^/.*?/host/.*?/Resources.*
-                                  type: string
-                                template:
-                                  description: "template is the full inventory path
-                                    of the virtual machine or template that will be
-                                    cloned when creating new machines in this failure
-                                    domain. The maximum length of the path is 2048
-                                    characters. \n When omitted, the template will
-                                    be calculated by the control plane machineset
-                                    operator based on the region and zone defined
-                                    in VSpherePlatformFailureDomainSpec. For example,
-                                    for zone=zonea, region=region1, and infrastructure
-                                    name=test, the template path would be calculated
-                                    as /<datacenter>/vm/test-rhcos-region1-zonea."
-                                  maxLength: 2048
-                                  minLength: 1
-                                  pattern: ^/.*?/vm/.*?
-                                  type: string
-                              required:
-                              - computeCluster
-                              - datacenter
-                              - datastore
-                              - networks
-                              type: object
-                            zone:
-                              description: zone defines the name of a zone tag that
-                                will be attached to a vCenter cluster. The tag category
-                                in vCenter must be named openshift-zone.
-                              maxLength: 80
-                              minLength: 1
-                              type: string
-                          required:
-                          - name
-                          - region
-                          - server
-                          - topology
-                          - zone
-                          type: object
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - name
-                        x-kubernetes-list-type: map
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IP
-                          addresses, one from IPv4 family and one from IPv6. In single
-                          stack clusters a single IP address is expected. When omitted,
-                          values from the status.ingressIPs will be used. Once set,
-                          the list cannot be completely removed (but its second entry
-                          can).
-                        items:
-                          description: IP is an IP address (for example, "10.0.0.0"
-                            or "fd00::").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                        x-kubernetes-validations:
-                        - message: ingressIPs must contain at most one IPv4 address
-                            and at most one IPv6 address
-                          rule: 'size(self) == 2 ? self.exists_one(x, x.contains('':''))
-                            : true'
-                      machineNetworks:
-                        description: machineNetworks are IP networks used to connect
-                          all the OpenShift cluster nodes. Each network is provided
-                          in the CIDR format and should be IPv4 or IPv6, for example
-                          "10.0.0.0/8" or "fd00::/8".
-                        items:
-                          description: CIDR is an IP address range in CIDR notation
-                            (for example, "10.0.0.0/8" or "fd00::/8").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[0-9]))$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))$)
-                          type: string
-                        maxItems: 32
-                        type: array
-                        x-kubernetes-list-type: set
-                      nodeNetworking:
-                        description: nodeNetworking contains the definition of internal
-                          and external network constraints for assigning the node's
-                          networking. If this field is omitted, networking defaults
-                          to the legacy address selection behavior which is to only
-                          support a single address and return the first one found.
-                        properties:
-                          external:
-                            description: external represents the network configuration
-                              of the node that is externally routable.
-                            properties:
-                              excludeNetworkSubnetCidr:
-                                description: excludeNetworkSubnetCidr IP addresses
-                                  in subnet ranges will be excluded when selecting
-                                  the IP address from the VirtualMachine's VM for
-                                  use in the status.addresses fields. ---
-                                items:
-                                  format: cidr
-                                  type: string
-                                type: array
-                                x-kubernetes-list-type: atomic
-                              network:
-                                description: network VirtualMachine's VM Network names
-                                  that will be used to when searching for status.addresses
-                                  fields. Note that if internal.networkSubnetCIDR
-                                  and external.networkSubnetCIDR are not set, then
-                                  the vNIC associated to this network must only have
-                                  a single IP address assigned to it. The available
-                                  networks (port groups) can be listed using `govc
-                                  ls 'network/*'`
-                                type: string
-                              networkSubnetCidr:
-                                description: networkSubnetCidr IP address on VirtualMachine's
-                                  network interfaces included in the fields' CIDRs
-                                  that will be used in respective status.addresses
-                                  fields. ---
-                                items:
-                                  format: cidr
-                                  type: string
-                                type: array
-                                x-kubernetes-list-type: set
-                            type: object
-                          internal:
-                            description: internal represents the network configuration
-                              of the node that is routable only within the cluster.
-                            properties:
-                              excludeNetworkSubnetCidr:
-                                description: excludeNetworkSubnetCidr IP addresses
-                                  in subnet ranges will be excluded when selecting
-                                  the IP address from the VirtualMachine's VM for
-                                  use in the status.addresses fields. ---
-                                items:
-                                  format: cidr
-                                  type: string
-                                type: array
-                                x-kubernetes-list-type: atomic
-                              network:
-                                description: network VirtualMachine's VM Network names
-                                  that will be used to when searching for status.addresses
-                                  fields. Note that if internal.networkSubnetCIDR
-                                  and external.networkSubnetCIDR are not set, then
-                                  the vNIC associated to this network must only have
-                                  a single IP address assigned to it. The available
-                                  networks (port groups) can be listed using `govc
-                                  ls 'network/*'`
-                                type: string
-                              networkSubnetCidr:
-                                description: networkSubnetCidr IP address on VirtualMachine's
-                                  network interfaces included in the fields' CIDRs
-                                  that will be used in respective status.addresses
-                                  fields. ---
-                                items:
-                                  format: cidr
-                                  type: string
-                                type: array
-                                x-kubernetes-list-type: set
-                            type: object
-                        type: object
-                      vcenters:
-                        description: vcenters holds the connection details for services
-                          to communicate with vCenter. Currently, only a single vCenter
-                          is supported. ---
-                        items:
-                          description: VSpherePlatformVCenterSpec stores the vCenter
-                            connection fields. This is used by the vSphere CCM.
-                          properties:
-                            datacenters:
-                              description: The vCenter Datacenters in which the RHCOS
-                                vm guests are located. This field will be used by
-                                the Cloud Controller Manager. Each datacenter listed
-                                here should be used within a topology.
-                              items:
-                                type: string
-                              minItems: 1
-                              type: array
-                              x-kubernetes-list-type: set
-                            port:
-                              description: port is the TCP port that will be used
-                                to communicate to the vCenter endpoint. When omitted,
-                                this means the user has no opinion and it is up to
-                                the platform to choose a sensible default, which is
-                                subject to change over time.
-                              format: int32
-                              maximum: 32767
-                              minimum: 1
-                              type: integer
-                            server:
-                              anyOf:
-                              - format: ipv4
-                              - format: ipv6
-                              - format: hostname
-                              description: server is the fully-qualified domain name
-                                or the IP address of the vCenter server. ---
-                              maxLength: 255
-                              type: string
-                          required:
-                          - datacenters
-                          - server
-                          type: object
-                        maxItems: 1
-                        minItems: 0
-                        type: array
-                        x-kubernetes-list-type: atomic
-                    type: object
-                    x-kubernetes-validations:
-                    - message: apiServerInternalIPs list is required once set
-                      rule: '!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)'
-                    - message: ingressIPs list is required once set
-                      rule: '!has(oldSelf.ingressIPs) || has(self.ingressIPs)'
-                type: object
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            properties:
-              apiServerInternalURI:
-                description: apiServerInternalURL is a valid URI with scheme 'https',
-                  address and optionally a port (defaulting to 443).  apiServerInternalURL
-                  can be used by components like kubelets, to contact the Kubernetes
-                  API server using the infrastructure provider rather than Kubernetes
-                  networking.
-                type: string
-              apiServerURL:
-                description: apiServerURL is a valid URI with scheme 'https', address
-                  and optionally a port (defaulting to 443).  apiServerURL can be
-                  used by components like the web console to tell users where to find
-                  the Kubernetes API.
-                type: string
-              controlPlaneTopology:
-                default: HighlyAvailable
-                description: controlPlaneTopology expresses the expectations for operands
-                  that normally run on control nodes. The default is 'HighlyAvailable',
-                  which represents the behavior operators have in a "normal" cluster.
-                  The 'SingleReplica' mode will be used in single-node deployments
-                  and the operators should not configure the operand for highly-available
-                  operation The 'External' mode indicates that the control plane is
-                  hosted externally to the cluster and that its components are not
-                  visible within the cluster.
-                enum:
-                - HighlyAvailable
-                - SingleReplica
-                - External
-                type: string
-              cpuPartitioning:
-                default: None
-                description: cpuPartitioning expresses if CPU partitioning is a currently
-                  enabled feature in the cluster. CPU Partitioning means that this
-                  cluster can support partitioning workloads to specific CPU Sets.
-                  Valid values are "None" and "AllNodes". When omitted, the default
-                  value is "None". The default value of "None" indicates that no nodes
-                  will be setup with CPU partitioning. The "AllNodes" value indicates
-                  that all nodes have been setup with CPU partitioning, and can then
-                  be further configured via the PerformanceProfile API.
-                enum:
-                - None
-                - AllNodes
-                type: string
-              etcdDiscoveryDomain:
-                description: 'etcdDiscoveryDomain is the domain used to fetch the
-                  SRV records for discovering etcd servers and clients. For more info:
-                  https://github.com/etcd-io/etcd/blob/329be66e8b3f9e2e6af83c123ff89297e49ebd15/Documentation/op-guide/clustering.md#dns-discovery
-                  deprecated: as of 4.7, this field is no longer set or honored.  It
-                  will be removed in a future release.'
-                type: string
-              infrastructureName:
-                description: infrastructureName uniquely identifies a cluster with
-                  a human friendly name. Once set it should not be changed. Must be
-                  of max length 27 and must have only alphanumeric or hyphen characters.
-                type: string
-              infrastructureTopology:
-                default: HighlyAvailable
-                description: 'infrastructureTopology expresses the expectations for
-                  infrastructure services that do not run on control plane nodes,
-                  usually indicated by a node selector for a `role` value other than
-                  `master`. The default is ''HighlyAvailable'', which represents the
-                  behavior operators have in a "normal" cluster. The ''SingleReplica''
-                  mode will be used in single-node deployments and the operators should
-                  not configure the operand for highly-available operation NOTE: External
-                  topology mode is not applicable for this field.'
-                enum:
-                - HighlyAvailable
-                - SingleReplica
-                type: string
-              platform:
-                description: "platform is the underlying infrastructure provider for
-                  the cluster. \n Deprecated: Use platformStatus.type instead."
-                enum:
-                - ""
-                - AWS
-                - Azure
-                - BareMetal
-                - GCP
-                - Libvirt
-                - OpenStack
-                - None
-                - VSphere
-                - oVirt
-                - IBMCloud
-                - KubeVirt
-                - EquinixMetal
-                - PowerVS
-                - AlibabaCloud
-                - Nutanix
-                - External
-                type: string
-              platformStatus:
-                description: platformStatus holds status information specific to the
-                  underlying infrastructure provider.
-                properties:
-                  alibabaCloud:
-                    description: AlibabaCloud contains settings specific to the Alibaba
-                      Cloud infrastructure provider.
-                    properties:
-                      region:
-                        description: region specifies the region for Alibaba Cloud
-                          resources created for the cluster.
-                        pattern: ^[0-9A-Za-z-]+$
-                        type: string
-                      resourceGroupID:
-                        description: resourceGroupID is the ID of the resource group
-                          for the cluster.
-                        pattern: ^(rg-[0-9A-Za-z]+)?$
-                        type: string
-                      resourceTags:
-                        description: resourceTags is a list of additional tags to
-                          apply to Alibaba Cloud resources created for the cluster.
-                        items:
-                          description: AlibabaCloudResourceTag is the set of tags
-                            to add to apply to resources.
-                          properties:
-                            key:
-                              description: key is the key of the tag.
-                              maxLength: 128
-                              minLength: 1
-                              type: string
-                            value:
-                              description: value is the value of the tag.
-                              maxLength: 128
-                              minLength: 1
-                              type: string
-                          required:
-                          - key
-                          - value
-                          type: object
-                        maxItems: 20
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - key
-                        x-kubernetes-list-type: map
-                    required:
-                    - region
-                    type: object
-                  aws:
-                    description: AWS contains settings specific to the Amazon Web
-                      Services infrastructure provider.
-                    properties:
-                      region:
-                        description: region holds the default AWS region for new AWS
-                          resources created by the cluster.
-                        type: string
-                      resourceTags:
-                        description: resourceTags is a list of additional tags to
-                          apply to AWS resources created for the cluster. See https://docs.aws.amazon.com/general/latest/gr/aws_tagging.html
-                          for information on tagging AWS resources. AWS supports a
-                          maximum of 50 tags per resource. OpenShift reserves 25 tags
-                          for its use, leaving 25 tags available for the user.
-                        items:
-                          description: AWSResourceTag is a tag to apply to AWS resources
-                            created for the cluster.
-                          properties:
-                            key:
-                              description: key is the key of the tag
-                              maxLength: 128
-                              minLength: 1
-                              pattern: ^[0-9A-Za-z_.:/=+-@]+$
-                              type: string
-                            value:
-                              description: value is the value of the tag. Some AWS
-                                service do not support empty values. Since tags are
-                                added to resources in many services, the length of
-                                the tag value must meet the requirements of all services.
-                              maxLength: 256
-                              minLength: 1
-                              pattern: ^[0-9A-Za-z_.:/=+-@]+$
-                              type: string
-                          required:
-                          - key
-                          - value
-                          type: object
-                        maxItems: 25
-                        type: array
-                        x-kubernetes-list-type: atomic
-                      serviceEndpoints:
-                        description: ServiceEndpoints list contains custom endpoints
-                          which will override default service endpoint of AWS Services.
-                          There must be only one ServiceEndpoint for a service.
-                        items:
-                          description: AWSServiceEndpoint store the configuration
-                            of a custom url to override existing defaults of AWS Services.
-                          properties:
-                            name:
-                              description: name is the name of the AWS service. The
-                                list of all the service names can be found at https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html
-                                This must be provided and cannot be empty.
-                              pattern: ^[a-z0-9-]+$
-                              type: string
-                            url:
-                              description: url is fully qualified URI with scheme
-                                https, that overrides the default generated endpoint
-                                for a client. This must be provided and cannot be
-                                empty.
-                              pattern: ^https://
-                              type: string
-                          type: object
-                        type: array
-                        x-kubernetes-list-type: atomic
-                    type: object
-                  azure:
-                    description: Azure contains settings specific to the Azure infrastructure
-                      provider.
-                    properties:
-                      armEndpoint:
-                        description: armEndpoint specifies a URL to use for resource
-                          management in non-soverign clouds such as Azure Stack.
-                        type: string
-                      cloudName:
-                        description: cloudName is the name of the Azure cloud environment
-                          which can be used to configure the Azure SDK with the appropriate
-                          Azure API endpoints. If empty, the value is equal to `AzurePublicCloud`.
-                        enum:
-                        - ""
-                        - AzurePublicCloud
-                        - AzureUSGovernmentCloud
-                        - AzureChinaCloud
-                        - AzureGermanCloud
-                        - AzureStackCloud
-                        type: string
-                      networkResourceGroupName:
-                        description: networkResourceGroupName is the Resource Group
-                          for network resources like the Virtual Network and Subnets
-                          used by the cluster. If empty, the value is same as ResourceGroupName.
-                        type: string
-                      resourceGroupName:
-                        description: resourceGroupName is the Resource Group for new
-                          Azure resources created for the cluster.
-                        type: string
-                      resourceTags:
-                        description: resourceTags is a list of additional tags to
-                          apply to Azure resources created for the cluster. See https://docs.microsoft.com/en-us/rest/api/resources/tags
-                          for information on tagging Azure resources. Due to limitations
-                          on Automation, Content Delivery Network, DNS Azure resources,
-                          a maximum of 15 tags may be applied. OpenShift reserves
-                          5 tags for internal use, allowing 10 tags for user configuration.
-                        items:
-                          description: AzureResourceTag is a tag to apply to Azure
-                            resources created for the cluster.
-                          properties:
-                            key:
-                              description: key is the key part of the tag. A tag key
-                                can have a maximum of 128 characters and cannot be
-                                empty. Key must begin with a letter, end with a letter,
-                                number or underscore, and must contain only alphanumeric
-                                characters and the following special characters `_
-                                . -`.
-                              maxLength: 128
-                              minLength: 1
-                              pattern: ^[a-zA-Z]([0-9A-Za-z_.-]*[0-9A-Za-z_])?$
-                              type: string
-                            value:
-                              description: 'value is the value part of the tag. A
-                                tag value can have a maximum of 256 characters and
-                                cannot be empty. Value must contain only alphanumeric
-                                characters and the following special characters `_
-                                + , - . / : ; < = > ? @`.'
-                              maxLength: 256
-                              minLength: 1
-                              pattern: ^[0-9A-Za-z_.=+-@]+$
-                              type: string
-                          required:
-                          - key
-                          - value
-                          type: object
-                        maxItems: 10
-                        type: array
-                        x-kubernetes-list-type: atomic
-                        x-kubernetes-validations:
-                        - message: resourceTags are immutable and may only be configured
-                            during installation
-                          rule: self.all(x, x in oldSelf) && oldSelf.all(x, x in self)
-                    type: object
-                    x-kubernetes-validations:
-                    - message: resourceTags may only be configured during installation
-                      rule: '!has(oldSelf.resourceTags) && !has(self.resourceTags)
-                        || has(oldSelf.resourceTags) && has(self.resourceTags)'
-                  baremetal:
-                    description: BareMetal contains settings specific to the BareMetal
-                      platform.
-                    properties:
-                      apiServerInternalIP:
-                        description: "apiServerInternalIP is an IP address to contact
-                          the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. It is the IP that the
-                          Infrastructure.status.apiServerInternalURI points to. It
-                          is the IP for a self-hosted load balancer in front of the
-                          API servers. \n Deprecated: Use APIServerInternalIPs instead."
-                        type: string
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IPs otherwise
-                          only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      ingressIP:
-                        description: "ingressIP is an external IP which routes to
-                          the default ingress controller. The IP is a suitable target
-                          of a wildcard DNS record used to resolve default route host
-                          names. \n Deprecated: Use IngressIPs instead."
-                        type: string
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IPs
-                          otherwise only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      loadBalancer:
-                        default:
-                          type: OpenShiftManagedDefault
-                        description: loadBalancer defines how the load balancer used
-                          by the cluster is configured.
-                        properties:
-                          type:
-                            default: OpenShiftManagedDefault
-                            description: type defines the type of load balancer used
-                              by the cluster on BareMetal platform which can be a
-                              user-managed or openshift-managed load balancer that
-                              is to be used for the OpenShift API and Ingress endpoints.
-                              When set to OpenShiftManagedDefault the static pods
-                              in charge of API and Ingress traffic load-balancing
-                              defined in the machine config operator will be deployed.
-                              When set to UserManaged these static pods will not be
-                              deployed and it is expected that the load balancer is
-                              configured out of band by the deployer. When omitted,
-                              this means no opinion and the platform is left to choose
-                              a reasonable default. The default value is OpenShiftManagedDefault.
-                            enum:
-                            - OpenShiftManagedDefault
-                            - UserManaged
-                            type: string
-                            x-kubernetes-validations:
-                            - message: type is immutable once set
-                              rule: oldSelf == '' || self == oldSelf
-                        type: object
-                      machineNetworks:
-                        description: machineNetworks are IP networks used to connect
-                          all the OpenShift cluster nodes.
-                        items:
-                          description: CIDR is an IP address range in CIDR notation
-                            (for example, "10.0.0.0/8" or "fd00::/8").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[0-9]))$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))$)
-                          type: string
-                        maxItems: 32
-                        type: array
-                        x-kubernetes-list-type: set
-                      nodeDNSIP:
-                        description: nodeDNSIP is the IP address for the internal
-                          DNS used by the nodes. Unlike the one managed by the DNS
-                          operator, `NodeDNSIP` provides name resolution for the nodes
-                          themselves. There is no DNS-as-a-service for BareMetal deployments.
-                          In order to minimize necessary changes to the datacenter
-                          DNS, a DNS service is hosted as a static pod to serve those
-                          hostnames to the nodes in the cluster.
-                        type: string
-                    type: object
-                  equinixMetal:
-                    description: EquinixMetal contains settings specific to the Equinix
-                      Metal infrastructure provider.
-                    properties:
-                      apiServerInternalIP:
-                        description: apiServerInternalIP is an IP address to contact
-                          the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. It is the IP that the
-                          Infrastructure.status.apiServerInternalURI points to. It
-                          is the IP for a self-hosted load balancer in front of the
-                          API servers.
-                        type: string
-                      ingressIP:
-                        description: ingressIP is an external IP which routes to the
-                          default ingress controller. The IP is a suitable target
-                          of a wildcard DNS record used to resolve default route host
-                          names.
-                        type: string
-                    type: object
-                  external:
-                    description: External contains settings specific to the generic
-                      External infrastructure provider.
-                    properties:
-                      cloudControllerManager:
-                        description: cloudControllerManager contains settings specific
-                          to the external Cloud Controller Manager (a.k.a. CCM or
-                          CPI). When omitted, new nodes will be not tainted and no
-                          extra initialization from the cloud controller manager is
-                          expected.
-                        properties:
-                          state:
-                            description: "state determines whether or not an external
-                              Cloud Controller Manager is expected to be installed
-                              within the cluster. https://kubernetes.io/docs/tasks/administer-cluster/running-cloud-controller/#running-cloud-controller-manager
-                              \n Valid values are \"External\", \"None\" and omitted.
-                              When set to \"External\", new nodes will be tainted
-                              as uninitialized when created, preventing them from
-                              running workloads until they are initialized by the
-                              cloud controller manager. When omitted or set to \"None\",
-                              new nodes will be not tainted and no extra initialization
-                              from the cloud controller manager is expected."
-                            enum:
-                            - ""
-                            - External
-                            - None
-                            type: string
-                            x-kubernetes-validations:
-                            - message: state is immutable once set
-                              rule: self == oldSelf
-                        type: object
-                        x-kubernetes-validations:
-                        - message: state may not be added or removed once set
-                          rule: (has(self.state) == has(oldSelf.state)) || (!has(oldSelf.state)
-                            && self.state != "External")
-                    type: object
-                    x-kubernetes-validations:
-                    - message: cloudControllerManager may not be added or removed
-                        once set
-                      rule: has(self.cloudControllerManager) == has(oldSelf.cloudControllerManager)
-                  gcp:
-                    description: GCP contains settings specific to the Google Cloud
-                      Platform infrastructure provider.
-                    properties:
-                      cloudLoadBalancerConfig:
-                        default:
-                          dnsType: PlatformDefault
-                        description: cloudLoadBalancerConfig is a union that contains
-                          the IP addresses of API, API-Int and Ingress Load Balancers
-                          created on the cloud platform. These values would not be
-                          populated on on-prem platforms. These Load Balancer IPs
-                          are used to configure the in-cluster DNS instances for API,
-                          API-Int and Ingress services. `dnsType` is expected to be
-                          set to `ClusterHosted` when these Load Balancer IP addresses
-                          are populated and used.
-                        nullable: true
-                        properties:
-                          clusterHosted:
-                            description: clusterHosted holds the IP addresses of API,
-                              API-Int and Ingress Load Balancers on Cloud Platforms.
-                              The DNS solution hosted within the cluster use these
-                              IP addresses to provide resolution for API, API-Int
-                              and Ingress services.
-                            properties:
-                              apiIntLoadBalancerIPs:
-                                description: apiIntLoadBalancerIPs holds Load Balancer
-                                  IPs for the internal API service. These Load Balancer
-                                  IP addresses can be IPv4 and/or IPv6 addresses.
-                                  Entries in the apiIntLoadBalancerIPs must be unique.
-                                  A maximum of 16 IP addresses are permitted.
-                                format: ip
-                                items:
-                                  description: IP is an IP address (for example, "10.0.0.0"
-                                    or "fd00::").
-                                  pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                                  type: string
-                                maxItems: 16
-                                type: array
-                                x-kubernetes-list-type: set
-                              apiLoadBalancerIPs:
-                                description: apiLoadBalancerIPs holds Load Balancer
-                                  IPs for the API service. These Load Balancer IP
-                                  addresses can be IPv4 and/or IPv6 addresses. Could
-                                  be empty for private clusters. Entries in the apiLoadBalancerIPs
-                                  must be unique. A maximum of 16 IP addresses are
-                                  permitted.
-                                format: ip
-                                items:
-                                  description: IP is an IP address (for example, "10.0.0.0"
-                                    or "fd00::").
-                                  pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                                  type: string
-                                maxItems: 16
-                                type: array
-                                x-kubernetes-list-type: set
-                              ingressLoadBalancerIPs:
-                                description: ingressLoadBalancerIPs holds IPs for
-                                  Ingress Load Balancers. These Load Balancer IP addresses
-                                  can be IPv4 and/or IPv6 addresses. Entries in the
-                                  ingressLoadBalancerIPs must be unique. A maximum
-                                  of 16 IP addresses are permitted.
-                                format: ip
-                                items:
-                                  description: IP is an IP address (for example, "10.0.0.0"
-                                    or "fd00::").
-                                  pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)
-                                  type: string
-                                maxItems: 16
-                                type: array
-                                x-kubernetes-list-type: set
-                            type: object
-                          dnsType:
-                            default: PlatformDefault
-                            description: dnsType indicates the type of DNS solution
-                              in use within the cluster. Its default value of `PlatformDefault`
-                              indicates that the cluster's DNS is the default provided
-                              by the cloud platform. It can be set to `ClusterHosted`
-                              to bypass the configuration of the cloud default DNS.
-                              In this mode, the cluster needs to provide a self-hosted
-                              DNS solution for the cluster's installation to succeed.
-                              The cluster's use of the cloud's Load Balancers is unaffected
-                              by this setting. The value is immutable after it has
-                              been set at install time. Currently, there is no way
-                              for the customer to add additional DNS entries into
-                              the cluster hosted DNS. Enabling this functionality
-                              allows the user to start their own DNS solution outside
-                              the cluster after installation is complete. The customer
-                              would be responsible for configuring this custom DNS
-                              solution, and it can be run in addition to the in-cluster
-                              DNS solution.
-                            enum:
-                            - ClusterHosted
-                            - PlatformDefault
-                            type: string
-                            x-kubernetes-validations:
-                            - message: dnsType is immutable
-                              rule: oldSelf == '' || self == oldSelf
-                        type: object
-                        x-kubernetes-validations:
-                        - message: clusterHosted is permitted only when dnsType is
-                            ClusterHosted
-                          rule: 'has(self.dnsType) && self.dnsType != ''ClusterHosted''
-                            ? !has(self.clusterHosted) : true'
-                      projectID:
-                        description: resourceGroupName is the Project ID for new GCP
-                          resources created for the cluster.
-                        type: string
-                      region:
-                        description: region holds the region for new GCP resources
-                          created for the cluster.
-                        type: string
-                      resourceLabels:
-                        description: resourceLabels is a list of additional labels
-                          to apply to GCP resources created for the cluster. See https://cloud.google.com/compute/docs/labeling-resources
-                          for information on labeling GCP resources. GCP supports
-                          a maximum of 64 labels per resource. OpenShift reserves
-                          32 labels for internal use, allowing 32 labels for user
-                          configuration.
-                        items:
-                          description: GCPResourceLabel is a label to apply to GCP
-                            resources created for the cluster.
-                          properties:
-                            key:
-                              description: key is the key part of the label. A label
-                                key can have a maximum of 63 characters and cannot
-                                be empty. Label key must begin with a lowercase letter,
-                                and must contain only lowercase letters, numeric characters,
-                                and the following special characters `_-`. Label key
-                                must not have the reserved prefixes `kubernetes-io`
-                                and `openshift-io`.
-                              maxLength: 63
-                              minLength: 1
-                              pattern: ^[a-z][0-9a-z_-]{0,62}$
-                              type: string
-                              x-kubernetes-validations:
-                              - message: label keys must not start with either `openshift-io`
-                                  or `kubernetes-io`
-                                rule: '!self.startsWith(''openshift-io'') && !self.startsWith(''kubernetes-io'')'
-                            value:
-                              description: value is the value part of the label. A
-                                label value can have a maximum of 63 characters and
-                                cannot be empty. Value must contain only lowercase
-                                letters, numeric characters, and the following special
-                                characters `_-`.
-                              maxLength: 63
-                              minLength: 1
-                              pattern: ^[0-9a-z_-]{1,63}$
-                              type: string
-                          required:
-                          - key
-                          - value
-                          type: object
-                        maxItems: 32
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - key
-                        x-kubernetes-list-type: map
-                        x-kubernetes-validations:
-                        - message: resourceLabels are immutable and may only be configured
-                            during installation
-                          rule: self.all(x, x in oldSelf) && oldSelf.all(x, x in self)
-                      resourceTags:
-                        description: resourceTags is a list of additional tags to
-                          apply to GCP resources created for the cluster. See https://cloud.google.com/resource-manager/docs/tags/tags-overview
-                          for information on tagging GCP resources. GCP supports a
-                          maximum of 50 tags per resource.
-                        items:
-                          description: GCPResourceTag is a tag to apply to GCP resources
-                            created for the cluster.
-                          properties:
-                            key:
-                              description: key is the key part of the tag. A tag key
-                                can have a maximum of 63 characters and cannot be
-                                empty. Tag key must begin and end with an alphanumeric
-                                character, and must contain only uppercase, lowercase
-                                alphanumeric characters, and the following special
-                                characters `._-`.
-                              maxLength: 63
-                              minLength: 1
-                              pattern: ^[a-zA-Z0-9]([0-9A-Za-z_.-]{0,61}[a-zA-Z0-9])?$
-                              type: string
-                            parentID:
-                              description: 'parentID is the ID of the hierarchical
-                                resource where the tags are defined, e.g. at the Organization
-                                or the Project level. To find the Organization or
-                                Project ID refer to the following pages: https://cloud.google.com/resource-manager/docs/creating-managing-organization#retrieving_your_organization_id,
-                                https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects.
-                                An OrganizationID must consist of decimal numbers,
-                                and cannot have leading zeroes. A ProjectID must be
-                                6 to 30 characters in length, can only contain lowercase
-                                letters, numbers, and hyphens, and must start with
-                                a letter, and cannot end with a hyphen.'
-                              maxLength: 32
-                              minLength: 1
-                              pattern: (^[1-9][0-9]{0,31}$)|(^[a-z][a-z0-9-]{4,28}[a-z0-9]$)
-                              type: string
-                            value:
-                              description: value is the value part of the tag. A tag
-                                value can have a maximum of 63 characters and cannot
-                                be empty. Tag value must begin and end with an alphanumeric
-                                character, and must contain only uppercase, lowercase
-                                alphanumeric characters, and the following special
-                                characters `_-.@%=+:,*#&(){}[]` and spaces.
-                              maxLength: 63
-                              minLength: 1
-                              pattern: ^[a-zA-Z0-9]([0-9A-Za-z_.@%=+:,*#&()\[\]{}\-\s]{0,61}[a-zA-Z0-9])?$
-                              type: string
-                          required:
-                          - key
-                          - parentID
-                          - value
-                          type: object
-                        maxItems: 50
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - key
-                        x-kubernetes-list-type: map
-                        x-kubernetes-validations:
-                        - message: resourceTags are immutable and may only be configured
-                            during installation
-                          rule: self.all(x, x in oldSelf) && oldSelf.all(x, x in self)
-                    type: object
-                    x-kubernetes-validations:
-                    - message: resourceLabels may only be configured during installation
-                      rule: '!has(oldSelf.resourceLabels) && !has(self.resourceLabels)
-                        || has(oldSelf.resourceLabels) && has(self.resourceLabels)'
-                    - message: resourceTags may only be configured during installation
-                      rule: '!has(oldSelf.resourceTags) && !has(self.resourceTags)
-                        || has(oldSelf.resourceTags) && has(self.resourceTags)'
-                  ibmcloud:
-                    description: IBMCloud contains settings specific to the IBMCloud
-                      infrastructure provider.
-                    properties:
-                      cisInstanceCRN:
-                        description: CISInstanceCRN is the CRN of the Cloud Internet
-                          Services instance managing the DNS zone for the cluster's
-                          base domain
-                        type: string
-                      dnsInstanceCRN:
-                        description: DNSInstanceCRN is the CRN of the DNS Services
-                          instance managing the DNS zone for the cluster's base domain
-                        type: string
-                      location:
-                        description: Location is where the cluster has been deployed
-                        type: string
-                      providerType:
-                        description: ProviderType indicates the type of cluster that
-                          was created
-                        type: string
-                      resourceGroupName:
-                        description: ResourceGroupName is the Resource Group for new
-                          IBMCloud resources created for the cluster.
-                        type: string
-                      serviceEndpoints:
-                        description: serviceEndpoints is a list of custom endpoints
-                          which will override the default service endpoints of an
-                          IBM Cloud service. These endpoints are consumed by components
-                          within the cluster to reach the respective IBM Cloud Services.
-                        items:
-                          description: IBMCloudServiceEndpoint stores the configuration
-                            of a custom url to override existing defaults of IBM Cloud
-                            Services.
-                          properties:
-                            name:
-                              description: 'name is the name of the IBM Cloud service.
-                                Possible values are: CIS, COS, DNSServices, GlobalSearch,
-                                GlobalTagging, HyperProtect, IAM, KeyProtect, ResourceController,
-                                ResourceManager, or VPC. For example, the IBM Cloud
-                                Private IAM service could be configured with the service
-                                `name` of `IAM` and `url` of `https://private.iam.cloud.ibm.com`
-                                Whereas the IBM Cloud Private VPC service for US South
-                                (Dallas) could be configured with the service `name`
-                                of `VPC` and `url` of `https://us.south.private.iaas.cloud.ibm.com`'
-                              enum:
-                              - CIS
-                              - COS
-                              - DNSServices
-                              - GlobalSearch
-                              - GlobalTagging
-                              - HyperProtect
-                              - IAM
-                              - KeyProtect
-                              - ResourceController
-                              - ResourceManager
-                              - VPC
-                              type: string
-                            url:
-                              description: url is fully qualified URI with scheme
-                                https, that overrides the default generated endpoint
-                                for a client. This must be provided and cannot be
-                                empty.
-                              type: string
-                              x-kubernetes-validations:
-                              - message: url must be a valid absolute URL
-                                rule: isURL(self)
-                          required:
-                          - name
-                          - url
-                          type: object
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - name
-                        x-kubernetes-list-type: map
-                    type: object
-                  kubevirt:
-                    description: Kubevirt contains settings specific to the kubevirt
-                      infrastructure provider.
-                    properties:
-                      apiServerInternalIP:
-                        description: apiServerInternalIP is an IP address to contact
-                          the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. It is the IP that the
-                          Infrastructure.status.apiServerInternalURI points to. It
-                          is the IP for a self-hosted load balancer in front of the
-                          API servers.
-                        type: string
-                      ingressIP:
-                        description: ingressIP is an external IP which routes to the
-                          default ingress controller. The IP is a suitable target
-                          of a wildcard DNS record used to resolve default route host
-                          names.
-                        type: string
-                    type: object
-                  nutanix:
-                    description: Nutanix contains settings specific to the Nutanix
-                      infrastructure provider.
-                    properties:
-                      apiServerInternalIP:
-                        description: "apiServerInternalIP is an IP address to contact
-                          the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. It is the IP that the
-                          Infrastructure.status.apiServerInternalURI points to. It
-                          is the IP for a self-hosted load balancer in front of the
-                          API servers. \n Deprecated: Use APIServerInternalIPs instead."
-                        type: string
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IPs otherwise
-                          only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      ingressIP:
-                        description: "ingressIP is an external IP which routes to
-                          the default ingress controller. The IP is a suitable target
-                          of a wildcard DNS record used to resolve default route host
-                          names. \n Deprecated: Use IngressIPs instead."
-                        type: string
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IPs
-                          otherwise only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      loadBalancer:
-                        default:
-                          type: OpenShiftManagedDefault
-                        description: loadBalancer defines how the load balancer used
-                          by the cluster is configured.
-                        properties:
-                          type:
-                            default: OpenShiftManagedDefault
-                            description: type defines the type of load balancer used
-                              by the cluster on Nutanix platform which can be a user-managed
-                              or openshift-managed load balancer that is to be used
-                              for the OpenShift API and Ingress endpoints. When set
-                              to OpenShiftManagedDefault the static pods in charge
-                              of API and Ingress traffic load-balancing defined in
-                              the machine config operator will be deployed. When set
-                              to UserManaged these static pods will not be deployed
-                              and it is expected that the load balancer is configured
-                              out of band by the deployer. When omitted, this means
-                              no opinion and the platform is left to choose a reasonable
-                              default. The default value is OpenShiftManagedDefault.
-                            enum:
-                            - OpenShiftManagedDefault
-                            - UserManaged
-                            type: string
-                            x-kubernetes-validations:
-                            - message: type is immutable once set
-                              rule: oldSelf == '' || self == oldSelf
-                        type: object
-                    type: object
-                  openstack:
-                    description: OpenStack contains settings specific to the OpenStack
-                      infrastructure provider.
-                    properties:
-                      apiServerInternalIP:
-                        description: "apiServerInternalIP is an IP address to contact
-                          the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. It is the IP that the
-                          Infrastructure.status.apiServerInternalURI points to. It
-                          is the IP for a self-hosted load balancer in front of the
-                          API servers. \n Deprecated: Use APIServerInternalIPs instead."
-                        type: string
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IPs otherwise
-                          only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      cloudName:
-                        description: cloudName is the name of the desired OpenStack
-                          cloud in the client configuration file (`clouds.yaml`).
-                        type: string
-                      ingressIP:
-                        description: "ingressIP is an external IP which routes to
-                          the default ingress controller. The IP is a suitable target
-                          of a wildcard DNS record used to resolve default route host
-                          names. \n Deprecated: Use IngressIPs instead."
-                        type: string
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IPs
-                          otherwise only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      loadBalancer:
-                        default:
-                          type: OpenShiftManagedDefault
-                        description: loadBalancer defines how the load balancer used
-                          by the cluster is configured.
-                        properties:
-                          type:
-                            default: OpenShiftManagedDefault
-                            description: type defines the type of load balancer used
-                              by the cluster on OpenStack platform which can be a
-                              user-managed or openshift-managed load balancer that
-                              is to be used for the OpenShift API and Ingress endpoints.
-                              When set to OpenShiftManagedDefault the static pods
-                              in charge of API and Ingress traffic load-balancing
-                              defined in the machine config operator will be deployed.
-                              When set to UserManaged these static pods will not be
-                              deployed and it is expected that the load balancer is
-                              configured out of band by the deployer. When omitted,
-                              this means no opinion and the platform is left to choose
-                              a reasonable default. The default value is OpenShiftManagedDefault.
-                            enum:
-                            - OpenShiftManagedDefault
-                            - UserManaged
-                            type: string
-                            x-kubernetes-validations:
-                            - message: type is immutable once set
-                              rule: oldSelf == '' || self == oldSelf
-                        type: object
-                      machineNetworks:
-                        description: machineNetworks are IP networks used to connect
-                          all the OpenShift cluster nodes.
-                        items:
-                          description: CIDR is an IP address range in CIDR notation
-                            (for example, "10.0.0.0/8" or "fd00::/8").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[0-9]))$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))$)
-                          type: string
-                        maxItems: 32
-                        type: array
-                        x-kubernetes-list-type: set
-                      nodeDNSIP:
-                        description: nodeDNSIP is the IP address for the internal
-                          DNS used by the nodes. Unlike the one managed by the DNS
-                          operator, `NodeDNSIP` provides name resolution for the nodes
-                          themselves. There is no DNS-as-a-service for OpenStack deployments.
-                          In order to minimize necessary changes to the datacenter
-                          DNS, a DNS service is hosted as a static pod to serve those
-                          hostnames to the nodes in the cluster.
-                        type: string
-                    type: object
-                  ovirt:
-                    description: Ovirt contains settings specific to the oVirt infrastructure
-                      provider.
-                    properties:
-                      apiServerInternalIP:
-                        description: "apiServerInternalIP is an IP address to contact
-                          the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. It is the IP that the
-                          Infrastructure.status.apiServerInternalURI points to. It
-                          is the IP for a self-hosted load balancer in front of the
-                          API servers. \n Deprecated: Use APIServerInternalIPs instead."
-                        type: string
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IPs otherwise
-                          only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      ingressIP:
-                        description: "ingressIP is an external IP which routes to
-                          the default ingress controller. The IP is a suitable target
-                          of a wildcard DNS record used to resolve default route host
-                          names. \n Deprecated: Use IngressIPs instead."
-                        type: string
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IPs
-                          otherwise only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      loadBalancer:
-                        default:
-                          type: OpenShiftManagedDefault
-                        description: loadBalancer defines how the load balancer used
-                          by the cluster is configured.
-                        properties:
-                          type:
-                            default: OpenShiftManagedDefault
-                            description: type defines the type of load balancer used
-                              by the cluster on Ovirt platform which can be a user-managed
-                              or openshift-managed load balancer that is to be used
-                              for the OpenShift API and Ingress endpoints. When set
-                              to OpenShiftManagedDefault the static pods in charge
-                              of API and Ingress traffic load-balancing defined in
-                              the machine config operator will be deployed. When set
-                              to UserManaged these static pods will not be deployed
-                              and it is expected that the load balancer is configured
-                              out of band by the deployer. When omitted, this means
-                              no opinion and the platform is left to choose a reasonable
-                              default. The default value is OpenShiftManagedDefault.
-                            enum:
-                            - OpenShiftManagedDefault
-                            - UserManaged
-                            type: string
-                            x-kubernetes-validations:
-                            - message: type is immutable once set
-                              rule: oldSelf == '' || self == oldSelf
-                        type: object
-                      nodeDNSIP:
-                        description: 'deprecated: as of 4.6, this field is no longer
-                          set or honored.  It will be removed in a future release.'
-                        type: string
-                    type: object
-                  powervs:
-                    description: PowerVS contains settings specific to the Power Systems
-                      Virtual Servers infrastructure provider.
-                    properties:
-                      cisInstanceCRN:
-                        description: CISInstanceCRN is the CRN of the Cloud Internet
-                          Services instance managing the DNS zone for the cluster's
-                          base domain
-                        type: string
-                      dnsInstanceCRN:
-                        description: DNSInstanceCRN is the CRN of the DNS Services
-                          instance managing the DNS zone for the cluster's base domain
-                        type: string
-                      region:
-                        description: region holds the default Power VS region for
-                          new Power VS resources created by the cluster.
-                        type: string
-                      resourceGroup:
-                        description: 'resourceGroup is the resource group name for
-                          new IBMCloud resources created for a cluster. The resource
-                          group specified here will be used by cluster-image-registry-operator
-                          to set up a COS Instance in IBMCloud for the cluster registry.
-                          More about resource groups can be found here: https://cloud.ibm.com/docs/account?topic=account-rgs.
-                          When omitted, the image registry operator won''t be able
-                          to configure storage, which results in the image registry
-                          cluster operator not being in an available state.'
-                        maxLength: 40
-                        pattern: ^[a-zA-Z0-9-_ ]+$
-                        type: string
-                        x-kubernetes-validations:
-                        - message: resourceGroup is immutable once set
-                          rule: oldSelf == '' || self == oldSelf
-                      serviceEndpoints:
-                        description: serviceEndpoints is a list of custom endpoints
-                          which will override the default service endpoints of a Power
-                          VS service.
-                        items:
-                          description: PowervsServiceEndpoint stores the configuration
-                            of a custom url to override existing defaults of PowerVS
-                            Services.
-                          properties:
-                            name:
-                              description: name is the name of the Power VS service.
-                                Few of the services are IAM - https://cloud.ibm.com/apidocs/iam-identity-token-api
-                                ResourceController - https://cloud.ibm.com/apidocs/resource-controller/resource-controller
-                                Power Cloud - https://cloud.ibm.com/apidocs/power-cloud
-                              pattern: ^[a-z0-9-]+$
-                              type: string
-                            url:
-                              description: url is fully qualified URI with scheme
-                                https, that overrides the default generated endpoint
-                                for a client. This must be provided and cannot be
-                                empty.
-                              format: uri
-                              pattern: ^https://
-                              type: string
-                          required:
-                          - name
-                          - url
-                          type: object
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - name
-                        x-kubernetes-list-type: map
-                      zone:
-                        description: 'zone holds the default zone for the new Power
-                          VS resources created by the cluster. Note: Currently only
-                          single-zone OCP clusters are supported'
-                        type: string
-                    type: object
-                    x-kubernetes-validations:
-                    - message: cannot unset resourceGroup once set
-                      rule: '!has(oldSelf.resourceGroup) || has(self.resourceGroup)'
-                  type:
-                    description: "type is the underlying infrastructure provider for
-                      the cluster. This value controls whether infrastructure automation
-                      such as service load balancers, dynamic volume provisioning,
-                      machine creation and deletion, and other integrations are enabled.
-                      If None, no infrastructure automation is enabled. Allowed values
-                      are \"AWS\", \"Azure\", \"BareMetal\", \"GCP\", \"Libvirt\",
-                      \"OpenStack\", \"VSphere\", \"oVirt\", \"EquinixMetal\", \"PowerVS\",
-                      \"AlibabaCloud\", \"Nutanix\" and \"None\". Individual components
-                      may not support all platforms, and must handle unrecognized
-                      platforms as None if they do not support that platform. \n This
-                      value will be synced with to the `status.platform` and `status.platformStatus.type`.
-                      Currently this value cannot be changed once set."
-                    enum:
-                    - ""
-                    - AWS
-                    - Azure
-                    - BareMetal
-                    - GCP
-                    - Libvirt
-                    - OpenStack
-                    - None
-                    - VSphere
-                    - oVirt
-                    - IBMCloud
-                    - KubeVirt
-                    - EquinixMetal
-                    - PowerVS
-                    - AlibabaCloud
-                    - Nutanix
-                    - External
-                    type: string
-                  vsphere:
-                    description: VSphere contains settings specific to the VSphere
-                      infrastructure provider.
-                    properties:
-                      apiServerInternalIP:
-                        description: "apiServerInternalIP is an IP address to contact
-                          the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. It is the IP that the
-                          Infrastructure.status.apiServerInternalURI points to. It
-                          is the IP for a self-hosted load balancer in front of the
-                          API servers. \n Deprecated: Use APIServerInternalIPs instead."
-                        type: string
-                      apiServerInternalIPs:
-                        description: apiServerInternalIPs are the IP addresses to
-                          contact the Kubernetes API server that can be used by components
-                          inside the cluster, like kubelets using the infrastructure
-                          rather than Kubernetes networking. These are the IPs for
-                          a self-hosted load balancer in front of the API servers.
-                          In dual stack clusters this list contains two IPs otherwise
-                          only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      ingressIP:
-                        description: "ingressIP is an external IP which routes to
-                          the default ingress controller. The IP is a suitable target
-                          of a wildcard DNS record used to resolve default route host
-                          names. \n Deprecated: Use IngressIPs instead."
-                        type: string
-                      ingressIPs:
-                        description: ingressIPs are the external IPs which route to
-                          the default ingress controller. The IPs are suitable targets
-                          of a wildcard DNS record used to resolve default route host
-                          names. In dual stack clusters this list contains two IPs
-                          otherwise only one.
-                        format: ip
-                        items:
-                          type: string
-                        maxItems: 2
-                        type: array
-                        x-kubernetes-list-type: set
-                      loadBalancer:
-                        default:
-                          type: OpenShiftManagedDefault
-                        description: loadBalancer defines how the load balancer used
-                          by the cluster is configured.
-                        properties:
-                          type:
-                            default: OpenShiftManagedDefault
-                            description: type defines the type of load balancer used
-                              by the cluster on VSphere platform which can be a user-managed
-                              or openshift-managed load balancer that is to be used
-                              for the OpenShift API and Ingress endpoints. When set
-                              to OpenShiftManagedDefault the static pods in charge
-                              of API and Ingress traffic load-balancing defined in
-                              the machine config operator will be deployed. When set
-                              to UserManaged these static pods will not be deployed
-                              and it is expected that the load balancer is configured
-                              out of band by the deployer. When omitted, this means
-                              no opinion and the platform is left to choose a reasonable
-                              default. The default value is OpenShiftManagedDefault.
-                            enum:
-                            - OpenShiftManagedDefault
-                            - UserManaged
-                            type: string
-                            x-kubernetes-validations:
-                            - message: type is immutable once set
-                              rule: oldSelf == '' || self == oldSelf
-                        type: object
-                      machineNetworks:
-                        description: machineNetworks are IP networks used to connect
-                          all the OpenShift cluster nodes.
-                        items:
-                          description: CIDR is an IP address range in CIDR notation
-                            (for example, "10.0.0.0/8" or "fd00::/8").
-                          pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[0-9]))$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))$)
-                          type: string
-                        maxItems: 32
-                        type: array
-                        x-kubernetes-list-type: set
-                      nodeDNSIP:
-                        description: nodeDNSIP is the IP address for the internal
-                          DNS used by the nodes. Unlike the one managed by the DNS
-                          operator, `NodeDNSIP` provides name resolution for the nodes
-                          themselves. There is no DNS-as-a-service for vSphere deployments.
-                          In order to minimize necessary changes to the datacenter
-                          DNS, a DNS service is hosted as a static pod to serve those
-                          hostnames to the nodes in the cluster.
-                        type: string
-                    type: object
-                type: object
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-TechPreviewNoUpgrade.crd.yaml-patch b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-TechPreviewNoUpgrade.crd.yaml-patch
deleted file mode 100644
index d127130a..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-TechPreviewNoUpgrade.crd.yaml-patch
+++ /dev/null
@@ -1,24 +0,0 @@
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/vcenters/items/properties/server/anyOf
-  value:
-    - format: ipv4
-    - format: ipv6
-    - format: hostname
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/failureDomains/items/properties/server/anyOf
-  value:
-    - format: ipv4
-    - format: ipv6
-    - format: hostname
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/nodeNetworking/properties/external/properties/excludeNetworkSubnetCidr/items/format
-  value: cidr
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/nodeNetworking/properties/external/properties/networkSubnetCidr/items/format
-  value: cidr
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/nodeNetworking/properties/internal/properties/excludeNetworkSubnetCidr/items/format
-  value: cidr
-- op: add
-  path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/platformSpec/properties/vsphere/properties/nodeNetworking/properties/internal/properties/networkSubnetCidr/items/format
-  value: cidr
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_ingress.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_ingress.crd.yaml
deleted file mode 100644
index c582dccb..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_ingress.crd.yaml
+++ /dev/null
@@ -1,553 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-  name: ingresses.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: Ingress
-    listKind: IngressList
-    plural: ingresses
-    singular: ingress
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "Ingress holds cluster-wide information about ingress, including
-          the default ingress domain used for routes. The canonical name is `cluster`.
-          \n Compatibility level 1: Stable within a major release for a minimum of
-          12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              appsDomain:
-                description: appsDomain is an optional domain to use instead of the
-                  one specified in the domain field when a Route is created without
-                  specifying an explicit host. If appsDomain is nonempty, this value
-                  is used to generate default host values for Route. Unlike domain,
-                  appsDomain may be modified after installation. This assumes a new
-                  ingresscontroller has been setup with a wildcard certificate.
-                type: string
-              componentRoutes:
-                description: "componentRoutes is an optional list of routes that are
-                  managed by OpenShift components that a cluster-admin is able to
-                  configure the hostname and serving certificate for. The namespace
-                  and name of each route in this list should match an existing entry
-                  in the status.componentRoutes list. \n To determine the set of configurable
-                  Routes, look at namespace and name of entries in the .status.componentRoutes
-                  list, where participating operators write the status of configurable
-                  routes."
-                items:
-                  description: ComponentRouteSpec allows for configuration of a route's
-                    hostname and serving certificate.
-                  properties:
-                    hostname:
-                      description: hostname is the hostname that should be used by
-                        the route.
-                      pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$
-                      type: string
-                    name:
-                      description: "name is the logical name of the route to customize.
-                        \n The namespace and name of this componentRoute must match
-                        a corresponding entry in the list of status.componentRoutes
-                        if the route is to be customized."
-                      maxLength: 256
-                      minLength: 1
-                      type: string
-                    namespace:
-                      description: "namespace is the namespace of the route to customize.
-                        \n The namespace and name of this componentRoute must match
-                        a corresponding entry in the list of status.componentRoutes
-                        if the route is to be customized."
-                      maxLength: 63
-                      minLength: 1
-                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
-                      type: string
-                    servingCertKeyPairSecret:
-                      description: servingCertKeyPairSecret is a reference to a secret
-                        of type `kubernetes.io/tls` in the openshift-config namespace.
-                        The serving cert/key pair must match and will be used by the
-                        operator to fulfill the intent of serving with this name.
-                        If the custom hostname uses the default routing suffix of
-                        the cluster, the Secret specification for a serving certificate
-                        will not be needed.
-                      properties:
-                        name:
-                          description: name is the metadata.name of the referenced
-                            secret
-                          type: string
-                      required:
-                      - name
-                      type: object
-                  required:
-                  - hostname
-                  - name
-                  - namespace
-                  type: object
-                type: array
-                x-kubernetes-list-map-keys:
-                - namespace
-                - name
-                x-kubernetes-list-type: map
-              domain:
-                description: "domain is used to generate a default host name for a
-                  route when the route's host name is empty. The generated host name
-                  will follow this pattern: \"<route-name>.<route-namespace>.<domain>\".
-                  \n It is also used as the default wildcard domain suffix for ingress.
-                  The default ingresscontroller domain will follow this pattern: \"*.<domain>\".
-                  \n Once set, changing domain is not currently supported."
-                type: string
-              loadBalancer:
-                description: loadBalancer contains the load balancer details in general
-                  which are not only specific to the underlying infrastructure provider
-                  of the current cluster and are required for Ingress Controller to
-                  work on OpenShift.
-                properties:
-                  platform:
-                    description: platform holds configuration specific to the underlying
-                      infrastructure provider for the ingress load balancers. When
-                      omitted, this means the user has no opinion and the platform
-                      is left to choose reasonable defaults. These defaults are subject
-                      to change over time.
-                    properties:
-                      aws:
-                        description: aws contains settings specific to the Amazon
-                          Web Services infrastructure provider.
-                        properties:
-                          type:
-                            description: "type allows user to set a load balancer
-                              type. When this field is set the default ingresscontroller
-                              will get created using the specified LBType. If this
-                              field is not set then the default ingress controller
-                              of LBType Classic will be created. Valid values are:
-                              \n * \"Classic\": A Classic Load Balancer that makes
-                              routing decisions at either the transport layer (TCP/SSL)
-                              or the application layer (HTTP/HTTPS). See the following
-                              for additional details: \n https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#clb
-                              \n * \"NLB\": A Network Load Balancer that makes routing
-                              decisions at the transport layer (TCP/SSL). See the
-                              following for additional details: \n https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#nlb"
-                            enum:
-                            - NLB
-                            - Classic
-                            type: string
-                        required:
-                        - type
-                        type: object
-                      type:
-                        description: type is the underlying infrastructure provider
-                          for the cluster. Allowed values are "AWS", "Azure", "BareMetal",
-                          "GCP", "Libvirt", "OpenStack", "VSphere", "oVirt", "KubeVirt",
-                          "EquinixMetal", "PowerVS", "AlibabaCloud", "Nutanix" and
-                          "None". Individual components may not support all platforms,
-                          and must handle unrecognized platforms as None if they do
-                          not support that platform.
-                        enum:
-                        - ""
-                        - AWS
-                        - Azure
-                        - BareMetal
-                        - GCP
-                        - Libvirt
-                        - OpenStack
-                        - None
-                        - VSphere
-                        - oVirt
-                        - IBMCloud
-                        - KubeVirt
-                        - EquinixMetal
-                        - PowerVS
-                        - AlibabaCloud
-                        - Nutanix
-                        - External
-                        type: string
-                    type: object
-                type: object
-              requiredHSTSPolicies:
-                description: "requiredHSTSPolicies specifies HSTS policies that are
-                  required to be set on newly created  or updated routes matching
-                  the domainPattern/s and namespaceSelector/s that are specified in
-                  the policy. Each requiredHSTSPolicy must have at least a domainPattern
-                  and a maxAge to validate a route HSTS Policy route annotation, and
-                  affect route admission. \n A candidate route is checked for HSTS
-                  Policies if it has the HSTS Policy route annotation: \"haproxy.router.openshift.io/hsts_header\"
-                  E.g. haproxy.router.openshift.io/hsts_header: max-age=31536000;preload;includeSubDomains
-                  \n - For each candidate route, if it matches a requiredHSTSPolicy
-                  domainPattern and optional namespaceSelector, then the maxAge, preloadPolicy,
-                  and includeSubdomainsPolicy must be valid to be admitted.  Otherwise,
-                  the route is rejected. - The first match, by domainPattern and optional
-                  namespaceSelector, in the ordering of the RequiredHSTSPolicies determines
-                  the route's admission status. - If the candidate route doesn't match
-                  any requiredHSTSPolicy domainPattern and optional namespaceSelector,
-                  then it may use any HSTS Policy annotation. \n The HSTS policy configuration
-                  may be changed after routes have already been created. An update
-                  to a previously admitted route may then fail if the updated route
-                  does not conform to the updated HSTS policy configuration. However,
-                  changing the HSTS policy configuration will not cause a route that
-                  is already admitted to stop working. \n Note that if there are no
-                  RequiredHSTSPolicies, any HSTS Policy annotation on the route is
-                  valid."
-                items:
-                  properties:
-                    domainPatterns:
-                      description: "domainPatterns is a list of domains for which
-                        the desired HSTS annotations are required. If domainPatterns
-                        is specified and a route is created with a spec.host matching
-                        one of the domains, the route must specify the HSTS Policy
-                        components described in the matching RequiredHSTSPolicy. \n
-                        The use of wildcards is allowed like this: *.foo.com matches
-                        everything under foo.com. foo.com only matches foo.com, so
-                        to cover foo.com and everything under it, you must specify
-                        *both*."
-                      items:
-                        type: string
-                      minItems: 1
-                      type: array
-                    includeSubDomainsPolicy:
-                      description: 'includeSubDomainsPolicy means the HSTS Policy
-                        should apply to any subdomains of the host''s domain name.  Thus,
-                        for the host bar.foo.com, if includeSubDomainsPolicy was set
-                        to RequireIncludeSubDomains: - the host app.bar.foo.com would
-                        inherit the HSTS Policy of bar.foo.com - the host bar.foo.com
-                        would inherit the HSTS Policy of bar.foo.com - the host foo.com
-                        would NOT inherit the HSTS Policy of bar.foo.com - the host
-                        def.foo.com would NOT inherit the HSTS Policy of bar.foo.com'
-                      enum:
-                      - RequireIncludeSubDomains
-                      - RequireNoIncludeSubDomains
-                      - NoOpinion
-                      type: string
-                    maxAge:
-                      description: maxAge is the delta time range in seconds during
-                        which hosts are regarded as HSTS hosts. If set to 0, it negates
-                        the effect, and hosts are removed as HSTS hosts. If set to
-                        0 and includeSubdomains is specified, all subdomains of the
-                        host are also removed as HSTS hosts. maxAge is a time-to-live
-                        value, and if this policy is not refreshed on a client, the
-                        HSTS policy will eventually expire on that client.
-                      properties:
-                        largestMaxAge:
-                          description: The largest allowed value (in seconds) of the
-                            RequiredHSTSPolicy max-age This value can be left unspecified,
-                            in which case no upper limit is enforced.
-                          format: int32
-                          maximum: 2147483647
-                          minimum: 0
-                          type: integer
-                        smallestMaxAge:
-                          description: The smallest allowed value (in seconds) of
-                            the RequiredHSTSPolicy max-age Setting max-age=0 allows
-                            the deletion of an existing HSTS header from a host.  This
-                            is a necessary tool for administrators to quickly correct
-                            mistakes. This value can be left unspecified, in which
-                            case no lower limit is enforced.
-                          format: int32
-                          maximum: 2147483647
-                          minimum: 0
-                          type: integer
-                      type: object
-                    namespaceSelector:
-                      description: namespaceSelector specifies a label selector such
-                        that the policy applies only to those routes that are in namespaces
-                        with labels that match the selector, and are in one of the
-                        DomainPatterns. Defaults to the empty LabelSelector, which
-                        matches everything.
-                      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
-                      x-kubernetes-map-type: atomic
-                    preloadPolicy:
-                      description: preloadPolicy directs the client to include hosts
-                        in its host preload list so that it never needs to do an initial
-                        load to get the HSTS header (note that this is not defined
-                        in RFC 6797 and is therefore client implementation-dependent).
-                      enum:
-                      - RequirePreload
-                      - RequireNoPreload
-                      - NoOpinion
-                      type: string
-                  required:
-                  - domainPatterns
-                  type: object
-                type: array
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            properties:
-              componentRoutes:
-                description: componentRoutes is where participating operators place
-                  the current route status for routes whose hostnames and serving
-                  certificates can be customized by the cluster-admin.
-                items:
-                  description: ComponentRouteStatus contains information allowing
-                    configuration of a route's hostname and serving certificate.
-                  properties:
-                    conditions:
-                      description: "conditions are used to communicate the state of
-                        the componentRoutes entry. \n Supported conditions include
-                        Available, Degraded and Progressing. \n If available is true,
-                        the content served by the route can be accessed by users.
-                        This includes cases where a default may continue to serve
-                        content while the customized route specified by the cluster-admin
-                        is being configured. \n If Degraded is true, that means something
-                        has gone wrong trying to handle the componentRoutes entry.
-                        The currentHostnames field may or may not be in effect. \n
-                        If Progressing is true, that means the component is taking
-                        some action related to the componentRoutes entry."
-                      items:
-                        description: "Condition contains details for one aspect of
-                          the current state of this API Resource. --- This struct
-                          is intended for direct use as an array at the field path
-                          .status.conditions.  For example, \n type FooStatus struct{
-                          // Represents the observations of a foo's current state.
-                          // Known .status.conditions.type are: \"Available\", \"Progressing\",
-                          and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
-                          // +listType=map // +listMapKey=type Conditions []metav1.Condition
-                          `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
-                          protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields
-                          }"
-                        properties:
-                          lastTransitionTime:
-                            description: lastTransitionTime is the last time the condition
-                              transitioned from one status to another. This should
-                              be when the underlying condition changed.  If that is
-                              not known, then using the time when the API field changed
-                              is acceptable.
-                            format: date-time
-                            type: string
-                          message:
-                            description: message is a human readable message indicating
-                              details about the transition. This may be an empty string.
-                            maxLength: 32768
-                            type: string
-                          observedGeneration:
-                            description: observedGeneration represents the .metadata.generation
-                              that the condition was set based upon. For instance,
-                              if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration
-                              is 9, the condition is out of date with respect to the
-                              current state of the instance.
-                            format: int64
-                            minimum: 0
-                            type: integer
-                          reason:
-                            description: reason contains a programmatic identifier
-                              indicating the reason for the condition's last transition.
-                              Producers of specific condition types may define expected
-                              values and meanings for this field, and whether the
-                              values are considered a guaranteed API. The value should
-                              be a CamelCase string. This field may not be empty.
-                            maxLength: 1024
-                            minLength: 1
-                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
-                            type: string
-                          status:
-                            description: status of the condition, one of True, False,
-                              Unknown.
-                            enum:
-                            - "True"
-                            - "False"
-                            - Unknown
-                            type: string
-                          type:
-                            description: type of condition in CamelCase or in foo.example.com/CamelCase.
-                              --- Many .condition.type values are consistent across
-                              resources like Available, but because arbitrary conditions
-                              can be useful (see .node.status.conditions), the ability
-                              to deconflict is important. The regex it matches is
-                              (dns1123SubdomainFmt/)?(qualifiedNameFmt)
-                            maxLength: 316
-                            pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
-                            type: string
-                        required:
-                        - lastTransitionTime
-                        - message
-                        - reason
-                        - status
-                        - type
-                        type: object
-                      type: array
-                      x-kubernetes-list-map-keys:
-                      - type
-                      x-kubernetes-list-type: map
-                    consumingUsers:
-                      description: consumingUsers is a slice of ServiceAccounts that
-                        need to have read permission on the servingCertKeyPairSecret
-                        secret.
-                      items:
-                        description: ConsumingUser is an alias for string which we
-                          add validation to. Currently only service accounts are supported.
-                        maxLength: 512
-                        minLength: 1
-                        pattern: ^system:serviceaccount:[a-z0-9]([-a-z0-9]*[a-z0-9])?:[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
-                        type: string
-                      maxItems: 5
-                      type: array
-                    currentHostnames:
-                      description: currentHostnames is the list of current names used
-                        by the route. Typically, this list should consist of a single
-                        hostname, but if multiple hostnames are supported by the route
-                        the operator may write multiple entries to this list.
-                      items:
-                        description: "Hostname is an alias for hostname string validation.
-                          \n The left operand of the | is the original kubebuilder
-                          hostname validation format, which is incorrect because it
-                          allows upper case letters, disallows hyphen or number in
-                          the TLD, and allows labels to start/end in non-alphanumeric
-                          characters.  See https://bugzilla.redhat.com/show_bug.cgi?id=2039256.
-                          ^([a-zA-Z0-9\\p{S}\\p{L}]((-?[a-zA-Z0-9\\p{S}\\p{L}]{0,62})?)|([a-zA-Z0-9\\p{S}\\p{L}](([a-zA-Z0-9-\\p{S}\\p{L}]{0,61}[a-zA-Z0-9\\p{S}\\p{L}])?)(\\.)){1,}([a-zA-Z\\p{L}]){2,63})$
-                          \n The right operand of the | is a new pattern that mimics
-                          the current API route admission validation on hostname,
-                          except that it allows hostnames longer than the maximum
-                          length: ^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$
-                          \n Both operand patterns are made available so that modifications
-                          on ingress spec can still happen after an invalid hostname
-                          was saved via validation by the incorrect left operand of
-                          the | operator."
-                        pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$
-                        type: string
-                      minItems: 1
-                      type: array
-                    defaultHostname:
-                      description: defaultHostname is the hostname of this route prior
-                        to customization.
-                      pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$
-                      type: string
-                    name:
-                      description: "name is the logical name of the route to customize.
-                        It does not have to be the actual name of a route resource
-                        but it cannot be renamed. \n The namespace and name of this
-                        componentRoute must match a corresponding entry in the list
-                        of spec.componentRoutes if the route is to be customized."
-                      maxLength: 256
-                      minLength: 1
-                      type: string
-                    namespace:
-                      description: "namespace is the namespace of the route to customize.
-                        It must be a real namespace. Using an actual namespace ensures
-                        that no two components will conflict and the same component
-                        can be installed multiple times. \n The namespace and name
-                        of this componentRoute must match a corresponding entry in
-                        the list of spec.componentRoutes if the route is to be customized."
-                      maxLength: 63
-                      minLength: 1
-                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
-                      type: string
-                    relatedObjects:
-                      description: relatedObjects is a list of resources which are
-                        useful when debugging or inspecting how spec.componentRoutes
-                        is applied.
-                      items:
-                        description: ObjectReference contains enough information to
-                          let you inspect or modify the referred object.
-                        properties:
-                          group:
-                            description: group of the referent.
-                            type: string
-                          name:
-                            description: name of the referent.
-                            type: string
-                          namespace:
-                            description: namespace of the referent.
-                            type: string
-                          resource:
-                            description: resource of the referent.
-                            type: string
-                        required:
-                        - group
-                        - name
-                        - resource
-                        type: object
-                      minItems: 1
-                      type: array
-                  required:
-                  - defaultHostname
-                  - name
-                  - namespace
-                  - relatedObjects
-                  type: object
-                type: array
-                x-kubernetes-list-map-keys:
-                - namespace
-                - name
-                x-kubernetes-list-type: map
-              defaultPlacement:
-                description: "defaultPlacement is set at installation time to control
-                  which nodes will host the ingress router pods by default. The options
-                  are control-plane nodes or worker nodes. \n This field works by
-                  dictating how the Cluster Ingress Operator will consider unset replicas
-                  and nodePlacement fields in IngressController resources when creating
-                  the corresponding Deployments. \n See the documentation for the
-                  IngressController replicas and nodePlacement fields for more information.
-                  \n When omitted, the default value is Workers"
-                enum:
-                - ControlPlane
-                - Workers
-                - ""
-                type: string
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_network-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_network-CustomNoUpgrade.crd.yaml
deleted file mode 100644
index 5392f14c..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_network-CustomNoUpgrade.crd.yaml
+++ /dev/null
@@ -1,284 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    release.openshift.io/feature-set: CustomNoUpgrade
-  name: networks.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: Network
-    listKind: NetworkList
-    plural: networks
-    singular: network
-  preserveUnknownFields: false
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "Network holds cluster-wide information about Network. The canonical
-          name is `cluster`. It is used to configure the desired network configuration,
-          such as: IP address pools for services/pod IPs, network plugin, etc. Please
-          view network.spec for an explanation on what applies when configuring this
-          resource. \n Compatibility level 1: Stable within a major release for a
-          minimum of 12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration. As a general
-              rule, this SHOULD NOT be read directly. Instead, you should consume
-              the NetworkStatus, as it indicates the currently deployed configuration.
-              Currently, most spec fields are immutable after installation. Please
-              view the individual ones for further details on each.
-            properties:
-              clusterNetwork:
-                description: IP address pool to use for pod IPs. This field is immutable
-                  after installation.
-                items:
-                  description: ClusterNetworkEntry is a contiguous block of IP addresses
-                    from which pod IPs are allocated.
-                  properties:
-                    cidr:
-                      description: The complete block for pod IPs.
-                      type: string
-                    hostPrefix:
-                      description: The size (prefix) of block to allocate to each
-                        node. If this field is not used by the plugin, it can be left
-                        unset.
-                      format: int32
-                      minimum: 0
-                      type: integer
-                  type: object
-                type: array
-              externalIP:
-                description: externalIP defines configuration for controllers that
-                  affect Service.ExternalIP. If nil, then ExternalIP is not allowed
-                  to be set.
-                properties:
-                  autoAssignCIDRs:
-                    description: autoAssignCIDRs is a list of CIDRs from which to
-                      automatically assign Service.ExternalIP. These are assigned
-                      when the service is of type LoadBalancer. In general, this is
-                      only useful for bare-metal clusters. In Openshift 3.x, this
-                      was misleadingly called "IngressIPs". Automatically assigned
-                      External IPs are not affected by any ExternalIPPolicy rules.
-                      Currently, only one entry may be provided.
-                    items:
-                      type: string
-                    type: array
-                  policy:
-                    description: policy is a set of restrictions applied to the ExternalIP
-                      field. If nil or empty, then ExternalIP is not allowed to be
-                      set.
-                    properties:
-                      allowedCIDRs:
-                        description: allowedCIDRs is the list of allowed CIDRs.
-                        items:
-                          type: string
-                        type: array
-                      rejectedCIDRs:
-                        description: rejectedCIDRs is the list of disallowed CIDRs.
-                          These take precedence over allowedCIDRs.
-                        items:
-                          type: string
-                        type: array
-                    type: object
-                type: object
-              networkType:
-                description: 'NetworkType is the plugin that is to be deployed (e.g.
-                  OpenShiftSDN). This should match a value that the cluster-network-operator
-                  understands, or else no networking will be installed. Currently
-                  supported values are: - OpenShiftSDN This field is immutable after
-                  installation.'
-                type: string
-              serviceNetwork:
-                description: IP address pool for services. Currently, we only support
-                  a single entry here. This field is immutable after installation.
-                items:
-                  type: string
-                type: array
-              serviceNodePortRange:
-                description: The port range allowed for Services of type NodePort.
-                  If not specified, the default of 30000-32767 will be used. Such
-                  Services without a NodePort specified will have one automatically
-                  allocated from this range. This parameter can be updated after the
-                  cluster is installed.
-                pattern: ^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])-([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$
-                type: string
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            properties:
-              clusterNetwork:
-                description: IP address pool to use for pod IPs.
-                items:
-                  description: ClusterNetworkEntry is a contiguous block of IP addresses
-                    from which pod IPs are allocated.
-                  properties:
-                    cidr:
-                      description: The complete block for pod IPs.
-                      type: string
-                    hostPrefix:
-                      description: The size (prefix) of block to allocate to each
-                        node. If this field is not used by the plugin, it can be left
-                        unset.
-                      format: int32
-                      minimum: 0
-                      type: integer
-                  type: object
-                type: array
-              clusterNetworkMTU:
-                description: ClusterNetworkMTU is the MTU for inter-pod networking.
-                type: integer
-              conditions:
-                description: 'conditions represents the observations of a network.config
-                  current state. Known .status.conditions.type are: "NetworkTypeMigrationInProgress",
-                  "NetworkTypeMigrationMTUReady", "NetworkTypeMigrationTargetCNIAvailable",
-                  "NetworkTypeMigrationTargetCNIInUse" and "NetworkTypeMigrationOriginalCNIPurged"'
-                items:
-                  description: "Condition contains details for one aspect of the current
-                    state of this API Resource. --- This struct is intended for direct
-                    use as an array at the field path .status.conditions.  For example,
-                    \n type FooStatus struct{ // Represents the observations of a
-                    foo's current state. // Known .status.conditions.type are: \"Available\",
-                    \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
-                    // +listType=map // +listMapKey=type Conditions []metav1.Condition
-                    `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
-                    protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
-                  properties:
-                    lastTransitionTime:
-                      description: lastTransitionTime is the last time the condition
-                        transitioned from one status to another. This should be when
-                        the underlying condition changed.  If that is not known, then
-                        using the time when the API field changed is acceptable.
-                      format: date-time
-                      type: string
-                    message:
-                      description: message is a human readable message indicating
-                        details about the transition. This may be an empty string.
-                      maxLength: 32768
-                      type: string
-                    observedGeneration:
-                      description: observedGeneration represents the .metadata.generation
-                        that the condition was set based upon. For instance, if .metadata.generation
-                        is currently 12, but the .status.conditions[x].observedGeneration
-                        is 9, the condition is out of date with respect to the current
-                        state of the instance.
-                      format: int64
-                      minimum: 0
-                      type: integer
-                    reason:
-                      description: reason contains a programmatic identifier indicating
-                        the reason for the condition's last transition. Producers
-                        of specific condition types may define expected values and
-                        meanings for this field, and whether the values are considered
-                        a guaranteed API. The value should be a CamelCase string.
-                        This field may not be empty.
-                      maxLength: 1024
-                      minLength: 1
-                      pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
-                      type: string
-                    status:
-                      description: status of the condition, one of True, False, Unknown.
-                      enum:
-                      - "True"
-                      - "False"
-                      - Unknown
-                      type: string
-                    type:
-                      description: type of condition in CamelCase or in foo.example.com/CamelCase.
-                        --- Many .condition.type values are consistent across resources
-                        like Available, but because arbitrary conditions can be useful
-                        (see .node.status.conditions), the ability to deconflict is
-                        important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
-                      maxLength: 316
-                      pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
-                      type: string
-                  required:
-                  - lastTransitionTime
-                  - message
-                  - reason
-                  - status
-                  - type
-                  type: object
-                type: array
-                x-kubernetes-list-map-keys:
-                - type
-                x-kubernetes-list-type: map
-              migration:
-                description: Migration contains the cluster network migration configuration.
-                properties:
-                  mtu:
-                    description: MTU contains the MTU migration configuration.
-                    properties:
-                      machine:
-                        description: Machine contains MTU migration configuration
-                          for the machine's uplink.
-                        properties:
-                          from:
-                            description: From is the MTU to migrate from.
-                            format: int32
-                            minimum: 0
-                            type: integer
-                          to:
-                            description: To is the MTU to migrate to.
-                            format: int32
-                            minimum: 0
-                            type: integer
-                        type: object
-                      network:
-                        description: Network contains MTU migration configuration
-                          for the default network.
-                        properties:
-                          from:
-                            description: From is the MTU to migrate from.
-                            format: int32
-                            minimum: 0
-                            type: integer
-                          to:
-                            description: To is the MTU to migrate to.
-                            format: int32
-                            minimum: 0
-                            type: integer
-                        type: object
-                    type: object
-                  networkType:
-                    description: 'NetworkType is the target plugin that is to be deployed.
-                      Currently supported values are: OpenShiftSDN, OVNKubernetes'
-                    enum:
-                    - OpenShiftSDN
-                    - OVNKubernetes
-                    type: string
-                type: object
-              networkType:
-                description: NetworkType is the plugin that is deployed (e.g. OpenShiftSDN).
-                type: string
-              serviceNetwork:
-                description: IP address pool for services. Currently, we only support
-                  a single entry here.
-                items:
-                  type: string
-                type: array
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_network-Default.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_network-Default.crd.yaml
deleted file mode 100644
index d71799f5..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_network-Default.crd.yaml
+++ /dev/null
@@ -1,284 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    release.openshift.io/feature-set: Default
-  name: networks.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: Network
-    listKind: NetworkList
-    plural: networks
-    singular: network
-  preserveUnknownFields: false
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "Network holds cluster-wide information about Network. The canonical
-          name is `cluster`. It is used to configure the desired network configuration,
-          such as: IP address pools for services/pod IPs, network plugin, etc. Please
-          view network.spec for an explanation on what applies when configuring this
-          resource. \n Compatibility level 1: Stable within a major release for a
-          minimum of 12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration. As a general
-              rule, this SHOULD NOT be read directly. Instead, you should consume
-              the NetworkStatus, as it indicates the currently deployed configuration.
-              Currently, most spec fields are immutable after installation. Please
-              view the individual ones for further details on each.
-            properties:
-              clusterNetwork:
-                description: IP address pool to use for pod IPs. This field is immutable
-                  after installation.
-                items:
-                  description: ClusterNetworkEntry is a contiguous block of IP addresses
-                    from which pod IPs are allocated.
-                  properties:
-                    cidr:
-                      description: The complete block for pod IPs.
-                      type: string
-                    hostPrefix:
-                      description: The size (prefix) of block to allocate to each
-                        node. If this field is not used by the plugin, it can be left
-                        unset.
-                      format: int32
-                      minimum: 0
-                      type: integer
-                  type: object
-                type: array
-              externalIP:
-                description: externalIP defines configuration for controllers that
-                  affect Service.ExternalIP. If nil, then ExternalIP is not allowed
-                  to be set.
-                properties:
-                  autoAssignCIDRs:
-                    description: autoAssignCIDRs is a list of CIDRs from which to
-                      automatically assign Service.ExternalIP. These are assigned
-                      when the service is of type LoadBalancer. In general, this is
-                      only useful for bare-metal clusters. In Openshift 3.x, this
-                      was misleadingly called "IngressIPs". Automatically assigned
-                      External IPs are not affected by any ExternalIPPolicy rules.
-                      Currently, only one entry may be provided.
-                    items:
-                      type: string
-                    type: array
-                  policy:
-                    description: policy is a set of restrictions applied to the ExternalIP
-                      field. If nil or empty, then ExternalIP is not allowed to be
-                      set.
-                    properties:
-                      allowedCIDRs:
-                        description: allowedCIDRs is the list of allowed CIDRs.
-                        items:
-                          type: string
-                        type: array
-                      rejectedCIDRs:
-                        description: rejectedCIDRs is the list of disallowed CIDRs.
-                          These take precedence over allowedCIDRs.
-                        items:
-                          type: string
-                        type: array
-                    type: object
-                type: object
-              networkType:
-                description: 'NetworkType is the plugin that is to be deployed (e.g.
-                  OpenShiftSDN). This should match a value that the cluster-network-operator
-                  understands, or else no networking will be installed. Currently
-                  supported values are: - OpenShiftSDN This field is immutable after
-                  installation.'
-                type: string
-              serviceNetwork:
-                description: IP address pool for services. Currently, we only support
-                  a single entry here. This field is immutable after installation.
-                items:
-                  type: string
-                type: array
-              serviceNodePortRange:
-                description: The port range allowed for Services of type NodePort.
-                  If not specified, the default of 30000-32767 will be used. Such
-                  Services without a NodePort specified will have one automatically
-                  allocated from this range. This parameter can be updated after the
-                  cluster is installed.
-                pattern: ^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])-([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$
-                type: string
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            properties:
-              clusterNetwork:
-                description: IP address pool to use for pod IPs.
-                items:
-                  description: ClusterNetworkEntry is a contiguous block of IP addresses
-                    from which pod IPs are allocated.
-                  properties:
-                    cidr:
-                      description: The complete block for pod IPs.
-                      type: string
-                    hostPrefix:
-                      description: The size (prefix) of block to allocate to each
-                        node. If this field is not used by the plugin, it can be left
-                        unset.
-                      format: int32
-                      minimum: 0
-                      type: integer
-                  type: object
-                type: array
-              clusterNetworkMTU:
-                description: ClusterNetworkMTU is the MTU for inter-pod networking.
-                type: integer
-              conditions:
-                description: 'conditions represents the observations of a network.config
-                  current state. Known .status.conditions.type are: "NetworkTypeMigrationInProgress",
-                  "NetworkTypeMigrationMTUReady", "NetworkTypeMigrationTargetCNIAvailable",
-                  "NetworkTypeMigrationTargetCNIInUse" and "NetworkTypeMigrationOriginalCNIPurged"'
-                items:
-                  description: "Condition contains details for one aspect of the current
-                    state of this API Resource. --- This struct is intended for direct
-                    use as an array at the field path .status.conditions.  For example,
-                    \n type FooStatus struct{ // Represents the observations of a
-                    foo's current state. // Known .status.conditions.type are: \"Available\",
-                    \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
-                    // +listType=map // +listMapKey=type Conditions []metav1.Condition
-                    `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
-                    protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
-                  properties:
-                    lastTransitionTime:
-                      description: lastTransitionTime is the last time the condition
-                        transitioned from one status to another. This should be when
-                        the underlying condition changed.  If that is not known, then
-                        using the time when the API field changed is acceptable.
-                      format: date-time
-                      type: string
-                    message:
-                      description: message is a human readable message indicating
-                        details about the transition. This may be an empty string.
-                      maxLength: 32768
-                      type: string
-                    observedGeneration:
-                      description: observedGeneration represents the .metadata.generation
-                        that the condition was set based upon. For instance, if .metadata.generation
-                        is currently 12, but the .status.conditions[x].observedGeneration
-                        is 9, the condition is out of date with respect to the current
-                        state of the instance.
-                      format: int64
-                      minimum: 0
-                      type: integer
-                    reason:
-                      description: reason contains a programmatic identifier indicating
-                        the reason for the condition's last transition. Producers
-                        of specific condition types may define expected values and
-                        meanings for this field, and whether the values are considered
-                        a guaranteed API. The value should be a CamelCase string.
-                        This field may not be empty.
-                      maxLength: 1024
-                      minLength: 1
-                      pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
-                      type: string
-                    status:
-                      description: status of the condition, one of True, False, Unknown.
-                      enum:
-                      - "True"
-                      - "False"
-                      - Unknown
-                      type: string
-                    type:
-                      description: type of condition in CamelCase or in foo.example.com/CamelCase.
-                        --- Many .condition.type values are consistent across resources
-                        like Available, but because arbitrary conditions can be useful
-                        (see .node.status.conditions), the ability to deconflict is
-                        important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
-                      maxLength: 316
-                      pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
-                      type: string
-                  required:
-                  - lastTransitionTime
-                  - message
-                  - reason
-                  - status
-                  - type
-                  type: object
-                type: array
-                x-kubernetes-list-map-keys:
-                - type
-                x-kubernetes-list-type: map
-              migration:
-                description: Migration contains the cluster network migration configuration.
-                properties:
-                  mtu:
-                    description: MTU contains the MTU migration configuration.
-                    properties:
-                      machine:
-                        description: Machine contains MTU migration configuration
-                          for the machine's uplink.
-                        properties:
-                          from:
-                            description: From is the MTU to migrate from.
-                            format: int32
-                            minimum: 0
-                            type: integer
-                          to:
-                            description: To is the MTU to migrate to.
-                            format: int32
-                            minimum: 0
-                            type: integer
-                        type: object
-                      network:
-                        description: Network contains MTU migration configuration
-                          for the default network.
-                        properties:
-                          from:
-                            description: From is the MTU to migrate from.
-                            format: int32
-                            minimum: 0
-                            type: integer
-                          to:
-                            description: To is the MTU to migrate to.
-                            format: int32
-                            minimum: 0
-                            type: integer
-                        type: object
-                    type: object
-                  networkType:
-                    description: 'NetworkType is the target plugin that is to be deployed.
-                      Currently supported values are: OpenShiftSDN, OVNKubernetes'
-                    enum:
-                    - OpenShiftSDN
-                    - OVNKubernetes
-                    type: string
-                type: object
-              networkType:
-                description: NetworkType is the plugin that is deployed (e.g. OpenShiftSDN).
-                type: string
-              serviceNetwork:
-                description: IP address pool for services. Currently, we only support
-                  a single entry here.
-                items:
-                  type: string
-                type: array
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_network-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_network-TechPreviewNoUpgrade.crd.yaml
deleted file mode 100644
index 8ec000b8..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_network-TechPreviewNoUpgrade.crd.yaml
+++ /dev/null
@@ -1,284 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    release.openshift.io/feature-set: TechPreviewNoUpgrade
-  name: networks.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: Network
-    listKind: NetworkList
-    plural: networks
-    singular: network
-  preserveUnknownFields: false
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "Network holds cluster-wide information about Network. The canonical
-          name is `cluster`. It is used to configure the desired network configuration,
-          such as: IP address pools for services/pod IPs, network plugin, etc. Please
-          view network.spec for an explanation on what applies when configuring this
-          resource. \n Compatibility level 1: Stable within a major release for a
-          minimum of 12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration. As a general
-              rule, this SHOULD NOT be read directly. Instead, you should consume
-              the NetworkStatus, as it indicates the currently deployed configuration.
-              Currently, most spec fields are immutable after installation. Please
-              view the individual ones for further details on each.
-            properties:
-              clusterNetwork:
-                description: IP address pool to use for pod IPs. This field is immutable
-                  after installation.
-                items:
-                  description: ClusterNetworkEntry is a contiguous block of IP addresses
-                    from which pod IPs are allocated.
-                  properties:
-                    cidr:
-                      description: The complete block for pod IPs.
-                      type: string
-                    hostPrefix:
-                      description: The size (prefix) of block to allocate to each
-                        node. If this field is not used by the plugin, it can be left
-                        unset.
-                      format: int32
-                      minimum: 0
-                      type: integer
-                  type: object
-                type: array
-              externalIP:
-                description: externalIP defines configuration for controllers that
-                  affect Service.ExternalIP. If nil, then ExternalIP is not allowed
-                  to be set.
-                properties:
-                  autoAssignCIDRs:
-                    description: autoAssignCIDRs is a list of CIDRs from which to
-                      automatically assign Service.ExternalIP. These are assigned
-                      when the service is of type LoadBalancer. In general, this is
-                      only useful for bare-metal clusters. In Openshift 3.x, this
-                      was misleadingly called "IngressIPs". Automatically assigned
-                      External IPs are not affected by any ExternalIPPolicy rules.
-                      Currently, only one entry may be provided.
-                    items:
-                      type: string
-                    type: array
-                  policy:
-                    description: policy is a set of restrictions applied to the ExternalIP
-                      field. If nil or empty, then ExternalIP is not allowed to be
-                      set.
-                    properties:
-                      allowedCIDRs:
-                        description: allowedCIDRs is the list of allowed CIDRs.
-                        items:
-                          type: string
-                        type: array
-                      rejectedCIDRs:
-                        description: rejectedCIDRs is the list of disallowed CIDRs.
-                          These take precedence over allowedCIDRs.
-                        items:
-                          type: string
-                        type: array
-                    type: object
-                type: object
-              networkType:
-                description: 'NetworkType is the plugin that is to be deployed (e.g.
-                  OpenShiftSDN). This should match a value that the cluster-network-operator
-                  understands, or else no networking will be installed. Currently
-                  supported values are: - OpenShiftSDN This field is immutable after
-                  installation.'
-                type: string
-              serviceNetwork:
-                description: IP address pool for services. Currently, we only support
-                  a single entry here. This field is immutable after installation.
-                items:
-                  type: string
-                type: array
-              serviceNodePortRange:
-                description: The port range allowed for Services of type NodePort.
-                  If not specified, the default of 30000-32767 will be used. Such
-                  Services without a NodePort specified will have one automatically
-                  allocated from this range. This parameter can be updated after the
-                  cluster is installed.
-                pattern: ^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])-([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$
-                type: string
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            properties:
-              clusterNetwork:
-                description: IP address pool to use for pod IPs.
-                items:
-                  description: ClusterNetworkEntry is a contiguous block of IP addresses
-                    from which pod IPs are allocated.
-                  properties:
-                    cidr:
-                      description: The complete block for pod IPs.
-                      type: string
-                    hostPrefix:
-                      description: The size (prefix) of block to allocate to each
-                        node. If this field is not used by the plugin, it can be left
-                        unset.
-                      format: int32
-                      minimum: 0
-                      type: integer
-                  type: object
-                type: array
-              clusterNetworkMTU:
-                description: ClusterNetworkMTU is the MTU for inter-pod networking.
-                type: integer
-              conditions:
-                description: 'conditions represents the observations of a network.config
-                  current state. Known .status.conditions.type are: "NetworkTypeMigrationInProgress",
-                  "NetworkTypeMigrationMTUReady", "NetworkTypeMigrationTargetCNIAvailable",
-                  "NetworkTypeMigrationTargetCNIInUse" and "NetworkTypeMigrationOriginalCNIPurged"'
-                items:
-                  description: "Condition contains details for one aspect of the current
-                    state of this API Resource. --- This struct is intended for direct
-                    use as an array at the field path .status.conditions.  For example,
-                    \n type FooStatus struct{ // Represents the observations of a
-                    foo's current state. // Known .status.conditions.type are: \"Available\",
-                    \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
-                    // +listType=map // +listMapKey=type Conditions []metav1.Condition
-                    `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
-                    protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
-                  properties:
-                    lastTransitionTime:
-                      description: lastTransitionTime is the last time the condition
-                        transitioned from one status to another. This should be when
-                        the underlying condition changed.  If that is not known, then
-                        using the time when the API field changed is acceptable.
-                      format: date-time
-                      type: string
-                    message:
-                      description: message is a human readable message indicating
-                        details about the transition. This may be an empty string.
-                      maxLength: 32768
-                      type: string
-                    observedGeneration:
-                      description: observedGeneration represents the .metadata.generation
-                        that the condition was set based upon. For instance, if .metadata.generation
-                        is currently 12, but the .status.conditions[x].observedGeneration
-                        is 9, the condition is out of date with respect to the current
-                        state of the instance.
-                      format: int64
-                      minimum: 0
-                      type: integer
-                    reason:
-                      description: reason contains a programmatic identifier indicating
-                        the reason for the condition's last transition. Producers
-                        of specific condition types may define expected values and
-                        meanings for this field, and whether the values are considered
-                        a guaranteed API. The value should be a CamelCase string.
-                        This field may not be empty.
-                      maxLength: 1024
-                      minLength: 1
-                      pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
-                      type: string
-                    status:
-                      description: status of the condition, one of True, False, Unknown.
-                      enum:
-                      - "True"
-                      - "False"
-                      - Unknown
-                      type: string
-                    type:
-                      description: type of condition in CamelCase or in foo.example.com/CamelCase.
-                        --- Many .condition.type values are consistent across resources
-                        like Available, but because arbitrary conditions can be useful
-                        (see .node.status.conditions), the ability to deconflict is
-                        important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
-                      maxLength: 316
-                      pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
-                      type: string
-                  required:
-                  - lastTransitionTime
-                  - message
-                  - reason
-                  - status
-                  - type
-                  type: object
-                type: array
-                x-kubernetes-list-map-keys:
-                - type
-                x-kubernetes-list-type: map
-              migration:
-                description: Migration contains the cluster network migration configuration.
-                properties:
-                  mtu:
-                    description: MTU contains the MTU migration configuration.
-                    properties:
-                      machine:
-                        description: Machine contains MTU migration configuration
-                          for the machine's uplink.
-                        properties:
-                          from:
-                            description: From is the MTU to migrate from.
-                            format: int32
-                            minimum: 0
-                            type: integer
-                          to:
-                            description: To is the MTU to migrate to.
-                            format: int32
-                            minimum: 0
-                            type: integer
-                        type: object
-                      network:
-                        description: Network contains MTU migration configuration
-                          for the default network.
-                        properties:
-                          from:
-                            description: From is the MTU to migrate from.
-                            format: int32
-                            minimum: 0
-                            type: integer
-                          to:
-                            description: To is the MTU to migrate to.
-                            format: int32
-                            minimum: 0
-                            type: integer
-                        type: object
-                    type: object
-                  networkType:
-                    description: 'NetworkType is the target plugin that is to be deployed.
-                      Currently supported values are: OpenShiftSDN, OVNKubernetes'
-                    enum:
-                    - OpenShiftSDN
-                    - OVNKubernetes
-                    type: string
-                type: object
-              networkType:
-                description: NetworkType is the plugin that is deployed (e.g. OpenShiftSDN).
-                type: string
-              serviceNetwork:
-                description: IP address pool for services. Currently, we only support
-                  a single entry here.
-                items:
-                  type: string
-                type: array
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_node.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_node.crd.yaml
deleted file mode 100644
index ab135b22..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_node.crd.yaml
+++ /dev/null
@@ -1,66 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/1107
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-  name: nodes.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: Node
-    listKind: NodeList
-    plural: nodes
-    singular: node
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "Node holds cluster-wide information about node specific features.
-          \n Compatibility level 1: Stable within a major release for a minimum of
-          12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              cgroupMode:
-                description: CgroupMode determines the cgroups version on the node
-                enum:
-                - v1
-                - v2
-                - ""
-                type: string
-              workerLatencyProfile:
-                description: WorkerLatencyProfile determins the how fast the kubelet
-                  is updating the status and corresponding reaction of the cluster
-                enum:
-                - Default
-                - MediumUpdateAverageReaction
-                - LowUpdateSlowReaction
-                type: string
-            type: object
-          status:
-            description: status holds observed values.
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_oauth.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_oauth.crd.yaml
deleted file mode 100644
index bc588e09..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_oauth.crd.yaml
+++ /dev/null
@@ -1,698 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-  name: oauths.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: OAuth
-    listKind: OAuthList
-    plural: oauths
-    singular: oauth
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "OAuth holds cluster-wide information about OAuth.  The canonical
-          name is `cluster`. It is used to configure the integrated OAuth server.
-          This configuration is only honored when the top level Authentication config
-          has type set to IntegratedOAuth. \n Compatibility level 1: Stable within
-          a major release for a minimum of 12 months or 3 minor releases (whichever
-          is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              identityProviders:
-                description: identityProviders is an ordered list of ways for a user
-                  to identify themselves. When this list is empty, no identities are
-                  provisioned for users.
-                items:
-                  description: IdentityProvider provides identities for users authenticating
-                    using credentials
-                  properties:
-                    basicAuth:
-                      description: basicAuth contains configuration options for the
-                        BasicAuth IdP
-                      properties:
-                        ca:
-                          description: ca is an optional reference to a config map
-                            by name containing the PEM-encoded CA bundle. It is used
-                            as a trust anchor to validate the TLS certificate presented
-                            by the remote server. The key "ca.crt" is used to locate
-                            the data. If specified and the config map or expected
-                            key is not found, the identity provider is not honored.
-                            If the specified ca data is not valid, the identity provider
-                            is not honored. If empty, the default system roots are
-                            used. The namespace for this config map is openshift-config.
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                config map
-                              type: string
-                          required:
-                          - name
-                          type: object
-                        tlsClientCert:
-                          description: tlsClientCert is an optional reference to a
-                            secret by name that contains the PEM-encoded TLS client
-                            certificate to present when connecting to the server.
-                            The key "tls.crt" is used to locate the data. If specified
-                            and the secret or expected key is not found, the identity
-                            provider is not honored. If the specified certificate
-                            data is not valid, the identity provider is not honored.
-                            The namespace for this secret is openshift-config.
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                secret
-                              type: string
-                          required:
-                          - name
-                          type: object
-                        tlsClientKey:
-                          description: tlsClientKey is an optional reference to a
-                            secret by name that contains the PEM-encoded TLS private
-                            key for the client certificate referenced in tlsClientCert.
-                            The key "tls.key" is used to locate the data. If specified
-                            and the secret or expected key is not found, the identity
-                            provider is not honored. If the specified certificate
-                            data is not valid, the identity provider is not honored.
-                            The namespace for this secret is openshift-config.
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                secret
-                              type: string
-                          required:
-                          - name
-                          type: object
-                        url:
-                          description: url is the remote URL to connect to
-                          type: string
-                      type: object
-                    github:
-                      description: github enables user authentication using GitHub
-                        credentials
-                      properties:
-                        ca:
-                          description: ca is an optional reference to a config map
-                            by name containing the PEM-encoded CA bundle. It is used
-                            as a trust anchor to validate the TLS certificate presented
-                            by the remote server. The key "ca.crt" is used to locate
-                            the data. If specified and the config map or expected
-                            key is not found, the identity provider is not honored.
-                            If the specified ca data is not valid, the identity provider
-                            is not honored. If empty, the default system roots are
-                            used. This can only be configured when hostname is set
-                            to a non-empty value. The namespace for this config map
-                            is openshift-config.
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                config map
-                              type: string
-                          required:
-                          - name
-                          type: object
-                        clientID:
-                          description: clientID is the oauth client ID
-                          type: string
-                        clientSecret:
-                          description: clientSecret is a required reference to the
-                            secret by name containing the oauth client secret. The
-                            key "clientSecret" is used to locate the data. If the
-                            secret or expected key is not found, the identity provider
-                            is not honored. The namespace for this secret is openshift-config.
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                secret
-                              type: string
-                          required:
-                          - name
-                          type: object
-                        hostname:
-                          description: hostname is the optional domain (e.g. "mycompany.com")
-                            for use with a hosted instance of GitHub Enterprise. It
-                            must match the GitHub Enterprise settings value configured
-                            at /setup/settings#hostname.
-                          type: string
-                        organizations:
-                          description: organizations optionally restricts which organizations
-                            are allowed to log in
-                          items:
-                            type: string
-                          type: array
-                        teams:
-                          description: teams optionally restricts which teams are
-                            allowed to log in. Format is <org>/<team>.
-                          items:
-                            type: string
-                          type: array
-                      type: object
-                    gitlab:
-                      description: gitlab enables user authentication using GitLab
-                        credentials
-                      properties:
-                        ca:
-                          description: ca is an optional reference to a config map
-                            by name containing the PEM-encoded CA bundle. It is used
-                            as a trust anchor to validate the TLS certificate presented
-                            by the remote server. The key "ca.crt" is used to locate
-                            the data. If specified and the config map or expected
-                            key is not found, the identity provider is not honored.
-                            If the specified ca data is not valid, the identity provider
-                            is not honored. If empty, the default system roots are
-                            used. The namespace for this config map is openshift-config.
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                config map
-                              type: string
-                          required:
-                          - name
-                          type: object
-                        clientID:
-                          description: clientID is the oauth client ID
-                          type: string
-                        clientSecret:
-                          description: clientSecret is a required reference to the
-                            secret by name containing the oauth client secret. The
-                            key "clientSecret" is used to locate the data. If the
-                            secret or expected key is not found, the identity provider
-                            is not honored. The namespace for this secret is openshift-config.
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                secret
-                              type: string
-                          required:
-                          - name
-                          type: object
-                        url:
-                          description: url is the oauth server base URL
-                          type: string
-                      type: object
-                    google:
-                      description: google enables user authentication using Google
-                        credentials
-                      properties:
-                        clientID:
-                          description: clientID is the oauth client ID
-                          type: string
-                        clientSecret:
-                          description: clientSecret is a required reference to the
-                            secret by name containing the oauth client secret. The
-                            key "clientSecret" is used to locate the data. If the
-                            secret or expected key is not found, the identity provider
-                            is not honored. The namespace for this secret is openshift-config.
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                secret
-                              type: string
-                          required:
-                          - name
-                          type: object
-                        hostedDomain:
-                          description: hostedDomain is the optional Google App domain
-                            (e.g. "mycompany.com") to restrict logins to
-                          type: string
-                      type: object
-                    htpasswd:
-                      description: htpasswd enables user authentication using an HTPasswd
-                        file to validate credentials
-                      properties:
-                        fileData:
-                          description: fileData is a required reference to a secret
-                            by name containing the data to use as the htpasswd file.
-                            The key "htpasswd" is used to locate the data. If the
-                            secret or expected key is not found, the identity provider
-                            is not honored. If the specified htpasswd data is not
-                            valid, the identity provider is not honored. The namespace
-                            for this secret is openshift-config.
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                secret
-                              type: string
-                          required:
-                          - name
-                          type: object
-                      type: object
-                    keystone:
-                      description: keystone enables user authentication using keystone
-                        password credentials
-                      properties:
-                        ca:
-                          description: ca is an optional reference to a config map
-                            by name containing the PEM-encoded CA bundle. It is used
-                            as a trust anchor to validate the TLS certificate presented
-                            by the remote server. The key "ca.crt" is used to locate
-                            the data. If specified and the config map or expected
-                            key is not found, the identity provider is not honored.
-                            If the specified ca data is not valid, the identity provider
-                            is not honored. If empty, the default system roots are
-                            used. The namespace for this config map is openshift-config.
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                config map
-                              type: string
-                          required:
-                          - name
-                          type: object
-                        domainName:
-                          description: domainName is required for keystone v3
-                          type: string
-                        tlsClientCert:
-                          description: tlsClientCert is an optional reference to a
-                            secret by name that contains the PEM-encoded TLS client
-                            certificate to present when connecting to the server.
-                            The key "tls.crt" is used to locate the data. If specified
-                            and the secret or expected key is not found, the identity
-                            provider is not honored. If the specified certificate
-                            data is not valid, the identity provider is not honored.
-                            The namespace for this secret is openshift-config.
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                secret
-                              type: string
-                          required:
-                          - name
-                          type: object
-                        tlsClientKey:
-                          description: tlsClientKey is an optional reference to a
-                            secret by name that contains the PEM-encoded TLS private
-                            key for the client certificate referenced in tlsClientCert.
-                            The key "tls.key" is used to locate the data. If specified
-                            and the secret or expected key is not found, the identity
-                            provider is not honored. If the specified certificate
-                            data is not valid, the identity provider is not honored.
-                            The namespace for this secret is openshift-config.
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                secret
-                              type: string
-                          required:
-                          - name
-                          type: object
-                        url:
-                          description: url is the remote URL to connect to
-                          type: string
-                      type: object
-                    ldap:
-                      description: ldap enables user authentication using LDAP credentials
-                      properties:
-                        attributes:
-                          description: attributes maps LDAP attributes to identities
-                          properties:
-                            email:
-                              description: email is the list of attributes whose values
-                                should be used as the email address. Optional. If
-                                unspecified, no email is set for the identity
-                              items:
-                                type: string
-                              type: array
-                            id:
-                              description: id is the list of attributes whose values
-                                should be used as the user ID. Required. First non-empty
-                                attribute is used. At least one attribute is required.
-                                If none of the listed attribute have a value, authentication
-                                fails. LDAP standard identity attribute is "dn"
-                              items:
-                                type: string
-                              type: array
-                            name:
-                              description: name is the list of attributes whose values
-                                should be used as the display name. Optional. If unspecified,
-                                no display name is set for the identity LDAP standard
-                                display name attribute is "cn"
-                              items:
-                                type: string
-                              type: array
-                            preferredUsername:
-                              description: preferredUsername is the list of attributes
-                                whose values should be used as the preferred username.
-                                LDAP standard login attribute is "uid"
-                              items:
-                                type: string
-                              type: array
-                          type: object
-                        bindDN:
-                          description: bindDN is an optional DN to bind with during
-                            the search phase.
-                          type: string
-                        bindPassword:
-                          description: bindPassword is an optional reference to a
-                            secret by name containing a password to bind with during
-                            the search phase. The key "bindPassword" is used to locate
-                            the data. If specified and the secret or expected key
-                            is not found, the identity provider is not honored. The
-                            namespace for this secret is openshift-config.
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                secret
-                              type: string
-                          required:
-                          - name
-                          type: object
-                        ca:
-                          description: ca is an optional reference to a config map
-                            by name containing the PEM-encoded CA bundle. It is used
-                            as a trust anchor to validate the TLS certificate presented
-                            by the remote server. The key "ca.crt" is used to locate
-                            the data. If specified and the config map or expected
-                            key is not found, the identity provider is not honored.
-                            If the specified ca data is not valid, the identity provider
-                            is not honored. If empty, the default system roots are
-                            used. The namespace for this config map is openshift-config.
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                config map
-                              type: string
-                          required:
-                          - name
-                          type: object
-                        insecure:
-                          description: 'insecure, if true, indicates the connection
-                            should not use TLS WARNING: Should not be set to `true`
-                            with the URL scheme "ldaps://" as "ldaps://" URLs always
-                            attempt to connect using TLS, even when `insecure` is
-                            set to `true` When `true`, "ldap://" URLS connect insecurely.
-                            When `false`, "ldap://" URLs are upgraded to a TLS connection
-                            using StartTLS as specified in https://tools.ietf.org/html/rfc2830.'
-                          type: boolean
-                        url:
-                          description: 'url is an RFC 2255 URL which specifies the
-                            LDAP search parameters to use. The syntax of the URL is:
-                            ldap://host:port/basedn?attribute?scope?filter'
-                          type: string
-                      type: object
-                    mappingMethod:
-                      description: mappingMethod determines how identities from this
-                        provider are mapped to users Defaults to "claim"
-                      type: string
-                    name:
-                      description: 'name is used to qualify the identities returned
-                        by this provider. - It MUST be unique and not shared by any
-                        other identity provider used - It MUST be a valid path segment:
-                        name cannot equal "." or ".." or contain "/" or "%" or ":"
-                        Ref: https://godoc.org/github.com/openshift/origin/pkg/user/apis/user/validation#ValidateIdentityProviderName'
-                      type: string
-                    openID:
-                      description: openID enables user authentication using OpenID
-                        credentials
-                      properties:
-                        ca:
-                          description: ca is an optional reference to a config map
-                            by name containing the PEM-encoded CA bundle. It is used
-                            as a trust anchor to validate the TLS certificate presented
-                            by the remote server. The key "ca.crt" is used to locate
-                            the data. If specified and the config map or expected
-                            key is not found, the identity provider is not honored.
-                            If the specified ca data is not valid, the identity provider
-                            is not honored. If empty, the default system roots are
-                            used. The namespace for this config map is openshift-config.
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                config map
-                              type: string
-                          required:
-                          - name
-                          type: object
-                        claims:
-                          description: claims mappings
-                          properties:
-                            email:
-                              description: email is the list of claims whose values
-                                should be used as the email address. Optional. If
-                                unspecified, no email is set for the identity
-                              items:
-                                type: string
-                              type: array
-                              x-kubernetes-list-type: atomic
-                            groups:
-                              description: groups is the list of claims value of which
-                                should be used to synchronize groups from the OIDC
-                                provider to OpenShift for the user. If multiple claims
-                                are specified, the first one with a non-empty value
-                                is used.
-                              items:
-                                description: OpenIDClaim represents a claim retrieved
-                                  from an OpenID provider's tokens or userInfo responses
-                                minLength: 1
-                                type: string
-                              type: array
-                              x-kubernetes-list-type: atomic
-                            name:
-                              description: name is the list of claims whose values
-                                should be used as the display name. Optional. If unspecified,
-                                no display name is set for the identity
-                              items:
-                                type: string
-                              type: array
-                              x-kubernetes-list-type: atomic
-                            preferredUsername:
-                              description: preferredUsername is the list of claims
-                                whose values should be used as the preferred username.
-                                If unspecified, the preferred username is determined
-                                from the value of the sub claim
-                              items:
-                                type: string
-                              type: array
-                              x-kubernetes-list-type: atomic
-                          type: object
-                        clientID:
-                          description: clientID is the oauth client ID
-                          type: string
-                        clientSecret:
-                          description: clientSecret is a required reference to the
-                            secret by name containing the oauth client secret. The
-                            key "clientSecret" is used to locate the data. If the
-                            secret or expected key is not found, the identity provider
-                            is not honored. The namespace for this secret is openshift-config.
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                secret
-                              type: string
-                          required:
-                          - name
-                          type: object
-                        extraAuthorizeParameters:
-                          additionalProperties:
-                            type: string
-                          description: extraAuthorizeParameters are any custom parameters
-                            to add to the authorize request.
-                          type: object
-                        extraScopes:
-                          description: extraScopes are any scopes to request in addition
-                            to the standard "openid" scope.
-                          items:
-                            type: string
-                          type: array
-                        issuer:
-                          description: issuer is the URL that the OpenID Provider
-                            asserts as its Issuer Identifier. It must use the https
-                            scheme with no query or fragment component.
-                          type: string
-                      type: object
-                    requestHeader:
-                      description: requestHeader enables user authentication using
-                        request header credentials
-                      properties:
-                        ca:
-                          description: ca is a required reference to a config map
-                            by name containing the PEM-encoded CA bundle. It is used
-                            as a trust anchor to validate the TLS certificate presented
-                            by the remote server. Specifically, it allows verification
-                            of incoming requests to prevent header spoofing. The key
-                            "ca.crt" is used to locate the data. If the config map
-                            or expected key is not found, the identity provider is
-                            not honored. If the specified ca data is not valid, the
-                            identity provider is not honored. The namespace for this
-                            config map is openshift-config.
-                          properties:
-                            name:
-                              description: name is the metadata.name of the referenced
-                                config map
-                              type: string
-                          required:
-                          - name
-                          type: object
-                        challengeURL:
-                          description: challengeURL is a URL to redirect unauthenticated
-                            /authorize requests to Unauthenticated requests from OAuth
-                            clients which expect WWW-Authenticate challenges will
-                            be redirected here. ${url} is replaced with the current
-                            URL, escaped to be safe in a query parameter https://www.example.com/sso-login?then=${url}
-                            ${query} is replaced with the current query string https://www.example.com/auth-proxy/oauth/authorize?${query}
-                            Required when challenge is set to true.
-                          type: string
-                        clientCommonNames:
-                          description: clientCommonNames is an optional list of common
-                            names to require a match from. If empty, any client certificate
-                            validated against the clientCA bundle is considered authoritative.
-                          items:
-                            type: string
-                          type: array
-                        emailHeaders:
-                          description: emailHeaders is the set of headers to check
-                            for the email address
-                          items:
-                            type: string
-                          type: array
-                        headers:
-                          description: headers is the set of headers to check for
-                            identity information
-                          items:
-                            type: string
-                          type: array
-                        loginURL:
-                          description: loginURL is a URL to redirect unauthenticated
-                            /authorize requests to Unauthenticated requests from OAuth
-                            clients which expect interactive logins will be redirected
-                            here ${url} is replaced with the current URL, escaped
-                            to be safe in a query parameter https://www.example.com/sso-login?then=${url}
-                            ${query} is replaced with the current query string https://www.example.com/auth-proxy/oauth/authorize?${query}
-                            Required when login is set to true.
-                          type: string
-                        nameHeaders:
-                          description: nameHeaders is the set of headers to check
-                            for the display name
-                          items:
-                            type: string
-                          type: array
-                        preferredUsernameHeaders:
-                          description: preferredUsernameHeaders is the set of headers
-                            to check for the preferred username
-                          items:
-                            type: string
-                          type: array
-                      type: object
-                    type:
-                      description: type identifies the identity provider type for
-                        this entry.
-                      type: string
-                  type: object
-                type: array
-                x-kubernetes-list-type: atomic
-              templates:
-                description: templates allow you to customize pages like the login
-                  page.
-                properties:
-                  error:
-                    description: error is the name of a secret that specifies a go
-                      template to use to render error pages during the authentication
-                      or grant flow. The key "errors.html" is used to locate the template
-                      data. If specified and the secret or expected key is not found,
-                      the default error page is used. If the specified template is
-                      not valid, the default error page is used. If unspecified, the
-                      default error page is used. The namespace for this secret is
-                      openshift-config.
-                    properties:
-                      name:
-                        description: name is the metadata.name of the referenced secret
-                        type: string
-                    required:
-                    - name
-                    type: object
-                  login:
-                    description: login is the name of a secret that specifies a go
-                      template to use to render the login page. The key "login.html"
-                      is used to locate the template data. If specified and the secret
-                      or expected key is not found, the default login page is used.
-                      If the specified template is not valid, the default login page
-                      is used. If unspecified, the default login page is used. The
-                      namespace for this secret is openshift-config.
-                    properties:
-                      name:
-                        description: name is the metadata.name of the referenced secret
-                        type: string
-                    required:
-                    - name
-                    type: object
-                  providerSelection:
-                    description: providerSelection is the name of a secret that specifies
-                      a go template to use to render the provider selection page.
-                      The key "providers.html" is used to locate the template data.
-                      If specified and the secret or expected key is not found, the
-                      default provider selection page is used. If the specified template
-                      is not valid, the default provider selection page is used. If
-                      unspecified, the default provider selection page is used. The
-                      namespace for this secret is openshift-config.
-                    properties:
-                      name:
-                        description: name is the metadata.name of the referenced secret
-                        type: string
-                    required:
-                    - name
-                    type: object
-                type: object
-              tokenConfig:
-                description: tokenConfig contains options for authorization and access
-                  tokens
-                properties:
-                  accessTokenInactivityTimeout:
-                    description: "accessTokenInactivityTimeout defines the token inactivity
-                      timeout for tokens granted by any client. The value represents
-                      the maximum amount of time that can occur between consecutive
-                      uses of the token. Tokens become invalid if they are not used
-                      within this temporal window. The user will need to acquire a
-                      new token to regain access once a token times out. Takes valid
-                      time duration string such as \"5m\", \"1.5h\" or \"2h45m\".
-                      The minimum allowed value for duration is 300s (5 minutes).
-                      If the timeout is configured per client, then that value takes
-                      precedence. If the timeout value is not specified and the client
-                      does not override the value, then tokens are valid until their
-                      lifetime. \n WARNING: existing tokens' timeout will not be affected
-                      (lowered) by changing this value"
-                    type: string
-                  accessTokenInactivityTimeoutSeconds:
-                    description: 'accessTokenInactivityTimeoutSeconds - DEPRECATED:
-                      setting this field has no effect.'
-                    format: int32
-                    type: integer
-                  accessTokenMaxAgeSeconds:
-                    description: accessTokenMaxAgeSeconds defines the maximum age
-                      of access tokens
-                    format: int32
-                    type: integer
-                type: object
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_project.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_project.crd.yaml
deleted file mode 100644
index ec2c7af3..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_project.crd.yaml
+++ /dev/null
@@ -1,68 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-  name: projects.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: Project
-    listKind: ProjectList
-    plural: projects
-    singular: project
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "Project holds cluster-wide information about Project.  The canonical
-          name is `cluster` \n Compatibility level 1: Stable within a major release
-          for a minimum of 12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              projectRequestMessage:
-                description: projectRequestMessage is the string presented to a user
-                  if they are unable to request a project via the projectrequest api
-                  endpoint
-                type: string
-              projectRequestTemplate:
-                description: projectRequestTemplate is the template to use for creating
-                  projects in response to projectrequest. This must point to a template
-                  in 'openshift-config' namespace. It is optional. If it is not specified,
-                  a default template is used.
-                properties:
-                  name:
-                    description: name is the metadata.name of the referenced project
-                      request template
-                    type: string
-                type: object
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_scheduler-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_scheduler-CustomNoUpgrade.crd.yaml
deleted file mode 100644
index f7a42766..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_scheduler-CustomNoUpgrade.crd.yaml
+++ /dev/null
@@ -1,130 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    release.openshift.io/feature-set: CustomNoUpgrade
-  name: schedulers.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: Scheduler
-    listKind: SchedulerList
-    plural: schedulers
-    singular: scheduler
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "Scheduler holds cluster-wide config information to run the Kubernetes
-          Scheduler and influence its placement decisions. The canonical name for
-          this config is `cluster`. \n Compatibility level 1: Stable within a major
-          release for a minimum of 12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              defaultNodeSelector:
-                description: 'defaultNodeSelector helps set the cluster-wide default
-                  node selector to restrict pod placement to specific nodes. This
-                  is applied to the pods created in all namespaces and creates an
-                  intersection with any existing nodeSelectors already set on a pod,
-                  additionally constraining that pod''s selector. For example, defaultNodeSelector:
-                  "type=user-node,region=east" would set nodeSelector field in pod
-                  spec to "type=user-node,region=east" to all pods created in all
-                  namespaces. Namespaces having project-wide node selectors won''t
-                  be impacted even if this field is set. This adds an annotation section
-                  to the namespace. For example, if a new namespace is created with
-                  node-selector=''type=user-node,region=east'', the annotation openshift.io/node-selector:
-                  type=user-node,region=east gets added to the project. When the openshift.io/node-selector
-                  annotation is set on the project the value is used in preference
-                  to the value we are setting for defaultNodeSelector field. For instance,
-                  openshift.io/node-selector: "type=user-node,region=west" means that
-                  the default of "type=user-node,region=east" set in defaultNodeSelector
-                  would not be applied.'
-                type: string
-              mastersSchedulable:
-                description: 'MastersSchedulable allows masters nodes to be schedulable.
-                  When this flag is turned on, all the master nodes in the cluster
-                  will be made schedulable, so that workload pods can run on them.
-                  The default value for this field is false, meaning none of the master
-                  nodes are schedulable. Important Note: Once the workload pods start
-                  running on the master nodes, extreme care must be taken to ensure
-                  that cluster-critical control plane components are not impacted.
-                  Please turn on this field after doing due diligence.'
-                type: boolean
-              policy:
-                description: 'DEPRECATED: the scheduler Policy API has been deprecated
-                  and will be removed in a future release. policy is a reference to
-                  a ConfigMap containing scheduler policy which has user specified
-                  predicates and priorities. If this ConfigMap is not available scheduler
-                  will default to use DefaultAlgorithmProvider. The namespace for
-                  this configmap is openshift-config.'
-                properties:
-                  name:
-                    description: name is the metadata.name of the referenced config
-                      map
-                    type: string
-                required:
-                - name
-                type: object
-              profile:
-                description: "profile sets which scheduling profile should be set
-                  in order to configure scheduling decisions for new pods. \n Valid
-                  values are \"LowNodeUtilization\", \"HighNodeUtilization\", \"NoScoring\"
-                  Defaults to \"LowNodeUtilization\""
-                enum:
-                - ""
-                - LowNodeUtilization
-                - HighNodeUtilization
-                - NoScoring
-                type: string
-              profileCustomizations:
-                description: profileCustomizations contains configuration for modifying
-                  the default behavior of existing scheduler profiles.
-                properties:
-                  dynamicResourceAllocation:
-                    description: dynamicResourceAllocation allows to enable or disable
-                      dynamic resource allocation within the scheduler. Dynamic resource
-                      allocation is an API for requesting and sharing resources between
-                      pods and containers inside a pod. Third-party resource drivers
-                      are responsible for tracking and allocating resources. Different
-                      kinds of resources support arbitrary parameters for defining
-                      requirements and initialization. Valid values are Enabled, Disabled
-                      and omitted. When omitted, this means no opinion and the platform
-                      is left to choose a reasonable default, which is subject to
-                      change over time. The current default is Disabled.
-                    enum:
-                    - ""
-                    - Enabled
-                    - Disabled
-                    type: string
-                type: object
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_scheduler-Default.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_scheduler-Default.crd.yaml
deleted file mode 100644
index aa89c10a..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_scheduler-Default.crd.yaml
+++ /dev/null
@@ -1,109 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    release.openshift.io/feature-set: Default
-  name: schedulers.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: Scheduler
-    listKind: SchedulerList
-    plural: schedulers
-    singular: scheduler
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "Scheduler holds cluster-wide config information to run the Kubernetes
-          Scheduler and influence its placement decisions. The canonical name for
-          this config is `cluster`. \n Compatibility level 1: Stable within a major
-          release for a minimum of 12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              defaultNodeSelector:
-                description: 'defaultNodeSelector helps set the cluster-wide default
-                  node selector to restrict pod placement to specific nodes. This
-                  is applied to the pods created in all namespaces and creates an
-                  intersection with any existing nodeSelectors already set on a pod,
-                  additionally constraining that pod''s selector. For example, defaultNodeSelector:
-                  "type=user-node,region=east" would set nodeSelector field in pod
-                  spec to "type=user-node,region=east" to all pods created in all
-                  namespaces. Namespaces having project-wide node selectors won''t
-                  be impacted even if this field is set. This adds an annotation section
-                  to the namespace. For example, if a new namespace is created with
-                  node-selector=''type=user-node,region=east'', the annotation openshift.io/node-selector:
-                  type=user-node,region=east gets added to the project. When the openshift.io/node-selector
-                  annotation is set on the project the value is used in preference
-                  to the value we are setting for defaultNodeSelector field. For instance,
-                  openshift.io/node-selector: "type=user-node,region=west" means that
-                  the default of "type=user-node,region=east" set in defaultNodeSelector
-                  would not be applied.'
-                type: string
-              mastersSchedulable:
-                description: 'MastersSchedulable allows masters nodes to be schedulable.
-                  When this flag is turned on, all the master nodes in the cluster
-                  will be made schedulable, so that workload pods can run on them.
-                  The default value for this field is false, meaning none of the master
-                  nodes are schedulable. Important Note: Once the workload pods start
-                  running on the master nodes, extreme care must be taken to ensure
-                  that cluster-critical control plane components are not impacted.
-                  Please turn on this field after doing due diligence.'
-                type: boolean
-              policy:
-                description: 'DEPRECATED: the scheduler Policy API has been deprecated
-                  and will be removed in a future release. policy is a reference to
-                  a ConfigMap containing scheduler policy which has user specified
-                  predicates and priorities. If this ConfigMap is not available scheduler
-                  will default to use DefaultAlgorithmProvider. The namespace for
-                  this configmap is openshift-config.'
-                properties:
-                  name:
-                    description: name is the metadata.name of the referenced config
-                      map
-                    type: string
-                required:
-                - name
-                type: object
-              profile:
-                description: "profile sets which scheduling profile should be set
-                  in order to configure scheduling decisions for new pods. \n Valid
-                  values are \"LowNodeUtilization\", \"HighNodeUtilization\", \"NoScoring\"
-                  Defaults to \"LowNodeUtilization\""
-                enum:
-                - ""
-                - LowNodeUtilization
-                - HighNodeUtilization
-                - NoScoring
-                type: string
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_scheduler-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_scheduler-TechPreviewNoUpgrade.crd.yaml
deleted file mode 100644
index 071b9dff..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_scheduler-TechPreviewNoUpgrade.crd.yaml
+++ /dev/null
@@ -1,130 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    release.openshift.io/feature-set: TechPreviewNoUpgrade
-  name: schedulers.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: Scheduler
-    listKind: SchedulerList
-    plural: schedulers
-    singular: scheduler
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "Scheduler holds cluster-wide config information to run the Kubernetes
-          Scheduler and influence its placement decisions. The canonical name for
-          this config is `cluster`. \n Compatibility level 1: Stable within a major
-          release for a minimum of 12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: spec holds user settable values for configuration
-            properties:
-              defaultNodeSelector:
-                description: 'defaultNodeSelector helps set the cluster-wide default
-                  node selector to restrict pod placement to specific nodes. This
-                  is applied to the pods created in all namespaces and creates an
-                  intersection with any existing nodeSelectors already set on a pod,
-                  additionally constraining that pod''s selector. For example, defaultNodeSelector:
-                  "type=user-node,region=east" would set nodeSelector field in pod
-                  spec to "type=user-node,region=east" to all pods created in all
-                  namespaces. Namespaces having project-wide node selectors won''t
-                  be impacted even if this field is set. This adds an annotation section
-                  to the namespace. For example, if a new namespace is created with
-                  node-selector=''type=user-node,region=east'', the annotation openshift.io/node-selector:
-                  type=user-node,region=east gets added to the project. When the openshift.io/node-selector
-                  annotation is set on the project the value is used in preference
-                  to the value we are setting for defaultNodeSelector field. For instance,
-                  openshift.io/node-selector: "type=user-node,region=west" means that
-                  the default of "type=user-node,region=east" set in defaultNodeSelector
-                  would not be applied.'
-                type: string
-              mastersSchedulable:
-                description: 'MastersSchedulable allows masters nodes to be schedulable.
-                  When this flag is turned on, all the master nodes in the cluster
-                  will be made schedulable, so that workload pods can run on them.
-                  The default value for this field is false, meaning none of the master
-                  nodes are schedulable. Important Note: Once the workload pods start
-                  running on the master nodes, extreme care must be taken to ensure
-                  that cluster-critical control plane components are not impacted.
-                  Please turn on this field after doing due diligence.'
-                type: boolean
-              policy:
-                description: 'DEPRECATED: the scheduler Policy API has been deprecated
-                  and will be removed in a future release. policy is a reference to
-                  a ConfigMap containing scheduler policy which has user specified
-                  predicates and priorities. If this ConfigMap is not available scheduler
-                  will default to use DefaultAlgorithmProvider. The namespace for
-                  this configmap is openshift-config.'
-                properties:
-                  name:
-                    description: name is the metadata.name of the referenced config
-                      map
-                    type: string
-                required:
-                - name
-                type: object
-              profile:
-                description: "profile sets which scheduling profile should be set
-                  in order to configure scheduling decisions for new pods. \n Valid
-                  values are \"LowNodeUtilization\", \"HighNodeUtilization\", \"NoScoring\"
-                  Defaults to \"LowNodeUtilization\""
-                enum:
-                - ""
-                - LowNodeUtilization
-                - HighNodeUtilization
-                - NoScoring
-                type: string
-              profileCustomizations:
-                description: profileCustomizations contains configuration for modifying
-                  the default behavior of existing scheduler profiles.
-                properties:
-                  dynamicResourceAllocation:
-                    description: dynamicResourceAllocation allows to enable or disable
-                      dynamic resource allocation within the scheduler. Dynamic resource
-                      allocation is an API for requesting and sharing resources between
-                      pods and containers inside a pod. Third-party resource drivers
-                      are responsible for tracking and allocating resources. Different
-                      kinds of resources support arbitrary parameters for defining
-                      requirements and initialization. Valid values are Enabled, Disabled
-                      and omitted. When omitted, this means no opinion and the platform
-                      is left to choose a reasonable default, which is subject to
-                      change over time. The current default is Disabled.
-                    enum:
-                    - ""
-                    - Enabled
-                    - Disabled
-                    type: string
-                type: object
-            type: object
-          status:
-            description: status holds observed values from the cluster. They may not
-              be overridden.
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_openshift-controller-manager-operator_01_build.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_openshift-controller-manager-operator_01_build.crd.yaml
deleted file mode 100644
index 94e7f015..00000000
--- a/vendor/github.com/openshift/api/config/v1/0000_10_openshift-controller-manager-operator_01_build.crd.yaml
+++ /dev/null
@@ -1,431 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    capability.openshift.io/name: Build
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-  name: builds.config.openshift.io
-spec:
-  group: config.openshift.io
-  names:
-    kind: Build
-    listKind: BuildList
-    plural: builds
-    singular: build
-  preserveUnknownFields: false
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "Build configures the behavior of OpenShift builds for the entire
-          cluster. This includes default settings that can be overridden in BuildConfig
-          objects, and overrides which are applied to all builds. \n The canonical
-          name is \"cluster\" \n Compatibility level 1: Stable within a major release
-          for a minimum of 12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: Spec holds user-settable values for the build controller
-              configuration
-            properties:
-              additionalTrustedCA:
-                description: "AdditionalTrustedCA is a reference to a ConfigMap containing
-                  additional CAs that should be trusted for image pushes and pulls
-                  during builds. The namespace for this config map is openshift-config.
-                  \n DEPRECATED: Additional CAs for image pull and push should be
-                  set on image.config.openshift.io/cluster instead."
-                properties:
-                  name:
-                    description: name is the metadata.name of the referenced config
-                      map
-                    type: string
-                required:
-                - name
-                type: object
-              buildDefaults:
-                description: BuildDefaults controls the default information for Builds
-                properties:
-                  defaultProxy:
-                    description: "DefaultProxy contains the default proxy settings
-                      for all build operations, including image pull/push and source
-                      download. \n Values can be overrode by setting the `HTTP_PROXY`,
-                      `HTTPS_PROXY`, and `NO_PROXY` environment variables in the build
-                      config's strategy."
-                    properties:
-                      httpProxy:
-                        description: httpProxy is the URL of the proxy for HTTP requests.  Empty
-                          means unset and will not result in an env var.
-                        type: string
-                      httpsProxy:
-                        description: httpsProxy is the URL of the proxy for HTTPS
-                          requests.  Empty means unset and will not result in an env
-                          var.
-                        type: string
-                      noProxy:
-                        description: noProxy is a comma-separated list of hostnames
-                          and/or CIDRs and/or IPs for which the proxy should not be
-                          used. Empty means unset and will not result in an env var.
-                        type: string
-                      readinessEndpoints:
-                        description: readinessEndpoints is a list of endpoints used
-                          to verify readiness of the proxy.
-                        items:
-                          type: string
-                        type: array
-                      trustedCA:
-                        description: "trustedCA is a reference to a ConfigMap containing
-                          a CA certificate bundle. The trustedCA field should only
-                          be consumed by a proxy validator. The validator is responsible
-                          for reading the certificate bundle from the required key
-                          \"ca-bundle.crt\", merging it with the system default trust
-                          bundle, and writing the merged trust bundle to a ConfigMap
-                          named \"trusted-ca-bundle\" in the \"openshift-config-managed\"
-                          namespace. Clients that expect to make proxy connections
-                          must use the trusted-ca-bundle for all HTTPS requests to
-                          the proxy, and may use the trusted-ca-bundle for non-proxy
-                          HTTPS requests as well. \n The namespace for the ConfigMap
-                          referenced by trustedCA is \"openshift-config\". Here is
-                          an example ConfigMap (in yaml): \n apiVersion: v1 kind:
-                          ConfigMap metadata: name: user-ca-bundle namespace: openshift-config
-                          data: ca-bundle.crt: | -----BEGIN CERTIFICATE----- Custom
-                          CA certificate bundle. -----END CERTIFICATE-----"
-                        properties:
-                          name:
-                            description: name is the metadata.name of the referenced
-                              config map
-                            type: string
-                        required:
-                        - name
-                        type: object
-                    type: object
-                  env:
-                    description: Env is a set of default environment variables that
-                      will be applied to the build if the specified variables do not
-                      exist on the build
-                    items:
-                      description: EnvVar represents an environment variable present
-                        in a Container.
-                      properties:
-                        name:
-                          description: Name of the environment variable. Must be a
-                            C_IDENTIFIER.
-                          type: string
-                        value:
-                          description: 'Variable references $(VAR_NAME) are expanded
-                            using the previously defined environment variables in
-                            the container and any service environment variables. If
-                            a variable cannot be resolved, the reference in the input
-                            string will be unchanged. Double $$ are reduced to a single
-                            $, which allows for escaping the $(VAR_NAME) syntax: i.e.
-                            "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
-                            Escaped references will never be expanded, regardless
-                            of whether the variable exists or not. Defaults to "".'
-                          type: string
-                        valueFrom:
-                          description: Source for the environment variable's value.
-                            Cannot be used if value is not empty.
-                          properties:
-                            configMapKeyRef:
-                              description: Selects a key of a ConfigMap.
-                              properties:
-                                key:
-                                  description: The key to select.
-                                  type: string
-                                name:
-                                  description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
-                                    TODO: Add other useful fields. apiVersion, kind,
-                                    uid?'
-                                  type: string
-                                optional:
-                                  description: Specify whether the ConfigMap or its
-                                    key must be defined
-                                  type: boolean
-                              required:
-                              - key
-                              type: object
-                              x-kubernetes-map-type: atomic
-                            fieldRef:
-                              description: 'Selects a field of the pod: supports metadata.name,
-                                metadata.namespace, `metadata.labels[''<KEY>'']`,
-                                `metadata.annotations[''<KEY>'']`, spec.nodeName,
-                                spec.serviceAccountName, status.hostIP, status.podIP,
-                                status.podIPs.'
-                              properties:
-                                apiVersion:
-                                  description: Version of the schema the FieldPath
-                                    is written in terms of, defaults to "v1".
-                                  type: string
-                                fieldPath:
-                                  description: Path of the field to select in the
-                                    specified API version.
-                                  type: string
-                              required:
-                              - fieldPath
-                              type: object
-                              x-kubernetes-map-type: atomic
-                            resourceFieldRef:
-                              description: 'Selects a resource of the container: only
-                                resources limits and requests (limits.cpu, limits.memory,
-                                limits.ephemeral-storage, requests.cpu, requests.memory
-                                and requests.ephemeral-storage) are currently supported.'
-                              properties:
-                                containerName:
-                                  description: 'Container name: required for volumes,
-                                    optional for env vars'
-                                  type: string
-                                divisor:
-                                  anyOf:
-                                  - type: integer
-                                  - type: string
-                                  description: Specifies the output format of the
-                                    exposed resources, defaults to "1"
-                                  pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
-                                  x-kubernetes-int-or-string: true
-                                resource:
-                                  description: 'Required: resource to select'
-                                  type: string
-                              required:
-                              - resource
-                              type: object
-                              x-kubernetes-map-type: atomic
-                            secretKeyRef:
-                              description: Selects a key of a secret in the pod's
-                                namespace
-                              properties:
-                                key:
-                                  description: The key of the secret to select from.  Must
-                                    be a valid secret key.
-                                  type: string
-                                name:
-                                  description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
-                                    TODO: Add other useful fields. apiVersion, kind,
-                                    uid?'
-                                  type: string
-                                optional:
-                                  description: Specify whether the Secret or its key
-                                    must be defined
-                                  type: boolean
-                              required:
-                              - key
-                              type: object
-                              x-kubernetes-map-type: atomic
-                          type: object
-                      required:
-                      - name
-                      type: object
-                    type: array
-                  gitProxy:
-                    description: "GitProxy contains the proxy settings for git operations
-                      only. If set, this will override any Proxy settings for all
-                      git commands, such as git clone. \n Values that are not set
-                      here will be inherited from DefaultProxy."
-                    properties:
-                      httpProxy:
-                        description: httpProxy is the URL of the proxy for HTTP requests.  Empty
-                          means unset and will not result in an env var.
-                        type: string
-                      httpsProxy:
-                        description: httpsProxy is the URL of the proxy for HTTPS
-                          requests.  Empty means unset and will not result in an env
-                          var.
-                        type: string
-                      noProxy:
-                        description: noProxy is a comma-separated list of hostnames
-                          and/or CIDRs and/or IPs for which the proxy should not be
-                          used. Empty means unset and will not result in an env var.
-                        type: string
-                      readinessEndpoints:
-                        description: readinessEndpoints is a list of endpoints used
-                          to verify readiness of the proxy.
-                        items:
-                          type: string
-                        type: array
-                      trustedCA:
-                        description: "trustedCA is a reference to a ConfigMap containing
-                          a CA certificate bundle. The trustedCA field should only
-                          be consumed by a proxy validator. The validator is responsible
-                          for reading the certificate bundle from the required key
-                          \"ca-bundle.crt\", merging it with the system default trust
-                          bundle, and writing the merged trust bundle to a ConfigMap
-                          named \"trusted-ca-bundle\" in the \"openshift-config-managed\"
-                          namespace. Clients that expect to make proxy connections
-                          must use the trusted-ca-bundle for all HTTPS requests to
-                          the proxy, and may use the trusted-ca-bundle for non-proxy
-                          HTTPS requests as well. \n The namespace for the ConfigMap
-                          referenced by trustedCA is \"openshift-config\". Here is
-                          an example ConfigMap (in yaml): \n apiVersion: v1 kind:
-                          ConfigMap metadata: name: user-ca-bundle namespace: openshift-config
-                          data: ca-bundle.crt: | -----BEGIN CERTIFICATE----- Custom
-                          CA certificate bundle. -----END CERTIFICATE-----"
-                        properties:
-                          name:
-                            description: name is the metadata.name of the referenced
-                              config map
-                            type: string
-                        required:
-                        - name
-                        type: object
-                    type: object
-                  imageLabels:
-                    description: ImageLabels is a list of docker labels that are applied
-                      to the resulting image. User can override a default label by
-                      providing a label with the same name in their Build/BuildConfig.
-                    items:
-                      properties:
-                        name:
-                          description: Name defines the name of the label. It must
-                            have non-zero length.
-                          type: string
-                        value:
-                          description: Value defines the literal value of the label.
-                          type: string
-                      type: object
-                    type: array
-                  resources:
-                    description: Resources defines resource requirements to execute
-                      the build.
-                    properties:
-                      claims:
-                        description: "Claims lists the names of resources, defined
-                          in spec.resourceClaims, that are used by this container.
-                          \n This is an alpha field and requires enabling the DynamicResourceAllocation
-                          feature gate. \n This field is immutable. It can only be
-                          set for containers."
-                        items:
-                          description: ResourceClaim references one entry in PodSpec.ResourceClaims.
-                          properties:
-                            name:
-                              description: Name must match the name of one entry in
-                                pod.spec.resourceClaims of the Pod where this field
-                                is used. It makes that resource available inside a
-                                container.
-                              type: string
-                          required:
-                          - name
-                          type: object
-                        type: array
-                        x-kubernetes-list-map-keys:
-                        - name
-                        x-kubernetes-list-type: map
-                      limits:
-                        additionalProperties:
-                          anyOf:
-                          - type: integer
-                          - type: string
-                          pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
-                          x-kubernetes-int-or-string: true
-                        description: 'Limits describes the maximum amount of compute
-                          resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
-                        type: object
-                      requests:
-                        additionalProperties:
-                          anyOf:
-                          - type: integer
-                          - type: string
-                          pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
-                          x-kubernetes-int-or-string: true
-                        description: 'Requests describes the minimum amount of compute
-                          resources required. If Requests is omitted for a container,
-                          it defaults to Limits if that is explicitly specified, otherwise
-                          to an implementation-defined value. Requests cannot exceed
-                          Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
-                        type: object
-                    type: object
-                type: object
-              buildOverrides:
-                description: BuildOverrides controls override settings for builds
-                properties:
-                  forcePull:
-                    description: ForcePull overrides, if set, the equivalent value
-                      in the builds, i.e. false disables force pull for all builds,
-                      true enables force pull for all builds, independently of what
-                      each build specifies itself
-                    type: boolean
-                  imageLabels:
-                    description: ImageLabels is a list of docker labels that are applied
-                      to the resulting image. If user provided a label in their Build/BuildConfig
-                      with the same name as one in this list, the user's label will
-                      be overwritten.
-                    items:
-                      properties:
-                        name:
-                          description: Name defines the name of the label. It must
-                            have non-zero length.
-                          type: string
-                        value:
-                          description: Value defines the literal value of the label.
-                          type: string
-                      type: object
-                    type: array
-                  nodeSelector:
-                    additionalProperties:
-                      type: string
-                    description: NodeSelector is a selector which must be true for
-                      the build pod to fit on a node
-                    type: object
-                  tolerations:
-                    description: Tolerations is a list of Tolerations that will override
-                      any existing tolerations set on a build pod.
-                    items:
-                      description: The pod this Toleration is attached to tolerates
-                        any taint that matches the triple <key,value,effect> using
-                        the matching operator <operator>.
-                      properties:
-                        effect:
-                          description: Effect indicates the taint effect to match.
-                            Empty means match all taint effects. When specified, allowed
-                            values are NoSchedule, PreferNoSchedule and NoExecute.
-                          type: string
-                        key:
-                          description: Key is the taint key that the toleration applies
-                            to. Empty means match all taint keys. If the key is empty,
-                            operator must be Exists; this combination means to match
-                            all values and all keys.
-                          type: string
-                        operator:
-                          description: Operator represents a key's relationship to
-                            the value. Valid operators are Exists and Equal. Defaults
-                            to Equal. Exists is equivalent to wildcard for value,
-                            so that a pod can tolerate all taints of a particular
-                            category.
-                          type: string
-                        tolerationSeconds:
-                          description: TolerationSeconds represents the period of
-                            time the toleration (which must be of effect NoExecute,
-                            otherwise this field is ignored) tolerates the taint.
-                            By default, it is not set, which means tolerate the taint
-                            forever (do not evict). Zero and negative values will
-                            be treated as 0 (evict immediately) by the system.
-                          format: int64
-                          type: integer
-                        value:
-                          description: Value is the taint value the toleration matches
-                            to. If the operator is Exists, the value should be empty,
-                            otherwise just a regular string.
-                          type: string
-                      type: object
-                    type: array
-                type: object
-            type: object
-        required:
-        - spec
-        type: object
-    served: true
-    storage: true
-    subresources:
-      status: {}
diff --git a/vendor/github.com/openshift/api/config/v1/custom.apiserver.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/custom.apiserver.testsuite.yaml
deleted file mode 100644
index 5e2dea3e..00000000
--- a/vendor/github.com/openshift/api/config/v1/custom.apiserver.testsuite.yaml
+++ /dev/null
@@ -1,35 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
-name: "[CustomNoUpgrade] APIServer"
-crd: 0000_10_config-operator_01_apiserver-CustomNoUpgrade.crd.yaml
-tests:
-  onCreate:
-    - name: Should be able to create encrypt with aescbc
-      initial: |
-        apiVersion: config.openshift.io/v1
-        kind: APIServer
-        spec:
-          encryption:
-            type: aescbc
-      expected: |
-        apiVersion: config.openshift.io/v1
-        kind: APIServer
-        spec:
-          audit:
-            profile: Default
-          encryption:
-            type: aescbc
-    - name: Should be able to create encrypt with aesgcm
-      initial: |
-        apiVersion: config.openshift.io/v1
-        kind: APIServer
-        spec:
-          encryption:
-            type: aesgcm
-      expected: |
-        apiVersion: config.openshift.io/v1
-        kind: APIServer
-        spec:
-          audit:
-            profile: Default
-          encryption:
-            type: aesgcm
diff --git a/vendor/github.com/openshift/api/config/v1/custom.authentication.single.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/custom.authentication.single.testsuite.yaml
new file mode 100644
index 00000000..7a55d429
--- /dev/null
+++ b/vendor/github.com/openshift/api/config/v1/custom.authentication.single.testsuite.yaml
@@ -0,0 +1,284 @@
+apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
+name: "[CustomNoUpgrade] Authentication SingleNode"
+crd: 0000_10_config-operator_01_authentications-SingleNode-CustomNoUpgrade.crd.yaml
+tests:
+  onCreate:
+  - name: Should be able to create a minimal Authentication
+    initial: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec: {} # No spec is required for a Authentication
+    expected: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec: {}
+  - name: Should be able to use the OIDC type
+    initial: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+    expected: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+  - name: Cannot set username claim prefix with policy NoPrefix
+    initial: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          claimMappings:
+            username:
+              claim: "preferred_username"
+              prefixPolicy: NoPrefix
+              prefix:
+                prefixString: "myoidc:"
+    expectedError: "prefix must be set if prefixPolicy is 'Prefix', but must remain unset otherwise"
+  - name: Can set username claim prefix with policy Prefix
+    initial: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          claimMappings:
+            username:
+              claim: "preferred_username"
+              prefixPolicy: Prefix
+              prefix:
+                prefixString: "myoidc:"
+    expected: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          claimMappings:
+            username:
+              claim: "preferred_username"
+              prefixPolicy: Prefix
+              prefix:
+                prefixString: "myoidc:"
+  - name: Cannot leave username claim prefix blank with policy Prefix
+    initial: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          claimMappings:
+            username:
+              claim: "preferred_username"
+              prefixPolicy: Prefix
+    expectedError: "prefix must be set if prefixPolicy is 'Prefix', but must remain unset otherwise"
+  - name: Can set OIDC providers with no username prefixing
+    initial: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          claimMappings:
+            username:
+              claim: "preferred_username"
+              prefixPolicy: NoPrefix
+    expected: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          claimMappings:
+            username:
+              claim: "preferred_username"
+              prefixPolicy: NoPrefix
+  onUpdate:
+  - name: Updating OIDC provider with a client that's not in the status
+    initial: &initConfig |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          oidcClients:
+            - componentNamespace: namespace
+              componentName: preexisting
+              clientID: someclient
+            - componentNamespace: namespace
+              componentName: name
+              clientID: legitclient
+      status:
+        oidcClients:
+        - componentNamespace: namespace
+          componentName: name
+        - componentNamespace: namespace2
+          componentName: name2
+        - componentNamespace: namespace2
+          componentName: name3
+    updated: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          oidcClients:
+          - componentNamespace: namespace
+            componentName: preexisting
+            clientID: someclient
+          - componentNamespace: namespace
+            componentName: name
+            clientID: legitclient
+          - componentNamespace: dif-namespace # new client here
+            componentName: tehName
+            clientID: cool-client
+      status:
+        oidcClients:
+        - componentNamespace: namespace
+          componentName: name
+        - componentNamespace: namespace2
+          componentName: name2
+        - componentNamespace: namespace2
+          componentName: name3
+    expectedError: "all oidcClients in the oidcProviders must match their componentName and componentNamespace to either a previously configured oidcClient or they must exist in the status.oidcClients"
+  - name: Updating OIDC provider with a client that's different from the previous one
+    initial: *initConfig
+    updated: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          oidcClients:
+          - componentNamespace: dif-namespace
+            componentName: tehName
+            clientID: cool-client
+      status:
+        oidcClients:
+        - componentNamespace: namespace
+          componentName: name
+        - componentNamespace: namespace2
+          componentName: name2
+        - componentNamespace: namespace2
+          componentName: name3
+    expectedError: "all oidcClients in the oidcProviders must match their componentName and componentNamespace to either a previously configured oidcClient or they must exist in the status.oidcClients"
+  - name: Updating previously existing client
+    initial: *initConfig
+    updated: &prevExistingUpdated |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          oidcClients:
+            - componentNamespace: namespace
+              componentName: preexisting
+              clientID: different-client
+      status:
+        oidcClients:
+        - componentNamespace: namespace
+          componentName: name
+        - componentNamespace: namespace2
+          componentName: name2
+        - componentNamespace: namespace2
+          componentName: name3
+    expected: *prevExistingUpdated
+  - name: Removing a configured client from the status (== component unregister)
+    initial: *initConfig
+    updated: &removeFromStatus |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          oidcClients:
+            - componentNamespace: namespace
+              componentName: preexisting
+              clientID: different-client
+            - componentNamespace: namespace
+              componentName: name
+              clientID: legitclient
+      status:
+        oidcClients:
+        - componentNamespace: namespace2
+          componentName: name2
+        - componentNamespace: namespace2
+          componentName: name3
+    expected: *removeFromStatus
+  - name: Simply add a valid client
+    initial: *initConfig
+    updated: &addClient |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          oidcClients:
+            - componentNamespace: namespace
+              componentName: preexisting
+              clientID: different-client
+            - componentNamespace: namespace
+              componentName: name
+              clientID: legitclient
+            - componentNamespace: namespace2
+              componentName: name3
+              clientID: justavalidclient
+      status:
+        oidcClients:
+        - componentNamespace: namespace
+          componentName: name
+        - componentNamespace: namespace2
+          componentName: name2
+        - componentNamespace: namespace2
+          componentName: name3
+    expected: *addClient
diff --git a/vendor/github.com/openshift/api/config/v1/custom.authentication.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/custom.authentication.testsuite.yaml
index 92e7d72e..1d8896c7 100644
--- a/vendor/github.com/openshift/api/config/v1/custom.authentication.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/custom.authentication.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[CustomNoUpgrade] Authentication"
-crd: 0000_10_config-operator_01_authentication.crd-CustomNoUpgrade.yaml
+crd: 0000_10_config-operator_01_authentications-SelfManagedHA-CustomNoUpgrade.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal Authentication
diff --git a/vendor/github.com/openshift/api/config/v1/custom.clusterversion.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/custom.clusterversion.testsuite.yaml
index f3090558..83898be0 100644
--- a/vendor/github.com/openshift/api/config/v1/custom.clusterversion.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/custom.clusterversion.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[CustomNoUpgrade] ClusterVersion"
-crd: 0000_00_cluster-version-operator_01_clusterversion-CustomNoUpgrade.crd.yaml
+crd: 0000_00_cluster-version-operator_01_clusterversions-CustomNoUpgrade.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal ClusterVersion
diff --git a/vendor/github.com/openshift/api/config/v1/custom.dns.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/custom.dns.testsuite.yaml
deleted file mode 100644
index ab1a123b..00000000
--- a/vendor/github.com/openshift/api/config/v1/custom.dns.testsuite.yaml
+++ /dev/null
@@ -1,104 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
-name: "[Custom] DNS"
-crd: 0000_10_config-operator_01_dns-CustomNoUpgrade.crd.yaml
-tests:
-  onCreate:
-  - name: Should be able to create a minimal DNS
-    initial: |
-      apiVersion: config.openshift.io/v1
-      kind: DNS
-      spec: {} # No spec is required for a DNS
-    expected: |
-      apiVersion: config.openshift.io/v1
-      kind: DNS
-      spec: {}
-  - name: Should be able to specify an AWS role ARN for a private hosted zone
-    initial: |
-      apiVersion: config.openshift.io/v1
-      kind: DNS
-      spec:
-        platform:
-          type: AWS
-          aws:
-            privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
-    expected: |
-      apiVersion: config.openshift.io/v1
-      kind: DNS
-      spec:
-        platform:
-          type: AWS
-          aws:
-            privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
-  - name: Should not be able to specify unsupported platform
-    initial: |
-      apiVersion: config.openshift.io/v1
-      kind: DNS
-      spec:
-        platform:
-          type: Azure
-          azure:
-            privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
-    expectedError: "Invalid value: \"string\": allowed values are '' and 'AWS'"
-  - name: Should not be able to specify invalid AWS role ARN
-    initial: |
-      apiVersion: config.openshift.io/v1
-      kind: DNS
-      metadata:
-        name: cluster
-      spec:
-        platform:
-          type: AWS
-          aws:
-            privateZoneIAMRole: arn:aws:iam:bad:123456789012:role/foo
-    expectedError: "DNS.config.openshift.io \"cluster\" is invalid: spec.platform.aws.privateZoneIAMRole: Invalid value: \"arn:aws:iam:bad:123456789012:role/foo\": spec.platform.aws.privateZoneIAMRole in body should match '^arn:(aws|aws-cn|aws-us-gov):iam::[0-9]{12}:role\\/.*$'"
-  - name: Should not be able to specify different type and platform
-    initial: |
-      apiVersion: config.openshift.io/v1
-      kind: DNS
-      spec:
-        platform:
-          type: ""
-          aws:
-            privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
-    expectedError: "Invalid value: \"object\": aws configuration is required when platform is AWS, and forbidden otherwise"
-  onUpdate:
-  - name: Can switch from empty (default), to AWS
-    initial: |
-      apiVersion: config.openshift.io/v1
-      kind: DNS
-      spec:
-        platform:
-          type: ""
-    updated: |
-      apiVersion: config.openshift.io/v1
-      kind: DNS
-      spec:
-        platform:
-          type: AWS
-          aws:
-            privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
-    expected: |
-      apiVersion: config.openshift.io/v1
-      kind: DNS
-      spec:
-        platform:
-          type: AWS
-          aws:
-            privateZoneIAMRole: arn:aws:iam::123456789012:role/foo
-  - name: Upgrade case is valid
-    initial: |
-      apiVersion: config.openshift.io/v1
-      kind: DNS
-      spec: {} # No spec is required for a DNS
-    updated: |
-      apiVersion: config.openshift.io/v1
-      kind: DNS
-      spec:
-        platform:
-          type: ""
-    expected: |
-      apiVersion: config.openshift.io/v1
-      kind: DNS
-      spec:
-        platform:
-          type: ""
diff --git a/vendor/github.com/openshift/api/config/v1/custom.infrastructure.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/custom.infrastructure.testsuite.yaml
index 24433f4f..48a26270 100644
--- a/vendor/github.com/openshift/api/config/v1/custom.infrastructure.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/custom.infrastructure.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Custom] Infrastructure"
-crd: 0000_10_config-operator_01_infrastructure-CustomNoUpgrade.crd.yaml
+crd: 0000_10_config-operator_01_infrastructures-CustomNoUpgrade.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal Infrastructure
diff --git a/vendor/github.com/openshift/api/config/v1/custom.network.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/custom.network.testsuite.yaml
deleted file mode 100644
index 59e9fbdf..00000000
--- a/vendor/github.com/openshift/api/config/v1/custom.network.testsuite.yaml
+++ /dev/null
@@ -1,28 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
-name: "[CustomNoUpgrade] Network"
-crd: 0000_10_config-operator_01_network-CustomNoUpgrade.crd.yaml
-tests:
-  onCreate:
-    - name: Should be able to set status conditions
-      initial: |
-        apiVersion: config.openshift.io/v1
-        kind: Network
-        spec: {} # No spec is required for a Network
-        status:
-          conditions:
-            - type: NetworkTypeMigrationInProgress
-              status: "False"
-              reason: "Reason"
-              message: "Message"
-              lastTransitionTime: "2023-10-25T12:00:00Z"
-      expected: |
-        apiVersion: config.openshift.io/v1
-        kind: Network
-        spec: {}
-        status:
-          conditions:
-            - type: NetworkTypeMigrationInProgress
-              status: "False"
-              reason: "Reason"
-              message: "Message"
-              lastTransitionTime: "2023-10-25T12:00:00Z"
diff --git a/vendor/github.com/openshift/api/config/v1/custom.scheduler.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/custom.scheduler.testsuite.yaml
index 57b546b6..26856685 100644
--- a/vendor/github.com/openshift/api/config/v1/custom.scheduler.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/custom.scheduler.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] Scheduler"
-crd: 0000_10_config-operator_01_scheduler-CustomNoUpgrade.crd.yaml
+crd: 0000_10_config-operator_01_schedulers-CustomNoUpgrade.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal Scheduler
diff --git a/vendor/github.com/openshift/api/config/v1/doc.go b/vendor/github.com/openshift/api/config/v1/doc.go
index 4ff5208f..f9945475 100644
--- a/vendor/github.com/openshift/api/config/v1/doc.go
+++ b/vendor/github.com/openshift/api/config/v1/doc.go
@@ -1,6 +1,7 @@
 // +k8s:deepcopy-gen=package,register
 // +k8s:defaulter-gen=TypeMeta
 // +k8s:openapi-gen=true
+// +openshift:featuregated-schema-gen=true
 
 // +kubebuilder:validation:Optional
 // +groupName=config.openshift.io
diff --git a/vendor/github.com/openshift/api/config/v1/feature_gates.go b/vendor/github.com/openshift/api/config/v1/feature_gates.go
index 7b7cbf64..d7f0b659 100644
--- a/vendor/github.com/openshift/api/config/v1/feature_gates.go
+++ b/vendor/github.com/openshift/api/config/v1/feature_gates.go
@@ -1,5 +1,7 @@
 package v1
 
+import "fmt"
+
 // FeatureGateDescription is a golang-only interface used to contains details for a feature gate.
 type FeatureGateDescription struct {
 	// FeatureGateAttributes is the information that appears in the API
@@ -15,6 +17,15 @@ type FeatureGateDescription struct {
 	OwningProduct OwningProduct
 }
 
+type ClusterProfileName string
+
+var (
+	Hypershift         = ClusterProfileName("include.release.openshift.io/ibm-cloud-managed")
+	SelfManaged        = ClusterProfileName("include.release.openshift.io/self-managed-high-availability")
+	SingleNode         = ClusterProfileName("include.release.openshift.io/single-node-developer")
+	AllClusterProfiles = []ClusterProfileName{Hypershift, SelfManaged, SingleNode}
+)
+
 type OwningProduct string
 
 var (
@@ -22,443 +33,531 @@ var (
 	kubernetes  = OwningProduct("Kubernetes")
 )
 
-var (
-	FeatureGateValidatingAdmissionPolicy = FeatureGateName("ValidatingAdmissionPolicy")
-	validatingAdmissionPolicy            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateValidatingAdmissionPolicy,
-		},
-		OwningJiraComponent: "kube-apiserver",
-		ResponsiblePerson:   "benluddy",
-		OwningProduct:       kubernetes,
-	}
-
-	FeatureGateGatewayAPI = FeatureGateName("GatewayAPI")
-	gateGatewayAPI        = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateGatewayAPI,
-		},
-		OwningJiraComponent: "Routing",
-		ResponsiblePerson:   "miciah",
-		OwningProduct:       ocpSpecific,
-	}
-
-	FeatureGateOpenShiftPodSecurityAdmission = FeatureGateName("OpenShiftPodSecurityAdmission")
-	openShiftPodSecurityAdmission            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateOpenShiftPodSecurityAdmission,
-		},
-		OwningJiraComponent: "auth",
-		ResponsiblePerson:   "stlaz",
-		OwningProduct:       ocpSpecific,
-	}
-
-	FeatureGateExternalCloudProvider = FeatureGateName("ExternalCloudProvider")
-	externalCloudProvider            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateExternalCloudProvider,
-		},
-		OwningJiraComponent: "cloud-provider",
-		ResponsiblePerson:   "jspeed",
-		OwningProduct:       ocpSpecific,
-	}
-
-	FeatureGateExternalCloudProviderAzure = FeatureGateName("ExternalCloudProviderAzure")
-	externalCloudProviderAzure            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateExternalCloudProviderAzure,
-		},
-		OwningJiraComponent: "cloud-provider",
-		ResponsiblePerson:   "jspeed",
-		OwningProduct:       ocpSpecific,
-	}
-
-	FeatureGateExternalCloudProviderGCP = FeatureGateName("ExternalCloudProviderGCP")
-	externalCloudProviderGCP            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateExternalCloudProviderGCP,
-		},
-		OwningJiraComponent: "cloud-provider",
-		ResponsiblePerson:   "jspeed",
-		OwningProduct:       ocpSpecific,
-	}
-
-	FeatureGateExternalCloudProviderExternal = FeatureGateName("ExternalCloudProviderExternal")
-	externalCloudProviderExternal            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateExternalCloudProviderExternal,
-		},
-		OwningJiraComponent: "cloud-provider",
-		ResponsiblePerson:   "elmiko",
-		OwningProduct:       ocpSpecific,
-	}
-
-	FeatureGateCSIDriverSharedResource = FeatureGateName("CSIDriverSharedResource")
-	csiDriverSharedResource            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateCSIDriverSharedResource,
-		},
-		OwningJiraComponent: "builds",
-		ResponsiblePerson:   "adkaplan",
-		OwningProduct:       ocpSpecific,
-	}
+type featureGateBuilder struct {
+	name                string
+	owningJiraComponent string
+	responsiblePerson   string
+	owningProduct       OwningProduct
 
-	FeatureGateBuildCSIVolumes = FeatureGateName("BuildCSIVolumes")
-	buildCSIVolumes            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateBuildCSIVolumes,
-		},
-		OwningJiraComponent: "builds",
-		ResponsiblePerson:   "adkaplan",
-		OwningProduct:       ocpSpecific,
-	}
-
-	FeatureGateNodeSwap = FeatureGateName("NodeSwap")
-	nodeSwap            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateNodeSwap,
-		},
-		OwningJiraComponent: "node",
-		ResponsiblePerson:   "ehashman",
-		OwningProduct:       kubernetes,
-	}
-
-	FeatureGateMachineAPIProviderOpenStack = FeatureGateName("MachineAPIProviderOpenStack")
-	machineAPIProviderOpenStack            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateMachineAPIProviderOpenStack,
-		},
-		OwningJiraComponent: "openstack",
-		ResponsiblePerson:   "egarcia",
-		OwningProduct:       ocpSpecific,
-	}
-
-	FeatureGateInsightsConfigAPI = FeatureGateName("InsightsConfigAPI")
-	insightsConfigAPI            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateInsightsConfigAPI,
-		},
-		OwningJiraComponent: "insights",
-		ResponsiblePerson:   "tremes",
-		OwningProduct:       ocpSpecific,
-	}
-
-	FeatureGateDynamicResourceAllocation = FeatureGateName("DynamicResourceAllocation")
-	dynamicResourceAllocation            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateDynamicResourceAllocation,
-		},
-		OwningJiraComponent: "scheduling",
-		ResponsiblePerson:   "jchaloup",
-		OwningProduct:       kubernetes,
-	}
-
-	FeatureGateAzureWorkloadIdentity = FeatureGateName("AzureWorkloadIdentity")
-	azureWorkloadIdentity            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateAzureWorkloadIdentity,
-		},
-		OwningJiraComponent: "cloud-credential-operator",
-		ResponsiblePerson:   "abutcher",
-		OwningProduct:       ocpSpecific,
-	}
-
-	FeatureGateMaxUnavailableStatefulSet = FeatureGateName("MaxUnavailableStatefulSet")
-	maxUnavailableStatefulSet            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateMaxUnavailableStatefulSet,
-		},
-		OwningJiraComponent: "apps",
-		ResponsiblePerson:   "atiratree",
-		OwningProduct:       kubernetes,
-	}
-
-	FeatureGateEventedPLEG = FeatureGateName("EventedPLEG")
-	eventedPleg            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateEventedPLEG,
-		},
-		OwningJiraComponent: "node",
-		ResponsiblePerson:   "sairameshv",
-		OwningProduct:       kubernetes,
-	}
-
-	FeatureGatePrivateHostedZoneAWS = FeatureGateName("PrivateHostedZoneAWS")
-	privateHostedZoneAWS            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGatePrivateHostedZoneAWS,
-		},
-		OwningJiraComponent: "Routing",
-		ResponsiblePerson:   "miciah",
-		OwningProduct:       ocpSpecific,
-	}
-
-	FeatureGateSigstoreImageVerification = FeatureGateName("SigstoreImageVerification")
-	sigstoreImageVerification            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateSigstoreImageVerification,
-		},
-		OwningJiraComponent: "node",
-		ResponsiblePerson:   "sgrunert",
-		OwningProduct:       ocpSpecific,
-	}
-
-	FeatureGateGCPLabelsTags = FeatureGateName("GCPLabelsTags")
-	gcpLabelsTags            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateGCPLabelsTags,
-		},
-		OwningJiraComponent: "Installer",
-		ResponsiblePerson:   "bhb",
-		OwningProduct:       ocpSpecific,
-	}
-
-	FeatureGateAlibabaPlatform = FeatureGateName("AlibabaPlatform")
-	alibabaPlatform            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateAlibabaPlatform,
-		},
-		OwningJiraComponent: "cloud-provider",
-		ResponsiblePerson:   "jspeed",
-		OwningProduct:       ocpSpecific,
-	}
+	statusByClusterProfileByFeatureSet map[ClusterProfileName]map[FeatureSet]bool
+}
 
-	FeatureGateCloudDualStackNodeIPs = FeatureGateName("CloudDualStackNodeIPs")
-	cloudDualStackNodeIPs            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateCloudDualStackNodeIPs,
-		},
-		OwningJiraComponent: "machine-config-operator/platform-baremetal",
-		ResponsiblePerson:   "mkowalsk",
-		OwningProduct:       kubernetes,
-	}
-	FeatureGateVSphereStaticIPs = FeatureGateName("VSphereStaticIPs")
-	vSphereStaticIPs            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateVSphereStaticIPs,
-		},
-		OwningJiraComponent: "splat",
-		ResponsiblePerson:   "rvanderp3",
-		OwningProduct:       ocpSpecific,
+// newFeatureGate featuregate are disabled in every FeatureSet and selectively enabled
+func newFeatureGate(name string) *featureGateBuilder {
+	b := &featureGateBuilder{
+		name:                               name,
+		statusByClusterProfileByFeatureSet: map[ClusterProfileName]map[FeatureSet]bool{},
 	}
-
-	FeatureGateRouteExternalCertificate = FeatureGateName("RouteExternalCertificate")
-	routeExternalCertificate            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateRouteExternalCertificate,
-		},
-		OwningJiraComponent: "router",
-		ResponsiblePerson:   "thejasn",
-		OwningProduct:       ocpSpecific,
+	for _, clusterProfile := range AllClusterProfiles {
+		byFeatureSet := map[FeatureSet]bool{}
+		for _, featureSet := range AllFixedFeatureSets {
+			byFeatureSet[featureSet] = false
+		}
+		b.statusByClusterProfileByFeatureSet[clusterProfile] = byFeatureSet
 	}
+	return b
+}
 
-	FeatureGateAdminNetworkPolicy = FeatureGateName("AdminNetworkPolicy")
-	adminNetworkPolicy            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateAdminNetworkPolicy,
-		},
-		OwningJiraComponent: "Networking/ovn-kubernetes",
-		ResponsiblePerson:   "tssurya",
-		OwningProduct:       ocpSpecific,
-	}
+func (b *featureGateBuilder) reportProblemsToJiraComponent(owningJiraComponent string) *featureGateBuilder {
+	b.owningJiraComponent = owningJiraComponent
+	return b
+}
 
-	FeatureGateNetworkLiveMigration = FeatureGateName("NetworkLiveMigration")
-	sdnLiveMigration                = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateNetworkLiveMigration,
-		},
-		OwningJiraComponent: "Networking/ovn-kubernetes",
-		ResponsiblePerson:   "pliu",
-		OwningProduct:       ocpSpecific,
-	}
+func (b *featureGateBuilder) contactPerson(responsiblePerson string) *featureGateBuilder {
+	b.responsiblePerson = responsiblePerson
+	return b
+}
 
-	FeatureGateAutomatedEtcdBackup = FeatureGateName("AutomatedEtcdBackup")
-	automatedEtcdBackup            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateAutomatedEtcdBackup,
-		},
-		OwningJiraComponent: "etcd",
-		ResponsiblePerson:   "hasbro17",
-		OwningProduct:       ocpSpecific,
-	}
+func (b *featureGateBuilder) productScope(owningProduct OwningProduct) *featureGateBuilder {
+	b.owningProduct = owningProduct
+	return b
+}
 
-	FeatureGateMachineAPIOperatorDisableMachineHealthCheckController = FeatureGateName("MachineAPIOperatorDisableMachineHealthCheckController")
-	machineAPIOperatorDisableMachineHealthCheckController            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateMachineAPIOperatorDisableMachineHealthCheckController,
-		},
-		OwningJiraComponent: "ecoproject",
-		ResponsiblePerson:   "msluiter",
-		OwningProduct:       ocpSpecific,
+func (b *featureGateBuilder) enableIn(featureSets ...FeatureSet) *featureGateBuilder {
+	for clusterProfile := range b.statusByClusterProfileByFeatureSet {
+		for _, featureSet := range featureSets {
+			b.statusByClusterProfileByFeatureSet[clusterProfile][featureSet] = true
+		}
 	}
+	return b
+}
 
-	FeatureGateDNSNameResolver = FeatureGateName("DNSNameResolver")
-	dnsNameResolver            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateDNSNameResolver,
-		},
-		OwningJiraComponent: "dns",
-		ResponsiblePerson:   "miciah",
-		OwningProduct:       ocpSpecific,
+func (b *featureGateBuilder) enableForClusterProfile(clusterProfile ClusterProfileName, featureSets ...FeatureSet) *featureGateBuilder {
+	for _, featureSet := range featureSets {
+		b.statusByClusterProfileByFeatureSet[clusterProfile][featureSet] = true
 	}
+	return b
+}
 
-	FeatureGateVSphereControlPlaneMachineset = FeatureGateName("VSphereControlPlaneMachineSet")
-	vSphereControlPlaneMachineset            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateVSphereControlPlaneMachineset,
-		},
-		OwningJiraComponent: "splat",
-		ResponsiblePerson:   "rvanderp3",
-		OwningProduct:       ocpSpecific,
+func (b *featureGateBuilder) register() (FeatureGateName, error) {
+	if len(b.name) == 0 {
+		return "", fmt.Errorf("missing name")
 	}
-
-	FeatureGateMachineConfigNodes = FeatureGateName("MachineConfigNodes")
-	machineConfigNodes            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateMachineConfigNodes,
-		},
-		OwningJiraComponent: "MachineConfigOperator",
-		ResponsiblePerson:   "cdoern",
-		OwningProduct:       ocpSpecific,
+	if len(b.owningJiraComponent) == 0 {
+		return "", fmt.Errorf("missing owningJiraComponent")
 	}
-
-	FeatureGateClusterAPIInstall = FeatureGateName("ClusterAPIInstall")
-	clusterAPIInstall            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateClusterAPIInstall,
-		},
-		OwningJiraComponent: "Installer",
-		ResponsiblePerson:   "vincepri",
-		OwningProduct:       ocpSpecific,
+	if len(b.responsiblePerson) == 0 {
+		return "", fmt.Errorf("missing responsiblePerson")
 	}
-
-	FeatureGateMetricsServer = FeatureGateName("MetricsServer")
-	metricsServer            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateMetricsServer,
-		},
-		OwningJiraComponent: "Monitoring",
-		ResponsiblePerson:   "slashpai",
-		OwningProduct:       ocpSpecific,
+	if len(b.owningProduct) == 0 {
+		return "", fmt.Errorf("missing owningProduct")
 	}
 
-	FeatureGateInstallAlternateInfrastructureAWS = FeatureGateName("InstallAlternateInfrastructureAWS")
-	installAlternateInfrastructureAWS            = FeatureGateDescription{
+	featureGateName := FeatureGateName(b.name)
+	description := FeatureGateDescription{
 		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateInstallAlternateInfrastructureAWS,
+			Name: featureGateName,
 		},
-		OwningJiraComponent: "Installer",
-		ResponsiblePerson:   "padillon",
-		OwningProduct:       ocpSpecific,
+		OwningJiraComponent: b.owningJiraComponent,
+		ResponsiblePerson:   b.responsiblePerson,
+		OwningProduct:       b.owningProduct,
 	}
 
-	FeatureGateGCPClusterHostedDNS = FeatureGateName("GCPClusterHostedDNS")
-	gcpClusterHostedDNS            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateGCPClusterHostedDNS,
-		},
-		OwningJiraComponent: "Installer",
-		ResponsiblePerson:   "barbacbd",
-		OwningProduct:       ocpSpecific,
-	}
+	// statusByClusterProfileByFeatureSet is initialized by constructor to be false for every combination
+	for clusterProfile, byFeatureSet := range b.statusByClusterProfileByFeatureSet {
+		for featureSet, enabled := range byFeatureSet {
+			if _, ok := allFeatureGates[clusterProfile]; !ok {
+				allFeatureGates[clusterProfile] = map[FeatureSet]*FeatureGateEnabledDisabled{}
+			}
+			if _, ok := allFeatureGates[clusterProfile][featureSet]; !ok {
+				allFeatureGates[clusterProfile][featureSet] = &FeatureGateEnabledDisabled{}
+			}
 
-	FeatureGateMixedCPUsAllocation = FeatureGateName("MixedCPUsAllocation")
-	mixedCPUsAllocation            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateMixedCPUsAllocation,
-		},
-		OwningJiraComponent: "NodeTuningOperator",
-		ResponsiblePerson:   "titzhak",
-		OwningProduct:       ocpSpecific,
+			if enabled {
+				allFeatureGates[clusterProfile][featureSet].Enabled = append(allFeatureGates[clusterProfile][featureSet].Enabled, description)
+			} else {
+				allFeatureGates[clusterProfile][featureSet].Disabled = append(allFeatureGates[clusterProfile][featureSet].Disabled, description)
+			}
+		}
 	}
 
-	FeatureGateManagedBootImages = FeatureGateName("ManagedBootImages")
-	managedBootImages            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateManagedBootImages,
-		},
-		OwningJiraComponent: "MachineConfigOperator",
-		ResponsiblePerson:   "djoshy",
-		OwningProduct:       ocpSpecific,
-	}
+	return featureGateName, nil
+}
 
-	FeatureGateDisableKubeletCloudCredentialProviders = FeatureGateName("DisableKubeletCloudCredentialProviders")
-	disableKubeletCloudCredentialProviders            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateDisableKubeletCloudCredentialProviders,
-		},
-		OwningJiraComponent: "cloud-provider",
-		ResponsiblePerson:   "jspeed",
-		OwningProduct:       kubernetes,
+func (b *featureGateBuilder) mustRegister() FeatureGateName {
+	ret, err := b.register()
+	if err != nil {
+		panic(err)
 	}
+	return ret
+}
 
-	FeatureGateOnClusterBuild = FeatureGateName("OnClusterBuild")
-	onClusterBuild            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateOnClusterBuild,
-		},
-		OwningJiraComponent: "MachineConfigOperator",
-		ResponsiblePerson:   "dkhater",
-		OwningProduct:       ocpSpecific,
+func FeatureSets(clusterProfile ClusterProfileName, featureSet FeatureSet) (*FeatureGateEnabledDisabled, error) {
+	byFeatureSet, ok := allFeatureGates[clusterProfile]
+	if !ok {
+		return nil, fmt.Errorf("no information found for ClusterProfile=%q", clusterProfile)
 	}
-
-	FeatureGateSignatureStores = FeatureGateName("SignatureStores")
-	signatureStores            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateSignatureStores,
-		},
-		OwningJiraComponent: "Cluster Version Operator",
-		ResponsiblePerson:   "lmohanty",
-		OwningProduct:       ocpSpecific,
+	featureGates, ok := byFeatureSet[featureSet]
+	if !ok {
+		return nil, fmt.Errorf("no information found for FeatureSet=%q under ClusterProfile=%q", featureSet, clusterProfile)
 	}
+	return featureGates.DeepCopy(), nil
+}
 
-	FeatureGateKMSv1 = FeatureGateName("KMSv1")
-	kmsv1            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateKMSv1,
-		},
-		OwningJiraComponent: "kube-apiserver",
-		ResponsiblePerson:   "dgrisonnet",
-		OwningProduct:       kubernetes,
-	}
+func AllFeatureSets() map[ClusterProfileName]map[FeatureSet]*FeatureGateEnabledDisabled {
+	ret := map[ClusterProfileName]map[FeatureSet]*FeatureGateEnabledDisabled{}
 
-	FeatureGatePinnedImages = FeatureGateName("PinnedImages")
-	pinnedImages            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGatePinnedImages,
-		},
-		OwningJiraComponent: "MachineConfigOperator",
-		ResponsiblePerson:   "jhernand",
-		OwningProduct:       ocpSpecific,
-	}
+	for clusterProfile, byFeatureSet := range allFeatureGates {
+		newByFeatureSet := map[FeatureSet]*FeatureGateEnabledDisabled{}
 
-	FeatureGateUpgradeStatus = FeatureGateName("UpgradeStatus")
-	upgradeStatus            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateUpgradeStatus,
-		},
-		OwningJiraComponent: "Cluster Version Operator",
-		ResponsiblePerson:   "pmuller",
-		OwningProduct:       ocpSpecific,
+		for featureSet, enabledDisabled := range byFeatureSet {
+			newByFeatureSet[featureSet] = enabledDisabled.DeepCopy()
+		}
+		ret[clusterProfile] = newByFeatureSet
 	}
 
-	FeatureGateTranslateStreamCloseWebsocketRequests = FeatureGateName("TranslateStreamCloseWebsocketRequests")
-	translateStreamCloseWebsocketRequests            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateTranslateStreamCloseWebsocketRequests,
-		},
-		OwningJiraComponent: "kube-apiserver",
-		ResponsiblePerson:   "akashem",
-		OwningProduct:       kubernetes,
-	}
+	return ret
+}
 
-	FeatureGateVolumeGroupSnapshot = FeatureGateName("VolumeGroupSnapshot")
-	volumeGroupSnapshot            = FeatureGateDescription{
-		FeatureGateAttributes: FeatureGateAttributes{
-			Name: FeatureGateVolumeGroupSnapshot,
-		},
-		OwningJiraComponent: "Storage / Kubernetes External Components",
-		ResponsiblePerson:   "fbertina",
-		OwningProduct:       kubernetes,
-	}
+var (
+	allFeatureGates = map[ClusterProfileName]map[FeatureSet]*FeatureGateEnabledDisabled{}
+
+	FeatureGateValidatingAdmissionPolicy = newFeatureGate("ValidatingAdmissionPolicy").
+						reportProblemsToJiraComponent("kube-apiserver").
+						contactPerson("benluddy").
+						productScope(kubernetes).
+						enableIn(TechPreviewNoUpgrade).
+						mustRegister()
+
+	FeatureGateGatewayAPI = newFeatureGate("GatewayAPI").
+				reportProblemsToJiraComponent("Routing").
+				contactPerson("miciah").
+				productScope(ocpSpecific).
+				enableIn(TechPreviewNoUpgrade).
+				mustRegister()
+
+	FeatureGateOpenShiftPodSecurityAdmission = newFeatureGate("OpenShiftPodSecurityAdmission").
+							reportProblemsToJiraComponent("auth").
+							contactPerson("stlaz").
+							productScope(ocpSpecific).
+							enableIn(Default, TechPreviewNoUpgrade).
+							mustRegister()
+
+	FeatureGateExternalCloudProvider = newFeatureGate("ExternalCloudProvider").
+						reportProblemsToJiraComponent("cloud-provider").
+						contactPerson("jspeed").
+						productScope(ocpSpecific).
+						enableIn(Default, TechPreviewNoUpgrade).
+						mustRegister()
+
+	FeatureGateExternalCloudProviderAzure = newFeatureGate("ExternalCloudProviderAzure").
+						reportProblemsToJiraComponent("cloud-provider").
+						contactPerson("jspeed").
+						productScope(ocpSpecific).
+						enableIn(Default, TechPreviewNoUpgrade).
+						mustRegister()
+
+	FeatureGateExternalCloudProviderGCP = newFeatureGate("ExternalCloudProviderGCP").
+						reportProblemsToJiraComponent("cloud-provider").
+						contactPerson("jspeed").
+						productScope(ocpSpecific).
+						enableIn(Default, TechPreviewNoUpgrade).
+						mustRegister()
+
+	FeatureGateExternalCloudProviderExternal = newFeatureGate("ExternalCloudProviderExternal").
+							reportProblemsToJiraComponent("cloud-provider").
+							contactPerson("elmiko").
+							productScope(ocpSpecific).
+							enableIn(Default, TechPreviewNoUpgrade).
+							mustRegister()
+
+	FeatureGateCSIDriverSharedResource = newFeatureGate("CSIDriverSharedResource").
+						reportProblemsToJiraComponent("builds").
+						contactPerson("adkaplan").
+						productScope(ocpSpecific).
+						enableIn(TechPreviewNoUpgrade).
+						mustRegister()
+
+	FeatureGateBuildCSIVolumes = newFeatureGate("BuildCSIVolumes").
+					reportProblemsToJiraComponent("builds").
+					contactPerson("adkaplan").
+					productScope(ocpSpecific).
+					enableIn(Default, TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateNodeSwap = newFeatureGate("NodeSwap").
+				reportProblemsToJiraComponent("node").
+				contactPerson("ehashman").
+				productScope(kubernetes).
+				enableIn(TechPreviewNoUpgrade).
+				mustRegister()
+
+	FeatureGateMachineAPIProviderOpenStack = newFeatureGate("MachineAPIProviderOpenStack").
+						reportProblemsToJiraComponent("openstack").
+						contactPerson("egarcia").
+						productScope(ocpSpecific).
+						enableIn(TechPreviewNoUpgrade).
+						mustRegister()
+
+	FeatureGateInsightsConfigAPI = newFeatureGate("InsightsConfigAPI").
+					reportProblemsToJiraComponent("insights").
+					contactPerson("tremes").
+					productScope(ocpSpecific).
+					enableIn(TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateDynamicResourceAllocation = newFeatureGate("DynamicResourceAllocation").
+						reportProblemsToJiraComponent("scheduling").
+						contactPerson("jchaloup").
+						productScope(kubernetes).
+						enableIn(TechPreviewNoUpgrade).
+						mustRegister()
+
+	FeatureGateAzureWorkloadIdentity = newFeatureGate("AzureWorkloadIdentity").
+						reportProblemsToJiraComponent("cloud-credential-operator").
+						contactPerson("abutcher").
+						productScope(ocpSpecific).
+						enableIn(Default, TechPreviewNoUpgrade).
+						mustRegister()
+
+	FeatureGateMaxUnavailableStatefulSet = newFeatureGate("MaxUnavailableStatefulSet").
+						reportProblemsToJiraComponent("apps").
+						contactPerson("atiratree").
+						productScope(kubernetes).
+						enableIn(TechPreviewNoUpgrade).
+						mustRegister()
+
+	FeatureGateEventedPLEG = newFeatureGate("EventedPLEG").
+				reportProblemsToJiraComponent("node").
+				contactPerson("sairameshv").
+				productScope(kubernetes).
+				mustRegister()
+
+	FeatureGatePrivateHostedZoneAWS = newFeatureGate("PrivateHostedZoneAWS").
+					reportProblemsToJiraComponent("Routing").
+					contactPerson("miciah").
+					productScope(ocpSpecific).
+					enableIn(Default, TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateSigstoreImageVerification = newFeatureGate("SigstoreImageVerification").
+						reportProblemsToJiraComponent("node").
+						contactPerson("sgrunert").
+						productScope(ocpSpecific).
+						enableIn(TechPreviewNoUpgrade).
+						mustRegister()
+
+	FeatureGateGCPLabelsTags = newFeatureGate("GCPLabelsTags").
+					reportProblemsToJiraComponent("Installer").
+					contactPerson("bhb").
+					productScope(ocpSpecific).
+					enableIn(TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateAlibabaPlatform = newFeatureGate("AlibabaPlatform").
+					reportProblemsToJiraComponent("cloud-provider").
+					contactPerson("jspeed").
+					productScope(ocpSpecific).
+					enableIn(Default, TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateCloudDualStackNodeIPs = newFeatureGate("CloudDualStackNodeIPs").
+						reportProblemsToJiraComponent("machine-config-operator/platform-baremetal").
+						contactPerson("mkowalsk").
+						productScope(kubernetes).
+						enableIn(Default, TechPreviewNoUpgrade).
+						mustRegister()
+
+	FeatureGateVSphereStaticIPs = newFeatureGate("VSphereStaticIPs").
+					reportProblemsToJiraComponent("splat").
+					contactPerson("rvanderp3").
+					productScope(ocpSpecific).
+					enableIn(Default, TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateRouteExternalCertificate = newFeatureGate("RouteExternalCertificate").
+						reportProblemsToJiraComponent("router").
+						contactPerson("thejasn").
+						productScope(ocpSpecific).
+						enableIn(TechPreviewNoUpgrade).
+						mustRegister()
+
+	FeatureGateAdminNetworkPolicy = newFeatureGate("AdminNetworkPolicy").
+					reportProblemsToJiraComponent("Networking/ovn-kubernetes").
+					contactPerson("tssurya").
+					productScope(ocpSpecific).
+					enableIn(TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateNetworkLiveMigration = newFeatureGate("NetworkLiveMigration").
+					reportProblemsToJiraComponent("Networking/ovn-kubernetes").
+					contactPerson("pliu").
+					productScope(ocpSpecific).
+					enableIn(Default, TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateHardwareSpeed = newFeatureGate("HardwareSpeed").
+					reportProblemsToJiraComponent("etcd").
+					contactPerson("hasbro17").
+					productScope(ocpSpecific).
+					enableIn(TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateAutomatedEtcdBackup = newFeatureGate("AutomatedEtcdBackup").
+					reportProblemsToJiraComponent("etcd").
+					contactPerson("hasbro17").
+					productScope(ocpSpecific).
+					enableIn(TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateMachineAPIOperatorDisableMachineHealthCheckController = newFeatureGate("MachineAPIOperatorDisableMachineHealthCheckController").
+										reportProblemsToJiraComponent("ecoproject").
+										contactPerson("msluiter").
+										productScope(ocpSpecific).
+										mustRegister()
+
+	FeatureGateDNSNameResolver = newFeatureGate("DNSNameResolver").
+					reportProblemsToJiraComponent("dns").
+					contactPerson("miciah").
+					productScope(ocpSpecific).
+					enableIn(TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateVSphereControlPlaneMachineset = newFeatureGate("VSphereControlPlaneMachineSet").
+							reportProblemsToJiraComponent("splat").
+							contactPerson("rvanderp3").
+							productScope(ocpSpecific).
+							enableIn(Default, TechPreviewNoUpgrade).
+							mustRegister()
+
+	FeatureGateMachineConfigNodes = newFeatureGate("MachineConfigNodes").
+					reportProblemsToJiraComponent("MachineConfigOperator").
+					contactPerson("cdoern").
+					productScope(ocpSpecific).
+					enableIn(TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateClusterAPIInstall = newFeatureGate("ClusterAPIInstall").
+					reportProblemsToJiraComponent("Installer").
+					contactPerson("vincepri").
+					productScope(ocpSpecific).
+					mustRegister()
+
+	FeatureGateMetricsServer = newFeatureGate("MetricsServer").
+					reportProblemsToJiraComponent("Monitoring").
+					contactPerson("slashpai").
+					productScope(ocpSpecific).
+					enableIn(TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateInstallAlternateInfrastructureAWS = newFeatureGate("InstallAlternateInfrastructureAWS").
+							reportProblemsToJiraComponent("Installer").
+							contactPerson("padillon").
+							productScope(ocpSpecific).
+							enableIn(TechPreviewNoUpgrade).
+							mustRegister()
+
+	FeatureGateGCPClusterHostedDNS = newFeatureGate("GCPClusterHostedDNS").
+					reportProblemsToJiraComponent("Installer").
+					contactPerson("barbacbd").
+					productScope(ocpSpecific).
+					enableIn(TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateMixedCPUsAllocation = newFeatureGate("MixedCPUsAllocation").
+					reportProblemsToJiraComponent("NodeTuningOperator").
+					contactPerson("titzhak").
+					productScope(ocpSpecific).
+					enableIn(TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateManagedBootImages = newFeatureGate("ManagedBootImages").
+					reportProblemsToJiraComponent("MachineConfigOperator").
+					contactPerson("djoshy").
+					productScope(ocpSpecific).
+					enableIn(TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateDisableKubeletCloudCredentialProviders = newFeatureGate("DisableKubeletCloudCredentialProviders").
+								reportProblemsToJiraComponent("cloud-provider").
+								contactPerson("jspeed").
+								productScope(kubernetes).
+								mustRegister()
+
+	FeatureGateOnClusterBuild = newFeatureGate("OnClusterBuild").
+					reportProblemsToJiraComponent("MachineConfigOperator").
+					contactPerson("dkhater").
+					productScope(ocpSpecific).
+					enableIn(TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateSignatureStores = newFeatureGate("SignatureStores").
+					reportProblemsToJiraComponent("Cluster Version Operator").
+					contactPerson("lmohanty").
+					productScope(ocpSpecific).
+					enableIn(TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateKMSv1 = newFeatureGate("KMSv1").
+				reportProblemsToJiraComponent("kube-apiserver").
+				contactPerson("dgrisonnet").
+				productScope(kubernetes).
+				enableIn(Default, TechPreviewNoUpgrade).
+				mustRegister()
+
+	FeatureGatePinnedImages = newFeatureGate("PinnedImages").
+				reportProblemsToJiraComponent("MachineConfigOperator").
+				contactPerson("jhernand").
+				productScope(ocpSpecific).
+				enableIn(TechPreviewNoUpgrade).
+				mustRegister()
+
+	FeatureGateUpgradeStatus = newFeatureGate("UpgradeStatus").
+					reportProblemsToJiraComponent("Cluster Version Operator").
+					contactPerson("pmuller").
+					productScope(ocpSpecific).
+					enableIn(TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateTranslateStreamCloseWebsocketRequests = newFeatureGate("TranslateStreamCloseWebsocketRequests").
+								reportProblemsToJiraComponent("kube-apiserver").
+								contactPerson("akashem").
+								productScope(kubernetes).
+								enableIn(TechPreviewNoUpgrade).
+								mustRegister()
+
+	FeatureGateVolumeGroupSnapshot = newFeatureGate("VolumeGroupSnapshot").
+					reportProblemsToJiraComponent("Storage / Kubernetes External Components").
+					contactPerson("fbertina").
+					productScope(kubernetes).
+					enableIn(TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateExternalOIDC = newFeatureGate("ExternalOIDC").
+				reportProblemsToJiraComponent("authentication").
+				contactPerson("stlaz").
+				productScope(ocpSpecific).
+				enableIn(TechPreviewNoUpgrade).
+				enableForClusterProfile(Hypershift, Default, TechPreviewNoUpgrade).
+				mustRegister()
+
+	FeatureGateExample = newFeatureGate("Example").
+				reportProblemsToJiraComponent("cluster-config").
+				contactPerson("deads").
+				productScope(ocpSpecific).
+				enableIn(TechPreviewNoUpgrade).
+				mustRegister()
+
+	FeatureGatePlatformOperators = newFeatureGate("PlatformOperators").
+					reportProblemsToJiraComponent("olm").
+					contactPerson("joe").
+					productScope(ocpSpecific).
+					enableIn(TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateNewOLM = newFeatureGate("NewOLM").
+				reportProblemsToJiraComponent("olm").
+				contactPerson("joe").
+				productScope(ocpSpecific).
+				enableIn(TechPreviewNoUpgrade).
+				mustRegister()
+
+	FeatureGateExternalRouteCertificate = newFeatureGate("ExternalRouteCertificate").
+						reportProblemsToJiraComponent("network-edge").
+						contactPerson("miciah").
+						productScope(ocpSpecific).
+						enableIn(TechPreviewNoUpgrade).
+						mustRegister()
+
+	FeatureGateInsightsOnDemandDataGather = newFeatureGate("InsightsOnDemandDataGather").
+						reportProblemsToJiraComponent("insights").
+						contactPerson("tremes").
+						productScope(ocpSpecific).
+						enableIn(TechPreviewNoUpgrade).
+						mustRegister()
+
+	FeatureGateAlertingRules = newFeatureGate("AlertingRules").
+					reportProblemsToJiraComponent("Monitoring").
+					contactPerson("simon").
+					productScope(ocpSpecific).
+					enableIn(TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateBareMetalLoadBalancer = newFeatureGate("BareMetalLoadBalancer").
+						reportProblemsToJiraComponent("metal").
+						contactPerson("EmilienM").
+						productScope(ocpSpecific).
+						enableIn(Default, TechPreviewNoUpgrade).
+						mustRegister()
+
+	FeatureGateInsightsConfig = newFeatureGate("InsightsConfig").
+					reportProblemsToJiraComponent("insights").
+					contactPerson("tremes").
+					productScope(ocpSpecific).
+					enableIn(TechPreviewNoUpgrade).
+					mustRegister()
+
+	FeatureGateImagePolicy = newFeatureGate("ImagePolicy").
+				reportProblemsToJiraComponent("node").
+				contactPerson("rphillips").
+				productScope(ocpSpecific).
+				enableIn(TechPreviewNoUpgrade).
+				mustRegister()
+
+	FeatureGateNodeDisruptionPolicy = newFeatureGate("NodeDisruptionPolicy").
+					reportProblemsToJiraComponent("MachineConfigOperator").
+					contactPerson("jerzhang").
+					productScope(ocpSpecific).
+					enableIn(TechPreviewNoUpgrade).
+					mustRegister()
 )
diff --git a/vendor/github.com/openshift/api/config/v1/stable.apiserver.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.apiserver.testsuite.yaml
index 75f846a3..0b32b75c 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.apiserver.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.apiserver.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] APIServer"
-crd: 0000_10_config-operator_01_apiserver-Default.crd.yaml
+crd: 0000_10_config-operator_01_apiservers.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create encrypt with aescbc
diff --git a/vendor/github.com/openshift/api/config/v1/stable.authentication.single.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.authentication.single.testsuite.yaml
new file mode 100644
index 00000000..0bfacdb4
--- /dev/null
+++ b/vendor/github.com/openshift/api/config/v1/stable.authentication.single.testsuite.yaml
@@ -0,0 +1,21 @@
+apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
+name: "[Stable] Authentication SingleNode"
+crd: 0000_10_config-operator_01_authentications-SingleNode-Default.crd.yaml
+tests:
+  onCreate:
+  - name: Should be able to create a minimal Authentication
+    initial: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec: {} # No spec is required for a Authentication
+    expected: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec: {}
+  - name: Shouldn't be able to use the OIDC type in a stable version of the resource
+    initial: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+    expectedError: "spec.type: Unsupported value: \"OIDC\": supported values: \"\", \"None\", \"IntegratedOAuth\""
\ No newline at end of file
diff --git a/vendor/github.com/openshift/api/config/v1/stable.authentication.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.authentication.testsuite.yaml
index 6e966c15..680e0bc3 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.authentication.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.authentication.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] Authentication"
-crd: 0000_10_config-operator_01_authentication.crd-Default.yaml
+crd: 0000_10_config-operator_01_authentications-SelfManagedHA-Default.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal Authentication
diff --git a/vendor/github.com/openshift/api/config/v1/stable.build.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.build.testsuite.yaml
index b422ebd2..d954f142 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.build.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.build.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] Build"
-crd: 0000_10_openshift-controller-manager-operator_01_build.crd.yaml
+crd: 0000_10_openshift-controller-manager_01_builds.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal Build
diff --git a/vendor/github.com/openshift/api/config/v1/stable.clusteroperator.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.clusteroperator.testsuite.yaml
index 177e8f69..cd4363fe 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.clusteroperator.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.clusteroperator.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] ClusterOperator"
-crd: 0000_00_cluster-version-operator_01_clusteroperator.crd.yaml
+crd: 0000_00_cluster-version-operator_01_clusteroperators.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal ClusterOperator
diff --git a/vendor/github.com/openshift/api/config/v1/stable.clusterversion.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.clusterversion.testsuite.yaml
index 4c3fed14..ee108929 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.clusterversion.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.clusterversion.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] ClusterVersion"
-crd: 0000_00_cluster-version-operator_01_clusterversion-Default.crd.yaml
+crd: 0000_00_cluster-version-operator_01_clusterversions-Default.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal ClusterVersion
diff --git a/vendor/github.com/openshift/api/config/v1/stable.console.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.console.testsuite.yaml
index 0081816f..d2fb2b59 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.console.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.console.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] Console"
-crd: 0000_10_config-operator_01_console.crd.yaml
+crd: 0000_10_config-operator_01_consoles.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal Console
diff --git a/vendor/github.com/openshift/api/config/v1/stable.dns.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.dns.testsuite.yaml
index 3054d200..0f052307 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.dns.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.dns.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] DNS"
-crd: 0000_10_config-operator_01_dns-Default.crd.yaml
+crd: 0000_10_config-operator_01_dnses.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal DNS
diff --git a/vendor/github.com/openshift/api/config/v1/stable.featuregate.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.featuregate.testsuite.yaml
index 6b6a4327..ca29248e 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.featuregate.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.featuregate.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] FeatureGate"
-crd: 0000_10_config-operator_01_featuregate.crd.yaml
+crd: 0000_10_config-operator_01_featuregates.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal FeatureGate
diff --git a/vendor/github.com/openshift/api/config/v1/stable.hypershift.authentication.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.hypershift.authentication.testsuite.yaml
index 406bf386..cfd006e3 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.hypershift.authentication.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.hypershift.authentication.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable][Hypershift] Authentication"
-crd: 0000_10_config-operator_01_authentication.crd-Default-Hypershift.yaml
+crd: 0000_10_config-operator_01_authentications-Hypershift.crd.yaml
 tests:
   onCreate:
     - name: Should be able to create a minimal Authentication
diff --git a/vendor/github.com/openshift/api/config/v1/stable.image.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.image.testsuite.yaml
index 6bfbb820..34a4d23d 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.image.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.image.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] Image"
-crd: 0000_10_config-operator_01_image.crd.yaml
+crd: 0000_10_config-operator_01_images.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal Image
diff --git a/vendor/github.com/openshift/api/config/v1/stable.imagecontentpolicy.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.imagecontentpolicy.testsuite.yaml
index bffdb6bc..d9181eb2 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.imagecontentpolicy.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.imagecontentpolicy.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] ImageContentPolicy"
-crd: 0000_10_config-operator_01_imagecontentpolicy.crd.yaml
+crd: 0000_10_config-operator_01_imagecontentpolicies.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal ImageContentPolicy
diff --git a/vendor/github.com/openshift/api/config/v1/stable.imagedigestmirrorset.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.imagedigestmirrorset.testsuite.yaml
index c25b1696..3250800b 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.imagedigestmirrorset.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.imagedigestmirrorset.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] ImageDigestMirrorSet"
-crd: 0000_10_config-operator_01_imagedigestmirrorset.crd.yaml
+crd: 0000_10_config-operator_01_imagedigestmirrorsets.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal ImageDigestMirrorSet
diff --git a/vendor/github.com/openshift/api/config/v1/stable.imagetagmirrorset.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.imagetagmirrorset.testsuite.yaml
index de91eb2c..6b8d12d9 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.imagetagmirrorset.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.imagetagmirrorset.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] ImageTagMirrorSet"
-crd: 0000_10_config-operator_01_imagetagmirrorset.crd.yaml
+crd: 0000_10_config-operator_01_imagetagmirrorsets.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal ImageTagMirrorSet
diff --git a/vendor/github.com/openshift/api/config/v1/stable.infrastructure.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.infrastructure.testsuite.yaml
index 9d0861b6..aa564b17 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.infrastructure.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.infrastructure.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] Infrastructure"
-crd: 0000_10_config-operator_01_infrastructure-Default.crd.yaml
+crd: 0000_10_config-operator_01_infrastructures-Default.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal Infrastructure
@@ -408,7 +408,7 @@ tests:
           platformStatus:
             powervs:
               resourceGroup: resource-group-should-not-accept-the-string-that-exceeds-max-length-set
-      expectedStatusError: "status.platformStatus.powervs.resourceGroup: Too long: may not be longer than 40"
+      expectedStatusError: "platformStatus.powervs.resourceGroup: Too long: may not be longer than 40"
     - name: PowerVS platform status's resourceGroup should match the regex configured
       initial: |
         apiVersion: config.openshift.io/v1
@@ -432,7 +432,7 @@ tests:
           platformStatus:
             powervs:
               resourceGroup: re$ource-group
-      expectedStatusError: "status.platformStatus.powervs.resourceGroup in body should match '^[a-zA-Z0-9-_ ]+$'"
+      expectedStatusError: "platformStatus.powervs.resourceGroup in body should match '^[a-zA-Z0-9-_ ]+$'"
     - name: Should not be able to change PowerVS platform status's resourceGroup once it was set
       initial: |
         apiVersion: config.openshift.io/v1
@@ -519,7 +519,46 @@ tests:
               loadBalancer:
                 type: OpenShiftManagedDefault
             type: OpenStack
-    - name: Should be able to override the default load balancer with a valid value
+    - name: Should be able to override the default BareMetal load balancer with a valid value
+      initial: |
+        apiVersion: config.openshift.io/v1
+        kind: Infrastructure
+        spec:
+          platformSpec:
+            baremetal: {}
+            type: BareMetal
+      updated: |
+        apiVersion: config.openshift.io/v1
+        kind: Infrastructure
+        spec:
+          platformSpec:
+            baremetal: {}
+            type: BareMetal
+        status:
+          platform: BareMetal
+          platformStatus:
+            baremetal:
+              loadBalancer:
+                type: UserManaged
+            type: BareMetal
+      expected: |
+        apiVersion: config.openshift.io/v1
+        kind: Infrastructure
+        spec:
+          platformSpec:
+            baremetal: {}
+            type: BareMetal
+        status:
+          controlPlaneTopology: HighlyAvailable
+          cpuPartitioning: None
+          infrastructureTopology: HighlyAvailable
+          platform: BareMetal
+          platformStatus:
+            baremetal:
+              loadBalancer:
+                type: UserManaged
+            type: BareMetal
+    - name: Should be able to override the default OpenStack load balancer with a valid value
       initial: |
         apiVersion: config.openshift.io/v1
         kind: Infrastructure
@@ -558,7 +597,41 @@ tests:
               loadBalancer:
                 type: UserManaged
             type: OpenStack
-    - name: Should not allow changing the immutable load balancer type field
+    - name: Should not allow changing the immutable BareMetal load balancer type field
+      initial: |
+        apiVersion: config.openshift.io/v1
+        kind: Infrastructure
+        spec:
+          platformSpec:
+            baremetal: {}
+            type: BareMetal
+        status:
+          controlPlaneTopology: HighlyAvailable
+          infrastructureTopology: HighlyAvailable
+          platform: BareMetal
+          platformStatus:
+            baremetal:
+              loadBalancer:
+                type: OpenShiftManagedDefault
+            type: BareMetal
+      updated: |
+        apiVersion: config.openshift.io/v1
+        kind: Infrastructure
+        spec:
+          platformSpec:
+            type: BareMetal
+            baremetal: {}
+        status:
+          controlPlaneTopology: HighlyAvailable
+          infrastructureTopology: HighlyAvailable
+          platform: BareMetal
+          platformStatus:
+            baremetal:
+              loadBalancer:
+                type: UserManaged
+            type: BareMetal
+      expectedStatusError: "status.platformStatus.baremetal.loadBalancer.type: Invalid value: \"string\": type is immutable once set"
+    - name: Should not allow changing the immutable OpenStack load balancer type field
       initial: |
         apiVersion: config.openshift.io/v1
         kind: Infrastructure
@@ -592,7 +665,7 @@ tests:
                 type: UserManaged
             type: OpenStack
       expectedStatusError: "status.platformStatus.openstack.loadBalancer.type: Invalid value: \"string\": type is immutable once set"
-    - name: Should not allow removing the immutable load balancer type field that was initially set
+    - name: Should not allow removing the immutable OpenStack load balancer type field that was initially set
       initial: |
         apiVersion: config.openshift.io/v1
         kind: Infrastructure
@@ -624,6 +697,38 @@ tests:
             openstack: {}
             type: OpenStack
       expectedStatusError: "status.platformStatus.openstack.loadBalancer.type: Invalid value: \"string\": type is immutable once set"
+    - name: Should not allow removing the immutable BareMetal load balancer type field that was initially set
+      initial: |
+        apiVersion: config.openshift.io/v1
+        kind: Infrastructure
+        spec:
+          platformSpec:
+            baremetal: {}
+            type: BareMetal
+        status:
+          controlPlaneTopology: HighlyAvailable
+          infrastructureTopology: HighlyAvailable
+          platform: BareMetal
+          platformStatus:
+            baremetal:
+              loadBalancer:
+                type: UserManaged
+            type: BareMetal
+      updated: |
+        apiVersion: config.openshift.io/v1
+        kind: Infrastructure
+        spec:
+          platformSpec:
+            type: BareMetal
+            baremetal: {}
+        status:
+          controlPlaneTopology: HighlyAvailable
+          infrastructureTopology: HighlyAvailable
+          platform: BareMetal
+          platformStatus:
+            baremetal: {}
+            type: BareMetal
+      expectedStatusError: "status.platformStatus.baremetal.loadBalancer.type: Invalid value: \"string\": type is immutable once set"
     - name: Should not allow setting the load balancer type to a wrong value
       initial: |
         apiVersion: config.openshift.io/v1
@@ -646,7 +751,7 @@ tests:
               loadBalancer:
                 type: FooBar
             type: OpenStack
-      expectedStatusError: "status.platformStatus.openstack.loadBalancer.type: Unsupported value: \"FooBar\": supported values: \"OpenShiftManagedDefault\", \"UserManaged\""
+      expectedStatusError: "platformStatus.openstack.loadBalancer.type: Unsupported value: \"FooBar\": supported values: \"OpenShiftManagedDefault\", \"UserManaged\""
     - name: Should not be able to update cloudControllerManager state to empty string when state is already set to None
       initial: |
         apiVersion: config.openshift.io/v1
@@ -1233,7 +1338,7 @@ tests:
                 url: https://dummy.vpc.com
               - name: COS
                 url: dummy-cos-com
-      expectedStatusError: " status.platformStatus.ibmcloud.serviceEndpoints[1].url: Invalid value: \"string\": url must be a valid absolute URL"
+      expectedStatusError: "platformStatus.ibmcloud.serviceEndpoints[1].url: Invalid value: \"string\": url must be a valid absolute URL"
     - name: Should not be able to add invalid (Name) ServiceEndpoints to IBMCloud PlatformStatus
       initial: |
         apiVersion: config.openshift.io/v1
@@ -1259,4 +1364,4 @@ tests:
                 url: https://dummy.vpc.com
               - name: BadService
                 url: https://bad-service.com
-      expectedStatusError: " status.platformStatus.ibmcloud.serviceEndpoints[1].name: Unsupported value: \"BadService\": supported values: \"CIS\", \"COS\", \"DNSServices\", \"GlobalSearch\", \"GlobalTagging\", \"HyperProtect\", \"IAM\", \"KeyProtect\", \"ResourceController\", \"ResourceManager\", \"VPC\""
+      expectedStatusError: "platformStatus.ibmcloud.serviceEndpoints[1].name: Unsupported value: \"BadService\": supported values: \"CIS\", \"COS\", \"DNSServices\", \"GlobalSearch\", \"GlobalTagging\", \"HyperProtect\", \"IAM\", \"KeyProtect\", \"ResourceController\", \"ResourceManager\", \"VPC\""
diff --git a/vendor/github.com/openshift/api/config/v1/stable.ingress.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.ingress.testsuite.yaml
index 90d48e89..fd7870d7 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.ingress.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.ingress.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] Ingress"
-crd: 0000_10_config-operator_01_ingress.crd.yaml
+crd: 0000_10_config-operator_01_ingresses.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal Ingress
diff --git a/vendor/github.com/openshift/api/config/v1/stable.network.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.network.testsuite.yaml
index c85d122a..16178e84 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.network.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.network.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] Network"
-crd: 0000_10_config-operator_01_network-Default.crd.yaml
+crd: 0000_10_config-operator_01_networks.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal Network
diff --git a/vendor/github.com/openshift/api/config/v1/stable.node.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.node.testsuite.yaml
index d6502600..4287b66f 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.node.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.node.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] Node"
-crd: 0000_10_config-operator_01_node.crd.yaml
+crd: 0000_10_config-operator_01_nodes.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal Node
diff --git a/vendor/github.com/openshift/api/config/v1/stable.oauth.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.oauth.testsuite.yaml
index d33d2bc1..b25ec548 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.oauth.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.oauth.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] OAuth"
-crd: 0000_10_config-operator_01_oauth.crd.yaml
+crd: 0000_10_config-operator_01_oauths.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal OAuth
diff --git a/vendor/github.com/openshift/api/config/v1/stable.operatorhub.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.operatorhub.testsuite.yaml
index 9dd7a4c6..445b2dc7 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.operatorhub.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.operatorhub.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] OperatorHub"
-crd: 0000_03_marketplace-operator_01_operatorhub.crd.yaml
+crd: 0000_03_marketplace_01_operatorhubs.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal OperatorHub
diff --git a/vendor/github.com/openshift/api/config/v1/stable.project.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.project.testsuite.yaml
index 0144ad32..4a14ccbf 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.project.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.project.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] Project"
-crd: 0000_10_config-operator_01_project.crd.yaml
+crd: 0000_10_config-operator_01_projects.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal Project
diff --git a/vendor/github.com/openshift/api/config/v1/stable.proxy.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.proxy.testsuite.yaml
index d49b8324..3886dde3 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.proxy.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.proxy.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] Proxy"
-crd: 0000_03_config-operator_01_proxy.crd.yaml
+crd: 0000_03_config-operator_01_proxies.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal Proxy
diff --git a/vendor/github.com/openshift/api/config/v1/stable.scheduler.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.scheduler.testsuite.yaml
index d6596548..87ff1734 100644
--- a/vendor/github.com/openshift/api/config/v1/stable.scheduler.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/stable.scheduler.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] Scheduler"
-crd: 0000_10_config-operator_01_scheduler-Default.crd.yaml
+crd: 0000_10_config-operator_01_schedulers-Default.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal Scheduler
diff --git a/vendor/github.com/openshift/api/config/v1/techpreview.apiserver.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/techpreview.apiserver.testsuite.yaml
deleted file mode 100644
index 74aa92b4..00000000
--- a/vendor/github.com/openshift/api/config/v1/techpreview.apiserver.testsuite.yaml
+++ /dev/null
@@ -1,35 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
-name: "[TechPreviewNoUpgrade] APIServer"
-crd: 0000_10_config-operator_01_apiserver-TechPreviewNoUpgrade.crd.yaml
-tests:
-  onCreate:
-    - name: Should be able to create encrypt with aescbc
-      initial: |
-        apiVersion: config.openshift.io/v1
-        kind: APIServer
-        spec:
-          encryption:
-            type: aescbc
-      expected: |
-        apiVersion: config.openshift.io/v1
-        kind: APIServer
-        spec:
-          audit:
-            profile: Default
-          encryption:
-            type: aescbc
-    - name: Should be able to create encrypt with aesgcm
-      initial: |
-        apiVersion: config.openshift.io/v1
-        kind: APIServer
-        spec:
-          encryption:
-            type: aesgcm
-      expected: |
-        apiVersion: config.openshift.io/v1
-        kind: APIServer
-        spec:
-          audit:
-            profile: Default
-          encryption:
-            type: aesgcm
diff --git a/vendor/github.com/openshift/api/config/v1/techpreview.authentication.single.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/techpreview.authentication.single.testsuite.yaml
new file mode 100644
index 00000000..924fb03f
--- /dev/null
+++ b/vendor/github.com/openshift/api/config/v1/techpreview.authentication.single.testsuite.yaml
@@ -0,0 +1,298 @@
+apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
+name: "[TechPreviewNoUpgrade] Authentication SingleNode"
+crd: 0000_10_config-operator_01_authentications-SingleNode-TechPreviewNoUpgrade.crd.yaml
+tests:
+  onCreate:
+  - name: Should be able to create a minimal Authentication
+    initial: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec: {} # No spec is required for a Authentication
+    expected: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec: {}
+  - name: Should be able to use the OIDC type
+    initial: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+    expected: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+  - name: Cannot set username claim prefix with policy NoPrefix
+    initial: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          claimMappings:
+            username:
+              claim: "preferred_username"
+              prefixPolicy: NoPrefix
+              prefix:
+                prefixString: "myoidc:"
+    expectedError: "prefix must be set if prefixPolicy is 'Prefix', but must remain unset otherwise"
+  - name: Can set username claim prefix with policy Prefix
+    initial: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          claimMappings:
+            username:
+              claim: "preferred_username"
+              prefixPolicy: Prefix
+              prefix:
+                prefixString: "myoidc:"
+    expected: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          claimMappings:
+            username:
+              claim: "preferred_username"
+              prefixPolicy: Prefix
+              prefix:
+                prefixString: "myoidc:"
+  - name: Cannot leave username claim prefix blank with policy Prefix
+    initial: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          claimMappings:
+            username:
+              claim: "preferred_username"
+              prefixPolicy: Prefix
+    expectedError: "prefix must be set if prefixPolicy is 'Prefix', but must remain unset otherwise"
+  - name: Can set OIDC providers with no username prefixing
+    initial: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          claimMappings:
+            username:
+              claim: "preferred_username"
+              prefixPolicy: NoPrefix
+    expected: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          claimMappings:
+            username:
+              claim: "preferred_username"
+              prefixPolicy: NoPrefix
+  onUpdate:
+  - name: Updating OIDC provider with a client that's not in the status
+    initial: &initConfig |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          oidcClients:
+            - componentNamespace: namespace
+              componentName: preexisting
+              clientID: someclient
+            - componentNamespace: namespace
+              componentName: name
+              clientID: legitclient
+      status:
+        oidcClients:
+        - componentNamespace: namespace
+          componentName: name
+        - componentNamespace: namespace2
+          componentName: name2
+        - componentNamespace: namespace2
+          componentName: name3
+    updated: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          oidcClients:
+          - componentNamespace: namespace
+            componentName: preexisting
+            clientID: someclient
+          - componentNamespace: namespace
+            componentName: name
+            clientID: legitclient
+          - componentNamespace: dif-namespace # new client here
+            componentName: tehName
+            clientID: cool-client
+      status:
+        oidcClients:
+        - componentNamespace: namespace
+          componentName: name
+        - componentNamespace: namespace2
+          componentName: name2
+        - componentNamespace: namespace2
+          componentName: name3
+    expectedError: "all oidcClients in the oidcProviders must match their componentName and componentNamespace to either a previously configured oidcClient or they must exist in the status.oidcClients"
+  - name: Updating OIDC provider with a client that's different from the previous one
+    initial: *initConfig
+    updated: |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          oidcClients:
+          - componentNamespace: dif-namespace
+            componentName: tehName
+            clientID: cool-client
+      status:
+        oidcClients:
+        - componentNamespace: namespace
+          componentName: name
+        - componentNamespace: namespace2
+          componentName: name2
+        - componentNamespace: namespace2
+          componentName: name3
+    expectedError: "all oidcClients in the oidcProviders must match their componentName and componentNamespace to either a previously configured oidcClient or they must exist in the status.oidcClients"
+  - name: Updating previously existing client
+    initial: *initConfig
+    updated: &prevExistingUpdated |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          oidcClients:
+            - componentNamespace: namespace
+              componentName: preexisting
+              clientID: different-client
+      status:
+        oidcClients:
+        - componentNamespace: namespace
+          componentName: name
+        - componentNamespace: namespace2
+          componentName: name2
+        - componentNamespace: namespace2
+          componentName: name3
+    expected: *prevExistingUpdated
+  - name: Removing a configured client from the status (== component unregister)
+    initial: *initConfig
+    updated: &removeFromStatus |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          oidcClients:
+            - componentNamespace: namespace
+              componentName: preexisting
+              clientID: different-client
+            - componentNamespace: namespace
+              componentName: name
+              clientID: legitclient
+      status:
+        oidcClients:
+        - componentNamespace: namespace2
+          componentName: name2
+        - componentNamespace: namespace2
+          componentName: name3
+    expected: *removeFromStatus
+  - name: Simply add a valid client
+    initial: *initConfig
+    updated: &addClient |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+        oidcProviders:
+        - name: myoidc
+          issuer:
+            issuerURL: https://meh.tld
+            audiences: ['openshift-aud']
+          oidcClients:
+            - componentNamespace: namespace
+              componentName: preexisting
+              clientID: different-client
+            - componentNamespace: namespace
+              componentName: name
+              clientID: legitclient
+            - componentNamespace: namespace2
+              componentName: name3
+              clientID: justavalidclient
+      status:
+        oidcClients:
+        - componentNamespace: namespace
+          componentName: name
+        - componentNamespace: namespace2
+          componentName: name2
+        - componentNamespace: namespace2
+          componentName: name3
+    expected: *addClient
+  - name: Remove all oidcProviders
+    initial: *initConfig
+    updated: &removeFromStatus |
+      apiVersion: config.openshift.io/v1
+      kind: Authentication
+      spec:
+        type: OIDC
+      status:
+        oidcClients:
+        - componentNamespace: namespace2
+          componentName: name2
+        - componentNamespace: namespace2
+          componentName: name3
+    expected: *removeFromStatus
diff --git a/vendor/github.com/openshift/api/config/v1/techpreview.authentication.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/techpreview.authentication.testsuite.yaml
index 9d978fcf..9c2913b0 100644
--- a/vendor/github.com/openshift/api/config/v1/techpreview.authentication.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/techpreview.authentication.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[TechPreviewNoUpgrade] Authentication"
-crd: 0000_10_config-operator_01_authentication.crd-TechPreviewNoUpgrade.yaml
+crd: 0000_10_config-operator_01_authentications-SelfManagedHA-TechPreviewNoUpgrade.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal Authentication
diff --git a/vendor/github.com/openshift/api/config/v1/techpreview.clusterversion.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/techpreview.clusterversion.testsuite.yaml
index 71988108..714e6bf8 100644
--- a/vendor/github.com/openshift/api/config/v1/techpreview.clusterversion.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/techpreview.clusterversion.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[TechPreviewNoUpgrade] ClusterVersion"
-crd: 0000_00_cluster-version-operator_01_clusterversion-TechPreviewNoUpgrade.crd.yaml
+crd: 0000_00_cluster-version-operator_01_clusterversions-TechPreviewNoUpgrade.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal ClusterVersion
diff --git a/vendor/github.com/openshift/api/config/v1/techpreview.dns.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/techpreview.dns.testsuite.yaml
deleted file mode 100644
index ec64352e..00000000
--- a/vendor/github.com/openshift/api/config/v1/techpreview.dns.testsuite.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
-name: "[TechPreview] DNS"
-crd: 0000_10_config-operator_01_dns-TechPreviewNoUpgrade.crd.yaml
-tests:
-  onCreate:
-  - name: Should be able to create a minimal DNS
-    initial: |
-      apiVersion: config.openshift.io/v1
-      kind: DNS
-      spec: {} # No spec is required for a DNS
-    expected: |
-      apiVersion: config.openshift.io/v1
-      kind: DNS
-      spec: {}
diff --git a/vendor/github.com/openshift/api/config/v1/techpreview.infrastructure.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/techpreview.infrastructure.testsuite.yaml
index d4a1113f..e6fbce40 100644
--- a/vendor/github.com/openshift/api/config/v1/techpreview.infrastructure.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/techpreview.infrastructure.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[TechPreviewNoUpgrade] Infrastructure"
-crd: 0000_10_config-operator_01_infrastructure-TechPreviewNoUpgrade.crd.yaml
+crd: 0000_10_config-operator_01_infrastructures-TechPreviewNoUpgrade.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal Infrastructure
@@ -45,7 +45,7 @@ tests:
       spec: {}
       status:
         cpuPartitioning: "Invalid"
-    expectedStatusError: 'status.cpuPartitioning: Unsupported value: "Invalid": supported values: "None", "AllNodes"'
+    expectedStatusError: 'cpuPartitioning: Unsupported value: "Invalid": supported values: "None", "AllNodes"'
   - name: Should set load balancer type to OpenShiftManagedDefault if not specified
     initial: |
       apiVersion: config.openshift.io/v1
@@ -83,111 +83,6 @@ tests:
             loadBalancer:
               type: OpenShiftManagedDefault
           type: BareMetal
-  - name: Should be able to override the default load balancer with a valid value
-    initial: |
-      apiVersion: config.openshift.io/v1
-      kind: Infrastructure
-      spec:
-        platformSpec:
-          baremetal: {}
-          type: BareMetal
-    updated: |
-      apiVersion: config.openshift.io/v1
-      kind: Infrastructure
-      spec:
-        platformSpec:
-          baremetal: {}
-          type: BareMetal
-      status:
-        platform: BareMetal
-        platformStatus:
-          baremetal:
-            loadBalancer:
-              type: UserManaged
-          type: BareMetal
-    expected: |
-      apiVersion: config.openshift.io/v1
-      kind: Infrastructure
-      spec:
-        platformSpec:
-          baremetal: {}
-          type: BareMetal
-      status:
-        controlPlaneTopology: HighlyAvailable
-        cpuPartitioning: None
-        infrastructureTopology: HighlyAvailable
-        platform: BareMetal
-        platformStatus:
-          baremetal:
-            loadBalancer:
-              type: UserManaged
-          type: BareMetal
-  - name: Should not allow changing the immutable load balancer type field
-    initial: |
-      apiVersion: config.openshift.io/v1
-      kind: Infrastructure
-      spec:
-        platformSpec:
-          baremetal: {}
-          type: BareMetal
-      status:
-        controlPlaneTopology: HighlyAvailable
-        infrastructureTopology: HighlyAvailable
-        platform: BareMetal
-        platformStatus:
-          baremetal:
-            loadBalancer:
-              type: OpenShiftManagedDefault
-          type: BareMetal
-    updated: |
-      apiVersion: config.openshift.io/v1
-      kind: Infrastructure
-      spec:
-        platformSpec:
-          type: BareMetal
-          baremetal: {}
-      status:
-        controlPlaneTopology: HighlyAvailable
-        infrastructureTopology: HighlyAvailable
-        platform: BareMetal
-        platformStatus:
-          baremetal:
-            loadBalancer:
-              type: UserManaged
-          type: BareMetal
-    expectedStatusError: "status.platformStatus.baremetal.loadBalancer.type: Invalid value: \"string\": type is immutable once set"
-  - name: Should not allow removing the immutable load balancer type field that was initially set
-    initial: |
-      apiVersion: config.openshift.io/v1
-      kind: Infrastructure
-      spec:
-        platformSpec:
-          baremetal: {}
-          type: BareMetal
-      status:
-        controlPlaneTopology: HighlyAvailable
-        infrastructureTopology: HighlyAvailable
-        platform: BareMetal
-        platformStatus:
-          baremetal:
-            loadBalancer:
-              type: UserManaged
-          type: BareMetal
-    updated: |
-      apiVersion: config.openshift.io/v1
-      kind: Infrastructure
-      spec:
-        platformSpec:
-          type: BareMetal
-          baremetal: {}
-      status:
-        controlPlaneTopology: HighlyAvailable
-        infrastructureTopology: HighlyAvailable
-        platform: BareMetal
-        platformStatus:
-          baremetal: {}
-          type: BareMetal
-    expectedStatusError: "status.platformStatus.baremetal.loadBalancer.type: Invalid value: \"string\": type is immutable once set"
   - name: Should not allow setting the load balancer type to a wrong value
     initial: |
       apiVersion: config.openshift.io/v1
@@ -210,7 +105,7 @@ tests:
             loadBalancer:
               type: FooBar
           type: BareMetal
-    expectedStatusError: "status.platformStatus.baremetal.loadBalancer.type: Unsupported value: \"FooBar\": supported values: \"OpenShiftManagedDefault\", \"UserManaged\""
+    expectedStatusError: "platformStatus.baremetal.loadBalancer.type: Unsupported value: \"FooBar\": supported values: \"OpenShiftManagedDefault\", \"UserManaged\""
   - name: Should not be able to modify an existing GCP ResourceLabels Label
     initial: |
       apiVersion: config.openshift.io/v1
@@ -654,7 +549,7 @@ tests:
         infrastructureTopology: HighlyAvailable
         platform: GCP
         platformStatus:
-          gcp: 
+          gcp:
             cloudLoadBalancerConfig:
               dnsType: ClusterHosted
               clusterHosted:
@@ -681,7 +576,7 @@ tests:
                 - 10.10.10.20
                 - not-an-ip-address
           type: GCP
-    expectedStatusError: "status.platformStatus.gcp.cloudLoadBalancerConfig.clusterHosted.apiIntLoadBalancerIPs[1]: Invalid value: \"not-an-ip-address\": status.platformStatus.gcp.cloudLoadBalancerConfig.clusterHosted.apiIntLoadBalancerIPs[1] in body should match '(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)'"
+    expectedStatusError: "platformStatus.gcp.cloudLoadBalancerConfig.clusterHosted.apiIntLoadBalancerIPs[1]: Invalid value: \"not-an-ip-address\": platformStatus.gcp.cloudLoadBalancerConfig.clusterHosted.apiIntLoadBalancerIPs[1] in body should match '(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)'"
   - name: Should not accept update when `clusterHosted` is specified with DNSType `PlatformDefault`
     initial: |
       apiVersion: config.openshift.io/v1
diff --git a/vendor/github.com/openshift/api/config/v1/techpreview.network.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/techpreview.network.testsuite.yaml
deleted file mode 100644
index d15fae3a..00000000
--- a/vendor/github.com/openshift/api/config/v1/techpreview.network.testsuite.yaml
+++ /dev/null
@@ -1,28 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
-name: "[TechPreviewNoUpgrade] Network"
-crd: 0000_10_config-operator_01_network-TechPreviewNoUpgrade.crd.yaml
-tests:
-  onCreate:
-    - name: Should be able to set status conditions
-      initial: |
-        apiVersion: config.openshift.io/v1
-        kind: Network
-        spec: {} # No spec is required for a Network
-        status:
-          conditions:
-            - type: NetworkTypeMigrationInProgress
-              status: "False"
-              reason: "Reason"
-              message: "Message"
-              lastTransitionTime: "2023-10-25T12:00:00Z"
-      expected: |
-        apiVersion: config.openshift.io/v1
-        kind: Network
-        spec: {}
-        status:
-          conditions:
-            - type: NetworkTypeMigrationInProgress
-              status: "False"
-              reason: "Reason"
-              message: "Message"
-              lastTransitionTime: "2023-10-25T12:00:00Z"
diff --git a/vendor/github.com/openshift/api/config/v1/techpreview.scheduler.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/techpreview.scheduler.testsuite.yaml
index 5b5eb895..a68d6a71 100644
--- a/vendor/github.com/openshift/api/config/v1/techpreview.scheduler.testsuite.yaml
+++ b/vendor/github.com/openshift/api/config/v1/techpreview.scheduler.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] Scheduler"
-crd: 0000_10_config-operator_01_scheduler-TechPreviewNoUpgrade.crd.yaml
+crd: 0000_10_config-operator_01_schedulers-TechPreviewNoUpgrade.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal Scheduler
diff --git a/vendor/github.com/openshift/api/config/v1/types_apiserver.go b/vendor/github.com/openshift/api/config/v1/types_apiserver.go
index 59b89388..bdae4668 100644
--- a/vendor/github.com/openshift/api/config/v1/types_apiserver.go
+++ b/vendor/github.com/openshift/api/config/v1/types_apiserver.go
@@ -14,6 +14,11 @@ import (
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
 // +openshift:compatibility-gen:level=1
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/470
+// +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=apiservers,scope=Cluster
+// +kubebuilder:subresource:status
 type APIServer struct {
 	metav1.TypeMeta `json:",inline"`
 
diff --git a/vendor/github.com/openshift/api/config/v1/types_authentication.go b/vendor/github.com/openshift/api/config/v1/types_authentication.go
index 62c9e7f5..b3dfa61b 100644
--- a/vendor/github.com/openshift/api/config/v1/types_authentication.go
+++ b/vendor/github.com/openshift/api/config/v1/types_authentication.go
@@ -4,15 +4,19 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 // +genclient
 // +genclient:nonNamespaced
-// +kubebuilder:subresource:status
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
-// +openshift:validation:FeatureSetAwareXValidation:featureSet=CustomNoUpgrade;TechPreviewNoUpgrade,rule="!has(self.spec.oidcProviders) || self.spec.oidcProviders.all(p, !has(p.oidcClients) || p.oidcClients.all(specC, self.status.oidcClients.exists(statusC, statusC.componentNamespace == specC.componentNamespace && statusC.componentName == specC.componentName) || (has(oldSelf.spec.oidcProviders) && oldSelf.spec.oidcProviders.exists(oldP, oldP.name == p.name && has(oldP.oidcClients) && oldP.oidcClients.exists(oldC, oldC.componentNamespace == specC.componentNamespace && oldC.componentName == specC.componentName)))))",message="all oidcClients in the oidcProviders must match their componentName and componentNamespace to either a previously configured oidcClient or they must exist in the status.oidcClients"
+// +openshift:validation:FeatureGateAwareXValidation:featureGate=ExternalOIDC,rule="!has(self.spec.oidcProviders) || self.spec.oidcProviders.all(p, !has(p.oidcClients) || p.oidcClients.all(specC, self.status.oidcClients.exists(statusC, statusC.componentNamespace == specC.componentNamespace && statusC.componentName == specC.componentName) || (has(oldSelf.spec.oidcProviders) && oldSelf.spec.oidcProviders.exists(oldP, oldP.name == p.name && has(oldP.oidcClients) && oldP.oidcClients.exists(oldC, oldC.componentNamespace == specC.componentNamespace && oldC.componentName == specC.componentName)))))",message="all oidcClients in the oidcProviders must match their componentName and componentNamespace to either a previously configured oidcClient or they must exist in the status.oidcClients"
 
 // Authentication specifies cluster-wide settings for authentication (like OAuth and
 // webhook token authenticators). The canonical name of an instance is `cluster`.
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
 // +openshift:compatibility-gen:level=1
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/470
+// +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=authentications,scope=Cluster
+// +kubebuilder:subresource:status
 type Authentication struct {
 	metav1.TypeMeta `json:",inline"`
 
@@ -85,7 +89,7 @@ type AuthenticationSpec struct {
 	// +listType=map
 	// +listMapKey=name
 	// +kubebuilder:validation:MaxItems=1
-	// +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade
+	// +openshift:enable:FeatureGate=ExternalOIDC
 	OIDCProviders []OIDCProvider `json:"oidcProviders,omitempty"`
 }
 
@@ -112,7 +116,7 @@ type AuthenticationStatus struct {
 	// +listMapKey=componentNamespace
 	// +listMapKey=componentName
 	// +kubebuilder:validation:MaxItems=20
-	// +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade
+	// +openshift:enable:FeatureGate=ExternalOIDC
 	OIDCClients []OIDCClientStatus `json:"oidcClients"`
 }
 
@@ -130,8 +134,8 @@ type AuthenticationList struct {
 	Items []Authentication `json:"items"`
 }
 
-// +openshift:validation:FeatureSetAwareEnum:featureSet=Default,enum="";None;IntegratedOAuth
-// +openshift:validation:FeatureSetAwareEnum:featureSet=CustomNoUpgrade;TechPreviewNoUpgrade,enum="";None;IntegratedOAuth;OIDC
+// +openshift:validation:FeatureGateAwareEnum:featureGate="",enum="";None;IntegratedOAuth
+// +openshift:validation:FeatureGateAwareEnum:featureGate=ExternalOIDC,enum="";None;IntegratedOAuth;OIDC
 type AuthenticationType string
 
 const (
diff --git a/vendor/github.com/openshift/api/config/v1/types_build.go b/vendor/github.com/openshift/api/config/v1/types_build.go
index e9aef037..dad47666 100644
--- a/vendor/github.com/openshift/api/config/v1/types_build.go
+++ b/vendor/github.com/openshift/api/config/v1/types_build.go
@@ -16,6 +16,12 @@ import (
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
 // +openshift:compatibility-gen:level=1
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/470
+// +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=openshift-controller-manager,operatorOrdering=01
+// +openshift:capability=Build
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=builds,scope=Cluster
+// +kubebuilder:subresource:status
 type Build struct {
 	metav1.TypeMeta `json:",inline"`
 
diff --git a/vendor/github.com/openshift/api/config/v1/types_cluster_operator.go b/vendor/github.com/openshift/api/config/v1/types_cluster_operator.go
index 78666bb1..a5666a78 100644
--- a/vendor/github.com/openshift/api/config/v1/types_cluster_operator.go
+++ b/vendor/github.com/openshift/api/config/v1/types_cluster_operator.go
@@ -15,6 +15,18 @@ import (
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
 // +openshift:compatibility-gen:level=1
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/497
+// +openshift:file-pattern=cvoRunLevel=0000_00,operatorName=cluster-version-operator,operatorOrdering=01
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=clusteroperators,scope=Cluster,shortName=co
+// +kubebuilder:subresource:status
+// +kubebuilder:printcolumn:name=Version,JSONPath=.status.versions[?(@.name=="operator")].version,type=string,description=The version the operator is at.
+// +kubebuilder:printcolumn:name=Available,JSONPath=.status.conditions[?(@.type=="Available")].status,type=string,description=Whether the operator is running and stable.
+// +kubebuilder:printcolumn:name=Progressing,JSONPath=.status.conditions[?(@.type=="Progressing")].status,type=string,description=Whether the operator is processing changes.
+// +kubebuilder:printcolumn:name=Degraded,JSONPath=.status.conditions[?(@.type=="Degraded")].status,type=string,description=Whether the operator is degraded.
+// +kubebuilder:printcolumn:name=Since,JSONPath=.status.conditions[?(@.type=="Available")].lastTransitionTime,type=date,description=The time the operator's Available status last changed.
+// +kubebuilder:metadata:annotations=include.release.openshift.io/self-managed-high-availability=true
+// +kubebuilder:metadata:annotations=include.release.openshift.io/single-node-developer=true
 type ClusterOperator struct {
 	metav1.TypeMeta `json:",inline"`
 
diff --git a/vendor/github.com/openshift/api/config/v1/types_cluster_version.go b/vendor/github.com/openshift/api/config/v1/types_cluster_version.go
index dc913b75..d568e1db 100644
--- a/vendor/github.com/openshift/api/config/v1/types_cluster_version.go
+++ b/vendor/github.com/openshift/api/config/v1/types_cluster_version.go
@@ -13,8 +13,20 @@ import (
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
 // +openshift:compatibility-gen:level=1
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/495
+// +openshift:file-pattern=cvoRunLevel=0000_00,operatorName=cluster-version-operator,operatorOrdering=01
+// +kubebuilder:object:root=true
+// +kubebuilder:subresource:status
+// +kubebuilder:resource:path=clusterversions,scope=Cluster
 // +kubebuilder:validation:XValidation:rule="has(self.spec.capabilities) && has(self.spec.capabilities.additionalEnabledCapabilities) && self.spec.capabilities.baselineCapabilitySet == 'None' && 'baremetal' in self.spec.capabilities.additionalEnabledCapabilities ? 'MachineAPI' in self.spec.capabilities.additionalEnabledCapabilities || (has(self.status) && has(self.status.capabilities) && has(self.status.capabilities.enabledCapabilities) && 'MachineAPI' in self.status.capabilities.enabledCapabilities) : true",message="the `baremetal` capability requires the `MachineAPI` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `MachineAPI` capability"
 // +kubebuilder:validation:XValidation:rule="has(self.spec.capabilities) && has(self.spec.capabilities.additionalEnabledCapabilities) && self.spec.capabilities.baselineCapabilitySet == 'None' && 'marketplace' in self.spec.capabilities.additionalEnabledCapabilities ? 'OperatorLifecycleManager' in self.spec.capabilities.additionalEnabledCapabilities || (has(self.status) && has(self.status.capabilities) && has(self.status.capabilities.enabledCapabilities) && 'OperatorLifecycleManager' in self.status.capabilities.enabledCapabilities) : true",message="the `marketplace` capability requires the `OperatorLifecycleManager` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `OperatorLifecycleManager` capability"
+// +kubebuilder:printcolumn:name=Version,JSONPath=.status.history[?(@.state=="Completed")].version,type=string
+// +kubebuilder:printcolumn:name=Available,JSONPath=.status.conditions[?(@.type=="Available")].status,type=string
+// +kubebuilder:printcolumn:name=Progressing,JSONPath=.status.conditions[?(@.type=="Progressing")].status,type=string
+// +kubebuilder:printcolumn:name=Since,JSONPath=.status.conditions[?(@.type=="Progressing")].lastTransitionTime,type=date
+// +kubebuilder:printcolumn:name=Status,JSONPath=.status.conditions[?(@.type=="Progressing")].message,type=string
+// +kubebuilder:metadata:annotations=include.release.openshift.io/self-managed-high-availability=true
+// +kubebuilder:metadata:annotations=include.release.openshift.io/single-node-developer=true
 type ClusterVersion struct {
 	metav1.TypeMeta `json:",inline"`
 
@@ -100,7 +112,7 @@ type ClusterVersionSpec struct {
 	//
 	// A maximum of 32 signature stores may be configured.
 	// +kubebuilder:validation:MaxItems=32
-	// +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade
+	// +openshift:enable:FeatureGate=SignatureStores
 	// +listType=map
 	// +listMapKey=url
 	// +optional
diff --git a/vendor/github.com/openshift/api/config/v1/types_console.go b/vendor/github.com/openshift/api/config/v1/types_console.go
index 92818184..36b1696a 100644
--- a/vendor/github.com/openshift/api/config/v1/types_console.go
+++ b/vendor/github.com/openshift/api/config/v1/types_console.go
@@ -14,6 +14,11 @@ import (
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
 // +openshift:compatibility-gen:level=1
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/470
+// +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=consoles,scope=Cluster
+// +kubebuilder:subresource:status
 type Console struct {
 	metav1.TypeMeta `json:",inline"`
 
diff --git a/vendor/github.com/openshift/api/config/v1/types_dns.go b/vendor/github.com/openshift/api/config/v1/types_dns.go
index 5f869767..1875c9cd 100644
--- a/vendor/github.com/openshift/api/config/v1/types_dns.go
+++ b/vendor/github.com/openshift/api/config/v1/types_dns.go
@@ -10,6 +10,11 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
 // +openshift:compatibility-gen:level=1
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/470
+// +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=dnses,scope=Cluster
+// +kubebuilder:subresource:status
 type DNS struct {
 	metav1.TypeMeta `json:",inline"`
 
diff --git a/vendor/github.com/openshift/api/config/v1/types_feature.go b/vendor/github.com/openshift/api/config/v1/types_feature.go
index f608fd0b..1497077a 100644
--- a/vendor/github.com/openshift/api/config/v1/types_feature.go
+++ b/vendor/github.com/openshift/api/config/v1/types_feature.go
@@ -1,8 +1,6 @@
 package v1
 
 import (
-	"fmt"
-
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -14,6 +12,11 @@ import (
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
 // +openshift:compatibility-gen:level=1
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/470
+// +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=featuregates,scope=Cluster
+// +kubebuilder:subresource:status
 type FeatureGate struct {
 	metav1.TypeMeta `json:",inline"`
 
@@ -47,6 +50,9 @@ var (
 
 	// TopologyManager enables ToplogyManager support. Upgrades are enabled with this feature.
 	LatencySensitive FeatureSet = "LatencySensitive"
+
+	// AllFixedFeatureSets are the featuresets that have known featuregates.  Custom doesn't for instance.  LatencySensitive is dead
+	AllFixedFeatureSets = []FeatureSet{Default, TechPreviewNoUpgrade}
 )
 
 type FeatureGateSpec struct {
@@ -143,171 +149,3 @@ type FeatureGateEnabledDisabled struct {
 	Enabled  []FeatureGateDescription
 	Disabled []FeatureGateDescription
 }
-
-// FeatureSets Contains a map of Feature names to Enabled/Disabled Feature.
-//
-// NOTE: The caller needs to make sure to check for the existence of the value
-// using golang's existence field. A possible scenario is an upgrade where new
-// FeatureSets are added and a controller has not been upgraded with a newer
-// version of this file. In this upgrade scenario the map could return nil.
-//
-// example:
-//
-//	if featureSet, ok := FeatureSets["SomeNewFeature"]; ok { }
-//
-// If you put an item in either of these lists, put your area and name on it so we can find owners.
-var FeatureSets = map[FeatureSet]*FeatureGateEnabledDisabled{
-	Default: defaultFeatures,
-	CustomNoUpgrade: {
-		Enabled: []FeatureGateDescription{},
-		Disabled: []FeatureGateDescription{
-			disableKubeletCloudCredentialProviders, // We do not currently ship the correct config to use the external credentials provider.
-		},
-	},
-	TechPreviewNoUpgrade: newDefaultFeatures().
-		with(validatingAdmissionPolicy).
-		with(csiDriverSharedResource).
-		with(nodeSwap).
-		with(machineAPIProviderOpenStack).
-		with(insightsConfigAPI).
-		with(dynamicResourceAllocation).
-		with(gateGatewayAPI).
-		with(maxUnavailableStatefulSet).
-		without(eventedPleg).
-		with(sigstoreImageVerification).
-		with(gcpLabelsTags).
-		with(gcpClusterHostedDNS).
-		with(vSphereStaticIPs).
-		with(routeExternalCertificate).
-		with(automatedEtcdBackup).
-		without(machineAPIOperatorDisableMachineHealthCheckController).
-		with(adminNetworkPolicy).
-		with(dnsNameResolver).
-		with(machineConfigNodes).
-		with(metricsServer).
-		with(installAlternateInfrastructureAWS).
-		without(clusterAPIInstall).
-		with(mixedCPUsAllocation).
-		with(managedBootImages).
-		without(disableKubeletCloudCredentialProviders).
-		with(onClusterBuild).
-		with(signatureStores).
-		with(pinnedImages).
-		with(upgradeStatus).
-		with(translateStreamCloseWebsocketRequests).
-		with(volumeGroupSnapshot).
-		toFeatures(defaultFeatures),
-	LatencySensitive: newDefaultFeatures().
-		toFeatures(defaultFeatures),
-}
-
-var defaultFeatures = &FeatureGateEnabledDisabled{
-	Enabled: []FeatureGateDescription{
-		openShiftPodSecurityAdmission,
-		alibabaPlatform, // This is a bug, it should be TechPreviewNoUpgrade. This must be downgraded before 4.14 is shipped.
-		azureWorkloadIdentity,
-		cloudDualStackNodeIPs,
-		externalCloudProvider,
-		externalCloudProviderAzure,
-		externalCloudProviderGCP,
-		externalCloudProviderExternal,
-		privateHostedZoneAWS,
-		buildCSIVolumes,
-		kmsv1,
-		vSphereControlPlaneMachineset,
-		sdnLiveMigration,
-	},
-	Disabled: []FeatureGateDescription{
-		disableKubeletCloudCredentialProviders, // We do not currently ship the correct config to use the external credentials provider.
-	},
-}
-
-type featureSetBuilder struct {
-	forceOn  []FeatureGateDescription
-	forceOff []FeatureGateDescription
-}
-
-func newDefaultFeatures() *featureSetBuilder {
-	return &featureSetBuilder{}
-}
-
-func (f *featureSetBuilder) with(forceOn FeatureGateDescription) *featureSetBuilder {
-	for _, curr := range f.forceOn {
-		if curr.FeatureGateAttributes.Name == forceOn.FeatureGateAttributes.Name {
-			panic(fmt.Errorf("coding error: %q enabled twice", forceOn.FeatureGateAttributes.Name))
-		}
-	}
-	f.forceOn = append(f.forceOn, forceOn)
-	return f
-}
-
-func (f *featureSetBuilder) without(forceOff FeatureGateDescription) *featureSetBuilder {
-	for _, curr := range f.forceOff {
-		if curr.FeatureGateAttributes.Name == forceOff.FeatureGateAttributes.Name {
-			panic(fmt.Errorf("coding error: %q disabled twice", forceOff.FeatureGateAttributes.Name))
-		}
-	}
-	f.forceOff = append(f.forceOff, forceOff)
-	return f
-}
-
-func (f *featureSetBuilder) isForcedOff(needle FeatureGateDescription) bool {
-	for _, forcedOff := range f.forceOff {
-		if needle.FeatureGateAttributes.Name == forcedOff.FeatureGateAttributes.Name {
-			return true
-		}
-	}
-	return false
-}
-
-func (f *featureSetBuilder) isForcedOn(needle FeatureGateDescription) bool {
-	for _, forceOn := range f.forceOn {
-		if needle.FeatureGateAttributes.Name == forceOn.FeatureGateAttributes.Name {
-			return true
-		}
-	}
-	return false
-}
-
-func (f *featureSetBuilder) toFeatures(defaultFeatures *FeatureGateEnabledDisabled) *FeatureGateEnabledDisabled {
-	finalOn := []FeatureGateDescription{}
-	finalOff := []FeatureGateDescription{}
-
-	// only add the default enabled features if they haven't been explicitly set off
-	for _, defaultOn := range defaultFeatures.Enabled {
-		if !f.isForcedOff(defaultOn) {
-			finalOn = append(finalOn, defaultOn)
-		}
-	}
-	for _, currOn := range f.forceOn {
-		if f.isForcedOff(currOn) {
-			panic("coding error, you can't have features both on and off")
-		}
-		found := false
-		for _, alreadyOn := range finalOn {
-			if alreadyOn.FeatureGateAttributes.Name == currOn.FeatureGateAttributes.Name {
-				found = true
-			}
-		}
-		if found {
-			continue
-		}
-
-		finalOn = append(finalOn, currOn)
-	}
-
-	// only add the default disabled features if they haven't been explicitly set on
-	for _, defaultOff := range defaultFeatures.Disabled {
-		if !f.isForcedOn(defaultOff) {
-			finalOff = append(finalOff, defaultOff)
-		}
-	}
-	for _, currOff := range f.forceOff {
-		finalOff = append(finalOff, currOff)
-	}
-
-	return &FeatureGateEnabledDisabled{
-		Enabled:  finalOn,
-		Disabled: finalOff,
-	}
-}
diff --git a/vendor/github.com/openshift/api/config/v1/types_image.go b/vendor/github.com/openshift/api/config/v1/types_image.go
index 928224c0..74511f86 100644
--- a/vendor/github.com/openshift/api/config/v1/types_image.go
+++ b/vendor/github.com/openshift/api/config/v1/types_image.go
@@ -15,6 +15,11 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
 // +openshift:compatibility-gen:level=1
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/470
+// +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=images,scope=Cluster
+// +kubebuilder:subresource:status
 type Image struct {
 	metav1.TypeMeta `json:",inline"`
 
diff --git a/vendor/github.com/openshift/api/config/v1/types_image_content_policy.go b/vendor/github.com/openshift/api/config/v1/types_image_content_policy.go
index 3dc315f6..f2faf199 100644
--- a/vendor/github.com/openshift/api/config/v1/types_image_content_policy.go
+++ b/vendor/github.com/openshift/api/config/v1/types_image_content_policy.go
@@ -11,6 +11,11 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
 // +openshift:compatibility-gen:level=1
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/874
+// +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=imagecontentpolicies,scope=Cluster
+// +kubebuilder:subresource:status
 type ImageContentPolicy struct {
 	metav1.TypeMeta `json:",inline"`
 
diff --git a/vendor/github.com/openshift/api/config/v1/types_image_digest_mirror_set.go b/vendor/github.com/openshift/api/config/v1/types_image_digest_mirror_set.go
index 987c6cfd..8fa38f22 100644
--- a/vendor/github.com/openshift/api/config/v1/types_image_digest_mirror_set.go
+++ b/vendor/github.com/openshift/api/config/v1/types_image_digest_mirror_set.go
@@ -11,6 +11,11 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
 // +openshift:compatibility-gen:level=1
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/1126
+// +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=imagedigestmirrorsets,scope=Cluster,shortName=idms
+// +kubebuilder:subresource:status
 type ImageDigestMirrorSet struct {
 	metav1.TypeMeta `json:",inline"`
 
diff --git a/vendor/github.com/openshift/api/config/v1/types_image_tag_mirror_set.go b/vendor/github.com/openshift/api/config/v1/types_image_tag_mirror_set.go
index 295522e5..d9627b78 100644
--- a/vendor/github.com/openshift/api/config/v1/types_image_tag_mirror_set.go
+++ b/vendor/github.com/openshift/api/config/v1/types_image_tag_mirror_set.go
@@ -11,6 +11,11 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
 // +openshift:compatibility-gen:level=1
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/1126
+// +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=imagetagmirrorsets,scope=Cluster,shortName=itms
+// +kubebuilder:subresource:status
 type ImageTagMirrorSet struct {
 	metav1.TypeMeta `json:",inline"`
 
diff --git a/vendor/github.com/openshift/api/config/v1/types_infrastructure.go b/vendor/github.com/openshift/api/config/v1/types_infrastructure.go
index 4ff2e68f..611ba928 100644
--- a/vendor/github.com/openshift/api/config/v1/types_infrastructure.go
+++ b/vendor/github.com/openshift/api/config/v1/types_infrastructure.go
@@ -13,6 +13,11 @@ import (
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
 // +openshift:compatibility-gen:level=1
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/470
+// +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=infrastructures,scope=Cluster
+// +kubebuilder:subresource:status
 type Infrastructure struct {
 	metav1.TypeMeta `json:",inline"`
 
@@ -603,8 +608,8 @@ const (
 type GCPPlatformSpec struct{}
 
 // GCPPlatformStatus holds the current status of the Google Cloud Platform infrastructure provider.
-// +openshift:validation:FeatureSetAwareXValidation:featureSet=CustomNoUpgrade;TechPreviewNoUpgrade,rule="!has(oldSelf.resourceLabels) && !has(self.resourceLabels) || has(oldSelf.resourceLabels) && has(self.resourceLabels)",message="resourceLabels may only be configured during installation"
-// +openshift:validation:FeatureSetAwareXValidation:featureSet=CustomNoUpgrade;TechPreviewNoUpgrade,rule="!has(oldSelf.resourceTags) && !has(self.resourceTags) || has(oldSelf.resourceTags) && has(self.resourceTags)",message="resourceTags may only be configured during installation"
+// +openshift:validation:FeatureGateAwareXValidation:featureGate=GCPLabelsTags,rule="!has(oldSelf.resourceLabels) && !has(self.resourceLabels) || has(oldSelf.resourceLabels) && has(self.resourceLabels)",message="resourceLabels may only be configured during installation"
+// +openshift:validation:FeatureGateAwareXValidation:featureGate=GCPLabelsTags,rule="!has(oldSelf.resourceTags) && !has(self.resourceTags) || has(oldSelf.resourceTags) && has(self.resourceTags)",message="resourceTags may only be configured during installation"
 type GCPPlatformStatus struct {
 	// resourceGroupName is the Project ID for new GCP resources created for the cluster.
 	ProjectID string `json:"projectID"`
@@ -621,7 +626,7 @@ type GCPPlatformStatus struct {
 	// +listType=map
 	// +listMapKey=key
 	// +optional
-	// +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade
+	// +openshift:enable:FeatureGate=GCPLabelsTags
 	ResourceLabels []GCPResourceLabel `json:"resourceLabels,omitempty"`
 
 	// resourceTags is a list of additional tags to apply to GCP resources created for the cluster.
@@ -632,7 +637,7 @@ type GCPPlatformStatus struct {
 	// +listType=map
 	// +listMapKey=key
 	// +optional
-	// +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade
+	// +openshift:enable:FeatureGate=GCPLabelsTags
 	ResourceTags []GCPResourceTag `json:"resourceTags,omitempty"`
 
 	// This field was introduced and removed under tech preview.
@@ -649,7 +654,7 @@ type GCPPlatformStatus struct {
 	//
 	// +default={"dnsType": "PlatformDefault"}
 	// +kubebuilder:default={"dnsType": "PlatformDefault"}
-	// +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade
+	// +openshift:enable:FeatureGate=GCPClusterHostedDNS
 	// +optional
 	// +nullable
 	CloudLoadBalancerConfig *CloudLoadBalancerConfig `json:"cloudLoadBalancerConfig,omitempty"`
@@ -898,7 +903,7 @@ type BareMetalPlatformStatus struct {
 	// loadBalancer defines how the load balancer used by the cluster is configured.
 	// +default={"type": "OpenShiftManagedDefault"}
 	// +kubebuilder:default={"type": "OpenShiftManagedDefault"}
-	// +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade
+	// +openshift:enable:FeatureGate=BareMetalLoadBalancer
 	// +optional
 	LoadBalancer *BareMetalPlatformLoadBalancer `json:"loadBalancer,omitempty"`
 
@@ -1105,7 +1110,7 @@ type OvirtPlatformStatus struct {
 	// loadBalancer defines how the load balancer used by the cluster is configured.
 	// +default={"type": "OpenShiftManagedDefault"}
 	// +kubebuilder:default={"type": "OpenShiftManagedDefault"}
-	// +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade
+	// +openshift:enable:FeatureGate=BareMetalLoadBalancer
 	// +optional
 	LoadBalancer *OvirtPlatformLoadBalancer `json:"loadBalancer,omitempty"`
 }
@@ -1235,6 +1240,7 @@ type VSpherePlatformTopology struct {
 	// VSpherePlatformFailureDomainSpec.
 	// For example, for zone=zonea, region=region1, and infrastructure name=test,
 	// the template path would be calculated as /<datacenter>/vm/test-rhcos-region1-zonea.
+	// +openshift:enable:FeatureGate=VSphereControlPlaneMachineSet
 	// +kubebuilder:validation:MinLength=1
 	// +kubebuilder:validation:MaxLength=2048
 	// +kubebuilder:validation:Pattern=`^/.*?/vm/.*?`
@@ -1436,7 +1442,7 @@ type VSpherePlatformStatus struct {
 	// loadBalancer defines how the load balancer used by the cluster is configured.
 	// +default={"type": "OpenShiftManagedDefault"}
 	// +kubebuilder:default={"type": "OpenShiftManagedDefault"}
-	// +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade
+	// +openshift:enable:FeatureGate=BareMetalLoadBalancer
 	// +optional
 	LoadBalancer *VSpherePlatformLoadBalancer `json:"loadBalancer,omitempty"`
 
@@ -1829,7 +1835,7 @@ type NutanixPlatformStatus struct {
 	// loadBalancer defines how the load balancer used by the cluster is configured.
 	// +default={"type": "OpenShiftManagedDefault"}
 	// +kubebuilder:default={"type": "OpenShiftManagedDefault"}
-	// +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade
+	// +openshift:enable:FeatureGate=BareMetalLoadBalancer
 	// +optional
 	LoadBalancer *NutanixPlatformLoadBalancer `json:"loadBalancer,omitempty"`
 }
diff --git a/vendor/github.com/openshift/api/config/v1/types_ingress.go b/vendor/github.com/openshift/api/config/v1/types_ingress.go
index e518f676..e7c547d9 100644
--- a/vendor/github.com/openshift/api/config/v1/types_ingress.go
+++ b/vendor/github.com/openshift/api/config/v1/types_ingress.go
@@ -13,6 +13,11 @@ import (
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
 // +openshift:compatibility-gen:level=1
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/470
+// +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=ingresses,scope=Cluster
+// +kubebuilder:subresource:status
 type Ingress struct {
 	metav1.TypeMeta `json:",inline"`
 
diff --git a/vendor/github.com/openshift/api/config/v1/types_network.go b/vendor/github.com/openshift/api/config/v1/types_network.go
index 794f3db7..e87785e3 100644
--- a/vendor/github.com/openshift/api/config/v1/types_network.go
+++ b/vendor/github.com/openshift/api/config/v1/types_network.go
@@ -10,7 +10,11 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 // Please view network.spec for an explanation on what applies when configuring this resource.
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/470
 // +openshift:compatibility-gen:level=1
+// +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=networks,scope=Cluster
 type Network struct {
 	metav1.TypeMeta `json:",inline"`
 
@@ -95,6 +99,7 @@ type NetworkStatus struct {
 	// +patchStrategy=merge
 	// +listType=map
 	// +listMapKey=type
+	// +openshift:enable:FeatureGate=NetworkLiveMigration
 	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
 }
 
diff --git a/vendor/github.com/openshift/api/config/v1/types_node.go b/vendor/github.com/openshift/api/config/v1/types_node.go
index 233c89d9..3dd31f39 100644
--- a/vendor/github.com/openshift/api/config/v1/types_node.go
+++ b/vendor/github.com/openshift/api/config/v1/types_node.go
@@ -14,6 +14,9 @@ import (
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
 // +openshift:compatibility-gen:level=1
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/1107
+// +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01
+// +kubebuilder:object:root=true
 // +kubebuilder:resource:path=nodes,scope=Cluster
 // +kubebuilder:subresource:status
 type Node struct {
diff --git a/vendor/github.com/openshift/api/config/v1/types_oauth.go b/vendor/github.com/openshift/api/config/v1/types_oauth.go
index 451a5ec3..6654479d 100644
--- a/vendor/github.com/openshift/api/config/v1/types_oauth.go
+++ b/vendor/github.com/openshift/api/config/v1/types_oauth.go
@@ -14,6 +14,11 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
 // +openshift:compatibility-gen:level=1
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/470
+// +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=oauths,scope=Cluster
+// +kubebuilder:subresource:status
 type OAuth struct {
 	metav1.TypeMeta `json:",inline"`
 
diff --git a/vendor/github.com/openshift/api/config/v1/types_operatorhub.go b/vendor/github.com/openshift/api/config/v1/types_operatorhub.go
index ba2c9634..1fddfa51 100644
--- a/vendor/github.com/openshift/api/config/v1/types_operatorhub.go
+++ b/vendor/github.com/openshift/api/config/v1/types_operatorhub.go
@@ -38,9 +38,14 @@ type OperatorHubStatus struct {
 // enabled to disabled and vice versa.
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=operatorhubs,scope=Cluster
 // +kubebuilder:subresource:status
 // +genclient
 // +genclient:nonNamespaced
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/470
+// +openshift:file-pattern=cvoRunLevel=0000_03,operatorName=marketplace,operatorOrdering=01
+// +openshift:capability=marketplace
 // +openshift:compatibility-gen:level=1
 type OperatorHub struct {
 	metav1.TypeMeta `json:",inline"`
diff --git a/vendor/github.com/openshift/api/config/v1/types_project.go b/vendor/github.com/openshift/api/config/v1/types_project.go
index 85afb90c..8d6d614b 100644
--- a/vendor/github.com/openshift/api/config/v1/types_project.go
+++ b/vendor/github.com/openshift/api/config/v1/types_project.go
@@ -10,6 +10,11 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
 // +openshift:compatibility-gen:level=1
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/470
+// +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=projects,scope=Cluster
+// +kubebuilder:subresource:status
 type Project struct {
 	metav1.TypeMeta `json:",inline"`
 
diff --git a/vendor/github.com/openshift/api/config/v1/types_proxy.go b/vendor/github.com/openshift/api/config/v1/types_proxy.go
index 40ed296d..851291bb 100644
--- a/vendor/github.com/openshift/api/config/v1/types_proxy.go
+++ b/vendor/github.com/openshift/api/config/v1/types_proxy.go
@@ -12,6 +12,11 @@ import (
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
 // +openshift:compatibility-gen:level=1
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/470
+// +openshift:file-pattern=cvoRunLevel=0000_03,operatorName=config-operator,operatorOrdering=01
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=proxies,scope=Cluster
+// +kubebuilder:subresource:status
 type Proxy struct {
 	metav1.TypeMeta `json:",inline"`
 
diff --git a/vendor/github.com/openshift/api/config/v1/types_scheduling.go b/vendor/github.com/openshift/api/config/v1/types_scheduling.go
index 07c4d2e4..061c4a88 100644
--- a/vendor/github.com/openshift/api/config/v1/types_scheduling.go
+++ b/vendor/github.com/openshift/api/config/v1/types_scheduling.go
@@ -11,6 +11,11 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
 // +openshift:compatibility-gen:level=1
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/470
+// +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=schedulers,scope=Cluster
+// +kubebuilder:subresource:status
 type Scheduler struct {
 	metav1.TypeMeta `json:",inline"`
 
@@ -43,7 +48,7 @@ type SchedulerSpec struct {
 	// +optional
 	Profile SchedulerProfile `json:"profile,omitempty"`
 	// profileCustomizations contains configuration for modifying the default behavior of existing scheduler profiles.
-	// +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade
+	// +openshift:enable:FeatureGate=DynamicResourceAllocation
 	// +optional
 	ProfileCustomizations ProfileCustomizations `json:"profileCustomizations"`
 	// defaultNodeSelector helps set the cluster-wide default node selector to
diff --git a/vendor/github.com/openshift/api/config/v1/types_tlssecurityprofile.go b/vendor/github.com/openshift/api/config/v1/types_tlssecurityprofile.go
index 4f69de40..c5dea1a0 100644
--- a/vendor/github.com/openshift/api/config/v1/types_tlssecurityprofile.go
+++ b/vendor/github.com/openshift/api/config/v1/types_tlssecurityprofile.go
@@ -27,35 +27,65 @@ type TLSSecurityProfile struct {
 	// and looks like this (yaml):
 	//
 	//   ciphers:
+	//
 	//     - TLS_AES_128_GCM_SHA256
+	//
 	//     - TLS_AES_256_GCM_SHA384
+	//
 	//     - TLS_CHACHA20_POLY1305_SHA256
+	//
 	//     - ECDHE-ECDSA-AES128-GCM-SHA256
+	//
 	//     - ECDHE-RSA-AES128-GCM-SHA256
+	//
 	//     - ECDHE-ECDSA-AES256-GCM-SHA384
+	//
 	//     - ECDHE-RSA-AES256-GCM-SHA384
+	//
 	//     - ECDHE-ECDSA-CHACHA20-POLY1305
+	//
 	//     - ECDHE-RSA-CHACHA20-POLY1305
+	//
 	//     - DHE-RSA-AES128-GCM-SHA256
+	//
 	//     - DHE-RSA-AES256-GCM-SHA384
+	//
 	//     - DHE-RSA-CHACHA20-POLY1305
+	//
 	//     - ECDHE-ECDSA-AES128-SHA256
+	//
 	//     - ECDHE-RSA-AES128-SHA256
+	//
 	//     - ECDHE-ECDSA-AES128-SHA
+	//
 	//     - ECDHE-RSA-AES128-SHA
+	//
 	//     - ECDHE-ECDSA-AES256-SHA384
+	//
 	//     - ECDHE-RSA-AES256-SHA384
+	//
 	//     - ECDHE-ECDSA-AES256-SHA
+	//
 	//     - ECDHE-RSA-AES256-SHA
+	//
 	//     - DHE-RSA-AES128-SHA256
+	//
 	//     - DHE-RSA-AES256-SHA256
+	//
 	//     - AES128-GCM-SHA256
+	//
 	//     - AES256-GCM-SHA384
+	//
 	//     - AES128-SHA256
+	//
 	//     - AES256-SHA256
+	//
 	//     - AES128-SHA
+	//
 	//     - AES256-SHA
+	//
 	//     - DES-CBC3-SHA
+	//
 	//   minTLSVersion: VersionTLS10
 	//
 	// +optional
@@ -68,17 +98,29 @@ type TLSSecurityProfile struct {
 	// and looks like this (yaml):
 	//
 	//   ciphers:
+	//
 	//     - TLS_AES_128_GCM_SHA256
+	//
 	//     - TLS_AES_256_GCM_SHA384
+	//
 	//     - TLS_CHACHA20_POLY1305_SHA256
+	//
 	//     - ECDHE-ECDSA-AES128-GCM-SHA256
+	//
 	//     - ECDHE-RSA-AES128-GCM-SHA256
+	//
 	//     - ECDHE-ECDSA-AES256-GCM-SHA384
+	//
 	//     - ECDHE-RSA-AES256-GCM-SHA384
+	//
 	//     - ECDHE-ECDSA-CHACHA20-POLY1305
+	//
 	//     - ECDHE-RSA-CHACHA20-POLY1305
+	//
 	//     - DHE-RSA-AES128-GCM-SHA256
+	//
 	//     - DHE-RSA-AES256-GCM-SHA384
+	//
 	//   minTLSVersion: VersionTLS12
 	//
 	// +optional
@@ -91,12 +133,14 @@ type TLSSecurityProfile struct {
 	// and looks like this (yaml):
 	//
 	//   ciphers:
+	//
 	//     - TLS_AES_128_GCM_SHA256
+	//
 	//     - TLS_AES_256_GCM_SHA384
+	//
 	//     - TLS_CHACHA20_POLY1305_SHA256
-	//   minTLSVersion: VersionTLS13
 	//
-	// NOTE: Currently unsupported.
+	//   minTLSVersion: VersionTLS13
 	//
 	// +optional
 	// +nullable
@@ -106,10 +150,15 @@ type TLSSecurityProfile struct {
 	// looks like this:
 	//
 	//   ciphers:
+	//
 	//     - ECDHE-ECDSA-CHACHA20-POLY1305
+	//
 	//     - ECDHE-RSA-CHACHA20-POLY1305
+	//
 	//     - ECDHE-RSA-AES128-GCM-SHA256
+	//
 	//     - ECDHE-ECDSA-AES128-GCM-SHA256
+	//
 	//   minTLSVersion: VersionTLS11
 	//
 	// +optional
@@ -177,7 +226,7 @@ type TLSProfileSpec struct {
 // TLSProtocolVersion is a way to specify the protocol version used for TLS connections.
 // Protocol versions are based on the following most common TLS configurations:
 //
-//   https://ssl-config.mozilla.org/
+//	https://ssl-config.mozilla.org/
 //
 // Note that SSLv3.0 is not a supported protocol version due to well known
 // vulnerabilities such as POODLE: https://en.wikipedia.org/wiki/POODLE
diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml
new file mode 100644
index 00000000..5caf5756
--- /dev/null
+++ b/vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml
@@ -0,0 +1,491 @@
+apiservers.config.openshift.io:
+  Annotations: {}
+  ApprovedPRNumber: https://github.com/openshift/api/pull/470
+  CRDName: apiservers.config.openshift.io
+  Capability: ""
+  Category: ""
+  FeatureGates: []
+  FilenameOperatorName: config-operator
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_10"
+  GroupName: config.openshift.io
+  HasStatus: true
+  KindName: APIServer
+  Labels: {}
+  PluralName: apiservers
+  PrinterColumns: []
+  Scope: Cluster
+  ShortNames: null
+  TopLevelFeatureGates: []
+  Version: v1
+
+authentications.config.openshift.io:
+  Annotations: {}
+  ApprovedPRNumber: https://github.com/openshift/api/pull/470
+  CRDName: authentications.config.openshift.io
+  Capability: ""
+  Category: ""
+  FeatureGates:
+  - ExternalOIDC
+  FilenameOperatorName: config-operator
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_10"
+  GroupName: config.openshift.io
+  HasStatus: true
+  KindName: Authentication
+  Labels: {}
+  PluralName: authentications
+  PrinterColumns: []
+  Scope: Cluster
+  ShortNames: null
+  TopLevelFeatureGates: []
+  Version: v1
+
+builds.config.openshift.io:
+  Annotations: {}
+  ApprovedPRNumber: https://github.com/openshift/api/pull/470
+  CRDName: builds.config.openshift.io
+  Capability: Build
+  Category: ""
+  FeatureGates: []
+  FilenameOperatorName: openshift-controller-manager
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_10"
+  GroupName: config.openshift.io
+  HasStatus: true
+  KindName: Build
+  Labels: {}
+  PluralName: builds
+  PrinterColumns: []
+  Scope: Cluster
+  ShortNames: null
+  TopLevelFeatureGates: []
+  Version: v1
+
+clusteroperators.config.openshift.io:
+  Annotations:
+    include.release.openshift.io/self-managed-high-availability: "true"
+    include.release.openshift.io/single-node-developer: "true"
+  ApprovedPRNumber: https://github.com/openshift/api/pull/497
+  CRDName: clusteroperators.config.openshift.io
+  Capability: ""
+  Category: ""
+  FeatureGates: []
+  FilenameOperatorName: cluster-version-operator
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_00"
+  GroupName: config.openshift.io
+  HasStatus: true
+  KindName: ClusterOperator
+  Labels: {}
+  PluralName: clusteroperators
+  PrinterColumns:
+  - description: The version the operator is at.
+    jsonPath: .status.versions[?(@.name=="operator")].version
+    name: Version
+    type: string
+  - description: Whether the operator is running and stable.
+    jsonPath: .status.conditions[?(@.type=="Available")].status
+    name: Available
+    type: string
+  - description: Whether the operator is processing changes.
+    jsonPath: .status.conditions[?(@.type=="Progressing")].status
+    name: Progressing
+    type: string
+  - description: Whether the operator is degraded.
+    jsonPath: .status.conditions[?(@.type=="Degraded")].status
+    name: Degraded
+    type: string
+  - description: The time the operator's Available status last changed.
+    jsonPath: .status.conditions[?(@.type=="Available")].lastTransitionTime
+    name: Since
+    type: date
+  Scope: Cluster
+  ShortNames:
+  - co
+  TopLevelFeatureGates: []
+  Version: v1
+
+clusterversions.config.openshift.io:
+  Annotations:
+    include.release.openshift.io/self-managed-high-availability: "true"
+    include.release.openshift.io/single-node-developer: "true"
+  ApprovedPRNumber: https://github.com/openshift/api/pull/495
+  CRDName: clusterversions.config.openshift.io
+  Capability: ""
+  Category: ""
+  FeatureGates:
+  - SignatureStores
+  FilenameOperatorName: cluster-version-operator
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_00"
+  GroupName: config.openshift.io
+  HasStatus: true
+  KindName: ClusterVersion
+  Labels: {}
+  PluralName: clusterversions
+  PrinterColumns:
+  - jsonPath: .status.history[?(@.state=="Completed")].version
+    name: Version
+    type: string
+  - jsonPath: .status.conditions[?(@.type=="Available")].status
+    name: Available
+    type: string
+  - jsonPath: .status.conditions[?(@.type=="Progressing")].status
+    name: Progressing
+    type: string
+  - jsonPath: .status.conditions[?(@.type=="Progressing")].lastTransitionTime
+    name: Since
+    type: date
+  - jsonPath: .status.conditions[?(@.type=="Progressing")].message
+    name: Status
+    type: string
+  Scope: Cluster
+  ShortNames: null
+  TopLevelFeatureGates: []
+  Version: v1
+
+consoles.config.openshift.io:
+  Annotations: {}
+  ApprovedPRNumber: https://github.com/openshift/api/pull/470
+  CRDName: consoles.config.openshift.io
+  Capability: ""
+  Category: ""
+  FeatureGates: []
+  FilenameOperatorName: config-operator
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_10"
+  GroupName: config.openshift.io
+  HasStatus: true
+  KindName: Console
+  Labels: {}
+  PluralName: consoles
+  PrinterColumns: []
+  Scope: Cluster
+  ShortNames: null
+  TopLevelFeatureGates: []
+  Version: v1
+
+dnses.config.openshift.io:
+  Annotations: {}
+  ApprovedPRNumber: https://github.com/openshift/api/pull/470
+  CRDName: dnses.config.openshift.io
+  Capability: ""
+  Category: ""
+  FeatureGates: []
+  FilenameOperatorName: config-operator
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_10"
+  GroupName: config.openshift.io
+  HasStatus: true
+  KindName: DNS
+  Labels: {}
+  PluralName: dnses
+  PrinterColumns: []
+  Scope: Cluster
+  ShortNames: null
+  TopLevelFeatureGates: []
+  Version: v1
+
+featuregates.config.openshift.io:
+  Annotations: {}
+  ApprovedPRNumber: https://github.com/openshift/api/pull/470
+  CRDName: featuregates.config.openshift.io
+  Capability: ""
+  Category: ""
+  FeatureGates: []
+  FilenameOperatorName: config-operator
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_10"
+  GroupName: config.openshift.io
+  HasStatus: true
+  KindName: FeatureGate
+  Labels: {}
+  PluralName: featuregates
+  PrinterColumns: []
+  Scope: Cluster
+  ShortNames: null
+  TopLevelFeatureGates: []
+  Version: v1
+
+images.config.openshift.io:
+  Annotations: {}
+  ApprovedPRNumber: https://github.com/openshift/api/pull/470
+  CRDName: images.config.openshift.io
+  Capability: ""
+  Category: ""
+  FeatureGates: []
+  FilenameOperatorName: config-operator
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_10"
+  GroupName: config.openshift.io
+  HasStatus: true
+  KindName: Image
+  Labels: {}
+  PluralName: images
+  PrinterColumns: []
+  Scope: Cluster
+  ShortNames: null
+  TopLevelFeatureGates: []
+  Version: v1
+
+imagecontentpolicies.config.openshift.io:
+  Annotations: {}
+  ApprovedPRNumber: https://github.com/openshift/api/pull/874
+  CRDName: imagecontentpolicies.config.openshift.io
+  Capability: ""
+  Category: ""
+  FeatureGates: []
+  FilenameOperatorName: config-operator
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_10"
+  GroupName: config.openshift.io
+  HasStatus: true
+  KindName: ImageContentPolicy
+  Labels: {}
+  PluralName: imagecontentpolicies
+  PrinterColumns: []
+  Scope: Cluster
+  ShortNames: null
+  TopLevelFeatureGates: []
+  Version: v1
+
+imagedigestmirrorsets.config.openshift.io:
+  Annotations: {}
+  ApprovedPRNumber: https://github.com/openshift/api/pull/1126
+  CRDName: imagedigestmirrorsets.config.openshift.io
+  Capability: ""
+  Category: ""
+  FeatureGates: []
+  FilenameOperatorName: config-operator
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_10"
+  GroupName: config.openshift.io
+  HasStatus: true
+  KindName: ImageDigestMirrorSet
+  Labels: {}
+  PluralName: imagedigestmirrorsets
+  PrinterColumns: []
+  Scope: Cluster
+  ShortNames:
+  - idms
+  TopLevelFeatureGates: []
+  Version: v1
+
+imagetagmirrorsets.config.openshift.io:
+  Annotations: {}
+  ApprovedPRNumber: https://github.com/openshift/api/pull/1126
+  CRDName: imagetagmirrorsets.config.openshift.io
+  Capability: ""
+  Category: ""
+  FeatureGates: []
+  FilenameOperatorName: config-operator
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_10"
+  GroupName: config.openshift.io
+  HasStatus: true
+  KindName: ImageTagMirrorSet
+  Labels: {}
+  PluralName: imagetagmirrorsets
+  PrinterColumns: []
+  Scope: Cluster
+  ShortNames:
+  - itms
+  TopLevelFeatureGates: []
+  Version: v1
+
+infrastructures.config.openshift.io:
+  Annotations: {}
+  ApprovedPRNumber: https://github.com/openshift/api/pull/470
+  CRDName: infrastructures.config.openshift.io
+  Capability: ""
+  Category: ""
+  FeatureGates:
+  - BareMetalLoadBalancer
+  - GCPClusterHostedDNS
+  - GCPLabelsTags
+  - VSphereControlPlaneMachineSet
+  FilenameOperatorName: config-operator
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_10"
+  GroupName: config.openshift.io
+  HasStatus: true
+  KindName: Infrastructure
+  Labels: {}
+  PluralName: infrastructures
+  PrinterColumns: []
+  Scope: Cluster
+  ShortNames: null
+  TopLevelFeatureGates: []
+  Version: v1
+
+ingresses.config.openshift.io:
+  Annotations: {}
+  ApprovedPRNumber: https://github.com/openshift/api/pull/470
+  CRDName: ingresses.config.openshift.io
+  Capability: ""
+  Category: ""
+  FeatureGates: []
+  FilenameOperatorName: config-operator
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_10"
+  GroupName: config.openshift.io
+  HasStatus: true
+  KindName: Ingress
+  Labels: {}
+  PluralName: ingresses
+  PrinterColumns: []
+  Scope: Cluster
+  ShortNames: null
+  TopLevelFeatureGates: []
+  Version: v1
+
+networks.config.openshift.io:
+  Annotations: {}
+  ApprovedPRNumber: https://github.com/openshift/api/pull/470
+  CRDName: networks.config.openshift.io
+  Capability: ""
+  Category: ""
+  FeatureGates:
+  - NetworkLiveMigration
+  FilenameOperatorName: config-operator
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_10"
+  GroupName: config.openshift.io
+  HasStatus: false
+  KindName: Network
+  Labels: {}
+  PluralName: networks
+  PrinterColumns: []
+  Scope: Cluster
+  ShortNames: null
+  TopLevelFeatureGates: []
+  Version: v1
+
+nodes.config.openshift.io:
+  Annotations: {}
+  ApprovedPRNumber: https://github.com/openshift/api/pull/1107
+  CRDName: nodes.config.openshift.io
+  Capability: ""
+  Category: ""
+  FeatureGates: []
+  FilenameOperatorName: config-operator
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_10"
+  GroupName: config.openshift.io
+  HasStatus: true
+  KindName: Node
+  Labels: {}
+  PluralName: nodes
+  PrinterColumns: []
+  Scope: Cluster
+  ShortNames: null
+  TopLevelFeatureGates: []
+  Version: v1
+
+oauths.config.openshift.io:
+  Annotations: {}
+  ApprovedPRNumber: https://github.com/openshift/api/pull/470
+  CRDName: oauths.config.openshift.io
+  Capability: ""
+  Category: ""
+  FeatureGates: []
+  FilenameOperatorName: config-operator
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_10"
+  GroupName: config.openshift.io
+  HasStatus: true
+  KindName: OAuth
+  Labels: {}
+  PluralName: oauths
+  PrinterColumns: []
+  Scope: Cluster
+  ShortNames: null
+  TopLevelFeatureGates: []
+  Version: v1
+
+operatorhubs.config.openshift.io:
+  Annotations: {}
+  ApprovedPRNumber: https://github.com/openshift/api/pull/470
+  CRDName: operatorhubs.config.openshift.io
+  Capability: marketplace
+  Category: ""
+  FeatureGates: []
+  FilenameOperatorName: marketplace
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_03"
+  GroupName: config.openshift.io
+  HasStatus: true
+  KindName: OperatorHub
+  Labels: {}
+  PluralName: operatorhubs
+  PrinterColumns: []
+  Scope: Cluster
+  ShortNames: null
+  TopLevelFeatureGates: []
+  Version: v1
+
+projects.config.openshift.io:
+  Annotations: {}
+  ApprovedPRNumber: https://github.com/openshift/api/pull/470
+  CRDName: projects.config.openshift.io
+  Capability: ""
+  Category: ""
+  FeatureGates: []
+  FilenameOperatorName: config-operator
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_10"
+  GroupName: config.openshift.io
+  HasStatus: true
+  KindName: Project
+  Labels: {}
+  PluralName: projects
+  PrinterColumns: []
+  Scope: Cluster
+  ShortNames: null
+  TopLevelFeatureGates: []
+  Version: v1
+
+proxies.config.openshift.io:
+  Annotations: {}
+  ApprovedPRNumber: https://github.com/openshift/api/pull/470
+  CRDName: proxies.config.openshift.io
+  Capability: ""
+  Category: ""
+  FeatureGates: []
+  FilenameOperatorName: config-operator
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_03"
+  GroupName: config.openshift.io
+  HasStatus: true
+  KindName: Proxy
+  Labels: {}
+  PluralName: proxies
+  PrinterColumns: []
+  Scope: Cluster
+  ShortNames: null
+  TopLevelFeatureGates: []
+  Version: v1
+
+schedulers.config.openshift.io:
+  Annotations: {}
+  ApprovedPRNumber: https://github.com/openshift/api/pull/470
+  CRDName: schedulers.config.openshift.io
+  Capability: ""
+  Category: ""
+  FeatureGates:
+  - DynamicResourceAllocation
+  FilenameOperatorName: config-operator
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_10"
+  GroupName: config.openshift.io
+  HasStatus: true
+  KindName: Scheduler
+  Labels: {}
+  PluralName: schedulers
+  PrinterColumns: []
+  Scope: Cluster
+  ShortNames: null
+  TopLevelFeatureGates: []
+  Version: v1
+
diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go
index 92e28191..f751368b 100644
--- a/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go
+++ b/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go
@@ -2521,10 +2521,10 @@ func (TLSProfileSpec) SwaggerDoc() map[string]string {
 var map_TLSSecurityProfile = map[string]string{
 	"":             "TLSSecurityProfile defines the schema for a TLS security profile. This object is used by operators to apply TLS security settings to operands.",
 	"type":         "type is one of Old, Intermediate, Modern or Custom. Custom provides the ability to specify individual TLS security profile parameters. Old, Intermediate and Modern are TLS security profiles based on:\n\nhttps://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations\n\nThe profiles are intent based, so they may change over time as new ciphers are developed and existing ciphers are found to be insecure.  Depending on precisely which ciphers are available to a process, the list may be reduced.\n\nNote that the Modern profile is currently not supported because it is not yet well adopted by common software libraries.",
-	"old":          "old is a TLS security profile based on:\n\nhttps://wiki.mozilla.org/Security/Server_Side_TLS#Old_backward_compatibility\n\nand looks like this (yaml):\n\n  ciphers:\n    - TLS_AES_128_GCM_SHA256\n    - TLS_AES_256_GCM_SHA384\n    - TLS_CHACHA20_POLY1305_SHA256\n    - ECDHE-ECDSA-AES128-GCM-SHA256\n    - ECDHE-RSA-AES128-GCM-SHA256\n    - ECDHE-ECDSA-AES256-GCM-SHA384\n    - ECDHE-RSA-AES256-GCM-SHA384\n    - ECDHE-ECDSA-CHACHA20-POLY1305\n    - ECDHE-RSA-CHACHA20-POLY1305\n    - DHE-RSA-AES128-GCM-SHA256\n    - DHE-RSA-AES256-GCM-SHA384\n    - DHE-RSA-CHACHA20-POLY1305\n    - ECDHE-ECDSA-AES128-SHA256\n    - ECDHE-RSA-AES128-SHA256\n    - ECDHE-ECDSA-AES128-SHA\n    - ECDHE-RSA-AES128-SHA\n    - ECDHE-ECDSA-AES256-SHA384\n    - ECDHE-RSA-AES256-SHA384\n    - ECDHE-ECDSA-AES256-SHA\n    - ECDHE-RSA-AES256-SHA\n    - DHE-RSA-AES128-SHA256\n    - DHE-RSA-AES256-SHA256\n    - AES128-GCM-SHA256\n    - AES256-GCM-SHA384\n    - AES128-SHA256\n    - AES256-SHA256\n    - AES128-SHA\n    - AES256-SHA\n    - DES-CBC3-SHA\n  minTLSVersion: VersionTLS10",
-	"intermediate": "intermediate is a TLS security profile based on:\n\nhttps://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29\n\nand looks like this (yaml):\n\n  ciphers:\n    - TLS_AES_128_GCM_SHA256\n    - TLS_AES_256_GCM_SHA384\n    - TLS_CHACHA20_POLY1305_SHA256\n    - ECDHE-ECDSA-AES128-GCM-SHA256\n    - ECDHE-RSA-AES128-GCM-SHA256\n    - ECDHE-ECDSA-AES256-GCM-SHA384\n    - ECDHE-RSA-AES256-GCM-SHA384\n    - ECDHE-ECDSA-CHACHA20-POLY1305\n    - ECDHE-RSA-CHACHA20-POLY1305\n    - DHE-RSA-AES128-GCM-SHA256\n    - DHE-RSA-AES256-GCM-SHA384\n  minTLSVersion: VersionTLS12",
-	"modern":       "modern is a TLS security profile based on:\n\nhttps://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility\n\nand looks like this (yaml):\n\n  ciphers:\n    - TLS_AES_128_GCM_SHA256\n    - TLS_AES_256_GCM_SHA384\n    - TLS_CHACHA20_POLY1305_SHA256\n  minTLSVersion: VersionTLS13\n\nNOTE: Currently unsupported.",
-	"custom":       "custom is a user-defined TLS security profile. Be extremely careful using a custom profile as invalid configurations can be catastrophic. An example custom profile looks like this:\n\n  ciphers:\n    - ECDHE-ECDSA-CHACHA20-POLY1305\n    - ECDHE-RSA-CHACHA20-POLY1305\n    - ECDHE-RSA-AES128-GCM-SHA256\n    - ECDHE-ECDSA-AES128-GCM-SHA256\n  minTLSVersion: VersionTLS11",
+	"old":          "old is a TLS security profile based on:\n\nhttps://wiki.mozilla.org/Security/Server_Side_TLS#Old_backward_compatibility\n\nand looks like this (yaml):\n\n  ciphers:\n\n    - TLS_AES_128_GCM_SHA256\n\n    - TLS_AES_256_GCM_SHA384\n\n    - TLS_CHACHA20_POLY1305_SHA256\n\n    - ECDHE-ECDSA-AES128-GCM-SHA256\n\n    - ECDHE-RSA-AES128-GCM-SHA256\n\n    - ECDHE-ECDSA-AES256-GCM-SHA384\n\n    - ECDHE-RSA-AES256-GCM-SHA384\n\n    - ECDHE-ECDSA-CHACHA20-POLY1305\n\n    - ECDHE-RSA-CHACHA20-POLY1305\n\n    - DHE-RSA-AES128-GCM-SHA256\n\n    - DHE-RSA-AES256-GCM-SHA384\n\n    - DHE-RSA-CHACHA20-POLY1305\n\n    - ECDHE-ECDSA-AES128-SHA256\n\n    - ECDHE-RSA-AES128-SHA256\n\n    - ECDHE-ECDSA-AES128-SHA\n\n    - ECDHE-RSA-AES128-SHA\n\n    - ECDHE-ECDSA-AES256-SHA384\n\n    - ECDHE-RSA-AES256-SHA384\n\n    - ECDHE-ECDSA-AES256-SHA\n\n    - ECDHE-RSA-AES256-SHA\n\n    - DHE-RSA-AES128-SHA256\n\n    - DHE-RSA-AES256-SHA256\n\n    - AES128-GCM-SHA256\n\n    - AES256-GCM-SHA384\n\n    - AES128-SHA256\n\n    - AES256-SHA256\n\n    - AES128-SHA\n\n    - AES256-SHA\n\n    - DES-CBC3-SHA\n\n  minTLSVersion: VersionTLS10",
+	"intermediate": "intermediate is a TLS security profile based on:\n\nhttps://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29\n\nand looks like this (yaml):\n\n  ciphers:\n\n    - TLS_AES_128_GCM_SHA256\n\n    - TLS_AES_256_GCM_SHA384\n\n    - TLS_CHACHA20_POLY1305_SHA256\n\n    - ECDHE-ECDSA-AES128-GCM-SHA256\n\n    - ECDHE-RSA-AES128-GCM-SHA256\n\n    - ECDHE-ECDSA-AES256-GCM-SHA384\n\n    - ECDHE-RSA-AES256-GCM-SHA384\n\n    - ECDHE-ECDSA-CHACHA20-POLY1305\n\n    - ECDHE-RSA-CHACHA20-POLY1305\n\n    - DHE-RSA-AES128-GCM-SHA256\n\n    - DHE-RSA-AES256-GCM-SHA384\n\n  minTLSVersion: VersionTLS12",
+	"modern":       "modern is a TLS security profile based on:\n\nhttps://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility\n\nand looks like this (yaml):\n\n  ciphers:\n\n    - TLS_AES_128_GCM_SHA256\n\n    - TLS_AES_256_GCM_SHA384\n\n    - TLS_CHACHA20_POLY1305_SHA256\n\n  minTLSVersion: VersionTLS13",
+	"custom":       "custom is a user-defined TLS security profile. Be extremely careful using a custom profile as invalid configurations can be catastrophic. An example custom profile looks like this:\n\n  ciphers:\n\n    - ECDHE-ECDSA-CHACHA20-POLY1305\n\n    - ECDHE-RSA-CHACHA20-POLY1305\n\n    - ECDHE-RSA-AES128-GCM-SHA256\n\n    - ECDHE-ECDSA-AES128-GCM-SHA256\n\n  minTLSVersion: VersionTLS11",
 }
 
 func (TLSSecurityProfile) SwaggerDoc() map[string]string {
diff --git a/vendor/github.com/openshift/api/console/v1alpha1/90_consoleplugin.crd.yaml b/vendor/github.com/openshift/api/console/v1alpha1/90_consoleplugin.crd.yaml
deleted file mode 100644
index f2cb187c..00000000
--- a/vendor/github.com/openshift/api/console/v1alpha1/90_consoleplugin.crd.yaml
+++ /dev/null
@@ -1,374 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/764
-    capability.openshift.io/name: Console
-    description: Extension for configuring openshift web console plugins.
-    displayName: ConsolePlugin
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-    service.beta.openshift.io/inject-cabundle: "true"
-  name: consoleplugins.console.openshift.io
-spec:
-  conversion:
-    strategy: Webhook
-    webhook:
-      clientConfig:
-        service:
-          name: webhook
-          namespace: openshift-console-operator
-          path: /crdconvert
-          port: 9443
-      conversionReviewVersions:
-      - v1
-      - v1alpha1
-  group: console.openshift.io
-  names:
-    kind: ConsolePlugin
-    listKind: ConsolePluginList
-    plural: consoleplugins
-    singular: consoleplugin
-  scope: Cluster
-  versions:
-  - name: v1
-    schema:
-      openAPIV3Schema:
-        description: "ConsolePlugin is an extension for customizing OpenShift web
-          console by dynamically loading code from another service running on the
-          cluster. \n Compatibility level 1: Stable within a major release for a minimum
-          of 12 months or 3 minor releases (whichever is longer)."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: ConsolePluginSpec is the desired plugin configuration.
-            properties:
-              backend:
-                description: backend holds the configuration of backend which is serving
-                  console's plugin .
-                properties:
-                  service:
-                    description: service is a Kubernetes Service that exposes the
-                      plugin using a deployment with an HTTP server. The Service must
-                      use HTTPS and Service serving certificate. The console backend
-                      will proxy the plugins assets from the Service using the service
-                      CA bundle.
-                    properties:
-                      basePath:
-                        default: /
-                        description: basePath is the path to the plugin's assets.
-                          The primary asset it the manifest file called `plugin-manifest.json`,
-                          which is a JSON document that contains metadata about the
-                          plugin and the extensions.
-                        maxLength: 256
-                        minLength: 1
-                        pattern: ^[a-zA-Z0-9.\-_~!$&'()*+,;=:@\/]*$
-                        type: string
-                      name:
-                        description: name of Service that is serving the plugin assets.
-                        maxLength: 128
-                        minLength: 1
-                        type: string
-                      namespace:
-                        description: namespace of Service that is serving the plugin
-                          assets.
-                        maxLength: 128
-                        minLength: 1
-                        type: string
-                      port:
-                        description: port on which the Service that is serving the
-                          plugin is listening to.
-                        format: int32
-                        maximum: 65535
-                        minimum: 1
-                        type: integer
-                    required:
-                    - name
-                    - namespace
-                    - port
-                    type: object
-                  type:
-                    description: "type is the backend type which servers the console's
-                      plugin. Currently only \"Service\" is supported. \n ---"
-                    enum:
-                    - Service
-                    type: string
-                required:
-                - type
-                type: object
-              displayName:
-                description: displayName is the display name of the plugin. The dispalyName
-                  should be between 1 and 128 characters.
-                maxLength: 128
-                minLength: 1
-                type: string
-              i18n:
-                description: i18n is the configuration of plugin's localization resources.
-                properties:
-                  loadType:
-                    description: loadType indicates how the plugin's localization
-                      resource should be loaded. Valid values are Preload, Lazy and
-                      the empty string. When set to Preload, all localization resources
-                      are fetched when the plugin is loaded. When set to Lazy, localization
-                      resources are lazily loaded as and when they are required by
-                      the console. When omitted or set to the empty string, the behaviour
-                      is equivalent to Lazy type.
-                    enum:
-                    - Preload
-                    - Lazy
-                    - ""
-                    type: string
-                required:
-                - loadType
-                type: object
-              proxy:
-                description: proxy is a list of proxies that describe various service
-                  type to which the plugin needs to connect to.
-                items:
-                  description: ConsolePluginProxy holds information on various service
-                    types to which console's backend will proxy the plugin's requests.
-                  properties:
-                    alias:
-                      description: "alias is a proxy name that identifies the plugin's
-                        proxy. An alias name should be unique per plugin. The console
-                        backend exposes following proxy endpoint: \n /api/proxy/plugin/<plugin-name>/<proxy-alias>/<request-path>?<optional-query-parameters>
-                        \n Request example path: \n /api/proxy/plugin/acm/search/pods?namespace=openshift-apiserver"
-                      maxLength: 128
-                      minLength: 1
-                      pattern: ^[A-Za-z0-9-_]+$
-                      type: string
-                    authorization:
-                      default: None
-                      description: authorization provides information about authorization
-                        type, which the proxied request should contain
-                      enum:
-                      - UserToken
-                      - None
-                      type: string
-                    caCertificate:
-                      description: caCertificate provides the cert authority certificate
-                        contents, in case the proxied Service is using custom service
-                        CA. By default, the service CA bundle provided by the service-ca
-                        operator is used.
-                      pattern: ^-----BEGIN CERTIFICATE-----([\s\S]*)-----END CERTIFICATE-----\s?$
-                      type: string
-                    endpoint:
-                      description: endpoint provides information about endpoint to
-                        which the request is proxied to.
-                      properties:
-                        service:
-                          description: 'service is an in-cluster Service that the
-                            plugin will connect to. The Service must use HTTPS. The
-                            console backend exposes an endpoint in order to proxy
-                            communication between the plugin and the Service. Note:
-                            service field is required for now, since currently only
-                            "Service" type is supported.'
-                          properties:
-                            name:
-                              description: name of Service that the plugin needs to
-                                connect to.
-                              maxLength: 128
-                              minLength: 1
-                              type: string
-                            namespace:
-                              description: namespace of Service that the plugin needs
-                                to connect to
-                              maxLength: 128
-                              minLength: 1
-                              type: string
-                            port:
-                              description: port on which the Service that the plugin
-                                needs to connect to is listening on.
-                              format: int32
-                              maximum: 65535
-                              minimum: 1
-                              type: integer
-                          required:
-                          - name
-                          - namespace
-                          - port
-                          type: object
-                        type:
-                          description: "type is the type of the console plugin's proxy.
-                            Currently only \"Service\" is supported. \n ---"
-                          enum:
-                          - Service
-                          type: string
-                      required:
-                      - type
-                      type: object
-                  required:
-                  - alias
-                  - endpoint
-                  type: object
-                type: array
-            required:
-            - backend
-            - displayName
-            type: object
-        required:
-        - metadata
-        - spec
-        type: object
-    served: true
-    storage: true
-  - name: v1alpha1
-    schema:
-      openAPIV3Schema:
-        description: "ConsolePlugin is an extension for customizing OpenShift web
-          console by dynamically loading code from another service running on the
-          cluster. \n Compatibility level 4: No compatibility is provided, the API
-          can change at any point for any reason. These capabilities should not be
-          used by applications needing long term support."
-        properties:
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          spec:
-            description: ConsolePluginSpec is the desired plugin configuration.
-            properties:
-              displayName:
-                description: displayName is the display name of the plugin.
-                minLength: 1
-                type: string
-              proxy:
-                description: proxy is a list of proxies that describe various service
-                  type to which the plugin needs to connect to.
-                items:
-                  description: ConsolePluginProxy holds information on various service
-                    types to which console's backend will proxy the plugin's requests.
-                  properties:
-                    alias:
-                      description: "alias is a proxy name that identifies the plugin's
-                        proxy. An alias name should be unique per plugin. The console
-                        backend exposes following proxy endpoint: \n /api/proxy/plugin/<plugin-name>/<proxy-alias>/<request-path>?<optional-query-parameters>
-                        \n Request example path: \n /api/proxy/plugin/acm/search/pods?namespace=openshift-apiserver"
-                      maxLength: 128
-                      minLength: 1
-                      pattern: ^[A-Za-z0-9-_]+$
-                      type: string
-                    authorize:
-                      default: false
-                      description: "authorize indicates if the proxied request should
-                        contain the logged-in user's OpenShift access token in the
-                        \"Authorization\" request header. For example: \n Authorization:
-                        Bearer sha256~kV46hPnEYhCWFnB85r5NrprAxggzgb6GOeLbgcKNsH0
-                        \n By default the access token is not part of the proxied
-                        request."
-                      type: boolean
-                    caCertificate:
-                      description: caCertificate provides the cert authority certificate
-                        contents, in case the proxied Service is using custom service
-                        CA. By default, the service CA bundle provided by the service-ca
-                        operator is used.
-                      pattern: ^-----BEGIN CERTIFICATE-----([\s\S]*)-----END CERTIFICATE-----\s?$
-                      type: string
-                    service:
-                      description: 'service is an in-cluster Service that the plugin
-                        will connect to. The Service must use HTTPS. The console backend
-                        exposes an endpoint in order to proxy communication between
-                        the plugin and the Service. Note: service field is required
-                        for now, since currently only "Service" type is supported.'
-                      properties:
-                        name:
-                          description: name of Service that the plugin needs to connect
-                            to.
-                          maxLength: 128
-                          minLength: 1
-                          type: string
-                        namespace:
-                          description: namespace of Service that the plugin needs
-                            to connect to
-                          maxLength: 128
-                          minLength: 1
-                          type: string
-                        port:
-                          description: port on which the Service that the plugin needs
-                            to connect to is listening on.
-                          format: int32
-                          maximum: 65535
-                          minimum: 1
-                          type: integer
-                      required:
-                      - name
-                      - namespace
-                      - port
-                      type: object
-                    type:
-                      description: type is the type of the console plugin's proxy.
-                        Currently only "Service" is supported.
-                      pattern: ^(Service)$
-                      type: string
-                  required:
-                  - alias
-                  - type
-                  type: object
-                type: array
-              service:
-                description: service is a Kubernetes Service that exposes the plugin
-                  using a deployment with an HTTP server. The Service must use HTTPS
-                  and Service serving certificate. The console backend will proxy
-                  the plugins assets from the Service using the service CA bundle.
-                properties:
-                  basePath:
-                    default: /
-                    description: basePath is the path to the plugin's assets. The
-                      primary asset it the manifest file called `plugin-manifest.json`,
-                      which is a JSON document that contains metadata about the plugin
-                      and the extensions.
-                    minLength: 1
-                    pattern: ^/
-                    type: string
-                  name:
-                    description: name of Service that is serving the plugin assets.
-                    maxLength: 128
-                    minLength: 1
-                    type: string
-                  namespace:
-                    description: namespace of Service that is serving the plugin assets.
-                    maxLength: 128
-                    minLength: 1
-                    type: string
-                  port:
-                    description: port on which the Service that is serving the plugin
-                      is listening to.
-                    format: int32
-                    maximum: 65535
-                    minimum: 1
-                    type: integer
-                required:
-                - basePath
-                - name
-                - namespace
-                - port
-                type: object
-            required:
-            - service
-            type: object
-        required:
-        - metadata
-        - spec
-        type: object
-    served: true
-    storage: false
diff --git a/vendor/github.com/openshift/api/console/v1alpha1/stable.consoleplugin.testsuite.yaml b/vendor/github.com/openshift/api/console/v1alpha1/stable.consoleplugin.testsuite.yaml
index d861a654..3a427825 100644
--- a/vendor/github.com/openshift/api/console/v1alpha1/stable.consoleplugin.testsuite.yaml
+++ b/vendor/github.com/openshift/api/console/v1alpha1/stable.consoleplugin.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] ConsolePlugin"
-crd: 90_consoleplugin.crd.yaml
+crd: 90_consoleplugins.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal ConsolePlugin
diff --git a/vendor/github.com/openshift/api/console/v1alpha1/types_console_plugin.go b/vendor/github.com/openshift/api/console/v1alpha1/types_console_plugin.go
index 835e2001..3533b639 100644
--- a/vendor/github.com/openshift/api/console/v1alpha1/types_console_plugin.go
+++ b/vendor/github.com/openshift/api/console/v1alpha1/types_console_plugin.go
@@ -11,6 +11,14 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 // dynamically loading code from another service running on the cluster.
 //
 // Compatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=consoleplugins,scope=Cluster
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/764
+// +openshift:file-pattern=operatorOrdering=90
+// +openshift:capability=Console
+// +kubebuilder:metadata:annotations="description=Extension for configuring openshift web console plugins."
+// +kubebuilder:metadata:annotations="displayName=ConsolePlugin"
+// +kubebuilder:metadata:annotations="service.beta.openshift.io/inject-cabundle=true"
 type ConsolePlugin struct {
 	metav1.TypeMeta `json:",inline"`
 
diff --git a/vendor/github.com/openshift/api/console/v1alpha1/zz_generated.featuregated-crd-manifests.yaml b/vendor/github.com/openshift/api/console/v1alpha1/zz_generated.featuregated-crd-manifests.yaml
new file mode 100644
index 00000000..d219598d
--- /dev/null
+++ b/vendor/github.com/openshift/api/console/v1alpha1/zz_generated.featuregated-crd-manifests.yaml
@@ -0,0 +1,24 @@
+consoleplugins.console.openshift.io:
+  Annotations:
+    description: Extension for configuring openshift web console plugins.
+    displayName: ConsolePlugin
+    service.beta.openshift.io/inject-cabundle: "true"
+  ApprovedPRNumber: https://github.com/openshift/api/pull/764
+  CRDName: consoleplugins.console.openshift.io
+  Capability: Console
+  Category: ""
+  FeatureGates: []
+  FilenameOperatorName: ""
+  FilenameOperatorOrdering: "90"
+  FilenameRunLevel: ""
+  GroupName: console.openshift.io
+  HasStatus: false
+  KindName: ConsolePlugin
+  Labels: {}
+  PluralName: consoleplugins
+  PrinterColumns: []
+  Scope: Cluster
+  ShortNames: null
+  TopLevelFeatureGates: []
+  Version: v1alpha1
+
diff --git a/vendor/github.com/openshift/api/security/v1/0000_03_security-openshift_01_scc.crd.yaml b/vendor/github.com/openshift/api/security/v1/0000_03_security-openshift_01_scc.crd.yaml
deleted file mode 100644
index a533efbc..00000000
--- a/vendor/github.com/openshift/api/security/v1/0000_03_security-openshift_01_scc.crd.yaml
+++ /dev/null
@@ -1,365 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
-  annotations:
-    api-approved.openshift.io: https://github.com/openshift/api/pull/470
-    include.release.openshift.io/ibm-cloud-managed: "true"
-    include.release.openshift.io/self-managed-high-availability: "true"
-    include.release.openshift.io/single-node-developer: "true"
-  name: securitycontextconstraints.security.openshift.io
-spec:
-  group: security.openshift.io
-  names:
-    kind: SecurityContextConstraints
-    listKind: SecurityContextConstraintsList
-    plural: securitycontextconstraints
-    singular: securitycontextconstraints
-  scope: Cluster
-  versions:
-  - additionalPrinterColumns:
-    - description: Determines if a container can request to be run as privileged
-      jsonPath: .allowPrivilegedContainer
-      name: Priv
-      type: string
-    - description: A list of capabilities that can be requested to add to the container
-      jsonPath: .allowedCapabilities
-      name: Caps
-      type: string
-    - description: Strategy that will dictate what labels will be set in the SecurityContext
-      jsonPath: .seLinuxContext.type
-      name: SELinux
-      type: string
-    - description: Strategy that will dictate what RunAsUser is used in the SecurityContext
-      jsonPath: .runAsUser.type
-      name: RunAsUser
-      type: string
-    - description: Strategy that will dictate what fs group is used by the SecurityContext
-      jsonPath: .fsGroup.type
-      name: FSGroup
-      type: string
-    - description: Strategy that will dictate what supplemental groups are used by
-        the SecurityContext
-      jsonPath: .supplementalGroups.type
-      name: SupGroup
-      type: string
-    - description: Sort order of SCCs
-      jsonPath: .priority
-      name: Priority
-      type: string
-    - description: Force containers to run with a read only root file system
-      jsonPath: .readOnlyRootFilesystem
-      name: ReadOnlyRootFS
-      type: string
-    - description: White list of allowed volume plugins
-      jsonPath: .volumes
-      name: Volumes
-      type: string
-    name: v1
-    schema:
-      openAPIV3Schema:
-        description: "SecurityContextConstraints governs the ability to make requests
-          that affect the SecurityContext that will be applied to a container. For
-          historical reasons SCC was exposed under the core Kubernetes API group.
-          That exposure is deprecated and will be removed in a future release - users
-          should instead use the security.openshift.io group to manage SecurityContextConstraints.
-          \n Compatibility level 1: Stable within a major release for a minimum of
-          12 months or 3 minor releases (whichever is longer)."
-        properties:
-          allowHostDirVolumePlugin:
-            description: AllowHostDirVolumePlugin determines if the policy allow containers
-              to use the HostDir volume plugin
-            type: boolean
-          allowHostIPC:
-            description: AllowHostIPC determines if the policy allows host ipc in
-              the containers.
-            type: boolean
-          allowHostNetwork:
-            description: AllowHostNetwork determines if the policy allows the use
-              of HostNetwork in the pod spec.
-            type: boolean
-          allowHostPID:
-            description: AllowHostPID determines if the policy allows host pid in
-              the containers.
-            type: boolean
-          allowHostPorts:
-            description: AllowHostPorts determines if the policy allows host ports
-              in the containers.
-            type: boolean
-          allowPrivilegeEscalation:
-            description: AllowPrivilegeEscalation determines if a pod can request
-              to allow privilege escalation. If unspecified, defaults to true.
-            nullable: true
-            type: boolean
-          allowPrivilegedContainer:
-            description: AllowPrivilegedContainer determines if a container can request
-              to be run as privileged.
-            type: boolean
-          allowedCapabilities:
-            description: AllowedCapabilities is a list of capabilities that can be
-              requested to add to the container. Capabilities in this field maybe
-              added at the pod author's discretion. You must not list a capability
-              in both AllowedCapabilities and RequiredDropCapabilities. To allow all
-              capabilities you may use '*'.
-            items:
-              description: Capability represent POSIX capabilities type
-              type: string
-            nullable: true
-            type: array
-          allowedFlexVolumes:
-            description: AllowedFlexVolumes is a whitelist of allowed Flexvolumes.  Empty
-              or nil indicates that all Flexvolumes may be used.  This parameter is
-              effective only when the usage of the Flexvolumes is allowed in the "Volumes"
-              field.
-            items:
-              description: AllowedFlexVolume represents a single Flexvolume that is
-                allowed to be used.
-              properties:
-                driver:
-                  description: Driver is the name of the Flexvolume driver.
-                  type: string
-              required:
-              - driver
-              type: object
-            nullable: true
-            type: array
-          allowedUnsafeSysctls:
-            description: "AllowedUnsafeSysctls is a list of explicitly allowed unsafe
-              sysctls, defaults to none. Each entry is either a plain sysctl name
-              or ends in \"*\" in which case it is considered as a prefix of allowed
-              sysctls. Single * means all unsafe sysctls are allowed. Kubelet has
-              to whitelist all allowed unsafe sysctls explicitly to avoid rejection.
-              \n Examples: e.g. \"foo/*\" allows \"foo/bar\", \"foo/baz\", etc. e.g.
-              \"foo.*\" allows \"foo.bar\", \"foo.baz\", etc."
-            items:
-              type: string
-            nullable: true
-            type: array
-          apiVersion:
-            description: 'APIVersion defines the versioned schema of this representation
-              of an object. Servers should convert recognized schemas to the latest
-              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
-            type: string
-          defaultAddCapabilities:
-            description: DefaultAddCapabilities is the default set of capabilities
-              that will be added to the container unless the pod spec specifically
-              drops the capability.  You may not list a capabiility in both DefaultAddCapabilities
-              and RequiredDropCapabilities.
-            items:
-              description: Capability represent POSIX capabilities type
-              type: string
-            nullable: true
-            type: array
-          defaultAllowPrivilegeEscalation:
-            description: DefaultAllowPrivilegeEscalation controls the default setting
-              for whether a process can gain more privileges than its parent process.
-            nullable: true
-            type: boolean
-          forbiddenSysctls:
-            description: "ForbiddenSysctls is a list of explicitly forbidden sysctls,
-              defaults to none. Each entry is either a plain sysctl name or ends in
-              \"*\" in which case it is considered as a prefix of forbidden sysctls.
-              Single * means all sysctls are forbidden. \n Examples: e.g. \"foo/*\"
-              forbids \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" forbids \"foo.bar\",
-              \"foo.baz\", etc."
-            items:
-              type: string
-            nullable: true
-            type: array
-          fsGroup:
-            description: FSGroup is the strategy that will dictate what fs group is
-              used by the SecurityContext.
-            nullable: true
-            properties:
-              ranges:
-                description: Ranges are the allowed ranges of fs groups.  If you would
-                  like to force a single fs group then supply a single range with
-                  the same start and end.
-                items:
-                  description: 'IDRange provides a min/max of an allowed range of
-                    IDs. TODO: this could be reused for UIDs.'
-                  properties:
-                    max:
-                      description: Max is the end of the range, inclusive.
-                      format: int64
-                      type: integer
-                    min:
-                      description: Min is the start of the range, inclusive.
-                      format: int64
-                      type: integer
-                  type: object
-                type: array
-              type:
-                description: Type is the strategy that will dictate what FSGroup is
-                  used in the SecurityContext.
-                type: string
-            type: object
-          groups:
-            description: The groups that have permission to use this security context
-              constraints
-            items:
-              type: string
-            nullable: true
-            type: array
-          kind:
-            description: 'Kind is a string value representing the REST resource this
-              object represents. Servers may infer this from the endpoint the client
-              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
-            type: string
-          metadata:
-            type: object
-          priority:
-            description: Priority influences the sort order of SCCs when evaluating
-              which SCCs to try first for a given pod request based on access in the
-              Users and Groups fields.  The higher the int, the higher priority. An
-              unset value is considered a 0 priority. If scores for multiple SCCs
-              are equal they will be sorted from most restrictive to least restrictive.
-              If both priorities and restrictions are equal the SCCs will be sorted
-              by name.
-            format: int32
-            nullable: true
-            type: integer
-          readOnlyRootFilesystem:
-            description: ReadOnlyRootFilesystem when set to true will force containers
-              to run with a read only root file system.  If the container specifically
-              requests to run with a non-read only root file system the SCC should
-              deny the pod. If set to false the container may run with a read only
-              root file system if it wishes but it will not be forced to.
-            type: boolean
-          requiredDropCapabilities:
-            description: RequiredDropCapabilities are the capabilities that will be
-              dropped from the container.  These are required to be dropped and cannot
-              be added.
-            items:
-              description: Capability represent POSIX capabilities type
-              type: string
-            nullable: true
-            type: array
-          runAsUser:
-            description: RunAsUser is the strategy that will dictate what RunAsUser
-              is used in the SecurityContext.
-            nullable: true
-            properties:
-              type:
-                description: Type is the strategy that will dictate what RunAsUser
-                  is used in the SecurityContext.
-                type: string
-              uid:
-                description: UID is the user id that containers must run as.  Required
-                  for the MustRunAs strategy if not using namespace/service account
-                  allocated uids.
-                format: int64
-                type: integer
-              uidRangeMax:
-                description: UIDRangeMax defines the max value for a strategy that
-                  allocates by range.
-                format: int64
-                type: integer
-              uidRangeMin:
-                description: UIDRangeMin defines the min value for a strategy that
-                  allocates by range.
-                format: int64
-                type: integer
-            type: object
-          seLinuxContext:
-            description: SELinuxContext is the strategy that will dictate what labels
-              will be set in the SecurityContext.
-            nullable: true
-            properties:
-              seLinuxOptions:
-                description: seLinuxOptions required to run as; required for MustRunAs
-                properties:
-                  level:
-                    description: Level is SELinux level label that applies to the
-                      container.
-                    type: string
-                  role:
-                    description: Role is a SELinux role label that applies to the
-                      container.
-                    type: string
-                  type:
-                    description: Type is a SELinux type label that applies to the
-                      container.
-                    type: string
-                  user:
-                    description: User is a SELinux user label that applies to the
-                      container.
-                    type: string
-                type: object
-              type:
-                description: Type is the strategy that will dictate what SELinux context
-                  is used in the SecurityContext.
-                type: string
-            type: object
-          seccompProfiles:
-            description: "SeccompProfiles lists the allowed profiles that may be set
-              for the pod or container's seccomp annotations.  An unset (nil) or empty
-              value means that no profiles may be specifid by the pod or container.\tThe
-              wildcard '*' may be used to allow all profiles.  When used to generate
-              a value for a pod the first non-wildcard profile will be used as the
-              default."
-            items:
-              type: string
-            nullable: true
-            type: array
-          supplementalGroups:
-            description: SupplementalGroups is the strategy that will dictate what
-              supplemental groups are used by the SecurityContext.
-            nullable: true
-            properties:
-              ranges:
-                description: Ranges are the allowed ranges of supplemental groups.  If
-                  you would like to force a single supplemental group then supply
-                  a single range with the same start and end.
-                items:
-                  description: 'IDRange provides a min/max of an allowed range of
-                    IDs. TODO: this could be reused for UIDs.'
-                  properties:
-                    max:
-                      description: Max is the end of the range, inclusive.
-                      format: int64
-                      type: integer
-                    min:
-                      description: Min is the start of the range, inclusive.
-                      format: int64
-                      type: integer
-                  type: object
-                type: array
-              type:
-                description: Type is the strategy that will dictate what supplemental
-                  groups is used in the SecurityContext.
-                type: string
-            type: object
-          users:
-            description: The users who have permissions to use this security context
-              constraints
-            items:
-              type: string
-            nullable: true
-            type: array
-          volumes:
-            description: Volumes is a white list of allowed volume plugins.  FSType
-              corresponds directly with the field names of a VolumeSource (azureFile,
-              configMap, emptyDir).  To allow all volumes you may use "*". To allow
-              no volumes, set to ["none"].
-            items:
-              description: FS Type gives strong typing to different file systems that
-                are used by volumes.
-              type: string
-            nullable: true
-            type: array
-        required:
-        - allowHostDirVolumePlugin
-        - allowHostIPC
-        - allowHostNetwork
-        - allowHostPID
-        - allowHostPorts
-        - allowPrivilegedContainer
-        - allowedCapabilities
-        - defaultAddCapabilities
-        - priority
-        - readOnlyRootFilesystem
-        - requiredDropCapabilities
-        - volumes
-        type: object
-    served: true
-    storage: true
diff --git a/vendor/github.com/openshift/api/security/v1/generated.proto b/vendor/github.com/openshift/api/security/v1/generated.proto
index d842079a..c6d60915 100644
--- a/vendor/github.com/openshift/api/security/v1/generated.proto
+++ b/vendor/github.com/openshift/api/security/v1/generated.proto
@@ -195,15 +195,19 @@ message SELinuxContextStrategyOptions {
 // SecurityContextConstraints.
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
-// +kubebuilder:printcolumn:name="Priv",type=string,JSONPath=`.allowPrivilegedContainer`,description="Determines if a container can request to be run as privileged"
-// +kubebuilder:printcolumn:name="Caps",type=string,JSONPath=`.allowedCapabilities`,description="A list of capabilities that can be requested to add to the container"
-// +kubebuilder:printcolumn:name="SELinux",type=string,JSONPath=`.seLinuxContext.type`,description="Strategy that will dictate what labels will be set in the SecurityContext"
-// +kubebuilder:printcolumn:name="RunAsUser",type=string,JSONPath=`.runAsUser.type`,description="Strategy that will dictate what RunAsUser is used in the SecurityContext"
-// +kubebuilder:printcolumn:name="FSGroup",type=string,JSONPath=`.fsGroup.type`,description="Strategy that will dictate what fs group is used by the SecurityContext"
-// +kubebuilder:printcolumn:name="SupGroup",type=string,JSONPath=`.supplementalGroups.type`,description="Strategy that will dictate what supplemental groups are used by the SecurityContext"
-// +kubebuilder:printcolumn:name="Priority",type=string,JSONPath=`.priority`,description="Sort order of SCCs"
-// +kubebuilder:printcolumn:name="ReadOnlyRootFS",type=string,JSONPath=`.readOnlyRootFilesystem`,description="Force containers to run with a read only root file system"
-// +kubebuilder:printcolumn:name="Volumes",type=string,JSONPath=`.volumes`,description="White list of allowed volume plugins"
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=securitycontextconstraints,scope=Cluster
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/470
+// +openshift:file-pattern=cvoRunLevel=0000_03,operatorName=config-operator,operatorOrdering=01
+// +kubebuilder:printcolumn:name="Priv",type=string,JSONPath=.allowPrivilegedContainer,description="Determines if a container can request to be run as privileged"
+// +kubebuilder:printcolumn:name="Caps",type=string,JSONPath=.allowedCapabilities,description="A list of capabilities that can be requested to add to the container"
+// +kubebuilder:printcolumn:name="SELinux",type=string,JSONPath=.seLinuxContext.type,description="Strategy that will dictate what labels will be set in the SecurityContext"
+// +kubebuilder:printcolumn:name="RunAsUser",type=string,JSONPath=.runAsUser.type,description="Strategy that will dictate what RunAsUser is used in the SecurityContext"
+// +kubebuilder:printcolumn:name="FSGroup",type=string,JSONPath=.fsGroup.type,description="Strategy that will dictate what fs group is used by the SecurityContext"
+// +kubebuilder:printcolumn:name="SupGroup",type=string,JSONPath=.supplementalGroups.type,description="Strategy that will dictate what supplemental groups are used by the SecurityContext"
+// +kubebuilder:printcolumn:name="Priority",type=string,JSONPath=.priority,description="Sort order of SCCs"
+// +kubebuilder:printcolumn:name="ReadOnlyRootFS",type=string,JSONPath=.readOnlyRootFilesystem,description="Force containers to run with a read only root file system"
+// +kubebuilder:printcolumn:name="Volumes",type=string,JSONPath=.volumes,description="White list of allowed volume plugins"
 // +kubebuilder:singular=securitycontextconstraint
 // +openshift:compatibility-gen:level=1
 message SecurityContextConstraints {
diff --git a/vendor/github.com/openshift/api/security/v1/stable.securitycontextconstraints.testsuite.yaml b/vendor/github.com/openshift/api/security/v1/stable.securitycontextconstraints.testsuite.yaml
index d663b94c..89a565d5 100644
--- a/vendor/github.com/openshift/api/security/v1/stable.securitycontextconstraints.testsuite.yaml
+++ b/vendor/github.com/openshift/api/security/v1/stable.securitycontextconstraints.testsuite.yaml
@@ -1,6 +1,6 @@
 apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
 name: "[Stable] SecurityContextConstraints"
-crd: 0000_03_security-openshift_01_scc.crd.yaml
+crd: 0000_03_config-operator_01_securitycontextconstraints.crd.yaml
 tests:
   onCreate:
   - name: Should be able to create a minimal SecurityContextConstraints
diff --git a/vendor/github.com/openshift/api/security/v1/types.go b/vendor/github.com/openshift/api/security/v1/types.go
index 3e208210..b57da305 100644
--- a/vendor/github.com/openshift/api/security/v1/types.go
+++ b/vendor/github.com/openshift/api/security/v1/types.go
@@ -22,15 +22,19 @@ var AllowAllCapabilities corev1.Capability = "*"
 // SecurityContextConstraints.
 //
 // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
-// +kubebuilder:printcolumn:name="Priv",type=string,JSONPath=`.allowPrivilegedContainer`,description="Determines if a container can request to be run as privileged"
-// +kubebuilder:printcolumn:name="Caps",type=string,JSONPath=`.allowedCapabilities`,description="A list of capabilities that can be requested to add to the container"
-// +kubebuilder:printcolumn:name="SELinux",type=string,JSONPath=`.seLinuxContext.type`,description="Strategy that will dictate what labels will be set in the SecurityContext"
-// +kubebuilder:printcolumn:name="RunAsUser",type=string,JSONPath=`.runAsUser.type`,description="Strategy that will dictate what RunAsUser is used in the SecurityContext"
-// +kubebuilder:printcolumn:name="FSGroup",type=string,JSONPath=`.fsGroup.type`,description="Strategy that will dictate what fs group is used by the SecurityContext"
-// +kubebuilder:printcolumn:name="SupGroup",type=string,JSONPath=`.supplementalGroups.type`,description="Strategy that will dictate what supplemental groups are used by the SecurityContext"
-// +kubebuilder:printcolumn:name="Priority",type=string,JSONPath=`.priority`,description="Sort order of SCCs"
-// +kubebuilder:printcolumn:name="ReadOnlyRootFS",type=string,JSONPath=`.readOnlyRootFilesystem`,description="Force containers to run with a read only root file system"
-// +kubebuilder:printcolumn:name="Volumes",type=string,JSONPath=`.volumes`,description="White list of allowed volume plugins"
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:path=securitycontextconstraints,scope=Cluster
+// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/470
+// +openshift:file-pattern=cvoRunLevel=0000_03,operatorName=config-operator,operatorOrdering=01
+// +kubebuilder:printcolumn:name="Priv",type=string,JSONPath=.allowPrivilegedContainer,description="Determines if a container can request to be run as privileged"
+// +kubebuilder:printcolumn:name="Caps",type=string,JSONPath=.allowedCapabilities,description="A list of capabilities that can be requested to add to the container"
+// +kubebuilder:printcolumn:name="SELinux",type=string,JSONPath=.seLinuxContext.type,description="Strategy that will dictate what labels will be set in the SecurityContext"
+// +kubebuilder:printcolumn:name="RunAsUser",type=string,JSONPath=.runAsUser.type,description="Strategy that will dictate what RunAsUser is used in the SecurityContext"
+// +kubebuilder:printcolumn:name="FSGroup",type=string,JSONPath=.fsGroup.type,description="Strategy that will dictate what fs group is used by the SecurityContext"
+// +kubebuilder:printcolumn:name="SupGroup",type=string,JSONPath=.supplementalGroups.type,description="Strategy that will dictate what supplemental groups are used by the SecurityContext"
+// +kubebuilder:printcolumn:name="Priority",type=string,JSONPath=.priority,description="Sort order of SCCs"
+// +kubebuilder:printcolumn:name="ReadOnlyRootFS",type=string,JSONPath=.readOnlyRootFilesystem,description="Force containers to run with a read only root file system"
+// +kubebuilder:printcolumn:name="Volumes",type=string,JSONPath=.volumes,description="White list of allowed volume plugins"
 // +kubebuilder:singular=securitycontextconstraint
 // +openshift:compatibility-gen:level=1
 type SecurityContextConstraints struct {
diff --git a/vendor/github.com/openshift/api/security/v1/zz_generated.featuregated-crd-manifests.yaml b/vendor/github.com/openshift/api/security/v1/zz_generated.featuregated-crd-manifests.yaml
new file mode 100644
index 00000000..ea3967ab
--- /dev/null
+++ b/vendor/github.com/openshift/api/security/v1/zz_generated.featuregated-crd-manifests.yaml
@@ -0,0 +1,58 @@
+securitycontextconstraints.security.openshift.io:
+  Annotations: {}
+  ApprovedPRNumber: https://github.com/openshift/api/pull/470
+  CRDName: securitycontextconstraints.security.openshift.io
+  Capability: ""
+  Category: ""
+  FeatureGates: []
+  FilenameOperatorName: config-operator
+  FilenameOperatorOrdering: "01"
+  FilenameRunLevel: "0000_03"
+  GroupName: security.openshift.io
+  HasStatus: false
+  KindName: SecurityContextConstraints
+  Labels: {}
+  PluralName: securitycontextconstraints
+  PrinterColumns:
+  - description: Determines if a container can request to be run as privileged
+    jsonPath: .allowPrivilegedContainer
+    name: Priv
+    type: string
+  - description: A list of capabilities that can be requested to add to the container
+    jsonPath: .allowedCapabilities
+    name: Caps
+    type: string
+  - description: Strategy that will dictate what labels will be set in the SecurityContext
+    jsonPath: .seLinuxContext.type
+    name: SELinux
+    type: string
+  - description: Strategy that will dictate what RunAsUser is used in the SecurityContext
+    jsonPath: .runAsUser.type
+    name: RunAsUser
+    type: string
+  - description: Strategy that will dictate what fs group is used by the SecurityContext
+    jsonPath: .fsGroup.type
+    name: FSGroup
+    type: string
+  - description: Strategy that will dictate what supplemental groups are used by the
+      SecurityContext
+    jsonPath: .supplementalGroups.type
+    name: SupGroup
+    type: string
+  - description: Sort order of SCCs
+    jsonPath: .priority
+    name: Priority
+    type: string
+  - description: Force containers to run with a read only root file system
+    jsonPath: .readOnlyRootFilesystem
+    name: ReadOnlyRootFS
+    type: string
+  - description: White list of allowed volume plugins
+    jsonPath: .volumes
+    name: Volumes
+    type: string
+  Scope: Cluster
+  ShortNames: null
+  TopLevelFeatureGates: []
+  Version: v1
+
diff --git a/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/subscription_types.go b/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/subscription_types.go
index 67248926..292fedf9 100644
--- a/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/subscription_types.go
+++ b/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/subscription_types.go
@@ -90,6 +90,13 @@ type SubscriptionConfig struct {
 	// Use empty object ({}) to erase original sub-attribute values.
 	// +optional
 	Affinity *corev1.Affinity `json:"affinity,omitempty" protobuf:"bytes,18,opt,name=affinity"`
+
+	// Annotations is an unstructured key value map stored with each Deployment, Pod, APIService in the Operator.
+	// Typically, annotations may be set by external tools to store and retrieve arbitrary metadata.
+	// Use this field to pre-define annotations that OLM should add to each of the Subscription's
+	// deployments, pods, and apiservices.
+	// +optional
+	Annotations map[string]string `json:"annotations,omitempty" protobuf:"bytes,12,rep,name=annotations"`
 }
 
 // SubscriptionConditionType indicates an explicit state condition about a Subscription in "abnormal-true"
diff --git a/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/zz_generated.deepcopy.go
index de6ec2b8..52f1a730 100644
--- a/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/zz_generated.deepcopy.go
+++ b/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/zz_generated.deepcopy.go
@@ -1429,6 +1429,13 @@ func (in *SubscriptionConfig) DeepCopyInto(out *SubscriptionConfig) {
 		*out = new(v1.Affinity)
 		(*in).DeepCopyInto(*out)
 	}
+	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 SubscriptionConfig.
diff --git a/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/register.go b/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/register.go
index a9914fb1..6f429848 100644
--- a/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/register.go
+++ b/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/register.go
@@ -14,6 +14,12 @@
 
 package monitoring
 
-const (
+// GroupName is set to var instead of const, since this provides the ability for clients importing the module -
+// github.com/prometheus-operator/prometheus-operator/pkg/apis to manage the operator's objects in a different
+// API group
+//
+// Use `ldflags` in the client side, e.g.:
+// go run -ldflags="-s -X github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring.GroupName=monitoring.example.com" ./example/client/.
+var (
 	GroupName = "monitoring.coreos.com"
 )
diff --git a/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/alertmanager_types.go b/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/alertmanager_types.go
index 78815919..f482db48 100644
--- a/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/alertmanager_types.go
+++ b/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/alertmanager_types.go
@@ -83,17 +83,15 @@ type AlertmanagerSpec struct {
 	Version string `json:"version,omitempty"`
 	// Tag of Alertmanager container image to be deployed. Defaults to the value of `version`.
 	// Version is ignored if Tag is set.
-	// Deprecated: use 'image' instead.  The image tag can be specified
-	// as part of the image URL.
+	// Deprecated: use 'image' instead. The image tag can be specified as part of the image URL.
 	Tag string `json:"tag,omitempty"`
 	// SHA of Alertmanager container image to be deployed. Defaults to the value of `version`.
 	// Similar to a tag, but the SHA explicitly deploys an immutable container image.
 	// Version and Tag are ignored if SHA is set.
-	// Deprecated: use 'image' instead.  The image digest can be specified
-	// as part of the image URL.
+	// Deprecated: use 'image' instead. The image digest can be specified as part of the image URL.
 	SHA string `json:"sha,omitempty"`
 	// Base image that is used to deploy pods, without tag.
-	// Deprecated: use 'image' instead
+	// Deprecated: use 'image' instead.
 	BaseImage string `json:"baseImage,omitempty"`
 	// An optional list of references to secrets in the same namespace
 	// to use for pulling prometheus and alertmanager images from registries
@@ -208,6 +206,9 @@ type AlertmanagerSpec struct {
 	ClusterAdvertiseAddress string `json:"clusterAdvertiseAddress,omitempty"`
 	// Interval between gossip attempts.
 	ClusterGossipInterval GoDuration `json:"clusterGossipInterval,omitempty"`
+	// Defines the identifier that uniquely identifies the Alertmanager cluster.
+	// You should only set it when the Alertmanager cluster includes Alertmanager instances which are external to this Alertmanager resource. In practice, the addresses of the external instances are provided via the `.spec.additionalPeers` field.
+	ClusterLabel *string `json:"clusterLabel,omitempty"`
 	// Interval between pushpull attempts.
 	ClusterPushpullInterval GoDuration `json:"clusterPushpullInterval,omitempty"`
 	// Timeout for cluster peering.
diff --git a/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/podmonitor_types.go b/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/podmonitor_types.go
index 2fdd107f..b2b73b7d 100644
--- a/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/podmonitor_types.go
+++ b/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/podmonitor_types.go
@@ -87,6 +87,17 @@ type PodMonitorSpec struct {
 	// +optional
 	TargetLimit *uint64 `json:"targetLimit,omitempty"`
 
+	// `scrapeProtocols` defines the protocols to negotiate during a scrape. It tells clients the
+	// protocols supported by Prometheus in order of preference (from most to least preferred).
+	//
+	// If unset, Prometheus uses its default value.
+	//
+	// It requires Prometheus >= v2.49.0.
+	//
+	// +listType=set
+	// +optional
+	ScrapeProtocols []ScrapeProtocol `json:"scrapeProtocols,omitempty"`
+
 	// Per-scrape limit on number of labels that will be accepted for a sample.
 	//
 	// It requires Prometheus >= v2.27.0.
@@ -120,6 +131,11 @@ type PodMonitorSpec struct {
 	//
 	// +optional
 	AttachMetadata *AttachMetadata `json:"attachMetadata,omitempty"`
+
+	// The scrape class to apply.
+	// +optional
+	// +kubebuilder:validation:MinLength=1
+	ScrapeClassName *string `json:"scrapeClass,omitempty"`
 }
 
 // PodMonitorList is a list of PodMonitors.
diff --git a/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/probe_types.go b/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/probe_types.go
index 59b85ae6..82f19337 100644
--- a/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/probe_types.go
+++ b/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/probe_types.go
@@ -84,6 +84,16 @@ type ProbeSpec struct {
 	// TargetLimit defines a limit on the number of scraped targets that will be accepted.
 	// +optional
 	TargetLimit *uint64 `json:"targetLimit,omitempty"`
+	// `scrapeProtocols` defines the protocols to negotiate during a scrape. It tells clients the
+	// protocols supported by Prometheus in order of preference (from most to least preferred).
+	//
+	// If unset, Prometheus uses its default value.
+	//
+	// It requires Prometheus >= v2.49.0.
+	//
+	// +listType=set
+	// +optional
+	ScrapeProtocols []ScrapeProtocol `json:"scrapeProtocols,omitempty"`
 	// Per-scrape limit on number of labels that will be accepted for a sample.
 	// Only valid in Prometheus versions 2.27.0 and newer.
 	// +optional
@@ -103,6 +113,11 @@ type ProbeSpec struct {
 	//
 	// +optional
 	KeepDroppedTargets *uint64 `json:"keepDroppedTargets,omitempty"`
+
+	// The scrape class to apply.
+	// +optional
+	// +kubebuilder:validation:MinLength=1
+	ScrapeClassName *string `json:"scrapeClass,omitempty"`
 }
 
 // ProbeTargets defines how to discover the probed targets.
diff --git a/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/prometheus_types.go b/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/prometheus_types.go
index e9abd48d..aa84d279 100644
--- a/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/prometheus_types.go
+++ b/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/prometheus_types.go
@@ -22,6 +22,7 @@ import (
 	"k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/util/intstr"
 )
 
@@ -31,16 +32,29 @@ const (
 	PrometheusKindKey = "prometheus"
 )
 
+// ScrapeProtocol represents a protocol used by Prometheus for scraping metrics.
+// Supported values are:
+// * `OpenMetricsText0.0.1`
+// * `OpenMetricsText1.0.0`
+// * `PrometheusProto`
+// * `PrometheusText0.0.4`
+// +kubebuilder:validation:Enum=PrometheusProto;OpenMetricsText0.0.1;OpenMetricsText1.0.0;PrometheusText0.0.4
+type ScrapeProtocol string
+
 // PrometheusInterface is used by Prometheus and PrometheusAgent to share common methods, e.g. config generation.
 // +k8s:deepcopy-gen=false
 type PrometheusInterface interface {
 	metav1.ObjectMetaAccessor
-	GetTypeMeta() metav1.TypeMeta
+	schema.ObjectKind
+
 	GetCommonPrometheusFields() CommonPrometheusFields
 	SetCommonPrometheusFields(CommonPrometheusFields)
+
 	GetStatus() PrometheusStatus
 }
 
+var _ = PrometheusInterface(&Prometheus{})
+
 func (l *Prometheus) GetCommonPrometheusFields() CommonPrometheusFields {
 	return l.Spec.CommonPrometheusFields
 }
@@ -49,14 +63,31 @@ func (l *Prometheus) SetCommonPrometheusFields(f CommonPrometheusFields) {
 	l.Spec.CommonPrometheusFields = f
 }
 
-func (l *Prometheus) GetTypeMeta() metav1.TypeMeta {
-	return l.TypeMeta
-}
-
 func (l *Prometheus) GetStatus() PrometheusStatus {
 	return l.Status
 }
 
+// +kubebuilder:validation:Enum=OnResource;OnShard
+type AdditionalLabelSelectors string
+
+const (
+	// Automatically add a label selector that will select all pods matching the same Prometheus/PrometheusAgent resource (irrespective of their shards).
+	ResourceNameLabelSelector AdditionalLabelSelectors = "OnResource"
+
+	// Automatically add a label selector that will select all pods matching the same shard.
+	ShardAndResourceNameLabelSelector AdditionalLabelSelectors = "OnShard"
+)
+
+type CoreV1TopologySpreadConstraint v1.TopologySpreadConstraint
+
+type TopologySpreadConstraint struct {
+	CoreV1TopologySpreadConstraint `json:",inline"`
+
+	//+optional
+	// Defines what Prometheus Operator managed labels should be added to labelSelector on the topologySpreadConstraint.
+	AdditionalLabelSelectors *AdditionalLabelSelectors `json:"additionalLabelSelectors,omitempty"`
+}
+
 // CommonPrometheusFields are the options available to both the Prometheus server and agent.
 // +k8s:deepcopy-gen=true
 type CommonPrometheusFields struct {
@@ -230,6 +261,17 @@ type CommonPrometheusFields struct {
 	// Number of seconds to wait until a scrape request times out.
 	ScrapeTimeout Duration `json:"scrapeTimeout,omitempty"`
 
+	// The protocols to negotiate during a scrape. It tells clients the
+	// protocols supported by Prometheus in order of preference (from most to least preferred).
+	//
+	// If unset, Prometheus uses its default value.
+	//
+	// It requires Prometheus >= v2.49.0.
+	//
+	// +listType=set
+	// +optional
+	ScrapeProtocols []ScrapeProtocol `json:"scrapeProtocols,omitempty"`
+
 	// The labels to add to any time series or alerts when communicating with
 	// external systems (federation, remote storage, Alertmanager).
 	// Labels defined by `spec.replicaExternalLabelName` and
@@ -320,9 +362,10 @@ type CommonPrometheusFields struct {
 	// Defines the Pods' tolerations if specified.
 	// +optional
 	Tolerations []v1.Toleration `json:"tolerations,omitempty"`
+
 	// Defines the pod's topology spread constraints if specified.
-	// +optional
-	TopologySpreadConstraints []v1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"`
+	//+optional
+	TopologySpreadConstraints []TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"`
 
 	// Defines the list of remote write configurations.
 	// +optional
@@ -621,6 +664,18 @@ type CommonPrometheusFields struct {
 	// If not specified, the configuration is reloaded using the /-/reload HTTP endpoint.
 	// +optional
 	ReloadStrategy *ReloadStrategyType `json:"reloadStrategy,omitempty"`
+
+	// Defines the maximum time that the `prometheus` container's startup probe will wait before being considered failed. The startup probe will return success after the WAL replay is complete.
+	// If set, the value should be greater than 60 (seconds). Otherwise it will be equal to 600 seconds (15 minutes).
+	// +optional
+	// +kubebuilder:validation:Minimum=60
+	MaximumStartupDurationSeconds *int32 `json:"maximumStartupDurationSeconds,omitempty"`
+
+	// EXPERIMENTAL List of scrape classes to expose to monitors and other scrape configs.
+	// This is experimental feature and might change in the future.
+	// +listType=map
+	// +listMapKey=name
+	ScrapeClasses []ScrapeClass `json:"scrapeClasses,omitempty"`
 }
 
 // +kubebuilder:validation:Enum=HTTP;ProcessSignal
@@ -661,6 +716,9 @@ func (cpf *CommonPrometheusFields) WebRoutePrefix() string {
 // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
 // +kubebuilder:printcolumn:name="Paused",type="boolean",JSONPath=".status.paused",description="Whether the resource reconciliation is paused or not",priority=1
 // +kubebuilder:subresource:status
+// +kubebuilder:subresource:scale:specpath=.spec.shards,statuspath=.status.shards,selectorpath=.status.selector
+// +genclient:method=GetScale,verb=get,subresource=scale,result=k8s.io/api/autoscaling/v1.Scale
+// +genclient:method=UpdateScale,verb=update,subresource=scale,input=k8s.io/api/autoscaling/v1.Scale,result=k8s.io/api/autoscaling/v1.Scale
 
 // Prometheus defines a Prometheus deployment.
 type Prometheus struct {
@@ -702,13 +760,11 @@ func (l *PrometheusList) DeepCopyObject() runtime.Object {
 type PrometheusSpec struct {
 	CommonPrometheusFields `json:",inline"`
 
-	// *Deprecated: use 'spec.image' instead.*
+	// Deprecated: use 'spec.image' instead.
 	BaseImage string `json:"baseImage,omitempty"`
-	// *Deprecated: use 'spec.image' instead. The image's tag can be specified
-	// as part of the image name.*
+	// Deprecated: use 'spec.image' instead. The image's tag can be specified as part of the image name.
 	Tag string `json:"tag,omitempty"`
-	// *Deprecated: use 'spec.image' instead. The image's digest can be
-	// specified as part of the image name.*
+	// Deprecated: use 'spec.image' instead. The image's digest can be specified as part of the image name.
 	SHA string `json:"sha,omitempty"`
 
 	// How long to retain the Prometheus data.
@@ -726,8 +782,8 @@ type PrometheusSpec struct {
 	// Defines the list of PrometheusRule objects to which the namespace label
 	// enforcement doesn't apply.
 	// This is only relevant when `spec.enforcedNamespaceLabel` is set to true.
-	// *Deprecated: use `spec.excludedFromEnforcement` instead.*
 	// +optional
+	// Deprecated: use `spec.excludedFromEnforcement` instead.
 	PrometheusRulesExcludedFromEnforce []PrometheusRuleExcludeConfig `json:"prometheusRulesExcludedFromEnforce,omitempty"`
 	// PrometheusRule objects to be selected for rule evaluation. An empty
 	// label selector matches all objects. A null label selector matches no
@@ -807,7 +863,7 @@ type PrometheusSpec struct {
 	// AllowOverlappingBlocks enables vertical compaction and vertical query
 	// merge in Prometheus.
 	//
-	// *Deprecated: this flag has no effect for Prometheus >= 2.39.0 where overlapping blocks are enabled by default.*
+	// Deprecated: this flag has no effect for Prometheus >= 2.39.0 where overlapping blocks are enabled by default.
 	AllowOverlappingBlocks bool `json:"allowOverlappingBlocks,omitempty"`
 
 	// Exemplars related settings that are runtime reloadable.
@@ -902,6 +958,10 @@ type PrometheusStatus struct {
 	// +listMapKey=shardID
 	// +optional
 	ShardStatuses []ShardStatus `json:"shardStatuses,omitempty"`
+	// Shards is the most recently observed number of shards.
+	Shards int32 `json:"shards,omitempty"`
+	// The selector used to match the pods targeted by this Prometheus resource.
+	Selector string `json:"selector,omitempty"`
 }
 
 // AlertingSpec defines parameters for alerting configuration of Prometheus servers.
@@ -921,7 +981,7 @@ type AlertingSpec struct {
 //
 // +k8s:openapi-gen=true
 type StorageSpec struct {
-	// *Deprecated: subPath usage will be removed in a future release.*
+	// Deprecated: subPath usage will be removed in a future release.
 	DisableMountSubPath bool `json:"disableMountSubPath,omitempty"`
 	// EmptyDirVolumeSource to be used by the StatefulSet.
 	// If specified, it takes precedence over `ephemeral` and `volumeClaimTemplate`.
@@ -1001,16 +1061,14 @@ type ThanosSpec struct {
 	// +optional
 	Version *string `json:"version,omitempty"`
 
-	// *Deprecated: use 'image' instead. The image's tag can be specified as
-	// part of the image name.*
 	// +optional
+	// Deprecated: use 'image' instead. The image's tag can be specified as as part of the image name.
 	Tag *string `json:"tag,omitempty"`
-	// *Deprecated: use 'image' instead.  The image digest can be specified
-	// as part of the image name.*
 	// +optional
+	// Deprecated: use 'image' instead.  The image digest can be specified as part of the image name.
 	SHA *string `json:"sha,omitempty"`
-	// *Deprecated: use 'image' instead.*
 	// +optional
+	// Deprecated: use 'image' instead.
 	BaseImage *string `json:"baseImage,omitempty"`
 
 	// Defines the resources requests and limits of the Thanos sidecar.
@@ -1031,7 +1089,7 @@ type ThanosSpec struct {
 	// +optional
 	ObjectStorageConfigFile *string `json:"objectStorageConfigFile,omitempty"`
 
-	// *Deprecated: use `grpcListenLocal` and `httpListenLocal` instead.*
+	// Deprecated: use `grpcListenLocal` and `httpListenLocal` instead.
 	ListenLocal bool `json:"listenLocal,omitempty"`
 
 	// When true, the Thanos sidecar listens on the loopback interface instead
@@ -1183,7 +1241,7 @@ type RemoteWriteSpec struct {
 	BasicAuth *BasicAuth `json:"basicAuth,omitempty"`
 	// File from which to read bearer token for the URL.
 	//
-	// *Deprecated: this will be removed in a future release. Prefer using `authorization`.*
+	// Deprecated: this will be removed in a future release. Prefer using `authorization`.
 	BearerTokenFile string `json:"bearerTokenFile,omitempty"`
 	// Authorization section for the URL.
 	//
@@ -1214,7 +1272,7 @@ type RemoteWriteSpec struct {
 	// *Warning: this field shouldn't be used because the token value appears
 	// in clear-text. Prefer using `authorization`.*
 	//
-	// *Deprecated: this will be removed in a future release.*
+	// Deprecated: this will be removed in a future release.
 	BearerToken string `json:"bearerToken,omitempty"`
 
 	// TLS Config to use for the URL.
@@ -1231,6 +1289,10 @@ type RemoteWriteSpec struct {
 	// MetadataConfig configures the sending of series metadata to the remote storage.
 	// +optional
 	MetadataConfig *MetadataConfig `json:"metadataConfig,omitempty"`
+
+	// Whether to enable HTTP2.
+	// +optional
+	EnableHttp2 *bool `json:"enableHTTP2,omitempty"`
 }
 
 // QueueConfig allows the tuning of remote write's queue_config parameters.
@@ -1373,7 +1435,7 @@ type RemoteReadSpec struct {
 	BasicAuth *BasicAuth `json:"basicAuth,omitempty"`
 	// File from which to read the bearer token for the URL.
 	//
-	// *Deprecated: this will be removed in a future release. Prefer using `authorization`.*
+	// Deprecated: this will be removed in a future release. Prefer using `authorization`.
 	BearerTokenFile string `json:"bearerTokenFile,omitempty"`
 	// Authorization section for the URL.
 	//
@@ -1387,7 +1449,7 @@ type RemoteReadSpec struct {
 	// *Warning: this field shouldn't be used because the token value appears
 	// in clear-text. Prefer using `authorization`.*
 	//
-	// *Deprecated: this will be removed in a future release.*
+	// Deprecated: this will be removed in a future release.
 	BearerToken string `json:"bearerToken,omitempty"`
 
 	// TLS Config to use for the URL.
@@ -1485,7 +1547,7 @@ type APIServerConfig struct {
 	//
 	// Cannot be set at the same time as `basicAuth`, `authorization`, or `bearerToken`.
 	//
-	// *Deprecated: this will be removed in a future release. Prefer using `authorization`.*
+	// Deprecated: this will be removed in a future release. Prefer using `authorization`.
 	BearerTokenFile string `json:"bearerTokenFile,omitempty"`
 
 	// TLS Config to use for the API server.
@@ -1504,7 +1566,7 @@ type APIServerConfig struct {
 	// *Warning: this field shouldn't be used because the token value appears
 	// in clear-text. Prefer using `authorization`.*
 	//
-	// *Deprecated: this will be removed in a future release.*
+	// Deprecated: this will be removed in a future release.
 	BearerToken string `json:"bearerToken,omitempty"`
 }
 
@@ -1542,7 +1604,7 @@ type AlertmanagerEndpoints struct {
 	//
 	// Cannot be set at the same time as `basicAuth`, `authorization`, or `sigv4`.
 	//
-	// *Deprecated: this will be removed in a future release. Prefer using `authorization`.*
+	// Deprecated: this will be removed in a future release. Prefer using `authorization`.
 	BearerTokenFile string `json:"bearerTokenFile,omitempty"`
 
 	// Authorization section for Alertmanager.
@@ -1714,3 +1776,20 @@ type AuthorizationValidationError struct {
 func (e *AuthorizationValidationError) Error() string {
 	return e.err
 }
+
+type ScrapeClass struct {
+	// Name of the scrape class.
+	// +kubebuilder:validation:MinLength=1
+	// +required
+	Name string `json:"name"`
+
+	// Default indicates that the scrape applies to all scrape objects that don't configure an explicit scrape class name.
+	//
+	// Only one scrape class can be set as default.
+	// +optional
+	Default *bool `json:"default,omitempty"`
+
+	// TLSConfig section for scrapes.
+	// +optional
+	TLSConfig *TLSConfig `json:"tlsConfig,omitempty"`
+}
diff --git a/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/servicemonitor_types.go b/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/servicemonitor_types.go
index 2d14f6f1..b357a376 100644
--- a/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/servicemonitor_types.go
+++ b/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/servicemonitor_types.go
@@ -86,6 +86,17 @@ type ServiceMonitorSpec struct {
 	// +optional
 	SampleLimit *uint64 `json:"sampleLimit,omitempty"`
 
+	// `scrapeProtocols` defines the protocols to negotiate during a scrape. It tells clients the
+	// protocols supported by Prometheus in order of preference (from most to least preferred).
+	//
+	// If unset, Prometheus uses its default value.
+	//
+	// It requires Prometheus >= v2.49.0.
+	//
+	// +listType=set
+	// +optional
+	ScrapeProtocols []ScrapeProtocol `json:"scrapeProtocols,omitempty"`
+
 	// `targetLimit` defines a limit on the number of scraped targets that will
 	// be accepted.
 	//
@@ -125,6 +136,11 @@ type ServiceMonitorSpec struct {
 	//
 	// +optional
 	AttachMetadata *AttachMetadata `json:"attachMetadata,omitempty"`
+
+	// The scrape class to apply.
+	// +optional
+	// +kubebuilder:validation:MinLength=1
+	ScrapeClassName *string `json:"scrapeClass,omitempty"`
 }
 
 // ServiceMonitorList is a list of ServiceMonitors.
diff --git a/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/types.go b/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/types.go
index 647538c4..ac317fad 100644
--- a/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/types.go
+++ b/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/types.go
@@ -200,8 +200,8 @@ type EmbeddedPersistentVolumeClaim struct {
 	// +optional
 	Spec v1.PersistentVolumeClaimSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
 
-	// *Deprecated: this field is never set.*
 	// +optional
+	// Deprecated: this field is never set.
 	Status v1.PersistentVolumeClaimStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
 }
 
@@ -366,10 +366,10 @@ type Endpoint struct {
 	// It takes precedence over `targetPort`.
 	Port string `json:"port,omitempty"`
 
-	// Name or number of the target port of the `Pod` object behind the Service, the
-	// port must be specified with container port property.
+	// Name or number of the target port of the `Pod` object behind the
+	// Service. The port must be specified with the container's port property.
 	//
-	// Deprecated: use `port` instead.
+	// +optional
 	TargetPort *intstr.IntOrString `json:"targetPort,omitempty"`
 
 	// HTTP path from which to scrape for metrics.
@@ -594,26 +594,34 @@ type SecretOrConfigMap struct {
 	ConfigMap *v1.ConfigMapKeySelector `json:"configMap,omitempty"`
 }
 
-// SecretOrConfigMapValidationError is returned by SecretOrConfigMap.Validate()
-// on semantically invalid configurations.
-// +k8s:openapi-gen=false
-type SecretOrConfigMapValidationError struct {
-	err string
-}
-
-func (e *SecretOrConfigMapValidationError) Error() string {
-	return e.err
-}
-
-// Validate semantically validates the given TLSConfig.
+// Validate semantically validates the given SecretOrConfigMap.
 func (c *SecretOrConfigMap) Validate() error {
+	if c == nil {
+		return nil
+	}
+
 	if c.Secret != nil && c.ConfigMap != nil {
-		return &SecretOrConfigMapValidationError{"SecretOrConfigMap can not specify both Secret and ConfigMap"}
+		return fmt.Errorf("cannot specify both Secret and ConfigMap")
 	}
 
 	return nil
 }
 
+func (c *SecretOrConfigMap) String() string {
+	if c == nil {
+		return "<nil>"
+	}
+
+	switch {
+	case c.Secret != nil:
+		return fmt.Sprintf("<secret=%s,key=%s>", c.Secret.LocalObjectReference.Name, c.Secret.Key)
+	case c.ConfigMap != nil:
+		return fmt.Sprintf("<configmap=%s,key=%s>", c.ConfigMap.LocalObjectReference.Name, c.ConfigMap.Key)
+	}
+
+	return "<empty>"
+}
+
 // SafeTLSConfig specifies safe TLS configuration parameters.
 // +k8s:openapi-gen=true
 type SafeTLSConfig struct {
@@ -633,22 +641,22 @@ type SafeTLSConfig struct {
 func (c *SafeTLSConfig) Validate() error {
 	if c.CA != (SecretOrConfigMap{}) {
 		if err := c.CA.Validate(); err != nil {
-			return err
+			return fmt.Errorf("ca %s: %w", c.CA.String(), err)
 		}
 	}
 
 	if c.Cert != (SecretOrConfigMap{}) {
 		if err := c.Cert.Validate(); err != nil {
-			return err
+			return fmt.Errorf("cert %s: %w", c.Cert.String(), err)
 		}
 	}
 
 	if c.Cert != (SecretOrConfigMap{}) && c.KeySecret == nil {
-		return &TLSConfigValidationError{"client cert specified without client key"}
+		return fmt.Errorf("client cert specified without client key")
 	}
 
 	if c.KeySecret != nil && c.Cert == (SecretOrConfigMap{}) {
-		return &TLSConfigValidationError{"client key specified without client cert"}
+		return fmt.Errorf("client key specified without client cert")
 	}
 
 	return nil
@@ -666,50 +674,39 @@ type TLSConfig struct {
 	KeyFile string `json:"keyFile,omitempty"`
 }
 
-// TLSConfigValidationError is returned by TLSConfig.Validate() on semantically
-// invalid tls configurations.
-// +k8s:openapi-gen=false
-type TLSConfigValidationError struct {
-	err string
-}
-
-func (e *TLSConfigValidationError) Error() string {
-	return e.err
-}
-
 // Validate semantically validates the given TLSConfig.
 func (c *TLSConfig) Validate() error {
 	if c.CA != (SecretOrConfigMap{}) {
 		if c.CAFile != "" {
-			return &TLSConfigValidationError{"tls config can not both specify CAFile and CA"}
+			return fmt.Errorf("cannot specify both caFile and ca")
 		}
 		if err := c.CA.Validate(); err != nil {
-			return &TLSConfigValidationError{"tls config CA is invalid"}
+			return fmt.Errorf("SecretOrConfigMap ca: %w", err)
 		}
 	}
 
 	if c.Cert != (SecretOrConfigMap{}) {
 		if c.CertFile != "" {
-			return &TLSConfigValidationError{"tls config can not both specify CertFile and Cert"}
+			return fmt.Errorf("cannot specify both certFile and cert")
 		}
 		if err := c.Cert.Validate(); err != nil {
-			return &TLSConfigValidationError{"tls config Cert is invalid"}
+			return fmt.Errorf("SecretOrConfigMap cert: %w", err)
 		}
 	}
 
 	if c.KeyFile != "" && c.KeySecret != nil {
-		return &TLSConfigValidationError{"tls config can not both specify KeyFile and KeySecret"}
+		return fmt.Errorf("cannot specify both keyFile and keySecret")
 	}
 
 	hasCert := c.CertFile != "" || c.Cert != (SecretOrConfigMap{})
 	hasKey := c.KeyFile != "" || c.KeySecret != nil
 
 	if hasCert && !hasKey {
-		return &TLSConfigValidationError{"tls config can not specify client cert without client key"}
+		return fmt.Errorf("cannot specify client cert without client key")
 	}
 
 	if hasKey && !hasCert {
-		return &TLSConfigValidationError{"tls config can not specify client key without client cert"}
+		return fmt.Errorf("cannot specify client key without client cert")
 	}
 
 	return nil
diff --git a/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/zz_generated.deepcopy.go b/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/zz_generated.deepcopy.go
index 73909ae3..a2099580 100644
--- a/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/zz_generated.deepcopy.go
+++ b/vendor/github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1/zz_generated.deepcopy.go
@@ -356,6 +356,11 @@ func (in *AlertmanagerSpec) DeepCopyInto(out *AlertmanagerSpec) {
 		*out = make([]string, len(*in))
 		copy(*out, *in)
 	}
+	if in.ClusterLabel != nil {
+		in, out := &in.ClusterLabel, &out.ClusterLabel
+		*out = new(string)
+		**out = **in
+	}
 	if in.AlertmanagerConfigSelector != nil {
 		in, out := &in.AlertmanagerConfigSelector, &out.AlertmanagerConfigSelector
 		*out = new(metav1.LabelSelector)
@@ -676,6 +681,11 @@ func (in *CommonPrometheusFields) DeepCopyInto(out *CommonPrometheusFields) {
 		*out = new(string)
 		**out = **in
 	}
+	if in.ScrapeProtocols != nil {
+		in, out := &in.ScrapeProtocols, &out.ScrapeProtocols
+		*out = make([]ScrapeProtocol, len(*in))
+		copy(*out, *in)
+	}
 	if in.ExternalLabels != nil {
 		in, out := &in.ExternalLabels, &out.ExternalLabels
 		*out = make(map[string]string, len(*in))
@@ -749,7 +759,7 @@ func (in *CommonPrometheusFields) DeepCopyInto(out *CommonPrometheusFields) {
 	}
 	if in.TopologySpreadConstraints != nil {
 		in, out := &in.TopologySpreadConstraints, &out.TopologySpreadConstraints
-		*out = make([]corev1.TopologySpreadConstraint, len(*in))
+		*out = make([]TopologySpreadConstraint, len(*in))
 		for i := range *in {
 			(*in)[i].DeepCopyInto(&(*out)[i])
 		}
@@ -898,6 +908,18 @@ func (in *CommonPrometheusFields) DeepCopyInto(out *CommonPrometheusFields) {
 		*out = new(ReloadStrategyType)
 		**out = **in
 	}
+	if in.MaximumStartupDurationSeconds != nil {
+		in, out := &in.MaximumStartupDurationSeconds, &out.MaximumStartupDurationSeconds
+		*out = new(int32)
+		**out = **in
+	}
+	if in.ScrapeClasses != nil {
+		in, out := &in.ScrapeClasses, &out.ScrapeClasses
+		*out = make([]ScrapeClass, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommonPrometheusFields.
@@ -926,6 +948,46 @@ func (in *Condition) DeepCopy() *Condition {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *CoreV1TopologySpreadConstraint) DeepCopyInto(out *CoreV1TopologySpreadConstraint) {
+	*out = *in
+	if in.LabelSelector != nil {
+		in, out := &in.LabelSelector, &out.LabelSelector
+		*out = new(metav1.LabelSelector)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.MinDomains != nil {
+		in, out := &in.MinDomains, &out.MinDomains
+		*out = new(int32)
+		**out = **in
+	}
+	if in.NodeAffinityPolicy != nil {
+		in, out := &in.NodeAffinityPolicy, &out.NodeAffinityPolicy
+		*out = new(corev1.NodeInclusionPolicy)
+		**out = **in
+	}
+	if in.NodeTaintsPolicy != nil {
+		in, out := &in.NodeTaintsPolicy, &out.NodeTaintsPolicy
+		*out = new(corev1.NodeInclusionPolicy)
+		**out = **in
+	}
+	if in.MatchLabelKeys != nil {
+		in, out := &in.MatchLabelKeys, &out.MatchLabelKeys
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CoreV1TopologySpreadConstraint.
+func (in *CoreV1TopologySpreadConstraint) DeepCopy() *CoreV1TopologySpreadConstraint {
+	if in == nil {
+		return nil
+	}
+	out := new(CoreV1TopologySpreadConstraint)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *EmbeddedObjectMetadata) DeepCopyInto(out *EmbeddedObjectMetadata) {
 	*out = *in
@@ -1549,6 +1611,11 @@ func (in *PodMonitorSpec) DeepCopyInto(out *PodMonitorSpec) {
 		*out = new(uint64)
 		**out = **in
 	}
+	if in.ScrapeProtocols != nil {
+		in, out := &in.ScrapeProtocols, &out.ScrapeProtocols
+		*out = make([]ScrapeProtocol, len(*in))
+		copy(*out, *in)
+	}
 	if in.LabelLimit != nil {
 		in, out := &in.LabelLimit, &out.LabelLimit
 		*out = new(uint64)
@@ -1574,6 +1641,11 @@ func (in *PodMonitorSpec) DeepCopyInto(out *PodMonitorSpec) {
 		*out = new(AttachMetadata)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.ScrapeClassName != nil {
+		in, out := &in.ScrapeClassName, &out.ScrapeClassName
+		*out = new(string)
+		**out = **in
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodMonitorSpec.
@@ -1679,6 +1751,11 @@ func (in *ProbeSpec) DeepCopyInto(out *ProbeSpec) {
 		*out = new(uint64)
 		**out = **in
 	}
+	if in.ScrapeProtocols != nil {
+		in, out := &in.ScrapeProtocols, &out.ScrapeProtocols
+		*out = make([]ScrapeProtocol, len(*in))
+		copy(*out, *in)
+	}
 	if in.LabelLimit != nil {
 		in, out := &in.LabelLimit, &out.LabelLimit
 		*out = new(uint64)
@@ -1699,6 +1776,11 @@ func (in *ProbeSpec) DeepCopyInto(out *ProbeSpec) {
 		*out = new(uint64)
 		**out = **in
 	}
+	if in.ScrapeClassName != nil {
+		in, out := &in.ScrapeClassName, &out.ScrapeClassName
+		*out = new(string)
+		**out = **in
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProbeSpec.
@@ -2349,6 +2431,11 @@ func (in *RemoteWriteSpec) DeepCopyInto(out *RemoteWriteSpec) {
 		*out = new(MetadataConfig)
 		**out = **in
 	}
+	if in.EnableHttp2 != nil {
+		in, out := &in.EnableHttp2, &out.EnableHttp2
+		*out = new(bool)
+		**out = **in
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RemoteWriteSpec.
@@ -2507,41 +2594,51 @@ func (in *SafeTLSConfig) DeepCopy() *SafeTLSConfig {
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *SecretOrConfigMap) DeepCopyInto(out *SecretOrConfigMap) {
+func (in *ScrapeClass) DeepCopyInto(out *ScrapeClass) {
 	*out = *in
-	if in.Secret != nil {
-		in, out := &in.Secret, &out.Secret
-		*out = new(corev1.SecretKeySelector)
-		(*in).DeepCopyInto(*out)
+	if in.Default != nil {
+		in, out := &in.Default, &out.Default
+		*out = new(bool)
+		**out = **in
 	}
-	if in.ConfigMap != nil {
-		in, out := &in.ConfigMap, &out.ConfigMap
-		*out = new(corev1.ConfigMapKeySelector)
+	if in.TLSConfig != nil {
+		in, out := &in.TLSConfig, &out.TLSConfig
+		*out = new(TLSConfig)
 		(*in).DeepCopyInto(*out)
 	}
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretOrConfigMap.
-func (in *SecretOrConfigMap) DeepCopy() *SecretOrConfigMap {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScrapeClass.
+func (in *ScrapeClass) DeepCopy() *ScrapeClass {
 	if in == nil {
 		return nil
 	}
-	out := new(SecretOrConfigMap)
+	out := new(ScrapeClass)
 	in.DeepCopyInto(out)
 	return out
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *SecretOrConfigMapValidationError) DeepCopyInto(out *SecretOrConfigMapValidationError) {
+func (in *SecretOrConfigMap) DeepCopyInto(out *SecretOrConfigMap) {
 	*out = *in
+	if in.Secret != nil {
+		in, out := &in.Secret, &out.Secret
+		*out = new(corev1.SecretKeySelector)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.ConfigMap != nil {
+		in, out := &in.ConfigMap, &out.ConfigMap
+		*out = new(corev1.ConfigMapKeySelector)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretOrConfigMapValidationError.
-func (in *SecretOrConfigMapValidationError) DeepCopy() *SecretOrConfigMapValidationError {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretOrConfigMap.
+func (in *SecretOrConfigMap) DeepCopy() *SecretOrConfigMap {
 	if in == nil {
 		return nil
 	}
-	out := new(SecretOrConfigMapValidationError)
+	out := new(SecretOrConfigMap)
 	in.DeepCopyInto(out)
 	return out
 }
@@ -2619,6 +2716,11 @@ func (in *ServiceMonitorSpec) DeepCopyInto(out *ServiceMonitorSpec) {
 		*out = new(uint64)
 		**out = **in
 	}
+	if in.ScrapeProtocols != nil {
+		in, out := &in.ScrapeProtocols, &out.ScrapeProtocols
+		*out = make([]ScrapeProtocol, len(*in))
+		copy(*out, *in)
+	}
 	if in.TargetLimit != nil {
 		in, out := &in.TargetLimit, &out.TargetLimit
 		*out = new(uint64)
@@ -2649,6 +2751,11 @@ func (in *ServiceMonitorSpec) DeepCopyInto(out *ServiceMonitorSpec) {
 		*out = new(AttachMetadata)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.ScrapeClassName != nil {
+		in, out := &in.ScrapeClassName, &out.ScrapeClassName
+		*out = new(string)
+		**out = **in
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceMonitorSpec.
@@ -2743,21 +2850,6 @@ func (in *TLSConfig) DeepCopy() *TLSConfig {
 	return out
 }
 
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *TLSConfigValidationError) DeepCopyInto(out *TLSConfigValidationError) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSConfigValidationError.
-func (in *TLSConfigValidationError) DeepCopy() *TLSConfigValidationError {
-	if in == nil {
-		return nil
-	}
-	out := new(TLSConfigValidationError)
-	in.DeepCopyInto(out)
-	return out
-}
-
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *TSDBSpec) DeepCopyInto(out *TSDBSpec) {
 	*out = *in
@@ -3109,6 +3201,27 @@ func (in *ThanosSpec) DeepCopy() *ThanosSpec {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *TopologySpreadConstraint) DeepCopyInto(out *TopologySpreadConstraint) {
+	*out = *in
+	in.CoreV1TopologySpreadConstraint.DeepCopyInto(&out.CoreV1TopologySpreadConstraint)
+	if in.AdditionalLabelSelectors != nil {
+		in, out := &in.AdditionalLabelSelectors, &out.AdditionalLabelSelectors
+		*out = new(AdditionalLabelSelectors)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TopologySpreadConstraint.
+func (in *TopologySpreadConstraint) DeepCopy() *TopologySpreadConstraint {
+	if in == nil {
+		return nil
+	}
+	out := new(TopologySpreadConstraint)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *WebConfigFileFields) DeepCopyInto(out *WebConfigFileFields) {
 	*out = *in
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go b/vendor/github.com/prometheus/client_golang/prometheus/histogram.go
index 1feba62c..b5c8bcb3 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/histogram.go
@@ -475,6 +475,9 @@ type HistogramOpts struct {
 
 	// now is for testing purposes, by default it's time.Now.
 	now func() time.Time
+
+	// afterFunc is for testing purposes, by default it's time.AfterFunc.
+	afterFunc func(time.Duration, func()) *time.Timer
 }
 
 // HistogramVecOpts bundles the options to create a HistogramVec metric.
@@ -526,7 +529,9 @@ func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogr
 	if opts.now == nil {
 		opts.now = time.Now
 	}
-
+	if opts.afterFunc == nil {
+		opts.afterFunc = time.AfterFunc
+	}
 	h := &histogram{
 		desc:                            desc,
 		upperBounds:                     opts.Buckets,
@@ -536,6 +541,7 @@ func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogr
 		nativeHistogramMinResetDuration: opts.NativeHistogramMinResetDuration,
 		lastResetTime:                   opts.now(),
 		now:                             opts.now,
+		afterFunc:                       opts.afterFunc,
 	}
 	if len(h.upperBounds) == 0 && opts.NativeHistogramBucketFactor <= 1 {
 		h.upperBounds = DefBuckets
@@ -716,9 +722,16 @@ type histogram struct {
 	nativeHistogramMinResetDuration time.Duration
 	// lastResetTime is protected by mtx. It is also used as created timestamp.
 	lastResetTime time.Time
+	// resetScheduled is protected by mtx. It is true if a reset is
+	// scheduled for a later time (when nativeHistogramMinResetDuration has
+	// passed).
+	resetScheduled bool
 
 	// now is for testing purposes, by default it's time.Now.
 	now func() time.Time
+
+	// afterFunc is for testing purposes, by default it's time.AfterFunc.
+	afterFunc func(time.Duration, func()) *time.Timer
 }
 
 func (h *histogram) Desc() *Desc {
@@ -874,21 +887,31 @@ func (h *histogram) limitBuckets(counts *histogramCounts, value float64, bucket
 	if h.maybeReset(hotCounts, coldCounts, coldIdx, value, bucket) {
 		return
 	}
+	// One of the other strategies will happen. To undo what they will do as
+	// soon as enough time has passed to satisfy
+	// h.nativeHistogramMinResetDuration, schedule a reset at the right time
+	// if we haven't done so already.
+	if h.nativeHistogramMinResetDuration > 0 && !h.resetScheduled {
+		h.resetScheduled = true
+		h.afterFunc(h.nativeHistogramMinResetDuration-h.now().Sub(h.lastResetTime), h.reset)
+	}
+
 	if h.maybeWidenZeroBucket(hotCounts, coldCounts) {
 		return
 	}
 	h.doubleBucketWidth(hotCounts, coldCounts)
 }
 
-// maybeReset resets the whole histogram if at least h.nativeHistogramMinResetDuration
-// has been passed. It returns true if the histogram has been reset. The caller
-// must have locked h.mtx.
+// maybeReset resets the whole histogram if at least
+// h.nativeHistogramMinResetDuration has been passed. It returns true if the
+// histogram has been reset. The caller must have locked h.mtx.
 func (h *histogram) maybeReset(
 	hot, cold *histogramCounts, coldIdx uint64, value float64, bucket int,
 ) bool {
 	// We are using the possibly mocked h.now() rather than
 	// time.Since(h.lastResetTime) to enable testing.
-	if h.nativeHistogramMinResetDuration == 0 ||
+	if h.nativeHistogramMinResetDuration == 0 || // No reset configured.
+		h.resetScheduled || // Do not interefere if a reset is already scheduled.
 		h.now().Sub(h.lastResetTime) < h.nativeHistogramMinResetDuration {
 		return false
 	}
@@ -906,6 +929,29 @@ func (h *histogram) maybeReset(
 	return true
 }
 
+// reset resets the whole histogram. It locks h.mtx itself, i.e. it has to be
+// called without having locked h.mtx.
+func (h *histogram) reset() {
+	h.mtx.Lock()
+	defer h.mtx.Unlock()
+
+	n := atomic.LoadUint64(&h.countAndHotIdx)
+	hotIdx := n >> 63
+	coldIdx := (^n) >> 63
+	hot := h.counts[hotIdx]
+	cold := h.counts[coldIdx]
+	// Completely reset coldCounts.
+	h.resetCounts(cold)
+	// Make coldCounts the new hot counts while resetting countAndHotIdx.
+	n = atomic.SwapUint64(&h.countAndHotIdx, coldIdx<<63)
+	count := n & ((1 << 63) - 1)
+	waitForCooldown(count, hot)
+	// Finally, reset the formerly hot counts, too.
+	h.resetCounts(hot)
+	h.lastResetTime = h.now()
+	h.resetScheduled = false
+}
+
 // maybeWidenZeroBucket widens the zero bucket until it includes the existing
 // buckets closest to the zero bucket (which could be two, if an equidistant
 // negative and a positive bucket exists, but usually it's only one bucket to be
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/labels.go b/vendor/github.com/prometheus/client_golang/prometheus/labels.go
index b3c4eca2..c21911f2 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/labels.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/labels.go
@@ -165,6 +165,8 @@ func validateValuesInLabels(labels Labels, expectedNumberOfValues int) error {
 
 func validateLabelValues(vals []string, expectedNumberOfValues int) error {
 	if len(vals) != expectedNumberOfValues {
+		// The call below makes vals escape, copy them to avoid that.
+		vals := append([]string(nil), vals...)
 		return fmt.Errorf(
 			"%w: expected %d label values but got %d in %#v",
 			errInconsistentCardinality, expectedNumberOfValues,
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go
index c0152cdb..8c1136ce 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go
@@ -11,8 +11,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-//go:build !windows && !js
-// +build !windows,!js
+//go:build !windows && !js && !wasip1
+// +build !windows,!js,!wasip1
 
 package prometheus
 
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_wasip1.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_wasip1.go
new file mode 100644
index 00000000..d8d9a6d7
--- /dev/null
+++ b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_wasip1.go
@@ -0,0 +1,26 @@
+// Copyright 2023 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//go:build wasip1
+// +build wasip1
+
+package prometheus
+
+func canCollectProcess() bool {
+	return false
+}
+
+func (*processCollector) processCollect(chan<- Metric) {
+	// noop on this platform
+	return
+}
diff --git a/vendor/github.com/red-hat-storage/ocs-operator/v4/services/provider/client/client.go b/vendor/github.com/red-hat-storage/ocs-operator/v4/services/provider/client/client.go
index ebb5f4bf..c9093c42 100644
--- a/vendor/github.com/red-hat-storage/ocs-operator/v4/services/provider/client/client.go
+++ b/vendor/github.com/red-hat-storage/ocs-operator/v4/services/provider/client/client.go
@@ -122,72 +122,72 @@ func (cc *OCSProviderClient) AcknowledgeOnboarding(ctx context.Context, consumer
 type StorageType uint
 
 const (
-	StorageTypeBlockpool StorageType = iota
-	StorageTypeSharedfilesystem
+	StorageTypeBlock StorageType = iota
+	StorageTypeSharedFile
 )
 
-func (cc *OCSProviderClient) FulfillStorageClassClaim(
+func (cc *OCSProviderClient) FulfillStorageClaim(
 	ctx context.Context,
 	consumerUUID string,
-	storageClassClaimName string,
+	storageClaimName string,
 	storageType StorageType,
 	storageProfile string,
 	encryptionMethod string,
-) (*pb.FulfillStorageClassClaimResponse, error) {
+) (*pb.FulfillStorageClaimResponse, error) {
 	if cc.Client == nil || cc.clientConn == nil {
 		return nil, fmt.Errorf("provider client is closed")
 	}
-	var st pb.FulfillStorageClassClaimRequest_StorageType
-	if storageType == StorageTypeSharedfilesystem {
-		st = pb.FulfillStorageClassClaimRequest_SHAREDFILESYSTEM
-	} else if storageType == StorageTypeBlockpool {
-		st = pb.FulfillStorageClassClaimRequest_BLOCKPOOL
+	var st pb.FulfillStorageClaimRequest_StorageType
+	if storageType == StorageTypeSharedFile {
+		st = pb.FulfillStorageClaimRequest_SHAREDFILE
+	} else if storageType == StorageTypeBlock {
+		st = pb.FulfillStorageClaimRequest_BLOCK
 	}
 
-	req := &pb.FulfillStorageClassClaimRequest{
-		StorageConsumerUUID:   consumerUUID,
-		StorageClassClaimName: storageClassClaimName,
-		EncryptionMethod:      encryptionMethod,
-		StorageType:           st,
-		StorageProfile:        storageProfile,
+	req := &pb.FulfillStorageClaimRequest{
+		StorageConsumerUUID: consumerUUID,
+		StorageClaimName:    storageClaimName,
+		EncryptionMethod:    encryptionMethod,
+		StorageType:         st,
+		StorageProfile:      storageProfile,
 	}
 
 	apiCtx, cancel := context.WithTimeout(ctx, cc.timeout)
 	defer cancel()
 
-	return cc.Client.FulfillStorageClassClaim(apiCtx, req)
+	return cc.Client.FulfillStorageClaim(apiCtx, req)
 }
 
-func (cc *OCSProviderClient) RevokeStorageClassClaim(ctx context.Context, consumerUUID, storageClassClaimName string) (*pb.RevokeStorageClassClaimResponse, error) {
+func (cc *OCSProviderClient) RevokeStorageClaim(ctx context.Context, consumerUUID, storageClaimName string) (*pb.RevokeStorageClaimResponse, error) {
 	if cc.Client == nil || cc.clientConn == nil {
 		return nil, fmt.Errorf("provider client is closed")
 	}
 
-	req := &pb.RevokeStorageClassClaimRequest{
-		StorageConsumerUUID:   consumerUUID,
-		StorageClassClaimName: storageClassClaimName,
+	req := &pb.RevokeStorageClaimRequest{
+		StorageConsumerUUID: consumerUUID,
+		StorageClaimName:    storageClaimName,
 	}
 
 	apiCtx, cancel := context.WithTimeout(ctx, cc.timeout)
 	defer cancel()
 
-	return cc.Client.RevokeStorageClassClaim(apiCtx, req)
+	return cc.Client.RevokeStorageClaim(apiCtx, req)
 }
 
-func (cc *OCSProviderClient) GetStorageClassClaimConfig(ctx context.Context, consumerUUID, storageClassClaimName string) (*pb.StorageClassClaimConfigResponse, error) {
+func (cc *OCSProviderClient) GetStorageClaimConfig(ctx context.Context, consumerUUID, storageClaimName string) (*pb.StorageClaimConfigResponse, error) {
 	if cc.Client == nil || cc.clientConn == nil {
 		return nil, fmt.Errorf("provider client is closed")
 	}
 
-	req := &pb.StorageClassClaimConfigRequest{
-		StorageConsumerUUID:   consumerUUID,
-		StorageClassClaimName: storageClassClaimName,
+	req := &pb.StorageClaimConfigRequest{
+		StorageConsumerUUID: consumerUUID,
+		StorageClaimName:    storageClaimName,
 	}
 
 	apiCtx, cancel := context.WithTimeout(ctx, cc.timeout)
 	defer cancel()
 
-	return cc.Client.GetStorageClassClaimConfig(apiCtx, req)
+	return cc.Client.GetStorageClaimConfig(apiCtx, req)
 }
 
 func NewStorageClientStatus() ifaces.StorageClientStatus {
diff --git a/vendor/github.com/red-hat-storage/ocs-operator/v4/services/provider/interfaces/interfaces.go b/vendor/github.com/red-hat-storage/ocs-operator/v4/services/provider/interfaces/interfaces.go
index ba58cb7f..4188cc1f 100644
--- a/vendor/github.com/red-hat-storage/ocs-operator/v4/services/provider/interfaces/interfaces.go
+++ b/vendor/github.com/red-hat-storage/ocs-operator/v4/services/provider/interfaces/interfaces.go
@@ -7,12 +7,14 @@ type StorageClientStatus interface {
 	GetPlatformVersion() string
 	GetOperatorVersion() string
 	GetClusterID() string
-	GetNamespacedName() string
+	GetClusterName() string
+	GetClientName() string
 
 	SetPlatformVersion(string) StorageClientStatus
 	SetOperatorVersion(string) StorageClientStatus
 	SetClusterID(string) StorageClientStatus
-	SetNamespacedName(string) StorageClientStatus
+	SetClusterName(string) StorageClientStatus
+	SetClientName(string) StorageClientStatus
 }
 
 type StorageClientOnboarding interface {
diff --git a/vendor/github.com/red-hat-storage/ocs-operator/v4/services/provider/pb/provider.pb.go b/vendor/github.com/red-hat-storage/ocs-operator/v4/services/provider/pb/provider.pb.go
index 0f4169eb..fb5118b5 100644
--- a/vendor/github.com/red-hat-storage/ocs-operator/v4/services/provider/pb/provider.pb.go
+++ b/vendor/github.com/red-hat-storage/ocs-operator/v4/services/provider/pb/provider.pb.go
@@ -21,50 +21,50 @@ const (
 	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
 )
 
-// StorageType of the storageclassClaim
-type FulfillStorageClassClaimRequest_StorageType int32
+// StorageType of the storageClaim
+type FulfillStorageClaimRequest_StorageType int32
 
 const (
-	FulfillStorageClassClaimRequest_SHAREDFILESYSTEM FulfillStorageClassClaimRequest_StorageType = 0
-	FulfillStorageClassClaimRequest_BLOCKPOOL        FulfillStorageClassClaimRequest_StorageType = 1
+	FulfillStorageClaimRequest_SHAREDFILE FulfillStorageClaimRequest_StorageType = 0
+	FulfillStorageClaimRequest_BLOCK      FulfillStorageClaimRequest_StorageType = 1
 )
 
-// Enum value maps for FulfillStorageClassClaimRequest_StorageType.
+// Enum value maps for FulfillStorageClaimRequest_StorageType.
 var (
-	FulfillStorageClassClaimRequest_StorageType_name = map[int32]string{
-		0: "SHAREDFILESYSTEM",
-		1: "BLOCKPOOL",
+	FulfillStorageClaimRequest_StorageType_name = map[int32]string{
+		0: "SHAREDFILE",
+		1: "BLOCK",
 	}
-	FulfillStorageClassClaimRequest_StorageType_value = map[string]int32{
-		"SHAREDFILESYSTEM": 0,
-		"BLOCKPOOL":        1,
+	FulfillStorageClaimRequest_StorageType_value = map[string]int32{
+		"SHAREDFILE": 0,
+		"BLOCK":      1,
 	}
 )
 
-func (x FulfillStorageClassClaimRequest_StorageType) Enum() *FulfillStorageClassClaimRequest_StorageType {
-	p := new(FulfillStorageClassClaimRequest_StorageType)
+func (x FulfillStorageClaimRequest_StorageType) Enum() *FulfillStorageClaimRequest_StorageType {
+	p := new(FulfillStorageClaimRequest_StorageType)
 	*p = x
 	return p
 }
 
-func (x FulfillStorageClassClaimRequest_StorageType) String() string {
+func (x FulfillStorageClaimRequest_StorageType) String() string {
 	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
 }
 
-func (FulfillStorageClassClaimRequest_StorageType) Descriptor() protoreflect.EnumDescriptor {
+func (FulfillStorageClaimRequest_StorageType) Descriptor() protoreflect.EnumDescriptor {
 	return file_provider_proto_enumTypes[0].Descriptor()
 }
 
-func (FulfillStorageClassClaimRequest_StorageType) Type() protoreflect.EnumType {
+func (FulfillStorageClaimRequest_StorageType) Type() protoreflect.EnumType {
 	return &file_provider_proto_enumTypes[0]
 }
 
-func (x FulfillStorageClassClaimRequest_StorageType) Number() protoreflect.EnumNumber {
+func (x FulfillStorageClaimRequest_StorageType) Number() protoreflect.EnumNumber {
 	return protoreflect.EnumNumber(x)
 }
 
-// Deprecated: Use FulfillStorageClassClaimRequest_StorageType.Descriptor instead.
-func (FulfillStorageClassClaimRequest_StorageType) EnumDescriptor() ([]byte, []int) {
+// Deprecated: Use FulfillStorageClaimRequest_StorageType.Descriptor instead.
+func (FulfillStorageClaimRequest_StorageType) EnumDescriptor() ([]byte, []int) {
 	return file_provider_proto_rawDescGZIP(), []int{9, 0}
 }
 
@@ -526,26 +526,26 @@ func (*AcknowledgeOnboardingResponse) Descriptor() ([]byte, []int) {
 	return file_provider_proto_rawDescGZIP(), []int{8}
 }
 
-// FulfillStorageClassClaimRequest holds the information required to
-// create the StorageclassClaim CR on provider cluster.
-type FulfillStorageClassClaimRequest struct {
+// FulfillStorageClaimRequest holds the information required to
+// create the StorageClaim CR on provider cluster.
+type FulfillStorageClaimRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	// name of the storageclassclaim on the consumer cluster.
-	StorageClassClaimName string `protobuf:"bytes,1,opt,name=storageClassClaimName,proto3" json:"storageClassClaimName,omitempty"`
+	// name of the storageClaim on the consumer cluster.
+	StorageClaimName string `protobuf:"bytes,1,opt,name=storageClaimName,proto3" json:"storageClaimName,omitempty"`
 	// K8s UID (UUID) of the consumer cluster.
 	StorageConsumerUUID string `protobuf:"bytes,2,opt,name=storageConsumerUUID,proto3" json:"storageConsumerUUID,omitempty"`
-	// encryption method of the storageclassclaim.
-	EncryptionMethod string                                      `protobuf:"bytes,3,opt,name=encryptionMethod,proto3" json:"encryptionMethod,omitempty"`
-	StorageType      FulfillStorageClassClaimRequest_StorageType `protobuf:"varint,4,opt,name=storageType,proto3,enum=provider.FulfillStorageClassClaimRequest_StorageType" json:"storageType,omitempty"`
-	// storageProfile of the storageclassclaim.
+	// encryption method of the storageClaim.
+	EncryptionMethod string                                 `protobuf:"bytes,3,opt,name=encryptionMethod,proto3" json:"encryptionMethod,omitempty"`
+	StorageType      FulfillStorageClaimRequest_StorageType `protobuf:"varint,4,opt,name=storageType,proto3,enum=provider.FulfillStorageClaimRequest_StorageType" json:"storageType,omitempty"`
+	// storageProfile of the storageClaim.
 	StorageProfile string `protobuf:"bytes,5,opt,name=storageProfile,proto3" json:"storageProfile,omitempty"`
 }
 
-func (x *FulfillStorageClassClaimRequest) Reset() {
-	*x = FulfillStorageClassClaimRequest{}
+func (x *FulfillStorageClaimRequest) Reset() {
+	*x = FulfillStorageClaimRequest{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_provider_proto_msgTypes[9]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -553,13 +553,13 @@ func (x *FulfillStorageClassClaimRequest) Reset() {
 	}
 }
 
-func (x *FulfillStorageClassClaimRequest) String() string {
+func (x *FulfillStorageClaimRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*FulfillStorageClassClaimRequest) ProtoMessage() {}
+func (*FulfillStorageClaimRequest) ProtoMessage() {}
 
-func (x *FulfillStorageClassClaimRequest) ProtoReflect() protoreflect.Message {
+func (x *FulfillStorageClaimRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_provider_proto_msgTypes[9]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -571,55 +571,55 @@ func (x *FulfillStorageClassClaimRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use FulfillStorageClassClaimRequest.ProtoReflect.Descriptor instead.
-func (*FulfillStorageClassClaimRequest) Descriptor() ([]byte, []int) {
+// Deprecated: Use FulfillStorageClaimRequest.ProtoReflect.Descriptor instead.
+func (*FulfillStorageClaimRequest) Descriptor() ([]byte, []int) {
 	return file_provider_proto_rawDescGZIP(), []int{9}
 }
 
-func (x *FulfillStorageClassClaimRequest) GetStorageClassClaimName() string {
+func (x *FulfillStorageClaimRequest) GetStorageClaimName() string {
 	if x != nil {
-		return x.StorageClassClaimName
+		return x.StorageClaimName
 	}
 	return ""
 }
 
-func (x *FulfillStorageClassClaimRequest) GetStorageConsumerUUID() string {
+func (x *FulfillStorageClaimRequest) GetStorageConsumerUUID() string {
 	if x != nil {
 		return x.StorageConsumerUUID
 	}
 	return ""
 }
 
-func (x *FulfillStorageClassClaimRequest) GetEncryptionMethod() string {
+func (x *FulfillStorageClaimRequest) GetEncryptionMethod() string {
 	if x != nil {
 		return x.EncryptionMethod
 	}
 	return ""
 }
 
-func (x *FulfillStorageClassClaimRequest) GetStorageType() FulfillStorageClassClaimRequest_StorageType {
+func (x *FulfillStorageClaimRequest) GetStorageType() FulfillStorageClaimRequest_StorageType {
 	if x != nil {
 		return x.StorageType
 	}
-	return FulfillStorageClassClaimRequest_SHAREDFILESYSTEM
+	return FulfillStorageClaimRequest_SHAREDFILE
 }
 
-func (x *FulfillStorageClassClaimRequest) GetStorageProfile() string {
+func (x *FulfillStorageClaimRequest) GetStorageProfile() string {
 	if x != nil {
 		return x.StorageProfile
 	}
 	return ""
 }
 
-// FulfillStorageClassClaimResponse holds the response for the FulfillStorageClassClaim API request.
-type FulfillStorageClassClaimResponse struct {
+// FulfillStorageClaimResponse holds the response for the FulfillStorageClaim API request.
+type FulfillStorageClaimResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
 
-func (x *FulfillStorageClassClaimResponse) Reset() {
-	*x = FulfillStorageClassClaimResponse{}
+func (x *FulfillStorageClaimResponse) Reset() {
+	*x = FulfillStorageClaimResponse{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_provider_proto_msgTypes[10]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -627,13 +627,13 @@ func (x *FulfillStorageClassClaimResponse) Reset() {
 	}
 }
 
-func (x *FulfillStorageClassClaimResponse) String() string {
+func (x *FulfillStorageClaimResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*FulfillStorageClassClaimResponse) ProtoMessage() {}
+func (*FulfillStorageClaimResponse) ProtoMessage() {}
 
-func (x *FulfillStorageClassClaimResponse) ProtoReflect() protoreflect.Message {
+func (x *FulfillStorageClaimResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_provider_proto_msgTypes[10]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -645,26 +645,26 @@ func (x *FulfillStorageClassClaimResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use FulfillStorageClassClaimResponse.ProtoReflect.Descriptor instead.
-func (*FulfillStorageClassClaimResponse) Descriptor() ([]byte, []int) {
+// Deprecated: Use FulfillStorageClaimResponse.ProtoReflect.Descriptor instead.
+func (*FulfillStorageClaimResponse) Descriptor() ([]byte, []int) {
 	return file_provider_proto_rawDescGZIP(), []int{10}
 }
 
-// RevokeStorageClassClaimRequest holds the information required to delete the
-// StorageclassClaim CR on provider cluster.
-type RevokeStorageClassClaimRequest struct {
+// RevokeStorageClaimRequest holds the information required to delete the
+// StorageClaim CR on provider cluster.
+type RevokeStorageClaimRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	// name of the storageclassclaim on the consumer cluster.
-	StorageClassClaimName string `protobuf:"bytes,1,opt,name=storageClassClaimName,proto3" json:"storageClassClaimName,omitempty"`
+	// name of the storageClaim on the consumer cluster.
+	StorageClaimName string `protobuf:"bytes,1,opt,name=storageClaimName,proto3" json:"storageClaimName,omitempty"`
 	// K8s UID (UUID) of the consumer cluster.
 	StorageConsumerUUID string `protobuf:"bytes,2,opt,name=storageConsumerUUID,proto3" json:"storageConsumerUUID,omitempty"`
 }
 
-func (x *RevokeStorageClassClaimRequest) Reset() {
-	*x = RevokeStorageClassClaimRequest{}
+func (x *RevokeStorageClaimRequest) Reset() {
+	*x = RevokeStorageClaimRequest{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_provider_proto_msgTypes[11]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -672,13 +672,13 @@ func (x *RevokeStorageClassClaimRequest) Reset() {
 	}
 }
 
-func (x *RevokeStorageClassClaimRequest) String() string {
+func (x *RevokeStorageClaimRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*RevokeStorageClassClaimRequest) ProtoMessage() {}
+func (*RevokeStorageClaimRequest) ProtoMessage() {}
 
-func (x *RevokeStorageClassClaimRequest) ProtoReflect() protoreflect.Message {
+func (x *RevokeStorageClaimRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_provider_proto_msgTypes[11]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -690,34 +690,34 @@ func (x *RevokeStorageClassClaimRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use RevokeStorageClassClaimRequest.ProtoReflect.Descriptor instead.
-func (*RevokeStorageClassClaimRequest) Descriptor() ([]byte, []int) {
+// Deprecated: Use RevokeStorageClaimRequest.ProtoReflect.Descriptor instead.
+func (*RevokeStorageClaimRequest) Descriptor() ([]byte, []int) {
 	return file_provider_proto_rawDescGZIP(), []int{11}
 }
 
-func (x *RevokeStorageClassClaimRequest) GetStorageClassClaimName() string {
+func (x *RevokeStorageClaimRequest) GetStorageClaimName() string {
 	if x != nil {
-		return x.StorageClassClaimName
+		return x.StorageClaimName
 	}
 	return ""
 }
 
-func (x *RevokeStorageClassClaimRequest) GetStorageConsumerUUID() string {
+func (x *RevokeStorageClaimRequest) GetStorageConsumerUUID() string {
 	if x != nil {
 		return x.StorageConsumerUUID
 	}
 	return ""
 }
 
-// RevokeStorageClassClaimResponse holds the response for the RevokeStorageClassClaim API request.
-type RevokeStorageClassClaimResponse struct {
+// RevokeStorageClaimResponse holds the response for the RevokeStorageClaim API request.
+type RevokeStorageClaimResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
 
-func (x *RevokeStorageClassClaimResponse) Reset() {
-	*x = RevokeStorageClassClaimResponse{}
+func (x *RevokeStorageClaimResponse) Reset() {
+	*x = RevokeStorageClaimResponse{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_provider_proto_msgTypes[12]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -725,13 +725,13 @@ func (x *RevokeStorageClassClaimResponse) Reset() {
 	}
 }
 
-func (x *RevokeStorageClassClaimResponse) String() string {
+func (x *RevokeStorageClaimResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*RevokeStorageClassClaimResponse) ProtoMessage() {}
+func (*RevokeStorageClaimResponse) ProtoMessage() {}
 
-func (x *RevokeStorageClassClaimResponse) ProtoReflect() protoreflect.Message {
+func (x *RevokeStorageClaimResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_provider_proto_msgTypes[12]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -743,26 +743,26 @@ func (x *RevokeStorageClassClaimResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use RevokeStorageClassClaimResponse.ProtoReflect.Descriptor instead.
-func (*RevokeStorageClassClaimResponse) Descriptor() ([]byte, []int) {
+// Deprecated: Use RevokeStorageClaimResponse.ProtoReflect.Descriptor instead.
+func (*RevokeStorageClaimResponse) Descriptor() ([]byte, []int) {
 	return file_provider_proto_rawDescGZIP(), []int{12}
 }
 
-// StorageClassClaimConfigRequest holds the information required to generate the
-// json config for StorageClassClaim specific resources.
-type StorageClassClaimConfigRequest struct {
+// StorageClaimConfigRequest holds the information required to generate the
+// json config for StorageClaim specific resources.
+type StorageClaimConfigRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	// name of the storageclassclaim on the consumer cluster.
-	StorageClassClaimName string `protobuf:"bytes,1,opt,name=storageClassClaimName,proto3" json:"storageClassClaimName,omitempty"`
+	// name of the storageClaim on the consumer cluster.
+	StorageClaimName string `protobuf:"bytes,1,opt,name=storageClaimName,proto3" json:"storageClaimName,omitempty"`
 	// K8s UID (UUID) of the consumer cluster.
 	StorageConsumerUUID string `protobuf:"bytes,2,opt,name=storageConsumerUUID,proto3" json:"storageConsumerUUID,omitempty"`
 }
 
-func (x *StorageClassClaimConfigRequest) Reset() {
-	*x = StorageClassClaimConfigRequest{}
+func (x *StorageClaimConfigRequest) Reset() {
+	*x = StorageClaimConfigRequest{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_provider_proto_msgTypes[13]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -770,13 +770,13 @@ func (x *StorageClassClaimConfigRequest) Reset() {
 	}
 }
 
-func (x *StorageClassClaimConfigRequest) String() string {
+func (x *StorageClaimConfigRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*StorageClassClaimConfigRequest) ProtoMessage() {}
+func (*StorageClaimConfigRequest) ProtoMessage() {}
 
-func (x *StorageClassClaimConfigRequest) ProtoReflect() protoreflect.Message {
+func (x *StorageClaimConfigRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_provider_proto_msgTypes[13]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -788,27 +788,27 @@ func (x *StorageClassClaimConfigRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use StorageClassClaimConfigRequest.ProtoReflect.Descriptor instead.
-func (*StorageClassClaimConfigRequest) Descriptor() ([]byte, []int) {
+// Deprecated: Use StorageClaimConfigRequest.ProtoReflect.Descriptor instead.
+func (*StorageClaimConfigRequest) Descriptor() ([]byte, []int) {
 	return file_provider_proto_rawDescGZIP(), []int{13}
 }
 
-func (x *StorageClassClaimConfigRequest) GetStorageClassClaimName() string {
+func (x *StorageClaimConfigRequest) GetStorageClaimName() string {
 	if x != nil {
-		return x.StorageClassClaimName
+		return x.StorageClaimName
 	}
 	return ""
 }
 
-func (x *StorageClassClaimConfigRequest) GetStorageConsumerUUID() string {
+func (x *StorageClaimConfigRequest) GetStorageConsumerUUID() string {
 	if x != nil {
 		return x.StorageConsumerUUID
 	}
 	return ""
 }
 
-// StorageClassClaimConfigResponse holds the response for the StorageClassClaimConfig API request.
-type StorageClassClaimConfigResponse struct {
+// StorageClaimConfigResponse holds the response for the StorageClaimConfig API request.
+type StorageClaimConfigResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
@@ -817,8 +817,8 @@ type StorageClassClaimConfigResponse struct {
 	ExternalResource []*ExternalResource `protobuf:"bytes,1,rep,name=externalResource,proto3" json:"externalResource,omitempty"`
 }
 
-func (x *StorageClassClaimConfigResponse) Reset() {
-	*x = StorageClassClaimConfigResponse{}
+func (x *StorageClaimConfigResponse) Reset() {
+	*x = StorageClaimConfigResponse{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_provider_proto_msgTypes[14]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -826,13 +826,13 @@ func (x *StorageClassClaimConfigResponse) Reset() {
 	}
 }
 
-func (x *StorageClassClaimConfigResponse) String() string {
+func (x *StorageClaimConfigResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*StorageClassClaimConfigResponse) ProtoMessage() {}
+func (*StorageClaimConfigResponse) ProtoMessage() {}
 
-func (x *StorageClassClaimConfigResponse) ProtoReflect() protoreflect.Message {
+func (x *StorageClaimConfigResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_provider_proto_msgTypes[14]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -844,12 +844,12 @@ func (x *StorageClassClaimConfigResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use StorageClassClaimConfigResponse.ProtoReflect.Descriptor instead.
-func (*StorageClassClaimConfigResponse) Descriptor() ([]byte, []int) {
+// Deprecated: Use StorageClaimConfigResponse.ProtoReflect.Descriptor instead.
+func (*StorageClaimConfigResponse) Descriptor() ([]byte, []int) {
 	return file_provider_proto_rawDescGZIP(), []int{14}
 }
 
-func (x *StorageClassClaimConfigResponse) GetExternalResource() []*ExternalResource {
+func (x *StorageClaimConfigResponse) GetExternalResource() []*ExternalResource {
 	if x != nil {
 		return x.ExternalResource
 	}
@@ -866,8 +866,10 @@ type ReportStatusRequest struct {
 	ClientOperatorVersion string `protobuf:"bytes,3,opt,name=clientOperatorVersion,proto3" json:"clientOperatorVersion,omitempty"`
 	// clusterID is the id of the openshift cluster
 	ClusterID string `protobuf:"bytes,4,opt,name=clusterID,proto3" json:"clusterID,omitempty"`
-	// NamespacedName is the name and namespace of the StorageClient
-	NamespacedName string `protobuf:"bytes,5,opt,name=NamespacedName,proto3" json:"NamespacedName,omitempty"`
+	// clusterName is the name of the openshift cluster
+	ClusterName string `protobuf:"bytes,5,opt,name=clusterName,proto3" json:"clusterName,omitempty"`
+	// clientName is the name of the connected storageclient
+	ClientName string `protobuf:"bytes,6,opt,name=clientName,proto3" json:"clientName,omitempty"`
 }
 
 func (x *ReportStatusRequest) Reset() {
@@ -930,9 +932,16 @@ func (x *ReportStatusRequest) GetClusterID() string {
 	return ""
 }
 
-func (x *ReportStatusRequest) GetNamespacedName() string {
+func (x *ReportStatusRequest) GetClusterName() string {
 	if x != nil {
-		return x.NamespacedName
+		return x.ClusterName
+	}
+	return ""
+}
+
+func (x *ReportStatusRequest) GetClientName() string {
+	if x != nil {
+		return x.ClientName
 	}
 	return ""
 }
@@ -1036,124 +1045,118 @@ var file_provider_proto_rawDesc = []byte{
 	0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x55, 0x55, 0x49, 0x44,
 	0x22, 0x1f, 0x0a, 0x1d, 0x41, 0x63, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x4f,
 	0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x22, 0xea, 0x02, 0x0a, 0x1f, 0x46, 0x75, 0x6c, 0x66, 0x69, 0x6c, 0x6c, 0x53, 0x74, 0x6f,
-	0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x15, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65,
-	0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61,
-	0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x13, 0x73,
-	0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x55, 0x55,
-	0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67,
-	0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x55, 0x55, 0x49, 0x44, 0x12, 0x2a, 0x0a,
-	0x10, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f,
-	0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74,
-	0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x57, 0x0a, 0x0b, 0x73, 0x74, 0x6f,
-	0x72, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x35,
-	0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x46, 0x75, 0x6c, 0x66, 0x69, 0x6c,
-	0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6c, 0x61,
-	0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67,
-	0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x54, 0x79,
-	0x70, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x50, 0x72, 0x6f,
-	0x66, 0x69, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x74, 0x6f, 0x72,
-	0x61, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x22, 0x32, 0x0a, 0x0b, 0x53, 0x74,
-	0x6f, 0x72, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x48, 0x41,
-	0x52, 0x45, 0x44, 0x46, 0x49, 0x4c, 0x45, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x10, 0x00, 0x12,
-	0x0d, 0x0a, 0x09, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x50, 0x4f, 0x4f, 0x4c, 0x10, 0x01, 0x22, 0x22,
-	0x0a, 0x20, 0x46, 0x75, 0x6c, 0x66, 0x69, 0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65,
-	0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x22, 0x88, 0x01, 0x0a, 0x1e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x74, 0x6f,
-	0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x15, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65,
-	0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61,
-	0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x13, 0x73,
-	0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x55, 0x55,
-	0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67,
-	0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x55, 0x55, 0x49, 0x44, 0x22, 0x21, 0x0a,
-	0x1f, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c,
-	0x61, 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x22, 0x88, 0x01, 0x0a, 0x1e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x73,
-	0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x15, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c,
-	0x61, 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x15, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73,
-	0x43, 0x6c, 0x61, 0x69, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x13, 0x73, 0x74, 0x6f,
-	0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x55, 0x55, 0x49, 0x44,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43,
-	0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x55, 0x55, 0x49, 0x44, 0x22, 0x69, 0x0a, 0x1f, 0x53,
-	0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d,
-	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46,
-	0x0a, 0x10, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72,
-	0x63, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69,
-	0x64, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x6f,
-	0x75, 0x72, 0x63, 0x65, 0x52, 0x10, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x65,
-	0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0xf9, 0x01, 0x0a, 0x13, 0x52, 0x65, 0x70, 0x6f, 0x72,
-	0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30,
-	0x0a, 0x13, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65,
-	0x72, 0x55, 0x55, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x74, 0x6f,
-	0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x55, 0x55, 0x49, 0x44,
-	0x12, 0x34, 0x0a, 0x15, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f,
-	0x72, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x15, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x56,
-	0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x15, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
-	0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18,
-	0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4f, 0x70, 0x65,
-	0x72, 0x61, 0x74, 0x6f, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09,
-	0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x12, 0x26, 0x0a, 0x0e, 0x4e, 0x61,
-	0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x0e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x64, 0x4e, 0x61,
-	0x6d, 0x65, 0x22, 0x5a, 0x0a, 0x14, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74,
-	0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x1c, 0x64, 0x65,
-	0x73, 0x69, 0x72, 0x65, 0x64, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61,
-	0x74, 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x1c, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4f,
-	0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x32, 0xb4,
-	0x06, 0x0a, 0x0b, 0x4f, 0x43, 0x53, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x58,
-	0x0a, 0x0f, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65,
-	0x72, 0x12, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x4f, 0x6e, 0x62,
+	0x65, 0x22, 0xcc, 0x02, 0x0a, 0x1a, 0x46, 0x75, 0x6c, 0x66, 0x69, 0x6c, 0x6c, 0x53, 0x74, 0x6f,
+	0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x12, 0x2a, 0x0a, 0x10, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x69, 0x6d,
+	0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x73, 0x74, 0x6f, 0x72,
+	0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x13,
+	0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x55,
+	0x55, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x74, 0x6f, 0x72, 0x61,
+	0x67, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x55, 0x55, 0x49, 0x44, 0x12, 0x2a,
+	0x0a, 0x10, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x68,
+	0x6f, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70,
+	0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x52, 0x0a, 0x0b, 0x73, 0x74,
+	0x6f, 0x72, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32,
+	0x30, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x46, 0x75, 0x6c, 0x66, 0x69,
+	0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70,
+	0x65, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26,
+	0x0a, 0x0e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65,
+	0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x50,
+	0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x22, 0x28, 0x0a, 0x0b, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67,
+	0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x48, 0x41, 0x52, 0x45, 0x44, 0x46,
+	0x49, 0x4c, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x01,
+	0x22, 0x1d, 0x0a, 0x1b, 0x46, 0x75, 0x6c, 0x66, 0x69, 0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61,
+	0x67, 0x65, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
+	0x79, 0x0a, 0x19, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65,
+	0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x10,
+	0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x4e, 0x61, 0x6d, 0x65,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43,
+	0x6c, 0x61, 0x69, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x13, 0x73, 0x74, 0x6f, 0x72,
+	0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x55, 0x55, 0x49, 0x44, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f,
+	0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x55, 0x55, 0x49, 0x44, 0x22, 0x1c, 0x0a, 0x1a, 0x52, 0x65,
+	0x76, 0x6f, 0x6b, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x69, 0x6d,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x79, 0x0a, 0x19, 0x53, 0x74, 0x6f, 0x72,
+	0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x10, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65,
+	0x43, 0x6c, 0x61, 0x69, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x10, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x4e, 0x61, 0x6d,
+	0x65, 0x12, 0x30, 0x0a, 0x13, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x73,
+	0x75, 0x6d, 0x65, 0x72, 0x55, 0x55, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13,
+	0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x55,
+	0x55, 0x49, 0x44, 0x22, 0x64, 0x0a, 0x1a, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c,
+	0x61, 0x69, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x12, 0x46, 0x0a, 0x10, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x73,
+	0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72,
+	0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x52,
+	0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x10, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61,
+	0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x93, 0x02, 0x0a, 0x13, 0x52, 0x65,
+	0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x30, 0x0a, 0x13, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x73,
+	0x75, 0x6d, 0x65, 0x72, 0x55, 0x55, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13,
+	0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x55,
+	0x55, 0x49, 0x44, 0x12, 0x34, 0x0a, 0x15, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x6c, 0x61,
+	0x74, 0x66, 0x6f, 0x72, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x15, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f,
+	0x72, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x15, 0x63, 0x6c, 0x69,
+	0x65, 0x6e, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69,
+	0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+	0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12,
+	0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x12, 0x20, 0x0a,
+	0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12,
+	0x1e, 0x0a, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22,
+	0x5a, 0x0a, 0x14, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x1c, 0x64, 0x65, 0x73, 0x69, 0x72,
+	0x65, 0x64, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72,
+	0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1c, 0x64,
+	0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4f, 0x70, 0x65, 0x72,
+	0x61, 0x74, 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x32, 0x87, 0x06, 0x0a, 0x0b,
+	0x4f, 0x43, 0x53, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x58, 0x0a, 0x0f, 0x4f,
+	0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x12, 0x20,
+	0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72,
+	0x64, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x1a, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x4f, 0x6e, 0x62, 0x6f,
+	0x61, 0x72, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72,
+	0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x76,
+	0x69, 0x64, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76,
+	0x69, 0x64, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x10,
+	0x4f, 0x66, 0x66, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72,
+	0x12, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x4f, 0x66, 0x66, 0x62,
 	0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x4f,
-	0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53,
-	0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1e, 0x2e, 0x70,
-	0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70,
-	0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
-	0x5b, 0x0a, 0x10, 0x4f, 0x66, 0x66, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x75,
-	0x6d, 0x65, 0x72, 0x12, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x4f,
+	0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x4f,
 	0x66, 0x66, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
-	0x72, 0x2e, 0x4f, 0x66, 0x66, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d,
-	0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6a, 0x0a, 0x15,
-	0x41, 0x63, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x4f, 0x6e, 0x62, 0x6f, 0x61,
-	0x72, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
-	0x2e, 0x41, 0x63, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x4f, 0x6e, 0x62, 0x6f,
-	0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e,
-	0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x41, 0x63, 0x6b, 0x6e, 0x6f, 0x77, 0x6c,
-	0x65, 0x64, 0x67, 0x65, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x18, 0x46, 0x75, 0x6c, 0x66,
-	0x69, 0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43,
-	0x6c, 0x61, 0x69, 0x6d, 0x12, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e,
-	0x46, 0x75, 0x6c, 0x66, 0x69, 0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c,
-	0x61, 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
-	0x2a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x46, 0x75, 0x6c, 0x66, 0x69,
-	0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6c,
-	0x61, 0x69, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x70, 0x0a,
-	0x17, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c,
-	0x61, 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x12, 0x28, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69,
-	0x64, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67,
-	0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x1a, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x52, 0x65,
-	0x76, 0x6f, 0x6b, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73,
-	0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
-	0x73, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61,
-	0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x28, 0x2e,
-	0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65,
-	0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64,
-	0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6a, 0x0a, 0x15, 0x41, 0x63, 0x6b,
+	0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69,
+	0x6e, 0x67, 0x12, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x41, 0x63,
+	0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64,
+	0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x70, 0x72, 0x6f,
+	0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x41, 0x63, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67,
+	0x65, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x64, 0x0a, 0x13, 0x46, 0x75, 0x6c, 0x66, 0x69, 0x6c, 0x6c,
+	0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x12, 0x24, 0x2e, 0x70,
+	0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x46, 0x75, 0x6c, 0x66, 0x69, 0x6c, 0x6c, 0x53,
+	0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x1a, 0x25, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x46, 0x75,
+	0x6c, 0x66, 0x69, 0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x69,
+	0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x61, 0x0a, 0x12, 0x52,
+	0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x69,
+	0x6d, 0x12, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x76,
+	0x6f, 0x6b, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
+	0x72, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43,
+	0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x64,
+	0x0a, 0x15, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x69,
+	0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64,
+	0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x43,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70,
+	0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43,
 	0x6c, 0x61, 0x69, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
 	0x73, 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0c, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74,
 	0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e,
@@ -1179,44 +1182,44 @@ func file_provider_proto_rawDescGZIP() []byte {
 var file_provider_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
 var file_provider_proto_msgTypes = make([]protoimpl.MessageInfo, 17)
 var file_provider_proto_goTypes = []interface{}{
-	(FulfillStorageClassClaimRequest_StorageType)(0), // 0: provider.FulfillStorageClassClaimRequest.StorageType
-	(*OnboardConsumerRequest)(nil),                   // 1: provider.OnboardConsumerRequest
-	(*OnboardConsumerResponse)(nil),                  // 2: provider.OnboardConsumerResponse
-	(*StorageConfigRequest)(nil),                     // 3: provider.StorageConfigRequest
-	(*ExternalResource)(nil),                         // 4: provider.ExternalResource
-	(*StorageConfigResponse)(nil),                    // 5: provider.StorageConfigResponse
-	(*OffboardConsumerRequest)(nil),                  // 6: provider.OffboardConsumerRequest
-	(*OffboardConsumerResponse)(nil),                 // 7: provider.OffboardConsumerResponse
-	(*AcknowledgeOnboardingRequest)(nil),             // 8: provider.AcknowledgeOnboardingRequest
-	(*AcknowledgeOnboardingResponse)(nil),            // 9: provider.AcknowledgeOnboardingResponse
-	(*FulfillStorageClassClaimRequest)(nil),          // 10: provider.FulfillStorageClassClaimRequest
-	(*FulfillStorageClassClaimResponse)(nil),         // 11: provider.FulfillStorageClassClaimResponse
-	(*RevokeStorageClassClaimRequest)(nil),           // 12: provider.RevokeStorageClassClaimRequest
-	(*RevokeStorageClassClaimResponse)(nil),          // 13: provider.RevokeStorageClassClaimResponse
-	(*StorageClassClaimConfigRequest)(nil),           // 14: provider.StorageClassClaimConfigRequest
-	(*StorageClassClaimConfigResponse)(nil),          // 15: provider.StorageClassClaimConfigResponse
-	(*ReportStatusRequest)(nil),                      // 16: provider.ReportStatusRequest
-	(*ReportStatusResponse)(nil),                     // 17: provider.ReportStatusResponse
+	(FulfillStorageClaimRequest_StorageType)(0), // 0: provider.FulfillStorageClaimRequest.StorageType
+	(*OnboardConsumerRequest)(nil),              // 1: provider.OnboardConsumerRequest
+	(*OnboardConsumerResponse)(nil),             // 2: provider.OnboardConsumerResponse
+	(*StorageConfigRequest)(nil),                // 3: provider.StorageConfigRequest
+	(*ExternalResource)(nil),                    // 4: provider.ExternalResource
+	(*StorageConfigResponse)(nil),               // 5: provider.StorageConfigResponse
+	(*OffboardConsumerRequest)(nil),             // 6: provider.OffboardConsumerRequest
+	(*OffboardConsumerResponse)(nil),            // 7: provider.OffboardConsumerResponse
+	(*AcknowledgeOnboardingRequest)(nil),        // 8: provider.AcknowledgeOnboardingRequest
+	(*AcknowledgeOnboardingResponse)(nil),       // 9: provider.AcknowledgeOnboardingResponse
+	(*FulfillStorageClaimRequest)(nil),          // 10: provider.FulfillStorageClaimRequest
+	(*FulfillStorageClaimResponse)(nil),         // 11: provider.FulfillStorageClaimResponse
+	(*RevokeStorageClaimRequest)(nil),           // 12: provider.RevokeStorageClaimRequest
+	(*RevokeStorageClaimResponse)(nil),          // 13: provider.RevokeStorageClaimResponse
+	(*StorageClaimConfigRequest)(nil),           // 14: provider.StorageClaimConfigRequest
+	(*StorageClaimConfigResponse)(nil),          // 15: provider.StorageClaimConfigResponse
+	(*ReportStatusRequest)(nil),                 // 16: provider.ReportStatusRequest
+	(*ReportStatusResponse)(nil),                // 17: provider.ReportStatusResponse
 }
 var file_provider_proto_depIdxs = []int32{
 	4,  // 0: provider.StorageConfigResponse.externalResource:type_name -> provider.ExternalResource
-	0,  // 1: provider.FulfillStorageClassClaimRequest.storageType:type_name -> provider.FulfillStorageClassClaimRequest.StorageType
-	4,  // 2: provider.StorageClassClaimConfigResponse.externalResource:type_name -> provider.ExternalResource
+	0,  // 1: provider.FulfillStorageClaimRequest.storageType:type_name -> provider.FulfillStorageClaimRequest.StorageType
+	4,  // 2: provider.StorageClaimConfigResponse.externalResource:type_name -> provider.ExternalResource
 	1,  // 3: provider.OCSProvider.OnboardConsumer:input_type -> provider.OnboardConsumerRequest
 	3,  // 4: provider.OCSProvider.GetStorageConfig:input_type -> provider.StorageConfigRequest
 	6,  // 5: provider.OCSProvider.OffboardConsumer:input_type -> provider.OffboardConsumerRequest
 	8,  // 6: provider.OCSProvider.AcknowledgeOnboarding:input_type -> provider.AcknowledgeOnboardingRequest
-	10, // 7: provider.OCSProvider.FulfillStorageClassClaim:input_type -> provider.FulfillStorageClassClaimRequest
-	12, // 8: provider.OCSProvider.RevokeStorageClassClaim:input_type -> provider.RevokeStorageClassClaimRequest
-	14, // 9: provider.OCSProvider.GetStorageClassClaimConfig:input_type -> provider.StorageClassClaimConfigRequest
+	10, // 7: provider.OCSProvider.FulfillStorageClaim:input_type -> provider.FulfillStorageClaimRequest
+	12, // 8: provider.OCSProvider.RevokeStorageClaim:input_type -> provider.RevokeStorageClaimRequest
+	14, // 9: provider.OCSProvider.GetStorageClaimConfig:input_type -> provider.StorageClaimConfigRequest
 	16, // 10: provider.OCSProvider.ReportStatus:input_type -> provider.ReportStatusRequest
 	2,  // 11: provider.OCSProvider.OnboardConsumer:output_type -> provider.OnboardConsumerResponse
 	5,  // 12: provider.OCSProvider.GetStorageConfig:output_type -> provider.StorageConfigResponse
 	7,  // 13: provider.OCSProvider.OffboardConsumer:output_type -> provider.OffboardConsumerResponse
 	9,  // 14: provider.OCSProvider.AcknowledgeOnboarding:output_type -> provider.AcknowledgeOnboardingResponse
-	11, // 15: provider.OCSProvider.FulfillStorageClassClaim:output_type -> provider.FulfillStorageClassClaimResponse
-	13, // 16: provider.OCSProvider.RevokeStorageClassClaim:output_type -> provider.RevokeStorageClassClaimResponse
-	15, // 17: provider.OCSProvider.GetStorageClassClaimConfig:output_type -> provider.StorageClassClaimConfigResponse
+	11, // 15: provider.OCSProvider.FulfillStorageClaim:output_type -> provider.FulfillStorageClaimResponse
+	13, // 16: provider.OCSProvider.RevokeStorageClaim:output_type -> provider.RevokeStorageClaimResponse
+	15, // 17: provider.OCSProvider.GetStorageClaimConfig:output_type -> provider.StorageClaimConfigResponse
 	17, // 18: provider.OCSProvider.ReportStatus:output_type -> provider.ReportStatusResponse
 	11, // [11:19] is the sub-list for method output_type
 	3,  // [3:11] is the sub-list for method input_type
@@ -1340,7 +1343,7 @@ func file_provider_proto_init() {
 			}
 		}
 		file_provider_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*FulfillStorageClassClaimRequest); i {
+			switch v := v.(*FulfillStorageClaimRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1352,7 +1355,7 @@ func file_provider_proto_init() {
 			}
 		}
 		file_provider_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*FulfillStorageClassClaimResponse); i {
+			switch v := v.(*FulfillStorageClaimResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1364,7 +1367,7 @@ func file_provider_proto_init() {
 			}
 		}
 		file_provider_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*RevokeStorageClassClaimRequest); i {
+			switch v := v.(*RevokeStorageClaimRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1376,7 +1379,7 @@ func file_provider_proto_init() {
 			}
 		}
 		file_provider_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*RevokeStorageClassClaimResponse); i {
+			switch v := v.(*RevokeStorageClaimResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1388,7 +1391,7 @@ func file_provider_proto_init() {
 			}
 		}
 		file_provider_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*StorageClassClaimConfigRequest); i {
+			switch v := v.(*StorageClaimConfigRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1400,7 +1403,7 @@ func file_provider_proto_init() {
 			}
 		}
 		file_provider_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*StorageClassClaimConfigResponse); i {
+			switch v := v.(*StorageClaimConfigResponse); i {
 			case 0:
 				return &v.state
 			case 1:
diff --git a/vendor/github.com/red-hat-storage/ocs-operator/v4/services/provider/pb/provider_grpc.pb.go b/vendor/github.com/red-hat-storage/ocs-operator/v4/services/provider/pb/provider_grpc.pb.go
index b69cdfcb..64c45e2b 100644
--- a/vendor/github.com/red-hat-storage/ocs-operator/v4/services/provider/pb/provider_grpc.pb.go
+++ b/vendor/github.com/red-hat-storage/ocs-operator/v4/services/provider/pb/provider_grpc.pb.go
@@ -27,15 +27,15 @@ type OCSProviderClient interface {
 	OffboardConsumer(ctx context.Context, in *OffboardConsumerRequest, opts ...grpc.CallOption) (*OffboardConsumerResponse, error)
 	// AcknowledgeOnboarding RPC call acknowledge the onboarding
 	AcknowledgeOnboarding(ctx context.Context, in *AcknowledgeOnboardingRequest, opts ...grpc.CallOption) (*AcknowledgeOnboardingResponse, error)
-	// FulfillStorageClassClaim RPC call to create the StorageclassClaim CR on
+	// FulfillStorageClaim RPC call to create the StorageClaim CR on
 	// provider cluster.
-	FulfillStorageClassClaim(ctx context.Context, in *FulfillStorageClassClaimRequest, opts ...grpc.CallOption) (*FulfillStorageClassClaimResponse, error)
-	// RevokeStorageClassClaim RPC call to delete the StorageclassClaim CR
+	FulfillStorageClaim(ctx context.Context, in *FulfillStorageClaimRequest, opts ...grpc.CallOption) (*FulfillStorageClaimResponse, error)
+	// RevokeStorageClaim RPC call to delete the StorageClaim CR
 	// on provider cluster.
-	RevokeStorageClassClaim(ctx context.Context, in *RevokeStorageClassClaimRequest, opts ...grpc.CallOption) (*RevokeStorageClassClaimResponse, error)
-	// GetStorageClassClaimConfig RPC call to generate the json config for claim
+	RevokeStorageClaim(ctx context.Context, in *RevokeStorageClaimRequest, opts ...grpc.CallOption) (*RevokeStorageClaimResponse, error)
+	// GetStorageClaimConfig RPC call to generate the json config for claim
 	// specific resources.
-	GetStorageClassClaimConfig(ctx context.Context, in *StorageClassClaimConfigRequest, opts ...grpc.CallOption) (*StorageClassClaimConfigResponse, error)
+	GetStorageClaimConfig(ctx context.Context, in *StorageClaimConfigRequest, opts ...grpc.CallOption) (*StorageClaimConfigResponse, error)
 	ReportStatus(ctx context.Context, in *ReportStatusRequest, opts ...grpc.CallOption) (*ReportStatusResponse, error)
 }
 
@@ -83,27 +83,27 @@ func (c *oCSProviderClient) AcknowledgeOnboarding(ctx context.Context, in *Ackno
 	return out, nil
 }
 
-func (c *oCSProviderClient) FulfillStorageClassClaim(ctx context.Context, in *FulfillStorageClassClaimRequest, opts ...grpc.CallOption) (*FulfillStorageClassClaimResponse, error) {
-	out := new(FulfillStorageClassClaimResponse)
-	err := c.cc.Invoke(ctx, "/provider.OCSProvider/FulfillStorageClassClaim", in, out, opts...)
+func (c *oCSProviderClient) FulfillStorageClaim(ctx context.Context, in *FulfillStorageClaimRequest, opts ...grpc.CallOption) (*FulfillStorageClaimResponse, error) {
+	out := new(FulfillStorageClaimResponse)
+	err := c.cc.Invoke(ctx, "/provider.OCSProvider/FulfillStorageClaim", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
 	return out, nil
 }
 
-func (c *oCSProviderClient) RevokeStorageClassClaim(ctx context.Context, in *RevokeStorageClassClaimRequest, opts ...grpc.CallOption) (*RevokeStorageClassClaimResponse, error) {
-	out := new(RevokeStorageClassClaimResponse)
-	err := c.cc.Invoke(ctx, "/provider.OCSProvider/RevokeStorageClassClaim", in, out, opts...)
+func (c *oCSProviderClient) RevokeStorageClaim(ctx context.Context, in *RevokeStorageClaimRequest, opts ...grpc.CallOption) (*RevokeStorageClaimResponse, error) {
+	out := new(RevokeStorageClaimResponse)
+	err := c.cc.Invoke(ctx, "/provider.OCSProvider/RevokeStorageClaim", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
 	return out, nil
 }
 
-func (c *oCSProviderClient) GetStorageClassClaimConfig(ctx context.Context, in *StorageClassClaimConfigRequest, opts ...grpc.CallOption) (*StorageClassClaimConfigResponse, error) {
-	out := new(StorageClassClaimConfigResponse)
-	err := c.cc.Invoke(ctx, "/provider.OCSProvider/GetStorageClassClaimConfig", in, out, opts...)
+func (c *oCSProviderClient) GetStorageClaimConfig(ctx context.Context, in *StorageClaimConfigRequest, opts ...grpc.CallOption) (*StorageClaimConfigResponse, error) {
+	out := new(StorageClaimConfigResponse)
+	err := c.cc.Invoke(ctx, "/provider.OCSProvider/GetStorageClaimConfig", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -132,15 +132,15 @@ type OCSProviderServer interface {
 	OffboardConsumer(context.Context, *OffboardConsumerRequest) (*OffboardConsumerResponse, error)
 	// AcknowledgeOnboarding RPC call acknowledge the onboarding
 	AcknowledgeOnboarding(context.Context, *AcknowledgeOnboardingRequest) (*AcknowledgeOnboardingResponse, error)
-	// FulfillStorageClassClaim RPC call to create the StorageclassClaim CR on
+	// FulfillStorageClaim RPC call to create the StorageClaim CR on
 	// provider cluster.
-	FulfillStorageClassClaim(context.Context, *FulfillStorageClassClaimRequest) (*FulfillStorageClassClaimResponse, error)
-	// RevokeStorageClassClaim RPC call to delete the StorageclassClaim CR
+	FulfillStorageClaim(context.Context, *FulfillStorageClaimRequest) (*FulfillStorageClaimResponse, error)
+	// RevokeStorageClaim RPC call to delete the StorageClaim CR
 	// on provider cluster.
-	RevokeStorageClassClaim(context.Context, *RevokeStorageClassClaimRequest) (*RevokeStorageClassClaimResponse, error)
-	// GetStorageClassClaimConfig RPC call to generate the json config for claim
+	RevokeStorageClaim(context.Context, *RevokeStorageClaimRequest) (*RevokeStorageClaimResponse, error)
+	// GetStorageClaimConfig RPC call to generate the json config for claim
 	// specific resources.
-	GetStorageClassClaimConfig(context.Context, *StorageClassClaimConfigRequest) (*StorageClassClaimConfigResponse, error)
+	GetStorageClaimConfig(context.Context, *StorageClaimConfigRequest) (*StorageClaimConfigResponse, error)
 	ReportStatus(context.Context, *ReportStatusRequest) (*ReportStatusResponse, error)
 	mustEmbedUnimplementedOCSProviderServer()
 }
@@ -161,14 +161,14 @@ func (UnimplementedOCSProviderServer) OffboardConsumer(context.Context, *Offboar
 func (UnimplementedOCSProviderServer) AcknowledgeOnboarding(context.Context, *AcknowledgeOnboardingRequest) (*AcknowledgeOnboardingResponse, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method AcknowledgeOnboarding not implemented")
 }
-func (UnimplementedOCSProviderServer) FulfillStorageClassClaim(context.Context, *FulfillStorageClassClaimRequest) (*FulfillStorageClassClaimResponse, error) {
-	return nil, status.Errorf(codes.Unimplemented, "method FulfillStorageClassClaim not implemented")
+func (UnimplementedOCSProviderServer) FulfillStorageClaim(context.Context, *FulfillStorageClaimRequest) (*FulfillStorageClaimResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method FulfillStorageClaim not implemented")
 }
-func (UnimplementedOCSProviderServer) RevokeStorageClassClaim(context.Context, *RevokeStorageClassClaimRequest) (*RevokeStorageClassClaimResponse, error) {
-	return nil, status.Errorf(codes.Unimplemented, "method RevokeStorageClassClaim not implemented")
+func (UnimplementedOCSProviderServer) RevokeStorageClaim(context.Context, *RevokeStorageClaimRequest) (*RevokeStorageClaimResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method RevokeStorageClaim not implemented")
 }
-func (UnimplementedOCSProviderServer) GetStorageClassClaimConfig(context.Context, *StorageClassClaimConfigRequest) (*StorageClassClaimConfigResponse, error) {
-	return nil, status.Errorf(codes.Unimplemented, "method GetStorageClassClaimConfig not implemented")
+func (UnimplementedOCSProviderServer) GetStorageClaimConfig(context.Context, *StorageClaimConfigRequest) (*StorageClaimConfigResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetStorageClaimConfig not implemented")
 }
 func (UnimplementedOCSProviderServer) ReportStatus(context.Context, *ReportStatusRequest) (*ReportStatusResponse, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method ReportStatus not implemented")
@@ -258,56 +258,56 @@ func _OCSProvider_AcknowledgeOnboarding_Handler(srv interface{}, ctx context.Con
 	return interceptor(ctx, in, info, handler)
 }
 
-func _OCSProvider_FulfillStorageClassClaim_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(FulfillStorageClassClaimRequest)
+func _OCSProvider_FulfillStorageClaim_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(FulfillStorageClaimRequest)
 	if err := dec(in); err != nil {
 		return nil, err
 	}
 	if interceptor == nil {
-		return srv.(OCSProviderServer).FulfillStorageClassClaim(ctx, in)
+		return srv.(OCSProviderServer).FulfillStorageClaim(ctx, in)
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: "/provider.OCSProvider/FulfillStorageClassClaim",
+		FullMethod: "/provider.OCSProvider/FulfillStorageClaim",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(OCSProviderServer).FulfillStorageClassClaim(ctx, req.(*FulfillStorageClassClaimRequest))
+		return srv.(OCSProviderServer).FulfillStorageClaim(ctx, req.(*FulfillStorageClaimRequest))
 	}
 	return interceptor(ctx, in, info, handler)
 }
 
-func _OCSProvider_RevokeStorageClassClaim_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(RevokeStorageClassClaimRequest)
+func _OCSProvider_RevokeStorageClaim_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(RevokeStorageClaimRequest)
 	if err := dec(in); err != nil {
 		return nil, err
 	}
 	if interceptor == nil {
-		return srv.(OCSProviderServer).RevokeStorageClassClaim(ctx, in)
+		return srv.(OCSProviderServer).RevokeStorageClaim(ctx, in)
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: "/provider.OCSProvider/RevokeStorageClassClaim",
+		FullMethod: "/provider.OCSProvider/RevokeStorageClaim",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(OCSProviderServer).RevokeStorageClassClaim(ctx, req.(*RevokeStorageClassClaimRequest))
+		return srv.(OCSProviderServer).RevokeStorageClaim(ctx, req.(*RevokeStorageClaimRequest))
 	}
 	return interceptor(ctx, in, info, handler)
 }
 
-func _OCSProvider_GetStorageClassClaimConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(StorageClassClaimConfigRequest)
+func _OCSProvider_GetStorageClaimConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(StorageClaimConfigRequest)
 	if err := dec(in); err != nil {
 		return nil, err
 	}
 	if interceptor == nil {
-		return srv.(OCSProviderServer).GetStorageClassClaimConfig(ctx, in)
+		return srv.(OCSProviderServer).GetStorageClaimConfig(ctx, in)
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: "/provider.OCSProvider/GetStorageClassClaimConfig",
+		FullMethod: "/provider.OCSProvider/GetStorageClaimConfig",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(OCSProviderServer).GetStorageClassClaimConfig(ctx, req.(*StorageClassClaimConfigRequest))
+		return srv.(OCSProviderServer).GetStorageClaimConfig(ctx, req.(*StorageClaimConfigRequest))
 	}
 	return interceptor(ctx, in, info, handler)
 }
@@ -354,16 +354,16 @@ var OCSProvider_ServiceDesc = grpc.ServiceDesc{
 			Handler:    _OCSProvider_AcknowledgeOnboarding_Handler,
 		},
 		{
-			MethodName: "FulfillStorageClassClaim",
-			Handler:    _OCSProvider_FulfillStorageClassClaim_Handler,
+			MethodName: "FulfillStorageClaim",
+			Handler:    _OCSProvider_FulfillStorageClaim_Handler,
 		},
 		{
-			MethodName: "RevokeStorageClassClaim",
-			Handler:    _OCSProvider_RevokeStorageClassClaim_Handler,
+			MethodName: "RevokeStorageClaim",
+			Handler:    _OCSProvider_RevokeStorageClaim_Handler,
 		},
 		{
-			MethodName: "GetStorageClassClaimConfig",
-			Handler:    _OCSProvider_GetStorageClassClaimConfig_Handler,
+			MethodName: "GetStorageClaimConfig",
+			Handler:    _OCSProvider_GetStorageClaimConfig_Handler,
 		},
 		{
 			MethodName: "ReportStatus",
diff --git a/vendor/github.com/red-hat-storage/ocs-operator/v4/services/provider/pb/storageclient.go b/vendor/github.com/red-hat-storage/ocs-operator/v4/services/provider/pb/storageclient.go
index 809671f7..f65ff70d 100644
--- a/vendor/github.com/red-hat-storage/ocs-operator/v4/services/provider/pb/storageclient.go
+++ b/vendor/github.com/red-hat-storage/ocs-operator/v4/services/provider/pb/storageclient.go
@@ -30,8 +30,13 @@ func (r *ReportStatusRequest) SetClusterID(clusterID string) ifaces.StorageClien
 	return r
 }
 
-func (r *ReportStatusRequest) SetNamespacedName(namespacedName string) ifaces.StorageClientStatus {
-	r.NamespacedName = namespacedName
+func (r *ReportStatusRequest) SetClientName(clientName string) ifaces.StorageClientStatus {
+	r.ClientName = clientName
+	return r
+}
+
+func (r *ReportStatusRequest) SetClusterName(clusterName string) ifaces.StorageClientStatus {
+	r.ClusterName = clusterName
 	return r
 }
 
diff --git a/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go b/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go
index 59548011..856c75dd 100644
--- a/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go
+++ b/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go
@@ -18,8 +18,8 @@
 
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.31.0
-// 	protoc        v4.22.0
+// 	protoc-gen-go v1.32.0
+// 	protoc        v4.25.2
 // source: grpc/binlog/v1/binarylog.proto
 
 package grpc_binarylog_v1
@@ -430,7 +430,7 @@ type ClientHeader struct {
 	MethodName string `protobuf:"bytes,2,opt,name=method_name,json=methodName,proto3" json:"method_name,omitempty"`
 	// A single process may be used to run multiple virtual
 	// servers with different identities.
-	// The authority is the name of such a server identitiy.
+	// The authority is the name of such a server identity.
 	// It is typically a portion of the URI in the form of
 	// <host> or <host>:<port> .
 	Authority string `protobuf:"bytes,3,opt,name=authority,proto3" json:"authority,omitempty"`
diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go
index e6f2625b..f0b7f320 100644
--- a/vendor/google.golang.org/grpc/clientconn.go
+++ b/vendor/google.golang.org/grpc/clientconn.go
@@ -1772,6 +1772,8 @@ func parseTarget(target string) (resolver.Target, error) {
 	return resolver.Target{URL: *u}, nil
 }
 
+// encodeAuthority escapes the authority string based on valid chars defined in
+// https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.
 func encodeAuthority(authority string) string {
 	const upperhex = "0123456789ABCDEF"
 
@@ -1860,27 +1862,15 @@ func (cc *ClientConn) determineAuthority() error {
 	}
 
 	endpoint := cc.parsedTarget.Endpoint()
-	target := cc.target
-	switch {
-	case authorityFromDialOption != "":
+	if authorityFromDialOption != "" {
 		cc.authority = authorityFromDialOption
-	case authorityFromCreds != "":
+	} else if authorityFromCreds != "" {
 		cc.authority = authorityFromCreds
-	case strings.HasPrefix(target, "unix:") || strings.HasPrefix(target, "unix-abstract:"):
-		// TODO: remove when the unix resolver implements optional interface to
-		// return channel authority.
-		cc.authority = "localhost"
-	case strings.HasPrefix(endpoint, ":"):
+	} else if auth, ok := cc.resolverBuilder.(resolver.AuthorityOverrider); ok {
+		cc.authority = auth.OverrideAuthority(cc.parsedTarget)
+	} else if strings.HasPrefix(endpoint, ":") {
 		cc.authority = "localhost" + endpoint
-	default:
-		// TODO: Define an optional interface on the resolver builder to return
-		// the channel authority given the user's dial target. For resolvers
-		// which don't implement this interface, we will use the endpoint from
-		// "scheme://authority/endpoint" as the default authority.
-		// Escape the endpoint to handle use cases where the endpoint
-		// might not be a valid authority by default.
-		// For example an endpoint which has multiple paths like
-		// 'a/b/c', which is not a valid authority by default.
+	} else {
 		cc.authority = encodeAuthority(endpoint)
 	}
 	channelz.Infof(logger, cc.channelzID, "Channel authority set to %q", cc.authority)
diff --git a/vendor/google.golang.org/grpc/encoding/proto/proto.go b/vendor/google.golang.org/grpc/encoding/proto/proto.go
index 0ee3d3ba..66d5cdf0 100644
--- a/vendor/google.golang.org/grpc/encoding/proto/proto.go
+++ b/vendor/google.golang.org/grpc/encoding/proto/proto.go
@@ -23,8 +23,9 @@ package proto
 import (
 	"fmt"
 
-	"github.com/golang/protobuf/proto"
 	"google.golang.org/grpc/encoding"
+	"google.golang.org/protobuf/proto"
+	"google.golang.org/protobuf/protoadapt"
 )
 
 // Name is the name registered for the proto compressor.
@@ -38,21 +39,34 @@ func init() {
 type codec struct{}
 
 func (codec) Marshal(v any) ([]byte, error) {
-	vv, ok := v.(proto.Message)
-	if !ok {
+	vv := messageV2Of(v)
+	if vv == nil {
 		return nil, fmt.Errorf("failed to marshal, message is %T, want proto.Message", v)
 	}
+
 	return proto.Marshal(vv)
 }
 
 func (codec) Unmarshal(data []byte, v any) error {
-	vv, ok := v.(proto.Message)
-	if !ok {
+	vv := messageV2Of(v)
+	if vv == nil {
 		return fmt.Errorf("failed to unmarshal, message is %T, want proto.Message", v)
 	}
+
 	return proto.Unmarshal(data, vv)
 }
 
+func messageV2Of(v any) proto.Message {
+	switch v := v.(type) {
+	case protoadapt.MessageV1:
+		return protoadapt.MessageV2Of(v)
+	case protoadapt.MessageV2:
+		return v
+	}
+
+	return nil
+}
+
 func (codec) Name() string {
 	return Name
 }
diff --git a/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go b/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go
index 0f31274a..e8456a77 100644
--- a/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go
+++ b/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go
@@ -25,11 +25,12 @@ import (
 	"sync/atomic"
 	"time"
 
-	"github.com/golang/protobuf/proto"
-	"github.com/golang/protobuf/ptypes"
 	binlogpb "google.golang.org/grpc/binarylog/grpc_binarylog_v1"
 	"google.golang.org/grpc/metadata"
 	"google.golang.org/grpc/status"
+	"google.golang.org/protobuf/proto"
+	"google.golang.org/protobuf/types/known/durationpb"
+	"google.golang.org/protobuf/types/known/timestamppb"
 )
 
 type callIDGenerator struct {
@@ -88,7 +89,7 @@ func NewTruncatingMethodLogger(h, m uint64) *TruncatingMethodLogger {
 // in TruncatingMethodLogger as possible.
 func (ml *TruncatingMethodLogger) Build(c LogEntryConfig) *binlogpb.GrpcLogEntry {
 	m := c.toProto()
-	timestamp, _ := ptypes.TimestampProto(time.Now())
+	timestamp := timestamppb.Now()
 	m.Timestamp = timestamp
 	m.CallId = ml.callID
 	m.SequenceIdWithinCall = ml.idWithinCallGen.next()
@@ -178,7 +179,7 @@ func (c *ClientHeader) toProto() *binlogpb.GrpcLogEntry {
 		Authority:  c.Authority,
 	}
 	if c.Timeout > 0 {
-		clientHeader.Timeout = ptypes.DurationProto(c.Timeout)
+		clientHeader.Timeout = durationpb.New(c.Timeout)
 	}
 	ret := &binlogpb.GrpcLogEntry{
 		Type: binlogpb.GrpcLogEntry_EVENT_TYPE_CLIENT_HEADER,
diff --git a/vendor/google.golang.org/grpc/internal/binarylog/sink.go b/vendor/google.golang.org/grpc/internal/binarylog/sink.go
index 264de387..9ea598b1 100644
--- a/vendor/google.golang.org/grpc/internal/binarylog/sink.go
+++ b/vendor/google.golang.org/grpc/internal/binarylog/sink.go
@@ -25,8 +25,8 @@ import (
 	"sync"
 	"time"
 
-	"github.com/golang/protobuf/proto"
 	binlogpb "google.golang.org/grpc/binarylog/grpc_binarylog_v1"
+	"google.golang.org/protobuf/proto"
 )
 
 var (
diff --git a/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go b/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go
index aa97273e..0126d6b5 100644
--- a/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go
+++ b/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go
@@ -1,3 +1,8 @@
+//go:build !go1.21
+
+// TODO: when this file is deleted (after Go 1.20 support is dropped), delete
+// all of grpcrand and call the rand package directly.
+
 /*
  *
  * Copyright 2018 gRPC authors.
diff --git a/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand_go1.21.go b/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand_go1.21.go
new file mode 100644
index 00000000..c37299af
--- /dev/null
+++ b/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand_go1.21.go
@@ -0,0 +1,73 @@
+//go:build go1.21
+
+/*
+ *
+ * Copyright 2024 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package grpcrand implements math/rand functions in a concurrent-safe way
+// with a global random source, independent of math/rand's global source.
+package grpcrand
+
+import "math/rand"
+
+// This implementation will be used for Go version 1.21 or newer.
+// For older versions, the original implementation with mutex will be used.
+
+// Int implements rand.Int on the grpcrand global source.
+func Int() int {
+	return rand.Int()
+}
+
+// Int63n implements rand.Int63n on the grpcrand global source.
+func Int63n(n int64) int64 {
+	return rand.Int63n(n)
+}
+
+// Intn implements rand.Intn on the grpcrand global source.
+func Intn(n int) int {
+	return rand.Intn(n)
+}
+
+// Int31n implements rand.Int31n on the grpcrand global source.
+func Int31n(n int32) int32 {
+	return rand.Int31n(n)
+}
+
+// Float64 implements rand.Float64 on the grpcrand global source.
+func Float64() float64 {
+	return rand.Float64()
+}
+
+// Uint64 implements rand.Uint64 on the grpcrand global source.
+func Uint64() uint64 {
+	return rand.Uint64()
+}
+
+// Uint32 implements rand.Uint32 on the grpcrand global source.
+func Uint32() uint32 {
+	return rand.Uint32()
+}
+
+// ExpFloat64 implements rand.ExpFloat64 on the grpcrand global source.
+func ExpFloat64() float64 {
+	return rand.ExpFloat64()
+}
+
+// Shuffle implements rand.Shuffle on the grpcrand global source.
+var Shuffle = func(n int, f func(int, int)) {
+	rand.Shuffle(n, f)
+}
diff --git a/vendor/google.golang.org/grpc/internal/internal.go b/vendor/google.golang.org/grpc/internal/internal.go
index 2549fe8e..6c7ea6a5 100644
--- a/vendor/google.golang.org/grpc/internal/internal.go
+++ b/vendor/google.golang.org/grpc/internal/internal.go
@@ -57,7 +57,7 @@ var (
 	// GetXDSHandshakeInfoForTesting returns a pointer to the xds.HandshakeInfo
 	// stored in the passed in attributes. This is set by
 	// credentials/xds/xds.go.
-	GetXDSHandshakeInfoForTesting any // func (*attributes.Attributes) *xds.HandshakeInfo
+	GetXDSHandshakeInfoForTesting any // func (*attributes.Attributes) *unsafe.Pointer
 	// GetServerCredentials returns the transport credentials configured on a
 	// gRPC server. An xDS-enabled server needs to know what type of credentials
 	// is configured on the underlying gRPC server. This is set by server.go.
@@ -68,11 +68,6 @@ var (
 	// This is used in the 1.0 release of gcp/observability, and thus must not be
 	// deleted or changed.
 	CanonicalString any // func (codes.Code) string
-	// DrainServerTransports initiates a graceful close of existing connections
-	// on a gRPC server accepted on the provided listener address. An
-	// xDS-enabled server invokes this method on a grpc.Server when a particular
-	// listener moves to "not-serving" mode.
-	DrainServerTransports any // func(*grpc.Server, string)
 	// IsRegisteredMethod returns whether the passed in method is registered as
 	// a method on the server.
 	IsRegisteredMethod any // func(*grpc.Server, string) bool
@@ -188,6 +183,19 @@ var (
 	ExitIdleModeForTesting any // func(*grpc.ClientConn) error
 
 	ChannelzTurnOffForTesting func()
+
+	// TriggerXDSResourceNameNotFoundForTesting triggers the resource-not-found
+	// error for a given resource type and name. This is usually triggered when
+	// the associated watch timer fires. For testing purposes, having this
+	// function makes events more predictable than relying on timer events.
+	TriggerXDSResourceNameNotFoundForTesting any // func(func(xdsresource.Type, string), string, string) error
+
+	// TriggerXDSResourceNotFoundClient invokes the testing xDS Client singleton
+	// to invoke resource not found for a resource type name and resource name.
+	TriggerXDSResourceNameNotFoundClient any // func(string, string) error
+
+	// FromOutgoingContextRaw returns the un-merged, intermediary contents of metadata.rawMD.
+	FromOutgoingContextRaw any // func(context.Context) (metadata.MD, [][]string, bool)
 )
 
 // HealthChecker defines the signature of the client-side LB channel health checking function.
diff --git a/vendor/google.golang.org/grpc/internal/pretty/pretty.go b/vendor/google.golang.org/grpc/internal/pretty/pretty.go
index 70331913..52cfab1b 100644
--- a/vendor/google.golang.org/grpc/internal/pretty/pretty.go
+++ b/vendor/google.golang.org/grpc/internal/pretty/pretty.go
@@ -24,7 +24,6 @@ import (
 	"encoding/json"
 	"fmt"
 
-	"github.com/golang/protobuf/jsonpb"
 	protov1 "github.com/golang/protobuf/proto"
 	"google.golang.org/protobuf/encoding/protojson"
 	protov2 "google.golang.org/protobuf/proto"
@@ -38,15 +37,15 @@ const jsonIndent = "  "
 func ToJSON(e any) string {
 	switch ee := e.(type) {
 	case protov1.Message:
-		mm := jsonpb.Marshaler{Indent: jsonIndent}
-		ret, err := mm.MarshalToString(ee)
+		mm := protojson.MarshalOptions{Indent: jsonIndent}
+		ret, err := mm.Marshal(protov1.MessageV2(ee))
 		if err != nil {
 			// This may fail for proto.Anys, e.g. for xDS v2, LDS, the v2
 			// messages are not imported, and this will fail because the message
 			// is not found.
 			return fmt.Sprintf("%+v", ee)
 		}
-		return ret
+		return string(ret)
 	case protov2.Message:
 		mm := protojson.MarshalOptions{
 			Multiline: true,
diff --git a/vendor/google.golang.org/grpc/internal/resolver/unix/unix.go b/vendor/google.golang.org/grpc/internal/resolver/unix/unix.go
index 16091168..27cd81af 100644
--- a/vendor/google.golang.org/grpc/internal/resolver/unix/unix.go
+++ b/vendor/google.golang.org/grpc/internal/resolver/unix/unix.go
@@ -61,6 +61,10 @@ func (b *builder) Scheme() string {
 	return b.scheme
 }
 
+func (b *builder) OverrideAuthority(resolver.Target) string {
+	return "localhost"
+}
+
 type nopResolver struct {
 }
 
diff --git a/vendor/google.golang.org/grpc/internal/status/status.go b/vendor/google.golang.org/grpc/internal/status/status.go
index 03ef2fed..c7dbc820 100644
--- a/vendor/google.golang.org/grpc/internal/status/status.go
+++ b/vendor/google.golang.org/grpc/internal/status/status.go
@@ -31,10 +31,11 @@ import (
 	"errors"
 	"fmt"
 
-	"github.com/golang/protobuf/proto"
-	"github.com/golang/protobuf/ptypes"
 	spb "google.golang.org/genproto/googleapis/rpc/status"
 	"google.golang.org/grpc/codes"
+	"google.golang.org/protobuf/proto"
+	"google.golang.org/protobuf/protoadapt"
+	"google.golang.org/protobuf/types/known/anypb"
 )
 
 // Status represents an RPC status code, message, and details.  It is immutable
@@ -130,14 +131,14 @@ func (s *Status) Err() error {
 
 // WithDetails returns a new status with the provided details messages appended to the status.
 // If any errors are encountered, it returns nil and the first error encountered.
-func (s *Status) WithDetails(details ...proto.Message) (*Status, error) {
+func (s *Status) WithDetails(details ...protoadapt.MessageV1) (*Status, error) {
 	if s.Code() == codes.OK {
 		return nil, errors.New("no error details for status with code OK")
 	}
 	// s.Code() != OK implies that s.Proto() != nil.
 	p := s.Proto()
 	for _, detail := range details {
-		any, err := ptypes.MarshalAny(detail)
+		any, err := anypb.New(protoadapt.MessageV2Of(detail))
 		if err != nil {
 			return nil, err
 		}
@@ -154,12 +155,12 @@ func (s *Status) Details() []any {
 	}
 	details := make([]any, 0, len(s.s.Details))
 	for _, any := range s.s.Details {
-		detail := &ptypes.DynamicAny{}
-		if err := ptypes.UnmarshalAny(any, detail); err != nil {
+		detail, err := any.UnmarshalNew()
+		if err != nil {
 			details = append(details, err)
 			continue
 		}
-		details = append(details, detail.Message)
+		details = append(details, detail)
 	}
 	return details
 }
diff --git a/vendor/google.golang.org/grpc/internal/tcp_keepalive_nonunix.go b/vendor/google.golang.org/grpc/internal/tcp_keepalive_others.go
similarity index 96%
rename from vendor/google.golang.org/grpc/internal/tcp_keepalive_nonunix.go
rename to vendor/google.golang.org/grpc/internal/tcp_keepalive_others.go
index aeffd3e1..4f347edd 100644
--- a/vendor/google.golang.org/grpc/internal/tcp_keepalive_nonunix.go
+++ b/vendor/google.golang.org/grpc/internal/tcp_keepalive_others.go
@@ -1,4 +1,4 @@
-//go:build !unix
+//go:build !unix && !windows
 
 /*
  * Copyright 2023 gRPC authors.
diff --git a/vendor/google.golang.org/grpc/internal/tcp_keepalive_windows.go b/vendor/google.golang.org/grpc/internal/tcp_keepalive_windows.go
new file mode 100644
index 00000000..fd7d43a8
--- /dev/null
+++ b/vendor/google.golang.org/grpc/internal/tcp_keepalive_windows.go
@@ -0,0 +1,54 @@
+//go:build windows
+
+/*
+ * Copyright 2023 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package internal
+
+import (
+	"net"
+	"syscall"
+	"time"
+
+	"golang.org/x/sys/windows"
+)
+
+// NetDialerWithTCPKeepalive returns a net.Dialer that enables TCP keepalives on
+// the underlying connection with OS default values for keepalive parameters.
+//
+// TODO: Once https://github.com/golang/go/issues/62254 lands, and the
+// appropriate Go version becomes less than our least supported Go version, we
+// should look into using the new API to make things more straightforward.
+func NetDialerWithTCPKeepalive() *net.Dialer {
+	return &net.Dialer{
+		// Setting a negative value here prevents the Go stdlib from overriding
+		// the values of TCP keepalive time and interval. It also prevents the
+		// Go stdlib from enabling TCP keepalives by default.
+		KeepAlive: time.Duration(-1),
+		// This method is called after the underlying network socket is created,
+		// but before dialing the socket (or calling its connect() method). The
+		// combination of unconditionally enabling TCP keepalives here, and
+		// disabling the overriding of TCP keepalive parameters by setting the
+		// KeepAlive field to a negative value above, results in OS defaults for
+		// the TCP keealive interval and time parameters.
+		Control: func(_, _ string, c syscall.RawConn) error {
+			return c.Control(func(fd uintptr) {
+				windows.SetsockoptInt(windows.Handle(fd), windows.SOL_SOCKET, windows.SO_KEEPALIVE, 1)
+			})
+		},
+	}
+}
diff --git a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go
index b330cced..83c38298 100644
--- a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go
+++ b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go
@@ -535,8 +535,8 @@ const minBatchSize = 1000
 // size is too low to give stream goroutines a chance to fill it up.
 //
 // Upon exiting, if the error causing the exit is not an I/O error, run()
-// flushes and closes the underlying connection.  Otherwise, the connection is
-// left open to allow the I/O error to be encountered by the reader instead.
+// flushes the underlying connection.  The connection is always left open to
+// allow different closing behavior on the client and server.
 func (l *loopyWriter) run() (err error) {
 	defer func() {
 		if l.logger.V(logLevel) {
@@ -544,7 +544,6 @@ func (l *loopyWriter) run() (err error) {
 		}
 		if !isIOError(err) {
 			l.framer.writer.Flush()
-			l.conn.Close()
 		}
 		l.cbuf.finish()
 	}()
diff --git a/vendor/google.golang.org/grpc/internal/transport/handler_server.go b/vendor/google.golang.org/grpc/internal/transport/handler_server.go
index a9d70e2a..bd39ff9a 100644
--- a/vendor/google.golang.org/grpc/internal/transport/handler_server.go
+++ b/vendor/google.golang.org/grpc/internal/transport/handler_server.go
@@ -35,7 +35,6 @@ import (
 	"sync"
 	"time"
 
-	"github.com/golang/protobuf/proto"
 	"golang.org/x/net/http2"
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/credentials"
@@ -45,6 +44,7 @@ import (
 	"google.golang.org/grpc/peer"
 	"google.golang.org/grpc/stats"
 	"google.golang.org/grpc/status"
+	"google.golang.org/protobuf/proto"
 )
 
 // NewServerHandlerTransport returns a ServerTransport handling gRPC from
diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_client.go b/vendor/google.golang.org/grpc/internal/transport/http2_client.go
index 59f67655..eff87996 100644
--- a/vendor/google.golang.org/grpc/internal/transport/http2_client.go
+++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go
@@ -59,6 +59,8 @@ import (
 // atomically.
 var clientConnectionCounter uint64
 
+var metadataFromOutgoingContextRaw = internal.FromOutgoingContextRaw.(func(context.Context) (metadata.MD, [][]string, bool))
+
 // http2Client implements the ClientTransport interface with HTTP2.
 type http2Client struct {
 	lastRead  int64 // Keep this field 64-bit aligned. Accessed atomically.
@@ -449,7 +451,13 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
 	}
 	go func() {
 		t.loopy = newLoopyWriter(clientSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger)
-		t.loopy.run()
+		if err := t.loopy.run(); !isIOError(err) {
+			// Immediately close the connection, as the loopy writer returns
+			// when there are no more active streams and we were draining (the
+			// server sent a GOAWAY).  For I/O errors, the reader will hit it
+			// after draining any remaining incoming data.
+			t.conn.Close()
+		}
 		close(t.writerDone)
 	}()
 	return t, nil
@@ -568,7 +576,7 @@ func (t *http2Client) createHeaderFields(ctx context.Context, callHdr *CallHdr)
 		headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-trace-bin", Value: encodeBinHeader(b)})
 	}
 
-	if md, added, ok := metadata.FromOutgoingContextRaw(ctx); ok {
+	if md, added, ok := metadataFromOutgoingContextRaw(ctx); ok {
 		var k string
 		for k, vv := range md {
 			// HTTP doesn't allow you to set pseudoheaders after non pseudoheaders were set.
@@ -1323,10 +1331,8 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) {
 	for streamID, stream := range t.activeStreams {
 		if streamID > id && streamID <= upperLimit {
 			// The stream was unprocessed by the server.
-			if streamID > id && streamID <= upperLimit {
-				atomic.StoreUint32(&stream.unprocessed, 1)
-				streamsToClose = append(streamsToClose, stream)
-			}
+			atomic.StoreUint32(&stream.unprocessed, 1)
+			streamsToClose = append(streamsToClose, stream)
 		}
 	}
 	t.mu.Unlock()
diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_server.go b/vendor/google.golang.org/grpc/internal/transport/http2_server.go
index 680c9eba..3839c1ad 100644
--- a/vendor/google.golang.org/grpc/internal/transport/http2_server.go
+++ b/vendor/google.golang.org/grpc/internal/transport/http2_server.go
@@ -32,13 +32,13 @@ import (
 	"sync/atomic"
 	"time"
 
-	"github.com/golang/protobuf/proto"
 	"golang.org/x/net/http2"
 	"golang.org/x/net/http2/hpack"
 	"google.golang.org/grpc/internal/grpclog"
 	"google.golang.org/grpc/internal/grpcutil"
 	"google.golang.org/grpc/internal/pretty"
 	"google.golang.org/grpc/internal/syscall"
+	"google.golang.org/protobuf/proto"
 
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/credentials"
@@ -322,8 +322,24 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
 	go func() {
 		t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger)
 		t.loopy.ssGoAwayHandler = t.outgoingGoAwayHandler
-		t.loopy.run()
+		err := t.loopy.run()
 		close(t.loopyWriterDone)
+		if !isIOError(err) {
+			// Close the connection if a non-I/O error occurs (for I/O errors
+			// the reader will also encounter the error and close).  Wait 1
+			// second before closing the connection, or when the reader is done
+			// (i.e. the client already closed the connection or a connection
+			// error occurred).  This avoids the potential problem where there
+			// is unread data on the receive side of the connection, which, if
+			// closed, would lead to a TCP RST instead of FIN, and the client
+			// encountering errors.  For more info:
+			// https://github.com/grpc/grpc-go/issues/5358
+			select {
+			case <-t.readerDone:
+			case <-time.After(time.Second):
+			}
+			t.conn.Close()
+		}
 	}()
 	go t.keepalive()
 	return t, nil
@@ -609,8 +625,8 @@ func (t *http2Server) operateHeaders(ctx context.Context, frame *http2.MetaHeade
 // traceCtx attaches trace to ctx and returns the new context.
 func (t *http2Server) HandleStreams(ctx context.Context, handle func(*Stream)) {
 	defer func() {
-		<-t.loopyWriterDone
 		close(t.readerDone)
+		<-t.loopyWriterDone
 	}()
 	for {
 		t.controlBuf.throttle()
@@ -636,10 +652,6 @@ func (t *http2Server) HandleStreams(ctx context.Context, handle func(*Stream)) {
 				}
 				continue
 			}
-			if err == io.EOF || err == io.ErrUnexpectedEOF {
-				t.Close(err)
-				return
-			}
 			t.Close(err)
 			return
 		}
@@ -960,7 +972,12 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error {
 		}
 	}
 	if err := t.writeHeaderLocked(s); err != nil {
-		return status.Convert(err).Err()
+		switch e := err.(type) {
+		case ConnectionError:
+			return status.Error(codes.Unavailable, e.Desc)
+		default:
+			return status.Convert(err).Err()
+		}
 	}
 	return nil
 }
@@ -1324,6 +1341,7 @@ func (t *http2Server) outgoingGoAwayHandler(g *goAway) (bool, error) {
 		if err := t.framer.fr.WriteGoAway(sid, g.code, g.debugData); err != nil {
 			return false, err
 		}
+		t.framer.writer.Flush()
 		if retErr != nil {
 			return false, retErr
 		}
@@ -1344,7 +1362,7 @@ func (t *http2Server) outgoingGoAwayHandler(g *goAway) (bool, error) {
 		return false, err
 	}
 	go func() {
-		timer := time.NewTimer(time.Minute)
+		timer := time.NewTimer(5 * time.Second)
 		defer timer.Stop()
 		select {
 		case <-t.drainEvent.Done():
diff --git a/vendor/google.golang.org/grpc/internal/transport/transport.go b/vendor/google.golang.org/grpc/internal/transport/transport.go
index b7b8fec1..d3796c25 100644
--- a/vendor/google.golang.org/grpc/internal/transport/transport.go
+++ b/vendor/google.golang.org/grpc/internal/transport/transport.go
@@ -28,6 +28,7 @@ import (
 	"fmt"
 	"io"
 	"net"
+	"strings"
 	"sync"
 	"sync/atomic"
 	"time"
@@ -362,8 +363,12 @@ func (s *Stream) SendCompress() string {
 
 // ClientAdvertisedCompressors returns the compressor names advertised by the
 // client via grpc-accept-encoding header.
-func (s *Stream) ClientAdvertisedCompressors() string {
-	return s.clientAdvertisedCompressors
+func (s *Stream) ClientAdvertisedCompressors() []string {
+	values := strings.Split(s.clientAdvertisedCompressors, ",")
+	for i, v := range values {
+		values[i] = strings.TrimSpace(v)
+	}
+	return values
 }
 
 // Done returns a channel which is closed when it receives the final status
diff --git a/vendor/google.golang.org/grpc/metadata/metadata.go b/vendor/google.golang.org/grpc/metadata/metadata.go
index 49446825..1e9485fd 100644
--- a/vendor/google.golang.org/grpc/metadata/metadata.go
+++ b/vendor/google.golang.org/grpc/metadata/metadata.go
@@ -25,8 +25,14 @@ import (
 	"context"
 	"fmt"
 	"strings"
+
+	"google.golang.org/grpc/internal"
 )
 
+func init() {
+	internal.FromOutgoingContextRaw = fromOutgoingContextRaw
+}
+
 // DecodeKeyValue returns k, v, nil.
 //
 // Deprecated: use k and v directly instead.
@@ -238,16 +244,13 @@ func copyOf(v []string) []string {
 	return vals
 }
 
-// FromOutgoingContextRaw returns the un-merged, intermediary contents of rawMD.
+// fromOutgoingContextRaw returns the un-merged, intermediary contents of rawMD.
 //
 // Remember to perform strings.ToLower on the keys, for both the returned MD (MD
 // is a map, there's no guarantee it's created using our helper functions) and
 // the extra kv pairs (AppendToOutgoingContext doesn't turn them into
 // lowercase).
-//
-// This is intended for gRPC-internal use ONLY. Users should use
-// FromOutgoingContext instead.
-func FromOutgoingContextRaw(ctx context.Context) (MD, [][]string, bool) {
+func fromOutgoingContextRaw(ctx context.Context) (MD, [][]string, bool) {
 	raw, ok := ctx.Value(mdOutgoingKey{}).(rawMD)
 	if !ok {
 		return nil, nil, false
diff --git a/vendor/google.golang.org/grpc/resolver/resolver.go b/vendor/google.golang.org/grpc/resolver/resolver.go
index bd1c7d01..d72f21c1 100644
--- a/vendor/google.golang.org/grpc/resolver/resolver.go
+++ b/vendor/google.golang.org/grpc/resolver/resolver.go
@@ -168,6 +168,9 @@ type BuildOptions struct {
 	// field. In most cases though, it is not appropriate, and this field may
 	// be ignored.
 	Dialer func(context.Context, string) (net.Conn, error)
+	// Authority is the effective authority of the clientconn for which the
+	// resolver is built.
+	Authority string
 }
 
 // An Endpoint is one network endpoint, or server, which may have multiple
@@ -314,3 +317,13 @@ type Resolver interface {
 	// Close closes the resolver.
 	Close()
 }
+
+// AuthorityOverrider is implemented by Builders that wish to override the
+// default authority for the ClientConn.
+// By default, the authority used is target.Endpoint().
+type AuthorityOverrider interface {
+	// OverrideAuthority returns the authority to use for a ClientConn with the
+	// given target. The implementation must generate it without blocking,
+	// typically in line, and must keep it unchanged.
+	OverrideAuthority(Target) string
+}
diff --git a/vendor/google.golang.org/grpc/resolver_wrapper.go b/vendor/google.golang.org/grpc/resolver_wrapper.go
index c79bab12..f845ac95 100644
--- a/vendor/google.golang.org/grpc/resolver_wrapper.go
+++ b/vendor/google.golang.org/grpc/resolver_wrapper.go
@@ -75,6 +75,7 @@ func (ccr *ccResolverWrapper) start() error {
 			DialCreds:            ccr.cc.dopts.copts.TransportCredentials,
 			CredsBundle:          ccr.cc.dopts.copts.CredsBundle,
 			Dialer:               ccr.cc.dopts.copts.Dialer,
+			Authority:            ccr.cc.authority,
 		}
 		var err error
 		ccr.resolver, err = ccr.cc.resolverBuilder.Build(ccr.cc.parsedTarget, ccr, opts)
diff --git a/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go
index b7723aa0..82493d23 100644
--- a/vendor/google.golang.org/grpc/rpc_util.go
+++ b/vendor/google.golang.org/grpc/rpc_util.go
@@ -189,6 +189,20 @@ type EmptyCallOption struct{}
 func (EmptyCallOption) before(*callInfo) error      { return nil }
 func (EmptyCallOption) after(*callInfo, *csAttempt) {}
 
+// StaticMethod returns a CallOption which specifies that a call is being made
+// to a method that is static, which means the method is known at compile time
+// and doesn't change at runtime. This can be used as a signal to stats plugins
+// that this method is safe to include as a key to a measurement.
+func StaticMethod() CallOption {
+	return StaticMethodCallOption{}
+}
+
+// StaticMethodCallOption is a CallOption that specifies that a call comes
+// from a static method.
+type StaticMethodCallOption struct {
+	EmptyCallOption
+}
+
 // Header returns a CallOptions that retrieves the header metadata
 // for a unary RPC.
 func Header(md *metadata.MD) CallOption {
@@ -640,14 +654,18 @@ func encode(c baseCodec, msg any) ([]byte, error) {
 	return b, nil
 }
 
-// compress returns the input bytes compressed by compressor or cp.  If both
-// compressors are nil, returns nil.
+// compress returns the input bytes compressed by compressor or cp.
+// If both compressors are nil, or if the message has zero length, returns nil,
+// indicating no compression was done.
 //
 // TODO(dfawley): eliminate cp parameter by wrapping Compressor in an encoding.Compressor.
 func compress(in []byte, cp Compressor, compressor encoding.Compressor) ([]byte, error) {
 	if compressor == nil && cp == nil {
 		return nil, nil
 	}
+	if len(in) == 0 {
+		return nil, nil
+	}
 	wrapErr := func(err error) error {
 		return status.Errorf(codes.Internal, "grpc: error while compressing: %v", err.Error())
 	}
@@ -726,17 +744,19 @@ type payloadInfo struct {
 	uncompressedBytes []byte
 }
 
-func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor) ([]byte, error) {
-	pf, buf, err := p.recvMsg(maxReceiveMessageSize)
+// recvAndDecompress reads a message from the stream, decompressing it if necessary.
+//
+// Cancelling the returned cancel function releases the buffer back to the pool. So the caller should cancel as soon as
+// the buffer is no longer needed.
+func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor,
+) (uncompressedBuf []byte, cancel func(), err error) {
+	pf, compressedBuf, err := p.recvMsg(maxReceiveMessageSize)
 	if err != nil {
-		return nil, err
-	}
-	if payInfo != nil {
-		payInfo.compressedLength = len(buf)
+		return nil, nil, err
 	}
 
 	if st := checkRecvPayload(pf, s.RecvCompress(), compressor != nil || dc != nil); st != nil {
-		return nil, st.Err()
+		return nil, nil, st.Err()
 	}
 
 	var size int
@@ -744,21 +764,35 @@ func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxRecei
 		// To match legacy behavior, if the decompressor is set by WithDecompressor or RPCDecompressor,
 		// use this decompressor as the default.
 		if dc != nil {
-			buf, err = dc.Do(bytes.NewReader(buf))
-			size = len(buf)
+			uncompressedBuf, err = dc.Do(bytes.NewReader(compressedBuf))
+			size = len(uncompressedBuf)
 		} else {
-			buf, size, err = decompress(compressor, buf, maxReceiveMessageSize)
+			uncompressedBuf, size, err = decompress(compressor, compressedBuf, maxReceiveMessageSize)
 		}
 		if err != nil {
-			return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message: %v", err)
+			return nil, nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message: %v", err)
 		}
 		if size > maxReceiveMessageSize {
 			// TODO: Revisit the error code. Currently keep it consistent with java
 			// implementation.
-			return nil, status.Errorf(codes.ResourceExhausted, "grpc: received message after decompression larger than max (%d vs. %d)", size, maxReceiveMessageSize)
+			return nil, nil, status.Errorf(codes.ResourceExhausted, "grpc: received message after decompression larger than max (%d vs. %d)", size, maxReceiveMessageSize)
 		}
+	} else {
+		uncompressedBuf = compressedBuf
 	}
-	return buf, nil
+
+	if payInfo != nil {
+		payInfo.compressedLength = len(compressedBuf)
+		payInfo.uncompressedBytes = uncompressedBuf
+
+		cancel = func() {}
+	} else {
+		cancel = func() {
+			p.recvBufferPool.Put(&compressedBuf)
+		}
+	}
+
+	return uncompressedBuf, cancel, nil
 }
 
 // Using compressor, decompress d, returning data and size.
@@ -778,6 +812,9 @@ func decompress(compressor encoding.Compressor, d []byte, maxReceiveMessageSize
 			// size is used as an estimate to size the buffer, but we
 			// will read more data if available.
 			// +MinRead so ReadFrom will not reallocate if size is correct.
+			//
+			// TODO: If we ensure that the buffer size is the same as the DecompressedSize,
+			// we can also utilize the recv buffer pool here.
 			buf := bytes.NewBuffer(make([]byte, 0, size+bytes.MinRead))
 			bytesRead, err := buf.ReadFrom(io.LimitReader(dcReader, int64(maxReceiveMessageSize)+1))
 			return buf.Bytes(), int(bytesRead), err
@@ -793,18 +830,15 @@ func decompress(compressor encoding.Compressor, d []byte, maxReceiveMessageSize
 // dc takes precedence over compressor.
 // TODO(dfawley): wrap the old compressor/decompressor using the new API?
 func recv(p *parser, c baseCodec, s *transport.Stream, dc Decompressor, m any, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor) error {
-	buf, err := recvAndDecompress(p, s, dc, maxReceiveMessageSize, payInfo, compressor)
+	buf, cancel, err := recvAndDecompress(p, s, dc, maxReceiveMessageSize, payInfo, compressor)
 	if err != nil {
 		return err
 	}
+	defer cancel()
+
 	if err := c.Unmarshal(buf, m); err != nil {
 		return status.Errorf(codes.Internal, "grpc: failed to unmarshal the received message: %v", err)
 	}
-	if payInfo != nil {
-		payInfo.uncompressedBytes = buf
-	} else {
-		p.recvBufferPool.Put(&buf)
-	}
 	return nil
 }
 
@@ -954,6 +988,7 @@ const (
 	SupportPackageIsVersion5 = true
 	SupportPackageIsVersion6 = true
 	SupportPackageIsVersion7 = true
+	SupportPackageIsVersion8 = true
 )
 
 const grpcUA = "grpc-go/" + Version
diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go
index 2fa694d5..a6a11704 100644
--- a/vendor/google.golang.org/grpc/server.go
+++ b/vendor/google.golang.org/grpc/server.go
@@ -33,8 +33,6 @@ import (
 	"sync/atomic"
 	"time"
 
-	"golang.org/x/net/trace"
-
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/credentials"
 	"google.golang.org/grpc/encoding"
@@ -74,9 +72,6 @@ func init() {
 		return srv.isRegisteredMethod(method)
 	}
 	internal.ServerFromContext = serverFromContext
-	internal.DrainServerTransports = func(srv *Server, addr string) {
-		srv.drainServerTransports(addr)
-	}
 	internal.AddGlobalServerOptions = func(opt ...ServerOption) {
 		globalServerOptions = append(globalServerOptions, opt...)
 	}
@@ -134,17 +129,19 @@ type Server struct {
 	drain    bool
 	cv       *sync.Cond              // signaled when connections close for GracefulStop
 	services map[string]*serviceInfo // service name -> service info
-	events   trace.EventLog
+	events   traceEventLog
 
 	quit               *grpcsync.Event
 	done               *grpcsync.Event
 	channelzRemoveOnce sync.Once
-	serveWG            sync.WaitGroup // counts active Serve goroutines for GracefulStop
+	serveWG            sync.WaitGroup // counts active Serve goroutines for Stop/GracefulStop
+	handlersWG         sync.WaitGroup // counts active method handler goroutines
 
 	channelzID *channelz.Identifier
 	czData     *channelzData
 
-	serverWorkerChannel chan func()
+	serverWorkerChannel      chan func()
+	serverWorkerChannelClose func()
 }
 
 type serverOptions struct {
@@ -175,6 +172,7 @@ type serverOptions struct {
 	headerTableSize       *uint32
 	numServerWorkers      uint32
 	recvBufferPool        SharedBufferPool
+	waitForHandlers       bool
 }
 
 var defaultServerOptions = serverOptions{
@@ -572,6 +570,21 @@ func NumStreamWorkers(numServerWorkers uint32) ServerOption {
 	})
 }
 
+// WaitForHandlers cause Stop to wait until all outstanding method handlers have
+// exited before returning.  If false, Stop will return as soon as all
+// connections have closed, but method handlers may still be running. By
+// default, Stop does not wait for method handlers to return.
+//
+// # Experimental
+//
+// Notice: This API is EXPERIMENTAL and may be changed or removed in a
+// later release.
+func WaitForHandlers(w bool) ServerOption {
+	return newFuncServerOption(func(o *serverOptions) {
+		o.waitForHandlers = w
+	})
+}
+
 // RecvBufferPool returns a ServerOption that configures the server
 // to use the provided shared buffer pool for parsing incoming messages. Depending
 // on the application's workload, this could result in reduced memory allocation.
@@ -623,15 +636,14 @@ func (s *Server) serverWorker() {
 // connections to reduce the time spent overall on runtime.morestack.
 func (s *Server) initServerWorkers() {
 	s.serverWorkerChannel = make(chan func())
+	s.serverWorkerChannelClose = grpcsync.OnceFunc(func() {
+		close(s.serverWorkerChannel)
+	})
 	for i := uint32(0); i < s.opts.numServerWorkers; i++ {
 		go s.serverWorker()
 	}
 }
 
-func (s *Server) stopServerWorkers() {
-	close(s.serverWorkerChannel)
-}
-
 // NewServer creates a gRPC server which has no service registered and has not
 // started to accept requests yet.
 func NewServer(opt ...ServerOption) *Server {
@@ -656,7 +668,7 @@ func NewServer(opt ...ServerOption) *Server {
 	s.cv = sync.NewCond(&s.mu)
 	if EnableTracing {
 		_, file, line, _ := runtime.Caller(1)
-		s.events = trace.NewEventLog("grpc.Server", fmt.Sprintf("%s:%d", file, line))
+		s.events = newTraceEventLog("grpc.Server", fmt.Sprintf("%s:%d", file, line))
 	}
 
 	if s.opts.numServerWorkers > 0 {
@@ -932,6 +944,12 @@ func (s *Server) handleRawConn(lisAddr string, rawConn net.Conn) {
 		return
 	}
 
+	if cc, ok := rawConn.(interface {
+		PassServerTransport(transport.ServerTransport)
+	}); ok {
+		cc.PassServerTransport(st)
+	}
+
 	if !s.addConn(lisAddr, st) {
 		return
 	}
@@ -941,15 +959,6 @@ func (s *Server) handleRawConn(lisAddr string, rawConn net.Conn) {
 	}()
 }
 
-func (s *Server) drainServerTransports(addr string) {
-	s.mu.Lock()
-	conns := s.conns[addr]
-	for st := range conns {
-		st.Drain("")
-	}
-	s.mu.Unlock()
-}
-
 // newHTTP2Transport sets up a http/2 transport (using the
 // gRPC http2 server transport in transport/http2_server.go).
 func (s *Server) newHTTP2Transport(c net.Conn) transport.ServerTransport {
@@ -1010,9 +1019,11 @@ func (s *Server) serveStreams(ctx context.Context, st transport.ServerTransport,
 
 	streamQuota := newHandlerQuota(s.opts.maxConcurrentStreams)
 	st.HandleStreams(ctx, func(stream *transport.Stream) {
+		s.handlersWG.Add(1)
 		streamQuota.acquire()
 		f := func() {
 			defer streamQuota.release()
+			defer s.handlersWG.Done()
 			s.handleStream(st, stream)
 		}
 
@@ -1331,7 +1342,8 @@ func (s *Server) processUnaryRPC(ctx context.Context, t transport.ServerTranspor
 	if len(shs) != 0 || len(binlogs) != 0 {
 		payInfo = &payloadInfo{}
 	}
-	d, err := recvAndDecompress(&parser{r: stream, recvBufferPool: s.opts.recvBufferPool}, stream, dc, s.opts.maxReceiveMessageSize, payInfo, decomp)
+
+	d, cancel, err := recvAndDecompress(&parser{r: stream, recvBufferPool: s.opts.recvBufferPool}, stream, dc, s.opts.maxReceiveMessageSize, payInfo, decomp)
 	if err != nil {
 		if e := t.WriteStatus(stream, status.Convert(err)); e != nil {
 			channelz.Warningf(logger, s.channelzID, "grpc: Server.processUnaryRPC failed to write status: %v", e)
@@ -1342,6 +1354,8 @@ func (s *Server) processUnaryRPC(ctx context.Context, t transport.ServerTranspor
 		t.IncrMsgRecv()
 	}
 	df := func(v any) error {
+		defer cancel()
+
 		if err := s.getCodec(stream.ContentSubtype()).Unmarshal(d, v); err != nil {
 			return status.Errorf(codes.Internal, "grpc: error unmarshalling request: %v", err)
 		}
@@ -1721,8 +1735,8 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str
 	ctx = contextWithServer(ctx, s)
 	var ti *traceInfo
 	if EnableTracing {
-		tr := trace.New("grpc.Recv."+methodFamily(stream.Method()), stream.Method())
-		ctx = trace.NewContext(ctx, tr)
+		tr := newTrace("grpc.Recv."+methodFamily(stream.Method()), stream.Method())
+		ctx = newTraceContext(ctx, tr)
 		ti = &traceInfo{
 			tr: tr,
 			firstLine: firstLine{
@@ -1898,15 +1912,23 @@ func (s *Server) stop(graceful bool) {
 		s.closeServerTransportsLocked()
 	}
 
-	if s.opts.numServerWorkers > 0 {
-		s.stopServerWorkers()
-	}
-
 	for len(s.conns) != 0 {
 		s.cv.Wait()
 	}
 	s.conns = nil
 
+	if s.opts.numServerWorkers > 0 {
+		// Closing the channel (only once, via grpcsync.OnceFunc) after all the
+		// connections have been closed above ensures that there are no
+		// goroutines executing the callback passed to st.HandleStreams (where
+		// the channel is written to).
+		s.serverWorkerChannelClose()
+	}
+
+	if graceful || s.opts.waitForHandlers {
+		s.handlersWG.Wait()
+	}
+
 	if s.events != nil {
 		s.events.Finish()
 		s.events = nil
@@ -2098,7 +2120,7 @@ func ClientSupportedCompressors(ctx context.Context) ([]string, error) {
 		return nil, fmt.Errorf("failed to fetch the stream from the given context %v", ctx)
 	}
 
-	return strings.Split(stream.ClientAdvertisedCompressors(), ","), nil
+	return stream.ClientAdvertisedCompressors(), nil
 }
 
 // SetTrailer sets the trailer metadata that will be sent when an RPC returns.
@@ -2138,7 +2160,7 @@ func (c *channelzServer) ChannelzMetric() *channelz.ServerInternalMetric {
 
 // validateSendCompressor returns an error when given compressor name cannot be
 // handled by the server or the client based on the advertised compressors.
-func validateSendCompressor(name, clientCompressors string) error {
+func validateSendCompressor(name string, clientCompressors []string) error {
 	if name == encoding.Identity {
 		return nil
 	}
@@ -2147,7 +2169,7 @@ func validateSendCompressor(name, clientCompressors string) error {
 		return fmt.Errorf("compressor not registered %q", name)
 	}
 
-	for _, c := range strings.Split(clientCompressors, ",") {
+	for _, c := range clientCompressors {
 		if c == name {
 			return nil // found match
 		}
diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go
index b14b2fbe..814e9983 100644
--- a/vendor/google.golang.org/grpc/stream.go
+++ b/vendor/google.golang.org/grpc/stream.go
@@ -27,7 +27,6 @@ import (
 	"sync"
 	"time"
 
-	"golang.org/x/net/trace"
 	"google.golang.org/grpc/balancer"
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/encoding"
@@ -48,6 +47,8 @@ import (
 	"google.golang.org/grpc/status"
 )
 
+var metadataFromOutgoingContextRaw = internal.FromOutgoingContextRaw.(func(context.Context) (metadata.MD, [][]string, bool))
+
 // StreamHandler defines the handler called by gRPC server to complete the
 // execution of a streaming RPC.
 //
@@ -184,7 +185,7 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth
 	// when the RPC completes.
 	opts = append([]CallOption{OnFinish(func(error) { cc.idlenessMgr.OnCallEnd() })}, opts...)
 
-	if md, added, ok := metadata.FromOutgoingContextRaw(ctx); ok {
+	if md, added, ok := metadataFromOutgoingContextRaw(ctx); ok {
 		// validate md
 		if err := imetadata.Validate(md); err != nil {
 			return nil, status.Error(codes.Internal, err.Error())
@@ -429,7 +430,7 @@ func (cs *clientStream) newAttemptLocked(isTransparent bool) (*csAttempt, error)
 	var trInfo *traceInfo
 	if EnableTracing {
 		trInfo = &traceInfo{
-			tr: trace.New("grpc.Sent."+methodFamily(method), method),
+			tr: newTrace("grpc.Sent."+methodFamily(method), method),
 			firstLine: firstLine{
 				client: true,
 			},
@@ -438,7 +439,7 @@ func (cs *clientStream) newAttemptLocked(isTransparent bool) (*csAttempt, error)
 			trInfo.firstLine.deadline = time.Until(deadline)
 		}
 		trInfo.tr.LazyLog(&trInfo.firstLine, false)
-		ctx = trace.NewContext(ctx, trInfo.tr)
+		ctx = newTraceContext(ctx, trInfo.tr)
 	}
 
 	if cs.cc.parsedTarget.URL.Scheme == internal.GRPCResolverSchemeExtraMetadata {
diff --git a/vendor/google.golang.org/grpc/trace.go b/vendor/google.golang.org/grpc/trace.go
index 9ded7932..10f4f798 100644
--- a/vendor/google.golang.org/grpc/trace.go
+++ b/vendor/google.golang.org/grpc/trace.go
@@ -26,8 +26,6 @@ import (
 	"strings"
 	"sync"
 	"time"
-
-	"golang.org/x/net/trace"
 )
 
 // EnableTracing controls whether to trace RPCs using the golang.org/x/net/trace package.
@@ -44,9 +42,31 @@ func methodFamily(m string) string {
 	return m
 }
 
+// traceEventLog mirrors golang.org/x/net/trace.EventLog.
+//
+// It exists in order to avoid importing x/net/trace on grpcnotrace builds.
+type traceEventLog interface {
+	Printf(format string, a ...any)
+	Errorf(format string, a ...any)
+	Finish()
+}
+
+// traceLog mirrors golang.org/x/net/trace.Trace.
+//
+// It exists in order to avoid importing x/net/trace on grpcnotrace builds.
+type traceLog interface {
+	LazyLog(x fmt.Stringer, sensitive bool)
+	LazyPrintf(format string, a ...any)
+	SetError()
+	SetRecycler(f func(any))
+	SetTraceInfo(traceID, spanID uint64)
+	SetMaxEvents(m int)
+	Finish()
+}
+
 // traceInfo contains tracing information for an RPC.
 type traceInfo struct {
-	tr        trace.Trace
+	tr        traceLog
 	firstLine firstLine
 }
 
diff --git a/vendor/google.golang.org/grpc/trace_notrace.go b/vendor/google.golang.org/grpc/trace_notrace.go
new file mode 100644
index 00000000..1da3a230
--- /dev/null
+++ b/vendor/google.golang.org/grpc/trace_notrace.go
@@ -0,0 +1,52 @@
+//go:build grpcnotrace
+
+/*
+ *
+ * Copyright 2024 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package grpc
+
+// grpcnotrace can be used to avoid importing golang.org/x/net/trace, which in
+// turn enables binaries using gRPC-Go for dead code elimination, which can
+// yield 10-15% improvements in binary size when tracing is not needed.
+
+import (
+	"context"
+	"fmt"
+)
+
+type notrace struct{}
+
+func (notrace) LazyLog(x fmt.Stringer, sensitive bool) {}
+func (notrace) LazyPrintf(format string, a ...any)     {}
+func (notrace) SetError()                              {}
+func (notrace) SetRecycler(f func(any))                {}
+func (notrace) SetTraceInfo(traceID, spanID uint64)    {}
+func (notrace) SetMaxEvents(m int)                     {}
+func (notrace) Finish()                                {}
+
+func newTrace(family, title string) traceLog {
+	return notrace{}
+}
+
+func newTraceContext(ctx context.Context, tr traceLog) context.Context {
+	return ctx
+}
+
+func newTraceEventLog(family, title string) traceEventLog {
+	return nil
+}
diff --git a/vendor/google.golang.org/grpc/trace_withtrace.go b/vendor/google.golang.org/grpc/trace_withtrace.go
new file mode 100644
index 00000000..88d6e857
--- /dev/null
+++ b/vendor/google.golang.org/grpc/trace_withtrace.go
@@ -0,0 +1,39 @@
+//go:build !grpcnotrace
+
+/*
+ *
+ * Copyright 2024 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package grpc
+
+import (
+	"context"
+
+	t "golang.org/x/net/trace"
+)
+
+func newTrace(family, title string) traceLog {
+	return t.New(family, title)
+}
+
+func newTraceContext(ctx context.Context, tr traceLog) context.Context {
+	return t.NewContext(ctx, tr)
+}
+
+func newTraceEventLog(family, title string) traceEventLog {
+	return t.NewEventLog(family, title)
+}
diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go
index a04793ae..46ad8113 100644
--- a/vendor/google.golang.org/grpc/version.go
+++ b/vendor/google.golang.org/grpc/version.go
@@ -19,4 +19,4 @@
 package grpc
 
 // Version is the current grpc version.
-const Version = "1.60.0"
+const Version = "1.62.1"
diff --git a/vendor/google.golang.org/grpc/vet.sh b/vendor/google.golang.org/grpc/vet.sh
index 896dc38f..7a33c215 100644
--- a/vendor/google.golang.org/grpc/vet.sh
+++ b/vendor/google.golang.org/grpc/vet.sh
@@ -41,7 +41,7 @@ if [[ "$1" = "-install" ]]; then
   popd
   if [[ -z "${VET_SKIP_PROTO}" ]]; then
     if [[ "${GITHUB_ACTIONS}" = "true" ]]; then
-      PROTOBUF_VERSION=22.0 # a.k.a v4.22.0 in pb.go files.
+      PROTOBUF_VERSION=25.2 # a.k.a. v4.22.0 in pb.go files.
       PROTOC_FILENAME=protoc-${PROTOBUF_VERSION}-linux-x86_64.zip
       pushd /home/runner/go
       wget https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/${PROTOC_FILENAME}
@@ -88,7 +88,7 @@ not git grep -l 'x/net/context' -- "*.go"
 git grep -l '"math/rand"' -- "*.go" 2>&1 | not grep -v '^examples\|^interop/stress\|grpcrand\|^benchmark\|wrr_test'
 
 # - Do not use "interface{}"; use "any" instead.
-git grep -l 'interface{}' -- "*.go" 2>&1 | not grep -v '\.pb\.go\|protoc-gen-go-grpc'
+git grep -l 'interface{}' -- "*.go" 2>&1 | not grep -v '\.pb\.go\|protoc-gen-go-grpc\|grpc_testing_not_regenerate'
 
 # - Do not call grpclog directly. Use grpclog.Component instead.
 git grep -l -e 'grpclog.I' --or -e 'grpclog.W' --or -e 'grpclog.E' --or -e 'grpclog.F' --or -e 'grpclog.V' -- "*.go" | not grep -v '^grpclog/component.go\|^internal/grpctest/tlogger_test.go'
@@ -127,7 +127,7 @@ staticcheck -go 1.19 -checks 'all' ./... > "${SC_OUT}" || true
 grep -v "(ST1000)" "${SC_OUT}" | grep -v "(SA1019)" | grep -v "(ST1003)" | not grep -v "(ST1019)\|\(other import of\)"
 
 # Exclude underscore checks for generated code.
-grep "(ST1003)" "${SC_OUT}" | not grep -v '\(.pb.go:\)\|\(code_string_test.go:\)'
+grep "(ST1003)" "${SC_OUT}" | not grep -v '\(.pb.go:\)\|\(code_string_test.go:\)\|\(grpc_testing_not_regenerate\)'
 
 # Error for duplicate imports not including grpc protos.
 grep "(ST1019)\|\(other import of\)" "${SC_OUT}" | not grep -Fv 'XXXXX PleaseIgnoreUnused
@@ -152,6 +152,7 @@ grep "(SA1019)" "${SC_OUT}" | not grep -Fv 'XXXXX PleaseIgnoreUnused
 XXXXX Protobuf related deprecation errors:
 "github.com/golang/protobuf
 .pb.go:
+grpc_testing_not_regenerate
 : ptypes.
 proto.RegisterType
 XXXXX gRPC internal usage deprecation errors:
@@ -184,9 +185,6 @@ GetSafeRegexMatch
 GetSuffixMatch
 GetTlsCertificateCertificateProviderInstance
 GetValidationContextCertificateProviderInstance
-XXXXX TODO: Remove the below deprecation usages:
-CloseNotifier
-Roots.Subjects
 XXXXX PleaseIgnoreUnused'
 
 echo SUCCESS
diff --git a/vendor/google.golang.org/protobuf/protoadapt/convert.go b/vendor/google.golang.org/protobuf/protoadapt/convert.go
new file mode 100644
index 00000000..ea276d15
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/protoadapt/convert.go
@@ -0,0 +1,31 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package protoadapt bridges the original and new proto APIs.
+package protoadapt
+
+import (
+	"google.golang.org/protobuf/proto"
+	"google.golang.org/protobuf/runtime/protoiface"
+	"google.golang.org/protobuf/runtime/protoimpl"
+)
+
+// MessageV1 is the original [github.com/golang/protobuf/proto.Message] type.
+type MessageV1 = protoiface.MessageV1
+
+// MessageV2 is the [google.golang.org/protobuf/proto.Message] type used by the
+// current [google.golang.org/protobuf] module, adding support for reflection.
+type MessageV2 = proto.Message
+
+// MessageV1Of converts a v2 message to a v1 message.
+// It returns nil if m is nil.
+func MessageV1Of(m MessageV2) MessageV1 {
+	return protoimpl.X.ProtoMessageV1Of(m)
+}
+
+// MessageV2Of converts a v1 message to a v2 message.
+// It returns nil if m is nil.
+func MessageV2Of(m MessageV1) MessageV2 {
+	return protoimpl.X.ProtoMessageV2Of(m)
+}
diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types_jsonschema.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types_jsonschema.go
index cc1c7437..8c4e147f 100644
--- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types_jsonschema.go
+++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types_jsonschema.go
@@ -210,6 +210,19 @@ type ValidationRule struct {
 	//   - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values
 	//     are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with
 	//     non-intersecting keys are appended, retaining their partial order.
+	//
+	// If `rule` makes use of the `oldSelf` variable it is implicitly a
+	// `transition rule`.
+	//
+	// By default, the `oldSelf` variable is the same type as `self`.
+	// When `optionalOldSelf` is true, the `oldSelf` variable is a CEL optional
+	//  variable whose value() is the same type as `self`.
+	// See the documentation for the `optionalOldSelf` field for details.
+	//
+	// Transition rules by default are applied only on UPDATE requests and are
+	// skipped if an old value could not be found. You can opt a transition
+	// rule into unconditional evaluation by setting `optionalOldSelf` to true.
+	//
 	Rule string
 	// Message represents the message displayed when validation fails. The message is required if the Rule contains
 	// line breaks. The message must not contain line breaks.
@@ -246,6 +259,24 @@ type ValidationRule struct {
 	// e.g. for attribute `foo.34$` appears in a list `testList`, the fieldPath could be set to `.testList['foo.34$']`
 	// +optional
 	FieldPath string
+
+	// optionalOldSelf is used to opt a transition rule into evaluation
+	// even when the object is first created, or if the old object is
+	// missing the value.
+	//
+	// When enabled `oldSelf` will be a CEL optional whose value will be
+	// `None` if there is no old value, or when the object is initially created.
+	//
+	// You may check for presence of oldSelf using `oldSelf.hasValue()` and
+	// unwrap it after checking using `oldSelf.value()`. Check the CEL
+	// documentation for Optional types for more information:
+	// https://pkg.go.dev/github.com/google/cel-go/cel#OptionalTypes
+	//
+	// May not be set unless `oldSelf` is used in `rule`.
+	//
+	// +featureGate=CRDValidationRatcheting
+	// +optional
+	OptionalOldSelf *bool
 }
 
 // JSON represents any valid JSON value.
diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.pb.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.pb.go
index 75a573a2..6c22a516 100644
--- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.pb.go
+++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.pb.go
@@ -814,202 +814,204 @@ func init() {
 }
 
 var fileDescriptor_f5a35c9667703937 = []byte{
-	// 3111 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x5a, 0xdd, 0x6f, 0x5c, 0x47,
-	0x15, 0xcf, 0x5d, 0x7b, 0xed, 0xf5, 0xd8, 0x89, 0xed, 0x49, 0x6c, 0x6e, 0xdc, 0xc4, 0xeb, 0x6c,
-	0x68, 0x70, 0xdb, 0x74, 0xdd, 0x9a, 0x96, 0x86, 0x82, 0x40, 0x5e, 0xdb, 0x69, 0xdd, 0xd8, 0xb1,
-	0x35, 0x9b, 0xa4, 0x6e, 0x8b, 0x68, 0xaf, 0xf7, 0x8e, 0xd7, 0xb7, 0xbe, 0x5f, 0x99, 0xb9, 0xd7,
-	0x1f, 0x12, 0x48, 0x15, 0xa8, 0x02, 0x2a, 0x41, 0x79, 0xa8, 0xca, 0x13, 0x42, 0x08, 0xf5, 0x01,
-	0x1e, 0xe0, 0x0d, 0xfe, 0x85, 0xbe, 0x20, 0xf5, 0x09, 0x55, 0x42, 0x5a, 0xd1, 0xe5, 0x1f, 0x40,
-	0x02, 0x84, 0xf0, 0x03, 0x42, 0xf3, 0x71, 0xe7, 0xce, 0xde, 0xdd, 0x4d, 0x22, 0x7b, 0xdd, 0xbe,
-	0xed, 0x9e, 0x73, 0xe6, 0xfc, 0xce, 0x9c, 0x39, 0x73, 0xe6, 0xcc, 0xb9, 0x03, 0xac, 0xdd, 0x1b,
-	0xb4, 0xec, 0x04, 0x73, 0xbb, 0xf1, 0x16, 0x26, 0x3e, 0x8e, 0x30, 0x9d, 0xdb, 0xc3, 0xbe, 0x1d,
-	0x90, 0x39, 0xc9, 0xb0, 0x42, 0x07, 0x1f, 0x44, 0xd8, 0xa7, 0x4e, 0xe0, 0xd3, 0xa7, 0xad, 0xd0,
-	0xa1, 0x98, 0xec, 0x61, 0x32, 0x17, 0xee, 0xd6, 0x19, 0x8f, 0xb6, 0x0a, 0xcc, 0xed, 0x3d, 0x3b,
-	0x57, 0xc7, 0x3e, 0x26, 0x56, 0x84, 0xed, 0x72, 0x48, 0x82, 0x28, 0x80, 0x37, 0x84, 0xa6, 0x72,
-	0x8b, 0xe0, 0x9b, 0x4a, 0x53, 0x39, 0xdc, 0xad, 0x33, 0x1e, 0x6d, 0x15, 0x28, 0xef, 0x3d, 0x3b,
-	0xf5, 0x74, 0xdd, 0x89, 0x76, 0xe2, 0xad, 0x72, 0x2d, 0xf0, 0xe6, 0xea, 0x41, 0x3d, 0x98, 0xe3,
-	0x0a, 0xb7, 0xe2, 0x6d, 0xfe, 0x8f, 0xff, 0xe1, 0xbf, 0x04, 0xd0, 0xd4, 0x73, 0xa9, 0xc9, 0x9e,
-	0x55, 0xdb, 0x71, 0x7c, 0x4c, 0x0e, 0x53, 0x3b, 0x3d, 0x1c, 0x59, 0x1d, 0xcc, 0x9b, 0x9a, 0xeb,
-	0x36, 0x8a, 0xc4, 0x7e, 0xe4, 0x78, 0xb8, 0x6d, 0xc0, 0xd7, 0x1e, 0x36, 0x80, 0xd6, 0x76, 0xb0,
-	0x67, 0x65, 0xc7, 0x95, 0x8e, 0x0c, 0x30, 0xbe, 0x18, 0xf8, 0x7b, 0x98, 0xb0, 0x09, 0x22, 0x7c,
-	0x3f, 0xc6, 0x34, 0x82, 0x15, 0xd0, 0x17, 0x3b, 0xb6, 0x69, 0xcc, 0x18, 0xb3, 0x43, 0x95, 0x67,
-	0x3e, 0x6e, 0x14, 0xcf, 0x34, 0x1b, 0xc5, 0xbe, 0xbb, 0x2b, 0x4b, 0x47, 0x8d, 0xe2, 0x95, 0x6e,
-	0x48, 0xd1, 0x61, 0x88, 0x69, 0xf9, 0xee, 0xca, 0x12, 0x62, 0x83, 0xe1, 0x4b, 0x60, 0xdc, 0xc6,
-	0xd4, 0x21, 0xd8, 0x5e, 0xd8, 0x58, 0xb9, 0x27, 0xf4, 0x9b, 0x39, 0xae, 0xf1, 0xa2, 0xd4, 0x38,
-	0xbe, 0x94, 0x15, 0x40, 0xed, 0x63, 0xe0, 0x26, 0x18, 0x0c, 0xb6, 0xde, 0xc6, 0xb5, 0x88, 0x9a,
-	0x7d, 0x33, 0x7d, 0xb3, 0xc3, 0xf3, 0x4f, 0x97, 0xd3, 0xc5, 0x53, 0x26, 0xf0, 0x15, 0x93, 0x93,
-	0x2d, 0x23, 0x6b, 0x7f, 0x39, 0x59, 0xb4, 0xca, 0xa8, 0x44, 0x1b, 0x5c, 0x17, 0x5a, 0x50, 0xa2,
-	0xae, 0xf4, 0x9b, 0x1c, 0x80, 0xfa, 0xe4, 0x69, 0x18, 0xf8, 0x14, 0xf7, 0x64, 0xf6, 0x14, 0x8c,
-	0xd5, 0xb8, 0xe6, 0x08, 0xdb, 0x12, 0xd7, 0xcc, 0x1d, 0xc7, 0x7a, 0x53, 0xe2, 0x8f, 0x2d, 0x66,
-	0xd4, 0xa1, 0x36, 0x00, 0x78, 0x07, 0x0c, 0x10, 0x4c, 0x63, 0x37, 0x32, 0xfb, 0x66, 0x8c, 0xd9,
-	0xe1, 0xf9, 0xeb, 0x5d, 0xa1, 0x78, 0x68, 0xb3, 0xe0, 0x2b, 0xef, 0x3d, 0x5b, 0xae, 0x46, 0x56,
-	0x14, 0xd3, 0xca, 0x39, 0x89, 0x34, 0x80, 0xb8, 0x0e, 0x24, 0x75, 0x95, 0xfe, 0x67, 0x80, 0x31,
-	0xdd, 0x4b, 0x7b, 0x0e, 0xde, 0x87, 0x04, 0x0c, 0x12, 0x11, 0x2c, 0xdc, 0x4f, 0xc3, 0xf3, 0xb7,
-	0xca, 0xc7, 0xdd, 0x51, 0xe5, 0xb6, 0xf8, 0xab, 0x0c, 0xb3, 0xe5, 0x92, 0x7f, 0x50, 0x02, 0x04,
-	0xf7, 0x40, 0x81, 0xc8, 0x35, 0xe2, 0x81, 0x34, 0x3c, 0xbf, 0xda, 0x1b, 0x50, 0xa1, 0xb3, 0x32,
-	0xd2, 0x6c, 0x14, 0x0b, 0xc9, 0x3f, 0xa4, 0xb0, 0x4a, 0xbf, 0xca, 0x81, 0xe9, 0xc5, 0x98, 0x46,
-	0x81, 0x87, 0x30, 0x0d, 0x62, 0x52, 0xc3, 0x8b, 0x81, 0x1b, 0x7b, 0xfe, 0x12, 0xde, 0x76, 0x7c,
-	0x27, 0x62, 0x31, 0x3a, 0x03, 0xfa, 0x7d, 0xcb, 0xc3, 0x32, 0x66, 0x46, 0xa4, 0x27, 0xfb, 0x6f,
-	0x5b, 0x1e, 0x46, 0x9c, 0xc3, 0x24, 0x58, 0x88, 0xc8, 0x1d, 0xa0, 0x24, 0xee, 0x1c, 0x86, 0x18,
-	0x71, 0x0e, 0xbc, 0x06, 0x06, 0xb6, 0x03, 0xe2, 0x59, 0x62, 0xf5, 0x86, 0xd2, 0xf5, 0xb8, 0xc9,
-	0xa9, 0x48, 0x72, 0xe1, 0xf3, 0x60, 0xd8, 0xc6, 0xb4, 0x46, 0x9c, 0x90, 0x41, 0x9b, 0xfd, 0x5c,
-	0xf8, 0xbc, 0x14, 0x1e, 0x5e, 0x4a, 0x59, 0x48, 0x97, 0x83, 0xd7, 0x41, 0x21, 0x24, 0x4e, 0x40,
-	0x9c, 0xe8, 0xd0, 0xcc, 0xcf, 0x18, 0xb3, 0xf9, 0xca, 0x98, 0x1c, 0x53, 0xd8, 0x90, 0x74, 0xa4,
-	0x24, 0x98, 0xf4, 0xdb, 0x34, 0xf0, 0x37, 0xac, 0x68, 0xc7, 0x1c, 0xe0, 0x08, 0x4a, 0xfa, 0x95,
-	0xea, 0xfa, 0x6d, 0x46, 0x47, 0x4a, 0xa2, 0xf4, 0x17, 0x03, 0x98, 0x59, 0x0f, 0x25, 0xee, 0x85,
-	0x37, 0x41, 0x81, 0x46, 0x2c, 0xe7, 0xd4, 0x0f, 0xa5, 0x7f, 0x9e, 0x4c, 0x54, 0x55, 0x25, 0xfd,
-	0xa8, 0x51, 0x9c, 0x4c, 0x47, 0x24, 0x54, 0xee, 0x1b, 0x35, 0x96, 0x85, 0xdc, 0x3e, 0xde, 0xda,
-	0x09, 0x82, 0x5d, 0xb9, 0xfa, 0x27, 0x08, 0xb9, 0x57, 0x85, 0xa2, 0x14, 0x53, 0x84, 0x9c, 0x24,
-	0xa3, 0x04, 0xa8, 0xf4, 0xdf, 0x5c, 0x76, 0x62, 0xda, 0xa2, 0xbf, 0x05, 0x0a, 0x6c, 0x0b, 0xd9,
-	0x56, 0x64, 0xc9, 0x4d, 0xf0, 0xcc, 0xa3, 0x6d, 0x38, 0xb1, 0x5f, 0xd7, 0x70, 0x64, 0x55, 0xa0,
-	0x74, 0x05, 0x48, 0x69, 0x48, 0x69, 0x85, 0x07, 0xa0, 0x9f, 0x86, 0xb8, 0x26, 0xe7, 0x7b, 0xef,
-	0x04, 0xd1, 0xde, 0x65, 0x0e, 0xd5, 0x10, 0xd7, 0xd2, 0x60, 0x64, 0xff, 0x10, 0x47, 0x84, 0xef,
-	0x18, 0x60, 0x80, 0xf2, 0xbc, 0x20, 0x73, 0xc9, 0xe6, 0x29, 0x80, 0x67, 0xf2, 0x8e, 0xf8, 0x8f,
-	0x24, 0x6e, 0xe9, 0x5f, 0x39, 0x70, 0xa5, 0xdb, 0xd0, 0xc5, 0xc0, 0xb7, 0xc5, 0x22, 0xac, 0xc8,
-	0x7d, 0x25, 0x22, 0xeb, 0x79, 0x7d, 0x5f, 0x1d, 0x35, 0x8a, 0x8f, 0x3f, 0x54, 0x81, 0xb6, 0x01,
-	0xbf, 0xae, 0xa6, 0x2c, 0x36, 0xe9, 0x95, 0x56, 0xc3, 0x8e, 0x1a, 0xc5, 0x51, 0x35, 0xac, 0xd5,
-	0x56, 0xb8, 0x07, 0xa0, 0x6b, 0xd1, 0xe8, 0x0e, 0xb1, 0x7c, 0x2a, 0xd4, 0x3a, 0x1e, 0x96, 0x9e,
-	0x7b, 0xf2, 0xd1, 0x82, 0x82, 0x8d, 0xa8, 0x4c, 0x49, 0x48, 0xb8, 0xda, 0xa6, 0x0d, 0x75, 0x40,
-	0x60, 0x39, 0x83, 0x60, 0x8b, 0xaa, 0x34, 0xa0, 0xe5, 0x70, 0x46, 0x45, 0x92, 0x0b, 0x9f, 0x00,
-	0x83, 0x1e, 0xa6, 0xd4, 0xaa, 0x63, 0xbe, 0xf7, 0x87, 0xd2, 0x43, 0x71, 0x4d, 0x90, 0x51, 0xc2,
-	0x2f, 0xfd, 0xdb, 0x00, 0x97, 0xba, 0x79, 0x6d, 0xd5, 0xa1, 0x11, 0xfc, 0x4e, 0x5b, 0xd8, 0x97,
-	0x1f, 0x6d, 0x86, 0x6c, 0x34, 0x0f, 0x7a, 0x95, 0x4a, 0x12, 0x8a, 0x16, 0xf2, 0xfb, 0x20, 0xef,
-	0x44, 0xd8, 0x4b, 0x4e, 0x4b, 0xd4, 0xfb, 0xb0, 0xab, 0x9c, 0x95, 0xf0, 0xf9, 0x15, 0x06, 0x84,
-	0x04, 0x5e, 0xe9, 0xa3, 0x1c, 0xb8, 0xdc, 0x6d, 0x08, 0xcb, 0xe3, 0x94, 0x39, 0x3b, 0x74, 0x63,
-	0x62, 0xb9, 0x32, 0xd8, 0x94, 0xb3, 0x37, 0x38, 0x15, 0x49, 0x2e, 0xcb, 0x9d, 0xd4, 0xf1, 0xeb,
-	0xb1, 0x6b, 0x11, 0x19, 0x49, 0x6a, 0xc2, 0x55, 0x49, 0x47, 0x4a, 0x02, 0x96, 0x01, 0xa0, 0x3b,
-	0x01, 0x89, 0x38, 0x06, 0xaf, 0x70, 0x86, 0x2a, 0xe7, 0x58, 0x46, 0xa8, 0x2a, 0x2a, 0xd2, 0x24,
-	0xd8, 0x41, 0xb2, 0xeb, 0xf8, 0xb6, 0x5c, 0x70, 0xb5, 0x77, 0x6f, 0x39, 0xbe, 0x8d, 0x38, 0x87,
-	0xe1, 0xbb, 0x0e, 0x8d, 0x18, 0x45, 0xae, 0x76, 0x8b, 0xc3, 0xb9, 0xa4, 0x92, 0x60, 0xf8, 0x35,
-	0x96, 0x60, 0x03, 0xe2, 0x60, 0x6a, 0x0e, 0xa4, 0xf8, 0x8b, 0x8a, 0x8a, 0x34, 0x89, 0xd2, 0x5f,
-	0xfb, 0xbb, 0xc7, 0x07, 0x4b, 0x20, 0xf0, 0x2a, 0xc8, 0xd7, 0x49, 0x10, 0x87, 0xd2, 0x4b, 0xca,
-	0xdb, 0x2f, 0x31, 0x22, 0x12, 0x3c, 0xf8, 0x3d, 0x90, 0xf7, 0xe5, 0x84, 0x59, 0x04, 0xbd, 0xda,
-	0xfb, 0x65, 0xe6, 0xde, 0x4a, 0xd1, 0x85, 0x23, 0x05, 0x28, 0x7c, 0x0e, 0xe4, 0x69, 0x2d, 0x08,
-	0xb1, 0x74, 0xe2, 0x74, 0x22, 0x54, 0x65, 0xc4, 0xa3, 0x46, 0xf1, 0x6c, 0xa2, 0x8e, 0x13, 0x90,
-	0x10, 0x86, 0x3f, 0x32, 0x40, 0x41, 0x1e, 0x17, 0xd4, 0x1c, 0xe4, 0xe1, 0xf9, 0x5a, 0xef, 0xed,
-	0x96, 0x65, 0x6f, 0xba, 0x66, 0x92, 0x40, 0x91, 0x02, 0x87, 0x3f, 0x30, 0x00, 0xa8, 0xa9, 0xb3,
-	0xcb, 0x1c, 0xe2, 0x3e, 0xec, 0xd9, 0x56, 0xd1, 0x4e, 0x45, 0x11, 0x08, 0x69, 0xa9, 0xa4, 0xa1,
-	0xc2, 0x2a, 0x98, 0x08, 0x09, 0xe6, 0xba, 0xef, 0xfa, 0xbb, 0x7e, 0xb0, 0xef, 0xdf, 0x74, 0xb0,
-	0x6b, 0x53, 0x13, 0xcc, 0x18, 0xb3, 0x85, 0xca, 0x65, 0x69, 0xff, 0xc4, 0x46, 0x27, 0x21, 0xd4,
-	0x79, 0x6c, 0xe9, 0xdd, 0xbe, 0x6c, 0xad, 0x95, 0x3d, 0x2f, 0xe0, 0xfb, 0x62, 0xf2, 0x22, 0x0f,
-	0x53, 0xd3, 0xe0, 0x0b, 0xf1, 0x46, 0xef, 0x17, 0x42, 0xe5, 0xfa, 0xf4, 0x90, 0x56, 0x24, 0x8a,
-	0x34, 0x13, 0xe0, 0x07, 0x06, 0x38, 0x6b, 0xd5, 0x6a, 0x38, 0x8c, 0xb0, 0x2d, 0xb6, 0x71, 0xee,
-	0x74, 0xa3, 0x7a, 0x42, 0x1a, 0x74, 0x76, 0x41, 0x47, 0x45, 0xad, 0x46, 0xc0, 0x17, 0xc1, 0x39,
-	0x1a, 0x05, 0x04, 0xdb, 0x49, 0x04, 0xc9, 0xec, 0x02, 0x9b, 0x8d, 0xe2, 0xb9, 0x6a, 0x0b, 0x07,
-	0x65, 0x24, 0x4b, 0x9f, 0xe4, 0x41, 0xf1, 0x21, 0x11, 0xfa, 0x08, 0x45, 0xef, 0x35, 0x30, 0xc0,
-	0x67, 0x6a, 0x73, 0x87, 0x14, 0xb4, 0xa3, 0x9e, 0x53, 0x91, 0xe4, 0xb2, 0xe3, 0x89, 0xe1, 0xb3,
-	0xe3, 0xa9, 0x8f, 0x0b, 0xaa, 0xe3, 0xa9, 0x2a, 0xc8, 0x28, 0xe1, 0xc3, 0x79, 0x00, 0x6c, 0x1c,
-	0x12, 0xcc, 0x32, 0x92, 0x6d, 0x0e, 0x72, 0x69, 0xb5, 0x3e, 0x4b, 0x8a, 0x83, 0x34, 0x29, 0x78,
-	0x13, 0xc0, 0xe4, 0x9f, 0x13, 0xf8, 0xaf, 0x5a, 0xc4, 0x77, 0xfc, 0xba, 0x59, 0xe0, 0x66, 0x4f,
-	0xb2, 0xd3, 0x76, 0xa9, 0x8d, 0x8b, 0x3a, 0x8c, 0x80, 0x7b, 0x60, 0x40, 0x5c, 0xa3, 0x79, 0xde,
-	0xe8, 0xe1, 0x8e, 0xbb, 0x67, 0xb9, 0x8e, 0xcd, 0xa1, 0x2a, 0x80, 0xbb, 0x87, 0xa3, 0x20, 0x89,
-	0x06, 0xdf, 0x33, 0xc0, 0x08, 0x8d, 0xb7, 0x88, 0x94, 0xa6, 0x3c, 0xab, 0x0f, 0xcf, 0xdf, 0xe9,
-	0x15, 0x7c, 0x55, 0xd3, 0x5d, 0x19, 0x6b, 0x36, 0x8a, 0x23, 0x3a, 0x05, 0xb5, 0x60, 0xc3, 0x3f,
-	0x1a, 0xc0, 0xb4, 0x6c, 0x11, 0xfa, 0x96, 0xbb, 0x41, 0x1c, 0x3f, 0xc2, 0x44, 0x5c, 0x88, 0xc4,
-	0xf1, 0xd1, 0xc3, 0x5a, 0x31, 0x7b, 0xcf, 0xaa, 0xcc, 0xc8, 0x95, 0x36, 0x17, 0xba, 0x58, 0x80,
-	0xba, 0xda, 0x56, 0xfa, 0x8f, 0x91, 0x4d, 0x2d, 0xda, 0x2c, 0xab, 0x35, 0xcb, 0xc5, 0x70, 0x09,
-	0x8c, 0xb1, 0xea, 0x17, 0xe1, 0xd0, 0x75, 0x6a, 0x16, 0xe5, 0xb7, 0x1f, 0x11, 0xdd, 0xea, 0x1a,
-	0x5e, 0xcd, 0xf0, 0x51, 0xdb, 0x08, 0xf8, 0x0a, 0x80, 0xa2, 0x2c, 0x6c, 0xd1, 0x23, 0x2a, 0x01,
-	0x55, 0xe0, 0x55, 0xdb, 0x24, 0x50, 0x87, 0x51, 0x70, 0x11, 0x8c, 0xbb, 0xd6, 0x16, 0x76, 0xab,
-	0xd8, 0xc5, 0xb5, 0x28, 0x20, 0x5c, 0x95, 0xb8, 0x1f, 0x4e, 0x34, 0x1b, 0xc5, 0xf1, 0xd5, 0x2c,
-	0x13, 0xb5, 0xcb, 0x97, 0xae, 0x64, 0xf7, 0xb2, 0x3e, 0x71, 0x51, 0x6c, 0x7f, 0x98, 0x03, 0x53,
-	0xdd, 0x83, 0x02, 0x7e, 0x5f, 0x95, 0xc6, 0xa2, 0xe2, 0x7b, 0xed, 0x14, 0x42, 0x4f, 0x5e, 0x07,
-	0x40, 0xfb, 0x55, 0x00, 0x1e, 0xb2, 0xf3, 0xda, 0x72, 0x93, 0x6b, 0xff, 0xe6, 0x69, 0xa0, 0x33,
-	0xfd, 0x95, 0x21, 0x51, 0x05, 0x58, 0x2e, 0x3f, 0xf4, 0x2d, 0x17, 0x97, 0x3e, 0x6a, 0xbb, 0xda,
-	0xa6, 0x9b, 0x15, 0xfe, 0xd8, 0x00, 0xa3, 0x41, 0x88, 0xfd, 0x85, 0x8d, 0x95, 0x7b, 0x5f, 0x15,
-	0x9b, 0x56, 0x3a, 0x68, 0xe5, 0xf8, 0x26, 0xb2, 0xfb, 0xb5, 0xd0, 0xb5, 0x41, 0x82, 0x90, 0x56,
-	0xce, 0x37, 0x1b, 0xc5, 0xd1, 0xf5, 0x56, 0x14, 0x94, 0x85, 0x2d, 0x79, 0x60, 0x62, 0xf9, 0x20,
-	0xc2, 0xc4, 0xb7, 0xdc, 0xa5, 0xa0, 0x16, 0x7b, 0xd8, 0x8f, 0x84, 0x8d, 0x99, 0x76, 0x81, 0xf1,
-	0x88, 0xed, 0x82, 0xcb, 0xa0, 0x2f, 0x26, 0xae, 0x8c, 0xda, 0x61, 0xd5, 0x04, 0x43, 0xab, 0x88,
-	0xd1, 0x4b, 0x57, 0x40, 0x3f, 0xb3, 0x13, 0x5e, 0x04, 0x7d, 0xc4, 0xda, 0xe7, 0x5a, 0x47, 0x2a,
-	0x83, 0x4c, 0x04, 0x59, 0xfb, 0x88, 0xd1, 0x4a, 0xff, 0x98, 0x01, 0xa3, 0x99, 0xb9, 0xc0, 0x29,
-	0x90, 0x53, 0x9d, 0x35, 0x20, 0x95, 0xe6, 0x56, 0x96, 0x50, 0xce, 0xb1, 0xe1, 0x0b, 0x2a, 0xbb,
-	0x0a, 0xd0, 0xa2, 0x3a, 0x2c, 0x38, 0x95, 0x95, 0x65, 0xa9, 0x3a, 0x66, 0x48, 0x92, 0x1e, 0x99,
-	0x0d, 0x78, 0x5b, 0xee, 0x0a, 0x61, 0x03, 0xde, 0x46, 0x8c, 0x76, 0xdc, 0x5e, 0x49, 0xd2, 0xac,
-	0xc9, 0x3f, 0x42, 0xb3, 0x66, 0xe0, 0x81, 0xcd, 0x9a, 0xab, 0x20, 0x1f, 0x39, 0x91, 0x8b, 0xf9,
-	0x49, 0xa5, 0x15, 0xc3, 0x77, 0x18, 0x11, 0x09, 0x1e, 0xc4, 0x60, 0xd0, 0xc6, 0xdb, 0x56, 0xec,
-	0x46, 0xfc, 0x50, 0x1a, 0x9e, 0xff, 0xd6, 0xc9, 0xa2, 0x47, 0x34, 0x33, 0x96, 0x84, 0x4a, 0x94,
-	0xe8, 0x86, 0x8f, 0x83, 0x41, 0xcf, 0x3a, 0x70, 0xbc, 0xd8, 0xe3, 0x15, 0xa3, 0x21, 0xc4, 0xd6,
-	0x04, 0x09, 0x25, 0x3c, 0x96, 0x04, 0xf1, 0x41, 0xcd, 0x8d, 0xa9, 0xb3, 0x87, 0x25, 0x53, 0x96,
-	0x74, 0x2a, 0x09, 0x2e, 0x67, 0xf8, 0xa8, 0x6d, 0x04, 0x07, 0x73, 0x7c, 0x3e, 0x78, 0x58, 0x03,
-	0x13, 0x24, 0x94, 0xf0, 0x5a, 0xc1, 0xa4, 0xfc, 0x48, 0x37, 0x30, 0x39, 0xb8, 0x6d, 0x04, 0x7c,
-	0x0a, 0x0c, 0x79, 0xd6, 0xc1, 0x2a, 0xf6, 0xeb, 0xd1, 0x8e, 0x79, 0x76, 0xc6, 0x98, 0xed, 0xab,
-	0x9c, 0x6d, 0x36, 0x8a, 0x43, 0x6b, 0x09, 0x11, 0xa5, 0x7c, 0x2e, 0xec, 0xf8, 0x52, 0xf8, 0x9c,
-	0x26, 0x9c, 0x10, 0x51, 0xca, 0x67, 0x95, 0x49, 0x68, 0x45, 0x6c, 0x5f, 0x99, 0xa3, 0xad, 0x17,
-	0xe7, 0x0d, 0x41, 0x46, 0x09, 0x1f, 0xce, 0x82, 0x82, 0x67, 0x1d, 0xf0, 0x3b, 0xa5, 0x39, 0xc6,
-	0xd5, 0xf2, 0x86, 0xe2, 0x9a, 0xa4, 0x21, 0xc5, 0xe5, 0x92, 0x8e, 0x2f, 0x24, 0xc7, 0x35, 0x49,
-	0x49, 0x43, 0x8a, 0xcb, 0xe2, 0x37, 0xf6, 0x9d, 0xfb, 0x31, 0x16, 0xc2, 0x90, 0x7b, 0x46, 0xc5,
-	0xef, 0xdd, 0x94, 0x85, 0x74, 0x39, 0x76, 0xa7, 0xf3, 0x62, 0x37, 0x72, 0x42, 0x17, 0xaf, 0x6f,
-	0x9b, 0xe7, 0xb9, 0xff, 0x79, 0x29, 0xbf, 0xa6, 0xa8, 0x48, 0x93, 0x80, 0x6f, 0x81, 0x7e, 0xec,
-	0xc7, 0x9e, 0x79, 0x81, 0x1f, 0xdf, 0x27, 0x8d, 0x3e, 0xb5, 0x5f, 0x96, 0xfd, 0xd8, 0x43, 0x5c,
-	0x33, 0x7c, 0x01, 0x9c, 0xf5, 0xac, 0x03, 0x96, 0x04, 0x30, 0x89, 0xd8, 0x45, 0x73, 0x82, 0xcf,
-	0x7b, 0x9c, 0x15, 0xb1, 0x6b, 0x3a, 0x03, 0xb5, 0xca, 0xf1, 0x81, 0x8e, 0xaf, 0x0d, 0x9c, 0xd4,
-	0x06, 0xea, 0x0c, 0xd4, 0x2a, 0xc7, 0x9c, 0x4c, 0xf0, 0xfd, 0xd8, 0x21, 0xd8, 0x36, 0xbf, 0xc4,
-	0xeb, 0x5e, 0xd9, 0xdf, 0x15, 0x34, 0xa4, 0xb8, 0xf0, 0x7e, 0xd2, 0x72, 0x30, 0xf9, 0xe6, 0xdb,
-	0xe8, 0x59, 0xea, 0x5e, 0x27, 0x0b, 0x84, 0x58, 0x87, 0xe2, 0x54, 0xd1, 0x9b, 0x0d, 0xd0, 0x07,
-	0x79, 0xcb, 0x75, 0xd7, 0xb7, 0xcd, 0x8b, 0xdc, 0xe3, 0x3d, 0x3c, 0x2d, 0x54, 0x86, 0x59, 0x60,
-	0xfa, 0x91, 0x80, 0x61, 0x78, 0x81, 0xcf, 0x62, 0x61, 0xea, 0xd4, 0xf0, 0xd6, 0x99, 0x7e, 0x24,
-	0x60, 0xf8, 0xfc, 0xfc, 0xc3, 0xf5, 0x6d, 0xf3, 0xb1, 0xd3, 0x9b, 0x1f, 0xd3, 0x8f, 0x04, 0x0c,
-	0xb4, 0x41, 0x9f, 0x1f, 0x44, 0xe6, 0xa5, 0x5e, 0x9f, 0xbd, 0xfc, 0x34, 0xb9, 0x1d, 0x44, 0x88,
-	0xa9, 0x87, 0x3f, 0x35, 0x00, 0x08, 0xd3, 0x48, 0xbc, 0x7c, 0xd2, 0x16, 0x40, 0x06, 0xad, 0x9c,
-	0x46, 0xef, 0xb2, 0x1f, 0x91, 0xc3, 0xf4, 0x5e, 0xa3, 0x45, 0xb9, 0x66, 0x00, 0xfc, 0xa5, 0x01,
-	0x2e, 0xe8, 0xe5, 0xae, 0xb2, 0x6c, 0x9a, 0xfb, 0x61, 0xbd, 0x87, 0x81, 0x5c, 0x09, 0x02, 0xb7,
-	0x62, 0x36, 0x1b, 0xc5, 0x0b, 0x0b, 0x1d, 0x00, 0x51, 0x47, 0x33, 0xe0, 0x6f, 0x0d, 0x30, 0x2e,
-	0xb3, 0xa3, 0x66, 0x5c, 0x91, 0xbb, 0xed, 0xad, 0x1e, 0xba, 0x2d, 0x0b, 0x21, 0xbc, 0xa7, 0xbe,
-	0x32, 0xb6, 0xf1, 0x51, 0xbb, 0x55, 0xf0, 0x0f, 0x06, 0x18, 0xb1, 0x71, 0x88, 0x7d, 0x1b, 0xfb,
-	0x35, 0x66, 0xe6, 0xcc, 0x49, 0xfb, 0x0a, 0x59, 0x33, 0x97, 0x34, 0xed, 0xc2, 0xc2, 0xb2, 0xb4,
-	0x70, 0x44, 0x67, 0x1d, 0x35, 0x8a, 0x93, 0xe9, 0x50, 0x9d, 0x83, 0x5a, 0x0c, 0x84, 0x3f, 0x33,
-	0xc0, 0x68, 0xea, 0x76, 0x71, 0x40, 0x5c, 0x39, 0x9d, 0x85, 0xe7, 0x25, 0xe8, 0x42, 0x2b, 0x16,
-	0xca, 0x82, 0xc3, 0xdf, 0x19, 0xac, 0xda, 0x4a, 0xee, 0x6a, 0xd4, 0x2c, 0x71, 0x0f, 0xbe, 0xde,
-	0x4b, 0x0f, 0x2a, 0xe5, 0xc2, 0x81, 0xd7, 0xd3, 0x4a, 0x4e, 0x71, 0x8e, 0x1a, 0xc5, 0x09, 0xdd,
-	0x7f, 0x8a, 0x81, 0x74, 0xe3, 0xe0, 0xbb, 0x06, 0x18, 0xc1, 0x69, 0xc1, 0x4c, 0xcd, 0xab, 0x27,
-	0x75, 0x5d, 0xc7, 0xf2, 0x5b, 0x5c, 0xa7, 0x35, 0x16, 0x45, 0x2d, 0xb0, 0xac, 0xf6, 0xc3, 0x07,
-	0x96, 0x17, 0xba, 0xd8, 0xfc, 0x72, 0xef, 0x6a, 0xbf, 0x65, 0xa1, 0x12, 0x25, 0xba, 0xe1, 0x75,
-	0x50, 0xf0, 0x63, 0xd7, 0xb5, 0xb6, 0x5c, 0x6c, 0x3e, 0xce, 0xab, 0x08, 0xd5, 0x5f, 0xbc, 0x2d,
-	0xe9, 0x48, 0x49, 0xc0, 0x6d, 0x30, 0x73, 0x70, 0x4b, 0x3d, 0xbe, 0xe8, 0xd8, 0xc0, 0x33, 0xaf,
-	0x71, 0x2d, 0x53, 0xcd, 0x46, 0x71, 0x72, 0xb3, 0x73, 0x8b, 0xef, 0xa1, 0x3a, 0xe0, 0x1b, 0xe0,
-	0x31, 0x4d, 0x66, 0xd9, 0xdb, 0xc2, 0xb6, 0x8d, 0xed, 0xe4, 0xa2, 0x65, 0x7e, 0x85, 0x43, 0xa8,
-	0x7d, 0xbc, 0x99, 0x15, 0x40, 0x0f, 0x1a, 0x0d, 0x57, 0xc1, 0xa4, 0xc6, 0x5e, 0xf1, 0xa3, 0x75,
-	0x52, 0x8d, 0x88, 0xe3, 0xd7, 0xcd, 0x59, 0xae, 0xf7, 0x42, 0xb2, 0xfb, 0x36, 0x35, 0x1e, 0xea,
-	0x32, 0x06, 0xbe, 0xdc, 0xa2, 0x8d, 0x7f, 0xb8, 0xb0, 0xc2, 0x5b, 0xf8, 0x90, 0x9a, 0x4f, 0xf0,
-	0xe2, 0x82, 0xaf, 0xf3, 0xa6, 0x46, 0x47, 0x5d, 0xe4, 0xe1, 0xb7, 0xc1, 0xf9, 0x0c, 0x87, 0xdd,
-	0x2b, 0xcc, 0x27, 0xc5, 0x05, 0x81, 0x55, 0xa2, 0x9b, 0x09, 0x11, 0x75, 0x92, 0x84, 0xdf, 0x04,
-	0x50, 0x23, 0xaf, 0x59, 0x21, 0x1f, 0xff, 0x94, 0xb8, 0xab, 0xb0, 0x15, 0xdd, 0x94, 0x34, 0xd4,
-	0x41, 0x0e, 0x7e, 0x68, 0xb4, 0xcc, 0x24, 0xbd, 0xcd, 0x52, 0xf3, 0x3a, 0xdf, 0xb0, 0x2f, 0x1f,
-	0x3f, 0x00, 0x53, 0x65, 0x28, 0x76, 0xb1, 0xe6, 0x61, 0x0d, 0x05, 0x75, 0x41, 0x9f, 0x62, 0x97,
-	0xe9, 0x4c, 0x0e, 0x87, 0x63, 0xa0, 0x6f, 0x17, 0xcb, 0xcf, 0xc6, 0x88, 0xfd, 0x84, 0x6f, 0x82,
-	0xfc, 0x9e, 0xe5, 0xc6, 0x49, 0x2b, 0xa0, 0x77, 0x67, 0x3d, 0x12, 0x7a, 0x5f, 0xcc, 0xdd, 0x30,
-	0xa6, 0xde, 0x37, 0xc0, 0x64, 0xe7, 0x53, 0xe5, 0x8b, 0xb2, 0xe8, 0x17, 0x06, 0x18, 0x6f, 0x3b,
-	0x40, 0x3a, 0x18, 0xe3, 0xb6, 0x1a, 0x73, 0xaf, 0x87, 0x27, 0x81, 0xd8, 0x08, 0xbc, 0xa2, 0xd5,
-	0x2d, 0xfb, 0x89, 0x01, 0xc6, 0xb2, 0x89, 0xf9, 0x0b, 0xf2, 0x52, 0xe9, 0xbd, 0x1c, 0x98, 0xec,
-	0x5c, 0x83, 0x43, 0x4f, 0x75, 0x17, 0x7a, 0xde, 0xa0, 0xe9, 0xd4, 0xb2, 0x7d, 0xc7, 0x00, 0xc3,
-	0x6f, 0x2b, 0xb9, 0xe4, 0x6b, 0x66, 0x2f, 0xbb, 0x42, 0xc9, 0xd1, 0x97, 0x32, 0x28, 0xd2, 0x21,
-	0x4b, 0xbf, 0x37, 0xc0, 0x44, 0xc7, 0xe3, 0x1c, 0x5e, 0x03, 0x03, 0x96, 0xeb, 0x06, 0xfb, 0xa2,
-	0x9b, 0xa7, 0xb5, 0xe5, 0x17, 0x38, 0x15, 0x49, 0xae, 0xe6, 0xb3, 0xdc, 0xe7, 0xe0, 0xb3, 0xd2,
-	0x9f, 0x0c, 0x70, 0xe9, 0x41, 0x51, 0xf7, 0x79, 0xaf, 0xe1, 0x2c, 0x28, 0xc8, 0x62, 0xfb, 0x90,
-	0xaf, 0x9f, 0xcc, 0xae, 0x32, 0x23, 0xf0, 0xd7, 0x32, 0xe2, 0x57, 0xe9, 0xd7, 0x06, 0x18, 0xab,
-	0x62, 0xb2, 0xe7, 0xd4, 0x30, 0xc2, 0xdb, 0x98, 0x60, 0xbf, 0x86, 0xe1, 0x1c, 0x18, 0xe2, 0x5f,
-	0x1b, 0x43, 0xab, 0x96, 0x7c, 0x23, 0x19, 0x97, 0x8e, 0x1e, 0xba, 0x9d, 0x30, 0x50, 0x2a, 0xa3,
-	0xbe, 0xa7, 0xe4, 0xba, 0x7e, 0x4f, 0xb9, 0x04, 0xfa, 0xc3, 0xb4, 0x01, 0x5c, 0x60, 0x5c, 0xde,
-	0xf3, 0xe5, 0x54, 0xce, 0x0d, 0x48, 0xc4, 0xbb, 0x5c, 0x79, 0xc9, 0x0d, 0x48, 0x84, 0x38, 0xb5,
-	0xf4, 0x41, 0x0e, 0x9c, 0x6b, 0xcd, 0xcf, 0x0c, 0x90, 0xc4, 0x6e, 0xdb, 0x07, 0x1c, 0xc6, 0x43,
-	0x9c, 0xa3, 0xbf, 0x1b, 0xc8, 0x3d, 0xf8, 0xdd, 0x00, 0x7c, 0x09, 0x8c, 0xcb, 0x9f, 0xcb, 0x07,
-	0x21, 0xc1, 0x94, 0x7f, 0x99, 0xec, 0x6b, 0x7d, 0xef, 0xb7, 0x96, 0x15, 0x40, 0xed, 0x63, 0xe0,
-	0x37, 0x32, 0x6f, 0x1a, 0xae, 0xa6, 0xef, 0x19, 0x58, 0x6d, 0xc7, 0x4b, 0x87, 0x7b, 0x6c, 0xcb,
-	0x2f, 0x13, 0x12, 0x90, 0xcc, 0x43, 0x87, 0x39, 0x30, 0xb4, 0xcd, 0x04, 0x78, 0x9f, 0x3c, 0xdf,
-	0xea, 0xf4, 0x9b, 0x09, 0x03, 0xa5, 0x32, 0xa5, 0x3f, 0x1b, 0xe0, 0x7c, 0xf2, 0x1a, 0xc8, 0x75,
-	0xb0, 0x1f, 0x2d, 0x06, 0xfe, 0xb6, 0x53, 0x87, 0x17, 0x45, 0xff, 0x53, 0x6b, 0x2a, 0x26, 0xbd,
-	0x4f, 0x78, 0x1f, 0x0c, 0x52, 0xb1, 0xd8, 0x32, 0x0e, 0x5f, 0x39, 0x7e, 0x1c, 0x66, 0xa3, 0x46,
-	0x94, 0x6f, 0x09, 0x35, 0xc1, 0x61, 0xa1, 0x58, 0xb3, 0x2a, 0xb1, 0x6f, 0xcb, 0x1e, 0xf8, 0x88,
-	0x08, 0xc5, 0xc5, 0x05, 0x41, 0x43, 0x8a, 0x5b, 0xfa, 0xa7, 0x01, 0xc6, 0xdb, 0x5e, 0x37, 0xc1,
-	0x1f, 0x1a, 0x60, 0xa4, 0xa6, 0x4d, 0x4f, 0x6e, 0xe8, 0xb5, 0x93, 0xbf, 0xa0, 0xd2, 0x94, 0x8a,
-	0x1a, 0x48, 0xa7, 0xa0, 0x16, 0x50, 0xb8, 0x09, 0xcc, 0x5a, 0xe6, 0x21, 0x61, 0xe6, 0xd3, 0xe4,
-	0xa5, 0x66, 0xa3, 0x68, 0x2e, 0x76, 0x91, 0x41, 0x5d, 0x47, 0x57, 0xbe, 0xfb, 0xf1, 0x67, 0xd3,
-	0x67, 0x3e, 0xf9, 0x6c, 0xfa, 0xcc, 0xa7, 0x9f, 0x4d, 0x9f, 0x79, 0xa7, 0x39, 0x6d, 0x7c, 0xdc,
-	0x9c, 0x36, 0x3e, 0x69, 0x4e, 0x1b, 0x9f, 0x36, 0xa7, 0x8d, 0xbf, 0x35, 0xa7, 0x8d, 0x9f, 0xff,
-	0x7d, 0xfa, 0xcc, 0xeb, 0x37, 0x8e, 0xfb, 0x7c, 0xf8, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x1d,
-	0x01, 0xc1, 0x04, 0x92, 0x2c, 0x00, 0x00,
+	// 3137 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x5a, 0xdf, 0x6f, 0x5c, 0x47,
+	0xf5, 0xcf, 0x5d, 0x7b, 0xed, 0xf5, 0xd8, 0x89, 0xed, 0x49, 0xec, 0xef, 0x8d, 0x9b, 0x78, 0x9d,
+	0xcd, 0xb7, 0xc1, 0x6d, 0xd3, 0x75, 0x1b, 0x5a, 0x1a, 0xca, 0x2f, 0x79, 0x6d, 0xa7, 0x75, 0x13,
+	0xc7, 0xd6, 0x6c, 0x92, 0xba, 0x2d, 0xa2, 0xbd, 0xde, 0x3b, 0xbb, 0xbe, 0xf5, 0xfd, 0x95, 0x99,
+	0x7b, 0xfd, 0x43, 0x02, 0xa9, 0x02, 0x55, 0x40, 0x25, 0x28, 0x0f, 0xa8, 0x3c, 0x21, 0x84, 0x50,
+	0x1f, 0xe0, 0x01, 0xde, 0xe0, 0x5f, 0xe8, 0x0b, 0x52, 0x25, 0x24, 0x54, 0x09, 0x69, 0x45, 0x97,
+	0x7f, 0x00, 0x09, 0x10, 0xc2, 0x0f, 0x08, 0xcd, 0x8f, 0x3b, 0x77, 0xf6, 0xee, 0x6e, 0x12, 0xd9,
+	0xeb, 0xf6, 0x6d, 0xf7, 0x9c, 0x33, 0xe7, 0x73, 0xe6, 0xcc, 0x99, 0x33, 0x67, 0xce, 0x1d, 0x60,
+	0xed, 0x5c, 0xa7, 0x65, 0x27, 0x58, 0xd8, 0x89, 0xb7, 0x30, 0xf1, 0x71, 0x84, 0xe9, 0xc2, 0x2e,
+	0xf6, 0xed, 0x80, 0x2c, 0x48, 0x86, 0x15, 0x3a, 0x78, 0x3f, 0xc2, 0x3e, 0x75, 0x02, 0x9f, 0x3e,
+	0x6d, 0x85, 0x0e, 0xc5, 0x64, 0x17, 0x93, 0x85, 0x70, 0xa7, 0xc1, 0x78, 0xb4, 0x5d, 0x60, 0x61,
+	0xf7, 0xd9, 0x85, 0x06, 0xf6, 0x31, 0xb1, 0x22, 0x6c, 0x97, 0x43, 0x12, 0x44, 0x01, 0xbc, 0x2e,
+	0x34, 0x95, 0xdb, 0x04, 0xdf, 0x54, 0x9a, 0xca, 0xe1, 0x4e, 0x83, 0xf1, 0x68, 0xbb, 0x40, 0x79,
+	0xf7, 0xd9, 0x99, 0xa7, 0x1b, 0x4e, 0xb4, 0x1d, 0x6f, 0x95, 0x6b, 0x81, 0xb7, 0xd0, 0x08, 0x1a,
+	0xc1, 0x02, 0x57, 0xb8, 0x15, 0xd7, 0xf9, 0x3f, 0xfe, 0x87, 0xff, 0x12, 0x40, 0x33, 0xcf, 0xa5,
+	0x26, 0x7b, 0x56, 0x6d, 0xdb, 0xf1, 0x31, 0x39, 0x48, 0xed, 0xf4, 0x70, 0x64, 0x75, 0x31, 0x6f,
+	0x66, 0xa1, 0xd7, 0x28, 0x12, 0xfb, 0x91, 0xe3, 0xe1, 0x8e, 0x01, 0x5f, 0x7a, 0xd8, 0x00, 0x5a,
+	0xdb, 0xc6, 0x9e, 0x95, 0x1d, 0x57, 0x3a, 0x34, 0xc0, 0xe4, 0x52, 0xe0, 0xef, 0x62, 0xc2, 0x26,
+	0x88, 0xf0, 0xfd, 0x18, 0xd3, 0x08, 0x56, 0xc0, 0x40, 0xec, 0xd8, 0xa6, 0x31, 0x67, 0xcc, 0x8f,
+	0x54, 0x9e, 0xf9, 0xa8, 0x59, 0x3c, 0xd5, 0x6a, 0x16, 0x07, 0xee, 0xae, 0x2e, 0x1f, 0x36, 0x8b,
+	0x97, 0x7a, 0x21, 0x45, 0x07, 0x21, 0xa6, 0xe5, 0xbb, 0xab, 0xcb, 0x88, 0x0d, 0x86, 0x2f, 0x81,
+	0x49, 0x1b, 0x53, 0x87, 0x60, 0x7b, 0x71, 0x63, 0xf5, 0x9e, 0xd0, 0x6f, 0xe6, 0xb8, 0xc6, 0xf3,
+	0x52, 0xe3, 0xe4, 0x72, 0x56, 0x00, 0x75, 0x8e, 0x81, 0x9b, 0x60, 0x38, 0xd8, 0x7a, 0x1b, 0xd7,
+	0x22, 0x6a, 0x0e, 0xcc, 0x0d, 0xcc, 0x8f, 0x5e, 0x7b, 0xba, 0x9c, 0x2e, 0x9e, 0x32, 0x81, 0xaf,
+	0x98, 0x9c, 0x6c, 0x19, 0x59, 0x7b, 0x2b, 0xc9, 0xa2, 0x55, 0xc6, 0x25, 0xda, 0xf0, 0xba, 0xd0,
+	0x82, 0x12, 0x75, 0xa5, 0x5f, 0xe5, 0x00, 0xd4, 0x27, 0x4f, 0xc3, 0xc0, 0xa7, 0xb8, 0x2f, 0xb3,
+	0xa7, 0x60, 0xa2, 0xc6, 0x35, 0x47, 0xd8, 0x96, 0xb8, 0x66, 0xee, 0x28, 0xd6, 0x9b, 0x12, 0x7f,
+	0x62, 0x29, 0xa3, 0x0e, 0x75, 0x00, 0xc0, 0x3b, 0x60, 0x88, 0x60, 0x1a, 0xbb, 0x91, 0x39, 0x30,
+	0x67, 0xcc, 0x8f, 0x5e, 0xbb, 0xda, 0x13, 0x8a, 0x87, 0x36, 0x0b, 0xbe, 0xf2, 0xee, 0xb3, 0xe5,
+	0x6a, 0x64, 0x45, 0x31, 0xad, 0x9c, 0x91, 0x48, 0x43, 0x88, 0xeb, 0x40, 0x52, 0x57, 0xe9, 0xbf,
+	0x06, 0x98, 0xd0, 0xbd, 0xb4, 0xeb, 0xe0, 0x3d, 0x48, 0xc0, 0x30, 0x11, 0xc1, 0xc2, 0xfd, 0x34,
+	0x7a, 0xed, 0x66, 0xf9, 0xa8, 0x3b, 0xaa, 0xdc, 0x11, 0x7f, 0x95, 0x51, 0xb6, 0x5c, 0xf2, 0x0f,
+	0x4a, 0x80, 0xe0, 0x2e, 0x28, 0x10, 0xb9, 0x46, 0x3c, 0x90, 0x46, 0xaf, 0xdd, 0xea, 0x0f, 0xa8,
+	0xd0, 0x59, 0x19, 0x6b, 0x35, 0x8b, 0x85, 0xe4, 0x1f, 0x52, 0x58, 0xa5, 0x5f, 0xe4, 0xc0, 0xec,
+	0x52, 0x4c, 0xa3, 0xc0, 0x43, 0x98, 0x06, 0x31, 0xa9, 0xe1, 0xa5, 0xc0, 0x8d, 0x3d, 0x7f, 0x19,
+	0xd7, 0x1d, 0xdf, 0x89, 0x58, 0x8c, 0xce, 0x81, 0x41, 0xdf, 0xf2, 0xb0, 0x8c, 0x99, 0x31, 0xe9,
+	0xc9, 0xc1, 0xdb, 0x96, 0x87, 0x11, 0xe7, 0x30, 0x09, 0x16, 0x22, 0x72, 0x07, 0x28, 0x89, 0x3b,
+	0x07, 0x21, 0x46, 0x9c, 0x03, 0xaf, 0x80, 0xa1, 0x7a, 0x40, 0x3c, 0x4b, 0xac, 0xde, 0x48, 0xba,
+	0x1e, 0x37, 0x38, 0x15, 0x49, 0x2e, 0x7c, 0x1e, 0x8c, 0xda, 0x98, 0xd6, 0x88, 0x13, 0x32, 0x68,
+	0x73, 0x90, 0x0b, 0x9f, 0x95, 0xc2, 0xa3, 0xcb, 0x29, 0x0b, 0xe9, 0x72, 0xf0, 0x2a, 0x28, 0x84,
+	0xc4, 0x09, 0x88, 0x13, 0x1d, 0x98, 0xf9, 0x39, 0x63, 0x3e, 0x5f, 0x99, 0x90, 0x63, 0x0a, 0x1b,
+	0x92, 0x8e, 0x94, 0x04, 0x93, 0x7e, 0x9b, 0x06, 0xfe, 0x86, 0x15, 0x6d, 0x9b, 0x43, 0x1c, 0x41,
+	0x49, 0xbf, 0x52, 0x5d, 0xbf, 0xcd, 0xe8, 0x48, 0x49, 0x94, 0xfe, 0x6c, 0x00, 0x33, 0xeb, 0xa1,
+	0xc4, 0xbd, 0xf0, 0x06, 0x28, 0xd0, 0x88, 0xe5, 0x9c, 0xc6, 0x81, 0xf4, 0xcf, 0x93, 0x89, 0xaa,
+	0xaa, 0xa4, 0x1f, 0x36, 0x8b, 0xd3, 0xe9, 0x88, 0x84, 0xca, 0x7d, 0xa3, 0xc6, 0xb2, 0x90, 0xdb,
+	0xc3, 0x5b, 0xdb, 0x41, 0xb0, 0x23, 0x57, 0xff, 0x18, 0x21, 0xf7, 0xaa, 0x50, 0x94, 0x62, 0x8a,
+	0x90, 0x93, 0x64, 0x94, 0x00, 0x95, 0xfe, 0x93, 0xcb, 0x4e, 0x4c, 0x5b, 0xf4, 0xb7, 0x40, 0x81,
+	0x6d, 0x21, 0xdb, 0x8a, 0x2c, 0xb9, 0x09, 0x9e, 0x79, 0xb4, 0x0d, 0x27, 0xf6, 0xeb, 0x1a, 0x8e,
+	0xac, 0x0a, 0x94, 0xae, 0x00, 0x29, 0x0d, 0x29, 0xad, 0x70, 0x1f, 0x0c, 0xd2, 0x10, 0xd7, 0xe4,
+	0x7c, 0xef, 0x1d, 0x23, 0xda, 0x7b, 0xcc, 0xa1, 0x1a, 0xe2, 0x5a, 0x1a, 0x8c, 0xec, 0x1f, 0xe2,
+	0x88, 0xf0, 0x1d, 0x03, 0x0c, 0x51, 0x9e, 0x17, 0x64, 0x2e, 0xd9, 0x3c, 0x01, 0xf0, 0x4c, 0xde,
+	0x11, 0xff, 0x91, 0xc4, 0x2d, 0xfd, 0x33, 0x07, 0x2e, 0xf5, 0x1a, 0xba, 0x14, 0xf8, 0xb6, 0x58,
+	0x84, 0x55, 0xb9, 0xaf, 0x44, 0x64, 0x3d, 0xaf, 0xef, 0xab, 0xc3, 0x66, 0xf1, 0xf1, 0x87, 0x2a,
+	0xd0, 0x36, 0xe0, 0x97, 0xd5, 0x94, 0xc5, 0x26, 0xbd, 0xd4, 0x6e, 0xd8, 0x61, 0xb3, 0x38, 0xae,
+	0x86, 0xb5, 0xdb, 0x0a, 0x77, 0x01, 0x74, 0x2d, 0x1a, 0xdd, 0x21, 0x96, 0x4f, 0x85, 0x5a, 0xc7,
+	0xc3, 0xd2, 0x73, 0x4f, 0x3e, 0x5a, 0x50, 0xb0, 0x11, 0x95, 0x19, 0x09, 0x09, 0x6f, 0x75, 0x68,
+	0x43, 0x5d, 0x10, 0x58, 0xce, 0x20, 0xd8, 0xa2, 0x2a, 0x0d, 0x68, 0x39, 0x9c, 0x51, 0x91, 0xe4,
+	0xc2, 0x27, 0xc0, 0xb0, 0x87, 0x29, 0xb5, 0x1a, 0x98, 0xef, 0xfd, 0x91, 0xf4, 0x50, 0x5c, 0x13,
+	0x64, 0x94, 0xf0, 0x4b, 0xff, 0x32, 0xc0, 0x85, 0x5e, 0x5e, 0xbb, 0xe5, 0xd0, 0x08, 0x7e, 0xb3,
+	0x23, 0xec, 0xcb, 0x8f, 0x36, 0x43, 0x36, 0x9a, 0x07, 0xbd, 0x4a, 0x25, 0x09, 0x45, 0x0b, 0xf9,
+	0x3d, 0x90, 0x77, 0x22, 0xec, 0x25, 0xa7, 0x25, 0xea, 0x7f, 0xd8, 0x55, 0x4e, 0x4b, 0xf8, 0xfc,
+	0x2a, 0x03, 0x42, 0x02, 0xaf, 0xf4, 0x61, 0x0e, 0x5c, 0xec, 0x35, 0x84, 0xe5, 0x71, 0xca, 0x9c,
+	0x1d, 0xba, 0x31, 0xb1, 0x5c, 0x19, 0x6c, 0xca, 0xd9, 0x1b, 0x9c, 0x8a, 0x24, 0x97, 0xe5, 0x4e,
+	0xea, 0xf8, 0x8d, 0xd8, 0xb5, 0x88, 0x8c, 0x24, 0x35, 0xe1, 0xaa, 0xa4, 0x23, 0x25, 0x01, 0xcb,
+	0x00, 0xd0, 0xed, 0x80, 0x44, 0x1c, 0x83, 0x57, 0x38, 0x23, 0x95, 0x33, 0x2c, 0x23, 0x54, 0x15,
+	0x15, 0x69, 0x12, 0xec, 0x20, 0xd9, 0x71, 0x7c, 0x5b, 0x2e, 0xb8, 0xda, 0xbb, 0x37, 0x1d, 0xdf,
+	0x46, 0x9c, 0xc3, 0xf0, 0x5d, 0x87, 0x46, 0x8c, 0x22, 0x57, 0xbb, 0xcd, 0xe1, 0x5c, 0x52, 0x49,
+	0x30, 0xfc, 0x1a, 0x4b, 0xb0, 0x01, 0x71, 0x30, 0x35, 0x87, 0x52, 0xfc, 0x25, 0x45, 0x45, 0x9a,
+	0x44, 0xe9, 0x2f, 0x83, 0xbd, 0xe3, 0x83, 0x25, 0x10, 0x78, 0x19, 0xe4, 0x1b, 0x24, 0x88, 0x43,
+	0xe9, 0x25, 0xe5, 0xed, 0x97, 0x18, 0x11, 0x09, 0x1e, 0xfc, 0x36, 0xc8, 0xfb, 0x72, 0xc2, 0x2c,
+	0x82, 0x5e, 0xed, 0xff, 0x32, 0x73, 0x6f, 0xa5, 0xe8, 0xc2, 0x91, 0x02, 0x14, 0x3e, 0x07, 0xf2,
+	0xb4, 0x16, 0x84, 0x58, 0x3a, 0x71, 0x36, 0x11, 0xaa, 0x32, 0xe2, 0x61, 0xb3, 0x78, 0x3a, 0x51,
+	0xc7, 0x09, 0x48, 0x08, 0xc3, 0xef, 0x1b, 0xa0, 0x20, 0x8f, 0x0b, 0x6a, 0x0e, 0xf3, 0xf0, 0x7c,
+	0xad, 0xff, 0x76, 0xcb, 0xb2, 0x37, 0x5d, 0x33, 0x49, 0xa0, 0x48, 0x81, 0xc3, 0xef, 0x1a, 0x00,
+	0xd4, 0xd4, 0xd9, 0x65, 0x8e, 0x70, 0x1f, 0xf6, 0x6d, 0xab, 0x68, 0xa7, 0xa2, 0x08, 0x84, 0xb4,
+	0x54, 0xd2, 0x50, 0x61, 0x15, 0x4c, 0x85, 0x04, 0x73, 0xdd, 0x77, 0xfd, 0x1d, 0x3f, 0xd8, 0xf3,
+	0x6f, 0x38, 0xd8, 0xb5, 0xa9, 0x09, 0xe6, 0x8c, 0xf9, 0x42, 0xe5, 0xa2, 0xb4, 0x7f, 0x6a, 0xa3,
+	0x9b, 0x10, 0xea, 0x3e, 0xb6, 0xf4, 0xee, 0x40, 0xb6, 0xd6, 0xca, 0x9e, 0x17, 0xf0, 0x7d, 0x31,
+	0x79, 0x91, 0x87, 0xa9, 0x69, 0xf0, 0x85, 0x78, 0xa3, 0xff, 0x0b, 0xa1, 0x72, 0x7d, 0x7a, 0x48,
+	0x2b, 0x12, 0x45, 0x9a, 0x09, 0xf0, 0xa7, 0x06, 0x38, 0x6d, 0xd5, 0x6a, 0x38, 0x8c, 0xb0, 0x2d,
+	0xb6, 0x71, 0xee, 0x64, 0xa3, 0x7a, 0x4a, 0x1a, 0x74, 0x7a, 0x51, 0x47, 0x45, 0xed, 0x46, 0xc0,
+	0x17, 0xc1, 0x19, 0x1a, 0x05, 0x04, 0xdb, 0x49, 0x04, 0xc9, 0xec, 0x02, 0x5b, 0xcd, 0xe2, 0x99,
+	0x6a, 0x1b, 0x07, 0x65, 0x24, 0x4b, 0x1f, 0xe7, 0x41, 0xf1, 0x21, 0x11, 0xfa, 0x08, 0x45, 0xef,
+	0x15, 0x30, 0xc4, 0x67, 0x6a, 0x73, 0x87, 0x14, 0xb4, 0xa3, 0x9e, 0x53, 0x91, 0xe4, 0xb2, 0xe3,
+	0x89, 0xe1, 0xb3, 0xe3, 0x69, 0x80, 0x0b, 0xaa, 0xe3, 0xa9, 0x2a, 0xc8, 0x28, 0xe1, 0xc3, 0x6b,
+	0x00, 0xd8, 0x38, 0x24, 0x98, 0x65, 0x24, 0xdb, 0x1c, 0xe6, 0xd2, 0x6a, 0x7d, 0x96, 0x15, 0x07,
+	0x69, 0x52, 0xf0, 0x06, 0x80, 0xc9, 0x3f, 0x27, 0xf0, 0x5f, 0xb5, 0x88, 0xef, 0xf8, 0x0d, 0xb3,
+	0xc0, 0xcd, 0x9e, 0x66, 0xa7, 0xed, 0x72, 0x07, 0x17, 0x75, 0x19, 0x01, 0x77, 0xc1, 0x90, 0xb8,
+	0x46, 0xf3, 0xbc, 0xd1, 0xc7, 0x1d, 0x77, 0xcf, 0x72, 0x1d, 0x9b, 0x43, 0x55, 0x00, 0x77, 0x0f,
+	0x47, 0x41, 0x12, 0x0d, 0xbe, 0x67, 0x80, 0x31, 0x1a, 0x6f, 0x11, 0x29, 0x4d, 0x79, 0x56, 0x1f,
+	0xbd, 0x76, 0xa7, 0x5f, 0xf0, 0x55, 0x4d, 0x77, 0x65, 0xa2, 0xd5, 0x2c, 0x8e, 0xe9, 0x14, 0xd4,
+	0x86, 0x0d, 0x7f, 0x6f, 0x00, 0xd3, 0xb2, 0x45, 0xe8, 0x5b, 0xee, 0x06, 0x71, 0xfc, 0x08, 0x13,
+	0x71, 0x21, 0x12, 0xc7, 0x47, 0x1f, 0x6b, 0xc5, 0xec, 0x3d, 0xab, 0x32, 0x27, 0x57, 0xda, 0x5c,
+	0xec, 0x61, 0x01, 0xea, 0x69, 0x5b, 0xe9, 0xdf, 0x46, 0x36, 0xb5, 0x68, 0xb3, 0xac, 0xd6, 0x2c,
+	0x17, 0xc3, 0x65, 0x30, 0xc1, 0xaa, 0x5f, 0x84, 0x43, 0xd7, 0xa9, 0x59, 0x94, 0xdf, 0x7e, 0x44,
+	0x74, 0xab, 0x6b, 0x78, 0x35, 0xc3, 0x47, 0x1d, 0x23, 0xe0, 0x2b, 0x00, 0x8a, 0xb2, 0xb0, 0x4d,
+	0x8f, 0xa8, 0x04, 0x54, 0x81, 0x57, 0xed, 0x90, 0x40, 0x5d, 0x46, 0xc1, 0x25, 0x30, 0xe9, 0x5a,
+	0x5b, 0xd8, 0xad, 0x62, 0x17, 0xd7, 0xa2, 0x80, 0x70, 0x55, 0xe2, 0x7e, 0x38, 0xd5, 0x6a, 0x16,
+	0x27, 0x6f, 0x65, 0x99, 0xa8, 0x53, 0xbe, 0x74, 0x29, 0xbb, 0x97, 0xf5, 0x89, 0x8b, 0x62, 0xfb,
+	0x83, 0x1c, 0x98, 0xe9, 0x1d, 0x14, 0xf0, 0x3b, 0xaa, 0x34, 0x16, 0x15, 0xdf, 0x6b, 0x27, 0x10,
+	0x7a, 0xf2, 0x3a, 0x00, 0x3a, 0xaf, 0x02, 0xf0, 0x80, 0x9d, 0xd7, 0x96, 0x9b, 0x5c, 0xfb, 0x37,
+	0x4f, 0x02, 0x9d, 0xe9, 0xaf, 0x8c, 0x88, 0x2a, 0xc0, 0x72, 0xf9, 0xa1, 0x6f, 0xb9, 0xb8, 0xf4,
+	0x61, 0xc7, 0xd5, 0x36, 0xdd, 0xac, 0xf0, 0x07, 0x06, 0x18, 0x0f, 0x42, 0xec, 0x2f, 0x6e, 0xac,
+	0xde, 0xfb, 0xa2, 0xd8, 0xb4, 0xd2, 0x41, 0xab, 0x47, 0x37, 0x91, 0xdd, 0xaf, 0x85, 0xae, 0x0d,
+	0x12, 0x84, 0xb4, 0x72, 0xb6, 0xd5, 0x2c, 0x8e, 0xaf, 0xb7, 0xa3, 0xa0, 0x2c, 0x6c, 0xc9, 0x03,
+	0x53, 0x2b, 0xfb, 0x11, 0x26, 0xbe, 0xe5, 0x2e, 0x07, 0xb5, 0xd8, 0xc3, 0x7e, 0x24, 0x6c, 0xcc,
+	0xb4, 0x0b, 0x8c, 0x47, 0x6c, 0x17, 0x5c, 0x04, 0x03, 0x31, 0x71, 0x65, 0xd4, 0x8e, 0xaa, 0x26,
+	0x18, 0xba, 0x85, 0x18, 0xbd, 0x74, 0x09, 0x0c, 0x32, 0x3b, 0xe1, 0x79, 0x30, 0x40, 0xac, 0x3d,
+	0xae, 0x75, 0xac, 0x32, 0xcc, 0x44, 0x90, 0xb5, 0x87, 0x18, 0xad, 0xf4, 0xf7, 0x39, 0x30, 0x9e,
+	0x99, 0x0b, 0x9c, 0x01, 0x39, 0xd5, 0x59, 0x03, 0x52, 0x69, 0x6e, 0x75, 0x19, 0xe5, 0x1c, 0x1b,
+	0xbe, 0xa0, 0xb2, 0xab, 0x00, 0x2d, 0xaa, 0xc3, 0x82, 0x53, 0x59, 0x59, 0x96, 0xaa, 0x63, 0x86,
+	0x24, 0xe9, 0x91, 0xd9, 0x80, 0xeb, 0x72, 0x57, 0x08, 0x1b, 0x70, 0x1d, 0x31, 0xda, 0x51, 0x7b,
+	0x25, 0x49, 0xb3, 0x26, 0xff, 0x08, 0xcd, 0x9a, 0xa1, 0x07, 0x36, 0x6b, 0x2e, 0x83, 0x7c, 0xe4,
+	0x44, 0x2e, 0xe6, 0x27, 0x95, 0x56, 0x0c, 0xdf, 0x61, 0x44, 0x24, 0x78, 0x10, 0x83, 0x61, 0x1b,
+	0xd7, 0xad, 0xd8, 0x8d, 0xf8, 0xa1, 0x34, 0x7a, 0xed, 0xeb, 0xc7, 0x8b, 0x1e, 0xd1, 0xcc, 0x58,
+	0x16, 0x2a, 0x51, 0xa2, 0x1b, 0x3e, 0x0e, 0x86, 0x3d, 0x6b, 0xdf, 0xf1, 0x62, 0x8f, 0x57, 0x8c,
+	0x86, 0x10, 0x5b, 0x13, 0x24, 0x94, 0xf0, 0x58, 0x12, 0xc4, 0xfb, 0x35, 0x37, 0xa6, 0xce, 0x2e,
+	0x96, 0x4c, 0x59, 0xd2, 0xa9, 0x24, 0xb8, 0x92, 0xe1, 0xa3, 0x8e, 0x11, 0x1c, 0xcc, 0xf1, 0xf9,
+	0xe0, 0x51, 0x0d, 0x4c, 0x90, 0x50, 0xc2, 0x6b, 0x07, 0x93, 0xf2, 0x63, 0xbd, 0xc0, 0xe4, 0xe0,
+	0x8e, 0x11, 0xf0, 0x29, 0x30, 0xe2, 0x59, 0xfb, 0xb7, 0xb0, 0xdf, 0x88, 0xb6, 0xcd, 0xd3, 0x73,
+	0xc6, 0xfc, 0x40, 0xe5, 0x74, 0xab, 0x59, 0x1c, 0x59, 0x4b, 0x88, 0x28, 0xe5, 0x73, 0x61, 0xc7,
+	0x97, 0xc2, 0x67, 0x34, 0xe1, 0x84, 0x88, 0x52, 0x3e, 0xab, 0x4c, 0x42, 0x2b, 0x62, 0xfb, 0xca,
+	0x1c, 0x6f, 0xbf, 0x38, 0x6f, 0x08, 0x32, 0x4a, 0xf8, 0x70, 0x1e, 0x14, 0x3c, 0x6b, 0x9f, 0xdf,
+	0x29, 0xcd, 0x09, 0xae, 0x96, 0x37, 0x14, 0xd7, 0x24, 0x0d, 0x29, 0x2e, 0x97, 0x74, 0x7c, 0x21,
+	0x39, 0xa9, 0x49, 0x4a, 0x1a, 0x52, 0x5c, 0x16, 0xbf, 0xb1, 0xef, 0xdc, 0x8f, 0xb1, 0x10, 0x86,
+	0xdc, 0x33, 0x2a, 0x7e, 0xef, 0xa6, 0x2c, 0xa4, 0xcb, 0xb1, 0x3b, 0x9d, 0x17, 0xbb, 0x91, 0x13,
+	0xba, 0x78, 0xbd, 0x6e, 0x9e, 0xe5, 0xfe, 0xe7, 0xa5, 0xfc, 0x9a, 0xa2, 0x22, 0x4d, 0x02, 0xbe,
+	0x05, 0x06, 0xb1, 0x1f, 0x7b, 0xe6, 0x39, 0x7e, 0x7c, 0x1f, 0x37, 0xfa, 0xd4, 0x7e, 0x59, 0xf1,
+	0x63, 0x0f, 0x71, 0xcd, 0xf0, 0x05, 0x70, 0xda, 0xb3, 0xf6, 0x59, 0x12, 0xc0, 0x24, 0x62, 0x17,
+	0xcd, 0x29, 0x3e, 0xef, 0x49, 0x56, 0xc4, 0xae, 0xe9, 0x0c, 0xd4, 0x2e, 0xc7, 0x07, 0x3a, 0xbe,
+	0x36, 0x70, 0x5a, 0x1b, 0xa8, 0x33, 0x50, 0xbb, 0x1c, 0x73, 0x32, 0xc1, 0xf7, 0x63, 0x87, 0x60,
+	0xdb, 0xfc, 0x3f, 0x5e, 0xf7, 0xca, 0xfe, 0xae, 0xa0, 0x21, 0xc5, 0x85, 0xf7, 0x93, 0x96, 0x83,
+	0xc9, 0x37, 0xdf, 0x46, 0xdf, 0x52, 0xf7, 0x3a, 0x59, 0x24, 0xc4, 0x3a, 0x10, 0xa7, 0x8a, 0xde,
+	0x6c, 0x80, 0x3e, 0xc8, 0x5b, 0xae, 0xbb, 0x5e, 0x37, 0xcf, 0x73, 0x8f, 0xf7, 0xf1, 0xb4, 0x50,
+	0x19, 0x66, 0x91, 0xe9, 0x47, 0x02, 0x86, 0xe1, 0x05, 0x3e, 0x8b, 0x85, 0x99, 0x13, 0xc3, 0x5b,
+	0x67, 0xfa, 0x91, 0x80, 0xe1, 0xf3, 0xf3, 0x0f, 0xd6, 0xeb, 0xe6, 0x63, 0x27, 0x37, 0x3f, 0xa6,
+	0x1f, 0x09, 0x18, 0x68, 0x83, 0x01, 0x3f, 0x88, 0xcc, 0x0b, 0xfd, 0x3e, 0x7b, 0xf9, 0x69, 0x72,
+	0x3b, 0x88, 0x10, 0x53, 0x0f, 0x7f, 0x64, 0x00, 0x10, 0xa6, 0x91, 0x78, 0xf1, 0xb8, 0x2d, 0x80,
+	0x0c, 0x5a, 0x39, 0x8d, 0xde, 0x15, 0x3f, 0x22, 0x07, 0xe9, 0xbd, 0x46, 0x8b, 0x72, 0xcd, 0x00,
+	0xf8, 0x73, 0x03, 0x9c, 0xd3, 0xcb, 0x5d, 0x65, 0xd9, 0x2c, 0xf7, 0xc3, 0x7a, 0x1f, 0x03, 0xb9,
+	0x12, 0x04, 0x6e, 0xc5, 0x6c, 0x35, 0x8b, 0xe7, 0x16, 0xbb, 0x00, 0xa2, 0xae, 0x66, 0xc0, 0x5f,
+	0x1b, 0x60, 0x52, 0x66, 0x47, 0xcd, 0xb8, 0x22, 0x77, 0xdb, 0x5b, 0x7d, 0x74, 0x5b, 0x16, 0x42,
+	0x78, 0x4f, 0x7d, 0x65, 0xec, 0xe0, 0xa3, 0x4e, 0xab, 0xe0, 0xef, 0x0c, 0x30, 0x66, 0xe3, 0x10,
+	0xfb, 0x36, 0xf6, 0x6b, 0xcc, 0xcc, 0xb9, 0xe3, 0xf6, 0x15, 0xb2, 0x66, 0x2e, 0x6b, 0xda, 0x85,
+	0x85, 0x65, 0x69, 0xe1, 0x98, 0xce, 0x3a, 0x6c, 0x16, 0xa7, 0xd3, 0xa1, 0x3a, 0x07, 0xb5, 0x19,
+	0x08, 0x7f, 0x6c, 0x80, 0xf1, 0xd4, 0xed, 0xe2, 0x80, 0xb8, 0x74, 0x32, 0x0b, 0xcf, 0x4b, 0xd0,
+	0xc5, 0x76, 0x2c, 0x94, 0x05, 0x87, 0xbf, 0x31, 0x58, 0xb5, 0x95, 0xdc, 0xd5, 0xa8, 0x59, 0xe2,
+	0x1e, 0x7c, 0xbd, 0x9f, 0x1e, 0x54, 0xca, 0x85, 0x03, 0xaf, 0xa6, 0x95, 0x9c, 0xe2, 0x1c, 0x36,
+	0x8b, 0x53, 0xba, 0xff, 0x14, 0x03, 0xe9, 0xc6, 0xc1, 0x77, 0x0d, 0x30, 0x86, 0xd3, 0x82, 0x99,
+	0x9a, 0x97, 0x8f, 0xeb, 0xba, 0xae, 0xe5, 0xb7, 0xb8, 0x4e, 0x6b, 0x2c, 0x8a, 0xda, 0x60, 0x59,
+	0xed, 0x87, 0xf7, 0x2d, 0x2f, 0x74, 0xb1, 0xf9, 0xff, 0xfd, 0xab, 0xfd, 0x56, 0x84, 0x4a, 0x94,
+	0xe8, 0x86, 0x57, 0x41, 0xc1, 0x8f, 0x5d, 0xd7, 0xda, 0x72, 0xb1, 0xf9, 0x38, 0xaf, 0x22, 0x54,
+	0x7f, 0xf1, 0xb6, 0xa4, 0x23, 0x25, 0x01, 0xeb, 0x60, 0x6e, 0xff, 0xa6, 0x7a, 0x7c, 0xd1, 0xb5,
+	0x81, 0x67, 0x5e, 0xe1, 0x5a, 0x66, 0x5a, 0xcd, 0xe2, 0xf4, 0x66, 0xf7, 0x16, 0xdf, 0x43, 0x75,
+	0xc0, 0x37, 0xc0, 0x63, 0x9a, 0xcc, 0x8a, 0xb7, 0x85, 0x6d, 0x1b, 0xdb, 0xc9, 0x45, 0xcb, 0xfc,
+	0x02, 0x87, 0x50, 0xfb, 0x78, 0x33, 0x2b, 0x80, 0x1e, 0x34, 0x1a, 0xde, 0x02, 0xd3, 0x1a, 0x7b,
+	0xd5, 0x8f, 0xd6, 0x49, 0x35, 0x22, 0x8e, 0xdf, 0x30, 0xe7, 0xb9, 0xde, 0x73, 0xc9, 0xee, 0xdb,
+	0xd4, 0x78, 0xa8, 0xc7, 0x18, 0xf8, 0x72, 0x9b, 0x36, 0xfe, 0xe1, 0xc2, 0x0a, 0x6f, 0xe2, 0x03,
+	0x6a, 0x3e, 0xc1, 0x8b, 0x0b, 0xbe, 0xce, 0x9b, 0x1a, 0x1d, 0xf5, 0x90, 0x87, 0xdf, 0x00, 0x67,
+	0x33, 0x1c, 0x76, 0xaf, 0x30, 0x9f, 0x14, 0x17, 0x04, 0x56, 0x89, 0x6e, 0x26, 0x44, 0xd4, 0x4d,
+	0x12, 0x7e, 0x15, 0x40, 0x8d, 0xbc, 0x66, 0x85, 0x7c, 0xfc, 0x53, 0xe2, 0xae, 0xc2, 0x56, 0x74,
+	0x53, 0xd2, 0x50, 0x17, 0x39, 0xf8, 0x81, 0xd1, 0x36, 0x93, 0xf4, 0x36, 0x4b, 0xcd, 0xab, 0x7c,
+	0xc3, 0xbe, 0x7c, 0xf4, 0x00, 0x4c, 0x95, 0xa1, 0xd8, 0xc5, 0x9a, 0x87, 0x35, 0x14, 0xd4, 0x03,
+	0x7d, 0x86, 0x5d, 0xa6, 0x33, 0x39, 0x1c, 0x4e, 0x80, 0x81, 0x1d, 0x2c, 0x3f, 0x1b, 0x23, 0xf6,
+	0x13, 0xbe, 0x09, 0xf2, 0xbb, 0x96, 0x1b, 0x27, 0xad, 0x80, 0xfe, 0x9d, 0xf5, 0x48, 0xe8, 0x7d,
+	0x31, 0x77, 0xdd, 0x98, 0x79, 0xdf, 0x00, 0xd3, 0xdd, 0x4f, 0x95, 0xcf, 0xcb, 0xa2, 0x9f, 0x19,
+	0x60, 0xb2, 0xe3, 0x00, 0xe9, 0x62, 0x8c, 0xdb, 0x6e, 0xcc, 0xbd, 0x3e, 0x9e, 0x04, 0x62, 0x23,
+	0xf0, 0x8a, 0x56, 0xb7, 0xec, 0x87, 0x06, 0x98, 0xc8, 0x26, 0xe6, 0xcf, 0xc9, 0x4b, 0xa5, 0xf7,
+	0x72, 0x60, 0xba, 0x7b, 0x0d, 0x0e, 0x3d, 0xd5, 0x5d, 0xe8, 0x7b, 0x83, 0xa6, 0x5b, 0xcb, 0xf6,
+	0x1d, 0x03, 0x8c, 0xbe, 0xad, 0xe4, 0x92, 0xaf, 0x99, 0xfd, 0xec, 0x0a, 0x25, 0x47, 0x5f, 0xca,
+	0xa0, 0x48, 0x87, 0x2c, 0xfd, 0xd6, 0x00, 0x53, 0x5d, 0x8f, 0x73, 0x78, 0x05, 0x0c, 0x59, 0xae,
+	0x1b, 0xec, 0x89, 0x6e, 0x9e, 0xd6, 0x96, 0x5f, 0xe4, 0x54, 0x24, 0xb9, 0x9a, 0xcf, 0x72, 0x9f,
+	0x81, 0xcf, 0x4a, 0x7f, 0x30, 0xc0, 0x85, 0x07, 0x45, 0xdd, 0x67, 0xbd, 0x86, 0xf3, 0xa0, 0x20,
+	0x8b, 0xed, 0x03, 0xbe, 0x7e, 0x32, 0xbb, 0xca, 0x8c, 0xc0, 0x5f, 0xcb, 0x88, 0x5f, 0xa5, 0x5f,
+	0x1a, 0x60, 0xa2, 0x8a, 0xc9, 0xae, 0x53, 0xc3, 0x08, 0xd7, 0x31, 0xc1, 0x7e, 0x0d, 0xc3, 0x05,
+	0x30, 0xc2, 0xbf, 0x36, 0x86, 0x56, 0x2d, 0xf9, 0x46, 0x32, 0x29, 0x1d, 0x3d, 0x72, 0x3b, 0x61,
+	0xa0, 0x54, 0x46, 0x7d, 0x4f, 0xc9, 0xf5, 0xfc, 0x9e, 0x72, 0x01, 0x0c, 0x86, 0x69, 0x03, 0xb8,
+	0xc0, 0xb8, 0xbc, 0xe7, 0xcb, 0xa9, 0x9c, 0x1b, 0x90, 0x88, 0x77, 0xb9, 0xf2, 0x92, 0x1b, 0x90,
+	0x08, 0x71, 0x6a, 0xe9, 0x4f, 0x39, 0x70, 0xa6, 0x3d, 0x3f, 0x33, 0x40, 0x12, 0xbb, 0x1d, 0x1f,
+	0x70, 0x18, 0x0f, 0x71, 0x8e, 0xfe, 0x6e, 0x20, 0xf7, 0xe0, 0x77, 0x03, 0xf0, 0x25, 0x30, 0x29,
+	0x7f, 0xae, 0xec, 0x87, 0x04, 0x53, 0xfe, 0x65, 0x72, 0xa0, 0xfd, 0xbd, 0xdf, 0x5a, 0x56, 0x00,
+	0x75, 0x8e, 0x81, 0x5f, 0xc9, 0xbc, 0x69, 0xb8, 0x9c, 0xbe, 0x67, 0x60, 0xb5, 0x1d, 0x2f, 0x1d,
+	0xee, 0xb1, 0x2d, 0xbf, 0x42, 0x48, 0x40, 0x32, 0x0f, 0x1d, 0x16, 0xc0, 0x48, 0x9d, 0x09, 0xf0,
+	0x3e, 0x79, 0xbe, 0xdd, 0xe9, 0x37, 0x12, 0x06, 0x4a, 0x65, 0xe0, 0xd7, 0xc0, 0x78, 0x10, 0x8a,
+	0x2a, 0x76, 0xdd, 0xb5, 0xab, 0xd8, 0xad, 0xf3, 0x8e, 0x5e, 0x21, 0x69, 0xbb, 0xb6, 0xb1, 0x50,
+	0x56, 0xb6, 0xf4, 0x47, 0x03, 0x9c, 0x4d, 0x1e, 0x13, 0xb9, 0x0e, 0xf6, 0xa3, 0xa5, 0xc0, 0xaf,
+	0x3b, 0x0d, 0x78, 0x5e, 0xb4, 0x4f, 0xb5, 0x9e, 0x64, 0xd2, 0x3a, 0x85, 0xf7, 0xc1, 0x30, 0x15,
+	0xb1, 0x22, 0xc3, 0xf8, 0x95, 0xa3, 0x87, 0x71, 0x36, 0xe8, 0x44, 0xf5, 0x97, 0x50, 0x13, 0x1c,
+	0x16, 0xc9, 0x35, 0xab, 0x12, 0xfb, 0xb6, 0x6c, 0xa1, 0x8f, 0x89, 0x48, 0x5e, 0x5a, 0x14, 0x34,
+	0xa4, 0xb8, 0xa5, 0x7f, 0x18, 0x60, 0xb2, 0xe3, 0x71, 0x14, 0xfc, 0x9e, 0x01, 0xc6, 0x6a, 0xda,
+	0xf4, 0x64, 0x3e, 0x58, 0x3b, 0xfe, 0x03, 0x2c, 0x4d, 0xa9, 0x28, 0xa1, 0x74, 0x0a, 0x6a, 0x03,
+	0x85, 0x9b, 0xc0, 0xac, 0x65, 0xde, 0x21, 0x66, 0xbe, 0x6c, 0x5e, 0x68, 0x35, 0x8b, 0xe6, 0x52,
+	0x0f, 0x19, 0xd4, 0x73, 0x74, 0xe5, 0x5b, 0x1f, 0x7d, 0x3a, 0x7b, 0xea, 0xe3, 0x4f, 0x67, 0x4f,
+	0x7d, 0xf2, 0xe9, 0xec, 0xa9, 0x77, 0x5a, 0xb3, 0xc6, 0x47, 0xad, 0x59, 0xe3, 0xe3, 0xd6, 0xac,
+	0xf1, 0x49, 0x6b, 0xd6, 0xf8, 0x6b, 0x6b, 0xd6, 0xf8, 0xc9, 0xdf, 0x66, 0x4f, 0xbd, 0x7e, 0xfd,
+	0xa8, 0xaf, 0x8f, 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, 0x28, 0x77, 0xf5, 0x22, 0xd1, 0x2c, 0x00,
+	0x00,
 }
 
 func (m *ConversionRequest) Marshal() (dAtA []byte, err error) {
@@ -2633,6 +2635,16 @@ func (m *ValidationRule) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 	_ = i
 	var l int
 	_ = l
+	if m.OptionalOldSelf != nil {
+		i--
+		if *m.OptionalOldSelf {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x30
+	}
 	i -= len(m.FieldPath)
 	copy(dAtA[i:], m.FieldPath)
 	i = encodeVarintGenerated(dAtA, i, uint64(len(m.FieldPath)))
@@ -3367,6 +3379,9 @@ func (m *ValidationRule) Size() (n int) {
 	}
 	l = len(m.FieldPath)
 	n += 1 + l + sovGenerated(uint64(l))
+	if m.OptionalOldSelf != nil {
+		n += 2
+	}
 	return n
 }
 
@@ -3845,6 +3860,7 @@ func (this *ValidationRule) String() string {
 		`MessageExpression:` + fmt.Sprintf("%v", this.MessageExpression) + `,`,
 		`Reason:` + valueToStringGenerated(this.Reason) + `,`,
 		`FieldPath:` + fmt.Sprintf("%v", this.FieldPath) + `,`,
+		`OptionalOldSelf:` + valueToStringGenerated(this.OptionalOldSelf) + `,`,
 		`}`,
 	}, "")
 	return s
@@ -9008,6 +9024,27 @@ func (m *ValidationRule) Unmarshal(dAtA []byte) error {
 			}
 			m.FieldPath = string(dAtA[iNdEx:postIndex])
 			iNdEx = postIndex
+		case 6:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field OptionalOldSelf", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenerated
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			b := bool(v != 0)
+			m.OptionalOldSelf = &b
 		default:
 			iNdEx = preIndex
 			skippy, err := skipGenerated(dAtA[iNdEx:])
diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.proto b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.proto
index 578d018a..3c39d63a 100644
--- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.proto
+++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.proto
@@ -658,6 +658,18 @@ message ValidationRule {
   //   - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values
   //     are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with
   //     non-intersecting keys are appended, retaining their partial order.
+  //
+  // If `rule` makes use of the `oldSelf` variable it is implicitly a
+  // `transition rule`.
+  //
+  // By default, the `oldSelf` variable is the same type as `self`.
+  // When `optionalOldSelf` is true, the `oldSelf` variable is a CEL optional
+  //  variable whose value() is the same type as `self`.
+  // See the documentation for the `optionalOldSelf` field for details.
+  //
+  // Transition rules by default are applied only on UPDATE requests and are
+  // skipped if an old value could not be found. You can opt a transition
+  // rule into unconditional evaluation by setting `optionalOldSelf` to true.
   optional string rule = 1;
 
   // Message represents the message displayed when validation fails. The message is required if the Rule contains
@@ -698,6 +710,24 @@ message ValidationRule {
   // e.g. for attribute `foo.34$` appears in a list `testList`, the fieldPath could be set to `.testList['foo.34$']`
   // +optional
   optional string fieldPath = 5;
+
+  // optionalOldSelf is used to opt a transition rule into evaluation
+  // even when the object is first created, or if the old object is
+  // missing the value.
+  //
+  // When enabled `oldSelf` will be a CEL optional whose value will be
+  // `None` if there is no old value, or when the object is initially created.
+  //
+  // You may check for presence of oldSelf using `oldSelf.hasValue()` and
+  // unwrap it after checking using `oldSelf.value()`. Check the CEL
+  // documentation for Optional types for more information:
+  // https://pkg.go.dev/github.com/google/cel-go/cel#OptionalTypes
+  //
+  // May not be set unless `oldSelf` is used in `rule`.
+  //
+  // +featureGate=CRDValidationRatcheting
+  // +optional
+  optional bool optionalOldSelf = 6;
 }
 
 // WebhookClientConfig contains the information to make a TLS connection with the webhook.
diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types_jsonschema.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types_jsonschema.go
index 1c90d464..a81451ad 100644
--- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types_jsonschema.go
+++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types_jsonschema.go
@@ -249,6 +249,19 @@ type ValidationRule struct {
 	//   - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values
 	//     are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with
 	//     non-intersecting keys are appended, retaining their partial order.
+	//
+	// If `rule` makes use of the `oldSelf` variable it is implicitly a
+	// `transition rule`.
+	//
+	// By default, the `oldSelf` variable is the same type as `self`.
+	// When `optionalOldSelf` is true, the `oldSelf` variable is a CEL optional
+	//  variable whose value() is the same type as `self`.
+	// See the documentation for the `optionalOldSelf` field for details.
+	//
+	// Transition rules by default are applied only on UPDATE requests and are
+	// skipped if an old value could not be found. You can opt a transition
+	// rule into unconditional evaluation by setting `optionalOldSelf` to true.
+	//
 	Rule string `json:"rule" protobuf:"bytes,1,opt,name=rule"`
 	// Message represents the message displayed when validation fails. The message is required if the Rule contains
 	// line breaks. The message must not contain line breaks.
@@ -285,6 +298,24 @@ type ValidationRule struct {
 	// e.g. for attribute `foo.34$` appears in a list `testList`, the fieldPath could be set to `.testList['foo.34$']`
 	// +optional
 	FieldPath string `json:"fieldPath,omitempty" protobuf:"bytes,5,opt,name=fieldPath"`
+
+	// optionalOldSelf is used to opt a transition rule into evaluation
+	// even when the object is first created, or if the old object is
+	// missing the value.
+	//
+	// When enabled `oldSelf` will be a CEL optional whose value will be
+	// `None` if there is no old value, or when the object is initially created.
+	//
+	// You may check for presence of oldSelf using `oldSelf.hasValue()` and
+	// unwrap it after checking using `oldSelf.value()`. Check the CEL
+	// documentation for Optional types for more information:
+	// https://pkg.go.dev/github.com/google/cel-go/cel#OptionalTypes
+	//
+	// May not be set unless `oldSelf` is used in `rule`.
+	//
+	// +featureGate=CRDValidationRatcheting
+	// +optional
+	OptionalOldSelf *bool `json:"optionalOldSelf,omitempty" protobuf:"bytes,6,opt,name=optionalOldSelf"`
 }
 
 // JSON represents any valid JSON value.
diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/zz_generated.conversion.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/zz_generated.conversion.go
index 0a82e4d8..405021bf 100644
--- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/zz_generated.conversion.go
+++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/zz_generated.conversion.go
@@ -1261,6 +1261,7 @@ func autoConvert_v1_ValidationRule_To_apiextensions_ValidationRule(in *Validatio
 	out.MessageExpression = in.MessageExpression
 	out.Reason = (*apiextensions.FieldValueErrorReason)(unsafe.Pointer(in.Reason))
 	out.FieldPath = in.FieldPath
+	out.OptionalOldSelf = (*bool)(unsafe.Pointer(in.OptionalOldSelf))
 	return nil
 }
 
@@ -1275,6 +1276,7 @@ func autoConvert_apiextensions_ValidationRule_To_v1_ValidationRule(in *apiextens
 	out.MessageExpression = in.MessageExpression
 	out.Reason = (*FieldValueErrorReason)(unsafe.Pointer(in.Reason))
 	out.FieldPath = in.FieldPath
+	out.OptionalOldSelf = (*bool)(unsafe.Pointer(in.OptionalOldSelf))
 	return nil
 }
 
diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/zz_generated.deepcopy.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/zz_generated.deepcopy.go
index b4347b8d..bc23fcd8 100644
--- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/zz_generated.deepcopy.go
+++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/zz_generated.deepcopy.go
@@ -619,6 +619,11 @@ func (in *ValidationRule) DeepCopyInto(out *ValidationRule) {
 		*out = new(FieldValueErrorReason)
 		**out = **in
 	}
+	if in.OptionalOldSelf != nil {
+		in, out := &in.OptionalOldSelf, &out.OptionalOldSelf
+		*out = new(bool)
+		**out = **in
+	}
 	return
 }
 
diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.pb.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.pb.go
index 981f6adb..c81fa6bc 100644
--- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.pb.go
+++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.pb.go
@@ -785,204 +785,206 @@ func init() {
 }
 
 var fileDescriptor_98a4cc6918394e53 = []byte{
-	// 3144 bytes of a gzipped FileDescriptorProto
+	// 3170 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xcd, 0x73, 0x1c, 0x47,
-	0xd9, 0xf7, 0xec, 0x6a, 0xa5, 0x55, 0x4b, 0xb6, 0xa5, 0xb6, 0xa5, 0x8c, 0x15, 0x47, 0x2b, 0xaf,
-	0xdf, 0xf8, 0x55, 0x12, 0x67, 0x95, 0xf8, 0x4d, 0xde, 0x84, 0x40, 0x8a, 0xd2, 0x4a, 0x72, 0x50,
-	0x62, 0x59, 0xa2, 0xd7, 0x76, 0x04, 0xf9, 0x1c, 0xed, 0xf4, 0xae, 0x26, 0x9a, 0x9d, 0x19, 0x77,
-	0xcf, 0xac, 0xa4, 0x0a, 0x50, 0x7c, 0x54, 0x0a, 0x8a, 0x02, 0x42, 0x91, 0x5c, 0x28, 0xe0, 0x10,
-	0x28, 0x2e, 0x1c, 0xe0, 0x00, 0x37, 0xf8, 0x03, 0x72, 0x4c, 0x51, 0x1c, 0x72, 0xa0, 0x16, 0xb2,
-	0x5c, 0x39, 0x52, 0x45, 0x95, 0x4e, 0x54, 0x7f, 0x4c, 0x4f, 0xef, 0xec, 0xae, 0xed, 0x8a, 0x76,
-	0x63, 0x6e, 0xbb, 0xcf, 0xd7, 0xef, 0x99, 0xa7, 0x9f, 0x7e, 0xfa, 0xe9, 0x67, 0x06, 0xd4, 0xf6,
-	0x9e, 0xa5, 0x25, 0xc7, 0x5f, 0xda, 0x8b, 0x76, 0x30, 0xf1, 0x70, 0x88, 0xe9, 0x52, 0x13, 0x7b,
-	0xb6, 0x4f, 0x96, 0x24, 0xc3, 0x0a, 0x1c, 0x7c, 0x10, 0x62, 0x8f, 0x3a, 0xbe, 0x47, 0x1f, 0xb7,
-	0x02, 0x87, 0x62, 0xd2, 0xc4, 0x64, 0x29, 0xd8, 0xab, 0x33, 0x1e, 0xed, 0x14, 0x58, 0x6a, 0x3e,
-	0xb9, 0x83, 0x43, 0xeb, 0xc9, 0xa5, 0x3a, 0xf6, 0x30, 0xb1, 0x42, 0x6c, 0x97, 0x02, 0xe2, 0x87,
-	0x3e, 0x7c, 0x5e, 0x98, 0x2b, 0x75, 0x48, 0xbf, 0xa1, 0xcc, 0x95, 0x82, 0xbd, 0x3a, 0xe3, 0xd1,
-	0x4e, 0x81, 0x92, 0x34, 0x37, 0xf7, 0x78, 0xdd, 0x09, 0x77, 0xa3, 0x9d, 0x52, 0xd5, 0x6f, 0x2c,
-	0xd5, 0xfd, 0xba, 0xbf, 0xc4, 0xad, 0xee, 0x44, 0x35, 0xfe, 0x8f, 0xff, 0xe1, 0xbf, 0x04, 0xda,
-	0xdc, 0x53, 0x89, 0xf3, 0x0d, 0xab, 0xba, 0xeb, 0x78, 0x98, 0x1c, 0x26, 0x1e, 0x37, 0x70, 0x68,
-	0x2d, 0x35, 0xbb, 0x7c, 0x9c, 0x5b, 0xea, 0xa7, 0x45, 0x22, 0x2f, 0x74, 0x1a, 0xb8, 0x4b, 0xe1,
-	0xff, 0xef, 0xa6, 0x40, 0xab, 0xbb, 0xb8, 0x61, 0xa5, 0xf5, 0x8a, 0x47, 0x06, 0x98, 0x5e, 0xf1,
-	0xbd, 0x26, 0x26, 0xec, 0x29, 0x11, 0xbe, 0x1d, 0x61, 0x1a, 0xc2, 0x32, 0xc8, 0x46, 0x8e, 0x6d,
-	0x1a, 0x0b, 0xc6, 0xe2, 0x78, 0xf9, 0x89, 0x0f, 0x5b, 0x85, 0x13, 0xed, 0x56, 0x21, 0x7b, 0x73,
-	0x7d, 0xf5, 0xa8, 0x55, 0xb8, 0xd0, 0x0f, 0x29, 0x3c, 0x0c, 0x30, 0x2d, 0xdd, 0x5c, 0x5f, 0x45,
-	0x4c, 0x19, 0xbe, 0x00, 0xa6, 0x6d, 0x4c, 0x1d, 0x82, 0xed, 0xe5, 0xad, 0xf5, 0x5b, 0xc2, 0xbe,
-	0x99, 0xe1, 0x16, 0xcf, 0x49, 0x8b, 0xd3, 0xab, 0x69, 0x01, 0xd4, 0xad, 0x03, 0xb7, 0xc1, 0x98,
-	0xbf, 0xf3, 0x16, 0xae, 0x86, 0xd4, 0xcc, 0x2e, 0x64, 0x17, 0x27, 0xae, 0x3c, 0x5e, 0x4a, 0x56,
-	0x50, 0xb9, 0xc0, 0x97, 0x4d, 0x3e, 0x6c, 0x09, 0x59, 0xfb, 0x6b, 0xf1, 0xca, 0x95, 0x4f, 0x4b,
-	0xb4, 0xb1, 0x4d, 0x61, 0x05, 0xc5, 0xe6, 0x8a, 0xbf, 0xca, 0x00, 0xa8, 0x3f, 0x3c, 0x0d, 0x7c,
-	0x8f, 0xe2, 0x81, 0x3c, 0x3d, 0x05, 0x53, 0x55, 0x6e, 0x39, 0xc4, 0xb6, 0xc4, 0x35, 0x33, 0x9f,
-	0xc6, 0x7b, 0x53, 0xe2, 0x4f, 0xad, 0xa4, 0xcc, 0xa1, 0x2e, 0x00, 0x78, 0x03, 0x8c, 0x12, 0x4c,
-	0x23, 0x37, 0x34, 0xb3, 0x0b, 0xc6, 0xe2, 0xc4, 0x95, 0xcb, 0x7d, 0xa1, 0x78, 0x7e, 0xb3, 0xe4,
-	0x2b, 0x35, 0x9f, 0x2c, 0x55, 0x42, 0x2b, 0x8c, 0x68, 0xf9, 0x94, 0x44, 0x1a, 0x45, 0xdc, 0x06,
-	0x92, 0xb6, 0x8a, 0xdf, 0xcb, 0x80, 0x29, 0x3d, 0x4a, 0x4d, 0x07, 0xef, 0xc3, 0x7d, 0x30, 0x46,
-	0x44, 0xb2, 0xf0, 0x38, 0x4d, 0x5c, 0xd9, 0x2a, 0x1d, 0x6b, 0x5b, 0x95, 0xba, 0x92, 0xb0, 0x3c,
-	0xc1, 0xd6, 0x4c, 0xfe, 0x41, 0x31, 0x1a, 0x7c, 0x1b, 0xe4, 0x89, 0x5c, 0x28, 0x9e, 0x4d, 0x13,
-	0x57, 0xbe, 0x3c, 0x40, 0x64, 0x61, 0xb8, 0x3c, 0xd9, 0x6e, 0x15, 0xf2, 0xf1, 0x3f, 0xa4, 0x00,
-	0x8b, 0xef, 0x65, 0xc0, 0xfc, 0x4a, 0x44, 0x43, 0xbf, 0x81, 0x30, 0xf5, 0x23, 0x52, 0xc5, 0x2b,
-	0xbe, 0x1b, 0x35, 0xbc, 0x55, 0x5c, 0x73, 0x3c, 0x27, 0x64, 0xd9, 0xba, 0x00, 0x46, 0x3c, 0xab,
-	0x81, 0x65, 0xf6, 0x4c, 0xca, 0x98, 0x8e, 0x5c, 0xb7, 0x1a, 0x18, 0x71, 0x0e, 0x93, 0x60, 0xc9,
-	0x22, 0xf7, 0x82, 0x92, 0xb8, 0x71, 0x18, 0x60, 0xc4, 0x39, 0xf0, 0x12, 0x18, 0xad, 0xf9, 0xa4,
-	0x61, 0x89, 0x75, 0x1c, 0x4f, 0x56, 0xe6, 0x2a, 0xa7, 0x22, 0xc9, 0x85, 0x4f, 0x83, 0x09, 0x1b,
-	0xd3, 0x2a, 0x71, 0x02, 0x06, 0x6d, 0x8e, 0x70, 0xe1, 0x33, 0x52, 0x78, 0x62, 0x35, 0x61, 0x21,
-	0x5d, 0x0e, 0x5e, 0x06, 0xf9, 0x80, 0x38, 0x3e, 0x71, 0xc2, 0x43, 0x33, 0xb7, 0x60, 0x2c, 0xe6,
-	0xca, 0x53, 0x52, 0x27, 0xbf, 0x25, 0xe9, 0x48, 0x49, 0xc0, 0x05, 0x90, 0x7f, 0xb1, 0xb2, 0x79,
-	0x7d, 0xcb, 0x0a, 0x77, 0xcd, 0x51, 0x8e, 0x30, 0xc2, 0xa4, 0x91, 0xa2, 0x16, 0xff, 0x9a, 0x01,
-	0x66, 0x3a, 0x2a, 0x71, 0x48, 0xe1, 0x55, 0x90, 0xa7, 0x21, 0xab, 0x38, 0xf5, 0x43, 0x19, 0x93,
-	0x47, 0x63, 0xb0, 0x8a, 0xa4, 0x1f, 0xb5, 0x0a, 0xb3, 0x89, 0x46, 0x4c, 0xe5, 0xf1, 0x50, 0xba,
-	0xf0, 0x17, 0x06, 0x38, 0xb3, 0x8f, 0x77, 0x76, 0x7d, 0x7f, 0x6f, 0xc5, 0x75, 0xb0, 0x17, 0xae,
-	0xf8, 0x5e, 0xcd, 0xa9, 0xcb, 0x1c, 0x40, 0xc7, 0xcc, 0x81, 0x97, 0xbb, 0x2d, 0x97, 0x1f, 0x68,
-	0xb7, 0x0a, 0x67, 0x7a, 0x30, 0x50, 0x2f, 0x3f, 0xe0, 0x36, 0x30, 0xab, 0xa9, 0x4d, 0x22, 0x0b,
-	0x98, 0x28, 0x5b, 0xe3, 0xe5, 0xf3, 0xed, 0x56, 0xc1, 0x5c, 0xe9, 0x23, 0x83, 0xfa, 0x6a, 0x17,
-	0xbf, 0x93, 0x4d, 0x87, 0x57, 0x4b, 0xb7, 0x37, 0x41, 0x9e, 0x6d, 0x63, 0xdb, 0x0a, 0x2d, 0xb9,
-	0x11, 0x9f, 0xb8, 0xb7, 0x4d, 0x2f, 0x6a, 0xc6, 0x06, 0x0e, 0xad, 0x32, 0x94, 0x0b, 0x02, 0x12,
-	0x1a, 0x52, 0x56, 0xe1, 0xd7, 0xc1, 0x08, 0x0d, 0x70, 0x55, 0x06, 0xfa, 0x95, 0xe3, 0x6e, 0xb6,
-	0x3e, 0x0f, 0x52, 0x09, 0x70, 0x35, 0xd9, 0x0b, 0xec, 0x1f, 0xe2, 0xb0, 0xf0, 0x1d, 0x03, 0x8c,
-	0x52, 0x5e, 0xa0, 0x64, 0x51, 0x7b, 0x6d, 0x58, 0x1e, 0xa4, 0xaa, 0xa0, 0xf8, 0x8f, 0x24, 0x78,
-	0xf1, 0x5f, 0x19, 0x70, 0xa1, 0x9f, 0xea, 0x8a, 0xef, 0xd9, 0x62, 0x39, 0xd6, 0xe5, 0xde, 0x16,
-	0x99, 0xfe, 0xb4, 0xbe, 0xb7, 0x8f, 0x5a, 0x85, 0x87, 0xef, 0x6a, 0x40, 0x2b, 0x02, 0x9f, 0x53,
-	0xcf, 0x2d, 0x0a, 0xc5, 0x85, 0x4e, 0xc7, 0x8e, 0x5a, 0x85, 0xd3, 0x4a, 0xad, 0xd3, 0x57, 0xd8,
-	0x04, 0xd0, 0xb5, 0x68, 0x78, 0x83, 0x58, 0x1e, 0x15, 0x66, 0x9d, 0x06, 0x96, 0xe1, 0x7b, 0xf4,
-	0xde, 0xd2, 0x83, 0x69, 0x94, 0xe7, 0x24, 0x24, 0xbc, 0xd6, 0x65, 0x0d, 0xf5, 0x40, 0x60, 0x75,
-	0x8b, 0x60, 0x8b, 0xaa, 0x52, 0xa4, 0x9d, 0x28, 0x8c, 0x8a, 0x24, 0x17, 0x3e, 0x02, 0xc6, 0x1a,
-	0x98, 0x52, 0xab, 0x8e, 0x79, 0xfd, 0x19, 0x4f, 0x8e, 0xe8, 0x0d, 0x41, 0x46, 0x31, 0x9f, 0xf5,
-	0x27, 0xe7, 0xfb, 0x45, 0xed, 0x9a, 0x43, 0x43, 0xf8, 0x6a, 0xd7, 0x06, 0x28, 0xdd, 0xdb, 0x13,
-	0x32, 0x6d, 0x9e, 0xfe, 0xaa, 0xf8, 0xc5, 0x14, 0x2d, 0xf9, 0xbf, 0x06, 0x72, 0x4e, 0x88, 0x1b,
-	0xf1, 0xd9, 0xfd, 0xf2, 0x90, 0x72, 0xaf, 0x7c, 0x52, 0xfa, 0x90, 0x5b, 0x67, 0x68, 0x48, 0x80,
-	0x16, 0x7f, 0x9d, 0x01, 0x0f, 0xf5, 0x53, 0x61, 0x07, 0x0a, 0x65, 0x11, 0x0f, 0xdc, 0x88, 0x58,
-	0xae, 0xcc, 0x38, 0x15, 0xf1, 0x2d, 0x4e, 0x45, 0x92, 0xcb, 0x4a, 0x3e, 0x75, 0xbc, 0x7a, 0xe4,
-	0x5a, 0x44, 0xa6, 0x93, 0x7a, 0xea, 0x8a, 0xa4, 0x23, 0x25, 0x01, 0x4b, 0x00, 0xd0, 0x5d, 0x9f,
-	0x84, 0x1c, 0x43, 0x56, 0xaf, 0x53, 0xac, 0x40, 0x54, 0x14, 0x15, 0x69, 0x12, 0xec, 0x44, 0xdb,
-	0x73, 0x3c, 0x5b, 0xae, 0xba, 0xda, 0xc5, 0x2f, 0x39, 0x9e, 0x8d, 0x38, 0x87, 0xe1, 0xbb, 0x0e,
-	0x0d, 0x19, 0x45, 0x2e, 0x79, 0x47, 0xd4, 0xb9, 0xa4, 0x92, 0x60, 0xf8, 0x55, 0x56, 0xf5, 0x7d,
-	0xe2, 0x60, 0x6a, 0x8e, 0x26, 0xf8, 0x2b, 0x8a, 0x8a, 0x34, 0x89, 0xe2, 0x3f, 0xf3, 0xfd, 0x93,
-	0x84, 0x95, 0x12, 0x78, 0x11, 0xe4, 0xea, 0xc4, 0x8f, 0x02, 0x19, 0x25, 0x15, 0xed, 0x17, 0x18,
-	0x11, 0x09, 0x1e, 0xcb, 0xca, 0x66, 0x47, 0x9b, 0xaa, 0xb2, 0x32, 0x6e, 0x4e, 0x63, 0x3e, 0xfc,
-	0x96, 0x01, 0x72, 0x9e, 0x0c, 0x0e, 0x4b, 0xb9, 0x57, 0x87, 0x94, 0x17, 0x3c, 0xbc, 0x89, 0xbb,
-	0x22, 0xf2, 0x02, 0x19, 0x3e, 0x05, 0x72, 0xb4, 0xea, 0x07, 0x58, 0x46, 0x7d, 0x3e, 0x16, 0xaa,
-	0x30, 0xe2, 0x51, 0xab, 0x70, 0x32, 0x36, 0xc7, 0x09, 0x48, 0x08, 0xc3, 0xef, 0x1a, 0x00, 0x34,
-	0x2d, 0xd7, 0xb1, 0x2d, 0xde, 0x32, 0xe4, 0xb8, 0xfb, 0x83, 0x4d, 0xeb, 0x5b, 0xca, 0xbc, 0x58,
-	0xb4, 0xe4, 0x3f, 0xd2, 0xa0, 0xe1, 0xbb, 0x06, 0x98, 0xa4, 0xd1, 0x0e, 0x91, 0x5a, 0x94, 0x37,
-	0x17, 0x13, 0x57, 0xbe, 0x32, 0x50, 0x5f, 0x2a, 0x1a, 0x40, 0x79, 0xaa, 0xdd, 0x2a, 0x4c, 0xea,
-	0x14, 0xd4, 0xe1, 0x00, 0xfc, 0x81, 0x01, 0xf2, 0xcd, 0xf8, 0xcc, 0x1e, 0xe3, 0x1b, 0xfe, 0xf5,
-	0x21, 0x2d, 0xac, 0xcc, 0xa8, 0x64, 0x17, 0xa8, 0x3e, 0x40, 0x79, 0x00, 0xff, 0x68, 0x00, 0xd3,
-	0xb2, 0x45, 0x81, 0xb7, 0xdc, 0x2d, 0xe2, 0x78, 0x21, 0x26, 0xa2, 0xdf, 0xa4, 0x66, 0x9e, 0xbb,
-	0x37, 0xd8, 0xb3, 0x30, 0xdd, 0xcb, 0x96, 0x17, 0xa4, 0x77, 0xe6, 0x72, 0x1f, 0x37, 0x50, 0x5f,
-	0x07, 0x79, 0xa2, 0x25, 0x2d, 0x8d, 0x39, 0x3e, 0x84, 0x44, 0x4b, 0x7a, 0x29, 0x59, 0x1d, 0x92,
-	0x0e, 0x4a, 0x83, 0x86, 0x9b, 0x60, 0x26, 0x20, 0x98, 0x03, 0xdc, 0xf4, 0xf6, 0x3c, 0x7f, 0xdf,
-	0xbb, 0xea, 0x60, 0xd7, 0xa6, 0x26, 0x58, 0x30, 0x16, 0xf3, 0xe5, 0x73, 0xed, 0x56, 0x61, 0x66,
-	0xab, 0x97, 0x00, 0xea, 0xad, 0x57, 0x7c, 0x37, 0x9b, 0xbe, 0x05, 0xa4, 0xbb, 0x08, 0xf8, 0xbe,
-	0x78, 0x7a, 0x11, 0x1b, 0x6a, 0x1a, 0x7c, 0xb5, 0xde, 0x1c, 0x52, 0x32, 0xa9, 0x36, 0x20, 0xe9,
-	0xe4, 0x14, 0x89, 0x22, 0xcd, 0x0f, 0xf8, 0x53, 0x03, 0x9c, 0xb4, 0xaa, 0x55, 0x1c, 0x84, 0xd8,
-	0x16, 0xc5, 0x3d, 0xf3, 0x19, 0xd4, 0xaf, 0x19, 0xe9, 0xd5, 0xc9, 0x65, 0x1d, 0x1a, 0x75, 0x7a,
-	0x02, 0x9f, 0x03, 0xa7, 0x68, 0xe8, 0x13, 0x6c, 0xa7, 0xda, 0x66, 0xd8, 0x6e, 0x15, 0x4e, 0x55,
-	0x3a, 0x38, 0x28, 0x25, 0x59, 0xfc, 0x5b, 0x0e, 0x14, 0xee, 0xb2, 0xd5, 0xee, 0xe1, 0x62, 0x76,
-	0x09, 0x8c, 0xf2, 0xc7, 0xb5, 0x79, 0x54, 0xf2, 0x5a, 0x2b, 0xc8, 0xa9, 0x48, 0x72, 0xd9, 0x41,
-	0xc1, 0xf0, 0x59, 0xfb, 0x92, 0xe5, 0x82, 0xea, 0xa0, 0xa8, 0x08, 0x32, 0x8a, 0xf9, 0xf0, 0x0a,
-	0x00, 0x36, 0x0e, 0x08, 0x66, 0x87, 0x95, 0x6d, 0x8e, 0x71, 0x69, 0xb5, 0x48, 0xab, 0x8a, 0x83,
-	0x34, 0x29, 0x78, 0x15, 0xc0, 0xf8, 0x9f, 0xe3, 0x7b, 0x2f, 0x5b, 0xc4, 0x73, 0xbc, 0xba, 0x99,
-	0xe7, 0x6e, 0xcf, 0xb2, 0x6e, 0x6c, 0xb5, 0x8b, 0x8b, 0x7a, 0x68, 0xc0, 0xb7, 0xc1, 0xa8, 0x18,
-	0xfa, 0xf0, 0x13, 0x62, 0x88, 0x55, 0x1e, 0xf0, 0x18, 0x71, 0x28, 0x24, 0x21, 0xbb, 0xab, 0x7b,
-	0xee, 0x7e, 0x57, 0xf7, 0x3b, 0x96, 0xd3, 0xd1, 0xff, 0xf2, 0x72, 0x5a, 0xfc, 0xb7, 0x91, 0xae,
-	0x39, 0xda, 0xa3, 0x56, 0xaa, 0x96, 0x8b, 0xe1, 0x2a, 0x98, 0x62, 0x37, 0x26, 0x84, 0x03, 0xd7,
-	0xa9, 0x5a, 0x94, 0x5f, 0xd8, 0x45, 0xb2, 0xab, 0x19, 0x52, 0x25, 0xc5, 0x47, 0x5d, 0x1a, 0xf0,
-	0x45, 0x00, 0xc5, 0x2d, 0xa2, 0xc3, 0x8e, 0x68, 0x88, 0xd4, 0x7d, 0xa0, 0xd2, 0x25, 0x81, 0x7a,
-	0x68, 0xc1, 0x15, 0x30, 0xed, 0x5a, 0x3b, 0xd8, 0xad, 0x60, 0x17, 0x57, 0x43, 0x9f, 0x70, 0x53,
-	0x62, 0xa4, 0x31, 0xd3, 0x6e, 0x15, 0xa6, 0xaf, 0xa5, 0x99, 0xa8, 0x5b, 0xbe, 0x78, 0x21, 0xbd,
-	0xb5, 0xf5, 0x07, 0x17, 0x77, 0xb3, 0x0f, 0x32, 0x60, 0xae, 0x7f, 0x66, 0xc0, 0x6f, 0x27, 0x57,
-	0x48, 0x71, 0x43, 0x78, 0x7d, 0x58, 0x59, 0x28, 0xef, 0x90, 0xa0, 0xfb, 0xfe, 0x08, 0xbf, 0xc1,
-	0xda, 0x35, 0xcb, 0x8d, 0x87, 0x56, 0xaf, 0x0d, 0xcd, 0x05, 0x06, 0x52, 0x1e, 0x17, 0x9d, 0xa0,
-	0xe5, 0xf2, 0xc6, 0xcf, 0x72, 0x71, 0xf1, 0x37, 0x46, 0x7a, 0x8a, 0x90, 0xec, 0x60, 0xf8, 0x43,
-	0x03, 0x9c, 0xf6, 0x03, 0xec, 0x2d, 0x6f, 0xad, 0xdf, 0xfa, 0x3f, 0xb1, 0x93, 0x65, 0xa8, 0xae,
-	0x1f, 0xd3, 0xcf, 0x17, 0x2b, 0x9b, 0xd7, 0x85, 0xc1, 0x2d, 0xe2, 0x07, 0xb4, 0x7c, 0xa6, 0xdd,
-	0x2a, 0x9c, 0xde, 0xec, 0x84, 0x42, 0x69, 0xec, 0x62, 0x03, 0xcc, 0xac, 0x1d, 0x84, 0x98, 0x78,
-	0x96, 0xbb, 0xea, 0x57, 0xa3, 0x06, 0xf6, 0x42, 0xe1, 0x68, 0x6a, 0xe2, 0x65, 0xdc, 0xe3, 0xc4,
-	0xeb, 0x21, 0x90, 0x8d, 0x88, 0x2b, 0xb3, 0x78, 0x42, 0x4d, 0x74, 0xd1, 0x35, 0xc4, 0xe8, 0xc5,
-	0x0b, 0x60, 0x84, 0xf9, 0x09, 0xcf, 0x81, 0x2c, 0xb1, 0xf6, 0xb9, 0xd5, 0xc9, 0xf2, 0x18, 0x13,
-	0x41, 0xd6, 0x3e, 0x62, 0xb4, 0xe2, 0x5f, 0x2e, 0x80, 0xd3, 0xa9, 0x67, 0x81, 0x73, 0x20, 0xa3,
-	0xc6, 0xc4, 0x40, 0x1a, 0xcd, 0xac, 0xaf, 0xa2, 0x8c, 0x63, 0xc3, 0x67, 0x54, 0xf1, 0x15, 0xa0,
-	0x05, 0x75, 0x96, 0x70, 0x2a, 0xeb, 0xcf, 0x13, 0x73, 0xcc, 0x91, 0xb8, 0x70, 0x32, 0x1f, 0x70,
-	0x4d, 0xee, 0x12, 0xe1, 0x03, 0xae, 0x21, 0x46, 0xfb, 0xb4, 0xe3, 0xbe, 0x78, 0xde, 0x98, 0xbb,
-	0x87, 0x79, 0xe3, 0xe8, 0x1d, 0xe7, 0x8d, 0x17, 0x41, 0x2e, 0x74, 0x42, 0x17, 0xf3, 0x83, 0x4c,
-	0xbb, 0x46, 0xdd, 0x60, 0x44, 0x24, 0x78, 0xf0, 0x2d, 0x30, 0x66, 0xe3, 0x9a, 0x15, 0xb9, 0x21,
-	0x3f, 0xb3, 0x26, 0xae, 0xac, 0x0c, 0x20, 0x85, 0xc4, 0x30, 0x78, 0x55, 0xd8, 0x45, 0x31, 0x00,
-	0x7c, 0x18, 0x8c, 0x35, 0xac, 0x03, 0xa7, 0x11, 0x35, 0x78, 0x83, 0x69, 0x08, 0xb1, 0x0d, 0x41,
-	0x42, 0x31, 0x8f, 0x55, 0x46, 0x7c, 0x50, 0x75, 0x23, 0xea, 0x34, 0xb1, 0x64, 0xca, 0xe6, 0x4f,
-	0x55, 0xc6, 0xb5, 0x14, 0x1f, 0x75, 0x69, 0x70, 0x30, 0xc7, 0xe3, 0xca, 0x13, 0x1a, 0x98, 0x20,
-	0xa1, 0x98, 0xd7, 0x09, 0x26, 0xe5, 0x27, 0xfb, 0x81, 0x49, 0xe5, 0x2e, 0x0d, 0xf8, 0x18, 0x18,
-	0x6f, 0x58, 0x07, 0xd7, 0xb0, 0x57, 0x0f, 0x77, 0xcd, 0x93, 0x0b, 0xc6, 0x62, 0xb6, 0x7c, 0xb2,
-	0xdd, 0x2a, 0x8c, 0x6f, 0xc4, 0x44, 0x94, 0xf0, 0xb9, 0xb0, 0xe3, 0x49, 0xe1, 0x53, 0x9a, 0x70,
-	0x4c, 0x44, 0x09, 0x9f, 0x75, 0x2f, 0x81, 0x15, 0xb2, 0xcd, 0x65, 0x9e, 0xee, 0xbc, 0xe6, 0x6e,
-	0x09, 0x32, 0x8a, 0xf9, 0x70, 0x11, 0xe4, 0x1b, 0xd6, 0x01, 0x1f, 0x49, 0x98, 0x53, 0xdc, 0x2c,
-	0x1f, 0x8c, 0x6f, 0x48, 0x1a, 0x52, 0x5c, 0x2e, 0xe9, 0x78, 0x42, 0x72, 0x5a, 0x93, 0x94, 0x34,
-	0xa4, 0xb8, 0x2c, 0x89, 0x23, 0xcf, 0xb9, 0x1d, 0x61, 0x21, 0x0c, 0x79, 0x64, 0x54, 0x12, 0xdf,
-	0x4c, 0x58, 0x48, 0x97, 0x83, 0x25, 0x00, 0x1a, 0x91, 0x1b, 0x3a, 0x81, 0x8b, 0x37, 0x6b, 0xe6,
-	0x19, 0x1e, 0x7f, 0xde, 0xf4, 0x6f, 0x28, 0x2a, 0xd2, 0x24, 0x20, 0x06, 0x23, 0xd8, 0x8b, 0x1a,
-	0xe6, 0x59, 0x7e, 0xb0, 0x0f, 0x24, 0x05, 0xd5, 0xce, 0x59, 0xf3, 0xa2, 0x06, 0xe2, 0xe6, 0xe1,
-	0x33, 0xe0, 0x64, 0xc3, 0x3a, 0x60, 0xe5, 0x00, 0x93, 0xd0, 0xc1, 0xd4, 0x9c, 0xe1, 0x0f, 0x3f,
-	0xcd, 0xba, 0xdd, 0x0d, 0x9d, 0x81, 0x3a, 0xe5, 0xb8, 0xa2, 0xe3, 0x69, 0x8a, 0xb3, 0x9a, 0xa2,
-	0xce, 0x40, 0x9d, 0x72, 0x2c, 0xd2, 0x04, 0xdf, 0x8e, 0x1c, 0x82, 0x6d, 0xf3, 0x01, 0xde, 0x20,
-	0xcb, 0x97, 0x15, 0x82, 0x86, 0x14, 0x17, 0x36, 0xe3, 0xd9, 0x95, 0xc9, 0xb7, 0xe1, 0xcd, 0xc1,
-	0x56, 0xf2, 0x4d, 0xb2, 0x4c, 0x88, 0x75, 0x28, 0x4e, 0x1a, 0x7d, 0x6a, 0x05, 0x29, 0xc8, 0x59,
-	0xae, 0xbb, 0x59, 0x33, 0xcf, 0xf1, 0xd8, 0x0f, 0xfa, 0x04, 0x51, 0x55, 0x67, 0x99, 0x81, 0x20,
-	0x81, 0xc5, 0x40, 0x7d, 0x8f, 0xa5, 0xc6, 0xdc, 0x70, 0x41, 0x37, 0x19, 0x08, 0x12, 0x58, 0xfc,
-	0x49, 0xbd, 0xc3, 0xcd, 0x9a, 0xf9, 0xe0, 0x90, 0x9f, 0x94, 0x81, 0x20, 0x81, 0x05, 0x1d, 0x90,
-	0xf5, 0xfc, 0xd0, 0x3c, 0x3f, 0x94, 0xe3, 0x99, 0x1f, 0x38, 0xd7, 0xfd, 0x10, 0x31, 0x0c, 0xf8,
-	0x13, 0x03, 0x80, 0x20, 0x49, 0xd1, 0x87, 0x06, 0x32, 0x12, 0x49, 0x41, 0x96, 0x92, 0xdc, 0x5e,
-	0xf3, 0x42, 0x72, 0x98, 0x5c, 0x8f, 0xb4, 0x3d, 0xa0, 0x79, 0x01, 0x7f, 0x69, 0x80, 0xb3, 0x7a,
-	0x9b, 0xac, 0xdc, 0x9b, 0xe7, 0x11, 0xb9, 0x31, 0xe8, 0x34, 0x2f, 0xfb, 0xbe, 0x5b, 0x36, 0xdb,
-	0xad, 0xc2, 0xd9, 0xe5, 0x1e, 0xa8, 0xa8, 0xa7, 0x2f, 0xf0, 0xb7, 0x06, 0x98, 0x96, 0x55, 0x54,
-	0xf3, 0xb0, 0xc0, 0x03, 0x88, 0x07, 0x1d, 0xc0, 0x34, 0x8e, 0x88, 0xa3, 0x7a, 0xc9, 0xde, 0xc5,
-	0x47, 0xdd, 0xae, 0xc1, 0x3f, 0x18, 0x60, 0xd2, 0xc6, 0x01, 0xf6, 0x6c, 0xec, 0x55, 0x99, 0xaf,
-	0x0b, 0x03, 0x19, 0x59, 0xa4, 0x7d, 0x5d, 0xd5, 0x20, 0x84, 0x9b, 0x25, 0xe9, 0xe6, 0xa4, 0xce,
-	0x3a, 0x6a, 0x15, 0x66, 0x13, 0x55, 0x9d, 0x83, 0x3a, 0xbc, 0x84, 0xef, 0x19, 0xe0, 0x74, 0xb2,
-	0x00, 0xe2, 0x48, 0xb9, 0x30, 0xc4, 0x3c, 0xe0, 0xed, 0xeb, 0x72, 0x27, 0x20, 0x4a, 0x7b, 0x00,
-	0x7f, 0x67, 0xb0, 0x4e, 0x2d, 0xbe, 0xf7, 0x51, 0xb3, 0xc8, 0x63, 0xf9, 0xc6, 0xc0, 0x63, 0xa9,
-	0x10, 0x44, 0x28, 0x2f, 0x27, 0xad, 0xa0, 0xe2, 0x1c, 0xb5, 0x0a, 0x33, 0x7a, 0x24, 0x15, 0x03,
-	0xe9, 0x1e, 0xc2, 0xef, 0x1b, 0x60, 0x12, 0x27, 0x1d, 0x37, 0x35, 0x2f, 0x0e, 0x24, 0x88, 0x3d,
-	0x9b, 0x78, 0x71, 0x53, 0xd7, 0x58, 0x14, 0x75, 0x60, 0xb3, 0x0e, 0x12, 0x1f, 0x58, 0x8d, 0xc0,
-	0xc5, 0xe6, 0xff, 0x0c, 0xb8, 0x83, 0x5c, 0x13, 0x76, 0x51, 0x0c, 0x00, 0x2f, 0x83, 0xbc, 0x17,
-	0xb9, 0xae, 0xb5, 0xe3, 0x62, 0xf3, 0x61, 0xde, 0x8b, 0xa8, 0x91, 0xec, 0x75, 0x49, 0x47, 0x4a,
-	0x02, 0xd6, 0xc0, 0xc2, 0xc1, 0x4b, 0xea, 0xf3, 0xa4, 0x9e, 0x43, 0x43, 0xf3, 0x12, 0xb7, 0x32,
-	0xd7, 0x6e, 0x15, 0x66, 0xb7, 0x7b, 0x8f, 0x15, 0xef, 0x6a, 0x03, 0xbe, 0x02, 0x1e, 0xd4, 0x64,
-	0xd6, 0x1a, 0x3b, 0xd8, 0xb6, 0xb1, 0x1d, 0x5f, 0xdc, 0xcc, 0xff, 0x15, 0x83, 0xcb, 0x78, 0x83,
-	0x6f, 0xa7, 0x05, 0xd0, 0x9d, 0xb4, 0xe1, 0x35, 0x30, 0xab, 0xb1, 0xd7, 0xbd, 0x70, 0x93, 0x54,
-	0x42, 0xe2, 0x78, 0x75, 0x73, 0x91, 0xdb, 0x3d, 0x1b, 0xef, 0xc8, 0x6d, 0x8d, 0x87, 0xfa, 0xe8,
-	0xc0, 0x2f, 0x75, 0x58, 0xe3, 0xaf, 0xd0, 0xac, 0xe0, 0x25, 0x7c, 0x48, 0xcd, 0x47, 0x78, 0x77,
-	0xc2, 0x17, 0x7b, 0x5b, 0xa3, 0xa3, 0x3e, 0xf2, 0xf0, 0x8b, 0xe0, 0x4c, 0x8a, 0xc3, 0xae, 0x28,
-	0xe6, 0xa3, 0xe2, 0xae, 0xc1, 0xfa, 0xd9, 0xed, 0x98, 0x88, 0x7a, 0x49, 0xc2, 0x2f, 0x00, 0xa8,
-	0x91, 0x37, 0xac, 0x80, 0xeb, 0x3f, 0x26, 0xae, 0x3d, 0x6c, 0x45, 0xb7, 0x25, 0x0d, 0xf5, 0x90,
-	0x83, 0x3f, 0x33, 0x3a, 0x9e, 0x24, 0xb9, 0x1d, 0x53, 0xf3, 0x32, 0xdf, 0xbf, 0x1b, 0xc7, 0xcc,
-	0x42, 0xed, 0x3d, 0x48, 0xe4, 0x62, 0x2d, 0xcc, 0x1a, 0x14, 0xea, 0xe3, 0xc2, 0x1c, 0xbb, 0xa1,
-	0xa7, 0x2a, 0x3c, 0x9c, 0x02, 0xd9, 0x3d, 0x2c, 0xbf, 0xaa, 0x40, 0xec, 0x27, 0xb4, 0x41, 0xae,
-	0x69, 0xb9, 0x51, 0x3c, 0x64, 0x18, 0x70, 0x77, 0x80, 0x84, 0xf1, 0xe7, 0x32, 0xcf, 0x1a, 0x73,
-	0xef, 0x1b, 0x60, 0xb6, 0xf7, 0xc1, 0x73, 0x5f, 0xdd, 0xfa, 0xb9, 0x01, 0xa6, 0xbb, 0xce, 0x98,
-	0x1e, 0x1e, 0xdd, 0xee, 0xf4, 0xe8, 0x95, 0x41, 0x1f, 0x16, 0x62, 0x73, 0xf0, 0x0e, 0x59, 0x77,
-	0xef, 0x47, 0x06, 0x98, 0x4a, 0x97, 0xed, 0xfb, 0x19, 0xaf, 0xe2, 0xfb, 0x19, 0x30, 0xdb, 0xbb,
-	0xb1, 0x87, 0x44, 0x4d, 0x30, 0x86, 0x33, 0x09, 0xea, 0x35, 0x35, 0x7e, 0xc7, 0x00, 0x13, 0x6f,
-	0x29, 0xb9, 0xf8, 0xad, 0xfb, 0xc0, 0x67, 0x50, 0xf1, 0x39, 0x99, 0x30, 0x28, 0xd2, 0x71, 0x8b,
-	0xbf, 0x37, 0xc0, 0x4c, 0xcf, 0x06, 0x00, 0x5e, 0x02, 0xa3, 0x96, 0xeb, 0xfa, 0xfb, 0x62, 0x94,
-	0xa8, 0xbd, 0x23, 0x58, 0xe6, 0x54, 0x24, 0xb9, 0x5a, 0xf4, 0x32, 0x9f, 0x55, 0xf4, 0x8a, 0x7f,
-	0x32, 0xc0, 0xf9, 0x3b, 0x65, 0xe2, 0x7d, 0x59, 0xd2, 0x45, 0x90, 0x97, 0xcd, 0xfb, 0x21, 0x5f,
-	0x4e, 0x59, 0x8a, 0x65, 0xd1, 0xe0, 0x1f, 0x9a, 0x89, 0x5f, 0xc5, 0x0f, 0x0c, 0x30, 0x55, 0xc1,
-	0xa4, 0xe9, 0x54, 0x31, 0xc2, 0x35, 0x4c, 0xb0, 0x57, 0xc5, 0x70, 0x09, 0x8c, 0xf3, 0xd7, 0xdd,
-	0x81, 0x55, 0x8d, 0x5f, 0xdd, 0x4c, 0xcb, 0x90, 0x8f, 0x5f, 0x8f, 0x19, 0x28, 0x91, 0x51, 0xaf,
-	0x79, 0x32, 0x7d, 0x5f, 0xf3, 0x9c, 0x07, 0x23, 0x41, 0x32, 0x88, 0xce, 0x33, 0x2e, 0x9f, 0x3d,
-	0x73, 0x2a, 0xe7, 0xfa, 0x24, 0xe4, 0xd3, 0xb5, 0x9c, 0xe4, 0xfa, 0x24, 0x44, 0x9c, 0xca, 0xf6,
-	0xcb, 0xa9, 0xce, 0x3a, 0xce, 0x00, 0x49, 0xe4, 0x76, 0xbd, 0x57, 0x62, 0x3c, 0xc4, 0x39, 0xfa,
-	0xe7, 0x2e, 0x99, 0x3b, 0x7f, 0xee, 0x02, 0x5f, 0x00, 0xd3, 0xf2, 0xe7, 0xda, 0x41, 0x40, 0x30,
-	0xe5, 0xef, 0x4e, 0xb3, 0x9d, 0x1f, 0xcd, 0x6e, 0xa4, 0x05, 0x50, 0xb7, 0x0e, 0xfc, 0x7c, 0xea,
-	0x53, 0x9c, 0x8b, 0xc9, 0x67, 0x38, 0xac, 0x25, 0xe4, 0x7d, 0xc6, 0x2d, 0x56, 0x06, 0xd6, 0x08,
-	0xf1, 0x49, 0xea, 0xfb, 0x9c, 0x25, 0x30, 0x5e, 0x63, 0x02, 0x7c, 0x5e, 0x9f, 0xeb, 0x0c, 0xfa,
-	0xd5, 0x98, 0x81, 0x12, 0x99, 0xe2, 0x9f, 0x0d, 0xd0, 0xeb, 0x4b, 0x39, 0x78, 0x4e, 0xcc, 0x5d,
-	0xb5, 0x61, 0x66, 0x3c, 0x73, 0x85, 0x4d, 0x30, 0x46, 0xc5, 0x62, 0xcb, 0x64, 0xdc, 0x3c, 0x66,
-	0x32, 0xa6, 0x53, 0x47, 0x34, 0x7c, 0x31, 0x35, 0x06, 0x63, 0xf9, 0x58, 0xb5, 0xca, 0x91, 0x67,
-	0xcb, 0x51, 0xfc, 0xa4, 0xc8, 0xc7, 0x95, 0x65, 0x41, 0x43, 0x8a, 0x5b, 0xae, 0x7e, 0xf8, 0xc9,
-	0xfc, 0x89, 0x8f, 0x3e, 0x99, 0x3f, 0xf1, 0xf1, 0x27, 0xf3, 0x27, 0xbe, 0xd9, 0x9e, 0x37, 0x3e,
-	0x6c, 0xcf, 0x1b, 0x1f, 0xb5, 0xe7, 0x8d, 0x8f, 0xdb, 0xf3, 0xc6, 0xdf, 0xdb, 0xf3, 0xc6, 0x8f,
-	0xff, 0x31, 0x7f, 0xe2, 0xab, 0xcf, 0x1f, 0xeb, 0xe3, 0xf4, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff,
-	0xde, 0xe9, 0x15, 0xbf, 0xf5, 0x2e, 0x00, 0x00,
+	0xd9, 0xf7, 0xec, 0x6a, 0xa5, 0x55, 0x4b, 0xb6, 0xa4, 0xb6, 0xa5, 0x8c, 0x15, 0x47, 0x2b, 0xaf,
+	0xdf, 0xf8, 0x55, 0x12, 0x67, 0x95, 0xf8, 0x4d, 0xde, 0xe4, 0xcd, 0x4b, 0x8a, 0xd2, 0x4a, 0x72,
+	0x50, 0x62, 0x59, 0xa2, 0xd7, 0x76, 0x04, 0xf9, 0x1c, 0xed, 0xf4, 0xae, 0x27, 0x9a, 0x9d, 0x19,
+	0x77, 0xcf, 0xac, 0xa4, 0x0a, 0x50, 0x7c, 0x54, 0x0a, 0x8a, 0x02, 0x42, 0x91, 0x5c, 0x28, 0xe0,
+	0x10, 0x28, 0x2e, 0x1c, 0xe0, 0x00, 0x37, 0xf8, 0x03, 0x72, 0x4c, 0x01, 0x87, 0x1c, 0xa8, 0x85,
+	0x2c, 0x57, 0x8e, 0x54, 0x51, 0xa5, 0x13, 0xd5, 0x1f, 0xd3, 0xd3, 0x3b, 0xbb, 0x6b, 0xbb, 0xa2,
+	0xdd, 0x98, 0xdb, 0xee, 0xf3, 0xf5, 0x7b, 0xe6, 0xe9, 0xa7, 0x9f, 0x7e, 0xfa, 0x99, 0x01, 0xb5,
+	0xbd, 0x67, 0x69, 0xc9, 0xf1, 0x97, 0xf7, 0xa2, 0x5d, 0x4c, 0x3c, 0x1c, 0x62, 0xba, 0xdc, 0xc4,
+	0x9e, 0xed, 0x93, 0x65, 0xc9, 0xb0, 0x02, 0x07, 0x1f, 0x84, 0xd8, 0xa3, 0x8e, 0xef, 0xd1, 0xc7,
+	0xad, 0xc0, 0xa1, 0x98, 0x34, 0x31, 0x59, 0x0e, 0xf6, 0xea, 0x8c, 0x47, 0x3b, 0x05, 0x96, 0x9b,
+	0x4f, 0xee, 0xe2, 0xd0, 0x7a, 0x72, 0xb9, 0x8e, 0x3d, 0x4c, 0xac, 0x10, 0xdb, 0xa5, 0x80, 0xf8,
+	0xa1, 0x0f, 0x9f, 0x17, 0xe6, 0x4a, 0x1d, 0xd2, 0x6f, 0x28, 0x73, 0xa5, 0x60, 0xaf, 0xce, 0x78,
+	0xb4, 0x53, 0xa0, 0x24, 0xcd, 0xcd, 0x3f, 0x5e, 0x77, 0xc2, 0x5b, 0xd1, 0x6e, 0xa9, 0xea, 0x37,
+	0x96, 0xeb, 0x7e, 0xdd, 0x5f, 0xe6, 0x56, 0x77, 0xa3, 0x1a, 0xff, 0xc7, 0xff, 0xf0, 0x5f, 0x02,
+	0x6d, 0xfe, 0xa9, 0xc4, 0xf9, 0x86, 0x55, 0xbd, 0xe5, 0x78, 0x98, 0x1c, 0x26, 0x1e, 0x37, 0x70,
+	0x68, 0x2d, 0x37, 0xbb, 0x7c, 0x9c, 0x5f, 0xee, 0xa7, 0x45, 0x22, 0x2f, 0x74, 0x1a, 0xb8, 0x4b,
+	0xe1, 0x7f, 0xef, 0xa6, 0x40, 0xab, 0xb7, 0x70, 0xc3, 0x4a, 0xeb, 0x15, 0x8f, 0x0c, 0x30, 0xb3,
+	0xea, 0x7b, 0x4d, 0x4c, 0xd8, 0x53, 0x22, 0x7c, 0x3b, 0xc2, 0x34, 0x84, 0x65, 0x90, 0x8d, 0x1c,
+	0xdb, 0x34, 0x16, 0x8d, 0xa5, 0xf1, 0xf2, 0x13, 0x1f, 0xb6, 0x0a, 0x27, 0xda, 0xad, 0x42, 0xf6,
+	0xc6, 0xc6, 0xda, 0x51, 0xab, 0x70, 0xbe, 0x1f, 0x52, 0x78, 0x18, 0x60, 0x5a, 0xba, 0xb1, 0xb1,
+	0x86, 0x98, 0x32, 0x7c, 0x01, 0xcc, 0xd8, 0x98, 0x3a, 0x04, 0xdb, 0x2b, 0xdb, 0x1b, 0x37, 0x85,
+	0x7d, 0x33, 0xc3, 0x2d, 0x9e, 0x95, 0x16, 0x67, 0xd6, 0xd2, 0x02, 0xa8, 0x5b, 0x07, 0xee, 0x80,
+	0x31, 0x7f, 0xf7, 0x2d, 0x5c, 0x0d, 0xa9, 0x99, 0x5d, 0xcc, 0x2e, 0x4d, 0x5c, 0x7e, 0xbc, 0x94,
+	0xac, 0xa0, 0x72, 0x81, 0x2f, 0x9b, 0x7c, 0xd8, 0x12, 0xb2, 0xf6, 0xd7, 0xe3, 0x95, 0x2b, 0x4f,
+	0x49, 0xb4, 0xb1, 0x2d, 0x61, 0x05, 0xc5, 0xe6, 0x8a, 0xbf, 0xc8, 0x00, 0xa8, 0x3f, 0x3c, 0x0d,
+	0x7c, 0x8f, 0xe2, 0x81, 0x3c, 0x3d, 0x05, 0xd3, 0x55, 0x6e, 0x39, 0xc4, 0xb6, 0xc4, 0x35, 0x33,
+	0x9f, 0xc6, 0x7b, 0x53, 0xe2, 0x4f, 0xaf, 0xa6, 0xcc, 0xa1, 0x2e, 0x00, 0x78, 0x1d, 0x8c, 0x12,
+	0x4c, 0x23, 0x37, 0x34, 0xb3, 0x8b, 0xc6, 0xd2, 0xc4, 0xe5, 0x4b, 0x7d, 0xa1, 0x78, 0x7e, 0xb3,
+	0xe4, 0x2b, 0x35, 0x9f, 0x2c, 0x55, 0x42, 0x2b, 0x8c, 0x68, 0xf9, 0x94, 0x44, 0x1a, 0x45, 0xdc,
+	0x06, 0x92, 0xb6, 0x8a, 0xdf, 0xc9, 0x80, 0x69, 0x3d, 0x4a, 0x4d, 0x07, 0xef, 0xc3, 0x7d, 0x30,
+	0x46, 0x44, 0xb2, 0xf0, 0x38, 0x4d, 0x5c, 0xde, 0x2e, 0x1d, 0x6b, 0x5b, 0x95, 0xba, 0x92, 0xb0,
+	0x3c, 0xc1, 0xd6, 0x4c, 0xfe, 0x41, 0x31, 0x1a, 0x7c, 0x1b, 0xe4, 0x89, 0x5c, 0x28, 0x9e, 0x4d,
+	0x13, 0x97, 0xbf, 0x38, 0x40, 0x64, 0x61, 0xb8, 0x3c, 0xd9, 0x6e, 0x15, 0xf2, 0xf1, 0x3f, 0xa4,
+	0x00, 0x8b, 0xef, 0x65, 0xc0, 0xc2, 0x6a, 0x44, 0x43, 0xbf, 0x81, 0x30, 0xf5, 0x23, 0x52, 0xc5,
+	0xab, 0xbe, 0x1b, 0x35, 0xbc, 0x35, 0x5c, 0x73, 0x3c, 0x27, 0x64, 0xd9, 0xba, 0x08, 0x46, 0x3c,
+	0xab, 0x81, 0x65, 0xf6, 0x4c, 0xca, 0x98, 0x8e, 0x5c, 0xb3, 0x1a, 0x18, 0x71, 0x0e, 0x93, 0x60,
+	0xc9, 0x22, 0xf7, 0x82, 0x92, 0xb8, 0x7e, 0x18, 0x60, 0xc4, 0x39, 0xf0, 0x22, 0x18, 0xad, 0xf9,
+	0xa4, 0x61, 0x89, 0x75, 0x1c, 0x4f, 0x56, 0xe6, 0x0a, 0xa7, 0x22, 0xc9, 0x85, 0x4f, 0x83, 0x09,
+	0x1b, 0xd3, 0x2a, 0x71, 0x02, 0x06, 0x6d, 0x8e, 0x70, 0xe1, 0xd3, 0x52, 0x78, 0x62, 0x2d, 0x61,
+	0x21, 0x5d, 0x0e, 0x5e, 0x02, 0xf9, 0x80, 0x38, 0x3e, 0x71, 0xc2, 0x43, 0x33, 0xb7, 0x68, 0x2c,
+	0xe5, 0xca, 0xd3, 0x52, 0x27, 0xbf, 0x2d, 0xe9, 0x48, 0x49, 0xc0, 0x45, 0x90, 0x7f, 0xb1, 0xb2,
+	0x75, 0x6d, 0xdb, 0x0a, 0x6f, 0x99, 0xa3, 0x1c, 0x61, 0x84, 0x49, 0x23, 0x45, 0x2d, 0xfe, 0x25,
+	0x03, 0xcc, 0x74, 0x54, 0xe2, 0x90, 0xc2, 0x2b, 0x20, 0x4f, 0x43, 0x56, 0x71, 0xea, 0x87, 0x32,
+	0x26, 0x8f, 0xc6, 0x60, 0x15, 0x49, 0x3f, 0x6a, 0x15, 0xe6, 0x12, 0x8d, 0x98, 0xca, 0xe3, 0xa1,
+	0x74, 0xe1, 0xcf, 0x0c, 0x70, 0x7a, 0x1f, 0xef, 0xde, 0xf2, 0xfd, 0xbd, 0x55, 0xd7, 0xc1, 0x5e,
+	0xb8, 0xea, 0x7b, 0x35, 0xa7, 0x2e, 0x73, 0x00, 0x1d, 0x33, 0x07, 0x5e, 0xee, 0xb6, 0x5c, 0x7e,
+	0xa0, 0xdd, 0x2a, 0x9c, 0xee, 0xc1, 0x40, 0xbd, 0xfc, 0x80, 0x3b, 0xc0, 0xac, 0xa6, 0x36, 0x89,
+	0x2c, 0x60, 0xa2, 0x6c, 0x8d, 0x97, 0xcf, 0xb5, 0x5b, 0x05, 0x73, 0xb5, 0x8f, 0x0c, 0xea, 0xab,
+	0x5d, 0xfc, 0x56, 0x36, 0x1d, 0x5e, 0x2d, 0xdd, 0xde, 0x04, 0x79, 0xb6, 0x8d, 0x6d, 0x2b, 0xb4,
+	0xe4, 0x46, 0x7c, 0xe2, 0xde, 0x36, 0xbd, 0xa8, 0x19, 0x9b, 0x38, 0xb4, 0xca, 0x50, 0x2e, 0x08,
+	0x48, 0x68, 0x48, 0x59, 0x85, 0x5f, 0x05, 0x23, 0x34, 0xc0, 0x55, 0x19, 0xe8, 0x57, 0x8e, 0xbb,
+	0xd9, 0xfa, 0x3c, 0x48, 0x25, 0xc0, 0xd5, 0x64, 0x2f, 0xb0, 0x7f, 0x88, 0xc3, 0xc2, 0x77, 0x0c,
+	0x30, 0x4a, 0x79, 0x81, 0x92, 0x45, 0xed, 0xb5, 0x61, 0x79, 0x90, 0xaa, 0x82, 0xe2, 0x3f, 0x92,
+	0xe0, 0xc5, 0x7f, 0x66, 0xc0, 0xf9, 0x7e, 0xaa, 0xab, 0xbe, 0x67, 0x8b, 0xe5, 0xd8, 0x90, 0x7b,
+	0x5b, 0x64, 0xfa, 0xd3, 0xfa, 0xde, 0x3e, 0x6a, 0x15, 0x1e, 0xbe, 0xab, 0x01, 0xad, 0x08, 0xfc,
+	0x9f, 0x7a, 0x6e, 0x51, 0x28, 0xce, 0x77, 0x3a, 0x76, 0xd4, 0x2a, 0x4c, 0x29, 0xb5, 0x4e, 0x5f,
+	0x61, 0x13, 0x40, 0xd7, 0xa2, 0xe1, 0x75, 0x62, 0x79, 0x54, 0x98, 0x75, 0x1a, 0x58, 0x86, 0xef,
+	0xd1, 0x7b, 0x4b, 0x0f, 0xa6, 0x51, 0x9e, 0x97, 0x90, 0xf0, 0x6a, 0x97, 0x35, 0xd4, 0x03, 0x81,
+	0xd5, 0x2d, 0x82, 0x2d, 0xaa, 0x4a, 0x91, 0x76, 0xa2, 0x30, 0x2a, 0x92, 0x5c, 0xf8, 0x08, 0x18,
+	0x6b, 0x60, 0x4a, 0xad, 0x3a, 0xe6, 0xf5, 0x67, 0x3c, 0x39, 0xa2, 0x37, 0x05, 0x19, 0xc5, 0x7c,
+	0xd6, 0x9f, 0x9c, 0xeb, 0x17, 0xb5, 0xab, 0x0e, 0x0d, 0xe1, 0xab, 0x5d, 0x1b, 0xa0, 0x74, 0x6f,
+	0x4f, 0xc8, 0xb4, 0x79, 0xfa, 0xab, 0xe2, 0x17, 0x53, 0xb4, 0xe4, 0xff, 0x0a, 0xc8, 0x39, 0x21,
+	0x6e, 0xc4, 0x67, 0xf7, 0xcb, 0x43, 0xca, 0xbd, 0xf2, 0x49, 0xe9, 0x43, 0x6e, 0x83, 0xa1, 0x21,
+	0x01, 0x5a, 0xfc, 0x65, 0x06, 0x3c, 0xd4, 0x4f, 0x85, 0x1d, 0x28, 0x94, 0x45, 0x3c, 0x70, 0x23,
+	0x62, 0xb9, 0x32, 0xe3, 0x54, 0xc4, 0xb7, 0x39, 0x15, 0x49, 0x2e, 0x2b, 0xf9, 0xd4, 0xf1, 0xea,
+	0x91, 0x6b, 0x11, 0x99, 0x4e, 0xea, 0xa9, 0x2b, 0x92, 0x8e, 0x94, 0x04, 0x2c, 0x01, 0x40, 0x6f,
+	0xf9, 0x24, 0xe4, 0x18, 0xb2, 0x7a, 0x9d, 0x62, 0x05, 0xa2, 0xa2, 0xa8, 0x48, 0x93, 0x60, 0x27,
+	0xda, 0x9e, 0xe3, 0xd9, 0x72, 0xd5, 0xd5, 0x2e, 0x7e, 0xc9, 0xf1, 0x6c, 0xc4, 0x39, 0x0c, 0xdf,
+	0x75, 0x68, 0xc8, 0x28, 0x72, 0xc9, 0x3b, 0xa2, 0xce, 0x25, 0x95, 0x04, 0xc3, 0xaf, 0xb2, 0xaa,
+	0xef, 0x13, 0x07, 0x53, 0x73, 0x34, 0xc1, 0x5f, 0x55, 0x54, 0xa4, 0x49, 0x14, 0xff, 0x91, 0xef,
+	0x9f, 0x24, 0xac, 0x94, 0xc0, 0x0b, 0x20, 0x57, 0x27, 0x7e, 0x14, 0xc8, 0x28, 0xa9, 0x68, 0xbf,
+	0xc0, 0x88, 0x48, 0xf0, 0x58, 0x56, 0x36, 0x3b, 0xda, 0x54, 0x95, 0x95, 0x71, 0x73, 0x1a, 0xf3,
+	0xe1, 0x37, 0x0c, 0x90, 0xf3, 0x64, 0x70, 0x58, 0xca, 0xbd, 0x3a, 0xa4, 0xbc, 0xe0, 0xe1, 0x4d,
+	0xdc, 0x15, 0x91, 0x17, 0xc8, 0xf0, 0x29, 0x90, 0xa3, 0x55, 0x3f, 0xc0, 0x32, 0xea, 0x0b, 0xb1,
+	0x50, 0x85, 0x11, 0x8f, 0x5a, 0x85, 0x93, 0xb1, 0x39, 0x4e, 0x40, 0x42, 0x18, 0x7e, 0xdb, 0x00,
+	0xa0, 0x69, 0xb9, 0x8e, 0x6d, 0xf1, 0x96, 0x21, 0xc7, 0xdd, 0x1f, 0x6c, 0x5a, 0xdf, 0x54, 0xe6,
+	0xc5, 0xa2, 0x25, 0xff, 0x91, 0x06, 0x0d, 0xdf, 0x35, 0xc0, 0x24, 0x8d, 0x76, 0x89, 0xd4, 0xa2,
+	0xbc, 0xb9, 0x98, 0xb8, 0xfc, 0xa5, 0x81, 0xfa, 0x52, 0xd1, 0x00, 0xca, 0xd3, 0xed, 0x56, 0x61,
+	0x52, 0xa7, 0xa0, 0x0e, 0x07, 0xe0, 0xf7, 0x0c, 0x90, 0x6f, 0xc6, 0x67, 0xf6, 0x18, 0xdf, 0xf0,
+	0xaf, 0x0f, 0x69, 0x61, 0x65, 0x46, 0x25, 0xbb, 0x40, 0xf5, 0x01, 0xca, 0x03, 0xf8, 0x7b, 0x03,
+	0x98, 0x96, 0x2d, 0x0a, 0xbc, 0xe5, 0x6e, 0x13, 0xc7, 0x0b, 0x31, 0x11, 0xfd, 0x26, 0x35, 0xf3,
+	0xdc, 0xbd, 0xc1, 0x9e, 0x85, 0xe9, 0x5e, 0xb6, 0xbc, 0x28, 0xbd, 0x33, 0x57, 0xfa, 0xb8, 0x81,
+	0xfa, 0x3a, 0xc8, 0x13, 0x2d, 0x69, 0x69, 0xcc, 0xf1, 0x21, 0x24, 0x5a, 0xd2, 0x4b, 0xc9, 0xea,
+	0x90, 0x74, 0x50, 0x1a, 0x34, 0xdc, 0x02, 0xb3, 0x01, 0xc1, 0x1c, 0xe0, 0x86, 0xb7, 0xe7, 0xf9,
+	0xfb, 0xde, 0x15, 0x07, 0xbb, 0x36, 0x35, 0xc1, 0xa2, 0xb1, 0x94, 0x2f, 0x9f, 0x6d, 0xb7, 0x0a,
+	0xb3, 0xdb, 0xbd, 0x04, 0x50, 0x6f, 0xbd, 0xe2, 0xbb, 0xd9, 0xf4, 0x2d, 0x20, 0xdd, 0x45, 0xc0,
+	0xf7, 0xc5, 0xd3, 0x8b, 0xd8, 0x50, 0xd3, 0xe0, 0xab, 0xf5, 0xe6, 0x90, 0x92, 0x49, 0xb5, 0x01,
+	0x49, 0x27, 0xa7, 0x48, 0x14, 0x69, 0x7e, 0xc0, 0x1f, 0x1b, 0xe0, 0xa4, 0x55, 0xad, 0xe2, 0x20,
+	0xc4, 0xb6, 0x28, 0xee, 0x99, 0xcf, 0xa0, 0x7e, 0xcd, 0x4a, 0xaf, 0x4e, 0xae, 0xe8, 0xd0, 0xa8,
+	0xd3, 0x13, 0xf8, 0x1c, 0x38, 0x45, 0x43, 0x9f, 0x60, 0x3b, 0xd5, 0x36, 0xc3, 0x76, 0xab, 0x70,
+	0xaa, 0xd2, 0xc1, 0x41, 0x29, 0xc9, 0xe2, 0x5f, 0x73, 0xa0, 0x70, 0x97, 0xad, 0x76, 0x0f, 0x17,
+	0xb3, 0x8b, 0x60, 0x94, 0x3f, 0xae, 0xcd, 0xa3, 0x92, 0xd7, 0x5a, 0x41, 0x4e, 0x45, 0x92, 0xcb,
+	0x0e, 0x0a, 0x86, 0xcf, 0xda, 0x97, 0x2c, 0x17, 0x54, 0x07, 0x45, 0x45, 0x90, 0x51, 0xcc, 0x87,
+	0x97, 0x01, 0xb0, 0x71, 0x40, 0x30, 0x3b, 0xac, 0x6c, 0x73, 0x8c, 0x4b, 0xab, 0x45, 0x5a, 0x53,
+	0x1c, 0xa4, 0x49, 0xc1, 0x2b, 0x00, 0xc6, 0xff, 0x1c, 0xdf, 0x7b, 0xd9, 0x22, 0x9e, 0xe3, 0xd5,
+	0xcd, 0x3c, 0x77, 0x7b, 0x8e, 0x75, 0x63, 0x6b, 0x5d, 0x5c, 0xd4, 0x43, 0x03, 0xbe, 0x0d, 0x46,
+	0xc5, 0xd0, 0x87, 0x9f, 0x10, 0x43, 0xac, 0xf2, 0x80, 0xc7, 0x88, 0x43, 0x21, 0x09, 0xd9, 0x5d,
+	0xdd, 0x73, 0xf7, 0xbb, 0xba, 0xdf, 0xb1, 0x9c, 0x8e, 0xfe, 0x87, 0x97, 0xd3, 0xe2, 0xbf, 0x8c,
+	0x74, 0xcd, 0xd1, 0x1e, 0xb5, 0x52, 0xb5, 0x5c, 0x0c, 0xd7, 0xc0, 0x34, 0xbb, 0x31, 0x21, 0x1c,
+	0xb8, 0x4e, 0xd5, 0xa2, 0xfc, 0xc2, 0x2e, 0x92, 0x5d, 0xcd, 0x90, 0x2a, 0x29, 0x3e, 0xea, 0xd2,
+	0x80, 0x2f, 0x02, 0x28, 0x6e, 0x11, 0x1d, 0x76, 0x44, 0x43, 0xa4, 0xee, 0x03, 0x95, 0x2e, 0x09,
+	0xd4, 0x43, 0x0b, 0xae, 0x82, 0x19, 0xd7, 0xda, 0xc5, 0x6e, 0x05, 0xbb, 0xb8, 0x1a, 0xfa, 0x84,
+	0x9b, 0x12, 0x23, 0x8d, 0xd9, 0x76, 0xab, 0x30, 0x73, 0x35, 0xcd, 0x44, 0xdd, 0xf2, 0xc5, 0xf3,
+	0xe9, 0xad, 0xad, 0x3f, 0xb8, 0xb8, 0x9b, 0x7d, 0x90, 0x01, 0xf3, 0xfd, 0x33, 0x03, 0x7e, 0x33,
+	0xb9, 0x42, 0x8a, 0x1b, 0xc2, 0xeb, 0xc3, 0xca, 0x42, 0x79, 0x87, 0x04, 0xdd, 0xf7, 0x47, 0xf8,
+	0x35, 0xd6, 0xae, 0x59, 0x6e, 0x3c, 0xb4, 0x7a, 0x6d, 0x68, 0x2e, 0x30, 0x90, 0xf2, 0xb8, 0xe8,
+	0x04, 0x2d, 0x97, 0x37, 0x7e, 0x96, 0x8b, 0x8b, 0xbf, 0x32, 0xd2, 0x53, 0x84, 0x64, 0x07, 0xc3,
+	0xef, 0x1b, 0x60, 0xca, 0x0f, 0xb0, 0xb7, 0xb2, 0xbd, 0x71, 0xf3, 0x7f, 0xc4, 0x4e, 0x96, 0xa1,
+	0xba, 0x76, 0x4c, 0x3f, 0x5f, 0xac, 0x6c, 0x5d, 0x13, 0x06, 0xb7, 0x89, 0x1f, 0xd0, 0xf2, 0xe9,
+	0x76, 0xab, 0x30, 0xb5, 0xd5, 0x09, 0x85, 0xd2, 0xd8, 0xc5, 0x06, 0x98, 0x5d, 0x3f, 0x08, 0x31,
+	0xf1, 0x2c, 0x77, 0xcd, 0xaf, 0x46, 0x0d, 0xec, 0x85, 0xc2, 0xd1, 0xd4, 0xc4, 0xcb, 0xb8, 0xc7,
+	0x89, 0xd7, 0x43, 0x20, 0x1b, 0x11, 0x57, 0x66, 0xf1, 0x84, 0x9a, 0xe8, 0xa2, 0xab, 0x88, 0xd1,
+	0x8b, 0xe7, 0xc1, 0x08, 0xf3, 0x13, 0x9e, 0x05, 0x59, 0x62, 0xed, 0x73, 0xab, 0x93, 0xe5, 0x31,
+	0x26, 0x82, 0xac, 0x7d, 0xc4, 0x68, 0xc5, 0x3f, 0x9f, 0x07, 0x53, 0xa9, 0x67, 0x81, 0xf3, 0x20,
+	0xa3, 0xc6, 0xc4, 0x40, 0x1a, 0xcd, 0x6c, 0xac, 0xa1, 0x8c, 0x63, 0xc3, 0x67, 0x54, 0xf1, 0x15,
+	0xa0, 0x05, 0x75, 0x96, 0x70, 0x2a, 0xeb, 0xcf, 0x13, 0x73, 0xcc, 0x91, 0xb8, 0x70, 0x32, 0x1f,
+	0x70, 0x4d, 0xee, 0x12, 0xe1, 0x03, 0xae, 0x21, 0x46, 0xfb, 0xb4, 0xe3, 0xbe, 0x78, 0xde, 0x98,
+	0xbb, 0x87, 0x79, 0xe3, 0xe8, 0x1d, 0xe7, 0x8d, 0x17, 0x40, 0x2e, 0x74, 0x42, 0x17, 0xf3, 0x83,
+	0x4c, 0xbb, 0x46, 0x5d, 0x67, 0x44, 0x24, 0x78, 0xf0, 0x2d, 0x30, 0x66, 0xe3, 0x9a, 0x15, 0xb9,
+	0x21, 0x3f, 0xb3, 0x26, 0x2e, 0xaf, 0x0e, 0x20, 0x85, 0xc4, 0x30, 0x78, 0x4d, 0xd8, 0x45, 0x31,
+	0x00, 0x7c, 0x18, 0x8c, 0x35, 0xac, 0x03, 0xa7, 0x11, 0x35, 0x78, 0x83, 0x69, 0x08, 0xb1, 0x4d,
+	0x41, 0x42, 0x31, 0x8f, 0x55, 0x46, 0x7c, 0x50, 0x75, 0x23, 0xea, 0x34, 0xb1, 0x64, 0xca, 0xe6,
+	0x4f, 0x55, 0xc6, 0xf5, 0x14, 0x1f, 0x75, 0x69, 0x70, 0x30, 0xc7, 0xe3, 0xca, 0x13, 0x1a, 0x98,
+	0x20, 0xa1, 0x98, 0xd7, 0x09, 0x26, 0xe5, 0x27, 0xfb, 0x81, 0x49, 0xe5, 0x2e, 0x0d, 0xf8, 0x18,
+	0x18, 0x6f, 0x58, 0x07, 0x57, 0xb1, 0x57, 0x0f, 0x6f, 0x99, 0x27, 0x17, 0x8d, 0xa5, 0x6c, 0xf9,
+	0x64, 0xbb, 0x55, 0x18, 0xdf, 0x8c, 0x89, 0x28, 0xe1, 0x73, 0x61, 0xc7, 0x93, 0xc2, 0xa7, 0x34,
+	0xe1, 0x98, 0x88, 0x12, 0x3e, 0xeb, 0x5e, 0x02, 0x2b, 0x64, 0x9b, 0xcb, 0x9c, 0xea, 0xbc, 0xe6,
+	0x6e, 0x0b, 0x32, 0x8a, 0xf9, 0x70, 0x09, 0xe4, 0x1b, 0xd6, 0x01, 0x1f, 0x49, 0x98, 0xd3, 0xdc,
+	0x2c, 0x1f, 0x8c, 0x6f, 0x4a, 0x1a, 0x52, 0x5c, 0x2e, 0xe9, 0x78, 0x42, 0x72, 0x46, 0x93, 0x94,
+	0x34, 0xa4, 0xb8, 0x2c, 0x89, 0x23, 0xcf, 0xb9, 0x1d, 0x61, 0x21, 0x0c, 0x79, 0x64, 0x54, 0x12,
+	0xdf, 0x48, 0x58, 0x48, 0x97, 0x83, 0x25, 0x00, 0x1a, 0x91, 0x1b, 0x3a, 0x81, 0x8b, 0xb7, 0x6a,
+	0xe6, 0x69, 0x1e, 0x7f, 0xde, 0xf4, 0x6f, 0x2a, 0x2a, 0xd2, 0x24, 0x20, 0x06, 0x23, 0xd8, 0x8b,
+	0x1a, 0xe6, 0x19, 0x7e, 0xb0, 0x0f, 0x24, 0x05, 0xd5, 0xce, 0x59, 0xf7, 0xa2, 0x06, 0xe2, 0xe6,
+	0xe1, 0x33, 0xe0, 0x64, 0xc3, 0x3a, 0x60, 0xe5, 0x00, 0x93, 0xd0, 0xc1, 0xd4, 0x9c, 0xe5, 0x0f,
+	0x3f, 0xc3, 0xba, 0xdd, 0x4d, 0x9d, 0x81, 0x3a, 0xe5, 0xb8, 0xa2, 0xe3, 0x69, 0x8a, 0x73, 0x9a,
+	0xa2, 0xce, 0x40, 0x9d, 0x72, 0x2c, 0xd2, 0x04, 0xdf, 0x8e, 0x1c, 0x82, 0x6d, 0xf3, 0x01, 0xde,
+	0x20, 0xcb, 0x97, 0x15, 0x82, 0x86, 0x14, 0x17, 0x36, 0xe3, 0xd9, 0x95, 0xc9, 0xb7, 0xe1, 0x8d,
+	0xc1, 0x56, 0xf2, 0x2d, 0xb2, 0x42, 0x88, 0x75, 0x28, 0x4e, 0x1a, 0x7d, 0x6a, 0x05, 0x29, 0xc8,
+	0x59, 0xae, 0xbb, 0x55, 0x33, 0xcf, 0xf2, 0xd8, 0x0f, 0xfa, 0x04, 0x51, 0x55, 0x67, 0x85, 0x81,
+	0x20, 0x81, 0xc5, 0x40, 0x7d, 0x8f, 0xa5, 0xc6, 0xfc, 0x70, 0x41, 0xb7, 0x18, 0x08, 0x12, 0x58,
+	0xfc, 0x49, 0xbd, 0xc3, 0xad, 0x9a, 0xf9, 0xe0, 0x90, 0x9f, 0x94, 0x81, 0x20, 0x81, 0x05, 0x1d,
+	0x90, 0xf5, 0xfc, 0xd0, 0x3c, 0x37, 0x94, 0xe3, 0x99, 0x1f, 0x38, 0xd7, 0xfc, 0x10, 0x31, 0x0c,
+	0xf8, 0x23, 0x03, 0x80, 0x20, 0x49, 0xd1, 0x87, 0x06, 0x32, 0x12, 0x49, 0x41, 0x96, 0x92, 0xdc,
+	0x5e, 0xf7, 0x42, 0x72, 0x98, 0x5c, 0x8f, 0xb4, 0x3d, 0xa0, 0x79, 0x01, 0x7f, 0x6e, 0x80, 0x33,
+	0x7a, 0x9b, 0xac, 0xdc, 0x5b, 0xe0, 0x11, 0xb9, 0x3e, 0xe8, 0x34, 0x2f, 0xfb, 0xbe, 0x5b, 0x36,
+	0xdb, 0xad, 0xc2, 0x99, 0x95, 0x1e, 0xa8, 0xa8, 0xa7, 0x2f, 0xf0, 0xd7, 0x06, 0x98, 0x91, 0x55,
+	0x54, 0xf3, 0xb0, 0xc0, 0x03, 0x88, 0x07, 0x1d, 0xc0, 0x34, 0x8e, 0x88, 0xa3, 0x7a, 0xc9, 0xde,
+	0xc5, 0x47, 0xdd, 0xae, 0xc1, 0xdf, 0x19, 0x60, 0xd2, 0xc6, 0x01, 0xf6, 0x6c, 0xec, 0x55, 0x99,
+	0xaf, 0x8b, 0x03, 0x19, 0x59, 0xa4, 0x7d, 0x5d, 0xd3, 0x20, 0x84, 0x9b, 0x25, 0xe9, 0xe6, 0xa4,
+	0xce, 0x3a, 0x6a, 0x15, 0xe6, 0x12, 0x55, 0x9d, 0x83, 0x3a, 0xbc, 0x84, 0xef, 0x19, 0x60, 0x2a,
+	0x59, 0x00, 0x71, 0xa4, 0x9c, 0x1f, 0x62, 0x1e, 0xf0, 0xf6, 0x75, 0xa5, 0x13, 0x10, 0xa5, 0x3d,
+	0x80, 0xbf, 0x31, 0x58, 0xa7, 0x16, 0xdf, 0xfb, 0xa8, 0x59, 0xe4, 0xb1, 0x7c, 0x63, 0xe0, 0xb1,
+	0x54, 0x08, 0x22, 0x94, 0x97, 0x92, 0x56, 0x50, 0x71, 0x8e, 0x5a, 0x85, 0x59, 0x3d, 0x92, 0x8a,
+	0x81, 0x74, 0x0f, 0xe1, 0x77, 0x0d, 0x30, 0x89, 0x93, 0x8e, 0x9b, 0x9a, 0x17, 0x06, 0x12, 0xc4,
+	0x9e, 0x4d, 0xbc, 0xb8, 0xa9, 0x6b, 0x2c, 0x8a, 0x3a, 0xb0, 0x59, 0x07, 0x89, 0x0f, 0xac, 0x46,
+	0xe0, 0x62, 0xf3, 0xbf, 0x06, 0xdc, 0x41, 0xae, 0x0b, 0xbb, 0x28, 0x06, 0x80, 0x97, 0x40, 0xde,
+	0x8b, 0x5c, 0xd7, 0xda, 0x75, 0xb1, 0xf9, 0x30, 0xef, 0x45, 0xd4, 0x48, 0xf6, 0x9a, 0xa4, 0x23,
+	0x25, 0x01, 0x6b, 0x60, 0xf1, 0xe0, 0x25, 0xf5, 0x79, 0x52, 0xcf, 0xa1, 0xa1, 0x79, 0x91, 0x5b,
+	0x99, 0x6f, 0xb7, 0x0a, 0x73, 0x3b, 0xbd, 0xc7, 0x8a, 0x77, 0xb5, 0x01, 0x5f, 0x01, 0x0f, 0x6a,
+	0x32, 0xeb, 0x8d, 0x5d, 0x6c, 0xdb, 0xd8, 0x8e, 0x2f, 0x6e, 0xe6, 0x7f, 0x8b, 0xc1, 0x65, 0xbc,
+	0xc1, 0x77, 0xd2, 0x02, 0xe8, 0x4e, 0xda, 0xf0, 0x2a, 0x98, 0xd3, 0xd8, 0x1b, 0x5e, 0xb8, 0x45,
+	0x2a, 0x21, 0x71, 0xbc, 0xba, 0xb9, 0xc4, 0xed, 0x9e, 0x89, 0x77, 0xe4, 0x8e, 0xc6, 0x43, 0x7d,
+	0x74, 0xe0, 0x17, 0x3a, 0xac, 0xf1, 0x57, 0x68, 0x56, 0xf0, 0x12, 0x3e, 0xa4, 0xe6, 0x23, 0xbc,
+	0x3b, 0xe1, 0x8b, 0xbd, 0xa3, 0xd1, 0x51, 0x1f, 0x79, 0xf8, 0x79, 0x70, 0x3a, 0xc5, 0x61, 0x57,
+	0x14, 0xf3, 0x51, 0x71, 0xd7, 0x60, 0xfd, 0xec, 0x4e, 0x4c, 0x44, 0xbd, 0x24, 0xe1, 0xe7, 0x00,
+	0xd4, 0xc8, 0x9b, 0x56, 0xc0, 0xf5, 0x1f, 0x13, 0xd7, 0x1e, 0xb6, 0xa2, 0x3b, 0x92, 0x86, 0x7a,
+	0xc8, 0xc1, 0x9f, 0x18, 0x1d, 0x4f, 0x92, 0xdc, 0x8e, 0xa9, 0x79, 0x89, 0xef, 0xdf, 0xcd, 0x63,
+	0x66, 0xa1, 0xf6, 0x1e, 0x24, 0x72, 0xb1, 0x16, 0x66, 0x0d, 0x0a, 0xf5, 0x71, 0x61, 0x9e, 0xdd,
+	0xd0, 0x53, 0x15, 0x1e, 0x4e, 0x83, 0xec, 0x1e, 0x96, 0x5f, 0x55, 0x20, 0xf6, 0x13, 0xda, 0x20,
+	0xd7, 0xb4, 0xdc, 0x28, 0x1e, 0x32, 0x0c, 0xb8, 0x3b, 0x40, 0xc2, 0xf8, 0x73, 0x99, 0x67, 0x8d,
+	0xf9, 0xf7, 0x0d, 0x30, 0xd7, 0xfb, 0xe0, 0xb9, 0xaf, 0x6e, 0xfd, 0xd4, 0x00, 0x33, 0x5d, 0x67,
+	0x4c, 0x0f, 0x8f, 0x6e, 0x77, 0x7a, 0xf4, 0xca, 0xa0, 0x0f, 0x0b, 0xb1, 0x39, 0x78, 0x87, 0xac,
+	0xbb, 0xf7, 0x03, 0x03, 0x4c, 0xa7, 0xcb, 0xf6, 0xfd, 0x8c, 0x57, 0xf1, 0xfd, 0x0c, 0x98, 0xeb,
+	0xdd, 0xd8, 0x43, 0xa2, 0x26, 0x18, 0xc3, 0x99, 0x04, 0xf5, 0x9a, 0x1a, 0xbf, 0x63, 0x80, 0x89,
+	0xb7, 0x94, 0x5c, 0xfc, 0xd6, 0x7d, 0xe0, 0x33, 0xa8, 0xf8, 0x9c, 0x4c, 0x18, 0x14, 0xe9, 0xb8,
+	0xc5, 0xdf, 0x1a, 0x60, 0xb6, 0x67, 0x03, 0x00, 0x2f, 0x82, 0x51, 0xcb, 0x75, 0xfd, 0x7d, 0x31,
+	0x4a, 0xd4, 0xde, 0x11, 0xac, 0x70, 0x2a, 0x92, 0x5c, 0x2d, 0x7a, 0x99, 0xcf, 0x2a, 0x7a, 0xc5,
+	0x3f, 0x18, 0xe0, 0xdc, 0x9d, 0x32, 0xf1, 0xbe, 0x2c, 0xe9, 0x12, 0xc8, 0xcb, 0xe6, 0xfd, 0x90,
+	0x2f, 0xa7, 0x2c, 0xc5, 0xb2, 0x68, 0xf0, 0x0f, 0xcd, 0xc4, 0xaf, 0xe2, 0x07, 0x06, 0x98, 0xae,
+	0x60, 0xd2, 0x74, 0xaa, 0x18, 0xe1, 0x1a, 0x26, 0xd8, 0xab, 0x62, 0xb8, 0x0c, 0xc6, 0xf9, 0xeb,
+	0xee, 0xc0, 0xaa, 0xc6, 0xaf, 0x6e, 0x66, 0x64, 0xc8, 0xc7, 0xaf, 0xc5, 0x0c, 0x94, 0xc8, 0xa8,
+	0xd7, 0x3c, 0x99, 0xbe, 0xaf, 0x79, 0xce, 0x81, 0x91, 0x20, 0x19, 0x44, 0xe7, 0x19, 0x97, 0xcf,
+	0x9e, 0x39, 0x95, 0x73, 0x7d, 0x12, 0xf2, 0xe9, 0x5a, 0x4e, 0x72, 0x7d, 0x12, 0x22, 0x4e, 0x2d,
+	0xfe, 0x29, 0x03, 0x4e, 0x75, 0xd6, 0x71, 0x06, 0x48, 0x22, 0xb7, 0xeb, 0xbd, 0x12, 0xe3, 0x21,
+	0xce, 0xd1, 0x3f, 0x77, 0xc9, 0xdc, 0xf9, 0x73, 0x17, 0xf8, 0x02, 0x98, 0x91, 0x3f, 0xd7, 0x0f,
+	0x02, 0x82, 0x29, 0x7f, 0x77, 0x9a, 0xed, 0xfc, 0x68, 0x76, 0x33, 0x2d, 0x80, 0xba, 0x75, 0xe0,
+	0xff, 0xa7, 0x3e, 0xc5, 0xb9, 0x90, 0x7c, 0x86, 0xc3, 0x5a, 0x42, 0xde, 0x67, 0xdc, 0x64, 0x65,
+	0x60, 0x9d, 0x10, 0x9f, 0xa4, 0xbe, 0xcf, 0x59, 0x06, 0xe3, 0x35, 0x26, 0xc0, 0xe7, 0xf5, 0xb9,
+	0xce, 0xa0, 0x5f, 0x89, 0x19, 0x28, 0x91, 0x81, 0xcf, 0x83, 0x29, 0x3f, 0x10, 0x1d, 0xf0, 0x96,
+	0x6b, 0x57, 0xb0, 0x5b, 0xe3, 0x93, 0xc4, 0x7c, 0x3c, 0xee, 0xed, 0x60, 0xa1, 0xb4, 0x6c, 0xf1,
+	0x8f, 0x06, 0xe8, 0xf5, 0xa1, 0x1d, 0x3c, 0x2b, 0xc6, 0xb6, 0xda, 0x2c, 0x34, 0x1e, 0xd9, 0xc2,
+	0x26, 0x18, 0xa3, 0x22, 0x57, 0x64, 0x2e, 0x6f, 0x1d, 0x33, 0x97, 0xd3, 0x99, 0x27, 0xfa, 0xc5,
+	0x98, 0x1a, 0x83, 0xb1, 0x74, 0xae, 0x5a, 0xe5, 0xc8, 0xb3, 0xe5, 0x24, 0x7f, 0x52, 0xa4, 0xf3,
+	0xea, 0x8a, 0xa0, 0x21, 0xc5, 0x2d, 0x57, 0x3f, 0xfc, 0x64, 0xe1, 0xc4, 0x47, 0x9f, 0x2c, 0x9c,
+	0xf8, 0xf8, 0x93, 0x85, 0x13, 0x5f, 0x6f, 0x2f, 0x18, 0x1f, 0xb6, 0x17, 0x8c, 0x8f, 0xda, 0x0b,
+	0xc6, 0xc7, 0xed, 0x05, 0xe3, 0x6f, 0xed, 0x05, 0xe3, 0x87, 0x7f, 0x5f, 0x38, 0xf1, 0xe5, 0xe7,
+	0x8f, 0xf5, 0x6d, 0xfb, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x16, 0x56, 0x59, 0x35, 0x34, 0x2f,
+	0x00, 0x00,
 }
 
 func (m *ConversionRequest) Marshal() (dAtA []byte, err error) {
@@ -2660,6 +2662,16 @@ func (m *ValidationRule) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 	_ = i
 	var l int
 	_ = l
+	if m.OptionalOldSelf != nil {
+		i--
+		if *m.OptionalOldSelf {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x30
+	}
 	i -= len(m.FieldPath)
 	copy(dAtA[i:], m.FieldPath)
 	i = encodeVarintGenerated(dAtA, i, uint64(len(m.FieldPath)))
@@ -3374,6 +3386,9 @@ func (m *ValidationRule) Size() (n int) {
 	}
 	l = len(m.FieldPath)
 	n += 1 + l + sovGenerated(uint64(l))
+	if m.OptionalOldSelf != nil {
+		n += 2
+	}
 	return n
 }
 
@@ -3843,6 +3858,7 @@ func (this *ValidationRule) String() string {
 		`MessageExpression:` + fmt.Sprintf("%v", this.MessageExpression) + `,`,
 		`Reason:` + valueToStringGenerated(this.Reason) + `,`,
 		`FieldPath:` + fmt.Sprintf("%v", this.FieldPath) + `,`,
+		`OptionalOldSelf:` + valueToStringGenerated(this.OptionalOldSelf) + `,`,
 		`}`,
 	}, "")
 	return s
@@ -9166,6 +9182,27 @@ func (m *ValidationRule) Unmarshal(dAtA []byte) error {
 			}
 			m.FieldPath = string(dAtA[iNdEx:postIndex])
 			iNdEx = postIndex
+		case 6:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field OptionalOldSelf", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenerated
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			b := bool(v != 0)
+			m.OptionalOldSelf = &b
 		default:
 			iNdEx = preIndex
 			skippy, err := skipGenerated(dAtA[iNdEx:])
diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.proto b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.proto
index 7cfb9c4d..b8477322 100644
--- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.proto
+++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.proto
@@ -710,6 +710,18 @@ message ValidationRule {
   //   - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values
   //     are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with
   //     non-intersecting keys are appended, retaining their partial order.
+  //
+  // If `rule` makes use of the `oldSelf` variable it is implicitly a
+  // `transition rule`.
+  //
+  // By default, the `oldSelf` variable is the same type as `self`.
+  // When `optionalOldSelf` is true, the `oldSelf` variable is a CEL optional
+  //  variable whose value() is the same type as `self`.
+  // See the documentation for the `optionalOldSelf` field for details.
+  //
+  // Transition rules by default are applied only on UPDATE requests and are
+  // skipped if an old value could not be found. You can opt a transition
+  // rule into unconditional evaluation by setting `optionalOldSelf` to true.
   optional string rule = 1;
 
   // Message represents the message displayed when validation fails. The message is required if the Rule contains
@@ -750,6 +762,24 @@ message ValidationRule {
   // e.g. for attribute `foo.34$` appears in a list `testList`, the fieldPath could be set to `.testList['foo.34$']`
   // +optional
   optional string fieldPath = 5;
+
+  // optionalOldSelf is used to opt a transition rule into evaluation
+  // even when the object is first created, or if the old object is
+  // missing the value.
+  //
+  // When enabled `oldSelf` will be a CEL optional whose value will be
+  // `None` if there is no old value, or when the object is initially created.
+  //
+  // You may check for presence of oldSelf using `oldSelf.hasValue()` and
+  // unwrap it after checking using `oldSelf.value()`. Check the CEL
+  // documentation for Optional types for more information:
+  // https://pkg.go.dev/github.com/google/cel-go/cel#OptionalTypes
+  //
+  // May not be set unless `oldSelf` is used in `rule`.
+  //
+  // +featureGate=CRDValidationRatcheting
+  // +optional
+  optional bool optionalOldSelf = 6;
 }
 
 // WebhookClientConfig contains the information to make a TLS connection with the webhook.
diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types_jsonschema.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types_jsonschema.go
index 59a09322..24c45bb0 100644
--- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types_jsonschema.go
+++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types_jsonschema.go
@@ -249,6 +249,19 @@ type ValidationRule struct {
 	//   - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values
 	//     are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with
 	//     non-intersecting keys are appended, retaining their partial order.
+	//
+	// If `rule` makes use of the `oldSelf` variable it is implicitly a
+	// `transition rule`.
+	//
+	// By default, the `oldSelf` variable is the same type as `self`.
+	// When `optionalOldSelf` is true, the `oldSelf` variable is a CEL optional
+	//  variable whose value() is the same type as `self`.
+	// See the documentation for the `optionalOldSelf` field for details.
+	//
+	// Transition rules by default are applied only on UPDATE requests and are
+	// skipped if an old value could not be found. You can opt a transition
+	// rule into unconditional evaluation by setting `optionalOldSelf` to true.
+	//
 	Rule string `json:"rule" protobuf:"bytes,1,opt,name=rule"`
 	// Message represents the message displayed when validation fails. The message is required if the Rule contains
 	// line breaks. The message must not contain line breaks.
@@ -285,6 +298,24 @@ type ValidationRule struct {
 	// e.g. for attribute `foo.34$` appears in a list `testList`, the fieldPath could be set to `.testList['foo.34$']`
 	// +optional
 	FieldPath string `json:"fieldPath,omitempty" protobuf:"bytes,5,opt,name=fieldPath"`
+
+	// optionalOldSelf is used to opt a transition rule into evaluation
+	// even when the object is first created, or if the old object is
+	// missing the value.
+	//
+	// When enabled `oldSelf` will be a CEL optional whose value will be
+	// `None` if there is no old value, or when the object is initially created.
+	//
+	// You may check for presence of oldSelf using `oldSelf.hasValue()` and
+	// unwrap it after checking using `oldSelf.value()`. Check the CEL
+	// documentation for Optional types for more information:
+	// https://pkg.go.dev/github.com/google/cel-go/cel#OptionalTypes
+	//
+	// May not be set unless `oldSelf` is used in `rule`.
+	//
+	// +featureGate=CRDValidationRatcheting
+	// +optional
+	OptionalOldSelf *bool `json:"optionalOldSelf,omitempty" protobuf:"bytes,6,opt,name=optionalOldSelf"`
 }
 
 // JSON represents any valid JSON value.
diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.conversion.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.conversion.go
index 65c023f0..fa6e0ef2 100644
--- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.conversion.go
+++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.conversion.go
@@ -1309,6 +1309,7 @@ func autoConvert_v1beta1_ValidationRule_To_apiextensions_ValidationRule(in *Vali
 	out.MessageExpression = in.MessageExpression
 	out.Reason = (*apiextensions.FieldValueErrorReason)(unsafe.Pointer(in.Reason))
 	out.FieldPath = in.FieldPath
+	out.OptionalOldSelf = (*bool)(unsafe.Pointer(in.OptionalOldSelf))
 	return nil
 }
 
@@ -1323,6 +1324,7 @@ func autoConvert_apiextensions_ValidationRule_To_v1beta1_ValidationRule(in *apie
 	out.MessageExpression = in.MessageExpression
 	out.Reason = (*FieldValueErrorReason)(unsafe.Pointer(in.Reason))
 	out.FieldPath = in.FieldPath
+	out.OptionalOldSelf = (*bool)(unsafe.Pointer(in.OptionalOldSelf))
 	return nil
 }
 
diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.deepcopy.go
index 9eeef6ca..bb8ab06c 100644
--- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.deepcopy.go
+++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.deepcopy.go
@@ -644,6 +644,11 @@ func (in *ValidationRule) DeepCopyInto(out *ValidationRule) {
 		*out = new(FieldValueErrorReason)
 		**out = **in
 	}
+	if in.OptionalOldSelf != nil {
+		in, out := &in.OptionalOldSelf, &out.OptionalOldSelf
+		*out = new(bool)
+		**out = **in
+	}
 	return
 }
 
diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/zz_generated.deepcopy.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/zz_generated.deepcopy.go
index f8a5ffbf..b5e5c35c 100644
--- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/zz_generated.deepcopy.go
+++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/zz_generated.deepcopy.go
@@ -536,6 +536,11 @@ func (in *ValidationRule) DeepCopyInto(out *ValidationRule) {
 		*out = new(FieldValueErrorReason)
 		**out = **in
 	}
+	if in.OptionalOldSelf != nil {
+		in, out := &in.OptionalOldSelf, &out.OptionalOldSelf
+		*out = new(bool)
+		**out = **in
+	}
 	return
 }
 
diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/applyconfiguration/apiextensions/v1/validationrule.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/applyconfiguration/apiextensions/v1/validationrule.go
index 1d38873d..c0eb0b51 100644
--- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/applyconfiguration/apiextensions/v1/validationrule.go
+++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/applyconfiguration/apiextensions/v1/validationrule.go
@@ -30,6 +30,7 @@ type ValidationRuleApplyConfiguration struct {
 	MessageExpression *string                   `json:"messageExpression,omitempty"`
 	Reason            *v1.FieldValueErrorReason `json:"reason,omitempty"`
 	FieldPath         *string                   `json:"fieldPath,omitempty"`
+	OptionalOldSelf   *bool                     `json:"optionalOldSelf,omitempty"`
 }
 
 // ValidationRuleApplyConfiguration constructs an declarative configuration of the ValidationRule type for use with
@@ -77,3 +78,11 @@ func (b *ValidationRuleApplyConfiguration) WithFieldPath(value string) *Validati
 	b.FieldPath = &value
 	return b
 }
+
+// WithOptionalOldSelf sets the OptionalOldSelf field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the OptionalOldSelf field is set to the value of the last call.
+func (b *ValidationRuleApplyConfiguration) WithOptionalOldSelf(value bool) *ValidationRuleApplyConfiguration {
+	b.OptionalOldSelf = &value
+	return b
+}
diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/applyconfiguration/apiextensions/v1beta1/validationrule.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/applyconfiguration/apiextensions/v1beta1/validationrule.go
index e52c2030..1b0df078 100644
--- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/applyconfiguration/apiextensions/v1beta1/validationrule.go
+++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/applyconfiguration/apiextensions/v1beta1/validationrule.go
@@ -30,6 +30,7 @@ type ValidationRuleApplyConfiguration struct {
 	MessageExpression *string                        `json:"messageExpression,omitempty"`
 	Reason            *v1beta1.FieldValueErrorReason `json:"reason,omitempty"`
 	FieldPath         *string                        `json:"fieldPath,omitempty"`
+	OptionalOldSelf   *bool                          `json:"optionalOldSelf,omitempty"`
 }
 
 // ValidationRuleApplyConfiguration constructs an declarative configuration of the ValidationRule type for use with
@@ -77,3 +78,11 @@ func (b *ValidationRuleApplyConfiguration) WithFieldPath(value string) *Validati
 	b.FieldPath = &value
 	return b
 }
+
+// WithOptionalOldSelf sets the OptionalOldSelf field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the OptionalOldSelf field is set to the value of the last call.
+func (b *ValidationRuleApplyConfiguration) WithOptionalOldSelf(value bool) *ValidationRuleApplyConfiguration {
+	b.OptionalOldSelf = &value
+	return b
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index f0bf9b21..a8bb4d3f 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -14,9 +14,10 @@ github.com/davecgh/go-spew/spew
 ## explicit; go 1.13
 github.com/emicklei/go-restful/v3
 github.com/emicklei/go-restful/v3/log
-# github.com/evanphx/json-patch/v5 v5.7.0
+# github.com/evanphx/json-patch/v5 v5.8.0
 ## explicit; go 1.18
 github.com/evanphx/json-patch/v5
+github.com/evanphx/json-patch/v5/internal/json
 # github.com/fsnotify/fsnotify v1.7.0
 ## explicit; go 1.17
 github.com/fsnotify/fsnotify
@@ -44,9 +45,8 @@ github.com/gogo/protobuf/sortkeys
 # github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da
 ## explicit
 github.com/golang/groupcache/lru
-# github.com/golang/protobuf v1.5.3
-## explicit; go 1.9
-github.com/golang/protobuf/jsonpb
+# github.com/golang/protobuf v1.5.4
+## explicit; go 1.17
 github.com/golang/protobuf/proto
 github.com/golang/protobuf/ptypes
 github.com/golang/protobuf/ptypes/any
@@ -131,8 +131,8 @@ github.com/onsi/ginkgo/reporters/stenographer
 github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable
 github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty
 github.com/onsi/ginkgo/types
-# github.com/onsi/gomega v1.30.0
-## explicit; go 1.18
+# github.com/onsi/gomega v1.32.0
+## explicit; go 1.20
 github.com/onsi/gomega
 github.com/onsi/gomega/format
 github.com/onsi/gomega/internal
@@ -143,13 +143,13 @@ github.com/onsi/gomega/matchers/support/goraph/edge
 github.com/onsi/gomega/matchers/support/goraph/node
 github.com/onsi/gomega/matchers/support/goraph/util
 github.com/onsi/gomega/types
-# github.com/openshift/api v0.0.0-20240301093301-ce10821dc999
+# github.com/openshift/api v0.0.0-20240323003854-2252c7adfb79
 ## explicit; go 1.21
 github.com/openshift/api/config/v1
 github.com/openshift/api/console/v1alpha1
 github.com/openshift/api/security/v1
-# github.com/operator-framework/api v0.20.0
-## explicit; go 1.19
+# github.com/operator-framework/api v0.22.0
+## explicit; go 1.21
 github.com/operator-framework/api/pkg/lib/version
 github.com/operator-framework/api/pkg/operators
 github.com/operator-framework/api/pkg/operators/v1alpha1
@@ -159,11 +159,11 @@ github.com/pkg/errors
 # github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
 ## explicit
 github.com/pmezard/go-difflib/difflib
-# github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.70.0
-## explicit; go 1.17
+# github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.72.0
+## explicit; go 1.21
 github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring
 github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1
-# github.com/prometheus/client_golang v1.17.0
+# github.com/prometheus/client_golang v1.18.0
 ## explicit; go 1.19
 github.com/prometheus/client_golang/prometheus
 github.com/prometheus/client_golang/prometheus/collectors
@@ -182,7 +182,7 @@ github.com/prometheus/common/model
 github.com/prometheus/procfs
 github.com/prometheus/procfs/internal/fs
 github.com/prometheus/procfs/internal/util
-# github.com/red-hat-storage/ocs-operator/v4 v4.0.0-20240325171742-7a2177d09b00
+# github.com/red-hat-storage/ocs-operator/v4 v4.0.0-20240422111920-faced96485bc
 ## explicit; go 1.21
 github.com/red-hat-storage/ocs-operator/v4/services/provider/client
 github.com/red-hat-storage/ocs-operator/v4/services/provider/interfaces
@@ -273,10 +273,10 @@ google.golang.org/appengine/internal/log
 google.golang.org/appengine/internal/remote_api
 google.golang.org/appengine/internal/urlfetch
 google.golang.org/appengine/urlfetch
-# google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97
+# google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80
 ## explicit; go 1.19
 google.golang.org/genproto/googleapis/rpc/status
-# google.golang.org/grpc v1.60.0
+# google.golang.org/grpc v1.62.1
 ## explicit; go 1.19
 google.golang.org/grpc
 google.golang.org/grpc/attributes
@@ -355,6 +355,7 @@ google.golang.org/protobuf/internal/set
 google.golang.org/protobuf/internal/strs
 google.golang.org/protobuf/internal/version
 google.golang.org/protobuf/proto
+google.golang.org/protobuf/protoadapt
 google.golang.org/protobuf/reflect/protodesc
 google.golang.org/protobuf/reflect/protoreflect
 google.golang.org/protobuf/reflect/protoregistry
@@ -377,7 +378,7 @@ gopkg.in/yaml.v2
 # gopkg.in/yaml.v3 v3.0.1
 ## explicit
 gopkg.in/yaml.v3
-# k8s.io/api v0.29.2
+# k8s.io/api v0.29.3
 ## explicit; go 1.21
 k8s.io/api/admission/v1
 k8s.io/api/admission/v1beta1
@@ -433,8 +434,8 @@ k8s.io/api/scheduling/v1beta1
 k8s.io/api/storage/v1
 k8s.io/api/storage/v1alpha1
 k8s.io/api/storage/v1beta1
-# k8s.io/apiextensions-apiserver v0.28.4
-## explicit; go 1.20
+# k8s.io/apiextensions-apiserver v0.29.2
+## explicit; go 1.21
 k8s.io/apiextensions-apiserver/pkg/apis/apiextensions
 k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1
 k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1
@@ -444,7 +445,7 @@ k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset
 k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme
 k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1
 k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1
-# k8s.io/apimachinery v0.29.2
+# k8s.io/apimachinery v0.29.3
 ## explicit; go 1.21
 k8s.io/apimachinery/pkg/api/equality
 k8s.io/apimachinery/pkg/api/errors
@@ -496,7 +497,7 @@ k8s.io/apimachinery/pkg/version
 k8s.io/apimachinery/pkg/watch
 k8s.io/apimachinery/third_party/forked/golang/json
 k8s.io/apimachinery/third_party/forked/golang/reflect
-# k8s.io/client-go v0.29.2
+# k8s.io/client-go v0.29.3
 ## explicit; go 1.21
 k8s.io/client-go/applyconfigurations/admissionregistration/v1
 k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1
@@ -639,8 +640,8 @@ k8s.io/client-go/util/homedir
 k8s.io/client-go/util/keyutil
 k8s.io/client-go/util/retry
 k8s.io/client-go/util/workqueue
-# k8s.io/component-base v0.28.4
-## explicit; go 1.20
+# k8s.io/component-base v0.29.2
+## explicit; go 1.21
 k8s.io/component-base/config
 k8s.io/component-base/config/v1alpha1
 # k8s.io/klog/v2 v2.120.1
@@ -663,7 +664,7 @@ k8s.io/kube-openapi/pkg/schemaconv
 k8s.io/kube-openapi/pkg/spec3
 k8s.io/kube-openapi/pkg/util/proto
 k8s.io/kube-openapi/pkg/validation/spec
-# k8s.io/utils v0.0.0-20240102154912-e7106e64919e
+# k8s.io/utils v0.0.0-20240310230437-4693a0247e57
 ## explicit; go 1.18
 k8s.io/utils/buffer
 k8s.io/utils/clock
@@ -675,8 +676,8 @@ k8s.io/utils/pointer
 k8s.io/utils/ptr
 k8s.io/utils/strings/slices
 k8s.io/utils/trace
-# sigs.k8s.io/controller-runtime v0.16.3
-## explicit; go 1.20
+# sigs.k8s.io/controller-runtime v0.17.2
+## explicit; go 1.21
 sigs.k8s.io/controller-runtime
 sigs.k8s.io/controller-runtime/pkg/builder
 sigs.k8s.io/controller-runtime/pkg/cache
@@ -704,6 +705,7 @@ sigs.k8s.io/controller-runtime/pkg/internal/httpserver
 sigs.k8s.io/controller-runtime/pkg/internal/log
 sigs.k8s.io/controller-runtime/pkg/internal/recorder
 sigs.k8s.io/controller-runtime/pkg/internal/source
+sigs.k8s.io/controller-runtime/pkg/internal/syncs
 sigs.k8s.io/controller-runtime/pkg/internal/testing/addr
 sigs.k8s.io/controller-runtime/pkg/internal/testing/certs
 sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane
diff --git a/vendor/sigs.k8s.io/controller-runtime/.golangci.yml b/vendor/sigs.k8s.io/controller-runtime/.golangci.yml
index deb6a783..a95c15b2 100644
--- a/vendor/sigs.k8s.io/controller-runtime/.golangci.yml
+++ b/vendor/sigs.k8s.io/controller-runtime/.golangci.yml
@@ -59,9 +59,9 @@ linters-settings:
       - pkg: sigs.k8s.io/controller-runtime
         alias: ctrl
   staticcheck:
-    go: "1.20"
+    go: "1.21"
   stylecheck:
-    go: "1.20"
+    go: "1.21"
   revive:
     rules:
       # The following rules are recommended https://github.com/mgechev/revive#recommended-configuration
diff --git a/vendor/sigs.k8s.io/controller-runtime/RELEASE.md b/vendor/sigs.k8s.io/controller-runtime/RELEASE.md
index f234494f..2a857b97 100644
--- a/vendor/sigs.k8s.io/controller-runtime/RELEASE.md
+++ b/vendor/sigs.k8s.io/controller-runtime/RELEASE.md
@@ -4,9 +4,9 @@ The Kubernetes controller-runtime Project is released on an as-needed basis. The
 
 **Note:** Releases are done from the `release-MAJOR.MINOR` branches. For PATCH releases is not required
 to create a new branch you will just need to ensure that all big fixes are cherry-picked into the respective
-`release-MAJOR.MINOR` branch. To know more about versioning check https://semver.org/. 
+`release-MAJOR.MINOR` branch. To know more about versioning check https://semver.org/.
 
-## How to do a release 
+## How to do a release
 
 ### Create the new branch and the release tag
 
@@ -15,7 +15,7 @@ to create a new branch you will just need to ensure that all big fixes are cherr
 
 ### Now, let's generate the changelog
 
-1. Create the changelog from the new branch `release-<MAJOR.MINOR>` (`git checkout release-<MAJOR.MINOR>`). 
+1. Create the changelog from the new branch `release-<MAJOR.MINOR>` (`git checkout release-<MAJOR.MINOR>`).
 You will need to use the [kubebuilder-release-tools][kubebuilder-release-tools] to generate the notes. See [here][release-notes-generation]
 
 > **Note**
@@ -24,12 +24,12 @@ You will need to use the [kubebuilder-release-tools][kubebuilder-release-tools]
 
 ### Draft a new release from GitHub
 
-1. Create a new tag with the correct version from the new `release-<MAJOR.MINOR>` branch 
+1. Create a new tag with the correct version from the new `release-<MAJOR.MINOR>` branch
 2. Add the changelog on it and publish. Now, the code source is released !
 
 ### Add a new Prow test the for the new branch release
 
-1. Create a new prow test under [github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/controller-runtime](https://github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/controller-runtime) 
+1. Create a new prow test under [github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/controller-runtime](https://github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/controller-runtime)
 for the new `release-<MAJOR.MINOR>` branch. (i.e. for the `0.11.0` release see the PR: https://github.com/kubernetes/test-infra/pull/25205)
 2. Ping the infra PR in the controller-runtime slack channel for reviews.
 
@@ -45,3 +45,7 @@ For more info, see the release page: https://github.com/kubernetes-sigs/controll
 ````
 
 2. An announcement email is sent to `kubebuilder@googlegroups.com` with the subject `[ANNOUNCE] Controller-Runtime $VERSION is released`
+
+[kubebuilder-release-tools]: https://github.com/kubernetes-sigs/kubebuilder-release-tools
+[release-notes-generation]: https://github.com/kubernetes-sigs/kubebuilder-release-tools/blob/master/README.md#release-notes-generation
+[release-process]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/VERSIONING.md#releasing
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go
index 5410e1cd..1cecf88e 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go
@@ -33,7 +33,7 @@ import (
 	"k8s.io/client-go/kubernetes/scheme"
 	"k8s.io/client-go/rest"
 	toolscache "k8s.io/client-go/tools/cache"
-	"k8s.io/utils/pointer"
+	"k8s.io/utils/ptr"
 
 	"sigs.k8s.io/controller-runtime/pkg/cache/internal"
 	"sigs.k8s.io/controller-runtime/pkg/client"
@@ -83,6 +83,9 @@ type Informers interface {
 	// of the underlying object.
 	GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind, opts ...InformerGetOption) (Informer, error)
 
+	// RemoveInformer removes an informer entry and stops it if it was running.
+	RemoveInformer(ctx context.Context, obj client.Object) error
+
 	// Start runs all the informers known to this cache until the context is closed.
 	// It blocks.
 	Start(ctx context.Context) error
@@ -121,6 +124,8 @@ type Informer interface {
 
 	// HasSynced return true if the informers underlying store has synced.
 	HasSynced() bool
+	// IsStopped returns true if the informer has been stopped.
+	IsStopped() bool
 }
 
 // AllNamespaces should be used as the map key to deliminate namespace settings
@@ -199,6 +204,12 @@ type Options struct {
 	// unless there is already one set in ByObject or DefaultNamespaces.
 	DefaultTransform toolscache.TransformFunc
 
+	// DefaultWatchErrorHandler will be used to the WatchErrorHandler which is called
+	// whenever ListAndWatch drops the connection with an error.
+	//
+	// After calling this handler, the informer will backoff and retry.
+	DefaultWatchErrorHandler toolscache.WatchErrorHandler
+
 	// DefaultUnsafeDisableDeepCopy is the default for UnsafeDisableDeepCopy
 	// for everything that doesn't specify this.
 	//
@@ -369,7 +380,8 @@ func newCache(restConfig *rest.Config, opts Options) newCacheFunc {
 					Field: config.FieldSelector,
 				},
 				Transform:             config.Transform,
-				UnsafeDisableDeepCopy: pointer.BoolDeref(config.UnsafeDisableDeepCopy, false),
+				WatchErrorHandler:     opts.DefaultWatchErrorHandler,
+				UnsafeDisableDeepCopy: ptr.Deref(config.UnsafeDisableDeepCopy, false),
 				NewInformer:           opts.newInformer,
 			}),
 			readerFailOnMissingInformer: opts.ReaderFailOnMissingInformer,
@@ -400,7 +412,7 @@ func defaultOpts(config *rest.Config, opts Options) (Options, error) {
 	// Construct a new Mapper if unset
 	if opts.Mapper == nil {
 		var err error
-		opts.Mapper, err = apiutil.NewDiscoveryRESTMapper(config, opts.HTTPClient)
+		opts.Mapper, err = apiutil.NewDynamicRESTMapper(config, opts.HTTPClient)
 		if err != nil {
 			return Options{}, fmt.Errorf("could not create RESTMapper from config: %w", err)
 		}
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/delegating_by_gvk_cache.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/delegating_by_gvk_cache.go
index f3fa4800..4db8208a 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/delegating_by_gvk_cache.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/delegating_by_gvk_cache.go
@@ -52,6 +52,14 @@ func (dbt *delegatingByGVKCache) List(ctx context.Context, list client.ObjectLis
 	return cache.List(ctx, list, opts...)
 }
 
+func (dbt *delegatingByGVKCache) RemoveInformer(ctx context.Context, obj client.Object) error {
+	cache, err := dbt.cacheForObject(obj)
+	if err != nil {
+		return err
+	}
+	return cache.RemoveInformer(ctx, obj)
+}
+
 func (dbt *delegatingByGVKCache) GetInformer(ctx context.Context, obj client.Object, opts ...InformerGetOption) (Informer, error) {
 	cache, err := dbt.cacheForObject(obj)
 	if err != nil {
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache.go
index 0f1b4e93..091667b7 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache.go
@@ -190,6 +190,17 @@ func (ic *informerCache) getInformerForKind(ctx context.Context, gvk schema.Grou
 	return ic.Informers.Get(ctx, gvk, obj, &internal.GetOptions{})
 }
 
+// RemoveInformer deactivates and removes the informer from the cache.
+func (ic *informerCache) RemoveInformer(_ context.Context, obj client.Object) error {
+	gvk, err := apiutil.GVKForObject(obj, ic.scheme)
+	if err != nil {
+		return err
+	}
+
+	ic.Informers.Remove(gvk, obj)
+	return nil
+}
+
 // NeedLeaderElection implements the LeaderElectionRunnable interface
 // to indicate that this can be started without requiring the leader lock.
 func (ic *informerCache) NeedLeaderElection() bool {
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/cache_reader.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/cache_reader.go
index eb941f03..2e4f5ce5 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/cache_reader.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/cache_reader.go
@@ -23,6 +23,7 @@ import (
 
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	apimeta "k8s.io/apimachinery/pkg/api/meta"
+	"k8s.io/apimachinery/pkg/fields"
 	"k8s.io/apimachinery/pkg/labels"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
@@ -117,16 +118,14 @@ func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...cli
 
 	switch {
 	case listOpts.FieldSelector != nil:
-		// TODO(directxman12): support more complicated field selectors by
-		// combining multiple indices, GetIndexers, etc
-		field, val, requiresExact := selector.RequiresExactMatch(listOpts.FieldSelector)
+		requiresExact := selector.RequiresExactMatch(listOpts.FieldSelector)
 		if !requiresExact {
 			return fmt.Errorf("non-exact field matches are not supported by the cache")
 		}
 		// list all objects by the field selector. If this is namespaced and we have one, ask for the
 		// namespaced index key. Otherwise, ask for the non-namespaced variant by using the fake "all namespaces"
 		// namespace.
-		objs, err = c.indexer.ByIndex(FieldIndexName(field), KeyToNamespacedKey(listOpts.Namespace, val))
+		objs, err = byIndexes(c.indexer, listOpts.FieldSelector.Requirements(), listOpts.Namespace)
 	case listOpts.Namespace != "":
 		objs, err = c.indexer.ByIndex(cache.NamespaceIndex, listOpts.Namespace)
 	default:
@@ -178,6 +177,54 @@ func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...cli
 	return apimeta.SetList(out, runtimeObjs)
 }
 
+func byIndexes(indexer cache.Indexer, requires fields.Requirements, namespace string) ([]interface{}, error) {
+	var (
+		err  error
+		objs []interface{}
+		vals []string
+	)
+	indexers := indexer.GetIndexers()
+	for idx, req := range requires {
+		indexName := FieldIndexName(req.Field)
+		indexedValue := KeyToNamespacedKey(namespace, req.Value)
+		if idx == 0 {
+			// we use first require to get snapshot data
+			// TODO(halfcrazy): use complicated index when client-go provides byIndexes
+			// https://github.com/kubernetes/kubernetes/issues/109329
+			objs, err = indexer.ByIndex(indexName, indexedValue)
+			if err != nil {
+				return nil, err
+			}
+			if len(objs) == 0 {
+				return nil, nil
+			}
+			continue
+		}
+		fn, exist := indexers[indexName]
+		if !exist {
+			return nil, fmt.Errorf("index with name %s does not exist", indexName)
+		}
+		filteredObjects := make([]interface{}, 0, len(objs))
+		for _, obj := range objs {
+			vals, err = fn(obj)
+			if err != nil {
+				return nil, err
+			}
+			for _, val := range vals {
+				if val == indexedValue {
+					filteredObjects = append(filteredObjects, obj)
+					break
+				}
+			}
+		}
+		if len(filteredObjects) == 0 {
+			return nil, nil
+		}
+		objs = filteredObjects
+	}
+	return objs, nil
+}
+
 // objectKeyToStorageKey converts an object key to store key.
 // It's akin to MetaNamespaceKeyFunc. It's separate from
 // String to allow keeping the key format easily in sync with
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers.go
index 1d2c9ce2..c270e809 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers.go
@@ -36,6 +36,7 @@ import (
 	"k8s.io/client-go/rest"
 	"k8s.io/client-go/tools/cache"
 	"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
+	"sigs.k8s.io/controller-runtime/pkg/internal/syncs"
 )
 
 // InformersOpts configures an InformerMap.
@@ -49,6 +50,7 @@ type InformersOpts struct {
 	Selector              Selector
 	Transform             cache.TransformFunc
 	UnsafeDisableDeepCopy bool
+	WatchErrorHandler     cache.WatchErrorHandler
 }
 
 // NewInformers creates a new InformersMap that can create informers under the hood.
@@ -76,6 +78,7 @@ func NewInformers(config *rest.Config, options *InformersOpts) *Informers {
 		transform:             options.Transform,
 		unsafeDisableDeepCopy: options.UnsafeDisableDeepCopy,
 		newInformer:           newInformer,
+		watchErrorHandler:     options.WatchErrorHandler,
 	}
 }
 
@@ -86,6 +89,20 @@ type Cache struct {
 
 	// CacheReader wraps Informer and implements the CacheReader interface for a single type
 	Reader CacheReader
+
+	// Stop can be used to stop this individual informer.
+	stop chan struct{}
+}
+
+// Start starts the informer managed by a MapEntry.
+// Blocks until the informer stops. The informer can be stopped
+// either individually (via the entry's stop channel) or globally
+// via the provided stop argument.
+func (c *Cache) Start(stop <-chan struct{}) {
+	// Stop on either the whole map stopping or just this informer being removed.
+	internalStop, cancel := syncs.MergeChans(stop, c.stop)
+	defer cancel()
+	c.Informer.Run(internalStop)
 }
 
 type tracker struct {
@@ -159,6 +176,11 @@ type Informers struct {
 
 	// NewInformer allows overriding of the shared index informer constructor for testing.
 	newInformer func(cache.ListerWatcher, runtime.Object, time.Duration, cache.Indexers) cache.SharedIndexInformer
+
+	// WatchErrorHandler allows the shared index informer's
+	// watchErrorHandler to be set by overriding the options
+	// or to use the default watchErrorHandler
+	watchErrorHandler cache.WatchErrorHandler
 }
 
 // Start calls Run on each of the informers and sets started to true. Blocks on the context.
@@ -173,13 +195,13 @@ func (ip *Informers) Start(ctx context.Context) error {
 
 		// Start each informer
 		for _, i := range ip.tracker.Structured {
-			ip.startInformerLocked(i.Informer)
+			ip.startInformerLocked(i)
 		}
 		for _, i := range ip.tracker.Unstructured {
-			ip.startInformerLocked(i.Informer)
+			ip.startInformerLocked(i)
 		}
 		for _, i := range ip.tracker.Metadata {
-			ip.startInformerLocked(i.Informer)
+			ip.startInformerLocked(i)
 		}
 
 		// Set started to true so we immediately start any informers added later.
@@ -194,7 +216,7 @@ func (ip *Informers) Start(ctx context.Context) error {
 	return nil
 }
 
-func (ip *Informers) startInformerLocked(informer cache.SharedIndexInformer) {
+func (ip *Informers) startInformerLocked(cacheEntry *Cache) {
 	// Don't start the informer in case we are already waiting for the items in
 	// the waitGroup to finish, since waitGroups don't support waiting and adding
 	// at the same time.
@@ -205,7 +227,7 @@ func (ip *Informers) startInformerLocked(informer cache.SharedIndexInformer) {
 	ip.waitGroup.Add(1)
 	go func() {
 		defer ip.waitGroup.Done()
-		informer.Run(ip.ctx.Done())
+		cacheEntry.Start(ip.ctx.Done())
 	}()
 }
 
@@ -281,6 +303,21 @@ func (ip *Informers) Get(ctx context.Context, gvk schema.GroupVersionKind, obj r
 	return started, i, nil
 }
 
+// Remove removes an informer entry and stops it if it was running.
+func (ip *Informers) Remove(gvk schema.GroupVersionKind, obj runtime.Object) {
+	ip.mu.Lock()
+	defer ip.mu.Unlock()
+
+	informerMap := ip.informersByType(obj)
+
+	entry, ok := informerMap[gvk]
+	if !ok {
+		return
+	}
+	close(entry.stop)
+	delete(informerMap, gvk)
+}
+
 func (ip *Informers) informersByType(obj runtime.Object) map[schema.GroupVersionKind]*Cache {
 	switch obj.(type) {
 	case runtime.Unstructured:
@@ -323,6 +360,13 @@ func (ip *Informers) addInformerToMap(gvk schema.GroupVersionKind, obj runtime.O
 		cache.NamespaceIndex: cache.MetaNamespaceIndexFunc,
 	})
 
+	// Set WatchErrorHandler on SharedIndexInformer if set
+	if ip.watchErrorHandler != nil {
+		if err := sharedIndexInformer.SetWatchErrorHandler(ip.watchErrorHandler); err != nil {
+			return nil, false, err
+		}
+	}
+
 	// Check to see if there is a transformer for this gvk
 	if err := sharedIndexInformer.SetTransform(ip.transform); err != nil {
 		return nil, false, err
@@ -342,13 +386,14 @@ func (ip *Informers) addInformerToMap(gvk schema.GroupVersionKind, obj runtime.O
 			scopeName:        mapping.Scope.Name(),
 			disableDeepCopy:  ip.unsafeDisableDeepCopy,
 		},
+		stop: make(chan struct{}),
 	}
 	ip.informersByType(obj)[gvk] = i
 
 	// Start the informer in case the InformersMap has started, otherwise it will be
 	// started when the InformersMap starts.
 	if ip.started {
-		ip.startInformerLocked(i.Informer)
+		ip.startInformerLocked(i)
 	}
 	return i, ip.started, nil
 }
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/multi_namespace_cache.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/multi_namespace_cache.go
index 87c31a7c..e38da145 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/multi_namespace_cache.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/multi_namespace_cache.go
@@ -109,6 +109,27 @@ func (c *multiNamespaceCache) GetInformer(ctx context.Context, obj client.Object
 	return &multiNamespaceInformer{namespaceToInformer: namespaceToInformer}, nil
 }
 
+func (c *multiNamespaceCache) RemoveInformer(ctx context.Context, obj client.Object) error {
+	// If the object is clusterscoped, get the informer from clusterCache,
+	// if not use the namespaced caches.
+	isNamespaced, err := apiutil.IsObjectNamespaced(obj, c.Scheme, c.RESTMapper)
+	if err != nil {
+		return err
+	}
+	if !isNamespaced {
+		return c.clusterCache.RemoveInformer(ctx, obj)
+	}
+
+	for _, cache := range c.namespaceToCache {
+		err := cache.RemoveInformer(ctx, obj)
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
 func (c *multiNamespaceCache) GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind, opts ...InformerGetOption) (Informer, error) {
 	// If the object is cluster scoped, get the informer from clusterCache,
 	// if not use the namespaced caches.
@@ -391,3 +412,13 @@ func (i *multiNamespaceInformer) HasSynced() bool {
 	}
 	return true
 }
+
+// IsStopped checks if each namespaced informer has stopped, returns false if any are still running.
+func (i *multiNamespaceInformer) IsStopped() bool {
+	for _, informer := range i.namespaceToInformer {
+		if stopped := informer.IsStopped(); !stopped {
+			return false
+		}
+	}
+	return true
+}
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/apimachinery.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/apimachinery.go
index 6a1bfb54..3c0206be 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/apimachinery.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/apimachinery.go
@@ -31,11 +31,9 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/runtime/serializer"
-	"k8s.io/client-go/discovery"
 	"k8s.io/client-go/dynamic"
 	clientgoscheme "k8s.io/client-go/kubernetes/scheme"
 	"k8s.io/client-go/rest"
-	"k8s.io/client-go/restmapper"
 )
 
 var (
@@ -60,25 +58,6 @@ func AddToProtobufScheme(addToScheme func(*runtime.Scheme) error) error {
 	return addToScheme(protobufScheme)
 }
 
-// NewDiscoveryRESTMapper constructs a new RESTMapper based on discovery
-// information fetched by a new client with the given config.
-func NewDiscoveryRESTMapper(c *rest.Config, httpClient *http.Client) (meta.RESTMapper, error) {
-	if httpClient == nil {
-		return nil, fmt.Errorf("httpClient must not be nil, consider using rest.HTTPClientFor(c) to create a client")
-	}
-
-	// Get a mapper
-	dc, err := discovery.NewDiscoveryClientForConfigAndClient(c, httpClient)
-	if err != nil {
-		return nil, err
-	}
-	gr, err := restmapper.GetAPIGroupResources(dc)
-	if err != nil {
-		return nil, err
-	}
-	return restmapper.NewDiscoveryRESTMapper(gr), nil
-}
-
 // IsObjectNamespaced returns true if the object is namespace scoped.
 // For unstructured objects the gvk is found from the object itself.
 func IsObjectNamespaced(obj runtime.Object, scheme *runtime.Scheme, restmapper meta.RESTMapper) (bool, error) {
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/restmapper.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/restmapper.go
index d5e03b2b..927be22b 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/restmapper.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/restmapper.go
@@ -21,6 +21,7 @@ import (
 	"net/http"
 	"sync"
 
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/api/meta"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime/schema"
@@ -52,7 +53,7 @@ func NewDynamicRESTMapper(cfg *rest.Config, httpClient *http.Client) (meta.RESTM
 // client for discovery information to do REST mappings.
 type mapper struct {
 	mapper      meta.RESTMapper
-	client      *discovery.DiscoveryClient
+	client      discovery.DiscoveryInterface
 	knownGroups map[string]*restmapper.APIGroupResources
 	apiGroups   map[string]*metav1.APIGroup
 
@@ -166,8 +167,10 @@ func (m *mapper) addKnownGroupAndReload(groupName string, versions ...string) er
 		if err != nil {
 			return err
 		}
-		for _, version := range apiGroup.Versions {
-			versions = append(versions, version.Version)
+		if apiGroup != nil {
+			for _, version := range apiGroup.Versions {
+				versions = append(versions, version.Version)
+			}
 		}
 	}
 
@@ -179,23 +182,28 @@ func (m *mapper) addKnownGroupAndReload(groupName string, versions ...string) er
 		Group:              metav1.APIGroup{Name: groupName},
 		VersionedResources: make(map[string][]metav1.APIResource),
 	}
-	if _, ok := m.knownGroups[groupName]; ok {
-		groupResources = m.knownGroups[groupName]
-	}
 
 	// Update information for group resources about versioned resources.
 	// The number of API calls is equal to the number of versions: /apis/<group>/<version>.
-	groupVersionResources, err := m.fetchGroupVersionResources(groupName, versions...)
+	// If we encounter a missing API version (NotFound error), we will remove the group from
+	// the m.apiGroups and m.knownGroups caches.
+	// If this happens, in the next call the group will be added back to apiGroups
+	// and only the existing versions will be loaded in knownGroups.
+	groupVersionResources, err := m.fetchGroupVersionResourcesLocked(groupName, versions...)
 	if err != nil {
 		return fmt.Errorf("failed to get API group resources: %w", err)
 	}
-	for version, resources := range groupVersionResources {
-		groupResources.VersionedResources[version.Version] = resources.APIResources
+
+	if _, ok := m.knownGroups[groupName]; ok {
+		groupResources = m.knownGroups[groupName]
 	}
 
 	// Update information for group resources about the API group by adding new versions.
 	// Ignore the versions that are already registered.
-	for _, version := range versions {
+	for groupVersion, resources := range groupVersionResources {
+		version := groupVersion.Version
+
+		groupResources.VersionedResources[version] = resources.APIResources
 		found := false
 		for _, v := range groupResources.Group.Versions {
 			if v.Version == version {
@@ -254,21 +262,17 @@ func (m *mapper) findAPIGroupByName(groupName string) (*metav1.APIGroup, error)
 	m.mu.Unlock()
 
 	// Looking in the cache again.
-	{
-		m.mu.RLock()
-		group, ok := m.apiGroups[groupName]
-		m.mu.RUnlock()
-		if ok {
-			return group, nil
-		}
-	}
+	m.mu.RLock()
+	defer m.mu.RUnlock()
 
-	// If there is still nothing, return an error.
-	return nil, fmt.Errorf("failed to find API group %q", groupName)
+	// Don't return an error here if the API group is not present.
+	// The reloaded RESTMapper will take care of returning a NoMatchError.
+	return m.apiGroups[groupName], nil
 }
 
-// fetchGroupVersionResources fetches the resources for the specified group and its versions.
-func (m *mapper) fetchGroupVersionResources(groupName string, versions ...string) (map[schema.GroupVersion]*metav1.APIResourceList, error) {
+// fetchGroupVersionResourcesLocked fetches the resources for the specified group and its versions.
+// This method might modify the cache so it needs to be called under the lock.
+func (m *mapper) fetchGroupVersionResourcesLocked(groupName string, versions ...string) (map[schema.GroupVersion]*metav1.APIResourceList, error) {
 	groupVersionResources := make(map[schema.GroupVersion]*metav1.APIResourceList)
 	failedGroups := make(map[schema.GroupVersion]error)
 
@@ -276,9 +280,20 @@ func (m *mapper) fetchGroupVersionResources(groupName string, versions ...string
 		groupVersion := schema.GroupVersion{Group: groupName, Version: version}
 
 		apiResourceList, err := m.client.ServerResourcesForGroupVersion(groupVersion.String())
-		if err != nil {
+		if apierrors.IsNotFound(err) {
+			// If the version is not found, we remove the group from the cache
+			// so it gets refreshed on the next call.
+			if m.isAPIGroupCached(groupVersion) {
+				delete(m.apiGroups, groupName)
+			}
+			if m.isGroupVersionCached(groupVersion) {
+				delete(m.knownGroups, groupName)
+			}
+			continue
+		} else if err != nil {
 			failedGroups[groupVersion] = err
 		}
+
 		if apiResourceList != nil {
 			// even in case of error, some fallback might have been returned.
 			groupVersionResources[groupVersion] = apiResourceList
@@ -292,3 +307,29 @@ func (m *mapper) fetchGroupVersionResources(groupName string, versions ...string
 
 	return groupVersionResources, nil
 }
+
+// isGroupVersionCached checks if a version for a group is cached in the known groups cache.
+func (m *mapper) isGroupVersionCached(gv schema.GroupVersion) bool {
+	if cachedGroup, ok := m.knownGroups[gv.Group]; ok {
+		_, cached := cachedGroup.VersionedResources[gv.Version]
+		return cached
+	}
+
+	return false
+}
+
+// isAPIGroupCached checks if a version for a group is cached in the api groups cache.
+func (m *mapper) isAPIGroupCached(gv schema.GroupVersion) bool {
+	cachedGroup, ok := m.apiGroups[gv.Group]
+	if !ok {
+		return false
+	}
+
+	for _, version := range cachedGroup.Versions {
+		if version.Version == gv.Version {
+			return true
+		}
+	}
+
+	return false
+}
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/client.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/client.go
index 2fb0acb7..c0ebb39e 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/client.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/client.go
@@ -90,11 +90,18 @@ type CacheOptions struct {
 type NewClientFunc func(config *rest.Config, options Options) (Client, error)
 
 // New returns a new Client using the provided config and Options.
-// The returned client reads *and* writes directly from the server
-// (it doesn't use object caches).  It understands how to work with
-// normal types (both custom resources and aggregated/built-in resources),
-// as well as unstructured types.
 //
+// The client's read behavior is determined by Options.Cache.
+// If either Options.Cache or Options.Cache.Reader is nil,
+// the client reads directly from the API server.
+// If both Options.Cache and Options.Cache.Reader are non-nil,
+// the client reads from a local cache. However, specific
+// resources can still be configured to bypass the cache based
+// on Options.Cache.Unstructured and Options.Cache.DisableFor.
+// Write operations are always performed directly on the API server.
+//
+// The client understands how to work with normal types (both custom resources
+// and aggregated/built-in resources), as well as unstructured types.
 // In the case of normal types, the scheme will be used to look up the
 // corresponding group, version, and kind for the given type.  In the
 // case of unstructured types, the group, version, and kind will be extracted
@@ -210,7 +217,8 @@ func newClient(config *rest.Config, options Options) (*client, error) {
 
 var _ Client = &client{}
 
-// client is a client.Client that reads and writes directly from/to an API server.
+// client is a client.Client configured to either read from a local cache or directly from the API server.
+// Write operations are always performed directly on the API server.
 // It lazily initializes new clients at the time they are used.
 type client struct {
 	typedClient        typedClient
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/options.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/options.go
index d81bf25d..798506f4 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/options.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/options.go
@@ -419,7 +419,7 @@ type ListOptions struct {
 	LabelSelector labels.Selector
 	// FieldSelector filters results by a particular field.  In order
 	// to use this with cache-based implementations, restrict usage to
-	// a single field-value pair that's been added to the indexers.
+	// exact match field-value pair that's been added to the indexers.
 	FieldSelector fields.Selector
 
 	// Namespace represents the namespace to list for, or empty for
@@ -514,7 +514,8 @@ type MatchingLabels map[string]string
 func (m MatchingLabels) ApplyToList(opts *ListOptions) {
 	// TODO(directxman12): can we avoid reserializing this over and over?
 	if opts.LabelSelector == nil {
-		opts.LabelSelector = labels.NewSelector()
+		opts.LabelSelector = labels.SelectorFromValidatedSet(map[string]string(m))
+		return
 	}
 	// If there's already a selector, we need to AND the two together.
 	noValidSel := labels.SelectorFromValidatedSet(map[string]string(m))
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil.go b/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil.go
index f76e012e..05153f74 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil.go
@@ -27,7 +27,7 @@ import (
 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
-	"k8s.io/utils/pointer"
+	"k8s.io/utils/ptr"
 
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
@@ -77,8 +77,8 @@ func SetControllerReference(owner, controlled metav1.Object, scheme *runtime.Sch
 		Kind:               gvk.Kind,
 		Name:               owner.GetName(),
 		UID:                owner.GetUID(),
-		BlockOwnerDeletion: pointer.Bool(true),
-		Controller:         pointer.Bool(true),
+		BlockOwnerDeletion: ptr.To(true),
+		Controller:         ptr.To(true),
 	}
 
 	// Return early with an error if the object is already controlled.
@@ -121,6 +121,84 @@ func SetOwnerReference(owner, object metav1.Object, scheme *runtime.Scheme) erro
 	return nil
 }
 
+// RemoveOwnerReference is a helper method to make sure the given object removes an owner reference to the object provided.
+// This allows you to remove the owner to establish a new owner of the object in a subsequent call.
+func RemoveOwnerReference(owner, object metav1.Object, scheme *runtime.Scheme) error {
+	owners := object.GetOwnerReferences()
+	length := len(owners)
+	if length < 1 {
+		return fmt.Errorf("%T does not have any owner references", object)
+	}
+	ro, ok := owner.(runtime.Object)
+	if !ok {
+		return fmt.Errorf("%T is not a runtime.Object, cannot call RemoveOwnerReference", owner)
+	}
+	gvk, err := apiutil.GVKForObject(ro, scheme)
+	if err != nil {
+		return err
+	}
+
+	index := indexOwnerRef(owners, metav1.OwnerReference{
+		APIVersion: gvk.GroupVersion().String(),
+		Name:       owner.GetName(),
+		Kind:       gvk.Kind,
+	})
+	if index == -1 {
+		return fmt.Errorf("%T does not have an owner reference for %T", object, owner)
+	}
+
+	owners = append(owners[:index], owners[index+1:]...)
+	object.SetOwnerReferences(owners)
+	return nil
+}
+
+// HasControllerReference returns true if the object
+// has an owner ref with controller equal to true
+func HasControllerReference(object metav1.Object) bool {
+	owners := object.GetOwnerReferences()
+	for _, owner := range owners {
+		isTrue := owner.Controller
+		if owner.Controller != nil && *isTrue {
+			return true
+		}
+	}
+	return false
+}
+
+// RemoveControllerReference removes an owner reference where the controller
+// equals true
+func RemoveControllerReference(owner, object metav1.Object, scheme *runtime.Scheme) error {
+	if ok := HasControllerReference(object); !ok {
+		return fmt.Errorf("%T does not have a owner reference with controller equals true", object)
+	}
+	ro, ok := owner.(runtime.Object)
+	if !ok {
+		return fmt.Errorf("%T is not a runtime.Object, cannot call RemoveControllerReference", owner)
+	}
+	gvk, err := apiutil.GVKForObject(ro, scheme)
+	if err != nil {
+		return err
+	}
+	ownerRefs := object.GetOwnerReferences()
+	index := indexOwnerRef(ownerRefs, metav1.OwnerReference{
+		APIVersion: gvk.GroupVersion().String(),
+		Name:       owner.GetName(),
+		Kind:       gvk.Kind,
+	})
+
+	if index == -1 {
+		return fmt.Errorf("%T does not have an controller reference for %T", object, owner)
+	}
+
+	if ownerRefs[index].Controller == nil || !*ownerRefs[index].Controller {
+		return fmt.Errorf("%T owner is not the controller reference for %T", owner, object)
+	}
+
+	ownerRefs = append(ownerRefs[:index], ownerRefs[index+1:]...)
+	object.SetOwnerReferences(ownerRefs)
+	return nil
+}
+
 func upsertOwnerRef(ref metav1.OwnerReference, object metav1.Object) {
 	owners := object.GetOwnerReferences()
 	if idx := indexOwnerRef(owners, ref); idx == -1 {
@@ -166,7 +244,6 @@ func referSameObject(a, b metav1.OwnerReference) bool {
 	if err != nil {
 		return false
 	}
-
 	return aGV.Group == bGV.Group && a.Kind == b.Kind && a.Name == b.Name
 }
 
@@ -193,6 +270,9 @@ const ( // They should complete the sentence "Deployment default/foo has been ..
 // The MutateFn is called regardless of creating or updating an object.
 //
 // It returns the executed operation and an error.
+//
+// Note: changes made by MutateFn to any sub-resource (status...), will be
+// discarded.
 func CreateOrUpdate(ctx context.Context, c client.Client, obj client.Object, f MutateFn) (OperationResult, error) {
 	key := client.ObjectKeyFromObject(obj)
 	if err := c.Get(ctx, key, obj); err != nil {
@@ -230,6 +310,12 @@ func CreateOrUpdate(ctx context.Context, c client.Client, obj client.Object, f M
 // The MutateFn is called regardless of creating or updating an object.
 //
 // It returns the executed operation and an error.
+//
+// Note: changes to any sub-resource other than status will be ignored.
+// Changes to the status sub-resource will only be applied if the object
+// already exist. To change the status on object creation, the easiest
+// way is to requeue the object in the controller if OperationResult is
+// OperationResultCreated
 func CreateOrPatch(ctx context.Context, c client.Client, obj client.Object, f MutateFn) (OperationResult, error) {
 	key := client.ObjectKeyFromObject(obj)
 	if err := c.Get(ctx, key, obj); err != nil {
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/crd.go b/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/crd.go
index f9c58ea2..5fdd657c 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/crd.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/crd.go
@@ -38,7 +38,7 @@ import (
 	"k8s.io/client-go/kubernetes/scheme"
 	"k8s.io/client-go/rest"
 	"k8s.io/client-go/util/retry"
-	"k8s.io/utils/pointer"
+	"k8s.io/utils/ptr"
 	"sigs.k8s.io/yaml"
 
 	"sigs.k8s.io/controller-runtime/pkg/client"
@@ -364,19 +364,26 @@ func modifyConversionWebhooks(crds []*apiextensionsv1.CustomResourceDefinition,
 	if err != nil {
 		return err
 	}
-	url := pointer.String(fmt.Sprintf("https://%s/convert", hostPort))
+	url := ptr.To(fmt.Sprintf("https://%s/convert", hostPort))
 
 	for i := range crds {
 		// Continue if we're preserving unknown fields.
 		if crds[i].Spec.PreserveUnknownFields {
 			continue
 		}
-		// Continue if the GroupKind isn't registered as being convertible.
-		if _, ok := convertibles[schema.GroupKind{
-			Group: crds[i].Spec.Group,
-			Kind:  crds[i].Spec.Names.Kind,
-		}]; !ok {
-			continue
+		if !webhookOptions.IgnoreSchemeConvertible {
+			// Continue if the GroupKind isn't registered as being convertible,
+			// and remove any existing conversion webhooks if they exist.
+			// This is to prevent the CRD from being rejected by the apiserver, usually
+			// manifests that are generated by controller-gen will have a conversion
+			// webhook set, but we don't want to enable it if the type isn't registered.
+			if _, ok := convertibles[schema.GroupKind{
+				Group: crds[i].Spec.Group,
+				Kind:  crds[i].Spec.Names.Kind,
+			}]; !ok {
+				crds[i].Spec.Conversion = nil
+				continue
+			}
 		}
 		if crds[i].Spec.Conversion == nil {
 			crds[i].Spec.Conversion = &apiextensionsv1.CustomResourceConversion{
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/webhook.go b/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/webhook.go
index f7e43a14..e4e54e47 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/webhook.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/webhook.go
@@ -49,6 +49,11 @@ type WebhookInstallOptions struct {
 	// ValidatingWebhooks is a list of ValidatingWebhookConfigurations to install
 	ValidatingWebhooks []*admissionv1.ValidatingWebhookConfiguration
 
+	// IgnoreSchemeConvertible, will modify any CRD conversion webhook to use the local serving host and port,
+	// bypassing the need to have the types registered in the Scheme. This is useful for testing CRD conversion webhooks
+	// with unregistered or unstructured types.
+	IgnoreSchemeConvertible bool
+
 	// IgnoreErrorIfPathMissing will ignore an error if a DirectoryPath does not exist when set to true
 	IgnoreErrorIfPathMissing bool
 
@@ -184,7 +189,8 @@ func defaultWebhookOptions(o *WebhookInstallOptions) {
 func WaitForWebhooks(config *rest.Config,
 	mutatingWebhooks []*admissionv1.MutatingWebhookConfiguration,
 	validatingWebhooks []*admissionv1.ValidatingWebhookConfiguration,
-	options WebhookInstallOptions) error {
+	options WebhookInstallOptions,
+) error {
 	waitingFor := map[schema.GroupVersionKind]*sets.Set[string]{}
 
 	for _, hook := range mutatingWebhooks {
@@ -242,7 +248,7 @@ func (p *webhookPoller) poll(ctx context.Context) (done bool, err error) {
 			continue
 		}
 		for _, name := range names.UnsortedList() {
-			var obj = &unstructured.Unstructured{}
+			obj := &unstructured.Unstructured{}
 			obj.SetGroupVersionKind(gvk)
 			err := c.Get(context.Background(), client.ObjectKey{
 				Namespace: "",
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/handler/eventhandler.go b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/eventhandler.go
index 2f380f4f..ff2f3e80 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/handler/eventhandler.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/eventhandler.go
@@ -42,7 +42,7 @@ import (
 // Unless you are implementing your own EventHandler, you can ignore the functions on the EventHandler interface.
 // Most users shouldn't need to implement their own EventHandler.
 type EventHandler interface {
-	// Create is called in response to an create event - e.g. Pod Creation.
+	// Create is called in response to a create event - e.g. Pod Creation.
 	Create(context.Context, event.CreateEvent, workqueue.RateLimitingInterface)
 
 	// Update is called in response to an update event -  e.g. Pod Updated.
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils.go
index 4f6d0843..8f6dc71e 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils.go
@@ -22,14 +22,16 @@ import (
 )
 
 // RequiresExactMatch checks if the given field selector is of the form `k=v` or `k==v`.
-func RequiresExactMatch(sel fields.Selector) (field, val string, required bool) {
+func RequiresExactMatch(sel fields.Selector) bool {
 	reqs := sel.Requirements()
-	if len(reqs) != 1 {
-		return "", "", false
+	if len(reqs) == 0 {
+		return false
 	}
-	req := reqs[0]
-	if req.Operator != selection.Equals && req.Operator != selection.DoubleEquals {
-		return "", "", false
+
+	for _, req := range reqs {
+		if req.Operator != selection.Equals && req.Operator != selection.DoubleEquals {
+			return false
+		}
 	}
-	return req.Field, req.Value, true
+	return true
 }
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/syncs/syncs.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/syncs/syncs.go
new file mode 100644
index 00000000..c78a3037
--- /dev/null
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/syncs/syncs.go
@@ -0,0 +1,38 @@
+package syncs
+
+import (
+	"context"
+	"reflect"
+	"sync"
+)
+
+// MergeChans returns a channel that is closed when any of the input channels are signaled.
+// The caller must call the returned CancelFunc to ensure no resources are leaked.
+func MergeChans[T any](chans ...<-chan T) (<-chan T, context.CancelFunc) {
+	var once sync.Once
+	out := make(chan T)
+	cancel := make(chan T)
+	cancelFunc := func() {
+		once.Do(func() {
+			close(cancel)
+		})
+		<-out
+	}
+	cases := make([]reflect.SelectCase, len(chans)+1)
+	for i := range chans {
+		cases[i] = reflect.SelectCase{
+			Dir:  reflect.SelectRecv,
+			Chan: reflect.ValueOf(chans[i]),
+		}
+	}
+	cases[len(cases)-1] = reflect.SelectCase{
+		Dir:  reflect.SelectRecv,
+		Chan: reflect.ValueOf(cancel),
+	}
+	go func() {
+		defer close(out)
+		_, _, _ = reflect.Select(cases)
+	}()
+
+	return out, cancelFunc
+}
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/kubectl.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/kubectl.go
index a27b7a0f..a41bb77c 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/kubectl.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/kubectl.go
@@ -112,6 +112,7 @@ func (k *KubeCtl) Run(args ...string) (stdout, stderr io.Reader, err error) {
 	cmd := exec.Command(k.Path, allArgs...)
 	cmd.Stdout = stdoutBuffer
 	cmd.Stderr = stderrBuffer
+	cmd.SysProcAttr = process.GetSysProcAttr()
 
 	err = cmd.Run()
 
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/procattr_other.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/procattr_other.go
new file mode 100644
index 00000000..df13b341
--- /dev/null
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/procattr_other.go
@@ -0,0 +1,28 @@
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
+
+/*
+Copyright 2016 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package process
+
+import "syscall"
+
+// GetSysProcAttr returns the SysProcAttr to use for the process,
+// for non-unix systems this returns nil.
+func GetSysProcAttr() *syscall.SysProcAttr {
+	return nil
+}
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/procattr_unix.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/procattr_unix.go
new file mode 100644
index 00000000..83ad509a
--- /dev/null
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/procattr_unix.go
@@ -0,0 +1,33 @@
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
+
+/*
+Copyright 2023 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package process
+
+import (
+	"golang.org/x/sys/unix"
+)
+
+// GetSysProcAttr returns the SysProcAttr to use for the process,
+// for unix systems this returns a SysProcAttr with Setpgid set to true,
+// which inherits the parent's process group id.
+func GetSysProcAttr() *unix.SysProcAttr {
+	return &unix.SysProcAttr{
+		Setpgid: true,
+	}
+}
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process.go
index af83c70a..03f25252 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process.go
@@ -155,6 +155,7 @@ func (ps *State) Start(stdout, stderr io.Writer) (err error) {
 	ps.Cmd = exec.Command(ps.Path, ps.Args...)
 	ps.Cmd.Stdout = stdout
 	ps.Cmd.Stderr = stderr
+	ps.Cmd.SysProcAttr = GetSysProcAttr()
 
 	ready := make(chan bool)
 	timedOut := time.After(ps.StartTimeout)
@@ -265,6 +266,9 @@ func (ps *State) Stop() error {
 	case <-ps.waitDone:
 		break
 	case <-timedOut:
+		if err := ps.Cmd.Process.Signal(syscall.SIGKILL); err != nil {
+			return fmt.Errorf("unable to kill process %s: %w", ps.Path, err)
+		}
 		return fmt.Errorf("timeout waiting for process %s to stop", path.Base(ps.Path))
 	}
 	ps.ready = false
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/manager/manager.go b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/manager.go
index 708a9cc1..25c3c737 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/manager/manager.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/manager.go
@@ -34,7 +34,7 @@ import (
 	"k8s.io/client-go/rest"
 	"k8s.io/client-go/tools/leaderelection/resourcelock"
 	"k8s.io/client-go/tools/record"
-	"k8s.io/utils/pointer"
+	"k8s.io/utils/ptr"
 	metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
 
 	"sigs.k8s.io/controller-runtime/pkg/cache"
@@ -409,10 +409,10 @@ func New(config *rest.Config, options Options) (Manager, error) {
 		return nil, fmt.Errorf("failed to new pprof listener: %w", err)
 	}
 
-	errChan := make(chan error)
+	errChan := make(chan error, 1)
 	runnables := newRunnables(options.BaseContext, errChan)
 	return &controllerManager{
-		stopProcedureEngaged:          pointer.Int64(0),
+		stopProcedureEngaged:          ptr.To(int64(0)),
 		cluster:                       cluster,
 		runnables:                     runnables,
 		errChan:                       errChan,
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/workqueue.go b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/workqueue.go
index 277b8788..cff1de4c 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/workqueue.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/workqueue.go
@@ -54,14 +54,14 @@ var (
 		Subsystem: WorkQueueSubsystem,
 		Name:      QueueLatencyKey,
 		Help:      "How long in seconds an item stays in workqueue before being requested",
-		Buckets:   prometheus.ExponentialBuckets(10e-9, 10, 10),
+		Buckets:   prometheus.ExponentialBuckets(10e-9, 10, 12),
 	}, []string{"name"})
 
 	workDuration = prometheus.NewHistogramVec(prometheus.HistogramOpts{
 		Subsystem: WorkQueueSubsystem,
 		Name:      WorkDurationKey,
 		Help:      "How long in seconds processing an item from workqueue takes.",
-		Buckets:   prometheus.ExponentialBuckets(10e-9, 10, 10),
+		Buckets:   prometheus.ExponentialBuckets(10e-9, 10, 12),
 	}, []string{"name"})
 
 	unfinished = prometheus.NewGaugeVec(prometheus.GaugeOpts{
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile.go b/vendor/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile.go
index 0f4e7e16..f1cce87c 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile.go
@@ -19,9 +19,11 @@ package reconcile
 import (
 	"context"
 	"errors"
+	"reflect"
 	"time"
 
 	"k8s.io/apimachinery/pkg/types"
+	"sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 // Result contains the result of a Reconciler invocation.
@@ -97,7 +99,7 @@ type Reconciler interface {
 	// If the error is nil and the returned Result has a non-zero result.RequeueAfter, the request
 	// will be requeued after the specified duration.
 	//
-	// If the error is nil and result.RequeueAfter is zero and result.Reque is true, the request
+	// If the error is nil and result.RequeueAfter is zero and result.Requeue is true, the request
 	// will be requeued using exponential backoff.
 	Reconcile(context.Context, Request) (Result, error)
 }
@@ -110,6 +112,36 @@ var _ Reconciler = Func(nil)
 // Reconcile implements Reconciler.
 func (r Func) Reconcile(ctx context.Context, o Request) (Result, error) { return r(ctx, o) }
 
+// ObjectReconciler is a specialized version of Reconciler that acts on instances of client.Object. Each reconciliation
+// event gets the associated object from Kubernetes before passing it to Reconcile. An ObjectReconciler can be used in
+// Builder.Complete by calling AsReconciler. See Reconciler for more details.
+type ObjectReconciler[T client.Object] interface {
+	Reconcile(context.Context, T) (Result, error)
+}
+
+// AsReconciler creates a Reconciler based on the given ObjectReconciler.
+func AsReconciler[T client.Object](client client.Client, rec ObjectReconciler[T]) Reconciler {
+	return &objectReconcilerAdapter[T]{
+		objReconciler: rec,
+		client:        client,
+	}
+}
+
+type objectReconcilerAdapter[T client.Object] struct {
+	objReconciler ObjectReconciler[T]
+	client        client.Client
+}
+
+// Reconcile implements Reconciler.
+func (a *objectReconcilerAdapter[T]) Reconcile(ctx context.Context, req Request) (Result, error) {
+	o := reflect.New(reflect.TypeOf(*new(T)).Elem()).Interface().(T)
+	if err := a.client.Get(ctx, req.NamespacedName, o); err != nil {
+		return Result{}, client.IgnoreNotFound(err)
+	}
+
+	return a.objReconciler.Reconcile(ctx, o)
+}
+
 // TerminalError is an error that will not be retried but still be logged
 // and recorded in metrics.
 func TerminalError(wrapped error) error {
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter.go
index a3b72071..c9662ce1 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter.go
@@ -27,12 +27,14 @@ import (
 )
 
 // Defaulter defines functions for setting defaults on resources.
+// Deprecated: Ue CustomDefaulter instead.
 type Defaulter interface {
 	runtime.Object
 	Default()
 }
 
 // DefaultingWebhookFor creates a new Webhook for Defaulting the provided type.
+// Deprecated: Use WithCustomDefaulter instead.
 func DefaultingWebhookFor(scheme *runtime.Scheme, defaulter Defaulter) *Webhook {
 	return &Webhook{
 		Handler: &mutatingHandler{defaulter: defaulter, decoder: NewDecoder(scheme)},
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/http.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/http.go
index 57e465ab..f049fb66 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/http.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/http.go
@@ -34,6 +34,26 @@ import (
 var admissionScheme = runtime.NewScheme()
 var admissionCodecs = serializer.NewCodecFactory(admissionScheme)
 
+// adapted from https://github.com/kubernetes/kubernetes/blob/c28c2009181fcc44c5f6b47e10e62dacf53e4da0/staging/src/k8s.io/pod-security-admission/cmd/webhook/server/server.go
+//
+// From https://github.com/kubernetes/apiserver/blob/d6876a0600de06fef75968c4641c64d7da499f25/pkg/server/config.go#L433-L442C5:
+//
+//	     1.5MB is the recommended client request size in byte
+//		 the etcd server should accept. See
+//		 https://github.com/etcd-io/etcd/blob/release-3.4/embed/config.go#L56.
+//		 A request body might be encoded in json, and is converted to
+//		 proto when persisted in etcd, so we allow 2x as the largest request
+//		 body size to be accepted and decoded in a write request.
+//
+// For the admission request, we can infer that it contains at most two objects
+// (the old and new versions of the object being admitted), each of which can
+// be at most 3MB in size. For the rest of the request, we can assume that
+// it will be less than 1MB in size. Therefore, we can set the max request
+// size to 7MB.
+// If your use case requires larger max request sizes, please
+// open an issue (https://github.com/kubernetes-sigs/controller-runtime/issues/new).
+const maxRequestSize = int64(7 * 1024 * 1024)
+
 func init() {
 	utilruntime.Must(v1.AddToScheme(admissionScheme))
 	utilruntime.Must(v1beta1.AddToScheme(admissionScheme))
@@ -42,27 +62,30 @@ func init() {
 var _ http.Handler = &Webhook{}
 
 func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	var body []byte
-	var err error
 	ctx := r.Context()
 	if wh.WithContextFunc != nil {
 		ctx = wh.WithContextFunc(ctx, r)
 	}
 
-	var reviewResponse Response
-	if r.Body == nil {
-		err = errors.New("request body is empty")
+	if r.Body == nil || r.Body == http.NoBody {
+		err := errors.New("request body is empty")
 		wh.getLogger(nil).Error(err, "bad request")
-		reviewResponse = Errored(http.StatusBadRequest, err)
-		wh.writeResponse(w, reviewResponse)
+		wh.writeResponse(w, Errored(http.StatusBadRequest, err))
 		return
 	}
 
 	defer r.Body.Close()
-	if body, err = io.ReadAll(r.Body); err != nil {
+	limitedReader := &io.LimitedReader{R: r.Body, N: maxRequestSize}
+	body, err := io.ReadAll(limitedReader)
+	if err != nil {
 		wh.getLogger(nil).Error(err, "unable to read the body from the incoming request")
-		reviewResponse = Errored(http.StatusBadRequest, err)
-		wh.writeResponse(w, reviewResponse)
+		wh.writeResponse(w, Errored(http.StatusBadRequest, err))
+		return
+	}
+	if limitedReader.N <= 0 {
+		err := fmt.Errorf("request entity is too large; limit is %d bytes", maxRequestSize)
+		wh.getLogger(nil).Error(err, "unable to read the body from the incoming request; limit reached")
+		wh.writeResponse(w, Errored(http.StatusRequestEntityTooLarge, err))
 		return
 	}
 
@@ -70,8 +93,7 @@ func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	if contentType := r.Header.Get("Content-Type"); contentType != "application/json" {
 		err = fmt.Errorf("contentType=%s, expected application/json", contentType)
 		wh.getLogger(nil).Error(err, "unable to process a request with unknown content type")
-		reviewResponse = Errored(http.StatusBadRequest, err)
-		wh.writeResponse(w, reviewResponse)
+		wh.writeResponse(w, Errored(http.StatusBadRequest, err))
 		return
 	}
 
@@ -89,14 +111,12 @@ func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	_, actualAdmRevGVK, err := admissionCodecs.UniversalDeserializer().Decode(body, nil, &ar)
 	if err != nil {
 		wh.getLogger(nil).Error(err, "unable to decode the request")
-		reviewResponse = Errored(http.StatusBadRequest, err)
-		wh.writeResponse(w, reviewResponse)
+		wh.writeResponse(w, Errored(http.StatusBadRequest, err))
 		return
 	}
 	wh.getLogger(&req).V(5).Info("received request")
 
-	reviewResponse = wh.Handle(ctx, req)
-	wh.writeResponseTyped(w, reviewResponse, actualAdmRevGVK)
+	wh.writeResponseTyped(w, wh.Handle(ctx, req), actualAdmRevGVK)
 }
 
 // writeResponse writes response to w generically, i.e. without encoding GVK information.
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator.go
index 00bda8a4..fa42217b 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator.go
@@ -33,6 +33,7 @@ type Warnings []string
 // Validator defines functions for validating an operation.
 // The custom resource kind which implements this interface can validate itself.
 // To validate the custom resource with another specific struct, use CustomValidator instead.
+// Deprecated: Use CustomValidator instead.
 type Validator interface {
 	runtime.Object
 
@@ -53,6 +54,7 @@ type Validator interface {
 }
 
 // ValidatingWebhookFor creates a new Webhook for validating the provided type.
+// Deprecated: Use WithCustomValidator instead.
 func ValidatingWebhookFor(scheme *runtime.Scheme, validator Validator) *Webhook {
 	return &Webhook{
 		Handler: &validatingHandler{validator: validator, decoder: NewDecoder(scheme)},
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator_custom.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator_custom.go
index e99fbd8a..07650aa6 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator_custom.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator_custom.go
@@ -30,7 +30,6 @@ import (
 // CustomValidator defines functions for validating an operation.
 // The object to be validated is passed into methods as a parameter.
 type CustomValidator interface {
-
 	// ValidateCreate validates the object on creation.
 	// The optional warnings will be added to the response as warning messages.
 	// Return an error if the object is invalid.
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/alias.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/alias.go
index 293137db..e8439e2e 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/alias.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/alias.go
@@ -24,9 +24,11 @@ import (
 // define some aliases for common bits of the webhook functionality
 
 // Defaulter defines functions for setting defaults on resources.
+// Deprecated: Use CustomDefaulter instead.
 type Defaulter = admission.Defaulter
 
 // Validator defines functions for validating an operation.
+// Deprecated: Use CustomValidator instead.
 type Validator = admission.Validator
 
 // CustomDefaulter defines functions for setting defaults on resources.