apiVersion: apps/v1 kind: StatefulSet metadata: name: {{ include "unitycatalog.server.fullname" . }} labels: {{- include "unitycatalog.server.labels" . | nindent 4 }} spec: serviceName: unitycatalog-server replicas: {{ .Values.server.statefulset.replicaCount }} selector: matchLabels: {{- include "unitycatalog.server.selectorLabels" . | nindent 6 }} template: metadata: annotations: checksum/config: {{ include "unitycatalog.server.configTemplate" . | sha256sum }} {{- with .Values.server.statefulset.podAnnotations }} {{- toYaml . | nindent 8 }} {{- end }} labels: {{- include "unitycatalog.server.labels" . | nindent 8 }} {{- with .Values.server.statefulset.podLabels }} {{- toYaml . | nindent 8 }} {{- end }} spec: {{- with .Values.server.statefulset.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} serviceAccountName: {{ include "unitycatalog.serviceAccountName" . }} {{- with .Values.server.statefulset.podSecurityContext }} securityContext: {{- toYaml . | nindent 8 }} {{- end }} initContainers: {{- if .Values.privateCA.enabled }} - name: generate-truststore image: eclipse-temurin:17-alpine command: - sh - -c - | echo "[INFO] Checking for CA file at /ca/ca.crt..." if [ ! -f /ca/ca.crt ]; then echo "[ERROR] /ca/ca.crt not found. Make sure the 'my-private-ca' Secret contains 'ca.crt'." exit 1 fi TRUSTSTORE_PATH="/truststore/truststore.jks" if [ -f "$TRUSTSTORE_PATH" ]; then echo "[INFO] Existing truststore found. Removing..." rm -f "$TRUSTSTORE_PATH" fi echo "[INFO] Copying default Java truststore to $TRUSTSTORE_PATH..." cp "$JAVA_HOME/lib/security/cacerts" "$TRUSTSTORE_PATH" echo "[INFO] Importing private CA into truststore..." keytool -importcert -noprompt \ -alias private-ca \ -file /ca/ca.crt \ -keystore "$TRUSTSTORE_PATH" \ -storepass changeit echo "[INFO] Truststore created successfully with private CA." volumeMounts: - name: ca-tls mountPath: /ca - name: truststore-volume mountPath: /truststore {{- end }} - name: render-config image: "{{ .Values.server.statefulset.initContainer.image.repository }}:{{ .Values.server.statefulset.initContainer.image.tag }}" imagePullPolicy: {{ .Values.server.statefulset.initContainer.image.pullPolicy }} command: - /bin/sh - -c - |- envsubst < /home/unitycatalog/etc/confTemplates/server.properties.template > /home/unitycatalog/etc/conf/server.properties envsubst < /home/unitycatalog/etc/confTemplates/server.log4j2.properties.template > /home/unitycatalog/etc/conf/server.log4j2.properties envsubst < /home/unitycatalog/etc/confTemplates/hibernate.properties.template > /home/unitycatalog/etc/conf/hibernate.properties volumeMounts: - name: config-templates mountPath: /home/unitycatalog/etc/confTemplates - name: config-volume mountPath: /home/unitycatalog/etc/conf env: {{- range $index, $config := .Values.storage.credentials.s3 }} - name: S3_ACCESS_KEY_{{ $index }} valueFrom: secretKeyRef: name: {{ $config.credentialsSecretName }} key: accessKey - name: S3_SECRET_KEY_{{ $index }} valueFrom: secretKeyRef: name: {{ $config.credentialsSecretName }} key: secretKey {{- end }} {{- range $index, $config := .Values.storage.credentials.adls }} - name: ADLS_TENANT_ID_{{ $index }} valueFrom: secretKeyRef: name: {{ $config.credentialsSecretName }} key: tenantId - name: ADLS_CLIENT_ID_{{ $index }} valueFrom: secretKeyRef: name: {{ $config.credentialsSecretName }} key: clientId - name: ADLS_CLIENT_SECRET_{{ $index }} valueFrom: secretKeyRef: name: {{ $config.credentialsSecretName }} key: clientSecret {{- end }} {{- if .Values.auth.enabled }} - name: OAUTH_CLIENT_ID valueFrom: secretKeyRef: name: {{ .Values.auth.clientSecretName }} key: clientId - name: OAUTH_CLIENT_SECRET valueFrom: secretKeyRef: name: {{ .Values.auth.clientSecretName }} key: clientSecret {{- end }} containers: - name: server {{- with .Values.server.statefulset.securityContext }} securityContext: {{- toYaml . | nindent 12 }} {{- end }} image: "{{ .Values.server.statefulset.image.repository }}:{{ .Values.server.statefulset.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.server.statefulset.image.pullPolicy }} ports: - name: api containerPort: {{ .Values.server.statefulset.port }} protocol: TCP {{- with .Values.server.statefulset.livenessProbe }} livenessProbe: {{- toYaml . | nindent 12 }} {{- end }} {{- with .Values.server.statefulset.readinessProbe }} readinessProbe: {{- toYaml . | nindent 12 }} {{- end }} {{- with .Values.server.statefulset.resources }} resources: {{- toYaml . | nindent 12 }} {{- end }} volumeMounts: - name: config-volume mountPath: /home/unitycatalog/etc/conf - name: db-volume mountPath: /home/unitycatalog/etc/db {{- range $index, $config := .Values.storage.credentials.gcs }} - name: gcs-credentials-{{ $index }} mountPath: /home/unitycatalog/etc/conf/gcs-credentials-{{ $index }}.json subPath: jsonKey readOnly: true {{- end }} {{- if .Values.privateCA.enabled }} - name: truststore-volume mountPath: /truststore env: - name: JAVA_TOOL_OPTIONS value: "-Djavax.net.ssl.trustStore=/truststore/truststore.jks -Djavax.net.ssl.trustStorePassword=changeit" {{- end }} {{- with .Values.server.statefulset.volumeMounts }} {{- toYaml . | nindent 12 }} {{- end }} {{ if and .Values.auth.enabled .Values.auth.users }} - name: create-users image: "{{ .Values.server.createUsersJob.image.repository }}:{{ .Values.server.createUsersJob.image.tag }}" imagePullPolicy: {{ .Values.server.createUsersJob.image.pullPolicy }} command: - /bin/sh - -c - |- set -ex until curl -H "Authorization: Bearer $(cat /home/unitycatalog/etc/conf/token.txt)" \ -X GET "http://localhost:{{ .Values.server.statefulset.port }}/api/1.0/unity-control/scim2/Users" \ -H "Content-Type: application/json" do echo "Waiting for Unity Catalog server API to be available..." sleep 1 done {{- range $index, $user := .Values.auth.users }} if curl -H "Authorization: Bearer $(cat /home/unitycatalog/etc/conf/token.txt)" \ -X GET "http://localhost:{{ $.Values.server.statefulset.port }}/api/1.0/unity-control/scim2/Users" \ -H "Content-Type: application/json" | jq -e '.Resources[] | select(.emails[0].value == "{{ $user.email }}")' then echo "User {{ $user.email }} already exists" else echo "User {{ $user.email }} is being created" curl -H "Authorization: Bearer $(cat /home/unitycatalog/etc/conf/token.txt)" \ -X POST "http://localhost:{{ $.Values.server.statefulset.port }}/api/1.0/unity-control/scim2/Users" \ -H "Content-Type: application/json" \ -d '{"displayName": "{{ $user.name }}", "emails": [{"primary": true, "value": "{{ $user.email }}"}]}' echo "User {{ $user.email }} created" fi {{- end }} tail -f /dev/null volumeMounts: - name: config-volume mountPath: /home/unitycatalog/etc/conf {{- end }} volumes: - configMap: name: {{ include "unitycatalog.fullname" . }}-server-config-templates name: config-templates {{- if not .Values.server.config.persistence.enabled }} - name: config-volume emptyDir: {} {{- end }} {{- if not (and (eq .Values.db.type "file") .Values.db.fileConfig.persistence.enabled) }} - name: db-volume emptyDir: {} {{- end }} {{- range $index, $config := .Values.storage.credentials.gcs }} - name: gcs-credentials-{{ $index }} secret: secretName: {{ $config.credentialsSecretName }} {{- end }} {{- with .Values.server.statefulset.volumes }} {{- toYaml . | nindent 8 }} {{- end }} {{- if .Values.privateCA.enabled }} - name: ca-tls secret: secretName: {{ .Values.privateCA.secretName }} - name: truststore-volume emptyDir: {} {{- end }} {{- with .Values.server.statefulset.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.server.statefulset.affinity }} affinity: {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.server.statefulset.tolerations }} tolerations: {{- toYaml . | nindent 8 }} {{- end }} volumeClaimTemplates: {{- if and (eq .Values.db.type "file") .Values.db.fileConfig.persistence.enabled }} - metadata: name: db-volume spec: accessModes: {{ .Values.db.fileConfig.persistence.accessModes }} resources: requests: storage: {{ .Values.db.fileConfig.persistence.size }} storageClassName: {{ .Values.db.fileConfig.persistence.storageClassName }} {{- end }} {{- if .Values.server.config.persistence.enabled }} - metadata: name: config-volume spec: accessModes: {{ .Values.server.config.persistence.accessModes }} resources: requests: storage: {{ .Values.server.config.persistence.size }} storageClassName: {{ .Values.server.config.persistence.storageClassName }} {{- end }}