diff --git a/charts/namada-indexer/templates/dependencies-job.yaml b/charts/namada-indexer/templates/dependencies-job.yaml new file mode 100644 index 0000000..551e41e --- /dev/null +++ b/charts/namada-indexer/templates/dependencies-job.yaml @@ -0,0 +1,80 @@ +{{- if or (and .Values.postgresOperator.install.enabled .Values.postgresOperator.enabled) (and .Values.redis.install.enabled .Values.redis.enabled) }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "namada-indexer.fullname" . }}-wait-dependencies + annotations: + "helm.sh/hook": post-install + "helm.sh/hook-weight": "-5" + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation + labels: + {{- include "namada-indexer.labels" . | nindent 4 }} +spec: + backoffLimit: 100 + template: + metadata: + name: {{ include "namada-indexer.fullname" . }}-wait-dependencies + spec: + serviceAccountName: {{ include "namada-indexer.serviceAccountName" . }} + restartPolicy: OnFailure + containers: + - name: wait + image: bitnami/kubectl:latest + command: + - /bin/sh + - -c + - | + # Scale deployment to 0 + kubectl scale deployment -n {{ .Release.Namespace }} {{ include "namada-indexer.fullname" . }} --replicas=0 + + {{- if and .Values.postgresOperator.install.enabled .Values.postgresOperator.enabled }} + # Wait for PostgreSQL Operator to be ready + until kubectl get deployment -n {{ .Release.Namespace }} {{ include "namada-indexer.fullname" . }}-postgres-operator; do + echo "Waiting for PostgreSQL Operator deployment..." + sleep 5 + done + + # Wait for PostgreSQL StatefulSet to be created + until kubectl get statefulset -n {{ .Release.Namespace }} {{ include "namada-indexer.fullname" . }}-db; do + echo "Waiting for PostgreSQL StatefulSet..." + sleep 5 + done + + # Wait for PostgreSQL secret + until kubectl get secret -n {{ .Release.Namespace }} namada.{{ include "namada-indexer.fullname" . }}-db.credentials.postgresql.acid.zalan.do; do + echo "Waiting for PostgreSQL secret..." + sleep 5 + done + + # Wait for PostgreSQL pods to be running + until [ "$(kubectl get pods -n {{ .Release.Namespace }} -l application=spilo --field-selector status.phase=Running -o name | wc -l)" -eq {{ .Values.postgresOperator.numberOfInstances }} ]; do + echo "Waiting for PostgreSQL pods ($(kubectl get pods -n {{ .Release.Namespace }} -l application=spilo --field-selector status.phase=Running -o name | wc -l)/{{ .Values.postgresOperator.numberOfInstances }})..." + sleep 5 + done + {{- end }} + + {{- if and .Values.redis.install.enabled .Values.redis.enabled }} + # Wait for Redis StatefulSet + until kubectl get statefulset -n {{ .Release.Namespace }} {{ .Release.Name }}-redis-node; do + echo "Waiting for Redis StatefulSet..." + sleep 5 + done + + # Get expected Redis replicas + REDIS_NODES=$(kubectl get statefulset -n {{ .Release.Namespace }} {{ .Release.Name }}-redis-node -o jsonpath='{.spec.replicas}') + + # Wait for Redis nodes to be fully ready (all 3 containers running) + until [ "$(kubectl get pods -n {{ .Release.Namespace }} -l app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/name=redis,app.kubernetes.io/component=node --field-selector status.phase=Running | grep '3/3' | wc -l)" -eq "$REDIS_NODES" ]; do + echo "Waiting for Redis nodes ($(kubectl get pods -n {{ .Release.Namespace }} -l app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/name=redis,app.kubernetes.io/component=node --field-selector status.phase=Running | grep '3/3' | wc -l)/$REDIS_NODES)..." + sleep 5 + done + {{- end }} + + echo "All dependencies are ready!" + + # Scale deployment back to desired replicas + kubectl scale deployment -n {{ .Release.Namespace }} {{ include "namada-indexer.fullname" . }} --replicas={{ .Values.replicaCount }} + + echo "✅ Dependencies check completed, deployment scaled up to {{ .Values.replicaCount }} replicas" + exit 0 +{{- end }} diff --git a/charts/namada-indexer/templates/deployment.yaml b/charts/namada-indexer/templates/deployment.yaml index af8ed80..2fda82a 100644 --- a/charts/namada-indexer/templates/deployment.yaml +++ b/charts/namada-indexer/templates/deployment.yaml @@ -8,6 +8,8 @@ metadata: {{- with .Values.labels }} {{- toYaml . | nindent 4 }} {{- end }} + annotations: + "helm.sh/hook-weight": "-10" spec: replicas: {{ .Values.replicaCount }} strategy: @@ -178,4 +180,4 @@ spec: {{- end }} {{- end }} {{- end }} - restartPolicy: OnFailure + restartPolicy: Always diff --git a/charts/namada-indexer/templates/postgresql-cleanup-hook.yaml b/charts/namada-indexer/templates/postgresql-cleanup-hook.yaml new file mode 100644 index 0000000..ab93f95 --- /dev/null +++ b/charts/namada-indexer/templates/postgresql-cleanup-hook.yaml @@ -0,0 +1,42 @@ +{{- if and .Values.postgresOperator.install.enabled .Values.postgresOperator.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "namada-indexer.fullname" . }}-db-cleanup + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation +spec: + template: + spec: + serviceAccountName: {{ include "namada-indexer.serviceAccountName" . }} + containers: + - name: kubectl + image: bitnami/kubectl:latest + command: + - /bin/sh + - -c + - | + # Delete dependencies job first + kubectl delete job -n {{ .Release.Namespace }} {{ include "namada-indexer.fullname" . }}-wait-dependencies --force --grace-period=0 || true + + # Delete any leftover pods from the dependencies job + kubectl delete pods -n {{ .Release.Namespace }} -l job-name={{ include "namada-indexer.fullname" . }}-wait-dependencies --force --grace-period=0 || true + + # Force delete the statefulset + kubectl delete statefulset -n {{ .Release.Namespace }} {{ include "namada-indexer.fullname" . }}-db --force --grace-period=0 || true + + # Remove finalizers from postgresql CRD + kubectl patch postgresql -n {{ .Release.Namespace }} {{ include "namada-indexer.fullname" . }}-db -p '{"metadata":{"finalizers":null}}' --type=merge || true + + # Delete PostgreSQL services + kubectl delete svc -n {{ .Release.Namespace }} \ + {{ include "namada-indexer.fullname" . }}-db \ + {{ include "namada-indexer.fullname" . }}-db-config \ + {{ include "namada-indexer.fullname" . }}-db-repl \ + {{ include "namada-indexer.fullname" . }}-db-pooler \ + {{ include "namada-indexer.fullname" . }}-db-repl-pooler \ + {{ include "namada-indexer.fullname" . }}-db-pooler-repl || true + restartPolicy: Never + backoffLimit: 1 +{{- end }} diff --git a/charts/namada-indexer/templates/postgresql.yaml b/charts/namada-indexer/templates/postgresql.yaml index b3e3e97..2a06b40 100644 --- a/charts/namada-indexer/templates/postgresql.yaml +++ b/charts/namada-indexer/templates/postgresql.yaml @@ -5,8 +5,12 @@ metadata: name: {{ include "namada-indexer.fullname" . }}-db labels: {{- include "namada-indexer.labels" . | nindent 4 }} + finalizers: + - kubernetes spec: teamId: {{ .Values.postgresOperator.teamId }} + deleteOptions: + forcedDeletion: true volume: size: {{ .Values.postgresOperator.volume.size }} {{- if .Values.postgresOperator.volume.storageClass }} diff --git a/charts/namada-indexer/templates/rbac.yaml b/charts/namada-indexer/templates/rbac.yaml new file mode 100644 index 0000000..a82e8c1 --- /dev/null +++ b/charts/namada-indexer/templates/rbac.yaml @@ -0,0 +1,48 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "namada-indexer.fullname" . }} + labels: + {{- include "namada-indexer.labels" . | nindent 4 }} +rules: + # For deployment scaling and management + - apiGroups: ["apps"] + resources: ["deployments", "deployments/scale", "statefulsets"] + verbs: ["get", "list", "watch", "update", "patch", "delete"] + + # For PostgreSQL operator and database management + - apiGroups: ["acid.zalan.do"] + resources: ["postgresqls", "postgresqls/status"] + verbs: ["get", "list", "watch", "patch", "delete"] + + # For pod and service management + - apiGroups: [""] + resources: ["pods", "services", "secrets", "configmaps", "persistentvolumeclaims"] + verbs: ["get", "list", "watch", "delete", "patch"] + + # For job management + - apiGroups: ["batch"] + resources: ["jobs"] + verbs: ["get", "list", "watch", "delete", "create"] + + # For connection pooler management + - apiGroups: ["apps"] + resources: ["deployments"] + resourceNames: ["db-connection-pooler"] + verbs: ["get", "list", "watch", "delete"] + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "namada-indexer.fullname" . }} + labels: + {{- include "namada-indexer.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "namada-indexer.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ include "namada-indexer.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} diff --git a/charts/namada-indexer/values.yaml b/charts/namada-indexer/values.yaml index 43b66e3..c607d31 100644 --- a/charts/namada-indexer/values.yaml +++ b/charts/namada-indexer/values.yaml @@ -24,6 +24,7 @@ postgresOperator: parameters: max_connections: "100" shared_buffers: "128MB" + resourcePolicy: "delete" externalPostgres: enabled: false @@ -51,11 +52,13 @@ redis: enabled: true size: "8Gi" storageClass: "" + resourcePolicy: "delete" master: persistence: enabled: true size: "8Gi" storageClass: "" + resourcePolicy: "delete" metrics: enabled: false serviceMonitor: