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:
parent
9030520e24
commit
1227fc2e1c
|
|
@ -447,8 +447,7 @@ spec:
|
||||||
default: 20m
|
default: 20m
|
||||||
description: timeout for successful migration of master pods from
|
description: timeout for successful migration of master pods from
|
||||||
unschedulable node
|
unschedulable node
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
node_readiness_label:
|
node_readiness_label:
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
type: string
|
type: string
|
||||||
|
|
@ -521,8 +520,7 @@ spec:
|
||||||
default: 5m
|
default: 5m
|
||||||
description: Postgres pods are terminated forcefully after this
|
description: Postgres pods are terminated forcefully after this
|
||||||
timeout
|
timeout
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
secret_name_template:
|
secret_name_template:
|
||||||
default: '{username}.{cluster}.credentials.{tprkind}.{tprgroup}'
|
default: '{username}.{cluster}.credentials.{tprkind}.{tprgroup}'
|
||||||
description: |-
|
description: |-
|
||||||
|
|
@ -783,13 +781,11 @@ spec:
|
||||||
repair_period:
|
repair_period:
|
||||||
default: 5m
|
default: 5m
|
||||||
description: period between consecutive repair requests
|
description: period between consecutive repair requests
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
resync_period:
|
resync_period:
|
||||||
default: 30m
|
default: 30m
|
||||||
description: period between consecutive sync requests
|
description: period between consecutive sync requests
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
scalyr:
|
scalyr:
|
||||||
description: ScalyrConfiguration defines the configuration for ScalyrAPI
|
description: ScalyrConfiguration defines the configuration for ScalyrAPI
|
||||||
properties:
|
properties:
|
||||||
|
|
@ -885,48 +881,40 @@ spec:
|
||||||
default: 1s
|
default: 1s
|
||||||
description: interval between consecutive attempts of operator
|
description: interval between consecutive attempts of operator
|
||||||
calling the Patroni API
|
calling the Patroni API
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
patroni_api_check_timeout:
|
patroni_api_check_timeout:
|
||||||
default: 5s
|
default: 5s
|
||||||
description: timeout when waiting for successful response from
|
description: timeout when waiting for successful response from
|
||||||
Patroni API
|
Patroni API
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
pod_deletion_wait_timeout:
|
pod_deletion_wait_timeout:
|
||||||
default: 10m
|
default: 10m
|
||||||
description: timeout when waiting for the Postgres pods to be
|
description: timeout when waiting for the Postgres pods to be
|
||||||
deleted
|
deleted
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
pod_label_wait_timeout:
|
pod_label_wait_timeout:
|
||||||
default: 10m
|
default: 10m
|
||||||
description: timeout when waiting for pod role and cluster labels
|
description: timeout when waiting for pod role and cluster labels
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
ready_wait_interval:
|
ready_wait_interval:
|
||||||
default: 4s
|
default: 4s
|
||||||
description: interval between consecutive attempts waiting for
|
description: interval between consecutive attempts waiting for
|
||||||
postgresql CRD to be created
|
postgresql CRD to be created
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
ready_wait_timeout:
|
ready_wait_timeout:
|
||||||
default: 30s
|
default: 30s
|
||||||
description: timeout for the complete postgres CRD creation
|
description: timeout for the complete postgres CRD creation
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
resource_check_interval:
|
resource_check_interval:
|
||||||
default: 3s
|
default: 3s
|
||||||
description: interval to wait between consecutive attempts to
|
description: interval to wait between consecutive attempts to
|
||||||
check for some K8s resources
|
check for some K8s resources
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
resource_check_timeout:
|
resource_check_timeout:
|
||||||
default: 10m
|
default: 10m
|
||||||
description: timeout when waiting for the presence of a certain
|
description: timeout when waiting for the presence of a certain
|
||||||
K8s resource
|
K8s resource
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
type: object
|
type: object
|
||||||
users:
|
users:
|
||||||
description: PostgresUsersConfiguration defines the system users of
|
description: PostgresUsersConfiguration defines the system users of
|
||||||
|
|
|
||||||
|
|
@ -447,8 +447,7 @@ spec:
|
||||||
default: 20m
|
default: 20m
|
||||||
description: timeout for successful migration of master pods from
|
description: timeout for successful migration of master pods from
|
||||||
unschedulable node
|
unschedulable node
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
node_readiness_label:
|
node_readiness_label:
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
type: string
|
type: string
|
||||||
|
|
@ -521,8 +520,7 @@ spec:
|
||||||
default: 5m
|
default: 5m
|
||||||
description: Postgres pods are terminated forcefully after this
|
description: Postgres pods are terminated forcefully after this
|
||||||
timeout
|
timeout
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
secret_name_template:
|
secret_name_template:
|
||||||
default: '{username}.{cluster}.credentials.{tprkind}.{tprgroup}'
|
default: '{username}.{cluster}.credentials.{tprkind}.{tprgroup}'
|
||||||
description: |-
|
description: |-
|
||||||
|
|
@ -783,13 +781,11 @@ spec:
|
||||||
repair_period:
|
repair_period:
|
||||||
default: 5m
|
default: 5m
|
||||||
description: period between consecutive repair requests
|
description: period between consecutive repair requests
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
resync_period:
|
resync_period:
|
||||||
default: 30m
|
default: 30m
|
||||||
description: period between consecutive sync requests
|
description: period between consecutive sync requests
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
scalyr:
|
scalyr:
|
||||||
description: ScalyrConfiguration defines the configuration for ScalyrAPI
|
description: ScalyrConfiguration defines the configuration for ScalyrAPI
|
||||||
properties:
|
properties:
|
||||||
|
|
@ -885,48 +881,40 @@ spec:
|
||||||
default: 1s
|
default: 1s
|
||||||
description: interval between consecutive attempts of operator
|
description: interval between consecutive attempts of operator
|
||||||
calling the Patroni API
|
calling the Patroni API
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
patroni_api_check_timeout:
|
patroni_api_check_timeout:
|
||||||
default: 5s
|
default: 5s
|
||||||
description: timeout when waiting for successful response from
|
description: timeout when waiting for successful response from
|
||||||
Patroni API
|
Patroni API
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
pod_deletion_wait_timeout:
|
pod_deletion_wait_timeout:
|
||||||
default: 10m
|
default: 10m
|
||||||
description: timeout when waiting for the Postgres pods to be
|
description: timeout when waiting for the Postgres pods to be
|
||||||
deleted
|
deleted
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
pod_label_wait_timeout:
|
pod_label_wait_timeout:
|
||||||
default: 10m
|
default: 10m
|
||||||
description: timeout when waiting for pod role and cluster labels
|
description: timeout when waiting for pod role and cluster labels
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
ready_wait_interval:
|
ready_wait_interval:
|
||||||
default: 4s
|
default: 4s
|
||||||
description: interval between consecutive attempts waiting for
|
description: interval between consecutive attempts waiting for
|
||||||
postgresql CRD to be created
|
postgresql CRD to be created
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
ready_wait_timeout:
|
ready_wait_timeout:
|
||||||
default: 30s
|
default: 30s
|
||||||
description: timeout for the complete postgres CRD creation
|
description: timeout for the complete postgres CRD creation
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
resource_check_interval:
|
resource_check_interval:
|
||||||
default: 3s
|
default: 3s
|
||||||
description: interval to wait between consecutive attempts to
|
description: interval to wait between consecutive attempts to
|
||||||
check for some K8s resources
|
check for some K8s resources
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
resource_check_timeout:
|
resource_check_timeout:
|
||||||
default: 10m
|
default: 10m
|
||||||
description: timeout when waiting for the presence of a certain
|
description: timeout when waiting for the presence of a certain
|
||||||
K8s resource
|
K8s resource
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
type: object
|
type: object
|
||||||
users:
|
users:
|
||||||
description: PostgresUsersConfiguration defines the system users of
|
description: PostgresUsersConfiguration defines the system users of
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type postgresqlCopy Postgresql
|
type postgresqlCopy Postgresql
|
||||||
|
|
@ -120,29 +119,3 @@ func (p *Postgresql) UnmarshalJSON(data []byte) error {
|
||||||
|
|
||||||
return nil
|
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 (
|
import (
|
||||||
"github.com/zalando/postgres-operator/pkg/util/config"
|
"github.com/zalando/postgres-operator/pkg/util/config"
|
||||||
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/zalando/postgres-operator/pkg/spec"
|
"github.com/zalando/postgres-operator/pkg/spec"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/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"`
|
PodServiceAccountRoleBindingDefinition string `json:"pod_service_account_role_binding_definition,omitempty"`
|
||||||
// +kubebuilder:default="5m"
|
// +kubebuilder:default="5m"
|
||||||
// Postgres pods are terminated forcefully after this timeout
|
// 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
|
// +optional
|
||||||
LivenessProbe *v1.Probe `json:"liveness_probe"`
|
LivenessProbe *v1.Probe `json:"liveness_probe"`
|
||||||
SpiloPrivileged bool `json:"spilo_privileged,omitempty"`
|
SpiloPrivileged bool `json:"spilo_privileged,omitempty"`
|
||||||
|
|
@ -143,9 +141,9 @@ type KubernetesMetaConfiguration struct {
|
||||||
PodPriorityClassName string `json:"pod_priority_class_name,omitempty"`
|
PodPriorityClassName string `json:"pod_priority_class_name,omitempty"`
|
||||||
// +kubebuilder:default="20m"
|
// +kubebuilder:default="20m"
|
||||||
// timeout for successful migration of master pods from unschedulable node
|
// timeout for successful migration of master pods from unschedulable node
|
||||||
MasterPodMoveTimeout Duration `json:"master_pod_move_timeout,omitempty"`
|
MasterPodMoveTimeout *metav1.Duration `json:"master_pod_move_timeout,omitempty"`
|
||||||
EnablePodAntiAffinity bool `json:"enable_pod_antiaffinity,omitempty"`
|
EnablePodAntiAffinity bool `json:"enable_pod_antiaffinity,omitempty"`
|
||||||
PodAntiAffinityPreferredDuringScheduling bool `json:"pod_antiaffinity_preferred_during_scheduling,omitempty"`
|
PodAntiAffinityPreferredDuringScheduling bool `json:"pod_antiaffinity_preferred_during_scheduling,omitempty"`
|
||||||
// +kubebuilder:default="kubernetes.io/hostname"
|
// +kubebuilder:default="kubernetes.io/hostname"
|
||||||
PodAntiAffinityTopologyKey string `json:"pod_antiaffinity_topology_key,omitempty"`
|
PodAntiAffinityTopologyKey string `json:"pod_antiaffinity_topology_key,omitempty"`
|
||||||
// +kubebuilder:validation:Enum=ordered_ready;parallel
|
// +kubebuilder:validation:Enum=ordered_ready;parallel
|
||||||
|
|
@ -186,28 +184,28 @@ type PostgresPodResourcesDefaults struct {
|
||||||
type OperatorTimeouts struct {
|
type OperatorTimeouts struct {
|
||||||
// +kubebuilder:default="3s"
|
// +kubebuilder:default="3s"
|
||||||
// interval to wait between consecutive attempts to check for some K8s resources
|
// 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"
|
// +kubebuilder:default="10m"
|
||||||
// timeout when waiting for the presence of a certain K8s resource
|
// 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"
|
// +kubebuilder:default="10m"
|
||||||
// timeout when waiting for pod role and cluster labels
|
// 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"
|
// +kubebuilder:default="10m"
|
||||||
// timeout when waiting for the Postgres pods to be deleted
|
// 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"
|
// +kubebuilder:default="4s"
|
||||||
// interval between consecutive attempts waiting for postgresql CRD to be created
|
// 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"
|
// +kubebuilder:default="30s"
|
||||||
// timeout for the complete postgres CRD creation
|
// 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"
|
// +kubebuilder:default="1s"
|
||||||
// interval between consecutive attempts of operator calling the Patroni API
|
// 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"
|
// +kubebuilder:default="5s"
|
||||||
// timeout when waiting for successful response from Patroni API
|
// 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
|
// LoadBalancerConfiguration defines the LB configuration
|
||||||
|
|
@ -420,10 +418,10 @@ type OperatorConfigurationData struct {
|
||||||
Workers uint32 `json:"workers,omitempty"`
|
Workers uint32 `json:"workers,omitempty"`
|
||||||
// +kubebuilder:default="30m"
|
// +kubebuilder:default="30m"
|
||||||
// period between consecutive sync requests
|
// period between consecutive sync requests
|
||||||
ResyncPeriod Duration `json:"resync_period,omitempty"`
|
ResyncPeriod *metav1.Duration `json:"resync_period,omitempty"`
|
||||||
// +kubebuilder:default="5m"
|
// +kubebuilder:default="5m"
|
||||||
// period between consecutive repair requests
|
// period between consecutive repair requests
|
||||||
RepairPeriod Duration `json:"repair_period,omitempty"`
|
RepairPeriod *metav1.Duration `json:"repair_period,omitempty"`
|
||||||
// +kubebuilder:default=true
|
// +kubebuilder:default=true
|
||||||
EnableMaintenanceWindows *bool `json:"enable_maintenance_windows,omitempty"`
|
EnableMaintenanceWindows *bool `json:"enable_maintenance_windows,omitempty"`
|
||||||
// +kubebuilder:validation:Type=array
|
// +kubebuilder:validation:Type=array
|
||||||
|
|
@ -478,6 +476,3 @@ type OperatorConfigurationData struct {
|
||||||
IgnoreInstanceLimitsAnnotationKey string `json:"ignore_instance_limits_annotation_key,omitempty"`
|
IgnoreInstanceLimitsAnnotationKey string `json:"ignore_instance_limits_annotation_key,omitempty"`
|
||||||
IgnoreResourcesLimitsAnnotationKey string `json:"ignore_resources_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
|
default: 20m
|
||||||
description: timeout for successful migration of master pods from
|
description: timeout for successful migration of master pods from
|
||||||
unschedulable node
|
unschedulable node
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
node_readiness_label:
|
node_readiness_label:
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
type: string
|
type: string
|
||||||
|
|
@ -521,8 +520,7 @@ spec:
|
||||||
default: 5m
|
default: 5m
|
||||||
description: Postgres pods are terminated forcefully after this
|
description: Postgres pods are terminated forcefully after this
|
||||||
timeout
|
timeout
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
secret_name_template:
|
secret_name_template:
|
||||||
default: '{username}.{cluster}.credentials.{tprkind}.{tprgroup}'
|
default: '{username}.{cluster}.credentials.{tprkind}.{tprgroup}'
|
||||||
description: |-
|
description: |-
|
||||||
|
|
@ -783,13 +781,11 @@ spec:
|
||||||
repair_period:
|
repair_period:
|
||||||
default: 5m
|
default: 5m
|
||||||
description: period between consecutive repair requests
|
description: period between consecutive repair requests
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
resync_period:
|
resync_period:
|
||||||
default: 30m
|
default: 30m
|
||||||
description: period between consecutive sync requests
|
description: period between consecutive sync requests
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
scalyr:
|
scalyr:
|
||||||
description: ScalyrConfiguration defines the configuration for ScalyrAPI
|
description: ScalyrConfiguration defines the configuration for ScalyrAPI
|
||||||
properties:
|
properties:
|
||||||
|
|
@ -885,48 +881,40 @@ spec:
|
||||||
default: 1s
|
default: 1s
|
||||||
description: interval between consecutive attempts of operator
|
description: interval between consecutive attempts of operator
|
||||||
calling the Patroni API
|
calling the Patroni API
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
patroni_api_check_timeout:
|
patroni_api_check_timeout:
|
||||||
default: 5s
|
default: 5s
|
||||||
description: timeout when waiting for successful response from
|
description: timeout when waiting for successful response from
|
||||||
Patroni API
|
Patroni API
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
pod_deletion_wait_timeout:
|
pod_deletion_wait_timeout:
|
||||||
default: 10m
|
default: 10m
|
||||||
description: timeout when waiting for the Postgres pods to be
|
description: timeout when waiting for the Postgres pods to be
|
||||||
deleted
|
deleted
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
pod_label_wait_timeout:
|
pod_label_wait_timeout:
|
||||||
default: 10m
|
default: 10m
|
||||||
description: timeout when waiting for pod role and cluster labels
|
description: timeout when waiting for pod role and cluster labels
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
ready_wait_interval:
|
ready_wait_interval:
|
||||||
default: 4s
|
default: 4s
|
||||||
description: interval between consecutive attempts waiting for
|
description: interval between consecutive attempts waiting for
|
||||||
postgresql CRD to be created
|
postgresql CRD to be created
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
ready_wait_timeout:
|
ready_wait_timeout:
|
||||||
default: 30s
|
default: 30s
|
||||||
description: timeout for the complete postgres CRD creation
|
description: timeout for the complete postgres CRD creation
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
resource_check_interval:
|
resource_check_interval:
|
||||||
default: 3s
|
default: 3s
|
||||||
description: interval to wait between consecutive attempts to
|
description: interval to wait between consecutive attempts to
|
||||||
check for some K8s resources
|
check for some K8s resources
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
resource_check_timeout:
|
resource_check_timeout:
|
||||||
default: 10m
|
default: 10m
|
||||||
description: timeout when waiting for the presence of a certain
|
description: timeout when waiting for the presence of a certain
|
||||||
K8s resource
|
K8s resource
|
||||||
format: int64
|
type: string
|
||||||
type: integer
|
|
||||||
type: object
|
type: object
|
||||||
users:
|
users:
|
||||||
description: PostgresUsersConfiguration defines the system users of
|
description: PostgresUsersConfiguration defines the system users of
|
||||||
|
|
|
||||||
|
|
@ -163,6 +163,11 @@ func (in *KubernetesMetaConfiguration) DeepCopyInto(out *KubernetesMetaConfigura
|
||||||
*out = new(bool)
|
*out = new(bool)
|
||||||
**out = **in
|
**out = **in
|
||||||
}
|
}
|
||||||
|
if in.PodTerminateGracePeriod != nil {
|
||||||
|
in, out := &in.PodTerminateGracePeriod, &out.PodTerminateGracePeriod
|
||||||
|
*out = new(metav1.Duration)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
if in.LivenessProbe != nil {
|
if in.LivenessProbe != nil {
|
||||||
in, out := &in.LivenessProbe, &out.LivenessProbe
|
in, out := &in.LivenessProbe, &out.LivenessProbe
|
||||||
*out = new(corev1.Probe)
|
*out = new(corev1.Probe)
|
||||||
|
|
@ -280,6 +285,11 @@ func (in *KubernetesMetaConfiguration) DeepCopyInto(out *KubernetesMetaConfigura
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out.PodEnvironmentConfigMap = in.PodEnvironmentConfigMap
|
out.PodEnvironmentConfigMap = in.PodEnvironmentConfigMap
|
||||||
|
if in.MasterPodMoveTimeout != nil {
|
||||||
|
in, out := &in.MasterPodMoveTimeout, &out.MasterPodMoveTimeout
|
||||||
|
*out = new(metav1.Duration)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
if in.PersistentVolumeClaimRetentionPolicy != nil {
|
if in.PersistentVolumeClaimRetentionPolicy != nil {
|
||||||
in, out := &in.PersistentVolumeClaimRetentionPolicy, &out.PersistentVolumeClaimRetentionPolicy
|
in, out := &in.PersistentVolumeClaimRetentionPolicy, &out.PersistentVolumeClaimRetentionPolicy
|
||||||
*out = make(map[string]string, len(*in))
|
*out = make(map[string]string, len(*in))
|
||||||
|
|
@ -433,6 +443,16 @@ func (in *OperatorConfigurationData) DeepCopyInto(out *OperatorConfigurationData
|
||||||
*out = make([]string, len(*in))
|
*out = make([]string, len(*in))
|
||||||
copy(*out, *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 {
|
if in.EnableMaintenanceWindows != nil {
|
||||||
in, out := &in.EnableMaintenanceWindows, &out.EnableMaintenanceWindows
|
in, out := &in.EnableMaintenanceWindows, &out.EnableMaintenanceWindows
|
||||||
*out = new(bool)
|
*out = new(bool)
|
||||||
|
|
@ -466,7 +486,7 @@ func (in *OperatorConfigurationData) DeepCopyInto(out *OperatorConfigurationData
|
||||||
in.MajorVersionUpgrade.DeepCopyInto(&out.MajorVersionUpgrade)
|
in.MajorVersionUpgrade.DeepCopyInto(&out.MajorVersionUpgrade)
|
||||||
in.Kubernetes.DeepCopyInto(&out.Kubernetes)
|
in.Kubernetes.DeepCopyInto(&out.Kubernetes)
|
||||||
out.PostgresPodResources = in.PostgresPodResources
|
out.PostgresPodResources = in.PostgresPodResources
|
||||||
out.Timeouts = in.Timeouts
|
in.Timeouts.DeepCopyInto(&out.Timeouts)
|
||||||
in.LoadBalancer.DeepCopyInto(&out.LoadBalancer)
|
in.LoadBalancer.DeepCopyInto(&out.LoadBalancer)
|
||||||
out.AWSGCP = in.AWSGCP
|
out.AWSGCP = in.AWSGCP
|
||||||
in.OperatorDebug.DeepCopyInto(&out.OperatorDebug)
|
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.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *OperatorTimeouts) DeepCopyInto(out *OperatorTimeouts) {
|
func (in *OperatorTimeouts) DeepCopyInto(out *OperatorTimeouts) {
|
||||||
*out = *in
|
*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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,8 @@ func TestCreate(t *testing.T) {
|
||||||
var cluster = New(
|
var cluster = New(
|
||||||
Config{
|
Config{
|
||||||
OpConfig: config.Config{
|
OpConfig: config.Config{
|
||||||
PodManagementPolicy: "ordered_ready",
|
PodManagementPolicy: "ordered_ready",
|
||||||
|
PodTerminateGracePeriod: &metav1.Duration{Duration: 600 * time.Second},
|
||||||
Resources: config.Resources{
|
Resources: config.Resources{
|
||||||
ClusterLabels: map[string]string{"application": "spilo"},
|
ClusterLabels: map[string]string{"application": "spilo"},
|
||||||
ClusterNameLabel: "cluster-name",
|
ClusterNameLabel: "cluster-name",
|
||||||
|
|
@ -147,8 +148,8 @@ func TestCreate(t *testing.T) {
|
||||||
DefaultMemoryRequest: "300Mi",
|
DefaultMemoryRequest: "300Mi",
|
||||||
DefaultMemoryLimit: "300Mi",
|
DefaultMemoryLimit: "300Mi",
|
||||||
PodRoleLabel: "spilo-role",
|
PodRoleLabel: "spilo-role",
|
||||||
ResourceCheckInterval: time.Duration(3),
|
ResourceCheckInterval: &metav1.Duration{Duration: 3 * time.Second},
|
||||||
ResourceCheckTimeout: time.Duration(10),
|
ResourceCheckTimeout: &metav1.Duration{Duration: 10 * time.Minute},
|
||||||
},
|
},
|
||||||
EnableFinalizers: util.True(),
|
EnableFinalizers: util.True(),
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -292,7 +292,7 @@ func (c *Cluster) generateConnectionPoolerPodTemplate(role PostgresRole) (
|
||||||
if connectionPoolerSpec == nil {
|
if connectionPoolerSpec == nil {
|
||||||
connectionPoolerSpec = &acidv1.ConnectionPooler{}
|
connectionPoolerSpec = &acidv1.ConnectionPooler{}
|
||||||
}
|
}
|
||||||
gracePeriod := int64(c.OpConfig.PodTerminateGracePeriod.Seconds())
|
gracePeriod := int64(util.CoalesceDuration(c.OpConfig.PodTerminateGracePeriod, "5m").Seconds())
|
||||||
resources, err := c.generateResourceRequirements(
|
resources, err := c.generateResourceRequirements(
|
||||||
connectionPoolerSpec.Resources,
|
connectionPoolerSpec.Resources,
|
||||||
makeDefaultConnectionPoolerResources(&c.OpConfig),
|
makeDefaultConnectionPoolerResources(&c.OpConfig),
|
||||||
|
|
|
||||||
|
|
@ -1165,7 +1165,7 @@ func (c *Cluster) getPodEnvironmentSecretVariables() ([]v1.EnvVar, error) {
|
||||||
|
|
||||||
secret := &v1.Secret{}
|
secret := &v1.Secret{}
|
||||||
var notFoundErr error
|
var notFoundErr error
|
||||||
err := retryutil.Retry(c.OpConfig.ResourceCheckInterval, c.OpConfig.ResourceCheckTimeout,
|
err := retryutil.Retry(c.OpConfig.ResourceCheckInterval.Duration, c.OpConfig.ResourceCheckTimeout.Duration,
|
||||||
func() (bool, error) {
|
func() (bool, error) {
|
||||||
var err error
|
var err error
|
||||||
secret, err = c.KubeClient.Secrets(c.Namespace).Get(
|
secret, err = c.KubeClient.Secrets(c.Namespace).Get(
|
||||||
|
|
@ -1498,7 +1498,7 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef
|
||||||
&tolerationSpec,
|
&tolerationSpec,
|
||||||
c.nodeAffinity(c.OpConfig.NodeReadinessLabel, spec.NodeAffinity),
|
c.nodeAffinity(c.OpConfig.NodeReadinessLabel, spec.NodeAffinity),
|
||||||
spec.SchedulerName,
|
spec.SchedulerName,
|
||||||
int64(c.OpConfig.PodTerminateGracePeriod.Seconds()),
|
int64(util.CoalesceDuration(c.OpConfig.PodTerminateGracePeriod, "5m").Seconds()),
|
||||||
c.OpConfig.PodServiceAccountName,
|
c.OpConfig.PodServiceAccountName,
|
||||||
c.OpConfig.KubeIAMRole,
|
c.OpConfig.KubeIAMRole,
|
||||||
effectivePodPriorityClassName,
|
effectivePodPriorityClassName,
|
||||||
|
|
@ -2431,7 +2431,7 @@ func (c *Cluster) generateLogicalBackupJob() (*batchv1.CronJob, error) {
|
||||||
&tolerationsSpec,
|
&tolerationsSpec,
|
||||||
c.nodeAffinity(c.OpConfig.NodeReadinessLabel, nil),
|
c.nodeAffinity(c.OpConfig.NodeReadinessLabel, nil),
|
||||||
nil,
|
nil,
|
||||||
int64(c.OpConfig.PodTerminateGracePeriod.Seconds()),
|
int64(util.CoalesceDuration(c.OpConfig.PodTerminateGracePeriod, "5m").Seconds()),
|
||||||
c.OpConfig.PodServiceAccountName,
|
c.OpConfig.PodServiceAccountName,
|
||||||
c.OpConfig.KubeIAMRole,
|
c.OpConfig.KubeIAMRole,
|
||||||
"",
|
"",
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
|
@ -361,8 +360,8 @@ func TestPodEnvironmentSecretVariables(t *testing.T) {
|
||||||
opConfig: config.Config{
|
opConfig: config.Config{
|
||||||
Resources: config.Resources{
|
Resources: config.Resources{
|
||||||
PodEnvironmentSecret: testPodEnvironmentObjectNotExists,
|
PodEnvironmentSecret: testPodEnvironmentObjectNotExists,
|
||||||
ResourceCheckInterval: time.Duration(testResourceCheckInterval),
|
ResourceCheckInterval: &metav1.Duration{Duration: testResourceCheckInterval},
|
||||||
ResourceCheckTimeout: time.Duration(testResourceCheckTimeout),
|
ResourceCheckTimeout: &metav1.Duration{Duration: testResourceCheckTimeout},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
err: fmt.Errorf("could not read Secret PodEnvironmentSecretName: still failing after %d retries: secret.core %q not found", maxRetries, testPodEnvironmentObjectNotExists),
|
err: fmt.Errorf("could not read Secret PodEnvironmentSecretName: still failing after %d retries: secret.core %q not found", maxRetries, testPodEnvironmentObjectNotExists),
|
||||||
|
|
@ -372,8 +371,8 @@ func TestPodEnvironmentSecretVariables(t *testing.T) {
|
||||||
opConfig: config.Config{
|
opConfig: config.Config{
|
||||||
Resources: config.Resources{
|
Resources: config.Resources{
|
||||||
PodEnvironmentSecret: testPodEnvironmentSecretNameAPIError,
|
PodEnvironmentSecret: testPodEnvironmentSecretNameAPIError,
|
||||||
ResourceCheckInterval: time.Duration(testResourceCheckInterval),
|
ResourceCheckInterval: &metav1.Duration{Duration: testResourceCheckInterval},
|
||||||
ResourceCheckTimeout: time.Duration(testResourceCheckTimeout),
|
ResourceCheckTimeout: &metav1.Duration{Duration: testResourceCheckTimeout},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
err: fmt.Errorf("could not read Secret PodEnvironmentSecretName: Secret PodEnvironmentSecret API error"),
|
err: fmt.Errorf("could not read Secret PodEnvironmentSecretName: Secret PodEnvironmentSecret API error"),
|
||||||
|
|
@ -383,8 +382,8 @@ func TestPodEnvironmentSecretVariables(t *testing.T) {
|
||||||
opConfig: config.Config{
|
opConfig: config.Config{
|
||||||
Resources: config.Resources{
|
Resources: config.Resources{
|
||||||
PodEnvironmentSecret: testPodEnvironmentSecretName,
|
PodEnvironmentSecret: testPodEnvironmentSecretName,
|
||||||
ResourceCheckInterval: time.Duration(testResourceCheckInterval),
|
ResourceCheckInterval: &metav1.Duration{Duration: testResourceCheckInterval},
|
||||||
ResourceCheckTimeout: time.Duration(testResourceCheckTimeout),
|
ResourceCheckTimeout: &metav1.Duration{Duration: testResourceCheckTimeout},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
envVars: []v1.EnvVar{
|
envVars: []v1.EnvVar{
|
||||||
|
|
@ -848,8 +847,8 @@ func TestGenerateSpiloPodEnvVars(t *testing.T) {
|
||||||
Name: testPodEnvironmentConfigMapName,
|
Name: testPodEnvironmentConfigMapName,
|
||||||
},
|
},
|
||||||
PodEnvironmentSecret: testPodEnvironmentSecretName,
|
PodEnvironmentSecret: testPodEnvironmentSecretName,
|
||||||
ResourceCheckInterval: time.Duration(testResourceCheckInterval),
|
ResourceCheckInterval: &metav1.Duration{Duration: testResourceCheckInterval},
|
||||||
ResourceCheckTimeout: time.Duration(testResourceCheckTimeout),
|
ResourceCheckTimeout: &metav1.Duration{Duration: testResourceCheckTimeout},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
cloneDescription: &acidv1.CloneDescription{},
|
cloneDescription: &acidv1.CloneDescription{},
|
||||||
|
|
@ -877,8 +876,8 @@ func TestGenerateSpiloPodEnvVars(t *testing.T) {
|
||||||
Name: testPodEnvironmentConfigMapName,
|
Name: testPodEnvironmentConfigMapName,
|
||||||
},
|
},
|
||||||
PodEnvironmentSecret: testPodEnvironmentSecretName,
|
PodEnvironmentSecret: testPodEnvironmentSecretName,
|
||||||
ResourceCheckInterval: time.Duration(testResourceCheckInterval),
|
ResourceCheckInterval: &metav1.Duration{Duration: testResourceCheckInterval},
|
||||||
ResourceCheckTimeout: time.Duration(testResourceCheckTimeout),
|
ResourceCheckTimeout: &metav1.Duration{Duration: testResourceCheckTimeout},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
cloneDescription: &acidv1.CloneDescription{},
|
cloneDescription: &acidv1.CloneDescription{},
|
||||||
|
|
@ -968,8 +967,8 @@ func TestGenerateSpiloPodEnvVars(t *testing.T) {
|
||||||
opConfig: config.Config{
|
opConfig: config.Config{
|
||||||
Resources: config.Resources{
|
Resources: config.Resources{
|
||||||
PodEnvironmentSecret: testPodEnvironmentSecretName,
|
PodEnvironmentSecret: testPodEnvironmentSecretName,
|
||||||
ResourceCheckInterval: time.Duration(testResourceCheckInterval),
|
ResourceCheckInterval: &metav1.Duration{Duration: testResourceCheckInterval},
|
||||||
ResourceCheckTimeout: time.Duration(testResourceCheckTimeout),
|
ResourceCheckTimeout: &metav1.Duration{Duration: testResourceCheckTimeout},
|
||||||
},
|
},
|
||||||
WALES3Bucket: "global-s3-bucket",
|
WALES3Bucket: "global-s3-bucket",
|
||||||
},
|
},
|
||||||
|
|
@ -986,8 +985,8 @@ func TestGenerateSpiloPodEnvVars(t *testing.T) {
|
||||||
opConfig: config.Config{
|
opConfig: config.Config{
|
||||||
Resources: config.Resources{
|
Resources: config.Resources{
|
||||||
PodEnvironmentSecret: testPodEnvironmentSecretName,
|
PodEnvironmentSecret: testPodEnvironmentSecretName,
|
||||||
ResourceCheckInterval: time.Duration(testResourceCheckInterval),
|
ResourceCheckInterval: &metav1.Duration{Duration: testResourceCheckInterval},
|
||||||
ResourceCheckTimeout: time.Duration(testResourceCheckTimeout),
|
ResourceCheckTimeout: &metav1.Duration{Duration: testResourceCheckTimeout},
|
||||||
},
|
},
|
||||||
WALES3Bucket: "global-s3-bucket",
|
WALES3Bucket: "global-s3-bucket",
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -334,7 +334,7 @@ func (c *Cluster) getPatroniConfig(pod *v1.Pod) (acidv1.Patroni, map[string]stri
|
||||||
pgParameters map[string]string
|
pgParameters map[string]string
|
||||||
)
|
)
|
||||||
podName := util.NameFromMeta(pod.ObjectMeta)
|
podName := util.NameFromMeta(pod.ObjectMeta)
|
||||||
err := retryutil.Retry(c.OpConfig.PatroniAPICheckInterval, c.OpConfig.PatroniAPICheckTimeout,
|
err := retryutil.Retry(c.OpConfig.PatroniAPICheckInterval.Duration, c.OpConfig.PatroniAPICheckTimeout.Duration,
|
||||||
func() (bool, error) {
|
func() (bool, error) {
|
||||||
var err error
|
var err error
|
||||||
patroniConfig, pgParameters, err = c.patroni.GetConfig(pod)
|
patroniConfig, pgParameters, err = c.patroni.GetConfig(pod)
|
||||||
|
|
@ -355,7 +355,7 @@ func (c *Cluster) getPatroniConfig(pod *v1.Pod) (acidv1.Patroni, map[string]stri
|
||||||
|
|
||||||
func (c *Cluster) getPatroniMemberData(pod *v1.Pod) (patroni.MemberData, error) {
|
func (c *Cluster) getPatroniMemberData(pod *v1.Pod) (patroni.MemberData, error) {
|
||||||
var memberData patroni.MemberData
|
var memberData patroni.MemberData
|
||||||
err := retryutil.Retry(c.OpConfig.PatroniAPICheckInterval, c.OpConfig.PatroniAPICheckTimeout,
|
err := retryutil.Retry(c.OpConfig.PatroniAPICheckInterval.Duration, c.OpConfig.PatroniAPICheckTimeout.Duration,
|
||||||
func() (bool, error) {
|
func() (bool, error) {
|
||||||
var err error
|
var err error
|
||||||
memberData, err = c.patroni.GetMemberData(pod)
|
memberData, err = c.patroni.GetMemberData(pod)
|
||||||
|
|
@ -506,7 +506,7 @@ func (c *Cluster) getSwitchoverCandidate(master *v1.Pod) (spec.NamespacedName, e
|
||||||
candidates := make([]patroni.ClusterMember, 0)
|
candidates := make([]patroni.ClusterMember, 0)
|
||||||
syncCandidates := make([]patroni.ClusterMember, 0)
|
syncCandidates := make([]patroni.ClusterMember, 0)
|
||||||
|
|
||||||
err := retryutil.Retry(c.OpConfig.PatroniAPICheckInterval, c.OpConfig.PatroniAPICheckTimeout,
|
err := retryutil.Retry(c.OpConfig.PatroniAPICheckInterval.Duration, c.OpConfig.PatroniAPICheckTimeout.Duration,
|
||||||
func() (bool, error) {
|
func() (bool, error) {
|
||||||
var err error
|
var err error
|
||||||
members, err = c.patroni.GetClusterMembers(master)
|
members, err = c.patroni.GetClusterMembers(master)
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import (
|
||||||
"github.com/zalando/postgres-operator/pkg/util/k8sutil"
|
"github.com/zalando/postgres-operator/pkg/util/k8sutil"
|
||||||
"github.com/zalando/postgres-operator/pkg/util/patroni"
|
"github.com/zalando/postgres-operator/pkg/util/patroni"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetSwitchoverCandidate(t *testing.T) {
|
func TestGetSwitchoverCandidate(t *testing.T) {
|
||||||
|
|
@ -28,8 +29,8 @@ func TestGetSwitchoverCandidate(t *testing.T) {
|
||||||
var cluster = New(
|
var cluster = New(
|
||||||
Config{
|
Config{
|
||||||
OpConfig: config.Config{
|
OpConfig: config.Config{
|
||||||
PatroniAPICheckInterval: time.Duration(1),
|
PatroniAPICheckInterval: &metav1.Duration{Duration: 1 * time.Second},
|
||||||
PatroniAPICheckTimeout: time.Duration(5),
|
PatroniAPICheckTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
},
|
},
|
||||||
}, k8sutil.KubernetesClient{}, acidv1.Postgresql{}, logger, eventRecorder)
|
}, k8sutil.KubernetesClient{}, acidv1.Postgresql{}, logger, eventRecorder)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -234,7 +234,7 @@ func (c *Cluster) replaceStatefulSet(newStatefulSet *appsv1.StatefulSet) error {
|
||||||
// wait until the statefulset is truly deleted
|
// wait until the statefulset is truly deleted
|
||||||
c.logger.Debug("waiting for the statefulset to be deleted")
|
c.logger.Debug("waiting for the statefulset to be deleted")
|
||||||
|
|
||||||
err = retryutil.Retry(c.OpConfig.ResourceCheckInterval, c.OpConfig.ResourceCheckTimeout,
|
err = retryutil.Retry(c.OpConfig.ResourceCheckInterval.Duration, c.OpConfig.ResourceCheckTimeout.Duration,
|
||||||
func() (bool, error) {
|
func() (bool, error) {
|
||||||
_, err2 := c.KubeClient.StatefulSets(oldStatefulset.Namespace).Get(context.TODO(), oldStatefulset.Name, metav1.GetOptions{})
|
_, err2 := c.KubeClient.StatefulSets(oldStatefulset.Namespace).Get(context.TODO(), oldStatefulset.Name, metav1.GetOptions{})
|
||||||
if err2 == nil {
|
if err2 == nil {
|
||||||
|
|
@ -550,7 +550,7 @@ func (c *Cluster) deletePrimaryPodDisruptionBudget() error {
|
||||||
c.logger.Infof("pod disruption budget %q has been deleted", util.NameFromMeta(c.PrimaryPodDisruptionBudget.ObjectMeta))
|
c.logger.Infof("pod disruption budget %q has been deleted", util.NameFromMeta(c.PrimaryPodDisruptionBudget.ObjectMeta))
|
||||||
c.PrimaryPodDisruptionBudget = nil
|
c.PrimaryPodDisruptionBudget = nil
|
||||||
|
|
||||||
err = retryutil.Retry(c.OpConfig.ResourceCheckInterval, c.OpConfig.ResourceCheckTimeout,
|
err = retryutil.Retry(c.OpConfig.ResourceCheckInterval.Duration, c.OpConfig.ResourceCheckTimeout.Duration,
|
||||||
func() (bool, error) {
|
func() (bool, error) {
|
||||||
_, err2 := c.KubeClient.PodDisruptionBudgets(pdbName.Namespace).Get(context.TODO(), pdbName.Name, metav1.GetOptions{})
|
_, err2 := c.KubeClient.PodDisruptionBudgets(pdbName.Namespace).Get(context.TODO(), pdbName.Name, metav1.GetOptions{})
|
||||||
if err2 == nil {
|
if err2 == nil {
|
||||||
|
|
@ -588,7 +588,7 @@ func (c *Cluster) deleteCriticalOpPodDisruptionBudget() error {
|
||||||
c.logger.Infof("pod disruption budget %q has been deleted", util.NameFromMeta(c.CriticalOpPodDisruptionBudget.ObjectMeta))
|
c.logger.Infof("pod disruption budget %q has been deleted", util.NameFromMeta(c.CriticalOpPodDisruptionBudget.ObjectMeta))
|
||||||
c.CriticalOpPodDisruptionBudget = nil
|
c.CriticalOpPodDisruptionBudget = nil
|
||||||
|
|
||||||
err = retryutil.Retry(c.OpConfig.ResourceCheckInterval, c.OpConfig.ResourceCheckTimeout,
|
err = retryutil.Retry(c.OpConfig.ResourceCheckInterval.Duration, c.OpConfig.ResourceCheckTimeout.Duration,
|
||||||
func() (bool, error) {
|
func() (bool, error) {
|
||||||
_, err2 := c.KubeClient.PodDisruptionBudgets(pdbName.Namespace).Get(context.TODO(), pdbName.Name, metav1.GetOptions{})
|
_, err2 := c.KubeClient.PodDisruptionBudgets(pdbName.Namespace).Get(context.TODO(), pdbName.Name, metav1.GetOptions{})
|
||||||
if err2 == nil {
|
if err2 == nil {
|
||||||
|
|
|
||||||
|
|
@ -101,8 +101,8 @@ func TestSyncStatefulSetsAnnotations(t *testing.T) {
|
||||||
DefaultMemoryLimit: "300Mi",
|
DefaultMemoryLimit: "300Mi",
|
||||||
InheritedAnnotations: []string{inheritedAnnotation},
|
InheritedAnnotations: []string{inheritedAnnotation},
|
||||||
PodRoleLabel: "spilo-role",
|
PodRoleLabel: "spilo-role",
|
||||||
ResourceCheckInterval: time.Duration(3),
|
ResourceCheckInterval: &metav1.Duration{Duration: 3 * time.Second},
|
||||||
ResourceCheckTimeout: time.Duration(10),
|
ResourceCheckTimeout: &metav1.Duration{Duration: 10 * time.Minute},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, client, pg, logger, eventRecorder)
|
}, client, pg, logger, eventRecorder)
|
||||||
|
|
@ -187,8 +187,8 @@ func TestPodAnnotationsSync(t *testing.T) {
|
||||||
var cluster = New(
|
var cluster = New(
|
||||||
Config{
|
Config{
|
||||||
OpConfig: config.Config{
|
OpConfig: config.Config{
|
||||||
PatroniAPICheckInterval: time.Duration(1),
|
PatroniAPICheckInterval: &metav1.Duration{Duration: 1 * time.Second},
|
||||||
PatroniAPICheckTimeout: time.Duration(5),
|
PatroniAPICheckTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
PodManagementPolicy: "ordered_ready",
|
PodManagementPolicy: "ordered_ready",
|
||||||
CustomPodAnnotations: customPodAnnotations,
|
CustomPodAnnotations: customPodAnnotations,
|
||||||
ConnectionPooler: config.ConnectionPooler{
|
ConnectionPooler: config.ConnectionPooler{
|
||||||
|
|
@ -207,8 +207,8 @@ func TestPodAnnotationsSync(t *testing.T) {
|
||||||
DefaultMemoryLimit: "300Mi",
|
DefaultMemoryLimit: "300Mi",
|
||||||
MaxInstances: -1,
|
MaxInstances: -1,
|
||||||
PodRoleLabel: "spilo-role",
|
PodRoleLabel: "spilo-role",
|
||||||
ResourceCheckInterval: time.Duration(3),
|
ResourceCheckInterval: &metav1.Duration{Duration: 3 * time.Second},
|
||||||
ResourceCheckTimeout: time.Duration(10),
|
ResourceCheckTimeout: &metav1.Duration{Duration: 10 * time.Minute},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, client, pg, logger, eventRecorder)
|
}, client, pg, logger, eventRecorder)
|
||||||
|
|
@ -381,8 +381,8 @@ func TestCheckAndSetGlobalPostgreSQLConfiguration(t *testing.T) {
|
||||||
DefaultMemoryRequest: "300Mi",
|
DefaultMemoryRequest: "300Mi",
|
||||||
DefaultMemoryLimit: "300Mi",
|
DefaultMemoryLimit: "300Mi",
|
||||||
PodRoleLabel: "spilo-role",
|
PodRoleLabel: "spilo-role",
|
||||||
ResourceCheckInterval: time.Duration(3),
|
ResourceCheckInterval: &metav1.Duration{Duration: 3 * time.Second},
|
||||||
ResourceCheckTimeout: time.Duration(10),
|
ResourceCheckTimeout: &metav1.Duration{Duration: 10 * time.Minute},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, client, pg, logger, eventRecorder)
|
}, client, pg, logger, eventRecorder)
|
||||||
|
|
@ -694,8 +694,8 @@ func TestSyncStandbyClusterConfiguration(t *testing.T) {
|
||||||
var cluster = New(
|
var cluster = New(
|
||||||
Config{
|
Config{
|
||||||
OpConfig: config.Config{
|
OpConfig: config.Config{
|
||||||
PatroniAPICheckInterval: time.Duration(1),
|
PatroniAPICheckInterval: &metav1.Duration{Duration: 1 * time.Second},
|
||||||
PatroniAPICheckTimeout: time.Duration(5),
|
PatroniAPICheckTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
PodManagementPolicy: "ordered_ready",
|
PodManagementPolicy: "ordered_ready",
|
||||||
Resources: config.Resources{
|
Resources: config.Resources{
|
||||||
ClusterLabels: map[string]string{"application": applicationLabel},
|
ClusterLabels: map[string]string{"application": applicationLabel},
|
||||||
|
|
@ -707,8 +707,8 @@ func TestSyncStandbyClusterConfiguration(t *testing.T) {
|
||||||
MinInstances: int32(-1),
|
MinInstances: int32(-1),
|
||||||
MaxInstances: int32(-1),
|
MaxInstances: int32(-1),
|
||||||
PodRoleLabel: "spilo-role",
|
PodRoleLabel: "spilo-role",
|
||||||
ResourceCheckInterval: time.Duration(3),
|
ResourceCheckInterval: &metav1.Duration{Duration: 3 * time.Second},
|
||||||
ResourceCheckTimeout: time.Duration(10),
|
ResourceCheckTimeout: &metav1.Duration{Duration: 10 * time.Minute},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, client, pg, logger, eventRecorder)
|
}, client, pg, logger, eventRecorder)
|
||||||
|
|
|
||||||
|
|
@ -342,7 +342,7 @@ func (c *Cluster) annotationsSet(annotations map[string]string) map[string]strin
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cluster) waitForPodLabel(podEvents chan PodEvent, stopCh chan struct{}, role *PostgresRole) (*v1.Pod, error) {
|
func (c *Cluster) waitForPodLabel(podEvents chan PodEvent, stopCh chan struct{}, role *PostgresRole) (*v1.Pod, error) {
|
||||||
timeout := time.After(c.OpConfig.PodLabelWaitTimeout)
|
timeout := time.After(c.OpConfig.PodLabelWaitTimeout.Duration)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case podEvent := <-podEvents:
|
case podEvent := <-podEvents:
|
||||||
|
|
@ -364,7 +364,7 @@ func (c *Cluster) waitForPodLabel(podEvents chan PodEvent, stopCh chan struct{},
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cluster) waitForPodDeletion(podEvents chan PodEvent) error {
|
func (c *Cluster) waitForPodDeletion(podEvents chan PodEvent) error {
|
||||||
timeout := time.After(c.OpConfig.PodDeletionWaitTimeout)
|
timeout := time.After(c.OpConfig.PodDeletionWaitTimeout.Duration)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case podEvent := <-podEvents:
|
case podEvent := <-podEvents:
|
||||||
|
|
@ -378,7 +378,7 @@ func (c *Cluster) waitForPodDeletion(podEvents chan PodEvent) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cluster) waitStatefulsetReady() error {
|
func (c *Cluster) waitStatefulsetReady() error {
|
||||||
return retryutil.Retry(c.OpConfig.ResourceCheckInterval, c.OpConfig.ResourceCheckTimeout,
|
return retryutil.Retry(c.OpConfig.ResourceCheckInterval.Duration, c.OpConfig.ResourceCheckTimeout.Duration,
|
||||||
func() (bool, error) {
|
func() (bool, error) {
|
||||||
listOptions := metav1.ListOptions{
|
listOptions := metav1.ListOptions{
|
||||||
LabelSelector: c.labelsSet(false).String(),
|
LabelSelector: c.labelsSet(false).String(),
|
||||||
|
|
@ -428,7 +428,7 @@ func (c *Cluster) _waitPodLabelsReady(anyReplica bool) error {
|
||||||
c.logger.Debug("Waiting for any replica pod to become ready")
|
c.logger.Debug("Waiting for any replica pod to become ready")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := retryutil.Retry(c.OpConfig.ResourceCheckInterval, c.OpConfig.ResourceCheckTimeout,
|
err := retryutil.Retry(c.OpConfig.ResourceCheckInterval.Duration, c.OpConfig.ResourceCheckTimeout.Duration,
|
||||||
func() (bool, error) {
|
func() (bool, error) {
|
||||||
masterCount := 0
|
masterCount := 0
|
||||||
if !anyReplica {
|
if !anyReplica {
|
||||||
|
|
|
||||||
|
|
@ -297,8 +297,8 @@ func newInheritedAnnotationsCluster(client k8sutil.KubernetesClient) (*Cluster,
|
||||||
cluster := New(
|
cluster := New(
|
||||||
Config{
|
Config{
|
||||||
OpConfig: config.Config{
|
OpConfig: config.Config{
|
||||||
PatroniAPICheckInterval: time.Duration(1),
|
PatroniAPICheckInterval: &metav1.Duration{Duration: 1 * time.Second},
|
||||||
PatroniAPICheckTimeout: time.Duration(5),
|
PatroniAPICheckTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
KubernetesUseConfigMaps: true,
|
KubernetesUseConfigMaps: true,
|
||||||
ConnectionPooler: config.ConnectionPooler{
|
ConnectionPooler: config.ConnectionPooler{
|
||||||
ConnectionPoolerDefaultCPURequest: "100m",
|
ConnectionPoolerDefaultCPURequest: "100m",
|
||||||
|
|
@ -318,8 +318,8 @@ func newInheritedAnnotationsCluster(client k8sutil.KubernetesClient) (*Cluster,
|
||||||
DefaultMemoryLimit: "300Mi",
|
DefaultMemoryLimit: "300Mi",
|
||||||
InheritedAnnotations: []string{"owned-by"},
|
InheritedAnnotations: []string{"owned-by"},
|
||||||
PodRoleLabel: "spilo-role",
|
PodRoleLabel: "spilo-role",
|
||||||
ResourceCheckInterval: time.Duration(testResourceCheckInterval),
|
ResourceCheckInterval: &metav1.Duration{Duration: testResourceCheckInterval},
|
||||||
ResourceCheckTimeout: time.Duration(testResourceCheckTimeout),
|
ResourceCheckTimeout: &metav1.Duration{Duration: testResourceCheckTimeout},
|
||||||
MinInstances: -1,
|
MinInstances: -1,
|
||||||
MaxInstances: -1,
|
MaxInstances: -1,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ func (c *Controller) nodeDelete(obj interface{}) {
|
||||||
|
|
||||||
func (c *Controller) moveMasterPodsOffNode(node *v1.Node) {
|
func (c *Controller) moveMasterPodsOffNode(node *v1.Node) {
|
||||||
// retry to move master until configured timeout is reached
|
// retry to move master until configured timeout is reached
|
||||||
err := retryutil.Retry(1*time.Minute, c.opConfig.MasterPodMoveTimeout,
|
err := retryutil.Retry(1*time.Minute, c.opConfig.MasterPodMoveTimeout.Duration,
|
||||||
func() (bool, error) {
|
func() (bool, error) {
|
||||||
err := c.attemptToMoveMasterPodsOffNode(node)
|
err := c.attemptToMoveMasterPodsOffNode(node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"time"
|
|
||||||
|
|
||||||
acidv1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1"
|
acidv1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1"
|
||||||
"github.com/zalando/postgres-operator/pkg/util"
|
"github.com/zalando/postgres-operator/pkg/util"
|
||||||
"github.com/zalando/postgres-operator/pkg/util/config"
|
"github.com/zalando/postgres-operator/pkg/util/config"
|
||||||
|
|
@ -44,8 +42,8 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
|
||||||
result.MaxInstances = fromCRD.MaxInstances
|
result.MaxInstances = fromCRD.MaxInstances
|
||||||
result.IgnoreInstanceLimitsAnnotationKey = fromCRD.IgnoreInstanceLimitsAnnotationKey
|
result.IgnoreInstanceLimitsAnnotationKey = fromCRD.IgnoreInstanceLimitsAnnotationKey
|
||||||
result.IgnoreResourcesLimitsAnnotationKey = fromCRD.IgnoreResourcesLimitsAnnotationKey
|
result.IgnoreResourcesLimitsAnnotationKey = fromCRD.IgnoreResourcesLimitsAnnotationKey
|
||||||
result.ResyncPeriod = util.CoalesceDuration(time.Duration(fromCRD.ResyncPeriod), "30m")
|
result.ResyncPeriod = util.CoalesceDuration(fromCRD.ResyncPeriod, "30m")
|
||||||
result.RepairPeriod = util.CoalesceDuration(time.Duration(fromCRD.RepairPeriod), "5m")
|
result.RepairPeriod = util.CoalesceDuration(fromCRD.RepairPeriod, "5m")
|
||||||
result.SetMemoryRequestToLimit = fromCRD.SetMemoryRequestToLimit
|
result.SetMemoryRequestToLimit = fromCRD.SetMemoryRequestToLimit
|
||||||
result.ShmVolume = util.CoalesceBool(fromCRD.ShmVolume, util.True())
|
result.ShmVolume = util.CoalesceBool(fromCRD.ShmVolume, util.True())
|
||||||
result.SidecarImages = fromCRD.SidecarImages
|
result.SidecarImages = fromCRD.SidecarImages
|
||||||
|
|
@ -75,7 +73,7 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
|
||||||
result.PodServiceAccountRoleBindingDefinition = fromCRD.Kubernetes.PodServiceAccountRoleBindingDefinition
|
result.PodServiceAccountRoleBindingDefinition = fromCRD.Kubernetes.PodServiceAccountRoleBindingDefinition
|
||||||
result.PodEnvironmentConfigMap = fromCRD.Kubernetes.PodEnvironmentConfigMap
|
result.PodEnvironmentConfigMap = fromCRD.Kubernetes.PodEnvironmentConfigMap
|
||||||
result.PodEnvironmentSecret = fromCRD.Kubernetes.PodEnvironmentSecret
|
result.PodEnvironmentSecret = fromCRD.Kubernetes.PodEnvironmentSecret
|
||||||
result.PodTerminateGracePeriod = util.CoalesceDuration(time.Duration(fromCRD.Kubernetes.PodTerminateGracePeriod), "5m")
|
result.PodTerminateGracePeriod = util.CoalesceDuration(fromCRD.Kubernetes.PodTerminateGracePeriod, "5m")
|
||||||
result.LivenessProbe = fromCRD.Kubernetes.LivenessProbe
|
result.LivenessProbe = fromCRD.Kubernetes.LivenessProbe
|
||||||
result.SpiloPrivileged = fromCRD.Kubernetes.SpiloPrivileged
|
result.SpiloPrivileged = fromCRD.Kubernetes.SpiloPrivileged
|
||||||
result.SpiloAllowPrivilegeEscalation = util.CoalesceBool(fromCRD.Kubernetes.SpiloAllowPrivilegeEscalation, util.True())
|
result.SpiloAllowPrivilegeEscalation = util.CoalesceBool(fromCRD.Kubernetes.SpiloAllowPrivilegeEscalation, util.True())
|
||||||
|
|
@ -129,7 +127,7 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
|
||||||
result.EnableSecretsDeletion = util.CoalesceBool(fromCRD.Kubernetes.EnableSecretsDeletion, util.True())
|
result.EnableSecretsDeletion = util.CoalesceBool(fromCRD.Kubernetes.EnableSecretsDeletion, util.True())
|
||||||
result.EnablePersistentVolumeClaimDeletion = util.CoalesceBool(fromCRD.Kubernetes.EnablePersistentVolumeClaimDeletion, util.True())
|
result.EnablePersistentVolumeClaimDeletion = util.CoalesceBool(fromCRD.Kubernetes.EnablePersistentVolumeClaimDeletion, util.True())
|
||||||
result.EnableReadinessProbe = fromCRD.Kubernetes.EnableReadinessProbe
|
result.EnableReadinessProbe = fromCRD.Kubernetes.EnableReadinessProbe
|
||||||
result.MasterPodMoveTimeout = util.CoalesceDuration(time.Duration(fromCRD.Kubernetes.MasterPodMoveTimeout), "10m")
|
result.MasterPodMoveTimeout = util.CoalesceDuration(fromCRD.Kubernetes.MasterPodMoveTimeout, "10m")
|
||||||
result.EnablePodAntiAffinity = fromCRD.Kubernetes.EnablePodAntiAffinity
|
result.EnablePodAntiAffinity = fromCRD.Kubernetes.EnablePodAntiAffinity
|
||||||
result.PodAntiAffinityTopologyKey = util.Coalesce(fromCRD.Kubernetes.PodAntiAffinityTopologyKey, "kubernetes.io/hostname")
|
result.PodAntiAffinityTopologyKey = util.Coalesce(fromCRD.Kubernetes.PodAntiAffinityTopologyKey, "kubernetes.io/hostname")
|
||||||
result.PodAntiAffinityPreferredDuringScheduling = fromCRD.Kubernetes.PodAntiAffinityPreferredDuringScheduling
|
result.PodAntiAffinityPreferredDuringScheduling = fromCRD.Kubernetes.PodAntiAffinityPreferredDuringScheduling
|
||||||
|
|
@ -146,14 +144,14 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
|
||||||
result.MaxMemoryRequest = fromCRD.PostgresPodResources.MaxMemoryRequest
|
result.MaxMemoryRequest = fromCRD.PostgresPodResources.MaxMemoryRequest
|
||||||
|
|
||||||
// timeout config
|
// timeout config
|
||||||
result.ResourceCheckInterval = util.CoalesceDuration(time.Duration(fromCRD.Timeouts.ResourceCheckInterval), "3s")
|
result.ResourceCheckInterval = util.CoalesceDuration(fromCRD.Timeouts.ResourceCheckInterval, "3s")
|
||||||
result.ResourceCheckTimeout = util.CoalesceDuration(time.Duration(fromCRD.Timeouts.ResourceCheckTimeout), "10m")
|
result.ResourceCheckTimeout = util.CoalesceDuration(fromCRD.Timeouts.ResourceCheckTimeout, "10m")
|
||||||
result.PodLabelWaitTimeout = util.CoalesceDuration(time.Duration(fromCRD.Timeouts.PodLabelWaitTimeout), "10m")
|
result.PodLabelWaitTimeout = util.CoalesceDuration(fromCRD.Timeouts.PodLabelWaitTimeout, "10m")
|
||||||
result.PodDeletionWaitTimeout = util.CoalesceDuration(time.Duration(fromCRD.Timeouts.PodDeletionWaitTimeout), "10m")
|
result.PodDeletionWaitTimeout = util.CoalesceDuration(fromCRD.Timeouts.PodDeletionWaitTimeout, "10m")
|
||||||
result.ReadyWaitInterval = util.CoalesceDuration(time.Duration(fromCRD.Timeouts.ReadyWaitInterval), "4s")
|
result.ReadyWaitInterval = util.CoalesceDuration(fromCRD.Timeouts.ReadyWaitInterval, "4s")
|
||||||
result.ReadyWaitTimeout = util.CoalesceDuration(time.Duration(fromCRD.Timeouts.ReadyWaitTimeout), "30s")
|
result.ReadyWaitTimeout = util.CoalesceDuration(fromCRD.Timeouts.ReadyWaitTimeout, "30s")
|
||||||
result.PatroniAPICheckInterval = util.CoalesceDuration(time.Duration(fromCRD.Timeouts.PatroniAPICheckInterval), "1s")
|
result.PatroniAPICheckInterval = util.CoalesceDuration(fromCRD.Timeouts.PatroniAPICheckInterval, "1s")
|
||||||
result.PatroniAPICheckTimeout = util.CoalesceDuration(time.Duration(fromCRD.Timeouts.PatroniAPICheckTimeout), "5s")
|
result.PatroniAPICheckTimeout = util.CoalesceDuration(fromCRD.Timeouts.PatroniAPICheckTimeout, "5s")
|
||||||
|
|
||||||
// load balancer config
|
// load balancer config
|
||||||
result.DbHostedZone = util.Coalesce(fromCRD.LoadBalancer.DbHostedZone, "db.example.com")
|
result.DbHostedZone = util.Coalesce(fromCRD.LoadBalancer.DbHostedZone, "db.example.com")
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import (
|
||||||
|
|
||||||
func (c *Controller) clusterResync(stopCh <-chan struct{}, wg *sync.WaitGroup) {
|
func (c *Controller) clusterResync(stopCh <-chan struct{}, wg *sync.WaitGroup) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
ticker := time.NewTicker(c.opConfig.ResyncPeriod)
|
ticker := time.NewTicker(c.opConfig.ResyncPeriod.Duration)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
|
|
||||||
|
|
@ -3,33 +3,33 @@ package config
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/zalando/postgres-operator/pkg/spec"
|
"github.com/zalando/postgres-operator/pkg/spec"
|
||||||
"github.com/zalando/postgres-operator/pkg/util/constants"
|
"github.com/zalando/postgres-operator/pkg/util/constants"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CRD describes CustomResourceDefinition specific configuration parameters
|
// CRD describes CustomResourceDefinition specific configuration parameters
|
||||||
type CRD struct {
|
type CRD struct {
|
||||||
ReadyWaitInterval time.Duration `name:"ready_wait_interval" default:"4s"`
|
ReadyWaitInterval *metav1.Duration `name:"ready_wait_interval" default:"4s"`
|
||||||
ReadyWaitTimeout time.Duration `name:"ready_wait_timeout" default:"30s"`
|
ReadyWaitTimeout *metav1.Duration `name:"ready_wait_timeout" default:"30s"`
|
||||||
ResyncPeriod time.Duration `name:"resync_period" default:"30m"`
|
ResyncPeriod *metav1.Duration `name:"resync_period" default:"30m"`
|
||||||
RepairPeriod time.Duration `name:"repair_period" default:"5m"`
|
RepairPeriod *metav1.Duration `name:"repair_period" default:"5m"`
|
||||||
EnableCRDRegistration *bool `name:"enable_crd_registration" default:"true"`
|
EnableCRDRegistration *bool `name:"enable_crd_registration" default:"true"`
|
||||||
CRDCategories []string `name:"crd_categories" default:"all"`
|
CRDCategories []string `name:"crd_categories" default:"all"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resources describes kubernetes resource specific configuration parameters
|
// Resources describes kubernetes resource specific configuration parameters
|
||||||
type Resources struct {
|
type Resources struct {
|
||||||
EnableOwnerReferences *bool `name:"enable_owner_references" default:"false"`
|
EnableOwnerReferences *bool `name:"enable_owner_references" default:"false"`
|
||||||
ResourceCheckInterval time.Duration `name:"resource_check_interval" default:"3s"`
|
ResourceCheckInterval *metav1.Duration `name:"resource_check_interval" default:"3s"`
|
||||||
ResourceCheckTimeout time.Duration `name:"resource_check_timeout" default:"10m"`
|
ResourceCheckTimeout *metav1.Duration `name:"resource_check_timeout" default:"10m"`
|
||||||
PodLabelWaitTimeout time.Duration `name:"pod_label_wait_timeout" default:"10m"`
|
PodLabelWaitTimeout *metav1.Duration `name:"pod_label_wait_timeout" default:"10m"`
|
||||||
PodDeletionWaitTimeout time.Duration `name:"pod_deletion_wait_timeout" default:"10m"`
|
PodDeletionWaitTimeout *metav1.Duration `name:"pod_deletion_wait_timeout" default:"10m"`
|
||||||
PodTerminateGracePeriod time.Duration `name:"pod_terminate_grace_period" default:"5m"`
|
PodTerminateGracePeriod *metav1.Duration `name:"pod_terminate_grace_period" default:"5m"`
|
||||||
LivenessProbe *v1.Probe `name:"-"`
|
LivenessProbe *v1.Probe `name:"-"`
|
||||||
SpiloRunAsUser *int64 `name:"spilo_runasuser"`
|
SpiloRunAsUser *int64 `name:"spilo_runasuser"`
|
||||||
SpiloRunAsGroup *int64 `name:"spilo_runasgroup"`
|
SpiloRunAsGroup *int64 `name:"spilo_runasgroup"`
|
||||||
|
|
@ -188,7 +188,7 @@ type Config struct {
|
||||||
// value of this string must be valid JSON or YAML; see initPodServiceAccount
|
// value of this string must be valid JSON or YAML; see initPodServiceAccount
|
||||||
PodServiceAccountDefinition string `name:"pod_service_account_definition" default:""`
|
PodServiceAccountDefinition string `name:"pod_service_account_definition" default:""`
|
||||||
PodServiceAccountRoleBindingDefinition string `name:"pod_service_account_role_binding_definition" default:""`
|
PodServiceAccountRoleBindingDefinition string `name:"pod_service_account_role_binding_definition" default:""`
|
||||||
MasterPodMoveTimeout time.Duration `name:"master_pod_move_timeout" default:"20m"`
|
MasterPodMoveTimeout *metav1.Duration `name:"master_pod_move_timeout" default:"20m"`
|
||||||
DbHostedZone string `name:"db_hosted_zone" default:"db.example.com"`
|
DbHostedZone string `name:"db_hosted_zone" default:"db.example.com"`
|
||||||
AWSRegion string `name:"aws_region" default:"eu-central-1"`
|
AWSRegion string `name:"aws_region" default:"eu-central-1"`
|
||||||
WALES3Bucket string `name:"wal_s3_bucket"`
|
WALES3Bucket string `name:"wal_s3_bucket"`
|
||||||
|
|
@ -242,7 +242,7 @@ type Config struct {
|
||||||
RingLogLines int `name:"ring_log_lines" default:"100"`
|
RingLogLines int `name:"ring_log_lines" default:"100"`
|
||||||
ClusterHistoryEntries int `name:"cluster_history_entries" default:"1000"`
|
ClusterHistoryEntries int `name:"cluster_history_entries" default:"1000"`
|
||||||
TeamAPIRoleConfiguration map[string]string `name:"team_api_role_configuration" default:"log_statement:all"`
|
TeamAPIRoleConfiguration map[string]string `name:"team_api_role_configuration" default:"log_statement:all"`
|
||||||
PodTerminateGracePeriod time.Duration `name:"pod_terminate_grace_period" default:"5m"`
|
PodTerminateGracePeriod *metav1.Duration `name:"pod_terminate_grace_period" default:"5m"`
|
||||||
PodManagementPolicy string `name:"pod_management_policy" default:"ordered_ready"`
|
PodManagementPolicy string `name:"pod_management_policy" default:"ordered_ready"`
|
||||||
EnableReadinessProbe bool `name:"enable_readiness_probe" default:"false"`
|
EnableReadinessProbe bool `name:"enable_readiness_probe" default:"false"`
|
||||||
ProtectedRoles []string `name:"protected_role_names" default:"admin,cron_admin"`
|
ProtectedRoles []string `name:"protected_role_names" default:"admin,cron_admin"`
|
||||||
|
|
@ -258,8 +258,8 @@ type Config struct {
|
||||||
MajorVersionUpgradeTeamAllowList []string `name:"major_version_upgrade_team_allow_list" default:""`
|
MajorVersionUpgradeTeamAllowList []string `name:"major_version_upgrade_team_allow_list" default:""`
|
||||||
MinimalMajorVersion string `name:"minimal_major_version" default:"14"`
|
MinimalMajorVersion string `name:"minimal_major_version" default:"14"`
|
||||||
TargetMajorVersion string `name:"target_major_version" default:"18"`
|
TargetMajorVersion string `name:"target_major_version" default:"18"`
|
||||||
PatroniAPICheckInterval time.Duration `name:"patroni_api_check_interval" default:"1s"`
|
PatroniAPICheckInterval *metav1.Duration `name:"patroni_api_check_interval" default:"1s"`
|
||||||
PatroniAPICheckTimeout time.Duration `name:"patroni_api_check_timeout" default:"5s"`
|
PatroniAPICheckTimeout *metav1.Duration `name:"patroni_api_check_timeout" default:"5s"`
|
||||||
EnablePatroniFailsafeMode *bool `name:"enable_patroni_failsafe_mode" default:"false"`
|
EnablePatroniFailsafeMode *bool `name:"enable_patroni_failsafe_mode" default:"false"`
|
||||||
EnableSecretsDeletion *bool `name:"enable_secrets_deletion" default:"true"`
|
EnableSecretsDeletion *bool `name:"enable_secrets_deletion" default:"true"`
|
||||||
EnablePersistentVolumeClaimDeletion *bool `name:"enable_persistent_volume_claim_deletion" default:"true"`
|
EnablePersistentVolumeClaimDeletion *bool `name:"enable_persistent_volume_claim_deletion" default:"true"`
|
||||||
|
|
|
||||||
|
|
@ -230,16 +230,16 @@ var newFromMapTests = []struct {
|
||||||
{
|
{
|
||||||
description: "duration parsing",
|
description: "duration parsing",
|
||||||
input: map[string]string{
|
input: map[string]string{
|
||||||
"ready_wait_interval": "10s",
|
"patroni_api_check_interval": "1s",
|
||||||
"ready_wait_timeout": "1m",
|
"patroni_api_check_timeout": "5s",
|
||||||
},
|
},
|
||||||
expectPanic: false,
|
expectPanic: false,
|
||||||
validateFunc: func(t *testing.T, cfg *Config) {
|
validateFunc: func(t *testing.T, cfg *Config) {
|
||||||
if cfg.ReadyWaitInterval.Seconds() != 10 {
|
if cfg.PatroniAPICheckInterval.Seconds() != 1 {
|
||||||
t.Errorf("expected ReadyWaitInterval=10s, got %v", cfg.ReadyWaitInterval)
|
t.Errorf("expected check interval of 1s, got %.0fs", cfg.PatroniAPICheckInterval.Seconds())
|
||||||
}
|
}
|
||||||
if cfg.ReadyWaitTimeout.Minutes() != 1 {
|
if cfg.PatroniAPICheckTimeout.Seconds() != 5 {
|
||||||
t.Errorf("expected ReadyWaitTimeout=1m, got %v", cfg.ReadyWaitTimeout)
|
t.Errorf("expected check timeout of 5s, got %.0fs", cfg.PatroniAPICheckTimeout.Seconds())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
type decoder interface {
|
type decoder interface {
|
||||||
|
|
@ -101,13 +103,7 @@ func processField(value string, field reflect.Value) error {
|
||||||
val int64
|
val int64
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
if field.Kind() == reflect.Int64 && typ.PkgPath() == "time" && typ.Name() == "Duration" {
|
val, err = strconv.ParseInt(value, 0, typ.Bits())
|
||||||
var d time.Duration
|
|
||||||
d, err = time.ParseDuration(value)
|
|
||||||
val = int64(d)
|
|
||||||
} else {
|
|
||||||
val, err = strconv.ParseInt(value, 0, typ.Bits())
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -165,6 +161,15 @@ func processField(value string, field reflect.Value) error {
|
||||||
mp.SetMapIndex(k, v)
|
mp.SetMapIndex(k, v)
|
||||||
}
|
}
|
||||||
field.Set(mp)
|
field.Set(mp)
|
||||||
|
case reflect.Struct:
|
||||||
|
if typ.Name() == "Duration" {
|
||||||
|
var d time.Duration
|
||||||
|
d, err := time.ParseDuration(value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
field.Set(reflect.ValueOf(metav1.Duration{Duration: d}))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -311,14 +311,14 @@ func CoalesceBool(val, defaultVal *bool) *bool {
|
||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
// CoalesceDuration works like coalesce but for time.Duration
|
// CoalesceDuration works like coalesce but for metav1.Duration
|
||||||
func CoalesceDuration(val time.Duration, defaultVal string) time.Duration {
|
func CoalesceDuration(val *metav1.Duration, defaultVal string) *metav1.Duration {
|
||||||
if val == 0 {
|
if val == nil || val.Duration == 0 {
|
||||||
duration, err := time.ParseDuration(defaultVal)
|
duration, err := time.ParseDuration(defaultVal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return duration
|
return &metav1.Duration{Duration: duration}
|
||||||
}
|
}
|
||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue