diff --git a/infrastructure/charts/mev-commit-preconf-rpc/Chart.yaml b/infrastructure/charts/mev-commit-preconf-rpc/Chart.yaml new file mode 100644 index 000000000..41f964653 --- /dev/null +++ b/infrastructure/charts/mev-commit-preconf-rpc/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: preconf-rpc +description: A Helm chart for MEV Commit Preconf RPC service +type: application +version: 0.1.0 +appVersion: "1.0.0" diff --git a/infrastructure/charts/mev-commit-preconf-rpc/templates/_helpers.tpl b/infrastructure/charts/mev-commit-preconf-rpc/templates/_helpers.tpl new file mode 100644 index 000000000..b1fb4ddec --- /dev/null +++ b/infrastructure/charts/mev-commit-preconf-rpc/templates/_helpers.tpl @@ -0,0 +1,63 @@ +# templates/_helpers.tpl +{{/* +Expand the name of the chart. +*/}} +{{- define "preconf-rpc.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "preconf-rpc.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "preconf-rpc.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "preconf-rpc.labels" -}} +helm.sh/chart: {{ include "preconf-rpc.chart" . }} +{{ include "preconf-rpc.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "preconf-rpc.selectorLabels" -}} +app.kubernetes.io/name: {{ include "preconf-rpc.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "preconf-rpc.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "preconf-rpc.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/infrastructure/charts/mev-commit-preconf-rpc/templates/deployment.yaml b/infrastructure/charts/mev-commit-preconf-rpc/templates/deployment.yaml new file mode 100644 index 000000000..769c15b1f --- /dev/null +++ b/infrastructure/charts/mev-commit-preconf-rpc/templates/deployment.yaml @@ -0,0 +1,137 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "preconf-rpc.fullname" . }} + labels: + {{- include "preconf-rpc.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "preconf-rpc.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "preconf-rpc.selectorLabels" . | nindent 8 }} + spec: + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: {{ .Values.config.httpPort }} + protocol: TCP + args: + - --http-port={{ .Values.config.httpPort }} + - --log-level={{ .Values.config.logLevel }} + - --log-fmt={{ .Values.config.logFormat }} + {{- if .Values.config.logTags }} + - --log-tags={{ .Values.config.logTags }} + {{- end }} + - --keystore-dir={{ .Values.keystore.dir }} + - --keystore-password=$(KEYSTORE_PASSWORD) + {{- range .Values.config.l1RpcUrls }} + - --l1-rpc-urls={{ . }} + {{- end }} + - --settlement-rpc-url={{ .Values.config.settlementRpcUrl }} + - --bidder-rpc-url={{ .Values.config.bidderRpcUrl }} + - --l1-contract-addr={{ .Values.config.l1ContractAddr }} + - --settlement-contract-addr={{ .Values.config.settlementContractAddr }} + - --deposit-address={{ .Values.config.depositAddress }} + - --bridge-address={{ .Values.config.bridgeAddress }} + - --settlement-threshold={{ .Values.config.settlementThreshold }} + - --settlement-topup={{ .Values.config.settlementTopup }} + - --auto-deposit-amount={{ .Values.config.autoDepositAmount }} + - --gas-tip-cap={{ .Values.config.gasTipCap }} + - --gas-fee-cap={{ .Values.config.gasFeeCap }} + env: + - name: KEYSTORE_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "preconf-rpc.fullname" . }}-keystore-password + key: password + - name: POSTGRES_PASSWORD + value: {{ .Values.postgresql.password | quote }} + - name: PRECONF_RPC_PG_HOST + value: {{ .Values.postgresql.host | quote }} + - name: PRECONF_RPC_PG_PORT + value: {{ .Values.postgresql.port | quote }} + - name: PRECONF_RPC_PG_USER + value: {{ .Values.postgresql.username | quote }} + - name: PRECONF_RPC_PG_PASSWORD + value: {{ .Values.postgresql.password | quote }} + - name: PRECONF_RPC_PG_DBNAME + value: {{ .Values.postgresql.database | quote }} + securityContext: + runAsUser: 0 + runAsGroup: 0 + runAsNonRoot: false + {{- if .Values.probes.liveness.enabled }} + livenessProbe: + httpGet: + {{- toYaml .Values.probes.liveness.httpGet | nindent 14 }} + initialDelaySeconds: {{ .Values.probes.liveness.initialDelaySeconds }} + periodSeconds: {{ .Values.probes.liveness.periodSeconds }} + timeoutSeconds: {{ .Values.probes.liveness.timeoutSeconds }} + failureThreshold: {{ .Values.probes.liveness.failureThreshold }} + successThreshold: {{ .Values.probes.liveness.successThreshold }} + {{- end }} + + {{- if .Values.probes.readiness.enabled }} + readinessProbe: + httpGet: + {{- toYaml .Values.probes.readiness.httpGet | nindent 14 }} + initialDelaySeconds: {{ .Values.probes.readiness.initialDelaySeconds }} + periodSeconds: {{ .Values.probes.readiness.periodSeconds }} + timeoutSeconds: {{ .Values.probes.readiness.timeoutSeconds }} + failureThreshold: {{ .Values.probes.readiness.failureThreshold }} + successThreshold: {{ .Values.probes.readiness.successThreshold }} + {{- end }} + + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: keystore-dir + mountPath: {{ .Values.keystore.dir }} + readOnly: false + + initContainers: + - name: rename-keystore + image: busybox:latest + command: + - sh + - -c + - | + FILENAME=$(cat /temp/filename.txt) + cp /temp/temp_keystore.json /keystore/"$FILENAME" + volumeMounts: + - mountPath: /temp + name: temp-keystore + readOnly: true + - mountPath: /keystore + name: keystore-dir + + volumes: + - name: temp-keystore + secret: + secretName: {{ include "preconf-rpc.fullname" . }}-keystore + - name: keystore-dir + emptyDir: {} + + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/infrastructure/charts/mev-commit-preconf-rpc/templates/externalsecret.yaml b/infrastructure/charts/mev-commit-preconf-rpc/templates/externalsecret.yaml new file mode 100644 index 000000000..c263f1b46 --- /dev/null +++ b/infrastructure/charts/mev-commit-preconf-rpc/templates/externalsecret.yaml @@ -0,0 +1,53 @@ +--- +# ExternalSecret for AWS SM - Keystore + Filename +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: {{ include "preconf-rpc.fullname" . }}-keystore + labels: + {{- include "preconf-rpc.labels" . | nindent 4 }} + annotations: + helm.sh/hook: pre-install,pre-upgrade + helm.sh/hook-weight: "-2" +spec: + refreshInterval: {{ .Values.keystore.refreshInterval }} + secretStoreRef: + name: {{ .Values.keystore.secretStore.name }} + kind: {{ .Values.keystore.secretStore.kind }} + target: + name: {{ include "preconf-rpc.fullname" . }}-keystore + creationPolicy: Owner + data: + - secretKey: temp_keystore.json + remoteRef: + key: {{ .Values.keystore.awsSecretName }} + property: {{ .Values.keystore.properties.keystore }} + - secretKey: filename.txt + remoteRef: + key: {{ .Values.keystore.awsSecretName }} + property: {{ .Values.keystore.properties.keystoreFilename }} + +--- +# ExternalSecret for keystore password +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: {{ include "preconf-rpc.fullname" . }}-keystore-password + labels: + {{- include "preconf-rpc.labels" . | nindent 4 }} + annotations: + helm.sh/hook: pre-install,pre-upgrade + helm.sh/hook-weight: "-2" +spec: + refreshInterval: {{ .Values.keystore.refreshInterval }} + secretStoreRef: + name: {{ .Values.keystore.secretStore.name }} + kind: {{ .Values.keystore.secretStore.kind }} + target: + name: {{ include "preconf-rpc.fullname" . }}-keystore-password + creationPolicy: Owner + data: + - secretKey: password + remoteRef: + key: {{ .Values.keystore.awsSecretName }} + property: {{ .Values.keystore.properties.keystorePassword }} diff --git a/infrastructure/charts/mev-commit-preconf-rpc/templates/service.yaml b/infrastructure/charts/mev-commit-preconf-rpc/templates/service.yaml new file mode 100644 index 000000000..6ca751ea5 --- /dev/null +++ b/infrastructure/charts/mev-commit-preconf-rpc/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "preconf-rpc.fullname" . }} + labels: + {{- include "preconf-rpc.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - name: http + port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + selector: + {{- include "preconf-rpc.selectorLabels" . | nindent 4 }} diff --git a/infrastructure/charts/mev-commit-preconf-rpc/values.yaml b/infrastructure/charts/mev-commit-preconf-rpc/values.yaml new file mode 100644 index 000000000..1a87ff2a4 --- /dev/null +++ b/infrastructure/charts/mev-commit-preconf-rpc/values.yaml @@ -0,0 +1,105 @@ +# Default values for preconf-rpc +replicaCount: 1 + +image: + repository: + pullPolicy: IfNotPresent + tag: "" + +service: + type: ClusterIP + port: 8080 + +ingress: + enabled: false + className: "" + annotations: {} + hosts: + - host: preconf-rpc.local + paths: + - path: / + pathType: Prefix + tls: [] + +resources: + limits: + cpu: 1000m + memory: 1Gi + requests: + cpu: 500m + memory: 512Mi + +# Health check probes configuration +probes: + liveness: + enabled: true + httpGet: + path: /health + port: 8080 + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + successThreshold: 1 + readiness: + enabled: true + httpGet: + path: /health + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 3 + failureThreshold: 3 + successThreshold: 1 + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +# Non-sensitive application config (CLI flags) +config: + httpPort: 8080 + logLevel: "info" + logFormat: "json" + logTags: "" + l1RpcUrls: + - "" + settlementRpcUrl: "" + bidderRpcUrl: "" + l1ContractAddr: "" + settlementContractAddr: "" + depositAddress: "" + bridgeAddress: "" + settlementThreshold: "2000000000000000000" # 2 ETH + settlementTopup: "2000000000000000000" # 10 ETH + autoDepositAmount: "100000000000000000" # 1 ETH + gasTipCap: "50000000" # 0.05 gWEI + gasFeeCap: "60000000" # 0.06 gWEI + +# Keystore configuration (using ESO for AWS Secrets Manager) +keystore: + dir: "/app/keystore" + refreshInterval: "1h" + secretStore: + name: "aws-cluster-secret-store" + kind: "ClusterSecretStore" + awsSecretName: "" # AWS Secret Manager secret name + # Properties from AWS (match the secret keys + properties: + keystore: "" + keystoreFilename: "" + keystorePassword: "" + +# PostgreSQL configuration +postgresql: + host: "preconf-rpc-pg.default.svc.cluster.local" + port: 5432 + username: "" + database: "" + password: "" + +service: + type: ClusterIP + port: 8080