@leverege/build-tools 2.65.1 → 2.66.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leverege/build-tools",
3
- "version": "2.65.1",
3
+ "version": "2.66.0",
4
4
  "description": "A collection of build / support tools for Leverege developers",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -83,10 +83,10 @@
83
83
  "semver": "^7.7.1",
84
84
  "simple-git": "^3.27.0",
85
85
  "toml": "^3.0.0",
86
- "zx": "^8.5.0"
86
+ "zx": "^8.5.2"
87
87
  },
88
88
  "devDependencies": {
89
89
  "@leverege/eslint-config-leverege": "^5.0.1",
90
- "npm": "^11.2.0"
90
+ "npm": "^11.3.0"
91
91
  }
92
92
  }
@@ -83,7 +83,7 @@ const touchFile = async ( filename ) => {
83
83
 
84
84
  // generates an executable script to use for defining the volume on k8s
85
85
  const writeApplyScript = async ( dir ) => {
86
- const applyScript = `#!/ust/bin/env bash
86
+ const applyScript = `#!/usr/bin/env bash
87
87
  #
88
88
  # Apply VolumeSnapshot resources prior to deploying the CNPG cluster
89
89
  #
@@ -387,7 +387,7 @@ const main = async () => {
387
387
  log( `
388
388
  ✅ Done. Snapshot: ${chalk.cyan( destSnapshot )}
389
389
  Recovery YAMLs written to: ${chalk.cyan( emitYamlDir )}
390
- Run '${chalk.yellow( './apply-recovery-yaml.sh' )}' to prep the cluster for recovery.
390
+ Run '${chalk.yellow( './apply-volumesnapshots.sh' )}' to prep the cluster for recovery.
391
391
  ` )
392
392
  }
393
393
 
@@ -434,7 +434,7 @@ const cleanupResources = async () => {
434
434
  } ) )
435
435
  )
436
436
 
437
- log( chalk.green( ' [✓] Parallel complete. Final GCE snapshot retained for CNPG bootstrapping.' ) )
437
+ log( chalk.green( '\n [✓] Parallel cleanup complete - final GCE snapshot retained for CNPG bootstrapping\n' ) )
438
438
  }
439
439
 
440
440
  if ( cleanupOnly ) {
@@ -447,3 +447,5 @@ await main().catch( err => errorExit( err.message || err ) )
447
447
  if ( cleanup ) {
448
448
  await cleanupResources()
449
449
  }
450
+
451
+ log( chalk.green( ` [✓] Cloning complete - recovery image name is => ${chalk.bold.yellow( k8sSnapshotName )}\n` ) )
@@ -0,0 +1,67 @@
1
+ apiVersion: v1
2
+ kind: ServiceAccount
3
+ metadata:
4
+ name: cnpg-cleanup-sa
5
+ namespace: cnpg-operands
6
+ annotations:
7
+ # wire up this KSA to the GSA to hook into IAM for workload identity
8
+ iam.gke.io/gcp-service-account: cnpg-cleanup-sa@${PROJECT_ID}.iam.gserviceaccount.com
9
+ ---
10
+ apiVersion: rbac.authorization.k8s.io/v1
11
+ kind: Role
12
+ metadata:
13
+ name: cnpg-cleanup-role
14
+ namespace: cnpg-operands
15
+ rules:
16
+ - apiGroups: ["postgresql.cnpg.io"]
17
+ resources: ["backups"]
18
+ verbs: ["get", "list", "delete"]
19
+ - apiGroups: ["snapshot.storage.k8s.io"]
20
+ resources: ["volumesnapshots"]
21
+ verbs: ["get", "list", "delete"]
22
+ ---
23
+ apiVersion: rbac.authorization.k8s.io/v1
24
+ kind: RoleBinding
25
+ metadata:
26
+ name: cnpg-cleanup-rolebinding
27
+ namespace: cnpg-operands
28
+ subjects:
29
+ - kind: ServiceAccount
30
+ name: cnpg-cleanup-sa
31
+ namespace: cnpg-operands
32
+ roleRef:
33
+ kind: Role
34
+ name: cnpg-cleanup-role
35
+ apiGroup: rbac.authorization.k8s.io
36
+ ---
37
+ apiVersion: batch/v1
38
+ kind: CronJob
39
+ metadata:
40
+ name: cnpg-cleanup-snapshot
41
+ namespace: cnpg-operands
42
+ spec:
43
+ schedule: "0 11 * * *" # 11 UTC is ~7AM EST
44
+ # schedule: "*/5 * * * *" # every 5 minutes for testing
45
+ successfulJobsHistoryLimit: 1
46
+ jobTemplate:
47
+ spec:
48
+ template:
49
+ spec:
50
+ restartPolicy: Never
51
+ serviceAccountName: cnpg-cleanup-sa
52
+ containers:
53
+ - name: cnpg-cleanup
54
+ image: gcr.io/google.com/cloudsdktool/cloud-sdk:latest
55
+ env:
56
+ - name: DRY_RUN
57
+ value: "false"
58
+ - name: RETENTION_DAYS
59
+ value: "21"
60
+ command:
61
+ - /bin/bash
62
+ - -c
63
+ - |
64
+ echo "🚀 Fetching cleanup script from GCS..."
65
+ apt-get update -qq
66
+ apt-get install -y jq libjq1 libonig5 --no-install-recommends -o=Dpkg::Use-Pty=0 -o=APT::Get::Assume-Yes=1 -o=Debug::pkgProblemResolver=1
67
+ gsutil cat gs://${PROJECT_ID}-k8s-cronjobs/cnpg-cleanup-script.sh | bash
@@ -0,0 +1,73 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+
4
+ KUBECTL_DELETE_ARGS=""
5
+ [[ "$DRY_RUN" == "true" ]] && KUBECTL_DELETE_ARGS="--dry-run=server"
6
+
7
+ # volumesnapshots namespace can be set here but if we need more than just the
8
+ # cnpg-operands then we'll need to the Role with a ClusterRole and bind it
9
+ # differently as well.
10
+ VSNAPS_NS="-n cnpg-operands"
11
+
12
+ # Default retention period (can override with env)
13
+ RETENTION_DAYS="${RETENTION_DAYS:-21}"
14
+ CURRENT_DATE=$(date +%s)
15
+
16
+ log() {
17
+ echo "[$(date -u '+%Y-%m-%dT%H:%M:%SZ')] $*"
18
+ }
19
+
20
+ should_delete() {
21
+ local creation_ts="$1"
22
+ local age_days
23
+ local created_secs
24
+ created_secs=$(date -d "$creation_ts" +%s)
25
+ age_days=$(( (CURRENT_DATE - created_secs) / 86400 ))
26
+ if (( age_days > RETENTION_DAYS )); then
27
+ echo "$age_days"
28
+ return 0
29
+ fi
30
+ return 1
31
+ }
32
+
33
+ cleanup_cnpg_backups() {
34
+ log "🔍 Cleaning CNPG backups older than $RETENTION_DAYS days"
35
+ kubectl get backups.postgresql.cnpg.io -n cnpg-operands -o json | jq -c '.items[]' | while read -r item; do
36
+ name=$(echo "$item" | jq -r '.metadata.name')
37
+ created=$(echo "$item" | jq -r '.metadata.creationTimestamp')
38
+ [[ "$name" != *"-backup-"* ]] && log "Skipping manual backup: $name" && continue
39
+
40
+ if age=$(should_delete "$created"); then
41
+ log "🗑 Deleting CNPG backup: $name (Age: $age days)"
42
+ kubectl delete backups.postgresql.cnpg.io "$name" -n cnpg-operands --ignore-not-found --wait=false $KUBECTL_DELETE_ARGS
43
+ fi
44
+ done
45
+ log "✅ CNPG backup cleanup complete"
46
+ }
47
+
48
+ cleanup_volume_snapshots() {
49
+ log "🔍 Cleaning VolumeSnapshots older than $RETENTION_DAYS days"
50
+ kubectl get volumesnapshots $VSNAPS_NS -o json | jq -c '.items[]' | while read -r item; do
51
+ ns=$(echo "$item" | jq -r '.metadata.namespace')
52
+ name=$(echo "$item" | jq -r '.metadata.name')
53
+ created=$(echo "$item" | jq -r '.metadata.creationTimestamp')
54
+ ready=$(echo "$item" | jq -r '.status.readyToUse // false')
55
+
56
+ [[ "$ready" != "true" ]] && continue
57
+
58
+ if age=$(should_delete "$created"); then
59
+ log "🗑 Deleting VolumeSnapshot: $ns/$name (Age: $age days)"
60
+ kubectl delete volumesnapshot -n "$ns" "$name" --ignore-not-found --wait=false $KUBECTL_DELETE_ARGS
61
+ fi
62
+ done
63
+ log "✅ VolumeSnapshot cleanup complete"
64
+ }
65
+
66
+ main() {
67
+ log "🚀 Starting cleanup job (retention: $RETENTION_DAYS days)"
68
+ cleanup_cnpg_backups
69
+ cleanup_volume_snapshots
70
+ log "🏁 All cleanup tasks complete"
71
+ }
72
+
73
+ main
@@ -0,0 +1 @@
1
+ cnpg-cleanup-cronjob.yaml
@@ -0,0 +1,28 @@
1
+ #!/bin/bash
2
+ #
3
+ # See => https://cloudnative-pg.io/documentation/current/installation_upgrade/
4
+ #
5
+ # OPVER="1.25.1"
6
+ OPVER="1.26.0-rc1" # 03/28/2025
7
+
8
+ createNamespaceIfNeeded cnpg-system
9
+
10
+ kubectl apply --server-side -f \
11
+ https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/main/releases/cnpg-${OPVER}.yaml $K8S_WHAT
12
+
13
+ # Legacy terraformed clusters (like sandbox) may need a special firewall rule
14
+ # added to the network layer on k8s. It should look like this:
15
+ #
16
+ # Name : cnpg-operator
17
+ # Ports : 8000,9443 <= kubectl cnpg status and webhooks
18
+ # Filters: 172.16.0.0/28 <= k8s control plane
19
+ #
20
+ # Old approach used the helm chart.
21
+ #
22
+ #addHelmRepo cnpg https://cloudnative-pg.github.io/charts
23
+ #
24
+ #helm upgrade --install cnpg cnpg/cloudnative-pg \
25
+ # --namespace cnpg-system --create-namespace \
26
+ # --set webhook.port="10250" $HELM_WHAT
27
+ #
28
+ #removeHelmRepo cnpg
@@ -2,13 +2,12 @@
2
2
  #
3
3
  # See => https://cloudnative-pg.io/documentation/current/installation_upgrade/
4
4
  #
5
- # OPVER="1.25.1"
6
- OPVER="1.26.0-rc1" # 03/28/2025
5
+ OPVER="1.25.1"
7
6
 
8
7
  createNamespaceIfNeeded cnpg-system
9
8
 
10
9
  kubectl apply --server-side -f \
11
- https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/main/releases/cnpg-${OPVER}.yaml $K8S_WHAT
10
+ https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-${OPVER%.*}/releases/cnpg-${OPVER}.yaml $K8S_WHAT
12
11
 
13
12
  # Legacy terraformed clusters (like sandbox) may need a special firewall rule
14
13
  # added to the network layer on k8s. It should look like this:
@@ -2,7 +2,7 @@
2
2
  #
3
3
  showInstalling "Elastic Search 8"
4
4
 
5
- [ -z "$ELASTIC_CHART_VERSION" ] && ELASTIC_CHART_VERSION="21.4.8"
5
+ [ -z "$ELASTIC_CHART_VERSION" ] && ELASTIC_CHART_VERSION="21.5.0"
6
6
 
7
7
  OCI_CHART="oci://registry-1.docker.io/bitnamicharts/elasticsearch"
8
8
 
@@ -4,7 +4,7 @@ showInstalling "The Prometheus Operator and Components"
4
4
  addHelmRepo prometheus-community https://prometheus-community.github.io/helm-charts
5
5
 
6
6
  showInstalling "The Prometheus Operator (kube-prometheus-stack)"
7
- [ -z "$PROMETHEUS_STACK_CHART_VERSION" ] && PROMETHEUS_STACK_CHART_VERSION="69"
7
+ [ -z "$PROMETHEUS_STACK_CHART_VERSION" ] && PROMETHEUS_STACK_CHART_VERSION="70"
8
8
 
9
9
  NS="--namespace prometheus"
10
10
 
@@ -7,7 +7,25 @@ fullnameOverride: "prometheus-stack-stackdriver-metrics"
7
7
  stackdriver:
8
8
  projectId: "${PROJECT_NAME}"
9
9
  metrics:
10
- typePrefixes: "pubsub.googleapis.com/subscription/oldest_unacked_message_age,pubsub.googleapis.com/subscription/num_undelivered_messages,pubsub.googleapis.com/subscription/pull_ack_request_count,pubsub.googleapis.com/subscription/streaming_pull_ack_request_count,pubsub.googleapis.com/topic/message_sizes,pubsub.googleapis.com/topic/send_request_count,firebasedatabase.googleapis.com/io/database_load,firebasedatabase.googleapis.com/network/sent_bytes_count,firebasedatabase.googleapis.com/network/active_connections"
10
+ typePrefixes: >
11
+ pubsub.googleapis.com/subscription/oldest_unacked_message_age,
12
+ pubsub.googleapis.com/subscription/num_undelivered_messages,
13
+ pubsub.googleapis.com/subscription/pull_ack_request_count,
14
+ pubsub.googleapis.com/subscription/streaming_pull_ack_request_count,
15
+ pubsub.googleapis.com/topic/message_sizes,
16
+ pubsub.googleapis.com/topic/send_request_count,
17
+ firebasedatabase.googleapis.com/io/database_load,
18
+ firebasedatabase.googleapis.com/network/sent_bytes_count,
19
+ firebasedatabase.googleapis.com/network/active_connections,
20
+ container.googleapis.com/accelerator/duty_cycle,
21
+ container.googleapis.com/accelerator/memory_usage,
22
+ container.googleapis.com/accelerator/request_count,
23
+ agent.googleapis.com/memory/bytes_used,
24
+ agent.googleapis.com/cpu/utilization,
25
+ storage.googleapis.com/network/received_bytes_count,
26
+ storage.googleapis.com/network/sent_bytes_count,
27
+ monitoring.googleapis.com/uptime_check/check_passed,
28
+ quota.googleapis.com/allocation/usage
11
29
 
12
30
  # https://artifacthub.io/packages/helm/prometheus-community/prometheus-stackdriver-exporter?modal=values&path=serviceMonitor
13
31
  serviceMonitor:
@@ -15,6 +33,8 @@ serviceMonitor:
15
33
  namespace: prometheus
16
34
  interval: "30s"
17
35
  relabelings:
36
+ # Legacy labelmap used to preserve compatibility with pre-operator Grafana dashboards
37
+ # Can be removed once legacy Prometheus stack is deprecated
18
38
  - action: labelmap
19
39
  regex: __meta_kubernetes_pod_label_(.+)
20
40
  - action: labelmap
@@ -4,7 +4,7 @@ showInstalling "Redis"
4
4
 
5
5
  OCI_CHART="oci://registry-1.docker.io/bitnamicharts/redis"
6
6
 
7
- [ -z "$REDIS_CHART_VERSION" ] && REDIS_CHART_VERSION="20.11.3"
7
+ [ -z "$REDIS_CHART_VERSION" ] && REDIS_CHART_VERSION="20.11.5"
8
8
 
9
9
  helm upgrade --install redis $OCI_CHART \
10
10
  --values redis/values.yaml \
@@ -17,7 +17,7 @@ TRAEFIK_NAMESPACE="traefik"
17
17
 
18
18
  addHelmRepo traefik https://helm.traefik.io/traefik
19
19
 
20
- [ -z "$TRAEFIK_CHART_VERSION" ] && TRAEFIK_CHART_VERSION="34"
20
+ [ -z "$TRAEFIK_CHART_VERSION" ] && TRAEFIK_CHART_VERSION="35"
21
21
  helm upgrade --install traefik traefik/traefik \
22
22
  --namespace $TRAEFIK_NAMESPACE --create-namespace \
23
23
  --values traefik/values.yaml \
@@ -25,7 +25,7 @@ velero schedule delete --all --confirm &> /dev/null
25
25
  helm upgrade \
26
26
  --install velero vmware-tanzu/velero \
27
27
  --namespace velero --create-namespace \
28
- --values velero/velero-local.yaml \
28
+ --values velero/values-local.yaml \
29
29
  --version $VELERO_CHART_VERSION $HELM_WHAT \
30
30
  --set configuration.backupStorageLocation[0].bucket="$GCE_BUCKET" \
31
31
  --set configuration.backupStorageLocation[0].config.serviceAccount="$GCE_SA_EMAIL" \
@@ -71,7 +71,7 @@ resources:
71
71
  cpu: 250m
72
72
  memory: 128Mi
73
73
  limits:
74
- cpu: 300m
74
+ cpu: 500m
75
75
  memory: 256Mi
76
76
 
77
77
  # Annotations to add to the Velero deployment's. Optional.
package/src/helmup.sh CHANGED
@@ -702,7 +702,11 @@ EOSNAPSC
702
702
  sleep 2 # hold up processing for a moment to allow IAM mods to propagate
703
703
  }
704
704
 
705
- function installCronCnpgCleanupSnapshot() {
705
+ # this function is a little convoluted in the way it attempts to install the
706
+ # scripts and yaml necessary for the CNPG cleanup activities - the idea is to
707
+ # be able to update the scripts without touching anything else since the target
708
+ # directory is the cnpg-operator setup
709
+ function installCnpgCleanupCronjob() {
706
710
  CNPG_OPERATOR_DIR="cnpg-operator"
707
711
  if [ ! -d "$CNPG_OPERATOR_DIR" ];
708
712
  then
@@ -713,23 +717,52 @@ CNPG_OPERATOR_MISSING
713
717
  exit 1
714
718
  fi
715
719
 
716
- CNPG_CLEANUP_CRONJOB_YAML="cnpg-cleanup-snapshot-cronjob.yaml"
717
- CNPG_CLEANUP_CRONJOB="$CNPG_OPERATOR_DIR/$CNPG_CLEANUP_CRONJOB_YAML"
718
- if [ ! -f "$CNPG_CLEANUP_CRONJOB" ];
720
+ # create the destination bucket for k8s cronjob scripts
721
+ BUCKET_SUFFIX="k8s-cronjobs"
722
+ makeUniformBucketWithCors $BUCKET_SUFFIX
723
+
724
+ CNPG_CLEANUP_CRONJOB_OVH="cnpg-cleanup-cronjob.yaml.ovh"
725
+ CNPG_CLEANUP_CRONJOB="$CNPG_OPERATOR_DIR/$CNPG_CLEANUP_CRONJOB_OVH"
726
+ CNPG_CLEANUP_SCRIPT_BASH="cnpg-cleanup-script.sh"
727
+ CNPG_CLEANUP_SCRIPT="$CNPG_OPERATOR_DIR/$CNPG_CLEANUP_SCRIPT_BASH"
728
+ if [ ! -f "$CNPG_CLEANUP_SCRIPT" ];
719
729
  then
720
730
  cat<<CNPG_FETCH_CLEANUP_CRONJOB_YAML
721
- `color y "Missing $CNPG_CLEANUP_CRONJOB_YAML - grabbing a copy from build-tools"`
731
+ `color y "Missing $CNPG_CLEANUP_SCRIPT_BASH - updating local cron setup scripts"`
722
732
 
723
733
  CNPG_FETCH_CLEANUP_CRONJOB_YAML
724
734
  CNPG_OP_ROOT="$(build-tools --reporoot)/src/helm-charts/cnpg-operator"
725
- cp $CNPG_OP_ROOT/$CNPG_CLEANUP_CRONJOB_YAML $CNPG_CLEANUP_CRONJOB
735
+ cp $CNPG_OP_ROOT/$CNPG_CLEANUP_CRONJOB_OVH $CNPG_CLEANUP_CRONJOB
736
+ cp $CNPG_OP_ROOT/$CNPG_CLEANUP_SCRIPT_BASH $CNPG_CLEANUP_SCRIPT
726
737
  fi
727
738
 
739
+ # copy / update the script in the bucket referenced in the cronjob
740
+ printf "\ngsutil cp $CNPG_CLEANUP_SCRIPT gs://$GCP_PROJECT_ID-$BUCKET_SUFFIX\n"
741
+ gsutil cp $CNPG_CLEANUP_SCRIPT gs://$GCP_PROJECT_ID-$BUCKET_SUFFIX
742
+
743
+ local CNPG_NAMESPACE="cnpg-operands"
744
+ local CNPG_CLEANUP_SA="cnpg-cleanup-sa"
745
+
746
+ gcloud iam service-accounts create "$CNPG_CLEANUP_SA" \
747
+ --project="$GCP_PROJECT_ID" \
748
+ --description="Used for cronjob cleanup with Workload Identity" \
749
+ --display-name="CNPG Cleanup SA" &> $DEVNULL
750
+ warnOnError $? "the GCP SA $CNPG_CLEANUP_SA may already exist"
751
+
752
+ gcloud projects add-iam-policy-binding "$GCP_PROJECT_ID" \
753
+ --project="$GCP_PROJECT_ID" \
754
+ --member="serviceAccount:$CNPG_CLEANUP_SA@$GCP_PROJECT_ID.iam.gserviceaccount.com" \
755
+ --role="roles/storage.objectViewer"
756
+
757
+ bindWorkloadIdentity "$CNPG_CLEANUP_SA" "$CNPG_NAMESPACE"
758
+
759
+ CNPG_CLEANUP_CRONJOB_YAML="$CNPG_OPERATOR_DIR/$(basename $CNPG_CLEANUP_CRONJOB_OVH .ovh)"
760
+ overwhelm -g # allow ovh -> yaml to occur
728
761
  cat<<CNPG_CLEANUP_CRONJOB_APPLY
729
- `color g "Creating cronjob =>"``color y " kubectl apply -f $CNPG_CLEANUP_CRONJOB"`
762
+ `color g "Creating cronjob =>"``color y " kubectl apply -f $CNPG_CLEANUP_CRONJOB_YAML"`
730
763
 
731
764
  CNPG_CLEANUP_CRONJOB_APPLY
732
- kubectl apply -f $CNPG_CLEANUP_CRONJOB
765
+ kubectl apply -f $CNPG_CLEANUP_CRONJOB_YAML
733
766
  }
734
767
 
735
768
  function ensureCnpgSecret() {
@@ -1001,7 +1034,7 @@ CATBACKUP
1001
1034
  ;;
1002
1035
 
1003
1036
  "cnpg-cronjob")
1004
- installCronCnpgCleanupSnapshot
1037
+ installCnpgCleanupCronjob
1005
1038
  ;;
1006
1039
 
1007
1040
  "cronZombieKiller"|"zombie-killer")
@@ -1,4 +1,8 @@
1
1
  steps:
2
+ - name: 'gcr.io/cloud-builders/docker'
3
+ entrypoint: 'bash'
4
+ args: ['-c', 'docker pull {{imageName}}:latest || exit 0']
5
+
2
6
  - name: 'gcr.io/cloud-builders/docker'
3
7
  args:
4
8
  - 'build'
@@ -6,8 +10,8 @@ steps:
6
10
  - '-t'
7
11
  - '{{imageName}}:{{imageVersion}}'
8
12
  - '--cache-from'
9
- - '{{imageName}}:{{imageVersion}}'
13
+ - '{{imageName}}:latest'
10
14
  - '.'
11
15
 
12
16
  images:
13
- - '{{imageName}}:{{imageVersion}}'
17
+ - '{{imageName}}:{{imageVersion}}'
@@ -1,73 +0,0 @@
1
- apiVersion: v1
2
- kind: ServiceAccount
3
- metadata:
4
- name: cnpg-cleanup-sa
5
- namespace: cnpg-operands
6
- ---
7
- apiVersion: rbac.authorization.k8s.io/v1
8
- kind: Role
9
- metadata:
10
- name: cnpg-cleanup-role
11
- namespace: cnpg-operands
12
- rules:
13
- - apiGroups: ["postgresql.cnpg.io"]
14
- resources: ["backups"]
15
- verbs: ["get", "list", "delete"]
16
- ---
17
- apiVersion: rbac.authorization.k8s.io/v1
18
- kind: RoleBinding
19
- metadata:
20
- name: cnpg-cleanup-rolebinding
21
- namespace: cnpg-operands
22
- subjects:
23
- - kind: ServiceAccount
24
- name: cnpg-cleanup-sa
25
- namespace: cnpg-operands
26
- roleRef:
27
- kind: Role
28
- name: cnpg-cleanup-role
29
- apiGroup: rbac.authorization.k8s.io
30
- ---
31
- apiVersion: batch/v1
32
- kind: CronJob
33
- metadata:
34
- name: cnpg-cleanup-snapshot
35
- namespace: cnpg-operands
36
- spec:
37
- schedule: "0 13 * * *" # 13 UTC is ~8AM EST
38
- successfulJobsHistoryLimit: 2
39
- jobTemplate:
40
- spec:
41
- template:
42
- spec:
43
- serviceAccountName: cnpg-cleanup-sa
44
- restartPolicy: Never
45
- containers:
46
- - name: cnpg-cleanup-snapshots
47
- image: bitnami/kubectl:latest
48
- command:
49
- - "/bin/bash"
50
- - "-c"
51
- - |
52
- echo "Starting CNPG Cleanup"
53
- CURRENT_DATE=$(date +%s)
54
- RETENTION_DAYS=21
55
- SNAPSHOTS_JSON=$(kubectl get backups.postgresql.cnpg.io -n cnpg-operands -o json)
56
- echo "$SNAPSHOTS_JSON" | jq -c '.items[]' | while read -r snapshot
57
- do
58
- NAME=$(echo "$snapshot" | jq -r '.metadata.name')
59
- CREATION_TIMESTAMP=$(echo "$snapshot" | jq -r '.metadata.creationTimestamp')
60
- if [[ "$NAME" != *"-backup-"* ]];
61
- then
62
- echo "Skipping manual snapshot: $NAME"
63
- continue
64
- fi
65
- SNAPSHOT_DATE=$(date -d "$CREATION_TIMESTAMP" +%s)
66
- AGE=$(( (CURRENT_DATE - SNAPSHOT_DATE) / 86400 ))
67
- if [ "$AGE" -gt "$RETENTION_DAYS" ];
68
- then
69
- echo "Deleting snapshot: $NAME (Age: $AGE days)"
70
- kubectl delete backups.postgresql.cnpg.io "$NAME" -n cnpg-operands 2> /dev/null
71
- fi
72
- done
73
- echo "Cleanup complete."