mirror of
https://github.com/zalando/postgres-operator.git
synced 2026-10-05 04:21:41 +02:00
define annotations for delete protection
This commit is contained in:
+89
-1
@@ -7,6 +7,7 @@ import warnings
|
||||
import os
|
||||
import yaml
|
||||
|
||||
from datetime import datetime
|
||||
from kubernetes import client, config
|
||||
|
||||
|
||||
@@ -614,6 +615,73 @@ class EndToEndTestCase(unittest.TestCase):
|
||||
"Origin": 2,
|
||||
})
|
||||
|
||||
@timeout_decorator.timeout(TEST_TIMEOUT_SEC)
|
||||
def test_x_cluster_deletion(self):
|
||||
'''
|
||||
Test deletion with configured protection
|
||||
'''
|
||||
k8s = self.k8s
|
||||
cluster_label = 'application=spilo,cluster-name=acid-minimal-cluster'
|
||||
|
||||
# configure delete protection
|
||||
patch_delete_annotations = {
|
||||
"data": {
|
||||
"delete_annotation_date_key": "delete-date",
|
||||
"delete_annotation_name_key": "delete-clustername"
|
||||
}
|
||||
}
|
||||
k8s.update_config(patch_delete_annotations)
|
||||
|
||||
# this delete attempt should be omitted because of missing annotations
|
||||
k8s.api.custom_objects_api.delete_namespaced_custom_object(
|
||||
"acid.zalan.do", "v1", "default", "postgresqls", "acid-minimal-cluster")
|
||||
|
||||
# check that pods and services are still there
|
||||
k8s.wait_for_running_pods(cluster_label, 2)
|
||||
k8s.wait_for_service(cluster_label)
|
||||
|
||||
# recreate Postgres cluster resource
|
||||
k8s.create_with_kubectl("manifests/minimal-postgres-manifest.yaml")
|
||||
|
||||
# wait a little before proceeding
|
||||
time.sleep(10)
|
||||
|
||||
# add annotations to manifest
|
||||
deleteDate = datetime.today().strftime('%Y-%m-%d')
|
||||
pg_patch_delete_annotations = {
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"delete-date": deleteDate,
|
||||
"delete-clustername": "acid-minimal-cluster",
|
||||
}
|
||||
}
|
||||
}
|
||||
k8s.api.custom_objects_api.patch_namespaced_custom_object(
|
||||
"acid.zalan.do", "v1", "default", "postgresqls", "acid-minimal-cluster", pg_patch_delete_annotations)
|
||||
|
||||
# wait a little before proceeding
|
||||
time.sleep(10)
|
||||
k8s.wait_for_running_pods(cluster_label, 2)
|
||||
k8s.wait_for_service(cluster_label)
|
||||
|
||||
# now delete process should be triggered
|
||||
k8s.api.custom_objects_api.delete_namespaced_custom_object(
|
||||
"acid.zalan.do", "v1", "default", "postgresqls", "acid-minimal-cluster")
|
||||
|
||||
# wait until cluster is deleted
|
||||
time.sleep(120)
|
||||
|
||||
print('Operator log: {}'.format(k8s.get_operator_log()))
|
||||
|
||||
# check if everything has been deleted
|
||||
self.assertEqual(0, k8s.count_pods_with_label(cluster_label))
|
||||
self.assertEqual(0, k8s.count_services_with_label(cluster_label))
|
||||
self.assertEqual(0, k8s.count_endpoints_with_label(cluster_label))
|
||||
self.assertEqual(0, k8s.count_statefulsets_with_label(cluster_label))
|
||||
self.assertEqual(0, k8s.count_deployments_with_label(cluster_label))
|
||||
self.assertEqual(0, k8s.count_pdbs_with_label(cluster_label))
|
||||
self.assertEqual(0, k8s.count_secrets_with_label(cluster_label))
|
||||
|
||||
def get_failover_targets(self, master_node, replica_nodes):
|
||||
'''
|
||||
If all pods live on the same node, failover will happen to other worker(s)
|
||||
@@ -700,11 +768,12 @@ class K8sApi:
|
||||
self.apps_v1 = client.AppsV1Api()
|
||||
self.batch_v1_beta1 = client.BatchV1beta1Api()
|
||||
self.custom_objects_api = client.CustomObjectsApi()
|
||||
self.policy_v1_beta1 = client.PolicyV1beta1Api()
|
||||
|
||||
|
||||
class K8s:
|
||||
'''
|
||||
Wraps around K8 api client and helper methods.
|
||||
Wraps around K8s api client and helper methods.
|
||||
'''
|
||||
|
||||
RETRY_TIMEOUT_SEC = 10
|
||||
@@ -824,6 +893,25 @@ class K8s:
|
||||
def count_pods_with_label(self, labels, namespace='default'):
|
||||
return len(self.api.core_v1.list_namespaced_pod(namespace, label_selector=labels).items)
|
||||
|
||||
def count_services_with_label(self, labels, namespace='default'):
|
||||
return len(self.api.core_v1.list_namespaced_service(namespace, label_selector=labels).items)
|
||||
|
||||
def count_endpoints_with_label(self, labels, namespace='default'):
|
||||
return len(self.api.core_v1.list_namespaced_endpoints(namespace, label_selector=labels).items)
|
||||
|
||||
def count_secrets_with_label(self, labels, namespace='default'):
|
||||
return len(self.api.core_v1.list_namespaced_secret(namespace, label_selector=labels).items)
|
||||
|
||||
def count_statefulsets_with_label(self, labels, namespace='default'):
|
||||
return len(self.api.apps_v1.list_namespaced_stateful_set(namespace, label_selector=labels).items)
|
||||
|
||||
def count_deployments_with_label(self, labels, namespace='default'):
|
||||
return len(self.api.apps_v1.list_namespaced_deployment(namespace, label_selector=labels).items)
|
||||
|
||||
def count_pdbs_with_label(self, labels, namespace='default'):
|
||||
return len(self.api.policy_v1_beta1.list_namespaced_pod_disruption_budget(
|
||||
namespace, label_selector=labels).items)
|
||||
|
||||
def wait_for_pod_failover(self, failover_targets, labels, namespace='default'):
|
||||
pod_phase = 'Failing over'
|
||||
new_pod_node = ''
|
||||
|
||||
Reference in New Issue
Block a user