You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@druid.apache.org by ad...@apache.org on 2026/02/24 06:07:28 UTC
(druid-operator) 01/02: add support for volume attribute class name
This is an automated email from the ASF dual-hosted git repository.
adheipsingh pushed a commit to branch 1.3.0-volume-attribute-className
in repository https://gitbox.apache.org/repos/asf/druid-operator.git
commit 5ede9f84aed8f635b611facf24acb1f9df23d1f9
Author: AdheipSingh <ad...@gmail.com>
AuthorDate: Sat Oct 4 02:03:17 2025 +0530
add support for volume attribute class name
---
apis/druid/v1alpha1/druid_types.go | 6 +-
chart/crds/druid.apache.org_druids.yaml | 1212 +++++++++++++++-----
config/crd/bases/druid.apache.org_druids.yaml | 1212 +++++++++++++++-----
controllers/druid/druid_controller.go | 6 +-
controllers/druid/handler.go | 8 +-
controllers/druid/volume_annotation_update.go | 278 -----
controllers/druid/volume_claim_template_update.go | 368 ++++++
...est.go => volume_claim_template_update_test.go} | 85 +-
e2e/configs/druid-cr.yaml | 18 +
e2e/configs/volume-attributes-class.yaml | 10 +
go.mod | 83 +-
go.sum | 248 ++--
main.go | 36 +-
13 files changed, 2538 insertions(+), 1032 deletions(-)
diff --git a/apis/druid/v1alpha1/druid_types.go b/apis/druid/v1alpha1/druid_types.go
index aacc91f..579a102 100644
--- a/apis/druid/v1alpha1/druid_types.go
+++ b/apis/druid/v1alpha1/druid_types.go
@@ -115,11 +115,11 @@ type DruidSpec struct {
// +kubebuilder:default:=false
DisablePVCDeletionFinalizer bool `json:"disablePVCDeletionFinalizer,omitempty"`
- // DisablePVCAnnotationUpdate When set to true, operator will not patch PVC annotations when VolumeClaimTemplate annotations are updated.
- // When disabled (false), updating VolumeClaimTemplate annotations will patch existing PVCs and recreate the StatefulSet.
+ // DisablePVCUpdates When set to true, operator will not patch PVCs when VolumeClaimTemplate annotations or volumeAttributeClassName are updated.
+ // When disabled (false), updating VolumeClaimTemplate annotations or volumeAttributeClassName will patch existing PVCs and recreate the StatefulSet.
// +optional
// +kubebuilder:default:=false
- DisablePVCAnnotationUpdate bool `json:"disablePVCAnnotationUpdate,omitempty"`
+ DisablePVCUpdates bool `json:"disablePVCAnnotationUpdate,omitempty"`
// DeleteOrphanPvc Orphaned (unmounted PVCs) shall be cleaned up by the operator.
// +optional
diff --git a/chart/crds/druid.apache.org_druids.yaml b/chart/crds/druid.apache.org_druids.yaml
index d14ed98..66efdf3 100644
--- a/chart/crds/druid.apache.org_druids.yaml
+++ b/chart/crds/druid.apache.org_druids.yaml
@@ -403,7 +403,7 @@ spec:
localhostProfile indicates a profile defined in a file on the node should be used.
The profile must be preconfigured on the node to work.
Must be a descending path, relative to the kubelet's configured seccomp profile location.
- Must only be set if type is "Localhost".
+ Must be set if type is "Localhost". Must NOT be set for any other type.
type: string
type:
description: |-
@@ -438,12 +438,9 @@ spec:
hostProcess:
description: |-
HostProcess determines if a container should be run as a 'Host Process' container.
- This field is alpha-level and will only be honored by components that enable the
- WindowsHostProcessContainers feature flag. Setting this field without the feature
- flag will result in errors when validating the Pod. All of a Pod's containers must
- have the same effective HostProcess value (it is not allowed to have a mix of HostProcess
- containers and non-HostProcess containers). In addition, if HostProcess is true
- then HostNetwork must also be set to true.
+ All of a Pod's containers must have the same effective HostProcess value
+ (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).
+ In addition, if HostProcess is true then HostNetwork must also be set to true.
type: boolean
runAsUserName:
description: |-
@@ -719,8 +716,9 @@ spec:
with the corresponding weight.
properties:
labelSelector:
- description: A label query over a set of resources,
- in this case pods.
+ description: |-
+ A label query over a set of resources, in this case pods.
+ If it's null, this PodAffinityTerm matches with no Pods.
properties:
matchExpressions:
description: matchExpressions is a list of label
@@ -764,6 +762,36 @@ spec:
type: object
type: object
x-kubernetes-map-type: atomic
+ matchLabelKeys:
+ description: |-
+ MatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MatchLabelKeys and LabelSelector.
+ Also, MatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
+ mismatchLabelKeys:
+ description: |-
+ MismatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector.
+ Also, MismatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
namespaceSelector:
description: |-
A label query over the set of namespaces that the term applies to.
@@ -864,8 +892,9 @@ spec:
a pod of the set of pods is running
properties:
labelSelector:
- description: A label query over a set of resources,
- in this case pods.
+ description: |-
+ A label query over a set of resources, in this case pods.
+ If it's null, this PodAffinityTerm matches with no Pods.
properties:
matchExpressions:
description: matchExpressions is a list of label
@@ -908,6 +937,36 @@ spec:
type: object
type: object
x-kubernetes-map-type: atomic
+ matchLabelKeys:
+ description: |-
+ MatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MatchLabelKeys and LabelSelector.
+ Also, MatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
+ mismatchLabelKeys:
+ description: |-
+ MismatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector.
+ Also, MismatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
namespaceSelector:
description: |-
A label query over the set of namespaces that the term applies to.
@@ -1004,8 +1063,9 @@ spec:
with the corresponding weight.
properties:
labelSelector:
- description: A label query over a set of resources,
- in this case pods.
+ description: |-
+ A label query over a set of resources, in this case pods.
+ If it's null, this PodAffinityTerm matches with no Pods.
properties:
matchExpressions:
description: matchExpressions is a list of label
@@ -1049,6 +1109,36 @@ spec:
type: object
type: object
x-kubernetes-map-type: atomic
+ matchLabelKeys:
+ description: |-
+ MatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MatchLabelKeys and LabelSelector.
+ Also, MatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
+ mismatchLabelKeys:
+ description: |-
+ MismatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector.
+ Also, MismatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
namespaceSelector:
description: |-
A label query over the set of namespaces that the term applies to.
@@ -1149,8 +1239,9 @@ spec:
a pod of the set of pods is running
properties:
labelSelector:
- description: A label query over a set of resources,
- in this case pods.
+ description: |-
+ A label query over a set of resources, in this case pods.
+ If it's null, this PodAffinityTerm matches with no Pods.
properties:
matchExpressions:
description: matchExpressions is a list of label
@@ -1193,6 +1284,36 @@ spec:
type: object
type: object
x-kubernetes-map-type: atomic
+ matchLabelKeys:
+ description: |-
+ MatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MatchLabelKeys and LabelSelector.
+ Also, MatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
+ mismatchLabelKeys:
+ description: |-
+ MismatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector.
+ Also, MismatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
namespaceSelector:
description: |-
A label query over the set of namespaces that the term applies to.
@@ -1414,7 +1535,7 @@ spec:
localhostProfile indicates a profile defined in a file on the node should be used.
The profile must be preconfigured on the node to work.
Must be a descending path, relative to the kubelet's configured seccomp profile location.
- Must only be set if type is "Localhost".
+ Must be set if type is "Localhost". Must NOT be set for any other type.
type: string
type:
description: |-
@@ -1449,12 +1570,9 @@ spec:
hostProcess:
description: |-
HostProcess determines if a container should be run as a 'Host Process' container.
- This field is alpha-level and will only be honored by components that enable the
- WindowsHostProcessContainers feature flag. Setting this field without the feature
- flag will result in errors when validating the Pod. All of a Pod's containers must
- have the same effective HostProcess value (it is not allowed to have a mix of HostProcess
- containers and non-HostProcess containers). In addition, if HostProcess is true
- then HostNetwork must also be set to true.
+ All of a Pod's containers must have the same effective HostProcess value
+ (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).
+ In addition, if HostProcess is true then HostNetwork must also be set to true.
type: boolean
runAsUserName:
description: |-
@@ -1499,8 +1617,8 @@ spec:
disablePVCAnnotationUpdate:
default: false
description: |-
- DisablePVCAnnotationUpdate When set to true, operator will not patch PVC annotations when VolumeClaimTemplate annotations are updated.
- When disabled (false), updating VolumeClaimTemplate annotations will patch existing PVCs and recreate the StatefulSet.
+ DisablePVCUpdates When set to true, operator will not patch PVCs when VolumeClaimTemplate annotations or volumeAttributeClassName are updated.
+ When disabled (false), updating VolumeClaimTemplate annotations or volumeAttributeClassName will patch existing PVCs and recreate the StatefulSet.
type: boolean
disablePVCDeletionFinalizer:
default: false
@@ -2332,7 +2450,7 @@ spec:
localhostProfile indicates a profile defined in a file on the node should be used.
The profile must be preconfigured on the node to work.
Must be a descending path, relative to the kubelet's configured seccomp profile location.
- Must only be set if type is "Localhost".
+ Must be set if type is "Localhost". Must NOT be set for any other type.
type: string
type:
description: |-
@@ -2367,12 +2485,9 @@ spec:
hostProcess:
description: |-
HostProcess determines if a container should be run as a 'Host Process' container.
- This field is alpha-level and will only be honored by components that enable the
- WindowsHostProcessContainers feature flag. Setting this field without the feature
- flag will result in errors when validating the Pod. All of a Pod's containers must
- have the same effective HostProcess value (it is not allowed to have a mix of HostProcess
- containers and non-HostProcess containers). In addition, if HostProcess is true
- then HostNetwork must also be set to true.
+ All of a Pod's containers must have the same effective HostProcess value
+ (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).
+ In addition, if HostProcess is true then HostNetwork must also be set to true.
type: boolean
runAsUserName:
description: |-
@@ -2652,8 +2767,9 @@ spec:
with the corresponding weight.
properties:
labelSelector:
- description: A label query over a set of resources,
- in this case pods.
+ description: |-
+ A label query over a set of resources, in this case pods.
+ If it's null, this PodAffinityTerm matches with no Pods.
properties:
matchExpressions:
description: matchExpressions is a list
@@ -2697,6 +2813,36 @@ spec:
type: object
type: object
x-kubernetes-map-type: atomic
+ matchLabelKeys:
+ description: |-
+ MatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MatchLabelKeys and LabelSelector.
+ Also, MatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
+ mismatchLabelKeys:
+ description: |-
+ MismatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector.
+ Also, MismatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
namespaceSelector:
description: |-
A label query over the set of namespaces that the term applies to.
@@ -2797,8 +2943,9 @@ spec:
a pod of the set of pods is running
properties:
labelSelector:
- description: A label query over a set of resources,
- in this case pods.
+ description: |-
+ A label query over a set of resources, in this case pods.
+ If it's null, this PodAffinityTerm matches with no Pods.
properties:
matchExpressions:
description: matchExpressions is a list of
@@ -2842,6 +2989,36 @@ spec:
type: object
type: object
x-kubernetes-map-type: atomic
+ matchLabelKeys:
+ description: |-
+ MatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MatchLabelKeys and LabelSelector.
+ Also, MatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
+ mismatchLabelKeys:
+ description: |-
+ MismatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector.
+ Also, MismatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
namespaceSelector:
description: |-
A label query over the set of namespaces that the term applies to.
@@ -2940,8 +3117,9 @@ spec:
with the corresponding weight.
properties:
labelSelector:
- description: A label query over a set of resources,
- in this case pods.
+ description: |-
+ A label query over a set of resources, in this case pods.
+ If it's null, this PodAffinityTerm matches with no Pods.
properties:
matchExpressions:
description: matchExpressions is a list
@@ -2985,6 +3163,36 @@ spec:
type: object
type: object
x-kubernetes-map-type: atomic
+ matchLabelKeys:
+ description: |-
+ MatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MatchLabelKeys and LabelSelector.
+ Also, MatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
+ mismatchLabelKeys:
+ description: |-
+ MismatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector.
+ Also, MismatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
namespaceSelector:
description: |-
A label query over the set of namespaces that the term applies to.
@@ -3085,8 +3293,9 @@ spec:
a pod of the set of pods is running
properties:
labelSelector:
- description: A label query over a set of resources,
- in this case pods.
+ description: |-
+ A label query over a set of resources, in this case pods.
+ If it's null, this PodAffinityTerm matches with no Pods.
properties:
matchExpressions:
description: matchExpressions is a list of
@@ -3130,6 +3339,36 @@ spec:
type: object
type: object
x-kubernetes-map-type: atomic
+ matchLabelKeys:
+ description: |-
+ MatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MatchLabelKeys and LabelSelector.
+ Also, MatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
+ mismatchLabelKeys:
+ description: |-
+ MismatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector.
+ Also, MismatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
namespaceSelector:
description: |-
A label query over the set of namespaces that the term applies to.
@@ -3322,7 +3561,7 @@ spec:
localhostProfile indicates a profile defined in a file on the node should be used.
The profile must be preconfigured on the node to work.
Must be a descending path, relative to the kubelet's configured seccomp profile location.
- Must only be set if type is "Localhost".
+ Must be set if type is "Localhost". Must NOT be set for any other type.
type: string
type:
description: |-
@@ -3357,12 +3596,9 @@ spec:
hostProcess:
description: |-
HostProcess determines if a container should be run as a 'Host Process' container.
- This field is alpha-level and will only be honored by components that enable the
- WindowsHostProcessContainers feature flag. Setting this field without the feature
- flag will result in errors when validating the Pod. All of a Pod's containers must
- have the same effective HostProcess value (it is not allowed to have a mix of HostProcess
- containers and non-HostProcess containers). In addition, if HostProcess is true
- then HostNetwork must also be set to true.
+ All of a Pod's containers must have the same effective HostProcess value
+ (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).
+ In addition, if HostProcess is true then HostNetwork must also be set to true.
type: boolean
runAsUserName:
description: |-
@@ -4553,6 +4789,18 @@ spec:
required:
- port
type: object
+ sleep:
+ description: Sleep represents the duration that the
+ container should sleep before being terminated.
+ properties:
+ seconds:
+ description: Seconds is the number of seconds to
+ sleep.
+ format: int64
+ type: integer
+ required:
+ - seconds
+ type: object
tcpSocket:
description: |-
Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept
@@ -4650,6 +4898,18 @@ spec:
required:
- port
type: object
+ sleep:
+ description: Sleep represents the duration that the
+ container should sleep before being terminated.
+ properties:
+ seconds:
+ description: Seconds is the number of seconds to
+ sleep.
+ format: int64
+ type: integer
+ required:
+ - seconds
+ type: object
tcpSocket:
description: |-
Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept
@@ -5005,34 +5265,6 @@ spec:
status field of the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
properties:
- claims:
- description: |-
- Claims lists the names of resources, defined in spec.resourceClaims,
- that are used by this container.
-
-
- This is an alpha field and requires enabling the
- DynamicResourceAllocation feature gate.
-
-
- 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:
@@ -5109,6 +5341,21 @@ spec:
storageClassName is the name of the StorageClass required by the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
type: string
+ volumeAttributesClassName:
+ description: |-
+ volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.
+ If specified, the CSI driver will create or update the volume with the attributes defined
+ in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,
+ it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass
+ will be applied to the claim but it's not allowed to reset this field to empty string once it is set.
+ If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass
+ will be set by the persistentvolume controller if it exists.
+ If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
+ set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
+ exists.
+ More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
+ type: string
volumeMode:
description: |-
volumeMode defines what type of volume is required by the claim.
@@ -5132,6 +5379,54 @@ spec:
items:
type: string
type: array
+ allocatedResourceStatuses:
+ additionalProperties:
+ description: |-
+ When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource
+ that it does not recognizes, then it should ignore that update and let other controllers
+ handle it.
+ type: string
+ description: "allocatedResourceStatuses stores status
+ of resource being resized for the given PVC.\nKey
+ names follow standard Kubernetes label syntax. Valid
+ values are either:\n\t* Un-prefixed keys:\n\t\t-
+ storage - the capacity of the volume.\n\t* Custom
+ resources must use implementation-defined prefixed
+ names such as \"example.com/my-custom-resource\"\nApart
+ from above values - keys that are unprefixed or
+ have kubernetes.io prefix are considered\nreserved
+ and hence may not be used.\n\n\nClaimResourceStatus
+ can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState
+ set when resize controller starts resizing the volume
+ in control-plane.\n\t- ControllerResizeFailed:\n\t\tState
+ set when resize has failed in resize controller
+ with a terminal error.\n\t- NodeResizePending:\n\t\tState
+ set when resize controller has finished resizing
+ the volume but further resizing of\n\t\tvolume is
+ needed on the node.\n\t- NodeResizeInProgress:\n\t\tState
+ set when kubelet starts resizing the volume.\n\t-
+ NodeResizeFailed:\n\t\tState set when resizing has
+ failed in kubelet with a terminal error. Transient
+ errors don't set\n\t\tNodeResizeFailed.\nFor example:
+ if expanding a PVC for more capacity - this field
+ can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage']
+ = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"NodeResizeFailed\"\nWhen this field is not set,
+ it means that no resize operation is in progress
+ for the given PVC.\n\n\nA controller that receives
+ PVC update with previously unknown resourceName
+ or ClaimResourceStatus\nshould ignore the update
+ for the purpose it was designed. For example - a
+ controller that\nonly is responsible for resizing
+ capacity of the volume, should ignore PVC updates
+ that change other valid\nresources associated with
+ PVC.\n\n\nThis is an alpha field and requires enabling
+ RecoverVolumeExpansionFailure feature."
+ type: object
+ x-kubernetes-map-type: granular
allocatedResources:
additionalProperties:
anyOf:
@@ -5139,15 +5434,33 @@ spec:
- 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: |-
- allocatedResources is the storage resource within AllocatedResources tracks the capacity allocated to a PVC. It may
- be larger than the actual capacity when a volume expansion operation is requested.
- For storage quota, the larger value from allocatedResources and PVC.spec.resources is used.
- If allocatedResources is not set, PVC.spec.resources alone is used for quota calculation.
- If a volume expansion capacity request is lowered, allocatedResources is only
- lowered if there are no expansion operations in progress and if the actual volume capacity
- is equal or lower than the requested capacity.
- This is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.
+ description: "allocatedResources tracks the resources
+ allocated to a PVC including its capacity.\nKey
+ names follow standard Kubernetes label syntax. Valid
+ values are either:\n\t* Un-prefixed keys:\n\t\t-
+ storage - the capacity of the volume.\n\t* Custom
+ resources must use implementation-defined prefixed
+ names such as \"example.com/my-custom-resource\"\nApart
+ from above values - keys that are unprefixed or
+ have kubernetes.io prefix are considered\nreserved
+ and hence may not be used.\n\n\nCapacity reported
+ here may be larger than the actual capacity when
+ a volume expansion operation\nis requested.\nFor
+ storage quota, the larger value from allocatedResources
+ and PVC.spec.resources is used.\nIf allocatedResources
+ is not set, PVC.spec.resources alone is used for
+ quota calculation.\nIf a volume expansion capacity
+ request is lowered, allocatedResources is only\nlowered
+ if there are no expansion operations in progress
+ and if the actual volume capacity\nis equal or lower
+ than the requested capacity.\n\n\nA controller that
+ receives PVC update with previously unknown resourceName\nshould
+ ignore the update for the purpose it was designed.
+ For example - a controller that\nonly is responsible
+ for resizing capacity of the volume, should ignore
+ PVC updates that change other valid\nresources associated
+ with PVC.\n\n\nThis is an alpha field and requires
+ enabling RecoverVolumeExpansionFailure feature."
type: object
capacity:
additionalProperties:
@@ -5199,17 +5512,45 @@ spec:
- type
type: object
type: array
+ currentVolumeAttributesClassName:
+ description: |-
+ currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using.
+ When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim
+ This is an alpha field and requires enabling VolumeAttributesClass feature.
+ type: string
+ modifyVolumeStatus:
+ description: |-
+ ModifyVolumeStatus represents the status object of ControllerModifyVolume operation.
+ When this is unset, there is no ModifyVolume operation being attempted.
+ This is an alpha field and requires enabling VolumeAttributesClass feature.
+ properties:
+ status:
+ description: "status is the status of the ControllerModifyVolume
+ operation. It can be in any of following states:\n
+ - Pending\n Pending indicates that the PersistentVolumeClaim
+ cannot be modified due to unmet requirements,
+ such as\n the specified VolumeAttributesClass
+ not existing.\n - InProgress\n InProgress
+ indicates that the volume is being modified.\n
+ - Infeasible\n Infeasible indicates that the
+ request has been rejected as invalid by the
+ CSI driver. To\n\t resolve the error, a valid
+ VolumeAttributesClass needs to be specified.\nNote:
+ New statuses can be added in the future. Consumers
+ should check for unknown statuses and fail appropriately."
+ type: string
+ targetVolumeAttributesClassName:
+ description: targetVolumeAttributesClassName is
+ the name of the VolumeAttributesClass the PVC
+ currently being reconciled
+ type: string
+ required:
+ - status
+ type: object
phase:
description: phase represents the current phase of
PersistentVolumeClaim.
type: string
- resizeStatus:
- description: |-
- resizeStatus stores status of resize operation.
- ResizeStatus is not set by default but when expansion is complete resizeStatus is set to empty
- string by resize controller or kubelet.
- This is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.
- type: string
type: object
type: object
type: array
@@ -5689,7 +6030,7 @@ spec:
localhostProfile indicates a profile defined in a file on the node should be used.
The profile must be preconfigured on the node to work.
Must be a descending path, relative to the kubelet's configured seccomp profile location.
- Must only be set if type is "Localhost".
+ Must be set if type is "Localhost". Must NOT be set for any other type.
type: string
type:
description: |-
@@ -5756,12 +6097,9 @@ spec:
hostProcess:
description: |-
HostProcess determines if a container should be run as a 'Host Process' container.
- This field is alpha-level and will only be honored by components that enable the
- WindowsHostProcessContainers feature flag. Setting this field without the feature
- flag will result in errors when validating the Pod. All of a Pod's containers must
- have the same effective HostProcess value (it is not allowed to have a mix of HostProcess
- containers and non-HostProcess containers). In addition, if HostProcess is true
- then HostNetwork must also be set to true.
+ All of a Pod's containers must have the same effective HostProcess value
+ (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).
+ In addition, if HostProcess is true then HostNetwork must also be set to true.
type: boolean
runAsUserName:
description: |-
@@ -5996,10 +6334,9 @@ spec:
This feature depends on whether the underlying cloud-provider supports specifying
the loadBalancerIP when a load balancer is created.
This field will be ignored if the cloud-provider does not support the feature.
- Deprecated: This field was under-specified and its meaning varies across implementations,
- and it cannot support dual-stack.
- As of Kubernetes v1.24, users are encouraged to use implementation-specific annotations when available.
- This field may be removed in a future API version.
+ Deprecated: This field was under-specified and its meaning varies across implementations.
+ Using it is non-portable and it may not support dual-stack.
+ Users are encouraged to use implementation-specific annotations when available.
type: string
loadBalancerSourceRanges:
description: |-
@@ -6021,10 +6358,22 @@ spec:
appProtocol:
description: |-
The application protocol for this port.
+ This is used as a hint for implementations to offer richer behavior for protocols that they understand.
This field follows standard Kubernetes label syntax.
- Un-prefixed names are reserved for IANA standard service names (as per
+ Valid values are either:
+
+
+ * Un-prefixed protocol names - reserved for IANA standard service names (as per
RFC-6335 and https://www.iana.org/assignments/service-names).
- Non-standard protocols should use prefixed names such as
+
+
+ * Kubernetes-defined prefixed names:
+ * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior-
+ * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455
+ * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455
+
+
+ * Other protocols should use implementation-defined prefixed names such as
mycompany.com/my-custom-protocol.
type: string
name:
@@ -6257,6 +6606,15 @@ spec:
IP is set for load-balancer ingress points that are IP based
(typically GCE or OpenStack load-balancers)
type: string
+ ipMode:
+ description: |-
+ IPMode specifies how the load-balancer IP behaves, and may only be specified when the ip field is specified.
+ Setting this to "VIP" indicates that traffic is delivered to the node with
+ the destination set to the load-balancer's IP and port.
+ Setting this to "Proxy" indicates that traffic is delivered to the node or pod with
+ the destination set to the node's IP and node port or the pod's IP and port.
+ Service implementations may use this information to adjust traffic routing.
+ type: string
ports:
description: |-
Ports is a list of records of service ports
@@ -6854,34 +7212,6 @@ spec:
status field of the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
properties:
- claims:
- description: |-
- Claims lists the names of resources, defined in spec.resourceClaims,
- that are used by this container.
-
-
- This is an alpha field and requires enabling the
- DynamicResourceAllocation feature gate.
-
-
- 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:
@@ -6958,6 +7288,21 @@ spec:
storageClassName is the name of the StorageClass required by the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
type: string
+ volumeAttributesClassName:
+ description: |-
+ volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.
+ If specified, the CSI driver will create or update the volume with the attributes defined
+ in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,
+ it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass
+ will be applied to the claim but it's not allowed to reset this field to empty string once it is set.
+ If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass
+ will be set by the persistentvolume controller if it exists.
+ If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
+ set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
+ exists.
+ More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
+ type: string
volumeMode:
description: |-
volumeMode defines what type of volume is required by the claim.
@@ -6981,6 +7326,54 @@ spec:
items:
type: string
type: array
+ allocatedResourceStatuses:
+ additionalProperties:
+ description: |-
+ When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource
+ that it does not recognizes, then it should ignore that update and let other controllers
+ handle it.
+ type: string
+ description: "allocatedResourceStatuses stores status
+ of resource being resized for the given PVC.\nKey
+ names follow standard Kubernetes label syntax. Valid
+ values are either:\n\t* Un-prefixed keys:\n\t\t-
+ storage - the capacity of the volume.\n\t* Custom
+ resources must use implementation-defined prefixed
+ names such as \"example.com/my-custom-resource\"\nApart
+ from above values - keys that are unprefixed or
+ have kubernetes.io prefix are considered\nreserved
+ and hence may not be used.\n\n\nClaimResourceStatus
+ can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState
+ set when resize controller starts resizing the volume
+ in control-plane.\n\t- ControllerResizeFailed:\n\t\tState
+ set when resize has failed in resize controller
+ with a terminal error.\n\t- NodeResizePending:\n\t\tState
+ set when resize controller has finished resizing
+ the volume but further resizing of\n\t\tvolume is
+ needed on the node.\n\t- NodeResizeInProgress:\n\t\tState
+ set when kubelet starts resizing the volume.\n\t-
+ NodeResizeFailed:\n\t\tState set when resizing has
+ failed in kubelet with a terminal error. Transient
+ errors don't set\n\t\tNodeResizeFailed.\nFor example:
+ if expanding a PVC for more capacity - this field
+ can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage']
+ = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"NodeResizeFailed\"\nWhen this field is not set,
+ it means that no resize operation is in progress
+ for the given PVC.\n\n\nA controller that receives
+ PVC update with previously unknown resourceName
+ or ClaimResourceStatus\nshould ignore the update
+ for the purpose it was designed. For example - a
+ controller that\nonly is responsible for resizing
+ capacity of the volume, should ignore PVC updates
+ that change other valid\nresources associated with
+ PVC.\n\n\nThis is an alpha field and requires enabling
+ RecoverVolumeExpansionFailure feature."
+ type: object
+ x-kubernetes-map-type: granular
allocatedResources:
additionalProperties:
anyOf:
@@ -6988,15 +7381,33 @@ spec:
- 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: |-
- allocatedResources is the storage resource within AllocatedResources tracks the capacity allocated to a PVC. It may
- be larger than the actual capacity when a volume expansion operation is requested.
- For storage quota, the larger value from allocatedResources and PVC.spec.resources is used.
- If allocatedResources is not set, PVC.spec.resources alone is used for quota calculation.
- If a volume expansion capacity request is lowered, allocatedResources is only
- lowered if there are no expansion operations in progress and if the actual volume capacity
- is equal or lower than the requested capacity.
- This is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.
+ description: "allocatedResources tracks the resources
+ allocated to a PVC including its capacity.\nKey
+ names follow standard Kubernetes label syntax. Valid
+ values are either:\n\t* Un-prefixed keys:\n\t\t-
+ storage - the capacity of the volume.\n\t* Custom
+ resources must use implementation-defined prefixed
+ names such as \"example.com/my-custom-resource\"\nApart
+ from above values - keys that are unprefixed or
+ have kubernetes.io prefix are considered\nreserved
+ and hence may not be used.\n\n\nCapacity reported
+ here may be larger than the actual capacity when
+ a volume expansion operation\nis requested.\nFor
+ storage quota, the larger value from allocatedResources
+ and PVC.spec.resources is used.\nIf allocatedResources
+ is not set, PVC.spec.resources alone is used for
+ quota calculation.\nIf a volume expansion capacity
+ request is lowered, allocatedResources is only\nlowered
+ if there are no expansion operations in progress
+ and if the actual volume capacity\nis equal or lower
+ than the requested capacity.\n\n\nA controller that
+ receives PVC update with previously unknown resourceName\nshould
+ ignore the update for the purpose it was designed.
+ For example - a controller that\nonly is responsible
+ for resizing capacity of the volume, should ignore
+ PVC updates that change other valid\nresources associated
+ with PVC.\n\n\nThis is an alpha field and requires
+ enabling RecoverVolumeExpansionFailure feature."
type: object
capacity:
additionalProperties:
@@ -7048,17 +7459,45 @@ spec:
- type
type: object
type: array
+ currentVolumeAttributesClassName:
+ description: |-
+ currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using.
+ When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim
+ This is an alpha field and requires enabling VolumeAttributesClass feature.
+ type: string
+ modifyVolumeStatus:
+ description: |-
+ ModifyVolumeStatus represents the status object of ControllerModifyVolume operation.
+ When this is unset, there is no ModifyVolume operation being attempted.
+ This is an alpha field and requires enabling VolumeAttributesClass feature.
+ properties:
+ status:
+ description: "status is the status of the ControllerModifyVolume
+ operation. It can be in any of following states:\n
+ - Pending\n Pending indicates that the PersistentVolumeClaim
+ cannot be modified due to unmet requirements,
+ such as\n the specified VolumeAttributesClass
+ not existing.\n - InProgress\n InProgress
+ indicates that the volume is being modified.\n
+ - Infeasible\n Infeasible indicates that the
+ request has been rejected as invalid by the
+ CSI driver. To\n\t resolve the error, a valid
+ VolumeAttributesClass needs to be specified.\nNote:
+ New statuses can be added in the future. Consumers
+ should check for unknown statuses and fail appropriately."
+ type: string
+ targetVolumeAttributesClassName:
+ description: targetVolumeAttributesClassName is
+ the name of the VolumeAttributesClass the PVC
+ currently being reconciled
+ type: string
+ required:
+ - status
+ type: object
phase:
description: phase represents the current phase of
PersistentVolumeClaim.
type: string
- resizeStatus:
- description: |-
- resizeStatus stores status of resize operation.
- ResizeStatus is not set by default but when expansion is complete resizeStatus is set to empty
- string by resize controller or kubelet.
- This is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.
- type: string
type: object
type: object
type: array
@@ -7699,34 +8138,6 @@ spec:
status field of the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
properties:
- claims:
- description: |-
- Claims lists the names of resources, defined in spec.resourceClaims,
- that are used by this container.
-
-
- This is an alpha field and requires enabling the
- DynamicResourceAllocation feature gate.
-
-
- 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:
@@ -7803,6 +8214,21 @@ spec:
storageClassName is the name of the StorageClass required by the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
type: string
+ volumeAttributesClassName:
+ description: |-
+ volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.
+ If specified, the CSI driver will create or update the volume with the attributes defined
+ in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,
+ it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass
+ will be applied to the claim but it's not allowed to reset this field to empty string once it is set.
+ If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass
+ will be set by the persistentvolume controller if it exists.
+ If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
+ set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
+ exists.
+ More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
+ type: string
volumeMode:
description: |-
volumeMode defines what type of volume is required by the claim.
@@ -8208,6 +8634,101 @@ spec:
description: Projection that may be projected along
with other supported volume types
properties:
+ clusterTrustBundle:
+ description: |-
+ ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field
+ of ClusterTrustBundle objects in an auto-updating file.
+
+
+ Alpha, gated by the ClusterTrustBundleProjection feature gate.
+
+
+ ClusterTrustBundle objects can either be selected by name, or by the
+ combination of signer name and a label selector.
+
+
+ Kubelet performs aggressive normalization of the PEM contents written
+ into the pod filesystem. Esoteric PEM features such as inter-block
+ comments and block headers are stripped. Certificates are deduplicated.
+ The ordering of certificates within the file is arbitrary, and Kubelet
+ may change the order over time.
+ properties:
+ labelSelector:
+ description: |-
+ Select all ClusterTrustBundles that match this label selector. Only has
+ effect if signerName is set. Mutually-exclusive with name. If unset,
+ interpreted as "match nothing". If set but empty, interpreted as "match
+ 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
+ name:
+ description: |-
+ Select a single ClusterTrustBundle by object name. Mutually-exclusive
+ with signerName and labelSelector.
+ type: string
+ optional:
+ description: |-
+ If true, don't block pod startup if the referenced ClusterTrustBundle(s)
+ aren't available. If using name, then the named ClusterTrustBundle is
+ allowed not to exist. If using signerName, then the combination of
+ signerName and labelSelector is allowed to match zero
+ ClusterTrustBundles.
+ type: boolean
+ path:
+ description: Relative path from the volume
+ root to write the bundle.
+ type: string
+ signerName:
+ description: |-
+ Select all ClusterTrustBundles that match this signer name.
+ Mutually-exclusive with name. The contents of all selected
+ ClusterTrustBundles will be unified and deduplicated.
+ type: string
+ required:
+ - path
+ type: object
configMap:
description: configMap information about the
configMap data to project
@@ -9031,7 +9552,7 @@ spec:
localhostProfile indicates a profile defined in a file on the node should be used.
The profile must be preconfigured on the node to work.
Must be a descending path, relative to the kubelet's configured seccomp profile location.
- Must only be set if type is "Localhost".
+ Must be set if type is "Localhost". Must NOT be set for any other type.
type: string
type:
description: |-
@@ -9098,12 +9619,9 @@ spec:
hostProcess:
description: |-
HostProcess determines if a container should be run as a 'Host Process' container.
- This field is alpha-level and will only be honored by components that enable the
- WindowsHostProcessContainers feature flag. Setting this field without the feature
- flag will result in errors when validating the Pod. All of a Pod's containers must
- have the same effective HostProcess value (it is not allowed to have a mix of HostProcess
- containers and non-HostProcess containers). In addition, if HostProcess is true
- then HostNetwork must also be set to true.
+ All of a Pod's containers must have the same effective HostProcess value
+ (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).
+ In addition, if HostProcess is true then HostNetwork must also be set to true.
type: boolean
runAsUserName:
description: |-
@@ -9337,10 +9855,9 @@ spec:
This feature depends on whether the underlying cloud-provider supports specifying
the loadBalancerIP when a load balancer is created.
This field will be ignored if the cloud-provider does not support the feature.
- Deprecated: This field was under-specified and its meaning varies across implementations,
- and it cannot support dual-stack.
- As of Kubernetes v1.24, users are encouraged to use implementation-specific annotations when available.
- This field may be removed in a future API version.
+ Deprecated: This field was under-specified and its meaning varies across implementations.
+ Using it is non-portable and it may not support dual-stack.
+ Users are encouraged to use implementation-specific annotations when available.
type: string
loadBalancerSourceRanges:
description: |-
@@ -9362,10 +9879,22 @@ spec:
appProtocol:
description: |-
The application protocol for this port.
+ This is used as a hint for implementations to offer richer behavior for protocols that they understand.
This field follows standard Kubernetes label syntax.
- Un-prefixed names are reserved for IANA standard service names (as per
+ Valid values are either:
+
+
+ * Un-prefixed protocol names - reserved for IANA standard service names (as per
RFC-6335 and https://www.iana.org/assignments/service-names).
- Non-standard protocols should use prefixed names such as
+
+
+ * Kubernetes-defined prefixed names:
+ * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior-
+ * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455
+ * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455
+
+
+ * Other protocols should use implementation-defined prefixed names such as
mycompany.com/my-custom-protocol.
type: string
name:
@@ -9597,6 +10126,15 @@ spec:
IP is set for load-balancer ingress points that are IP based
(typically GCE or OpenStack load-balancers)
type: string
+ ipMode:
+ description: |-
+ IPMode specifies how the load-balancer IP behaves, and may only be specified when the ip field is specified.
+ Setting this to "VIP" indicates that traffic is delivered to the node with
+ the destination set to the load-balancer's IP and port.
+ Setting this to "Proxy" indicates that traffic is delivered to the node or pod with
+ the destination set to the node's IP and node port or the pod's IP and port.
+ Service implementations may use this information to adjust traffic routing.
+ type: string
ports:
description: |-
Ports is a list of records of service ports
@@ -10008,34 +10546,6 @@ spec:
status field of the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
properties:
- claims:
- description: |-
- Claims lists the names of resources, defined in spec.resourceClaims,
- that are used by this container.
-
-
- This is an alpha field and requires enabling the
- DynamicResourceAllocation feature gate.
-
-
- 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:
@@ -10111,6 +10621,21 @@ spec:
storageClassName is the name of the StorageClass required by the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
type: string
+ volumeAttributesClassName:
+ description: |-
+ volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.
+ If specified, the CSI driver will create or update the volume with the attributes defined
+ in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,
+ it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass
+ will be applied to the claim but it's not allowed to reset this field to empty string once it is set.
+ If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass
+ will be set by the persistentvolume controller if it exists.
+ If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
+ set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
+ exists.
+ More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
+ type: string
volumeMode:
description: |-
volumeMode defines what type of volume is required by the claim.
@@ -10134,6 +10659,50 @@ spec:
items:
type: string
type: array
+ allocatedResourceStatuses:
+ additionalProperties:
+ description: |-
+ When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource
+ that it does not recognizes, then it should ignore that update and let other controllers
+ handle it.
+ type: string
+ description: "allocatedResourceStatuses stores status of
+ resource being resized for the given PVC.\nKey names follow
+ standard Kubernetes label syntax. Valid values are either:\n\t*
+ Un-prefixed keys:\n\t\t- storage - the capacity of the
+ volume.\n\t* Custom resources must use implementation-defined
+ prefixed names such as \"example.com/my-custom-resource\"\nApart
+ from above values - keys that are unprefixed or have kubernetes.io
+ prefix are considered\nreserved and hence may not be used.\n\n\nClaimResourceStatus
+ can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState
+ set when resize controller starts resizing the volume
+ in control-plane.\n\t- ControllerResizeFailed:\n\t\tState
+ set when resize has failed in resize controller with a
+ terminal error.\n\t- NodeResizePending:\n\t\tState set
+ when resize controller has finished resizing the volume
+ but further resizing of\n\t\tvolume is needed on the node.\n\t-
+ NodeResizeInProgress:\n\t\tState set when kubelet starts
+ resizing the volume.\n\t- NodeResizeFailed:\n\t\tState
+ set when resizing has failed in kubelet with a terminal
+ error. Transient errors don't set\n\t\tNodeResizeFailed.\nFor
+ example: if expanding a PVC for more capacity - this field
+ can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage']
+ = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"NodeResizeFailed\"\nWhen this field is not set, it
+ means that no resize operation is in progress for the
+ given PVC.\n\n\nA controller that receives PVC update
+ with previously unknown resourceName or ClaimResourceStatus\nshould
+ ignore the update for the purpose it was designed. For
+ example - a controller that\nonly is responsible for resizing
+ capacity of the volume, should ignore PVC updates that
+ change other valid\nresources associated with PVC.\n\n\nThis
+ is an alpha field and requires enabling RecoverVolumeExpansionFailure
+ feature."
+ type: object
+ x-kubernetes-map-type: granular
allocatedResources:
additionalProperties:
anyOf:
@@ -10141,15 +10710,30 @@ spec:
- 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: |-
- allocatedResources is the storage resource within AllocatedResources tracks the capacity allocated to a PVC. It may
- be larger than the actual capacity when a volume expansion operation is requested.
- For storage quota, the larger value from allocatedResources and PVC.spec.resources is used.
- If allocatedResources is not set, PVC.spec.resources alone is used for quota calculation.
- If a volume expansion capacity request is lowered, allocatedResources is only
- lowered if there are no expansion operations in progress and if the actual volume capacity
- is equal or lower than the requested capacity.
- This is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.
+ description: "allocatedResources tracks the resources allocated
+ to a PVC including its capacity.\nKey names follow standard
+ Kubernetes label syntax. Valid values are either:\n\t*
+ Un-prefixed keys:\n\t\t- storage - the capacity of the
+ volume.\n\t* Custom resources must use implementation-defined
+ prefixed names such as \"example.com/my-custom-resource\"\nApart
+ from above values - keys that are unprefixed or have kubernetes.io
+ prefix are considered\nreserved and hence may not be used.\n\n\nCapacity
+ reported here may be larger than the actual capacity when
+ a volume expansion operation\nis requested.\nFor storage
+ quota, the larger value from allocatedResources and PVC.spec.resources
+ is used.\nIf allocatedResources is not set, PVC.spec.resources
+ alone is used for quota calculation.\nIf a volume expansion
+ capacity request is lowered, allocatedResources is only\nlowered
+ if there are no expansion operations in progress and if
+ the actual volume capacity\nis equal or lower than the
+ requested capacity.\n\n\nA controller that receives PVC
+ update with previously unknown resourceName\nshould ignore
+ the update for the purpose it was designed. For example
+ - a controller that\nonly is responsible for resizing
+ capacity of the volume, should ignore PVC updates that
+ change other valid\nresources associated with PVC.\n\n\nThis
+ is an alpha field and requires enabling RecoverVolumeExpansionFailure
+ feature."
type: object
capacity:
additionalProperties:
@@ -10200,15 +10784,42 @@ spec:
- type
type: object
type: array
- phase:
- description: phase represents the current phase of PersistentVolumeClaim.
+ currentVolumeAttributesClassName:
+ description: |-
+ currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using.
+ When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim
+ This is an alpha field and requires enabling VolumeAttributesClass feature.
type: string
- resizeStatus:
+ modifyVolumeStatus:
description: |-
- resizeStatus stores status of resize operation.
- ResizeStatus is not set by default but when expansion is complete resizeStatus is set to empty
- string by resize controller or kubelet.
- This is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.
+ ModifyVolumeStatus represents the status object of ControllerModifyVolume operation.
+ When this is unset, there is no ModifyVolume operation being attempted.
+ This is an alpha field and requires enabling VolumeAttributesClass feature.
+ properties:
+ status:
+ description: "status is the status of the ControllerModifyVolume
+ operation. It can be in any of following states:\n
+ - Pending\n Pending indicates that the PersistentVolumeClaim
+ cannot be modified due to unmet requirements, such
+ as\n the specified VolumeAttributesClass not existing.\n
+ - InProgress\n InProgress indicates that the volume
+ is being modified.\n - Infeasible\n Infeasible indicates
+ that the request has been rejected as invalid by the
+ CSI driver. To\n\t resolve the error, a valid VolumeAttributesClass
+ needs to be specified.\nNote: New statuses can be
+ added in the future. Consumers should check for unknown
+ statuses and fail appropriately."
+ type: string
+ targetVolumeAttributesClassName:
+ description: targetVolumeAttributesClassName is the
+ name of the VolumeAttributesClass the PVC currently
+ being reconciled
+ type: string
+ required:
+ - status
+ type: object
+ phase:
+ description: phase represents the current phase of PersistentVolumeClaim.
type: string
type: object
type: object
@@ -10845,34 +11456,6 @@ spec:
status field of the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
properties:
- claims:
- description: |-
- Claims lists the names of resources, defined in spec.resourceClaims,
- that are used by this container.
-
-
- This is an alpha field and requires enabling the
- DynamicResourceAllocation feature gate.
-
-
- 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:
@@ -10949,6 +11532,21 @@ spec:
storageClassName is the name of the StorageClass required by the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
type: string
+ volumeAttributesClassName:
+ description: |-
+ volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.
+ If specified, the CSI driver will create or update the volume with the attributes defined
+ in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,
+ it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass
+ will be applied to the claim but it's not allowed to reset this field to empty string once it is set.
+ If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass
+ will be set by the persistentvolume controller if it exists.
+ If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
+ set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
+ exists.
+ More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
+ type: string
volumeMode:
description: |-
volumeMode defines what type of volume is required by the claim.
@@ -11352,6 +11950,100 @@ spec:
description: Projection that may be projected along with
other supported volume types
properties:
+ clusterTrustBundle:
+ description: |-
+ ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field
+ of ClusterTrustBundle objects in an auto-updating file.
+
+
+ Alpha, gated by the ClusterTrustBundleProjection feature gate.
+
+
+ ClusterTrustBundle objects can either be selected by name, or by the
+ combination of signer name and a label selector.
+
+
+ Kubelet performs aggressive normalization of the PEM contents written
+ into the pod filesystem. Esoteric PEM features such as inter-block
+ comments and block headers are stripped. Certificates are deduplicated.
+ The ordering of certificates within the file is arbitrary, and Kubelet
+ may change the order over time.
+ properties:
+ labelSelector:
+ description: |-
+ Select all ClusterTrustBundles that match this label selector. Only has
+ effect if signerName is set. Mutually-exclusive with name. If unset,
+ interpreted as "match nothing". If set but empty, interpreted as "match
+ 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
+ name:
+ description: |-
+ Select a single ClusterTrustBundle by object name. Mutually-exclusive
+ with signerName and labelSelector.
+ type: string
+ optional:
+ description: |-
+ If true, don't block pod startup if the referenced ClusterTrustBundle(s)
+ aren't available. If using name, then the named ClusterTrustBundle is
+ allowed not to exist. If using signerName, then the combination of
+ signerName and labelSelector is allowed to match zero
+ ClusterTrustBundles.
+ type: boolean
+ path:
+ description: Relative path from the volume root
+ to write the bundle.
+ type: string
+ signerName:
+ description: |-
+ Select all ClusterTrustBundles that match this signer name.
+ Mutually-exclusive with name. The contents of all selected
+ ClusterTrustBundles will be unified and deduplicated.
+ type: string
+ required:
+ - path
+ type: object
configMap:
description: configMap information about the configMap
data to project
diff --git a/config/crd/bases/druid.apache.org_druids.yaml b/config/crd/bases/druid.apache.org_druids.yaml
index d14ed98..66efdf3 100644
--- a/config/crd/bases/druid.apache.org_druids.yaml
+++ b/config/crd/bases/druid.apache.org_druids.yaml
@@ -403,7 +403,7 @@ spec:
localhostProfile indicates a profile defined in a file on the node should be used.
The profile must be preconfigured on the node to work.
Must be a descending path, relative to the kubelet's configured seccomp profile location.
- Must only be set if type is "Localhost".
+ Must be set if type is "Localhost". Must NOT be set for any other type.
type: string
type:
description: |-
@@ -438,12 +438,9 @@ spec:
hostProcess:
description: |-
HostProcess determines if a container should be run as a 'Host Process' container.
- This field is alpha-level and will only be honored by components that enable the
- WindowsHostProcessContainers feature flag. Setting this field without the feature
- flag will result in errors when validating the Pod. All of a Pod's containers must
- have the same effective HostProcess value (it is not allowed to have a mix of HostProcess
- containers and non-HostProcess containers). In addition, if HostProcess is true
- then HostNetwork must also be set to true.
+ All of a Pod's containers must have the same effective HostProcess value
+ (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).
+ In addition, if HostProcess is true then HostNetwork must also be set to true.
type: boolean
runAsUserName:
description: |-
@@ -719,8 +716,9 @@ spec:
with the corresponding weight.
properties:
labelSelector:
- description: A label query over a set of resources,
- in this case pods.
+ description: |-
+ A label query over a set of resources, in this case pods.
+ If it's null, this PodAffinityTerm matches with no Pods.
properties:
matchExpressions:
description: matchExpressions is a list of label
@@ -764,6 +762,36 @@ spec:
type: object
type: object
x-kubernetes-map-type: atomic
+ matchLabelKeys:
+ description: |-
+ MatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MatchLabelKeys and LabelSelector.
+ Also, MatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
+ mismatchLabelKeys:
+ description: |-
+ MismatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector.
+ Also, MismatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
namespaceSelector:
description: |-
A label query over the set of namespaces that the term applies to.
@@ -864,8 +892,9 @@ spec:
a pod of the set of pods is running
properties:
labelSelector:
- description: A label query over a set of resources,
- in this case pods.
+ description: |-
+ A label query over a set of resources, in this case pods.
+ If it's null, this PodAffinityTerm matches with no Pods.
properties:
matchExpressions:
description: matchExpressions is a list of label
@@ -908,6 +937,36 @@ spec:
type: object
type: object
x-kubernetes-map-type: atomic
+ matchLabelKeys:
+ description: |-
+ MatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MatchLabelKeys and LabelSelector.
+ Also, MatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
+ mismatchLabelKeys:
+ description: |-
+ MismatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector.
+ Also, MismatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
namespaceSelector:
description: |-
A label query over the set of namespaces that the term applies to.
@@ -1004,8 +1063,9 @@ spec:
with the corresponding weight.
properties:
labelSelector:
- description: A label query over a set of resources,
- in this case pods.
+ description: |-
+ A label query over a set of resources, in this case pods.
+ If it's null, this PodAffinityTerm matches with no Pods.
properties:
matchExpressions:
description: matchExpressions is a list of label
@@ -1049,6 +1109,36 @@ spec:
type: object
type: object
x-kubernetes-map-type: atomic
+ matchLabelKeys:
+ description: |-
+ MatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MatchLabelKeys and LabelSelector.
+ Also, MatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
+ mismatchLabelKeys:
+ description: |-
+ MismatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector.
+ Also, MismatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
namespaceSelector:
description: |-
A label query over the set of namespaces that the term applies to.
@@ -1149,8 +1239,9 @@ spec:
a pod of the set of pods is running
properties:
labelSelector:
- description: A label query over a set of resources,
- in this case pods.
+ description: |-
+ A label query over a set of resources, in this case pods.
+ If it's null, this PodAffinityTerm matches with no Pods.
properties:
matchExpressions:
description: matchExpressions is a list of label
@@ -1193,6 +1284,36 @@ spec:
type: object
type: object
x-kubernetes-map-type: atomic
+ matchLabelKeys:
+ description: |-
+ MatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MatchLabelKeys and LabelSelector.
+ Also, MatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
+ mismatchLabelKeys:
+ description: |-
+ MismatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector.
+ Also, MismatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
namespaceSelector:
description: |-
A label query over the set of namespaces that the term applies to.
@@ -1414,7 +1535,7 @@ spec:
localhostProfile indicates a profile defined in a file on the node should be used.
The profile must be preconfigured on the node to work.
Must be a descending path, relative to the kubelet's configured seccomp profile location.
- Must only be set if type is "Localhost".
+ Must be set if type is "Localhost". Must NOT be set for any other type.
type: string
type:
description: |-
@@ -1449,12 +1570,9 @@ spec:
hostProcess:
description: |-
HostProcess determines if a container should be run as a 'Host Process' container.
- This field is alpha-level and will only be honored by components that enable the
- WindowsHostProcessContainers feature flag. Setting this field without the feature
- flag will result in errors when validating the Pod. All of a Pod's containers must
- have the same effective HostProcess value (it is not allowed to have a mix of HostProcess
- containers and non-HostProcess containers). In addition, if HostProcess is true
- then HostNetwork must also be set to true.
+ All of a Pod's containers must have the same effective HostProcess value
+ (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).
+ In addition, if HostProcess is true then HostNetwork must also be set to true.
type: boolean
runAsUserName:
description: |-
@@ -1499,8 +1617,8 @@ spec:
disablePVCAnnotationUpdate:
default: false
description: |-
- DisablePVCAnnotationUpdate When set to true, operator will not patch PVC annotations when VolumeClaimTemplate annotations are updated.
- When disabled (false), updating VolumeClaimTemplate annotations will patch existing PVCs and recreate the StatefulSet.
+ DisablePVCUpdates When set to true, operator will not patch PVCs when VolumeClaimTemplate annotations or volumeAttributeClassName are updated.
+ When disabled (false), updating VolumeClaimTemplate annotations or volumeAttributeClassName will patch existing PVCs and recreate the StatefulSet.
type: boolean
disablePVCDeletionFinalizer:
default: false
@@ -2332,7 +2450,7 @@ spec:
localhostProfile indicates a profile defined in a file on the node should be used.
The profile must be preconfigured on the node to work.
Must be a descending path, relative to the kubelet's configured seccomp profile location.
- Must only be set if type is "Localhost".
+ Must be set if type is "Localhost". Must NOT be set for any other type.
type: string
type:
description: |-
@@ -2367,12 +2485,9 @@ spec:
hostProcess:
description: |-
HostProcess determines if a container should be run as a 'Host Process' container.
- This field is alpha-level and will only be honored by components that enable the
- WindowsHostProcessContainers feature flag. Setting this field without the feature
- flag will result in errors when validating the Pod. All of a Pod's containers must
- have the same effective HostProcess value (it is not allowed to have a mix of HostProcess
- containers and non-HostProcess containers). In addition, if HostProcess is true
- then HostNetwork must also be set to true.
+ All of a Pod's containers must have the same effective HostProcess value
+ (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).
+ In addition, if HostProcess is true then HostNetwork must also be set to true.
type: boolean
runAsUserName:
description: |-
@@ -2652,8 +2767,9 @@ spec:
with the corresponding weight.
properties:
labelSelector:
- description: A label query over a set of resources,
- in this case pods.
+ description: |-
+ A label query over a set of resources, in this case pods.
+ If it's null, this PodAffinityTerm matches with no Pods.
properties:
matchExpressions:
description: matchExpressions is a list
@@ -2697,6 +2813,36 @@ spec:
type: object
type: object
x-kubernetes-map-type: atomic
+ matchLabelKeys:
+ description: |-
+ MatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MatchLabelKeys and LabelSelector.
+ Also, MatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
+ mismatchLabelKeys:
+ description: |-
+ MismatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector.
+ Also, MismatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
namespaceSelector:
description: |-
A label query over the set of namespaces that the term applies to.
@@ -2797,8 +2943,9 @@ spec:
a pod of the set of pods is running
properties:
labelSelector:
- description: A label query over a set of resources,
- in this case pods.
+ description: |-
+ A label query over a set of resources, in this case pods.
+ If it's null, this PodAffinityTerm matches with no Pods.
properties:
matchExpressions:
description: matchExpressions is a list of
@@ -2842,6 +2989,36 @@ spec:
type: object
type: object
x-kubernetes-map-type: atomic
+ matchLabelKeys:
+ description: |-
+ MatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MatchLabelKeys and LabelSelector.
+ Also, MatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
+ mismatchLabelKeys:
+ description: |-
+ MismatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector.
+ Also, MismatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
namespaceSelector:
description: |-
A label query over the set of namespaces that the term applies to.
@@ -2940,8 +3117,9 @@ spec:
with the corresponding weight.
properties:
labelSelector:
- description: A label query over a set of resources,
- in this case pods.
+ description: |-
+ A label query over a set of resources, in this case pods.
+ If it's null, this PodAffinityTerm matches with no Pods.
properties:
matchExpressions:
description: matchExpressions is a list
@@ -2985,6 +3163,36 @@ spec:
type: object
type: object
x-kubernetes-map-type: atomic
+ matchLabelKeys:
+ description: |-
+ MatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MatchLabelKeys and LabelSelector.
+ Also, MatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
+ mismatchLabelKeys:
+ description: |-
+ MismatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector.
+ Also, MismatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
namespaceSelector:
description: |-
A label query over the set of namespaces that the term applies to.
@@ -3085,8 +3293,9 @@ spec:
a pod of the set of pods is running
properties:
labelSelector:
- description: A label query over a set of resources,
- in this case pods.
+ description: |-
+ A label query over a set of resources, in this case pods.
+ If it's null, this PodAffinityTerm matches with no Pods.
properties:
matchExpressions:
description: matchExpressions is a list of
@@ -3130,6 +3339,36 @@ spec:
type: object
type: object
x-kubernetes-map-type: atomic
+ matchLabelKeys:
+ description: |-
+ MatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MatchLabelKeys and LabelSelector.
+ Also, MatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
+ mismatchLabelKeys:
+ description: |-
+ MismatchLabelKeys is a set of pod label keys to select which pods will
+ be taken into consideration. The keys are used to lookup values from the
+ incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)`
+ to select the group of existing pods which pods will be taken into consideration
+ for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming
+ pod labels will be ignored. The default value is empty.
+ The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector.
+ Also, MismatchLabelKeys cannot be set when LabelSelector isn't set.
+ This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
namespaceSelector:
description: |-
A label query over the set of namespaces that the term applies to.
@@ -3322,7 +3561,7 @@ spec:
localhostProfile indicates a profile defined in a file on the node should be used.
The profile must be preconfigured on the node to work.
Must be a descending path, relative to the kubelet's configured seccomp profile location.
- Must only be set if type is "Localhost".
+ Must be set if type is "Localhost". Must NOT be set for any other type.
type: string
type:
description: |-
@@ -3357,12 +3596,9 @@ spec:
hostProcess:
description: |-
HostProcess determines if a container should be run as a 'Host Process' container.
- This field is alpha-level and will only be honored by components that enable the
- WindowsHostProcessContainers feature flag. Setting this field without the feature
- flag will result in errors when validating the Pod. All of a Pod's containers must
- have the same effective HostProcess value (it is not allowed to have a mix of HostProcess
- containers and non-HostProcess containers). In addition, if HostProcess is true
- then HostNetwork must also be set to true.
+ All of a Pod's containers must have the same effective HostProcess value
+ (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).
+ In addition, if HostProcess is true then HostNetwork must also be set to true.
type: boolean
runAsUserName:
description: |-
@@ -4553,6 +4789,18 @@ spec:
required:
- port
type: object
+ sleep:
+ description: Sleep represents the duration that the
+ container should sleep before being terminated.
+ properties:
+ seconds:
+ description: Seconds is the number of seconds to
+ sleep.
+ format: int64
+ type: integer
+ required:
+ - seconds
+ type: object
tcpSocket:
description: |-
Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept
@@ -4650,6 +4898,18 @@ spec:
required:
- port
type: object
+ sleep:
+ description: Sleep represents the duration that the
+ container should sleep before being terminated.
+ properties:
+ seconds:
+ description: Seconds is the number of seconds to
+ sleep.
+ format: int64
+ type: integer
+ required:
+ - seconds
+ type: object
tcpSocket:
description: |-
Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept
@@ -5005,34 +5265,6 @@ spec:
status field of the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
properties:
- claims:
- description: |-
- Claims lists the names of resources, defined in spec.resourceClaims,
- that are used by this container.
-
-
- This is an alpha field and requires enabling the
- DynamicResourceAllocation feature gate.
-
-
- 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:
@@ -5109,6 +5341,21 @@ spec:
storageClassName is the name of the StorageClass required by the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
type: string
+ volumeAttributesClassName:
+ description: |-
+ volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.
+ If specified, the CSI driver will create or update the volume with the attributes defined
+ in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,
+ it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass
+ will be applied to the claim but it's not allowed to reset this field to empty string once it is set.
+ If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass
+ will be set by the persistentvolume controller if it exists.
+ If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
+ set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
+ exists.
+ More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
+ type: string
volumeMode:
description: |-
volumeMode defines what type of volume is required by the claim.
@@ -5132,6 +5379,54 @@ spec:
items:
type: string
type: array
+ allocatedResourceStatuses:
+ additionalProperties:
+ description: |-
+ When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource
+ that it does not recognizes, then it should ignore that update and let other controllers
+ handle it.
+ type: string
+ description: "allocatedResourceStatuses stores status
+ of resource being resized for the given PVC.\nKey
+ names follow standard Kubernetes label syntax. Valid
+ values are either:\n\t* Un-prefixed keys:\n\t\t-
+ storage - the capacity of the volume.\n\t* Custom
+ resources must use implementation-defined prefixed
+ names such as \"example.com/my-custom-resource\"\nApart
+ from above values - keys that are unprefixed or
+ have kubernetes.io prefix are considered\nreserved
+ and hence may not be used.\n\n\nClaimResourceStatus
+ can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState
+ set when resize controller starts resizing the volume
+ in control-plane.\n\t- ControllerResizeFailed:\n\t\tState
+ set when resize has failed in resize controller
+ with a terminal error.\n\t- NodeResizePending:\n\t\tState
+ set when resize controller has finished resizing
+ the volume but further resizing of\n\t\tvolume is
+ needed on the node.\n\t- NodeResizeInProgress:\n\t\tState
+ set when kubelet starts resizing the volume.\n\t-
+ NodeResizeFailed:\n\t\tState set when resizing has
+ failed in kubelet with a terminal error. Transient
+ errors don't set\n\t\tNodeResizeFailed.\nFor example:
+ if expanding a PVC for more capacity - this field
+ can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage']
+ = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"NodeResizeFailed\"\nWhen this field is not set,
+ it means that no resize operation is in progress
+ for the given PVC.\n\n\nA controller that receives
+ PVC update with previously unknown resourceName
+ or ClaimResourceStatus\nshould ignore the update
+ for the purpose it was designed. For example - a
+ controller that\nonly is responsible for resizing
+ capacity of the volume, should ignore PVC updates
+ that change other valid\nresources associated with
+ PVC.\n\n\nThis is an alpha field and requires enabling
+ RecoverVolumeExpansionFailure feature."
+ type: object
+ x-kubernetes-map-type: granular
allocatedResources:
additionalProperties:
anyOf:
@@ -5139,15 +5434,33 @@ spec:
- 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: |-
- allocatedResources is the storage resource within AllocatedResources tracks the capacity allocated to a PVC. It may
- be larger than the actual capacity when a volume expansion operation is requested.
- For storage quota, the larger value from allocatedResources and PVC.spec.resources is used.
- If allocatedResources is not set, PVC.spec.resources alone is used for quota calculation.
- If a volume expansion capacity request is lowered, allocatedResources is only
- lowered if there are no expansion operations in progress and if the actual volume capacity
- is equal or lower than the requested capacity.
- This is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.
+ description: "allocatedResources tracks the resources
+ allocated to a PVC including its capacity.\nKey
+ names follow standard Kubernetes label syntax. Valid
+ values are either:\n\t* Un-prefixed keys:\n\t\t-
+ storage - the capacity of the volume.\n\t* Custom
+ resources must use implementation-defined prefixed
+ names such as \"example.com/my-custom-resource\"\nApart
+ from above values - keys that are unprefixed or
+ have kubernetes.io prefix are considered\nreserved
+ and hence may not be used.\n\n\nCapacity reported
+ here may be larger than the actual capacity when
+ a volume expansion operation\nis requested.\nFor
+ storage quota, the larger value from allocatedResources
+ and PVC.spec.resources is used.\nIf allocatedResources
+ is not set, PVC.spec.resources alone is used for
+ quota calculation.\nIf a volume expansion capacity
+ request is lowered, allocatedResources is only\nlowered
+ if there are no expansion operations in progress
+ and if the actual volume capacity\nis equal or lower
+ than the requested capacity.\n\n\nA controller that
+ receives PVC update with previously unknown resourceName\nshould
+ ignore the update for the purpose it was designed.
+ For example - a controller that\nonly is responsible
+ for resizing capacity of the volume, should ignore
+ PVC updates that change other valid\nresources associated
+ with PVC.\n\n\nThis is an alpha field and requires
+ enabling RecoverVolumeExpansionFailure feature."
type: object
capacity:
additionalProperties:
@@ -5199,17 +5512,45 @@ spec:
- type
type: object
type: array
+ currentVolumeAttributesClassName:
+ description: |-
+ currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using.
+ When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim
+ This is an alpha field and requires enabling VolumeAttributesClass feature.
+ type: string
+ modifyVolumeStatus:
+ description: |-
+ ModifyVolumeStatus represents the status object of ControllerModifyVolume operation.
+ When this is unset, there is no ModifyVolume operation being attempted.
+ This is an alpha field and requires enabling VolumeAttributesClass feature.
+ properties:
+ status:
+ description: "status is the status of the ControllerModifyVolume
+ operation. It can be in any of following states:\n
+ - Pending\n Pending indicates that the PersistentVolumeClaim
+ cannot be modified due to unmet requirements,
+ such as\n the specified VolumeAttributesClass
+ not existing.\n - InProgress\n InProgress
+ indicates that the volume is being modified.\n
+ - Infeasible\n Infeasible indicates that the
+ request has been rejected as invalid by the
+ CSI driver. To\n\t resolve the error, a valid
+ VolumeAttributesClass needs to be specified.\nNote:
+ New statuses can be added in the future. Consumers
+ should check for unknown statuses and fail appropriately."
+ type: string
+ targetVolumeAttributesClassName:
+ description: targetVolumeAttributesClassName is
+ the name of the VolumeAttributesClass the PVC
+ currently being reconciled
+ type: string
+ required:
+ - status
+ type: object
phase:
description: phase represents the current phase of
PersistentVolumeClaim.
type: string
- resizeStatus:
- description: |-
- resizeStatus stores status of resize operation.
- ResizeStatus is not set by default but when expansion is complete resizeStatus is set to empty
- string by resize controller or kubelet.
- This is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.
- type: string
type: object
type: object
type: array
@@ -5689,7 +6030,7 @@ spec:
localhostProfile indicates a profile defined in a file on the node should be used.
The profile must be preconfigured on the node to work.
Must be a descending path, relative to the kubelet's configured seccomp profile location.
- Must only be set if type is "Localhost".
+ Must be set if type is "Localhost". Must NOT be set for any other type.
type: string
type:
description: |-
@@ -5756,12 +6097,9 @@ spec:
hostProcess:
description: |-
HostProcess determines if a container should be run as a 'Host Process' container.
- This field is alpha-level and will only be honored by components that enable the
- WindowsHostProcessContainers feature flag. Setting this field without the feature
- flag will result in errors when validating the Pod. All of a Pod's containers must
- have the same effective HostProcess value (it is not allowed to have a mix of HostProcess
- containers and non-HostProcess containers). In addition, if HostProcess is true
- then HostNetwork must also be set to true.
+ All of a Pod's containers must have the same effective HostProcess value
+ (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).
+ In addition, if HostProcess is true then HostNetwork must also be set to true.
type: boolean
runAsUserName:
description: |-
@@ -5996,10 +6334,9 @@ spec:
This feature depends on whether the underlying cloud-provider supports specifying
the loadBalancerIP when a load balancer is created.
This field will be ignored if the cloud-provider does not support the feature.
- Deprecated: This field was under-specified and its meaning varies across implementations,
- and it cannot support dual-stack.
- As of Kubernetes v1.24, users are encouraged to use implementation-specific annotations when available.
- This field may be removed in a future API version.
+ Deprecated: This field was under-specified and its meaning varies across implementations.
+ Using it is non-portable and it may not support dual-stack.
+ Users are encouraged to use implementation-specific annotations when available.
type: string
loadBalancerSourceRanges:
description: |-
@@ -6021,10 +6358,22 @@ spec:
appProtocol:
description: |-
The application protocol for this port.
+ This is used as a hint for implementations to offer richer behavior for protocols that they understand.
This field follows standard Kubernetes label syntax.
- Un-prefixed names are reserved for IANA standard service names (as per
+ Valid values are either:
+
+
+ * Un-prefixed protocol names - reserved for IANA standard service names (as per
RFC-6335 and https://www.iana.org/assignments/service-names).
- Non-standard protocols should use prefixed names such as
+
+
+ * Kubernetes-defined prefixed names:
+ * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior-
+ * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455
+ * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455
+
+
+ * Other protocols should use implementation-defined prefixed names such as
mycompany.com/my-custom-protocol.
type: string
name:
@@ -6257,6 +6606,15 @@ spec:
IP is set for load-balancer ingress points that are IP based
(typically GCE or OpenStack load-balancers)
type: string
+ ipMode:
+ description: |-
+ IPMode specifies how the load-balancer IP behaves, and may only be specified when the ip field is specified.
+ Setting this to "VIP" indicates that traffic is delivered to the node with
+ the destination set to the load-balancer's IP and port.
+ Setting this to "Proxy" indicates that traffic is delivered to the node or pod with
+ the destination set to the node's IP and node port or the pod's IP and port.
+ Service implementations may use this information to adjust traffic routing.
+ type: string
ports:
description: |-
Ports is a list of records of service ports
@@ -6854,34 +7212,6 @@ spec:
status field of the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
properties:
- claims:
- description: |-
- Claims lists the names of resources, defined in spec.resourceClaims,
- that are used by this container.
-
-
- This is an alpha field and requires enabling the
- DynamicResourceAllocation feature gate.
-
-
- 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:
@@ -6958,6 +7288,21 @@ spec:
storageClassName is the name of the StorageClass required by the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
type: string
+ volumeAttributesClassName:
+ description: |-
+ volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.
+ If specified, the CSI driver will create or update the volume with the attributes defined
+ in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,
+ it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass
+ will be applied to the claim but it's not allowed to reset this field to empty string once it is set.
+ If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass
+ will be set by the persistentvolume controller if it exists.
+ If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
+ set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
+ exists.
+ More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
+ type: string
volumeMode:
description: |-
volumeMode defines what type of volume is required by the claim.
@@ -6981,6 +7326,54 @@ spec:
items:
type: string
type: array
+ allocatedResourceStatuses:
+ additionalProperties:
+ description: |-
+ When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource
+ that it does not recognizes, then it should ignore that update and let other controllers
+ handle it.
+ type: string
+ description: "allocatedResourceStatuses stores status
+ of resource being resized for the given PVC.\nKey
+ names follow standard Kubernetes label syntax. Valid
+ values are either:\n\t* Un-prefixed keys:\n\t\t-
+ storage - the capacity of the volume.\n\t* Custom
+ resources must use implementation-defined prefixed
+ names such as \"example.com/my-custom-resource\"\nApart
+ from above values - keys that are unprefixed or
+ have kubernetes.io prefix are considered\nreserved
+ and hence may not be used.\n\n\nClaimResourceStatus
+ can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState
+ set when resize controller starts resizing the volume
+ in control-plane.\n\t- ControllerResizeFailed:\n\t\tState
+ set when resize has failed in resize controller
+ with a terminal error.\n\t- NodeResizePending:\n\t\tState
+ set when resize controller has finished resizing
+ the volume but further resizing of\n\t\tvolume is
+ needed on the node.\n\t- NodeResizeInProgress:\n\t\tState
+ set when kubelet starts resizing the volume.\n\t-
+ NodeResizeFailed:\n\t\tState set when resizing has
+ failed in kubelet with a terminal error. Transient
+ errors don't set\n\t\tNodeResizeFailed.\nFor example:
+ if expanding a PVC for more capacity - this field
+ can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage']
+ = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"NodeResizeFailed\"\nWhen this field is not set,
+ it means that no resize operation is in progress
+ for the given PVC.\n\n\nA controller that receives
+ PVC update with previously unknown resourceName
+ or ClaimResourceStatus\nshould ignore the update
+ for the purpose it was designed. For example - a
+ controller that\nonly is responsible for resizing
+ capacity of the volume, should ignore PVC updates
+ that change other valid\nresources associated with
+ PVC.\n\n\nThis is an alpha field and requires enabling
+ RecoverVolumeExpansionFailure feature."
+ type: object
+ x-kubernetes-map-type: granular
allocatedResources:
additionalProperties:
anyOf:
@@ -6988,15 +7381,33 @@ spec:
- 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: |-
- allocatedResources is the storage resource within AllocatedResources tracks the capacity allocated to a PVC. It may
- be larger than the actual capacity when a volume expansion operation is requested.
- For storage quota, the larger value from allocatedResources and PVC.spec.resources is used.
- If allocatedResources is not set, PVC.spec.resources alone is used for quota calculation.
- If a volume expansion capacity request is lowered, allocatedResources is only
- lowered if there are no expansion operations in progress and if the actual volume capacity
- is equal or lower than the requested capacity.
- This is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.
+ description: "allocatedResources tracks the resources
+ allocated to a PVC including its capacity.\nKey
+ names follow standard Kubernetes label syntax. Valid
+ values are either:\n\t* Un-prefixed keys:\n\t\t-
+ storage - the capacity of the volume.\n\t* Custom
+ resources must use implementation-defined prefixed
+ names such as \"example.com/my-custom-resource\"\nApart
+ from above values - keys that are unprefixed or
+ have kubernetes.io prefix are considered\nreserved
+ and hence may not be used.\n\n\nCapacity reported
+ here may be larger than the actual capacity when
+ a volume expansion operation\nis requested.\nFor
+ storage quota, the larger value from allocatedResources
+ and PVC.spec.resources is used.\nIf allocatedResources
+ is not set, PVC.spec.resources alone is used for
+ quota calculation.\nIf a volume expansion capacity
+ request is lowered, allocatedResources is only\nlowered
+ if there are no expansion operations in progress
+ and if the actual volume capacity\nis equal or lower
+ than the requested capacity.\n\n\nA controller that
+ receives PVC update with previously unknown resourceName\nshould
+ ignore the update for the purpose it was designed.
+ For example - a controller that\nonly is responsible
+ for resizing capacity of the volume, should ignore
+ PVC updates that change other valid\nresources associated
+ with PVC.\n\n\nThis is an alpha field and requires
+ enabling RecoverVolumeExpansionFailure feature."
type: object
capacity:
additionalProperties:
@@ -7048,17 +7459,45 @@ spec:
- type
type: object
type: array
+ currentVolumeAttributesClassName:
+ description: |-
+ currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using.
+ When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim
+ This is an alpha field and requires enabling VolumeAttributesClass feature.
+ type: string
+ modifyVolumeStatus:
+ description: |-
+ ModifyVolumeStatus represents the status object of ControllerModifyVolume operation.
+ When this is unset, there is no ModifyVolume operation being attempted.
+ This is an alpha field and requires enabling VolumeAttributesClass feature.
+ properties:
+ status:
+ description: "status is the status of the ControllerModifyVolume
+ operation. It can be in any of following states:\n
+ - Pending\n Pending indicates that the PersistentVolumeClaim
+ cannot be modified due to unmet requirements,
+ such as\n the specified VolumeAttributesClass
+ not existing.\n - InProgress\n InProgress
+ indicates that the volume is being modified.\n
+ - Infeasible\n Infeasible indicates that the
+ request has been rejected as invalid by the
+ CSI driver. To\n\t resolve the error, a valid
+ VolumeAttributesClass needs to be specified.\nNote:
+ New statuses can be added in the future. Consumers
+ should check for unknown statuses and fail appropriately."
+ type: string
+ targetVolumeAttributesClassName:
+ description: targetVolumeAttributesClassName is
+ the name of the VolumeAttributesClass the PVC
+ currently being reconciled
+ type: string
+ required:
+ - status
+ type: object
phase:
description: phase represents the current phase of
PersistentVolumeClaim.
type: string
- resizeStatus:
- description: |-
- resizeStatus stores status of resize operation.
- ResizeStatus is not set by default but when expansion is complete resizeStatus is set to empty
- string by resize controller or kubelet.
- This is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.
- type: string
type: object
type: object
type: array
@@ -7699,34 +8138,6 @@ spec:
status field of the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
properties:
- claims:
- description: |-
- Claims lists the names of resources, defined in spec.resourceClaims,
- that are used by this container.
-
-
- This is an alpha field and requires enabling the
- DynamicResourceAllocation feature gate.
-
-
- 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:
@@ -7803,6 +8214,21 @@ spec:
storageClassName is the name of the StorageClass required by the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
type: string
+ volumeAttributesClassName:
+ description: |-
+ volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.
+ If specified, the CSI driver will create or update the volume with the attributes defined
+ in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,
+ it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass
+ will be applied to the claim but it's not allowed to reset this field to empty string once it is set.
+ If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass
+ will be set by the persistentvolume controller if it exists.
+ If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
+ set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
+ exists.
+ More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
+ type: string
volumeMode:
description: |-
volumeMode defines what type of volume is required by the claim.
@@ -8208,6 +8634,101 @@ spec:
description: Projection that may be projected along
with other supported volume types
properties:
+ clusterTrustBundle:
+ description: |-
+ ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field
+ of ClusterTrustBundle objects in an auto-updating file.
+
+
+ Alpha, gated by the ClusterTrustBundleProjection feature gate.
+
+
+ ClusterTrustBundle objects can either be selected by name, or by the
+ combination of signer name and a label selector.
+
+
+ Kubelet performs aggressive normalization of the PEM contents written
+ into the pod filesystem. Esoteric PEM features such as inter-block
+ comments and block headers are stripped. Certificates are deduplicated.
+ The ordering of certificates within the file is arbitrary, and Kubelet
+ may change the order over time.
+ properties:
+ labelSelector:
+ description: |-
+ Select all ClusterTrustBundles that match this label selector. Only has
+ effect if signerName is set. Mutually-exclusive with name. If unset,
+ interpreted as "match nothing". If set but empty, interpreted as "match
+ 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
+ name:
+ description: |-
+ Select a single ClusterTrustBundle by object name. Mutually-exclusive
+ with signerName and labelSelector.
+ type: string
+ optional:
+ description: |-
+ If true, don't block pod startup if the referenced ClusterTrustBundle(s)
+ aren't available. If using name, then the named ClusterTrustBundle is
+ allowed not to exist. If using signerName, then the combination of
+ signerName and labelSelector is allowed to match zero
+ ClusterTrustBundles.
+ type: boolean
+ path:
+ description: Relative path from the volume
+ root to write the bundle.
+ type: string
+ signerName:
+ description: |-
+ Select all ClusterTrustBundles that match this signer name.
+ Mutually-exclusive with name. The contents of all selected
+ ClusterTrustBundles will be unified and deduplicated.
+ type: string
+ required:
+ - path
+ type: object
configMap:
description: configMap information about the
configMap data to project
@@ -9031,7 +9552,7 @@ spec:
localhostProfile indicates a profile defined in a file on the node should be used.
The profile must be preconfigured on the node to work.
Must be a descending path, relative to the kubelet's configured seccomp profile location.
- Must only be set if type is "Localhost".
+ Must be set if type is "Localhost". Must NOT be set for any other type.
type: string
type:
description: |-
@@ -9098,12 +9619,9 @@ spec:
hostProcess:
description: |-
HostProcess determines if a container should be run as a 'Host Process' container.
- This field is alpha-level and will only be honored by components that enable the
- WindowsHostProcessContainers feature flag. Setting this field without the feature
- flag will result in errors when validating the Pod. All of a Pod's containers must
- have the same effective HostProcess value (it is not allowed to have a mix of HostProcess
- containers and non-HostProcess containers). In addition, if HostProcess is true
- then HostNetwork must also be set to true.
+ All of a Pod's containers must have the same effective HostProcess value
+ (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).
+ In addition, if HostProcess is true then HostNetwork must also be set to true.
type: boolean
runAsUserName:
description: |-
@@ -9337,10 +9855,9 @@ spec:
This feature depends on whether the underlying cloud-provider supports specifying
the loadBalancerIP when a load balancer is created.
This field will be ignored if the cloud-provider does not support the feature.
- Deprecated: This field was under-specified and its meaning varies across implementations,
- and it cannot support dual-stack.
- As of Kubernetes v1.24, users are encouraged to use implementation-specific annotations when available.
- This field may be removed in a future API version.
+ Deprecated: This field was under-specified and its meaning varies across implementations.
+ Using it is non-portable and it may not support dual-stack.
+ Users are encouraged to use implementation-specific annotations when available.
type: string
loadBalancerSourceRanges:
description: |-
@@ -9362,10 +9879,22 @@ spec:
appProtocol:
description: |-
The application protocol for this port.
+ This is used as a hint for implementations to offer richer behavior for protocols that they understand.
This field follows standard Kubernetes label syntax.
- Un-prefixed names are reserved for IANA standard service names (as per
+ Valid values are either:
+
+
+ * Un-prefixed protocol names - reserved for IANA standard service names (as per
RFC-6335 and https://www.iana.org/assignments/service-names).
- Non-standard protocols should use prefixed names such as
+
+
+ * Kubernetes-defined prefixed names:
+ * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior-
+ * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455
+ * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455
+
+
+ * Other protocols should use implementation-defined prefixed names such as
mycompany.com/my-custom-protocol.
type: string
name:
@@ -9597,6 +10126,15 @@ spec:
IP is set for load-balancer ingress points that are IP based
(typically GCE or OpenStack load-balancers)
type: string
+ ipMode:
+ description: |-
+ IPMode specifies how the load-balancer IP behaves, and may only be specified when the ip field is specified.
+ Setting this to "VIP" indicates that traffic is delivered to the node with
+ the destination set to the load-balancer's IP and port.
+ Setting this to "Proxy" indicates that traffic is delivered to the node or pod with
+ the destination set to the node's IP and node port or the pod's IP and port.
+ Service implementations may use this information to adjust traffic routing.
+ type: string
ports:
description: |-
Ports is a list of records of service ports
@@ -10008,34 +10546,6 @@ spec:
status field of the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
properties:
- claims:
- description: |-
- Claims lists the names of resources, defined in spec.resourceClaims,
- that are used by this container.
-
-
- This is an alpha field and requires enabling the
- DynamicResourceAllocation feature gate.
-
-
- 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:
@@ -10111,6 +10621,21 @@ spec:
storageClassName is the name of the StorageClass required by the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
type: string
+ volumeAttributesClassName:
+ description: |-
+ volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.
+ If specified, the CSI driver will create or update the volume with the attributes defined
+ in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,
+ it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass
+ will be applied to the claim but it's not allowed to reset this field to empty string once it is set.
+ If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass
+ will be set by the persistentvolume controller if it exists.
+ If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
+ set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
+ exists.
+ More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
+ type: string
volumeMode:
description: |-
volumeMode defines what type of volume is required by the claim.
@@ -10134,6 +10659,50 @@ spec:
items:
type: string
type: array
+ allocatedResourceStatuses:
+ additionalProperties:
+ description: |-
+ When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource
+ that it does not recognizes, then it should ignore that update and let other controllers
+ handle it.
+ type: string
+ description: "allocatedResourceStatuses stores status of
+ resource being resized for the given PVC.\nKey names follow
+ standard Kubernetes label syntax. Valid values are either:\n\t*
+ Un-prefixed keys:\n\t\t- storage - the capacity of the
+ volume.\n\t* Custom resources must use implementation-defined
+ prefixed names such as \"example.com/my-custom-resource\"\nApart
+ from above values - keys that are unprefixed or have kubernetes.io
+ prefix are considered\nreserved and hence may not be used.\n\n\nClaimResourceStatus
+ can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState
+ set when resize controller starts resizing the volume
+ in control-plane.\n\t- ControllerResizeFailed:\n\t\tState
+ set when resize has failed in resize controller with a
+ terminal error.\n\t- NodeResizePending:\n\t\tState set
+ when resize controller has finished resizing the volume
+ but further resizing of\n\t\tvolume is needed on the node.\n\t-
+ NodeResizeInProgress:\n\t\tState set when kubelet starts
+ resizing the volume.\n\t- NodeResizeFailed:\n\t\tState
+ set when resizing has failed in kubelet with a terminal
+ error. Transient errors don't set\n\t\tNodeResizeFailed.\nFor
+ example: if expanding a PVC for more capacity - this field
+ can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage']
+ = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage']
+ = \"NodeResizeFailed\"\nWhen this field is not set, it
+ means that no resize operation is in progress for the
+ given PVC.\n\n\nA controller that receives PVC update
+ with previously unknown resourceName or ClaimResourceStatus\nshould
+ ignore the update for the purpose it was designed. For
+ example - a controller that\nonly is responsible for resizing
+ capacity of the volume, should ignore PVC updates that
+ change other valid\nresources associated with PVC.\n\n\nThis
+ is an alpha field and requires enabling RecoverVolumeExpansionFailure
+ feature."
+ type: object
+ x-kubernetes-map-type: granular
allocatedResources:
additionalProperties:
anyOf:
@@ -10141,15 +10710,30 @@ spec:
- 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: |-
- allocatedResources is the storage resource within AllocatedResources tracks the capacity allocated to a PVC. It may
- be larger than the actual capacity when a volume expansion operation is requested.
- For storage quota, the larger value from allocatedResources and PVC.spec.resources is used.
- If allocatedResources is not set, PVC.spec.resources alone is used for quota calculation.
- If a volume expansion capacity request is lowered, allocatedResources is only
- lowered if there are no expansion operations in progress and if the actual volume capacity
- is equal or lower than the requested capacity.
- This is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.
+ description: "allocatedResources tracks the resources allocated
+ to a PVC including its capacity.\nKey names follow standard
+ Kubernetes label syntax. Valid values are either:\n\t*
+ Un-prefixed keys:\n\t\t- storage - the capacity of the
+ volume.\n\t* Custom resources must use implementation-defined
+ prefixed names such as \"example.com/my-custom-resource\"\nApart
+ from above values - keys that are unprefixed or have kubernetes.io
+ prefix are considered\nreserved and hence may not be used.\n\n\nCapacity
+ reported here may be larger than the actual capacity when
+ a volume expansion operation\nis requested.\nFor storage
+ quota, the larger value from allocatedResources and PVC.spec.resources
+ is used.\nIf allocatedResources is not set, PVC.spec.resources
+ alone is used for quota calculation.\nIf a volume expansion
+ capacity request is lowered, allocatedResources is only\nlowered
+ if there are no expansion operations in progress and if
+ the actual volume capacity\nis equal or lower than the
+ requested capacity.\n\n\nA controller that receives PVC
+ update with previously unknown resourceName\nshould ignore
+ the update for the purpose it was designed. For example
+ - a controller that\nonly is responsible for resizing
+ capacity of the volume, should ignore PVC updates that
+ change other valid\nresources associated with PVC.\n\n\nThis
+ is an alpha field and requires enabling RecoverVolumeExpansionFailure
+ feature."
type: object
capacity:
additionalProperties:
@@ -10200,15 +10784,42 @@ spec:
- type
type: object
type: array
- phase:
- description: phase represents the current phase of PersistentVolumeClaim.
+ currentVolumeAttributesClassName:
+ description: |-
+ currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using.
+ When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim
+ This is an alpha field and requires enabling VolumeAttributesClass feature.
type: string
- resizeStatus:
+ modifyVolumeStatus:
description: |-
- resizeStatus stores status of resize operation.
- ResizeStatus is not set by default but when expansion is complete resizeStatus is set to empty
- string by resize controller or kubelet.
- This is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.
+ ModifyVolumeStatus represents the status object of ControllerModifyVolume operation.
+ When this is unset, there is no ModifyVolume operation being attempted.
+ This is an alpha field and requires enabling VolumeAttributesClass feature.
+ properties:
+ status:
+ description: "status is the status of the ControllerModifyVolume
+ operation. It can be in any of following states:\n
+ - Pending\n Pending indicates that the PersistentVolumeClaim
+ cannot be modified due to unmet requirements, such
+ as\n the specified VolumeAttributesClass not existing.\n
+ - InProgress\n InProgress indicates that the volume
+ is being modified.\n - Infeasible\n Infeasible indicates
+ that the request has been rejected as invalid by the
+ CSI driver. To\n\t resolve the error, a valid VolumeAttributesClass
+ needs to be specified.\nNote: New statuses can be
+ added in the future. Consumers should check for unknown
+ statuses and fail appropriately."
+ type: string
+ targetVolumeAttributesClassName:
+ description: targetVolumeAttributesClassName is the
+ name of the VolumeAttributesClass the PVC currently
+ being reconciled
+ type: string
+ required:
+ - status
+ type: object
+ phase:
+ description: phase represents the current phase of PersistentVolumeClaim.
type: string
type: object
type: object
@@ -10845,34 +11456,6 @@ spec:
status field of the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
properties:
- claims:
- description: |-
- Claims lists the names of resources, defined in spec.resourceClaims,
- that are used by this container.
-
-
- This is an alpha field and requires enabling the
- DynamicResourceAllocation feature gate.
-
-
- 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:
@@ -10949,6 +11532,21 @@ spec:
storageClassName is the name of the StorageClass required by the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
type: string
+ volumeAttributesClassName:
+ description: |-
+ volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.
+ If specified, the CSI driver will create or update the volume with the attributes defined
+ in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,
+ it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass
+ will be applied to the claim but it's not allowed to reset this field to empty string once it is set.
+ If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass
+ will be set by the persistentvolume controller if it exists.
+ If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
+ set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
+ exists.
+ More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass
+ (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.
+ type: string
volumeMode:
description: |-
volumeMode defines what type of volume is required by the claim.
@@ -11352,6 +11950,100 @@ spec:
description: Projection that may be projected along with
other supported volume types
properties:
+ clusterTrustBundle:
+ description: |-
+ ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field
+ of ClusterTrustBundle objects in an auto-updating file.
+
+
+ Alpha, gated by the ClusterTrustBundleProjection feature gate.
+
+
+ ClusterTrustBundle objects can either be selected by name, or by the
+ combination of signer name and a label selector.
+
+
+ Kubelet performs aggressive normalization of the PEM contents written
+ into the pod filesystem. Esoteric PEM features such as inter-block
+ comments and block headers are stripped. Certificates are deduplicated.
+ The ordering of certificates within the file is arbitrary, and Kubelet
+ may change the order over time.
+ properties:
+ labelSelector:
+ description: |-
+ Select all ClusterTrustBundles that match this label selector. Only has
+ effect if signerName is set. Mutually-exclusive with name. If unset,
+ interpreted as "match nothing". If set but empty, interpreted as "match
+ 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
+ name:
+ description: |-
+ Select a single ClusterTrustBundle by object name. Mutually-exclusive
+ with signerName and labelSelector.
+ type: string
+ optional:
+ description: |-
+ If true, don't block pod startup if the referenced ClusterTrustBundle(s)
+ aren't available. If using name, then the named ClusterTrustBundle is
+ allowed not to exist. If using signerName, then the combination of
+ signerName and labelSelector is allowed to match zero
+ ClusterTrustBundles.
+ type: boolean
+ path:
+ description: Relative path from the volume root
+ to write the bundle.
+ type: string
+ signerName:
+ description: |-
+ Select all ClusterTrustBundles that match this signer name.
+ Mutually-exclusive with name. The contents of all selected
+ ClusterTrustBundles will be unified and deduplicated.
+ type: string
+ required:
+ - path
+ type: object
configMap:
description: configMap information about the configMap
data to project
diff --git a/controllers/druid/druid_controller.go b/controllers/druid/druid_controller.go
index 1cd6073..4959d00 100644
--- a/controllers/druid/druid_controller.go
+++ b/controllers/druid/druid_controller.go
@@ -78,9 +78,9 @@ func (r *DruidReconciler) Reconcile(ctx context.Context, request reconcile.Reque
}
// Update Druid Dynamic Configs
- // if err := updateDruidDynamicConfigs(ctx, r.Client, instance, emitEvent); err != nil {
- // return ctrl.Result{}, err
- // }
+ if err := updateDruidDynamicConfigs(ctx, r.Client, instance, emitEvent); err != nil {
+ return ctrl.Result{}, err
+ }
// If both operations succeed, requeue after specified wait time
return ctrl.Result{RequeueAfter: r.ReconcileWait}, nil
diff --git a/controllers/druid/handler.go b/controllers/druid/handler.go
index 5d8807f..5967498 100644
--- a/controllers/druid/handler.go
+++ b/controllers/druid/handler.go
@@ -165,16 +165,16 @@ func deployDruidCluster(ctx context.Context, sdk client.Client, m *v1alpha1.Drui
}
}
- // Handle VolumeClaimTemplate annotation updates (enabled by default unless disabled)
- // If StatefulSet was deleted for annotation updates, skip creation in this reconcile to avoid race condition
+ // Handle VolumeClaimTemplate updates (annotations and volumeAttributeClassName)
+ // If StatefulSet was deleted for updates, skip creation in this reconcile to avoid race condition
if m.Generation > 1 {
- deleted, err := patchStatefulSetVolumeClaimTemplateAnnotations(ctx, sdk, m, &nodeSpec, emitEvents, nodeSpecUniqueStr)
+ deleted, err := patchStatefulSetVolumeClaimTemplates(ctx, sdk, m, &nodeSpec, emitEvents, nodeSpecUniqueStr)
if err != nil {
return err
}
if deleted {
// StatefulSet was deleted, skip creation in this reconcile loop
- // It will be created in the next reconcile with updated annotations
+ // It will be created in the next reconcile with updated configuration
continue
}
}
diff --git a/controllers/druid/volume_annotation_update.go b/controllers/druid/volume_annotation_update.go
deleted file mode 100644
index f024def..0000000
--- a/controllers/druid/volume_annotation_update.go
+++ /dev/null
@@ -1,278 +0,0 @@
-package druid
-
-import (
- "context"
- "fmt"
- "reflect"
- "strings"
-
- "github.com/datainfrahq/druid-operator/apis/druid/v1alpha1"
- appsv1 "k8s.io/api/apps/v1"
- v1 "k8s.io/api/core/v1"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/runtime"
- "sigs.k8s.io/controller-runtime/pkg/client"
-)
-
-// patchStatefulSetVolumeClaimTemplateAnnotations handles annotation updates for StatefulSet VolumeClaimTemplates
-// Returns (deleted bool, error) - deleted indicates if the StatefulSet was deleted in this call
-func patchStatefulSetVolumeClaimTemplateAnnotations(ctx context.Context, sdk client.Client, m *v1alpha1.Druid,
- nodeSpec *v1alpha1.DruidNodeSpec, emitEvent EventEmitter, nodeSpecUniqueStr string) (bool, error) {
-
- // Skip if PVC annotation update is disabled
- if m.Spec.DisablePVCAnnotationUpdate {
- return false, nil
- }
-
- // Only process StatefulSets (default kind is StatefulSet when not specified or anything other than "Deployment")
- if nodeSpec.Kind == "Deployment" {
- return false, nil
- }
-
- // Get the existing StatefulSet
- sts, err := readers.Get(ctx, sdk, nodeSpecUniqueStr, m, func() object { return &appsv1.StatefulSet{} }, emitEvent)
- if err != nil {
- // StatefulSet doesn't exist yet, will be created with proper annotations
- // This is expected after we delete it for recreation
- return false, nil
- }
-
- statefulSet := sts.(*appsv1.StatefulSet)
-
- // Check if annotation changes are needed
- annotationChangesNeeded, annotationDetails := detectAnnotationChanges(statefulSet, nodeSpec)
- if !annotationChangesNeeded {
- return false, nil
- }
-
- // Before proceeding, check if PVCs already have the desired annotations
- // This prevents re-processing after StatefulSet deletion
- pvcAlreadyUpdated, err := checkPVCAnnotationsAlreadyUpdated(ctx, sdk, statefulSet, nodeSpec, m, emitEvent, nodeSpecUniqueStr)
- if err != nil {
- return false, err
- }
- if pvcAlreadyUpdated {
- // PVCs already have the desired annotations, likely from a previous reconcile
- // The StatefulSet will be recreated with correct annotations by sdkCreateOrUpdateAsNeeded
- return false, nil
- }
-
- // Don't proceed unless all statefulsets are up and running
- getSTSList, err := readers.List(ctx, sdk, m, makeLabelsForDruid(m), emitEvent, func() objectList { return &appsv1.StatefulSetList{} }, func(listObj runtime.Object) []object {
- items := listObj.(*appsv1.StatefulSetList).Items
- result := make([]object, len(items))
- for i := 0; i < len(items); i++ {
- result[i] = &items[i]
- }
- return result
- })
- if err != nil {
- return false, nil
- }
-
- for _, sts := range getSTSList {
- if sts.(*appsv1.StatefulSet).Status.Replicas != sts.(*appsv1.StatefulSet).Status.ReadyReplicas {
- return false, nil
- }
- }
-
- // Emit event for annotation change detection
- msg := fmt.Sprintf("Detected annotation changes in VolumeClaimTemplates for StatefulSet [%s] in Namespace [%s]: %s",
- statefulSet.Name, statefulSet.Namespace, annotationDetails)
- emitEvent.EmitEventGeneric(m, string(druidPvcAnnotationChangeDetected), msg, nil)
-
- // First, delete the StatefulSet with cascade=orphan (similar to volume expansion)
- msg = fmt.Sprintf("Deleting StatefulSet [%s] with cascade=orphan to apply annotation changes", statefulSet.Name)
- emitEvent.EmitEventGeneric(m, string(druidStsOrphanedForAnnotations), msg, nil)
-
- if err := writers.Delete(ctx, sdk, m, statefulSet, emitEvent, client.PropagationPolicy(metav1.DeletePropagationOrphan)); err != nil {
- return false, err
- }
-
- msg = fmt.Sprintf("StatefulSet [%s] successfully deleted with cascade=orphan for annotation updates", statefulSet.Name)
- emitEvent.EmitEventGeneric(m, string(druidStsOrphanedForAnnotations), msg, nil)
-
- // Then update PVC annotations after deletion (similar to volume expansion)
- if err := patchPVCAnnotations(ctx, sdk, statefulSet, nodeSpec, m, emitEvent, nodeSpecUniqueStr); err != nil {
- return false, err
- }
-
- // Return true to indicate StatefulSet was deleted
- return true, nil
-}
-
-// detectAnnotationChanges compares current and desired annotations for VolumeClaimTemplates
-func detectAnnotationChanges(sts *appsv1.StatefulSet, nodeSpec *v1alpha1.DruidNodeSpec) (bool, string) {
- var changeDetails []string
-
- // Create a map of current VCT annotations by name
- currentVCTAnnotations := make(map[string]map[string]string)
- for _, vct := range sts.Spec.VolumeClaimTemplates {
- currentVCTAnnotations[vct.Name] = vct.ObjectMeta.Annotations
- }
-
- // Check each desired VCT for annotation changes
- for _, desiredVCT := range nodeSpec.VolumeClaimTemplates {
- currentAnnotations, exists := currentVCTAnnotations[desiredVCT.Name]
-
- // If VCT doesn't exist in current StatefulSet, skip (it's a new VCT)
- if !exists {
- continue
- }
-
- // Compare annotations
- if !reflect.DeepEqual(currentAnnotations, desiredVCT.ObjectMeta.Annotations) {
- changeDetails = append(changeDetails, fmt.Sprintf("VCT %s: annotations changed", desiredVCT.Name))
- }
- }
-
- if len(changeDetails) > 0 {
- return true, strings.Join(changeDetails, "; ")
- }
-
- return false, ""
-}
-
-// patchPVCAnnotations patches existing PVCs with new annotations from VolumeClaimTemplates
-func patchPVCAnnotations(ctx context.Context, sdk client.Client, sts *appsv1.StatefulSet,
- nodeSpec *v1alpha1.DruidNodeSpec, m *v1alpha1.Druid, emitEvent EventEmitter, nodeSpecUniqueStr string) error {
-
- // Get PVCs for this StatefulSet
- pvcLabels := map[string]string{
- "nodeSpecUniqueStr": nodeSpecUniqueStr,
- }
-
- pvcList, err := readers.List(ctx, sdk, m, pvcLabels, emitEvent, func() objectList { return &v1.PersistentVolumeClaimList{} }, func(listObj runtime.Object) []object {
- items := listObj.(*v1.PersistentVolumeClaimList).Items
- result := make([]object, len(items))
- for i := 0; i < len(items); i++ {
- result[i] = &items[i]
- }
- return result
- })
- if err != nil {
- return err
- }
-
- // Create a map of desired annotations by VCT name
- desiredAnnotationsByVCT := make(map[string]map[string]string)
- for _, vct := range nodeSpec.VolumeClaimTemplates {
- desiredAnnotationsByVCT[vct.Name] = vct.ObjectMeta.Annotations
- }
-
- // Patch each PVC with new annotations
- for _, pvcObj := range pvcList {
- pvc := pvcObj.(*v1.PersistentVolumeClaim)
-
- // Determine which VolumeClaimTemplate this PVC belongs to
- vctName := extractVCTNameFromPVC(pvc.Name, sts.Name)
- if vctName == "" {
- continue
- }
-
- desiredAnnotations, exists := desiredAnnotationsByVCT[vctName]
- if !exists {
- continue
- }
-
- // Check if annotations need updating
- if reflect.DeepEqual(pvc.ObjectMeta.Annotations, desiredAnnotations) {
- continue
- }
-
- // Create patch for annotations
- pvcCopy := pvc.DeepCopy()
- patch := client.MergeFrom(pvcCopy)
-
- // Update or set annotations
- if pvc.ObjectMeta.Annotations == nil {
- pvc.ObjectMeta.Annotations = make(map[string]string)
- }
-
- // Apply desired annotations
- for key, value := range desiredAnnotations {
- pvc.ObjectMeta.Annotations[key] = value
- }
-
- // Remove annotations that are not in desired state
- for key := range pvc.ObjectMeta.Annotations {
- if _, exists := desiredAnnotations[key]; !exists {
- delete(pvc.ObjectMeta.Annotations, key)
- }
- }
-
- // Patch the PVC
- if err := writers.Patch(ctx, sdk, m, pvc, false, patch, emitEvent); err != nil {
- return err
- }
-
- msg := fmt.Sprintf("PVC [%s] successfully patched with updated annotations", pvc.Name)
- emitEvent.EmitEventGeneric(m, string(druidPvcAnnotationsUpdated), msg, nil)
- }
-
- return nil
-}
-
-// checkPVCAnnotationsAlreadyUpdated checks if PVCs already have the desired annotations
-func checkPVCAnnotationsAlreadyUpdated(ctx context.Context, sdk client.Client, sts *appsv1.StatefulSet,
- nodeSpec *v1alpha1.DruidNodeSpec, m *v1alpha1.Druid, emitEvent EventEmitter, nodeSpecUniqueStr string) (bool, error) {
-
- // Get PVCs for this StatefulSet
- pvcLabels := map[string]string{
- "nodeSpecUniqueStr": nodeSpecUniqueStr,
- }
-
- pvcList, err := readers.List(ctx, sdk, m, pvcLabels, emitEvent, func() objectList { return &v1.PersistentVolumeClaimList{} }, func(listObj runtime.Object) []object {
- items := listObj.(*v1.PersistentVolumeClaimList).Items
- result := make([]object, len(items))
- for i := 0; i < len(items); i++ {
- result[i] = &items[i]
- }
- return result
- })
- if err != nil {
- return false, err
- }
-
- // Create a map of desired annotations by VCT name
- desiredAnnotationsByVCT := make(map[string]map[string]string)
- for _, vct := range nodeSpec.VolumeClaimTemplates {
- desiredAnnotationsByVCT[vct.Name] = vct.ObjectMeta.Annotations
- }
-
- // Check each PVC to see if it already has the desired annotations
- for _, pvcObj := range pvcList {
- pvc := pvcObj.(*v1.PersistentVolumeClaim)
-
- // Determine which VolumeClaimTemplate this PVC belongs to
- vctName := extractVCTNameFromPVC(pvc.Name, sts.Name)
- if vctName == "" {
- continue
- }
-
- desiredAnnotations, exists := desiredAnnotationsByVCT[vctName]
- if !exists {
- continue
- }
-
- // If any PVC doesn't have the desired annotations, return false
- if !reflect.DeepEqual(pvc.ObjectMeta.Annotations, desiredAnnotations) {
- return false, nil
- }
- }
-
- // All PVCs have the desired annotations
- return true, nil
-}
-
-// extractVCTNameFromPVC extracts the VolumeClaimTemplate name from a PVC name
-// PVC naming format: {vctName}-{statefulSetName}-{ordinal}
-func extractVCTNameFromPVC(pvcName, stsName string) string {
- // Remove the StatefulSet name and ordinal suffix
- suffix := fmt.Sprintf("-%s-", stsName)
- idx := strings.LastIndex(pvcName, suffix)
- if idx == -1 {
- return ""
- }
- return pvcName[:idx]
-}
diff --git a/controllers/druid/volume_claim_template_update.go b/controllers/druid/volume_claim_template_update.go
new file mode 100644
index 0000000..d33ce84
--- /dev/null
+++ b/controllers/druid/volume_claim_template_update.go
@@ -0,0 +1,368 @@
+package druid
+
+import (
+ "context"
+ "fmt"
+ "reflect"
+ "strings"
+
+ "github.com/datainfrahq/druid-operator/apis/druid/v1alpha1"
+ appsv1 "k8s.io/api/apps/v1"
+ v1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+// VolumeClaimTemplateChanges tracks what changed in VolumeClaimTemplates
+type VolumeClaimTemplateChanges struct {
+ HasChanges bool
+ AnnotationChanges map[string]bool // VCT name -> has annotation changes
+ VolumeAttributeClassChanges map[string]bool // VCT name -> has volumeAttributeClassName changes
+ Details string
+}
+
+// patchStatefulSetVolumeClaimTemplates handles updates to VolumeClaimTemplates that require StatefulSet recreation
+// This includes both annotation and volumeAttributeClassName updates
+// Returns (deleted bool, error) - deleted indicates if the StatefulSet was deleted in this call
+func patchStatefulSetVolumeClaimTemplates(ctx context.Context, sdk client.Client, m *v1alpha1.Druid,
+ nodeSpec *v1alpha1.DruidNodeSpec, emitEvent EventEmitter, nodeSpecUniqueStr string) (bool, error) {
+
+ // Skip if PVC updates are disabled
+ if m.Spec.DisablePVCUpdates {
+ return false, nil
+ }
+
+ // Only process StatefulSets
+ if nodeSpec.Kind == "Deployment" {
+ return false, nil
+ }
+
+ // Get the existing StatefulSet
+ sts, err := readers.Get(ctx, sdk, nodeSpecUniqueStr, m, func() object { return &appsv1.StatefulSet{} }, emitEvent)
+ if err != nil {
+ // StatefulSet doesn't exist yet, will be created with proper configuration
+ return false, nil
+ }
+
+ statefulSet := sts.(*appsv1.StatefulSet)
+
+ // Check for VolumeClaimTemplate changes
+ changes := detectVolumeClaimTemplateChanges(statefulSet, nodeSpec)
+ fmt.Println(changes)
+ if !changes.HasChanges {
+ return false, nil
+ }
+
+ // Check if PVCs already have the desired configuration
+ pvcAlreadyUpdated, err := checkPVCsAlreadyUpdated(ctx, sdk, statefulSet, nodeSpec, m, emitEvent, nodeSpecUniqueStr)
+ if err != nil {
+ return false, err
+ }
+ if pvcAlreadyUpdated {
+ // PVCs already updated from a previous reconcile
+ return false, nil
+ }
+
+ // Don't proceed unless all statefulsets are up and running
+ if err := waitForAllStatefulSetsReady(ctx, sdk, m, emitEvent); err != nil {
+ return false, nil
+ }
+
+ // Emit event for change detection
+ msg := fmt.Sprintf("Detected VolumeClaimTemplate changes for StatefulSet [%s] in Namespace [%s]: %s",
+ statefulSet.Name, statefulSet.Namespace, changes.Details)
+ emitEvent.EmitEventGeneric(m, "VolumeClaimTemplateChangeDetected", msg, nil)
+
+ // Delete the StatefulSet with cascade=orphan
+ msg = fmt.Sprintf("Deleting StatefulSet [%s] with cascade=orphan to apply VolumeClaimTemplate changes", statefulSet.Name)
+ emitEvent.EmitEventGeneric(m, "StatefulSetOrphanedForVCTChanges", msg, nil)
+
+ if err := writers.Delete(ctx, sdk, m, statefulSet, emitEvent, client.PropagationPolicy(metav1.DeletePropagationOrphan)); err != nil {
+ return false, err
+ }
+
+ msg = fmt.Sprintf("StatefulSet [%s] successfully deleted with cascade=orphan", statefulSet.Name)
+ emitEvent.EmitEventGeneric(m, "StatefulSetOrphanedForVCTChanges", msg, nil)
+
+ // Update PVCs with new configuration
+ if err := patchPVCs(ctx, sdk, statefulSet, nodeSpec, m, emitEvent, nodeSpecUniqueStr, changes); err != nil {
+ return false, err
+ }
+
+ return true, nil
+}
+
+// detectVolumeClaimTemplateChanges detects all changes in VolumeClaimTemplates
+func detectVolumeClaimTemplateChanges(sts *appsv1.StatefulSet, nodeSpec *v1alpha1.DruidNodeSpec) VolumeClaimTemplateChanges {
+ changes := VolumeClaimTemplateChanges{
+ HasChanges: false,
+ AnnotationChanges: make(map[string]bool),
+ VolumeAttributeClassChanges: make(map[string]bool),
+ }
+
+ fmt.Println(sts.Name)
+ var changeDetails []string
+
+ // Create maps of current VCT configuration
+ currentVCTMap := make(map[string]v1.PersistentVolumeClaim)
+ for _, vct := range sts.Spec.VolumeClaimTemplates {
+ currentVCTMap[vct.Name] = vct
+ }
+
+ // Check each desired VCT for changes
+ for _, desiredVCT := range nodeSpec.VolumeClaimTemplates {
+ currentVCT, exists := currentVCTMap[desiredVCT.Name]
+ if !exists {
+ // New VCT, skip
+ continue
+ }
+
+ // Check annotation changes
+ if !reflect.DeepEqual(currentVCT.ObjectMeta.Annotations, desiredVCT.ObjectMeta.Annotations) {
+ changes.AnnotationChanges[desiredVCT.Name] = true
+ changeDetails = append(changeDetails, fmt.Sprintf("VCT %s: annotations changed", desiredVCT.Name))
+ changes.HasChanges = true
+ }
+
+ // Check volumeAttributeClassName changes
+ currentVolAttrClass := ""
+ if currentVCT.Spec.VolumeAttributesClassName != nil {
+ currentVolAttrClass = *currentVCT.Spec.VolumeAttributesClassName
+ }
+ desiredVolAttrClass := ""
+ if desiredVCT.Spec.VolumeAttributesClassName != nil {
+ desiredVolAttrClass = *desiredVCT.Spec.VolumeAttributesClassName
+ }
+
+ if currentVolAttrClass != desiredVolAttrClass {
+ changes.VolumeAttributeClassChanges[desiredVCT.Name] = true
+ changeDetails = append(changeDetails, fmt.Sprintf("VCT %s: volumeAttributeClassName changed from '%s' to '%s'",
+ desiredVCT.Name, currentVolAttrClass, desiredVolAttrClass))
+ changes.HasChanges = true
+ }
+ }
+
+ if len(changeDetails) > 0 {
+ changes.Details = strings.Join(changeDetails, "; ")
+ }
+
+ return changes
+}
+
+// patchPVCs patches existing PVCs with new configuration
+func patchPVCs(ctx context.Context, sdk client.Client, sts *appsv1.StatefulSet,
+ nodeSpec *v1alpha1.DruidNodeSpec, m *v1alpha1.Druid, emitEvent EventEmitter,
+ nodeSpecUniqueStr string, changes VolumeClaimTemplateChanges) error {
+
+ // Get PVCs for this StatefulSet
+ pvcLabels := map[string]string{
+ "nodeSpecUniqueStr": nodeSpecUniqueStr,
+ }
+
+ pvcList, err := readers.List(ctx, sdk, m, pvcLabels, emitEvent, func() objectList { return &v1.PersistentVolumeClaimList{} }, func(listObj runtime.Object) []object {
+ items := listObj.(*v1.PersistentVolumeClaimList).Items
+ result := make([]object, len(items))
+ for i := 0; i < len(items); i++ {
+ result[i] = &items[i]
+ }
+ return result
+ })
+ if err != nil {
+ return err
+ }
+
+ // Create map of desired VCT configurations
+ desiredVCTMap := make(map[string]v1.PersistentVolumeClaim)
+ for _, vct := range nodeSpec.VolumeClaimTemplates {
+ desiredVCTMap[vct.Name] = vct
+ }
+
+ // Patch each PVC with new configuration
+ for _, pvcObj := range pvcList {
+ pvc := pvcObj.(*v1.PersistentVolumeClaim)
+
+ // Determine which VolumeClaimTemplate this PVC belongs to
+ vctName := extractVCTNameFromPVC(pvc.Name, sts.Name)
+ if vctName == "" {
+ continue
+ }
+
+ desiredVCT, exists := desiredVCTMap[vctName]
+ if !exists {
+ continue
+ }
+
+ // Check if this PVC needs updates
+ needsPatch := false
+ updateMessages := []string{}
+
+ // Check annotations
+ if changes.AnnotationChanges[vctName] {
+ if !reflect.DeepEqual(pvc.ObjectMeta.Annotations, desiredVCT.ObjectMeta.Annotations) {
+ needsPatch = true
+ updateMessages = append(updateMessages, "annotations")
+ }
+ }
+
+ // Check volumeAttributeClassName
+ if changes.VolumeAttributeClassChanges[vctName] {
+ currentVolAttrClass := ""
+ if pvc.Spec.VolumeAttributesClassName != nil {
+ currentVolAttrClass = *pvc.Spec.VolumeAttributesClassName
+ }
+ desiredVolAttrClass := ""
+ if desiredVCT.Spec.VolumeAttributesClassName != nil {
+ desiredVolAttrClass = *desiredVCT.Spec.VolumeAttributesClassName
+ }
+
+ if currentVolAttrClass != desiredVolAttrClass {
+ needsPatch = true
+ updateMessages = append(updateMessages, fmt.Sprintf("volumeAttributeClassName to '%s'", desiredVolAttrClass))
+ }
+ }
+
+ if !needsPatch {
+ continue
+ }
+
+ // Create patch
+ pvcCopy := pvc.DeepCopy()
+ patch := client.MergeFrom(pvcCopy)
+
+ // Apply annotation updates
+ if changes.AnnotationChanges[vctName] {
+ if pvc.ObjectMeta.Annotations == nil {
+ pvc.ObjectMeta.Annotations = make(map[string]string)
+ }
+
+ // Apply desired annotations
+ for key, value := range desiredVCT.ObjectMeta.Annotations {
+ pvc.ObjectMeta.Annotations[key] = value
+ }
+
+ // Remove annotations not in desired state
+ for key := range pvc.ObjectMeta.Annotations {
+ if _, exists := desiredVCT.ObjectMeta.Annotations[key]; !exists {
+ delete(pvc.ObjectMeta.Annotations, key)
+ }
+ }
+ }
+
+ // Apply volumeAttributeClassName update
+ if changes.VolumeAttributeClassChanges[vctName] {
+ pvc.Spec.VolumeAttributesClassName = desiredVCT.Spec.VolumeAttributesClassName
+ }
+
+ // Patch the PVC
+ if err := writers.Patch(ctx, sdk, m, pvc, false, patch, emitEvent); err != nil {
+ return err
+ }
+
+ msg := fmt.Sprintf("PVC [%s] successfully patched with: %s", pvc.Name, strings.Join(updateMessages, ", "))
+ emitEvent.EmitEventGeneric(m, "PVCUpdated", msg, nil)
+ }
+
+ return nil
+}
+
+// checkPVCsAlreadyUpdated checks if PVCs already have the desired configuration
+func checkPVCsAlreadyUpdated(ctx context.Context, sdk client.Client, sts *appsv1.StatefulSet,
+ nodeSpec *v1alpha1.DruidNodeSpec, m *v1alpha1.Druid, emitEvent EventEmitter, nodeSpecUniqueStr string) (bool, error) {
+
+ // Get PVCs for this StatefulSet
+ pvcLabels := map[string]string{
+ "nodeSpecUniqueStr": nodeSpecUniqueStr,
+ }
+
+ pvcList, err := readers.List(ctx, sdk, m, pvcLabels, emitEvent, func() objectList { return &v1.PersistentVolumeClaimList{} }, func(listObj runtime.Object) []object {
+ items := listObj.(*v1.PersistentVolumeClaimList).Items
+ result := make([]object, len(items))
+ for i := 0; i < len(items); i++ {
+ result[i] = &items[i]
+ }
+ return result
+ })
+ if err != nil {
+ return false, err
+ }
+
+ // Create map of desired VCT configurations
+ desiredVCTMap := make(map[string]v1.PersistentVolumeClaim)
+ for _, vct := range nodeSpec.VolumeClaimTemplates {
+ desiredVCTMap[vct.Name] = vct
+ }
+
+ // Check each PVC
+ for _, pvcObj := range pvcList {
+ pvc := pvcObj.(*v1.PersistentVolumeClaim)
+
+ // Determine which VolumeClaimTemplate this PVC belongs to
+ vctName := extractVCTNameFromPVC(pvc.Name, sts.Name)
+ if vctName == "" {
+ continue
+ }
+
+ desiredVCT, exists := desiredVCTMap[vctName]
+ if !exists {
+ continue
+ }
+
+ // Check annotations
+ if !reflect.DeepEqual(pvc.ObjectMeta.Annotations, desiredVCT.ObjectMeta.Annotations) {
+ return false, nil
+ }
+
+ // Check volumeAttributeClassName
+ currentVolAttrClass := ""
+ if pvc.Spec.VolumeAttributesClassName != nil {
+ currentVolAttrClass = *pvc.Spec.VolumeAttributesClassName
+ }
+ desiredVolAttrClass := ""
+ if desiredVCT.Spec.VolumeAttributesClassName != nil {
+ desiredVolAttrClass = *desiredVCT.Spec.VolumeAttributesClassName
+ }
+
+ if currentVolAttrClass != desiredVolAttrClass {
+ return false, nil
+ }
+ }
+
+ // All PVCs have the desired configuration
+ return true, nil
+}
+
+// waitForAllStatefulSetsReady waits for all StatefulSets to be ready
+func waitForAllStatefulSetsReady(ctx context.Context, sdk client.Client, m *v1alpha1.Druid, emitEvent EventEmitter) error {
+ getSTSList, err := readers.List(ctx, sdk, m, makeLabelsForDruid(m), emitEvent, func() objectList { return &appsv1.StatefulSetList{} }, func(listObj runtime.Object) []object {
+ items := listObj.(*appsv1.StatefulSetList).Items
+ result := make([]object, len(items))
+ for i := 0; i < len(items); i++ {
+ result[i] = &items[i]
+ }
+ return result
+ })
+ if err != nil {
+ return err
+ }
+
+ for _, sts := range getSTSList {
+ if sts.(*appsv1.StatefulSet).Status.Replicas != sts.(*appsv1.StatefulSet).Status.ReadyReplicas {
+ return fmt.Errorf("not all StatefulSets are ready")
+ }
+ }
+
+ return nil
+}
+
+// extractVCTNameFromPVC extracts the VolumeClaimTemplate name from a PVC name
+// PVC naming format: {vctName}-{statefulSetName}-{ordinal}
+func extractVCTNameFromPVC(pvcName, stsName string) string {
+ // Remove the StatefulSet name and ordinal suffix
+ suffix := fmt.Sprintf("-%s-", stsName)
+ idx := strings.LastIndex(pvcName, suffix)
+ if idx == -1 {
+ return ""
+ }
+ return pvcName[:idx]
+}
diff --git a/controllers/druid/volume_annotation_update_test.go b/controllers/druid/volume_claim_template_update_test.go
similarity index 69%
rename from controllers/druid/volume_annotation_update_test.go
rename to controllers/druid/volume_claim_template_update_test.go
index 2a81685..26e49e7 100644
--- a/controllers/druid/volume_annotation_update_test.go
+++ b/controllers/druid/volume_claim_template_update_test.go
@@ -23,7 +23,12 @@ func (m *mockEventEmitter) EmitEventOnCreate(obj, createObj object, err error)
func (m *mockEventEmitter) EmitEventOnPatch(obj, patchObj object, err error) {}
func (m *mockEventEmitter) EmitEventOnList(obj object, listObj objectList, err error) {}
-func TestDetectAnnotationChanges(t *testing.T) {
+// Helper function to create string pointers
+func stringPtr(s string) *string {
+ return &s
+}
+
+func TestDetectVolumeClaimTemplateChanges(t *testing.T) {
tests := []struct {
name string
currentStatefulSet *appsv1.StatefulSet
@@ -127,13 +132,81 @@ func TestDetectAnnotationChanges(t *testing.T) {
expectChanges: false,
expectDetails: "",
},
+ {
+ name: "Detect volumeAttributeClassName changes",
+ currentStatefulSet: &appsv1.StatefulSet{
+ Spec: appsv1.StatefulSetSpec{
+ VolumeClaimTemplates: []v1.PersistentVolumeClaim{
+ {
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "segment-cache",
+ },
+ Spec: v1.PersistentVolumeClaimSpec{
+ VolumeAttributesClassName: stringPtr("old-class"),
+ },
+ },
+ },
+ },
+ },
+ nodeSpec: &v1alpha1.DruidNodeSpec{
+ VolumeClaimTemplates: []v1.PersistentVolumeClaim{
+ {
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "segment-cache",
+ },
+ Spec: v1.PersistentVolumeClaimSpec{
+ VolumeAttributesClassName: stringPtr("new-class"),
+ },
+ },
+ },
+ },
+ expectChanges: true,
+ expectDetails: "VCT segment-cache: volumeAttributeClassName changed from 'old-class' to 'new-class'",
+ },
+ {
+ name: "Detect both annotation and volumeAttributeClassName changes",
+ currentStatefulSet: &appsv1.StatefulSet{
+ Spec: appsv1.StatefulSetSpec{
+ VolumeClaimTemplates: []v1.PersistentVolumeClaim{
+ {
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "segment-cache",
+ Annotations: map[string]string{
+ "backup": "disabled",
+ },
+ },
+ Spec: v1.PersistentVolumeClaimSpec{
+ VolumeAttributesClassName: stringPtr("standard"),
+ },
+ },
+ },
+ },
+ },
+ nodeSpec: &v1alpha1.DruidNodeSpec{
+ VolumeClaimTemplates: []v1.PersistentVolumeClaim{
+ {
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "segment-cache",
+ Annotations: map[string]string{
+ "backup": "enabled",
+ },
+ },
+ Spec: v1.PersistentVolumeClaimSpec{
+ VolumeAttributesClassName: stringPtr("premium"),
+ },
+ },
+ },
+ },
+ expectChanges: true,
+ expectDetails: "VCT segment-cache: annotations changed; VCT segment-cache: volumeAttributeClassName changed from 'standard' to 'premium'",
+ },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- hasChanges, details := detectAnnotationChanges(tt.currentStatefulSet, tt.nodeSpec)
- assert.Equal(t, tt.expectChanges, hasChanges)
- assert.Equal(t, tt.expectDetails, details)
+ changes := detectVolumeClaimTemplateChanges(tt.currentStatefulSet, tt.nodeSpec)
+ assert.Equal(t, tt.expectChanges, changes.HasChanges)
+ assert.Equal(t, tt.expectDetails, changes.Details)
})
}
}
@@ -185,7 +258,7 @@ func TestPatchStatefulSetVolumeClaimTemplateAnnotationsDisabled(t *testing.T) {
Namespace: "default",
},
Spec: v1alpha1.DruidSpec{
- DisablePVCAnnotationUpdate: true, // Feature disabled
+ DisablePVCUpdates: true, // Feature disabled
},
}
@@ -197,7 +270,7 @@ func TestPatchStatefulSetVolumeClaimTemplateAnnotationsDisabled(t *testing.T) {
emitter := &mockEventEmitter{}
// Test should return immediately when feature is disabled
- deleted, err := patchStatefulSetVolumeClaimTemplateAnnotations(ctx, nil, druid, nodeSpec, emitter, "test")
+ deleted, err := patchStatefulSetVolumeClaimTemplates(ctx, nil, druid, nodeSpec, emitter, "test")
assert.NoError(t, err)
assert.False(t, deleted) // Should not delete when disabled
}
diff --git a/e2e/configs/druid-cr.yaml b/e2e/configs/druid-cr.yaml
index 69cbe4d..fd7a3f6 100644
--- a/e2e/configs/druid-cr.yaml
+++ b/e2e/configs/druid-cr.yaml
@@ -142,6 +142,9 @@ spec:
volumeClaimTemplates:
- metadata:
name: data-volume
+ annotations:
+ backup.kubernetes.io/enabled: "true"
+ volume.kubernetes.io/tier: "performance"
spec:
accessModes:
- ReadWriteOnce
@@ -149,6 +152,7 @@ spec:
requests:
storage: 2Gi
storageClassName: standard
+ volumeAttributesClassName: fast-ssd-class
runtime.properties: |
druid.service=druid/broker
# HTTP server threads
@@ -214,6 +218,20 @@ spec:
clusterIP: None
nodeConfigMountPath: "/opt/druid/conf/druid/cluster/data/historical"
replicas: 1
+ volumeClaimTemplates:
+ - metadata:
+ name: segment-cache
+ annotations:
+ backup.kubernetes.io/enabled: "true"
+ volume.kubernetes.io/tier: "performance"
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 5Gi
+ storageClassName: standard
+ volumeAttributesClassName: fast-ssd-class
runtime.properties: |
druid.service=druid/historical
druid.processing.buffer.sizeBytes=25000000
diff --git a/e2e/configs/volume-attributes-class.yaml b/e2e/configs/volume-attributes-class.yaml
new file mode 100644
index 0000000..42c651a
--- /dev/null
+++ b/e2e/configs/volume-attributes-class.yaml
@@ -0,0 +1,10 @@
+apiVersion: storage.k8s.io/v1
+kind: VolumeAttributesClass
+metadata:
+ name: fast-ssd-class
+driverName: example.io/fast-ssd
+parameters:
+ provisioned-iops: "10000"
+ provisioned-throughput: "100MiB/s"
+ encryption: "true"
+ replica-count: "3"
\ No newline at end of file
diff --git a/go.mod b/go.mod
index 01f3448..767df27 100644
--- a/go.mod
+++ b/go.mod
@@ -1,78 +1,79 @@
module github.com/datainfrahq/druid-operator
-go 1.20
+go 1.21
+
+toolchain go1.23.2
require (
github.com/datainfrahq/operator-runtime v0.0.2-0.20230425161705-667c247a660b
github.com/ghodss/yaml v1.0.0
- github.com/go-logr/logr v1.2.4
- github.com/onsi/ginkgo/v2 v2.9.5
- github.com/onsi/gomega v1.27.7
- github.com/stretchr/testify v1.8.1
- k8s.io/api v0.27.7
- k8s.io/apimachinery v0.27.7
- k8s.io/client-go v0.27.7
- sigs.k8s.io/controller-runtime v0.15.3
+ github.com/go-logr/logr v1.4.1
+ github.com/onsi/ginkgo/v2 v2.14.0
+ github.com/onsi/gomega v1.30.0
+ github.com/stretchr/testify v1.8.4
+ k8s.io/api v0.29.0
+ k8s.io/apimachinery v0.29.0
+ k8s.io/client-go v0.29.0
+ sigs.k8s.io/controller-runtime v0.17.0
)
require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
- github.com/emicklei/go-restful/v3 v3.9.0 // indirect
- github.com/evanphx/json-patch v4.12.0+incompatible // indirect
- github.com/evanphx/json-patch/v5 v5.6.0 // indirect
- github.com/fsnotify/fsnotify v1.6.0 // indirect
- github.com/go-logr/zapr v1.2.4 // indirect
+ github.com/emicklei/go-restful/v3 v3.11.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.19.6 // indirect
- github.com/go-openapi/jsonreference v0.20.1 // indirect
+ github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // 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/google/gnostic v0.5.7-v3refs // indirect
- github.com/google/go-cmp v0.5.9 // indirect
- github.com/google/gofuzz v1.1.0 // 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
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
- github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
+ github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
- github.com/prometheus/client_golang v1.15.1 // indirect
- github.com/prometheus/client_model v0.4.0 // indirect
- github.com/prometheus/common v0.42.0 // indirect
- github.com/prometheus/procfs v0.9.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
github.com/spf13/pflag v1.0.5 // indirect
- go.uber.org/atomic v1.7.0 // indirect
- go.uber.org/multierr v1.6.0 // indirect
- go.uber.org/zap v1.24.0 // indirect
- golang.org/x/net v0.17.0 // indirect
- golang.org/x/oauth2 v0.5.0 // indirect
- golang.org/x/sys v0.13.0 // indirect
- golang.org/x/term v0.13.0 // indirect
- golang.org/x/text v0.13.0 // indirect
+ go.uber.org/multierr v1.11.0 // indirect
+ go.uber.org/zap v1.26.0 // indirect
+ golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
+ golang.org/x/net v0.19.0 // indirect
+ golang.org/x/oauth2 v0.12.0 // indirect
+ golang.org/x/sys v0.16.0 // indirect
+ golang.org/x/term v0.15.0 // indirect
+ golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.3.0 // indirect
- golang.org/x/tools v0.9.1 // indirect
- gomodules.xyz/jsonpatch/v2 v2.3.0 // indirect
+ golang.org/x/tools v0.16.1 // indirect
+ gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
- google.golang.org/protobuf v1.30.0 // indirect
+ google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
- k8s.io/apiextensions-apiserver v0.27.7 // indirect
- k8s.io/component-base v0.27.7 // indirect
- k8s.io/klog/v2 v2.90.1 // indirect
- k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect
- k8s.io/utils v0.0.0-20230209194617-a36077c30491 // indirect
+ k8s.io/apiextensions-apiserver v0.29.0 // indirect
+ k8s.io/component-base v0.29.0 // indirect
+ k8s.io/klog/v2 v2.110.1 // indirect
+ k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
+ k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
- sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
- sigs.k8s.io/yaml v1.3.0 // indirect
+ sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
+ sigs.k8s.io/yaml v1.4.0 // indirect
)
diff --git a/go.sum b/go.sum
index 43ed29b..92c4457 100644
--- a/go.sum
+++ b/go.sum
@@ -1,79 +1,56 @@
-cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
-github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
-github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
-github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
-github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/datainfrahq/operator-runtime v0.0.2-0.20230425161705-667c247a660b h1:BuG3c4Gh7l44zBdEGiwXQHwI0f2nZ3igBjpByr89928=
github.com/datainfrahq/operator-runtime v0.0.2-0.20230425161705-667c247a660b/go.mod h1:Pd4ny0zdmpQIBYtZnK1knh0DFqUQ6LIdi71DsAXDr3E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
-github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE=
-github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
-github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
-github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
+github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww=
-github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
-github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
-github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
+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.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
+github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
-github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo=
-github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA=
+github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
+github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
+github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
-github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8=
-github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
+github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
+github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
-github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
-github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
-github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
-github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
-github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
-github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
-github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
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/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54=
-github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ=
-github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
-github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+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.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
-github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
+github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
@@ -81,25 +58,23 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
-github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
-github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
-github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
+github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg=
+github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -107,184 +82,129 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
-github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q=
-github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
-github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU=
-github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4=
-github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+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/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
+github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI=
-github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
-github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
-github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
-github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
-github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
-github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
-github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
-github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
+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/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
+github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
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.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
-go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
-go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
-go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
-go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
-go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
-go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
-go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
-go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
+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=
+go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
-golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
-golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
+golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
-golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
-golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
-golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
-golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
-golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
-golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
-golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
+golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
+golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4=
+golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
-golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
-golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
+golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
+golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
+golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
-golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
-golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
-golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
+golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA=
+golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-gomodules.xyz/jsonpatch/v2 v2.3.0 h1:8NFhfS6gzxNqjLIYnZxg319wZ5Qjnx4m/CcX+Klzazc=
-gomodules.xyz/jsonpatch/v2 v2.3.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
-google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
-google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+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.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
-google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
-google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
-google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
-google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
-google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-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=
-google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
-google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
-google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
-google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
+google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
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.0-20200615113413-eeeca48fe776/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=
-honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-k8s.io/api v0.27.7 h1:7yG4D3t/q4utJe2ptlRw9aPuxcSmroTsYxsofkQNl/A=
-k8s.io/api v0.27.7/go.mod h1:ZNExI/Lhrs9YrLgVWx6jjHZdoWCTXfBXuFjt1X6olro=
-k8s.io/apiextensions-apiserver v0.27.7 h1:YqIOwZAUokzxJIjunmUd4zS1v3JhK34EPXn+pP0/bsU=
-k8s.io/apiextensions-apiserver v0.27.7/go.mod h1:x0p+b5a955lfPz9gaDeBy43obM12s+N9dNHK6+dUL+g=
-k8s.io/apimachinery v0.27.7 h1:Gxgtb7Y/Rsu8ymgmUEaiErkxa6RY4oTd8kNUI6SUR58=
-k8s.io/apimachinery v0.27.7/go.mod h1:jBGQgTjkw99ef6q5hv1YurDd3BqKDk9YRxmX0Ozo0i8=
-k8s.io/client-go v0.27.7 h1:+Xgh9OOKv6A3qdD4Dnl/0VOI5EvAv+0s/OseDxVVTwQ=
-k8s.io/client-go v0.27.7/go.mod h1:dZ2kqcalYp5YZ2EV12XIMc77G6PxHWOJp/kclZr4+5Q=
-k8s.io/component-base v0.27.7 h1:kngM58HR9W9Nqpv7e4rpdRyWnKl/ABpUhLAZ+HoliMs=
-k8s.io/component-base v0.27.7/go.mod h1:YGjlCVL1oeKvG3HSciyPHFh+LCjIEqsxz4BDR3cfHRs=
-k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
-k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
-k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg=
-k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg=
-k8s.io/utils v0.0.0-20230209194617-a36077c30491 h1:r0BAOLElQnnFhE/ApUsg3iHdVYYPBjNSSOMowRZxxsY=
-k8s.io/utils v0.0.0-20230209194617-a36077c30491/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
-sigs.k8s.io/controller-runtime v0.15.3 h1:L+t5heIaI3zeejoIyyvLQs5vTVu/67IU2FfisVzFlBc=
-sigs.k8s.io/controller-runtime v0.15.3/go.mod h1:kp4jckA4vTx281S/0Yk2LFEEQe67mjg+ev/yknv47Ds=
+k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A=
+k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA=
+k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0=
+k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc=
+k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o=
+k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis=
+k8s.io/client-go v0.29.0 h1:KmlDtFcrdUzOYrBhXHgKw5ycWzc3ryPX5mQe0SkG3y8=
+k8s.io/client-go v0.29.0/go.mod h1:yLkXH4HKMAywcrD82KMSmfYg2DlE8mepPR4JGSo5n38=
+k8s.io/component-base v0.29.0 h1:T7rjd5wvLnPBV1vC4zWd/iWRbV8Mdxs+nGaoaFzGw3s=
+k8s.io/component-base v0.29.0/go.mod h1:sADonFTQ9Zc9yFLghpDpmNXEdHyQmFIGbiuZbqAXQ1M=
+k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0=
+k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo=
+k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780=
+k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA=
+k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
+k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+sigs.k8s.io/controller-runtime v0.17.0 h1:fjJQf8Ukya+VjogLO6/bNX9HE6Y2xpsO5+fyS26ur/s=
+sigs.k8s.io/controller-runtime v0.17.0/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.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
-sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
-sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
-sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
+sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
+sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
+sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
+sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
diff --git a/main.go b/main.go
index a826a52..09d4e24 100644
--- a/main.go
+++ b/main.go
@@ -25,7 +25,10 @@ import (
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
// to ensure that exec-entrypoint and run can make use of them.
_ "k8s.io/client-go/plugin/pkg/client/auth"
+ "k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/cache"
+ "sigs.k8s.io/controller-runtime/pkg/metrics/server"
+ "sigs.k8s.io/controller-runtime/pkg/webhook"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
@@ -70,14 +73,18 @@ func main() {
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
- Scheme: scheme,
- MetricsBindAddress: metricsAddr,
- Port: 9443,
+ Scheme: scheme,
+ Metrics: server.Options{
+ BindAddress: metricsAddr,
+ },
+ WebhookServer: webhook.NewServer(webhook.Options{
+ Port: 9443,
+ }),
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
LeaderElectionID: "e6946145.apache.org",
- Namespace: os.Getenv("WATCH_NAMESPACE"),
- NewCache: watchNamespaceCache(),
+ //Namespace: os.Getenv("WATCH_NAMESPACE"),
+ NewCache: watchNamespaceCache(),
// LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily
// when the Manager ends. This requires the binary to immediately end when the
// Manager is stopped, otherwise, this setting is unsafe. Setting this significantly
@@ -124,16 +131,19 @@ func main() {
}
func watchNamespaceCache() cache.NewCacheFunc {
- var managerWatchCache cache.NewCacheFunc
ns := strings.Split(watchNamespace, ",")
- if len(ns) > 1 {
- for i := range ns {
- ns[i] = strings.TrimSpace(ns[i])
+ if len(ns) > 0 && watchNamespace != "" {
+ return func(config *rest.Config, opts cache.Options) (cache.Cache, error) {
+ opts.DefaultNamespaces = make(map[string]cache.Config)
+ for _, namespace := range ns {
+ namespace = strings.TrimSpace(namespace)
+ if namespace != "" {
+ opts.DefaultNamespaces[namespace] = cache.Config{}
+ }
+ }
+ return cache.New(config, opts)
}
- managerWatchCache = cache.MultiNamespacedCacheBuilder(ns)
- return managerWatchCache
}
- managerWatchCache = (cache.NewCacheFunc)(nil)
- return managerWatchCache
+ return nil
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org