switch to metav1.Duration for timeout options (#3121)

* switch to metav1.Duration for timeout options
* fix custom config parsing and use safe coalesce
This commit is contained in:
Felix Kunde
2026-06-29 10:32:24 +02:00
committed by GitHub
parent 9030520e24
commit 1227fc2e1c
23 changed files with 214 additions and 218 deletions
-27
View File
@@ -4,7 +4,6 @@ import (
"encoding/json"
"fmt"
"strings"
"time"
)
type postgresqlCopy Postgresql
@@ -120,29 +119,3 @@ func (p *Postgresql) UnmarshalJSON(data []byte) error {
return nil
}
// UnmarshalJSON convert to Duration from byte slice of json
func (d *Duration) UnmarshalJSON(b []byte) error {
var (
v interface{}
err error
)
if err = json.Unmarshal(b, &v); err != nil {
return err
}
switch val := v.(type) {
case string:
t, err := time.ParseDuration(val)
if err != nil {
return err
}
*d = Duration(t)
return nil
case float64:
t := time.Duration(val)
*d = Duration(t)
return nil
default:
return fmt.Errorf("could not recognize type %T as a valid type to unmarshal to Duration", val)
}
}
@@ -5,8 +5,6 @@ package v1
import (
"github.com/zalando/postgres-operator/pkg/util/config"
"time"
"github.com/zalando/postgres-operator/pkg/spec"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -78,7 +76,7 @@ type KubernetesMetaConfiguration struct {
PodServiceAccountRoleBindingDefinition string `json:"pod_service_account_role_binding_definition,omitempty"`
// +kubebuilder:default="5m"
// Postgres pods are terminated forcefully after this timeout
PodTerminateGracePeriod Duration `json:"pod_terminate_grace_period,omitempty"`
PodTerminateGracePeriod *metav1.Duration `json:"pod_terminate_grace_period,omitempty"`
// +optional
LivenessProbe *v1.Probe `json:"liveness_probe"`
SpiloPrivileged bool `json:"spilo_privileged,omitempty"`
@@ -143,9 +141,9 @@ type KubernetesMetaConfiguration struct {
PodPriorityClassName string `json:"pod_priority_class_name,omitempty"`
// +kubebuilder:default="20m"
// timeout for successful migration of master pods from unschedulable node
MasterPodMoveTimeout Duration `json:"master_pod_move_timeout,omitempty"`
EnablePodAntiAffinity bool `json:"enable_pod_antiaffinity,omitempty"`
PodAntiAffinityPreferredDuringScheduling bool `json:"pod_antiaffinity_preferred_during_scheduling,omitempty"`
MasterPodMoveTimeout *metav1.Duration `json:"master_pod_move_timeout,omitempty"`
EnablePodAntiAffinity bool `json:"enable_pod_antiaffinity,omitempty"`
PodAntiAffinityPreferredDuringScheduling bool `json:"pod_antiaffinity_preferred_during_scheduling,omitempty"`
// +kubebuilder:default="kubernetes.io/hostname"
PodAntiAffinityTopologyKey string `json:"pod_antiaffinity_topology_key,omitempty"`
// +kubebuilder:validation:Enum=ordered_ready;parallel
@@ -186,28 +184,28 @@ type PostgresPodResourcesDefaults struct {
type OperatorTimeouts struct {
// +kubebuilder:default="3s"
// interval to wait between consecutive attempts to check for some K8s resources
ResourceCheckInterval Duration `json:"resource_check_interval,omitempty"`
ResourceCheckInterval *metav1.Duration `json:"resource_check_interval,omitempty"`
// +kubebuilder:default="10m"
// timeout when waiting for the presence of a certain K8s resource
ResourceCheckTimeout Duration `json:"resource_check_timeout,omitempty"`
ResourceCheckTimeout *metav1.Duration `json:"resource_check_timeout,omitempty"`
// +kubebuilder:default="10m"
// timeout when waiting for pod role and cluster labels
PodLabelWaitTimeout Duration `json:"pod_label_wait_timeout,omitempty"`
PodLabelWaitTimeout *metav1.Duration `json:"pod_label_wait_timeout,omitempty"`
// +kubebuilder:default="10m"
// timeout when waiting for the Postgres pods to be deleted
PodDeletionWaitTimeout Duration `json:"pod_deletion_wait_timeout,omitempty"`
PodDeletionWaitTimeout *metav1.Duration `json:"pod_deletion_wait_timeout,omitempty"`
// +kubebuilder:default="4s"
// interval between consecutive attempts waiting for postgresql CRD to be created
ReadyWaitInterval Duration `json:"ready_wait_interval,omitempty"`
ReadyWaitInterval *metav1.Duration `json:"ready_wait_interval,omitempty"`
// +kubebuilder:default="30s"
// timeout for the complete postgres CRD creation
ReadyWaitTimeout Duration `json:"ready_wait_timeout,omitempty"`
ReadyWaitTimeout *metav1.Duration `json:"ready_wait_timeout,omitempty"`
// +kubebuilder:default="1s"
// interval between consecutive attempts of operator calling the Patroni API
PatroniAPICheckInterval Duration `json:"patroni_api_check_interval,omitempty"`
PatroniAPICheckInterval *metav1.Duration `json:"patroni_api_check_interval,omitempty"`
// +kubebuilder:default="5s"
// timeout when waiting for successful response from Patroni API
PatroniAPICheckTimeout Duration `json:"patroni_api_check_timeout,omitempty"`
PatroniAPICheckTimeout *metav1.Duration `json:"patroni_api_check_timeout,omitempty"`
}
// LoadBalancerConfiguration defines the LB configuration
@@ -420,10 +418,10 @@ type OperatorConfigurationData struct {
Workers uint32 `json:"workers,omitempty"`
// +kubebuilder:default="30m"
// period between consecutive sync requests
ResyncPeriod Duration `json:"resync_period,omitempty"`
ResyncPeriod *metav1.Duration `json:"resync_period,omitempty"`
// +kubebuilder:default="5m"
// period between consecutive repair requests
RepairPeriod Duration `json:"repair_period,omitempty"`
RepairPeriod *metav1.Duration `json:"repair_period,omitempty"`
// +kubebuilder:default=true
EnableMaintenanceWindows *bool `json:"enable_maintenance_windows,omitempty"`
// +kubebuilder:validation:Type=array
@@ -478,6 +476,3 @@ type OperatorConfigurationData struct {
IgnoreInstanceLimitsAnnotationKey string `json:"ignore_instance_limits_annotation_key,omitempty"`
IgnoreResourcesLimitsAnnotationKey string `json:"ignore_resources_limits_annotation_key,omitempty"`
}
// Duration shortens this frequently used name
type Duration time.Duration
@@ -447,8 +447,7 @@ spec:
default: 20m
description: timeout for successful migration of master pods from
unschedulable node
format: int64
type: integer
type: string
node_readiness_label:
additionalProperties:
type: string
@@ -521,8 +520,7 @@ spec:
default: 5m
description: Postgres pods are terminated forcefully after this
timeout
format: int64
type: integer
type: string
secret_name_template:
default: '{username}.{cluster}.credentials.{tprkind}.{tprgroup}'
description: |-
@@ -783,13 +781,11 @@ spec:
repair_period:
default: 5m
description: period between consecutive repair requests
format: int64
type: integer
type: string
resync_period:
default: 30m
description: period between consecutive sync requests
format: int64
type: integer
type: string
scalyr:
description: ScalyrConfiguration defines the configuration for ScalyrAPI
properties:
@@ -885,48 +881,40 @@ spec:
default: 1s
description: interval between consecutive attempts of operator
calling the Patroni API
format: int64
type: integer
type: string
patroni_api_check_timeout:
default: 5s
description: timeout when waiting for successful response from
Patroni API
format: int64
type: integer
type: string
pod_deletion_wait_timeout:
default: 10m
description: timeout when waiting for the Postgres pods to be
deleted
format: int64
type: integer
type: string
pod_label_wait_timeout:
default: 10m
description: timeout when waiting for pod role and cluster labels
format: int64
type: integer
type: string
ready_wait_interval:
default: 4s
description: interval between consecutive attempts waiting for
postgresql CRD to be created
format: int64
type: integer
type: string
ready_wait_timeout:
default: 30s
description: timeout for the complete postgres CRD creation
format: int64
type: integer
type: string
resource_check_interval:
default: 3s
description: interval to wait between consecutive attempts to
check for some K8s resources
format: int64
type: integer
type: string
resource_check_timeout:
default: 10m
description: timeout when waiting for the presence of a certain
K8s resource
format: int64
type: integer
type: string
type: object
users:
description: PostgresUsersConfiguration defines the system users of
@@ -163,6 +163,11 @@ func (in *KubernetesMetaConfiguration) DeepCopyInto(out *KubernetesMetaConfigura
*out = new(bool)
**out = **in
}
if in.PodTerminateGracePeriod != nil {
in, out := &in.PodTerminateGracePeriod, &out.PodTerminateGracePeriod
*out = new(metav1.Duration)
**out = **in
}
if in.LivenessProbe != nil {
in, out := &in.LivenessProbe, &out.LivenessProbe
*out = new(corev1.Probe)
@@ -280,6 +285,11 @@ func (in *KubernetesMetaConfiguration) DeepCopyInto(out *KubernetesMetaConfigura
}
}
out.PodEnvironmentConfigMap = in.PodEnvironmentConfigMap
if in.MasterPodMoveTimeout != nil {
in, out := &in.MasterPodMoveTimeout, &out.MasterPodMoveTimeout
*out = new(metav1.Duration)
**out = **in
}
if in.PersistentVolumeClaimRetentionPolicy != nil {
in, out := &in.PersistentVolumeClaimRetentionPolicy, &out.PersistentVolumeClaimRetentionPolicy
*out = make(map[string]string, len(*in))
@@ -433,6 +443,16 @@ func (in *OperatorConfigurationData) DeepCopyInto(out *OperatorConfigurationData
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.ResyncPeriod != nil {
in, out := &in.ResyncPeriod, &out.ResyncPeriod
*out = new(metav1.Duration)
**out = **in
}
if in.RepairPeriod != nil {
in, out := &in.RepairPeriod, &out.RepairPeriod
*out = new(metav1.Duration)
**out = **in
}
if in.EnableMaintenanceWindows != nil {
in, out := &in.EnableMaintenanceWindows, &out.EnableMaintenanceWindows
*out = new(bool)
@@ -466,7 +486,7 @@ func (in *OperatorConfigurationData) DeepCopyInto(out *OperatorConfigurationData
in.MajorVersionUpgrade.DeepCopyInto(&out.MajorVersionUpgrade)
in.Kubernetes.DeepCopyInto(&out.Kubernetes)
out.PostgresPodResources = in.PostgresPodResources
out.Timeouts = in.Timeouts
in.Timeouts.DeepCopyInto(&out.Timeouts)
in.LoadBalancer.DeepCopyInto(&out.LoadBalancer)
out.AWSGCP = in.AWSGCP
in.OperatorDebug.DeepCopyInto(&out.OperatorDebug)
@@ -582,6 +602,46 @@ func (in *OperatorLogicalBackupConfiguration) DeepCopy() *OperatorLogicalBackupC
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OperatorTimeouts) DeepCopyInto(out *OperatorTimeouts) {
*out = *in
if in.ResourceCheckInterval != nil {
in, out := &in.ResourceCheckInterval, &out.ResourceCheckInterval
*out = new(metav1.Duration)
**out = **in
}
if in.ResourceCheckTimeout != nil {
in, out := &in.ResourceCheckTimeout, &out.ResourceCheckTimeout
*out = new(metav1.Duration)
**out = **in
}
if in.PodLabelWaitTimeout != nil {
in, out := &in.PodLabelWaitTimeout, &out.PodLabelWaitTimeout
*out = new(metav1.Duration)
**out = **in
}
if in.PodDeletionWaitTimeout != nil {
in, out := &in.PodDeletionWaitTimeout, &out.PodDeletionWaitTimeout
*out = new(metav1.Duration)
**out = **in
}
if in.ReadyWaitInterval != nil {
in, out := &in.ReadyWaitInterval, &out.ReadyWaitInterval
*out = new(metav1.Duration)
**out = **in
}
if in.ReadyWaitTimeout != nil {
in, out := &in.ReadyWaitTimeout, &out.ReadyWaitTimeout
*out = new(metav1.Duration)
**out = **in
}
if in.PatroniAPICheckInterval != nil {
in, out := &in.PatroniAPICheckInterval, &out.PatroniAPICheckInterval
*out = new(metav1.Duration)
**out = **in
}
if in.PatroniAPICheckTimeout != nil {
in, out := &in.PatroniAPICheckTimeout, &out.PatroniAPICheckTimeout
*out = new(metav1.Duration)
**out = **in
}
return
}