From 617efc686c1296b05a6565d3588e96659c37a492 Mon Sep 17 00:00:00 2001 From: chliddle Date: Tue, 17 Dec 2024 17:07:58 +0000 Subject: [PATCH 1/2] ci: fix tests --- .github/workflows/test.yml | 18 ++++++++++++------ .../allora-worker/{vaules.yaml => values.yaml} | 0 .../templates/rpc_node.yaml | 6 +++--- charts/cosmos-operator-rpc-node/values.yaml | 2 +- 4 files changed, 16 insertions(+), 10 deletions(-) rename charts/allora-worker/{vaules.yaml => values.yaml} (100%) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 019ca25..df2a21c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,14 +30,20 @@ jobs: with: version: v3.10.0 - - name: Run Helm lint - run: helm lint ${{ matrix.chart_dir }} -f ${{ matrix.chart_dir }}/examples/values.yaml - - - name: Run Helm template - run: helm template ${{ matrix.chart_dir }} -f ${{ matrix.chart_dir }}/examples/values.yaml - - name: Install chart dependencies run: | if [ -f ${{ matrix.chart_dir }}/Chart.yaml ]; then + helm repo add bitnami https://charts.bitnami.com/bitnami + helm repo add zalando https://opensource.zalando.com/postgres-operator/charts/postgres-operator + helm repo update helm dependency update ${{ matrix.chart_dir }} + helm dependency build ${{ matrix.chart_dir }} fi + + - name: Run Helm lint + run: helm lint ${{ matrix.chart_dir }} -f ${{ matrix.chart_dir }}/values.yaml + + - name: Run Helm template + run: helm template ${{ matrix.chart_dir }} -f ${{ matrix.chart_dir }}/values.yaml + + diff --git a/charts/allora-worker/vaules.yaml b/charts/allora-worker/values.yaml similarity index 100% rename from charts/allora-worker/vaules.yaml rename to charts/allora-worker/values.yaml diff --git a/charts/cosmos-operator-rpc-node/templates/rpc_node.yaml b/charts/cosmos-operator-rpc-node/templates/rpc_node.yaml index 11d9597..34dc8ce 100644 --- a/charts/cosmos-operator-rpc-node/templates/rpc_node.yaml +++ b/charts/cosmos-operator-rpc-node/templates/rpc_node.yaml @@ -77,8 +77,8 @@ spec: image: "{{ .Values.image }}:{{ .Values.imageTag }}" {{ if .Values.resources }} resources: - {{ toYaml .Values.resources | nindent 6 }} - {{ end }} + {{- toYaml .Values.resources | nindent 6 }} + {{- end }} {{ if .Values.nodeSelectorLabel }} nodeSelector: {{ toYaml .Values.nodeSelectorLabel | nindent 6 }} @@ -94,7 +94,7 @@ spec: operator: In values: - {{ .Release.Name }} - topologyKey: "kubernetes.io/hostname" + topologyKey: "kubernetes.io/hostname" {{- end }} nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: diff --git a/charts/cosmos-operator-rpc-node/values.yaml b/charts/cosmos-operator-rpc-node/values.yaml index f4d0acf..152d3b6 100644 --- a/charts/cosmos-operator-rpc-node/values.yaml +++ b/charts/cosmos-operator-rpc-node/values.yaml @@ -21,7 +21,7 @@ volumeRetainPolicy: "Retain" resources: {} # Note: Optional additional configuration for the pod template -initContainers: [] +initContainers: {} cosmosNodeLabels: {} cosmosNodeAnnotations: {} priorityClassName: "" From 227c7a5e6b885195d32e53d8ef21817cc4535d41 Mon Sep 17 00:00:00 2001 From: chliddle Date: Tue, 17 Dec 2024 17:08:11 +0000 Subject: [PATCH 2/2] feat: namada indexer helm chart --- charts/namada-indexer/.helmignore | 32 +++ charts/namada-indexer/.releaserc.js | 17 ++ charts/namada-indexer/Chart.lock | 9 + charts/namada-indexer/Chart.yaml | 16 ++ charts/namada-indexer/README.md | 166 ++++++++++++++++ charts/namada-indexer/templates/_helpers.tpl | 160 +++++++++++++++ .../namada-indexer/templates/configmap.yaml | 21 ++ .../templates/dependencies-job.yaml | 83 ++++++++ .../namada-indexer/templates/deployment.yaml | 188 ++++++++++++++++++ charts/namada-indexer/templates/ingress.yaml | 42 ++++ .../templates/postgresql-cleanup-hook.yaml | 49 +++++ .../namada-indexer/templates/postgresql.yaml | 44 ++++ charts/namada-indexer/templates/rbac.yaml | 62 ++++++ .../templates/service-account.yaml | 19 ++ charts/namada-indexer/templates/service.yaml | 22 ++ charts/namada-indexer/values.yaml | 168 ++++++++++++++++ 16 files changed, 1098 insertions(+) create mode 100644 charts/namada-indexer/.helmignore create mode 100644 charts/namada-indexer/.releaserc.js create mode 100644 charts/namada-indexer/Chart.lock create mode 100644 charts/namada-indexer/Chart.yaml create mode 100644 charts/namada-indexer/README.md create mode 100644 charts/namada-indexer/templates/_helpers.tpl create mode 100644 charts/namada-indexer/templates/configmap.yaml create mode 100644 charts/namada-indexer/templates/dependencies-job.yaml create mode 100644 charts/namada-indexer/templates/deployment.yaml create mode 100644 charts/namada-indexer/templates/ingress.yaml create mode 100644 charts/namada-indexer/templates/postgresql-cleanup-hook.yaml create mode 100644 charts/namada-indexer/templates/postgresql.yaml create mode 100644 charts/namada-indexer/templates/rbac.yaml create mode 100644 charts/namada-indexer/templates/service-account.yaml create mode 100644 charts/namada-indexer/templates/service.yaml create mode 100644 charts/namada-indexer/values.yaml diff --git a/charts/namada-indexer/.helmignore b/charts/namada-indexer/.helmignore new file mode 100644 index 0000000..328945e --- /dev/null +++ b/charts/namada-indexer/.helmignore @@ -0,0 +1,32 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. + +# # Ignore all .tgz files except in charts directory +# /charts/*.tgz +# !charts/*.tgz + +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ + +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ + +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ + +# Project specific +.releaserc.js diff --git a/charts/namada-indexer/.releaserc.js b/charts/namada-indexer/.releaserc.js new file mode 100644 index 0000000..6763f80 --- /dev/null +++ b/charts/namada-indexer/.releaserc.js @@ -0,0 +1,17 @@ +const chartName = 'namada-indexer'; +const chartPath = __dirname; + +module.exports = { + extends: '../.github/chart-release.config.js', + tagFormat: 'namada-indexer-v${version}', + plugins: [ + '@semantic-release/commit-analyzer', + '@semantic-release/release-notes-generator', + '@semantic-release/changelog', + '@semantic-release/git', + '@semantic-release/github', + ['@semantic-release/exec', { + prepareCmd: 'sed -i "s/^version:.*$/version: ${nextRelease.version}/" Chart.yaml && helm package . --version ${nextRelease.version} --app-version ${nextRelease.version} && mv *.tgz ../' + }] + ] +}; diff --git a/charts/namada-indexer/Chart.lock b/charts/namada-indexer/Chart.lock new file mode 100644 index 0000000..b96fbc2 --- /dev/null +++ b/charts/namada-indexer/Chart.lock @@ -0,0 +1,9 @@ +dependencies: +- name: postgres-operator + repository: https://opensource.zalando.com/postgres-operator/charts/postgres-operator + version: 1.13.0 +- name: redis + repository: https://charts.bitnami.com/bitnami + version: 20.5.0 +digest: sha256:8336dfdf07439b8fb5ff7e54910d67b4833b1a02394bfddb438241eb827c9a17 +generated: "2024-12-11T14:02:20.240034Z" diff --git a/charts/namada-indexer/Chart.yaml b/charts/namada-indexer/Chart.yaml new file mode 100644 index 0000000..cd988bc --- /dev/null +++ b/charts/namada-indexer/Chart.yaml @@ -0,0 +1,16 @@ +apiVersion: v2 +name: namada-indexer +description: A Helm chart for deploying a namada indexer +type: application +version: 0.0.0-development +appVersion: "1.0" + +dependencies: + - name: postgres-operator + version: "1.13.0" + repository: "https://opensource.zalando.com/postgres-operator/charts/postgres-operator" + condition: postgresOperator.install.enabled + - name: redis + version: "20.5.0" + repository: "https://charts.bitnami.com/bitnami" + condition: redis.install.enabled diff --git a/charts/namada-indexer/README.md b/charts/namada-indexer/README.md new file mode 100644 index 0000000..22460b6 --- /dev/null +++ b/charts/namada-indexer/README.md @@ -0,0 +1,166 @@ +# Namada Indexer Helm Chart + +A Helm chart for deploying the Namada blockchain indexer and its components. + +## Overview + +This chart deploys a complete Namada indexing solution including: + +- Chain indexer +- Governance indexer +- PoS indexer +- Rewards indexer +- Parameters indexer +- Transaction indexer +- Web API server +- PostgreSQL database (optional) +- Redis cache (optional) + +## Prerequisites + +- Helm 3.2.0+ +- Ingress Controller (nginx) +- Cert-manager (optional, for TLS) + +## Installation + +1. Add required Helm repositories: + +```bash +helm repo add bitnami https://charts.bitnami.com/bitnami +helm repo add zalando https://opensource.zalando.com/postgres-operator/charts/postgres-operator +helm repo update +``` + +2. Update chart dependencies: + +```bash +helm dependency update . +helm dependency build . +``` + +3. Install the chart: + +```bash +helm install namada-indexer . \ + --create-namespace \ + --namespace namada-indexer \ + -f values.yaml +``` + +For a basic installation with default values: + +```bash +helm install namada-indexer . \ + --create-namespace \ + --namespace namada-indexer +``` + +To upgrade an existing installation: + +```bash +helm upgrade namada-indexer . \ + --namespace namada-indexer \ + -f values.yaml +``` + +## Configuration + +### Database Configuration + +#### Option 1: Built-in PostgreSQL + +```yaml +postgresOperator: + install: + enabled: true + enabled: true + teamId: "namada" + volume: + size: 100Gi + storageClass: "oci-bv" + numberOfInstances: 3 +``` + +#### Option 2: External PostgreSQL + +```yaml +postgresOperator: + install: + enabled: false + enabled: false + +externalPostgres: + enabled: true + host: "your-postgres-host" + port: "5432" + credentialSecret: + name: "your-postgres-secret" +``` + +### Redis Configuration + +#### Option 1: Built-in Redis (Default) + +```yaml +redis: + install: + enabled: true + enabled: true + architecture: replication + sentinel: + enabled: true + quorum: 2 + replica: + replicaCount: 3 +``` + +#### Option 2: External Redis + +```yaml +redis: + install: + enabled: false + enabled: false + +externalRedis: + enabled: true + host: "your-redis-host" + port: "6379" +``` + +### Indexer Configuration + +```yaml +configmaps: + config: + data: + TENDERMINT_URL: "http://your-tendermint-rpc:26657/" + +containers: + chain: + resources: + limits: + cpu: "1" + memory: "1Gi" + webserver: + ingress: + enabled: true + hosts: + - host: api.your-domain.com +``` + +## Dependencies + +This chart depends on: + +- PostgreSQL Operator (optional) +- Redis (optional) + +## Contributing + +[Contributing guidelines](CONTRIBUTING.md) + +## License + +Apache 2.0 diff --git a/charts/namada-indexer/templates/_helpers.tpl b/charts/namada-indexer/templates/_helpers.tpl new file mode 100644 index 0000000..4ada5fd --- /dev/null +++ b/charts/namada-indexer/templates/_helpers.tpl @@ -0,0 +1,160 @@ +{{- define "namada-indexer.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "namada-indexer.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} + +{{- define "namada-indexer.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "namada-indexer.labels" -}} +helm.sh/chart: {{ include "namada-indexer.chart" . }} +{{ include "namada-indexer.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "namada-indexer.selectorLabels" -}} +app.kubernetes.io/name: {{ include "namada-indexer.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "namada-indexer.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "namada-indexer.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Container configuration helper +*/}} +{{- define "namada-indexer.containerConfig" -}} +{{- $ := index . 0 -}} +{{- $container := index . 1 -}} +{{- with $container -}} +{{- if .command }} +command: +{{- toYaml .command | nindent 2 }} +{{- end }} +{{- if .args }} +args: +{{- toYaml .args | nindent 2 }} +{{- end }} +{{- if .ports }} +ports: +{{- toYaml .ports | nindent 2 }} +{{- end }} +{{- if .livenessProbe }} +livenessProbe: +{{- toYaml .livenessProbe | nindent 2 }} +{{- end }} +{{- end }} +{{- if $.Values.containerDefaults }} +resources: +{{- toYaml $.Values.containerDefaults.resources | nindent 2 }} +envFrom: +{{- toYaml $.Values.containerDefaults.envFrom | nindent 2 }} +env: +{{- end }} +{{- end }} + +{{/* +Database configuration helper +*/}} +{{- define "namada-indexer.dbConfig" -}} +{{- if .Values.postgresOperator.enabled }} +DB_HOST: "{{ include "namada-indexer.fullname" . }}-db.{{ .Release.Namespace }}.svc.cluster.local" +SECRET_NAME: "namada.{{ .Release.Namespace }}-db.credentials.postgresql.acid.zalan.do" +{{- else if .Values.externalPostgres.enabled }} +DB_HOST: {{ .Values.externalPostgres.host | quote }} +SECRET_NAME: {{ .Values.externalPostgres.credentialSecret.name | quote }} +{{- end }} +{{- end }} + +{{/* +Database environment variables +*/}} +{{- define "namada-indexer.dbEnv" -}} +{{- if .Values.postgresOperator.enabled }} +- name: DB_USER + valueFrom: + secretKeyRef: + name: namada.{{ .Release.Name }}-db.credentials.postgresql.acid.zalan.do + key: username +- name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: namada.{{ .Release.Name }}-db.credentials.postgresql.acid.zalan.do + key: password +{{- else if .Values.externalPostgres.enabled }} +- name: DB_USER + valueFrom: + secretKeyRef: + name: {{ .Values.externalPostgres.credentialSecret.name }} + key: {{ .Values.externalPostgres.credentialSecret.usernameKey | default "username" }} +- name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.externalPostgres.credentialSecret.name }} + key: {{ .Values.externalPostgres.credentialSecret.passwordKey | default "password" }} +{{- end }} +{{- end }} + +{{/* +Database configuration validation +*/}} +{{- define "namada-indexer.validateDbConfig" -}} +{{- if and .Values.postgresOperator.enabled .Values.externalPostgres.enabled }} +{{- fail "Cannot enable both postgresOperator and externalPostgres at the same time" }} +{{- end }} +{{- if not (or .Values.postgresOperator.enabled .Values.externalPostgres.enabled) }} +{{- fail "Either postgresOperator or externalPostgres must be enabled" }} +{{- end }} +{{- end }} + +{{/* +Redis configuration helper +*/}} +{{- define "namada-indexer.redisConfig" -}} +{{- if .Values.redis.install.enabled }} +REDIS_HOST: "{{ .Release.Name }}-redis-master.{{ .Release.Namespace }}.svc.cluster.local" +REDIS_PORT: "6379" +REDIS_SECRET_NAME: "{{ .Release.Name }}-redis" +{{- else if .Values.externalRedis.enabled }} +REDIS_HOST: {{ .Values.externalRedis.host | quote }} +REDIS_PORT: {{ .Values.externalRedis.port | quote }} +REDIS_SECRET_NAME: {{ .Values.externalRedis.credentialSecret.name | quote }} +{{- end }} +{{- end }} + +{{/* +Redis configuration validation +*/}} +{{- define "namada-indexer.validateRedisConfig" -}} +{{- if and .Values.redis.install.enabled .Values.externalRedis.enabled }} +{{- fail "Cannot enable both redis.install and externalRedis at the same time" }} +{{- end }} +{{- if not (or .Values.redis.install.enabled .Values.externalRedis.enabled) }} +{{- fail "Either redis.install or externalRedis must be enabled" }} +{{- end }} +{{- end }} diff --git a/charts/namada-indexer/templates/configmap.yaml b/charts/namada-indexer/templates/configmap.yaml new file mode 100644 index 0000000..5cd7345 --- /dev/null +++ b/charts/namada-indexer/templates/configmap.yaml @@ -0,0 +1,21 @@ +{{- $dbConfig := include "namada-indexer.dbConfig" . | fromYaml }} +{{- $redisConfig := include "namada-indexer.redisConfig" . | fromYaml }} +{{- range $name, $configmap := .Values.configmaps }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "namada-indexer.fullname" $ }}-{{ $name }} + labels: + {{- include "namada-indexer.labels" $ | nindent 4 }} +data: + {{- if $dbConfig }} + {{- toYaml $dbConfig | nindent 2 }} + {{- end }} + {{- if $redisConfig }} + {{- toYaml $redisConfig | nindent 2 }} + {{- end }} + {{- range $key, $value := $configmap.data }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} diff --git a/charts/namada-indexer/templates/dependencies-job.yaml b/charts/namada-indexer/templates/dependencies-job.yaml new file mode 100644 index 0000000..25b4b97 --- /dev/null +++ b/charts/namada-indexer/templates/dependencies-job.yaml @@ -0,0 +1,83 @@ +{{- if or (.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: + {{- if .Values.argocd.deployment }} + "argocd.argoproj.io/hook": "Sync" + "argocd.argoproj.io/sync-wave": "1" + {{- else }} + "helm.sh/hook": "post-install" + "helm.sh/hook-weight": "-5" + "helm.sh/hook-delete-policy": "hook-succeeded,before-hook-creation" + {{- end }} + 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 + - | + # Only try to scale if deployment exists + if kubectl get deployment -n {{ .Release.Namespace }} {{ include "namada-indexer.fullname" . }}; then + kubectl scale deployment -n {{ .Release.Namespace }} {{ include "namada-indexer.fullname" . }} --replicas=0 + fi + + {{- if .Values.postgresOperator.enabled }} + # 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!" + + # Only try to scale back if deployment exists + if kubectl get deployment -n {{ .Release.Namespace }} {{ include "namada-indexer.fullname" . }}; then + kubectl scale deployment -n {{ .Release.Namespace }} {{ include "namada-indexer.fullname" . }} --replicas={{ .Values.replicaCount }} + fi + + 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 new file mode 100644 index 0000000..4dfdb47 --- /dev/null +++ b/charts/namada-indexer/templates/deployment.yaml @@ -0,0 +1,188 @@ +{{- include "namada-indexer.validateDbConfig" . }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "namada-indexer.fullname" . }} + labels: + {{- include "namada-indexer.labels" . | nindent 4 }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.argocd.deployment }} + annotations: + "argocd.argoproj.io/sync-wave": "2" + {{- else }} + annotations: + "helm.sh/hook-weight": "-10" + {{- end }} +spec: + replicas: {{ .Values.replicaCount }} + strategy: + {{- toYaml .Values.strategy | nindent 4 }} + selector: + matchLabels: + {{- include "namada-indexer.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "namada-indexer.selectorLabels" . | nindent 8 }} + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "namada-indexer.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + {{- range $key, $value := .Values.containers }} + - name: {{ $key }} + image: {{ $value.image }} + imagePullPolicy: {{ $.Values.imagePullPolicy | default "IfNotPresent" }} + {{- with $.Values.containerDefaults }} + # Apply all defaults first + {{- if .command }} + command: + {{- toYaml .command | nindent 12 }} + {{- end }} + {{- if .args }} + args: + {{- toYaml .args | nindent 12 }} + {{- end }} + {{- if .ports }} + ports: + {{- toYaml .ports | nindent 12 }} + {{- end }} + {{- if .resources }} + resources: + {{- toYaml .resources | nindent 12 }} + {{- end }} + {{- if .livenessProbe }} + livenessProbe: + {{- toYaml .livenessProbe | nindent 12 }} + {{- end }} + {{- if .readinessProbe }} + readinessProbe: + {{- toYaml .readinessProbe | nindent 12 }} + {{- end }} + {{- if .volumeMounts }} + volumeMounts: + {{- toYaml .volumeMounts | nindent 12 }} + {{- end }} + {{- end }} + + # Then apply container-specific overrides + {{- if $value.ports }} + ports: + {{- toYaml $value.ports | nindent 12 }} + {{- end }} + {{- if $value.command }} + command: + {{- toYaml $value.command | nindent 12 }} + {{- end }} + {{- if $value.args }} + args: + {{- toYaml $value.args | nindent 12 }} + {{- end }} + + # Merge envFrom from both defaults and container-specific + envFrom: + {{- if $.Values.containerDefaults.envFrom }} + {{- toYaml $.Values.containerDefaults.envFrom | nindent 12 }} + {{- end }} + {{- if $value.envFrom }} + {{- toYaml $value.envFrom | nindent 12 }} + {{- end }} + {{- range $.Values.externalSecrets }} + - secretRef: + name: {{ .target.name }} + {{- end }} + env: + {{- include "namada-indexer.dbEnv" $ | nindent 12 }} + {{- with $value.env }} + {{- toYaml . | nindent 12 }} + {{- end }} + + {{- if $value.volumeMounts }} + volumeMounts: + {{- toYaml $value.volumeMounts | nindent 12 }} + {{- end }} + {{- if $value.env }} + env: + {{- toYaml $value.env | nindent 12 }} + {{- end }} + {{- if $value.resources }} + resources: + {{- toYaml $value.resources | nindent 12 }} + {{- end }} + {{- if $value.livenessProbe }} + livenessProbe: + {{- toYaml $value.livenessProbe | nindent 12 }} + {{- end }} + {{- if $value.readinessProbe }} + readinessProbe: + {{- toYaml $value.readinessProbe | nindent 12 }} + {{- end }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.initContainers }} + initContainers: + {{- range $key, $value := .Values.initContainers }} + - name: {{ $key }} + image: {{ $value.image }} + imagePullPolicy: {{ $.Values.imagePullPolicy | default "IfNotPresent" }} + command: {{- toYaml $value.command | nindent 12 }} + # Merge envFrom from both defaults and container-specific + envFrom: + {{- if $.Values.containerDefaults.envFrom }} + {{- toYaml $.Values.containerDefaults.envFrom | nindent 12 }} + {{- end }} + {{- if $value.envFrom }} + {{- toYaml $value.envFrom | nindent 12 }} + {{- end }} + env: + {{- include "namada-indexer.dbEnv" $ | nindent 12 }} + {{- if $value.env }} + {{- toYaml $value.env | nindent 12 }} + {{- end }} + {{- if $value.volumeMounts }} + volumeMounts: + {{- toYaml $value.volumeMounts | nindent 12 }} + {{- end }} + {{- end }} + {{- end }} + volumes: + {{- if .Values.additionalVolumes }} + {{- range $key, $value := .Values.additionalVolumes }} + - name: {{ $key }} + {{- if $value.hostPath }} + hostPath: + path: {{ $value.hostPath.path }} + type: {{ $value.hostPath.type | default "DirectoryOrCreate" }} + {{- end }} + {{- if $value.configMap }} + configMap: + name: {{ $value.configMap.name }} + {{- end }} + {{- if $value.secret }} + secret: + secretName: {{ $value.secret.secretName }} + {{- end }} + {{- end }} + {{- end }} + restartPolicy: Always diff --git a/charts/namada-indexer/templates/ingress.yaml b/charts/namada-indexer/templates/ingress.yaml new file mode 100644 index 0000000..cef3a5c --- /dev/null +++ b/charts/namada-indexer/templates/ingress.yaml @@ -0,0 +1,42 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "namada-indexer.fullname" . -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "namada-indexer.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.ingress.className }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ $fullName }}-{{ .serviceName }} + port: + number: {{ .servicePort }} + {{- end }} + {{- end }} +{{- end }} 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..aee8b8b --- /dev/null +++ b/charts/namada-indexer/templates/postgresql-cleanup-hook.yaml @@ -0,0 +1,49 @@ +{{- if and .Values.postgresOperator.install.enabled .Values.postgresOperator.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "namada-indexer.fullname" . }}-db-cleanup + annotations: + {{- if .Values.argocd.deployment }} + "argocd.argoproj.io/hook": "PreDelete" + "argocd.argoproj.io/sync-wave": "-2" + {{- else }} + "helm.sh/hook": "pre-delete" + "helm.sh/hook-delete-policy": "hook-succeeded,before-hook-creation" + {{- end }} + labels: + {{- include "namada-indexer.labels" . | nindent 4 }} +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 new file mode 100644 index 0000000..33eddbb --- /dev/null +++ b/charts/namada-indexer/templates/postgresql.yaml @@ -0,0 +1,44 @@ +{{- if .Values.postgresOperator.enabled }} +apiVersion: "acid.zalan.do/v1" +kind: postgresql +metadata: + name: {{ include "namada-indexer.fullname" . }}-db + labels: + {{- include "namada-indexer.labels" . | nindent 4 }} + finalizers: + - kubernetes + annotations: + {{- if .Values.argocd.deployment }} + "argocd.argoproj.io/sync-wave": "0" + {{- end }} +spec: + teamId: {{ .Values.postgresOperator.teamId }} + {{- if .Values.postgresOperator.kubernetes }} + kubernetes: + {{- toYaml .Values.postgresOperator.kubernetes | nindent 4 }} + {{- end }} + volume: + size: {{ .Values.postgresOperator.volume.size }} + {{- if .Values.postgresOperator.volume.storageClass }} + storageClass: {{ .Values.postgresOperator.volume.storageClass }} + {{- end }} + numberOfInstances: {{ .Values.postgresOperator.numberOfInstances }} + users: + {{- toYaml .Values.postgresOperator.users | nindent 4 }} + databases: + {{- toYaml .Values.postgresOperator.databases | nindent 4 }} + postgresql: + version: {{ .Values.postgresOperator.version | quote }} + parameters: + {{- toYaml .Values.postgresOperator.parameters | nindent 6 }} + {{- if .Values.postgresOperator.enableConnectionPooler }} + enableConnectionPooler: {{ .Values.postgresOperator.enableConnectionPooler }} + {{- end }} + {{- if .Values.postgresOperator.enableReplicaConnectionPooler }} + enableReplicaConnectionPooler: {{ .Values.postgresOperator.enableReplicaConnectionPooler }} + {{- end }} + {{- with .Values.postgresOperator.nodeAffinity }} + nodeAffinity: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/namada-indexer/templates/rbac.yaml b/charts/namada-indexer/templates/rbac.yaml new file mode 100644 index 0000000..3ac5a66 --- /dev/null +++ b/charts/namada-indexer/templates/rbac.yaml @@ -0,0 +1,62 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "namada-indexer.fullname" . }} + labels: + {{- include "namada-indexer.labels" . | nindent 4 }} + annotations: + {{- if .Values.argocd.deployment }} + "argocd.argoproj.io/sync-wave": "-3" + {{- else }} + "helm.sh/hook": "pre-install,pre-upgrade" + "helm.sh/hook-weight": "-9" + {{- end }} +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 }} + annotations: + {{- if .Values.argocd.deployment }} + "argocd.argoproj.io/sync-wave": "-3" + {{- else }} + "helm.sh/hook": "pre-install,pre-upgrade" + "helm.sh/hook-weight": "-9" + {{- end }} +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/templates/service-account.yaml b/charts/namada-indexer/templates/service-account.yaml new file mode 100644 index 0000000..7e943c1 --- /dev/null +++ b/charts/namada-indexer/templates/service-account.yaml @@ -0,0 +1,19 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "namada-indexer.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "namada-indexer.labels" . | nindent 4 }} + annotations: + {{- if .Values.argocd.deployment }} + "argocd.argoproj.io/sync-wave": "-4" + {{- else }} + "helm.sh/hook": "pre-install,pre-upgrade" + "helm.sh/hook-weight": "-10" + {{- end }} + {{- with .Values.serviceAccount.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/namada-indexer/templates/service.yaml b/charts/namada-indexer/templates/service.yaml new file mode 100644 index 0000000..f68baa8 --- /dev/null +++ b/charts/namada-indexer/templates/service.yaml @@ -0,0 +1,22 @@ +{{- range $key, $value := .Values.containers }} +{{- if hasKey $value "service" }} +{{- if $value.service.enabled }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "namada-indexer.fullname" $ }}-{{ $key }} + labels: + {{- include "namada-indexer.labels" $ | nindent 4 }} +spec: + type: {{ $value.service.type }} + ports: + - port: {{ $value.service.port }} + targetPort: {{ $value.service.targetPort | default $value.containerPort }} + protocol: TCP + name: {{ $key }} + selector: + {{- include "namada-indexer.selectorLabels" $ | nindent 4 }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/namada-indexer/values.yaml b/charts/namada-indexer/values.yaml new file mode 100644 index 0000000..8359517 --- /dev/null +++ b/charts/namada-indexer/values.yaml @@ -0,0 +1,168 @@ +replicaCount: 1 + +# If deployed by argocd add sync waves to batch jobs +argocd: + deployment: false + +# Common configurations in ConfigMaps +configmaps: + config: + data: {} + +# PostgreSQL Operator Configuration +postgresOperator: + install: + enabled: true + enabled: true + teamId: "" + volume: + size: "" + storageClass: "" + numberOfInstances: 1 + users: {} + databases: {} + version: "" + parameters: {} + resourcePolicy: "" + +externalPostgres: + enabled: false + host: "" + port: "" + database: "" + credentialSecret: + name: "" + usernameKey: "" + passwordKey: "" + +# Redis Configuration +redis: + install: + enabled: true + enabled: true + architecture: standalone + sentinel: + enabled: false + masterSet: "" + quorum: 2 + replica: + replicaCount: 1 + persistence: + enabled: false + size: "" + storageClass: "" + resourcePolicy: "" + master: + persistence: + enabled: false + size: "" + storageClass: "" + resourcePolicy: "" + metrics: + enabled: false + serviceMonitor: + enabled: false + +externalRedis: + enabled: false + host: "" + port: "" + +# Common container defaults +containerDefaults: + resources: + limits: {} + requests: {} + envFrom: [] + +# Init containers configuration +initContainers: + init-db: + image: "" + command: [] + args: [] + +# Main containers configuration +containers: + + chain: + image: "" + command: [] + args: [] + + governance: + image: "" + command: [] + args: [] + + pos: + image: "" + command: [] + args: [] + + rewards: + image: "" + command: [] + args: [] + + parameters: + image: "" + command: [] + args: [] + + transactions: + image: "" + command: [] + args: [] + + webserver: + image: "" + command: [] + args: [] + ports: + - name: http + containerPort: 5001 + protocol: TCP + service: + enabled: false + type: ClusterIP + port: 80 + targetPort: 5001 + +# Global configuration +imagePullSecrets: [] +imagePullPolicy: IfNotPresent + +podSecurityContext: {} + +securityContext: {} + +strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + +serviceAccount: + create: false + name: "" + +# Ingress configuration +ingress: + enabled: false + className: "" + annotations: {} + hosts: [] + tls: [] + +# Resource quotas and limits +resources: {} + +# Node selector +nodeSelector: {} + +# Tolerations +tolerations: [] + +# Affinity +affinity: {}