Change chart directory structure

This commit is contained in:
wbsong111
2026-01-19 16:11:44 +09:00
parent 0f2284bf35
commit 0436749932
5948 changed files with 119 additions and 79 deletions
@@ -0,0 +1,303 @@
{{- define "lakekeeper.image-name" -}}
{{- $isPlus := eq (required "lakekeeper.edition must be specified" .Values.lakekeeper.edition) "plus" -}}
{{- $repository := "" -}}
{{- if .Values.catalog.image.repository -}}
{{- $repository = .Values.catalog.image.repository -}}
{{- else if $isPlus -}}
{{- $repository = "quay.io/vakamo/lakekeeper-plus" -}}
{{- else -}}
{{- $repository = "quay.io/lakekeeper/catalog" -}}
{{- end -}}
{{- $tag := "" -}}
{{- /* Default versions: enterprise=v0.10.2, community=v0.10.2 */ -}}
{{- if .Values.catalog.image.tag -}}
{{- $tag = .Values.catalog.image.tag -}}
{{- else if $isPlus -}}
{{- $tag = "v0.10.2-distroless" -}}
{{- else -}}
{{- $tag = "v0.10.4" -}}
{{- end -}}
{{- printf "%s:%s" $repository $tag -}}
{{- end -}}
{{/*
Define the image configs for catalog containers
*/}}
{{- define "iceberg-catalog.image" }}
image: {{ include "lakekeeper.image-name" . }}
imagePullPolicy: {{ .Values.catalog.image.pullPolicy }}
securityContext:
runAsUser: {{ .Values.catalog.image.uid }}
runAsGroup: {{ .Values.catalog.image.gid }}
{{- if .Values.catalog.containerSecurityContext }}
{{- omit .Values.catalog.containerSecurityContext "runAsUser" "runAsGroup" | toYaml | nindent 2 }}
{{- end }}
{{- end }}
{{/*
Expand the name of the chart.
*/}}
{{- define "iceberg-catalog.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 "iceberg-catalog.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 "iceberg-catalog.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "iceberg-catalog.labels" -}}
helm.sh/chart: {{ include "iceberg-catalog.chart" . }}
{{ include "iceberg-catalog.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
app.kubernetes.io/part-of: lakekeeper
{{- if .Values.additionalLabels }}
{{ toYaml .Values.additionalLabels }}
{{- end }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "iceberg-catalog.selectorLabels" -}}
app.kubernetes.io/name: {{ include "iceberg-catalog.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "iceberg-catalog.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "iceberg-catalog.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
The list of `envFrom` for catalog Pods
*/}}
{{- define "iceberg-catalog.envFrom" }}
- secretRef:
name: {{ include "iceberg-catalog.fullname" . }}-config-envs
{{- end }}
{{/*
Construct the `postgresql.fullname` of the postgresql sub-chat chart.
Used to discover the Service and Secret name created by the sub-chart.
*/}}
{{- define "iceberg-catalog.postgresql.fullname" -}}
{{- if .Values.postgresql.fullnameOverride -}}
{{- .Values.postgresql.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default "postgresql" .Values.postgresql.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Construct the `openfga.fullname` of the openfga sub-chat chart.
Used to discover the Service and Secret name created by the sub-chart.
*/}}
{{- define "iceberg-catalog.openfga.fullname" -}}
{{- if .Values.openfga.fullnameOverride }}
{{- .Values.openfga.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default "openfga" .Values.openfga.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
The list of `env` catalog Pods
*/}}
{{- define "iceberg-catalog.env" }}
{{- if .Values.postgresql.enabled }}
- name: LAKEKEEPER__PG_HOST_W
value: {{ include "iceberg-catalog.postgresql.fullname" . }}
- name: LAKEKEEPER__PG_PORT
value: {{ .Values.postgresql.service.port | quote }}
{{- if .Values.postgresql.userDatabase.existingSecret }}
- name: LAKEKEEPER__PG_DATABASE
valueFrom:
secretKeyRef:
name: {{ .Values.postgresql.userDatabase.existingSecret }}
key: {{ .Values.postgresql.userDatabase.name.secretKey }}
{{- else }}
- name: LAKEKEEPER__PG_DATABASE
valueFrom:
secretKeyRef:
name: {{ include "iceberg-catalog.postgresql.fullname" . }}
key: POSTGRES_DB
{{- end }}
{{- end }}
{{- /* set LAKEKEEPER__PG_USER */ -}}
{{- if .Values.postgresql.enabled }}
{{- if .Values.postgresql.userDatabase.existingSecret }}
- name: LAKEKEEPER__PG_USER
valueFrom:
secretKeyRef:
name: {{ .Values.postgresql.userDatabase.existingSecret }}
key: {{ .Values.postgresql.userDatabase.user.secretKey }}
{{- else }}
- name: LAKEKEEPER__PG_USER
valueFrom:
secretKeyRef:
name: {{ include "iceberg-catalog.postgresql.fullname" . }}
key: USERDB_USER
{{- end }}
{{- else }}
{{- if .Values.externalDatabase.userSecret }}
- name: LAKEKEEPER__PG_USER
valueFrom:
secretKeyRef:
name: {{ .Values.externalDatabase.userSecret }}
key: {{ .Values.externalDatabase.userSecretKey }}
{{- else }}
{{- /* in this case, LAKEKEEPER__PG_USER is set in the `-config-envs` Secret */ -}}
{{- end }}
{{- end }}
{{- /* set LAKEKEEPER__PG_PASSWORD */ -}}
{{- if .Values.postgresql.enabled }}
{{- if .Values.postgresql.userDatabase.existingSecret }}
- name: LAKEKEEPER__PG_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.postgresql.userDatabase.existingSecret }}
key: {{ .Values.postgresql.userDatabase.password.secretKey }}
{{- else }}
- name: LAKEKEEPER__PG_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "iceberg-catalog.postgresql.fullname" . }}
key: USERDB_PASSWORD
{{- end }}
{{- else }}
{{- if .Values.externalDatabase.passwordSecret }}
- name: LAKEKEEPER__PG_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.externalDatabase.passwordSecret }}
key: {{ .Values.externalDatabase.passwordSecretKey }}
{{- else }}
{{- /* in this case, LAKEKEEPER__PG_PASSWORD is set in the `-config-envs` Secret */ -}}
{{- end }}
{{- end }}
{{- /* set LAKEKEEPER__PG_ENCRYPTION_KEY */ -}}
{{- if eq "postgres" (lower .Values.secretBackend.type) }}
{{- if .Values.secretBackend.postgres.encryptionKeySecret }}
- name: LAKEKEEPER__PG_ENCRYPTION_KEY
valueFrom:
secretKeyRef:
name: {{ .Values.secretBackend.postgres.encryptionKeySecret }}
key: {{ .Values.secretBackend.postgres.encryptionKeySecretKey }}
{{- else }}
- name: LAKEKEEPER__PG_ENCRYPTION_KEY
valueFrom:
secretKeyRef:
name: {{ include "iceberg-catalog.fullname" . }}-postgres-encryption
key: encryptionKey
{{- end }}
{{- end }}
{{- if eq "kv2" (lower .Values.secretBackend.type) }}
{{- /* set LAKEKEEPER__KV2__USER */ -}}
{{- if empty .Values.secretBackend.kv2.user }}
{{- if .Values.secretBackend.kv2.userSecret }}
- name: LAKEKEEPER__KV2__USER
valueFrom:
secretKeyRef:
name: {{ .Values.secretBackend.kv2.userSecret }}
key: {{ .Values.secretBackend.kv2.userSecretKey }}
{{- end }}
{{- end }}
{{- if empty .Values.secretBackend.kv2.password }}
{{- if .Values.secretBackend.kv2.passwordSecret }}
- name: LAKEKEEPER__KV2__PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.secretBackend.kv2.passwordSecret }}
key: {{ .Values.secretBackend.kv2.passwordSecretKey }}
{{- end }}
{{- end }}
{{- end }}
{{- /* set LAKEKEEPER__LICENSE__KEY for plus edition only*/ -}}
{{- if and .Values.lakekeeper.useLicenseSecret (eq .Values.lakekeeper.edition "plus") }}
- name: LAKEKEEPER__LICENSE__KEY
valueFrom:
secretKeyRef:
name: {{ .Values.lakekeeper.licenseSecretName }}
key: {{ .Values.lakekeeper.licenseSecretKey }}
{{- end }}
{{- if eq "openfga" (lower .Values.authz.backend) }}
{{- if empty .Values.authz.openfga.clientId }}
{{- /* set LAKEKEEPER__OPENFGA__CLIENT_ID */ -}}
{{- if .Values.authz.openfga.clientIdSecret }}
- name: LAKEKEEPER__OPENFGA__CLIENT_ID
valueFrom:
secretKeyRef:
name: {{ .Values.authz.openfga.clientIdSecret }}
key: {{ .Values.authz.openfga.clientIdSecretKey }}
{{- end }}
{{- end }}
{{- if empty .Values.authz.openfga.clientSecret }}
{{- /* set LAKEKEEPER__OPENFGA__CLIENT_SECRET */ -}}
{{- if .Values.authz.openfga.clientSecretSecret }}
- name: LAKEKEEPER__OPENFGA__CLIENT_SECRET
valueFrom:
secretKeyRef:
name: {{ .Values.authz.openfga.clientSecretSecret }}
key: {{ .Values.authz.openfga.clientSecretSecretKey }}
{{- end }}
{{- end }}
{{- end }}
{{- /* user-defined environment variables */ -}}
{{- if .Values.catalog.extraEnv }}
{{ toYaml .Values.catalog.extraEnv }}
{{- end }}
- name: LAKEKEEPER__PLACEHOLDER
value: "placeholder"
{{- end }}
@@ -0,0 +1,49 @@
{{/*
Define an init-container which checks the DB status
EXAMPLE USAGE: {{ include "iceberg-catalog.init_container.check_db" (dict "Release" .Release "Values" .Values "Chart" .Chart "awaitMigration" true) }}
*/}}
{{- define "iceberg-catalog.init_container.check_db" }}
{{/*
Wait for OpenFGA - source: https://github.com/openfga/helm-charts/blob/main/charts/openfga/templates/deployment.yaml
*/}}
{{- if and (has .Values.openfga.datastore.engine (list "postgres" "mysql")) .Values.openfga.datastore.applyMigrations .Values.openfga.datastore.waitForMigrations (eq .Values.openfga.datastore.migrationType "job") }}
- name: wait-for-openfga
securityContext:
{{- toYaml .Values.openfga.securityContext | nindent 12 }}
image: "{{ .Values.openfga.initContainer.repository }}:{{ .Values.openfga.initContainer.tag }}"
imagePullPolicy: {{ .Values.openfga.initContainer.pullPolicy }}
args: ["job-wr", '{{ include "iceberg-catalog.openfga.fullname" . }}-migrate']
resources:
{{- toYaml .Values.openfga.datastore.migrations.resources | nindent 12 }}
{{- end }}
- name: check-db
{{- include "iceberg-catalog.image" . | indent 2 }}
resources:
{{- toYaml .Values.catalog.initContainers.checkDb.resources | nindent 4 }}
envFrom:
{{- include "iceberg-catalog.envFrom" . | indent 4 }}
{{- if .Values.catalog.extraEnvFrom -}}
{{- toYaml .Values.catalog.extraEnvFrom | nindent 4 }}
{{- end }}
env:
{{- include "iceberg-catalog.env" . | indent 4 }}
{{- if .Values.catalog.command }}
command:
{{- toYaml .Values.catalog.command | nindent 4 }}
{{- end }}
args:
- wait-for-db
{{- if eq .awaitMigration true }}
- -dm
{{- else }}
- -d
{{- end }}
- -r
- "100"
- -b
- "2"
{{- with .Values.catalog.extraVolumeMounts }}
volumeMounts:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
@@ -0,0 +1,5 @@
{{/* Require that .Values.authz.type is either "allowall" or "openfga" */}}
{{- if not (or (eq .Values.authz.backend "allowall") (eq .Values.authz.backend "openfga")) }}
{{ required "authz.backend must be one of `allowall` or `openfga`. " nil }}
{{- end }}
@@ -0,0 +1,133 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "iceberg-catalog.fullname" . }}
{{- if .Values.catalog.annotations }}
annotations:
{{- toYaml .Values.catalog.annotations | nindent 4 }}
{{- end }}
labels:
{{- include "iceberg-catalog.labels" . | nindent 4 }}
app.kubernetes.io/component: catalog
spec:
replicas: {{ .Values.catalog.replicas }}
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 0
selector:
matchLabels:
{{- include "iceberg-catalog.selectorLabels" . | nindent 6 }}
app.kubernetes.io/component: catalog
template:
metadata:
annotations:
checksum/secret-config-envs: {{ include (print $.Template.BasePath "/config/secret-config-envs.yaml") . | sha256sum }}
{{- if .Values.catalog.podAnnotations -}}
{{- toYaml .Values.catalog.podAnnotations | nindent 8 }}
{{- end }}
{{- if .Values.catalog.safeToEvict }}
cluster-autoscaler.kubernetes.io/safe-to-evict: "true"
{{- end }}
{{- if .Values.catalog.prometheus.setScrapeAnnotations }}
prometheus.io/port: "9000"
prometheus.io/scrape: "true"
{{- end }}
labels:
{{- include "iceberg-catalog.labels" . | nindent 8 }}
app.kubernetes.io/component: catalog
{{- with .Values.catalog.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
restartPolicy: Always
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.catalog.nodeSelector }}
nodeSelector:
{{- toYaml .Values.catalog.nodeSelector | nindent 8 }}
{{- end }}
{{- if .Values.catalog.topologySpreadConstraints }}
topologySpreadConstraints:
{{- toYaml .Values.catalog.topologySpreadConstraints | nindent 8 }}
{{- end }}
{{- if .Values.catalog.affinity }}
affinity:
{{- toYaml .Values.catalog.affinity | nindent 8 }}
{{- end }}
{{- if .Values.catalog.tolerations }}
tolerations:
{{- toYaml .Values.catalog.tolerations | nindent 8 }}
{{- end }}
{{- if .Values.catalog.priorityClassName }}
priorityClassName: {{ .Values.catalog.priorityClassName | quote }}
{{- end }}
serviceAccountName: {{ include "iceberg-catalog.serviceAccountName" . }}
{{- if .Values.catalog.podSecurityContext }}
securityContext:
{{- toYaml .Values.catalog.podSecurityContext | nindent 8 }}
{{- end }}
initContainers:
{{- if .Values.catalog.extraInitContainers }}
{{- toYaml .Values.catalog.extraInitContainers | nindent 8 }}
{{- end }}
{{- include "iceberg-catalog.init_container.check_db" (dict "Release" .Release "Values" .Values "Chart" .Chart "awaitMigration" true) | indent 8 }}
containers:
- name: {{ .Chart.Name }}
{{- include "iceberg-catalog.image" . | indent 10 }}
env:
{{- include "iceberg-catalog.env" . | indent 12 }}
envFrom:
{{- include "iceberg-catalog.envFrom" . | indent 12 }}
{{- if .Values.catalog.extraEnvFrom -}}
{{- toYaml .Values.catalog.extraEnvFrom | nindent 12 }}
{{- end }}
ports:
- name: http
containerPort: 8181
protocol: TCP
- name: metrics
containerPort: 9000
protocol: TCP
{{- if .Values.catalog.command }}
command:
{{- toYaml .Values.catalog.command | nindent 12 }}
{{- end }}
args:
- serve
{{- if .Values.catalog.livenessProbe.enabled }}
livenessProbe:
initialDelaySeconds: {{ .Values.catalog.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.catalog.livenessProbe.periodSeconds }}
failureThreshold: {{ .Values.catalog.livenessProbe.failureThreshold }}
timeoutSeconds: {{ .Values.catalog.livenessProbe.timeoutSeconds }}
httpGet:
path: /health
port: 8181
{{- end }}
{{- if .Values.catalog.readinessProbe.enabled }}
readinessProbe:
initialDelaySeconds: {{ .Values.catalog.readinessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.catalog.readinessProbe.periodSeconds }}
failureThreshold: {{ .Values.catalog.readinessProbe.failureThreshold }}
timeoutSeconds: {{ .Values.catalog.readinessProbe.timeoutSeconds }}
httpGet:
path: /health
port: 8181
{{- end }}
resources:
{{- toYaml .Values.catalog.resources | nindent 12 }}
{{- with .Values.catalog.extraVolumeMounts }}
volumeMounts:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- if .Values.catalog.extraContainers }}
{{- toYaml .Values.catalog.extraContainers | nindent 8 }}
{{- end }}
{{- with .Values.catalog.extraVolumes }}
volumes:
{{- toYaml . | nindent 8 }}
{{- end }}
@@ -0,0 +1,18 @@
{{- if (.Values.catalog.autoscaling.enabled) }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "iceberg-catalog.fullname" . }}
labels:
{{- include "iceberg-catalog.labels" . | nindent 4 }}
app.kubernetes.io/component: catalog
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "iceberg-catalog.fullname" . }}
minReplicas: {{ .Values.catalog.replicas }}
maxReplicas: {{ .Values.catalog.autoscaling.maxReplicas }}
metrics:
{{- toYaml .Values.catalog.autoscaling.metrics | nindent 4 }}
{{- end }}
@@ -0,0 +1,39 @@
{{- if .Values.catalog.ingress.enabled}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "iceberg-catalog.fullname" . }}
{{- if .Values.catalog.ingress.annotations }}
annotations:
{{- toYaml .Values.catalog.ingress.annotations | nindent 4 }}
{{- end }}
labels:
{{- include "iceberg-catalog.labels" . | nindent 4 }}
app.kubernetes.io/component: catalog
{{- if .Values.catalog.ingress.labels }}
{{- toYaml .Values.catalog.ingress.labels | nindent 4 }}
{{- end }}
spec:
{{- if .Values.catalog.ingress.tls.enabled }}
tls:
- hosts:
- {{ .Values.catalog.ingress.host }}
{{- if .Values.catalog.ingress.tls.secretName }}
secretName: {{ .Values.catalog.ingress.tls.secretName }}
{{- end }}
{{- end }}
{{- if .Values.catalog.ingress.ingressClassName }}
ingressClassName: {{ .Values.catalog.ingress.ingressClassName }}
{{- end }}
rules:
- host: {{ .Values.catalog.ingress.host }}
http:
paths:
- path: {{ .Values.catalog.ingress.path }}
pathType: ImplementationSpecific
backend:
service:
name: {{ include "iceberg-catalog.fullname" . }}
port:
name: http
{{- end }}
@@ -0,0 +1,20 @@
{{- if .Values.catalog.podDisruptionBudget.enabled }}
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: {{ include "iceberg-catalog.fullname" . }}
labels:
{{- include "iceberg-catalog.labels" . | nindent 4 }}
app.kubernetes.io/component: catalog
spec:
{{- if .Values.catalog.podDisruptionBudget.maxUnavailable }}
maxUnavailable: {{ .Values.catalog.podDisruptionBudget.maxUnavailable }}
{{- end }}
{{- if .Values.catalog.podDisruptionBudget.minAvailable }}
minAvailable: {{ .Values.catalog.podDisruptionBudget.minAvailable }}
{{- end }}
selector:
matchLabels:
{{- include "iceberg-catalog.selectorLabels" . | nindent 6 }}
app.kubernetes.io/component: catalog
{{- end }}
@@ -0,0 +1,38 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "iceberg-catalog.fullname" . }}
{{- if .Values.catalog.service.annotations }}
annotations:
{{- toYaml .Values.catalog.service.annotations | nindent 4 }}
{{- end }}
labels:
{{- include "iceberg-catalog.labels" . | nindent 4 }}
app.kubernetes.io/component: catalog
spec:
type: {{ .Values.catalog.service.type }}
sessionAffinity: {{ .Values.catalog.service.sessionAffinity }}
{{- if .Values.catalog.service.sessionAffinityConfig }}
sessionAffinityConfig:
{{- toYaml .Values.catalog.service.sessionAffinityConfig | nindent 4 }}
{{- end }}
ports:
- port: {{ .Values.catalog.service.externalPort | default 8181 }}
targetPort: http
protocol: TCP
{{- if and (eq .Values.catalog.service.type "NodePort") (.Values.catalog.service.nodePort.http) }}
nodePort: {{ .Values.catalog.service.nodePort.http }}
{{- end }}
name: http
selector:
{{- include "iceberg-catalog.selectorLabels" . | nindent 4 }}
app.kubernetes.io/component: catalog
{{- if eq .Values.catalog.service.type "LoadBalancer" }}
{{- if .Values.catalog.service.loadBalancerIP }}
loadBalancerIP: {{ .Values.catalog.service.loadBalancerIP | quote }}
{{- end }}
{{- if .Values.catalog.service.loadBalancerSourceRanges }}
loadBalancerSourceRanges:
{{- toYaml .Values.catalog.service.loadBalancerSourceRanges | nindent 4 }}
{{- end }}
{{- end }}
@@ -0,0 +1,20 @@
{{- if eq "postgres" (lower .Values.secretBackend.type) }}
{{- if empty .Values.secretBackend.postgres.encryptionKeySecret }}
{{- $secretName := include "iceberg-catalog.fullname" . }}
{{- $secretName = printf "%s-postgres-encryption" $secretName }}
apiVersion: v1
kind: Secret
metadata:
name: {{ $secretName }}
annotations:
helm.sh/resource-policy: "keep"
labels:
app.kubernetes.io/component: config
type: Opaque
data:
{{- $secretObj := (lookup "v1" "Secret" .Release.Namespace $secretName) | default dict }}
{{- $secretData := (get $secretObj "data") | default dict }}
{{- $encryptionKey := (get $secretData "encryptionKey") | default (randAlphaNum 40 | b64enc) }}
encryptionKey: {{ $encryptionKey | quote }}
{{- end }}
{{- end }}
@@ -0,0 +1,127 @@
{{/* Checks for `catalog.ingress.path` */}}
{{- if .Values.catalog.ingress.path }}
{{- if not (.Values.catalog.ingress.path | hasPrefix "/") }}
{{ required "The `catalog.ingress.path` should start with a '/'!" nil }}
{{- end }}
{{- if and (ne .Values.catalog.ingress.path "/") (.Values.catalog.ingress.path | hasSuffix "/") }}
{{ required "The `catalog.ingress.path` should NOT include a trailing '/'!" nil }}
{{- end }}
{{- end }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "iceberg-catalog.fullname" . }}-config-envs
labels:
{{- include "iceberg-catalog.labels" . | nindent 4 }}
app.kubernetes.io/component: config
data:
# Database Configs
{{- if not .Values.postgresql.enabled }}
{{- if .Values.externalDatabase.host_read }}
LAKEKEEPER__PG_HOST_R: {{ .Values.externalDatabase.host_read | toString | b64enc | quote }}
{{- end }}
{{- if .Values.externalDatabase.host_write }}
LAKEKEEPER__PG_HOST_W: {{ .Values.externalDatabase.host_write | toString | b64enc | quote }}
{{- end }}
{{- if .Values.externalDatabase.port }}
LAKEKEEPER__PG_PORT: {{ .Values.externalDatabase.port | toString | b64enc | quote }}
{{- end }}
{{- if .Values.externalDatabase.database }}
LAKEKEEPER__PG_DATABASE: {{ .Values.externalDatabase.database | toString | b64enc | quote }}
{{- end }}
{{- if not .Values.externalDatabase.userSecret }}
LAKEKEEPER__PG_USER: {{ .Values.externalDatabase.user | toString | b64enc | quote }}
{{- end }}
{{- if not .Values.externalDatabase.passwordSecret }}
LAKEKEEPER__PG_PASSWORD: {{ .Values.externalDatabase.password | toString | b64enc | quote }}
{{- end }}
{{- end }}
# Lakekeeper License Configs
{{- if and .Values.lakekeeper.licenseKey (not .Values.lakekeeper.useLicenseSecret) }}
LAKEKEEPER__LICENSE__KEY: {{ .Values.lakekeeper.licenseKey | toString | b64enc | quote }}
{{- end }}
# OPENID Auth Configs
{{- if .Values.auth.oauth2.providerUri }}
LAKEKEEPER__OPENID_PROVIDER_URI: {{ .Values.auth.oauth2.providerUri | toString | b64enc | quote }}
{{- if .Values.auth.oauth2.audience }}
LAKEKEEPER__OPENID_AUDIENCE: {{ .Values.auth.oauth2.audience | toString | b64enc | quote }}
{{- end }}
# .Values.auth.oauth2.additionalIssuers is a list.
# If it is not empty, join the list with a comma and set the value to LAKEKEEPER__OPENID_ADDITIONAL_ISSUERS
{{- if .Values.auth.oauth2.additionalIssuers }}
LAKEKEEPER__OPENID_ADDITIONAL_ISSUERS: {{ .Values.auth.oauth2.additionalIssuers | join "," | b64enc | quote }}
{{- end }}
{{- end }}
# UI Auth configs
{{- if .Values.auth.oauth2.ui.clientID }}
LAKEKEEPER__UI__OPENID_CLIENT_ID: {{ .Values.auth.oauth2.ui.clientID | toString | b64enc | quote }}
{{- end }}
{{- if .Values.auth.oauth2.ui.scopes }}
LAKEKEEPER__UI__OPENID_SCOPE: {{ .Values.auth.oauth2.ui.scopes | toString | b64enc | quote }}
{{- end }}
{{- if .Values.auth.oauth2.ui.resource }}
LAKEKEEPER__UI__OPENID_RESOURCE: {{ .Values.auth.oauth2.ui.resource | toString | b64enc | quote }}
{{- end }}
# Kubernetes Auth Configs
{{- if .Values.auth.k8s.enabled }}
LAKEKEEPER__ENABLE_KUBERNETES_AUTHENTICATION: {{ "true" | b64enc | quote }}
{{- if .Values.auth.k8s.audience }}
LAKEKEEPER__KUBERNETES_AUTHENTICATION_AUDIENCE: {{ .Values.auth.k8s.audience | toString | b64enc | quote }}
{{- end }}
{{- end }}
{{- if .Values.auth.k8s.legacyEnabled }}
LAKEKEEPER__KUBERNETES_AUTHENTICATION_ACCEPT_LEGACY_SERVICEACCOUNT: {{ "true" | b64enc | quote }}
{{- end }}
# Secret store configs
{{- if eq "postgres" (lower .Values.secretBackend.type) }}
LAKEKEEPER__SECRET_BACKEND: {{ "Postgres" | b64enc | quote }}
# LAKEKEEPER__PG_ENCRYPTION_KEY is mounted as secret
{{- end }}
{{- if eq "kv2" (lower .Values.secretBackend.type) }}
LAKEKEEPER__KV2__URL: {{ .Values.secretBackend.kv2.url | toString | b64enc | quote }}
{{- if .Values.secretBackend.kv2.user }}
LAKEKEEPER__KV2__USER: {{ .Values.secretBackend.kv2.user | toString | b64enc | quote }}
{{- end }}
{{- if .Values.secretBackend.kv2.password }}
LAKEKEEPER__KV2__PASSWORD: {{ .Values.secretBackend.kv2.password | toString | b64enc | quote }}
{{- end }}
LAKEKEEPER__KV2__SECRET_MOUNT: {{ .Values.secretBackend.kv2.secret_mount | toString | b64enc | quote }}
{{- end }}
# Authorization configs
LAKEKEEPER__AUTHZ_BACKEND: {{ .Values.authz.backend | toString | b64enc | quote }}
{{- if eq "openfga" (lower .Values.authz.backend) }}
{{- if .Values.authz.openfga.endpoint }}
LAKEKEEPER__OPENFGA__ENDPOINT: {{ .Values.authz.openfga.endpoint | toString | b64enc | quote }}
{{- else if .Values.internalOpenFGA }}
LAKEKEEPER__OPENFGA__ENDPOINT: {{ printf "http://%s.%s.svc.%s:%d" ( include "iceberg-catalog.openfga.fullname" . ) (.Release.Namespace) (.Values.clusterDomain) (int (split ":" .Values.openfga.grpc.addr)._1) | b64enc | quote }}
{{- end }}
{{- if .Values.authz.openfga.store }}
LAKEKEEPER__OPENFGA__STORE_NAME: {{ .Values.authz.openfga.store | toString | b64enc | quote }}
{{- end }}
{{- if .Values.authz.openfga.apiKey }}
LAKEKEEPER__OPENFGA__API_KEY: {{ .Values.authz.openfga.apiKey | toString | b64enc | quote }}
{{- end }}
{{- if .Values.authz.openfga.clientId }}
LAKEKEEPER__OPENFGA__CLIENT_ID: {{ .Values.authz.openfga.clientId | toString | b64enc | quote }}
{{- end }}
{{- if .Values.authz.openfga.clientSecret }}
LAKEKEEPER__OPENFGA__CLIENT_SECRET: {{ .Values.authz.openfga.clientSecret | toString | b64enc | quote }}
{{- end }}
{{- if .Values.authz.openfga.tokenEndpoint }}
LAKEKEEPER__OPENFGA__TOKEN_ENDPOINT: {{ .Values.authz.openfga.tokenEndpoint | toString | b64enc | quote }}
{{- end }}
{{- end }}
# User Configs
{{- range $k, $v := .Values.catalog.config }}
{{ $k | quote }}: {{ $v | toString | b64enc | quote }}
{{- end }}
@@ -0,0 +1,95 @@
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "iceberg-catalog.fullname" . }}-db-migration-{{ .Release.Revision }}
labels:
{{- include "iceberg-catalog.labels" . | nindent 4 }}
app.kubernetes.io/component: db-migration
{{- if .Values.catalog.dbMigrations.labels }}
{{- toYaml .Values.catalog.dbMigrations.labels | nindent 4 }}
{{- end }}
annotations:
argocd.argoproj.io/hook: Sync
argocd.argoproj.io/sync-wave: "0"
{{- if not .Values.helmWait }}
helm.sh/hook: post-install,post-upgrade
helm.sh/hook-weight: "-100"
helm.sh/hook-delete-policy: before-hook-creation
{{- else }}
helm-hook-enabled: "false"
{{- end }}
{{- if .Values.catalog.dbMigrations.annotations }}
{{- toYaml .Values.catalog.dbMigrations.annotations | nindent 4 }}
{{- end }}
spec:
template:
metadata:
name: "{{ include "iceberg-catalog.fullname" . }}-migration"
annotations:
checksum/secret-config-envs: {{ include (print $.Template.BasePath "/config/secret-config-envs.yaml") . | sha256sum }}
{{- if .Values.catalog.dbMigrations.podAnnotations -}}
{{- toYaml .Values.catalog.dbMigrations.podAnnotations | nindent 8 }}
{{- end }}
labels:
{{- include "iceberg-catalog.labels" . | nindent 8 }}
app.kubernetes.io/component: db-migration
{{- if .Values.catalog.dbMigrations.podLabels }}
{{- toYaml .Values.catalog.dbMigrations.podLabels | nindent 8 }}
{{- end }}
spec:
restartPolicy: OnFailure
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.catalog.nodeSelector }}
nodeSelector:
{{- toYaml .Values.catalog.nodeSelector | nindent 8 }}
{{- end }}
{{- if .Values.catalog.affinity }}
affinity:
{{- toYaml .Values.catalog.affinity | nindent 8 }}
{{- end }}
{{- if .Values.catalog.tolerations }}
tolerations:
{{- toYaml .Values.catalog.tolerations | nindent 8 }}
{{- end }}
{{- if .Values.catalog.priorityClassName }}
priorityClassName: {{ .Values.catalog.priorityClassName | quote }}
{{- end }}
serviceAccountName: {{ include "iceberg-catalog.serviceAccountName" . }}
{{- if .Values.catalog.podSecurityContext }}
securityContext:
{{- toYaml .Values.catalog.podSecurityContext | nindent 8 }}
{{- end }}
initContainers:
{{- if .Values.catalog.dbMigrations.extraInitContainers }}
{{- toYaml .Values.catalog.dbMigrations.extraInitContainers | nindent 8 }}
{{- end }}
{{- include "iceberg-catalog.init_container.check_db" (dict "Release" .Release "Values" .Values "Chart" .Chart "awaitMigration" false) | indent 8 }}
containers:
- name: migration
{{- include "iceberg-catalog.image" . | indent 10 }}
env:
{{- include "iceberg-catalog.env" . | indent 12 }}
envFrom:
{{- include "iceberg-catalog.envFrom" . | indent 12 }}
{{- if .Values.catalog.extraEnvFrom -}}
{{- toYaml .Values.catalog.extraEnvFrom | nindent 12 }}
{{- end }}
{{- if .Values.catalog.command }}
command:
{{- toYaml .Values.catalog.command | nindent 12 }}
{{- end }}
args:
- migrate
resources:
{{- toYaml .Values.catalog.dbMigrations.resources | nindent 12 }}
{{- with .Values.catalog.extraVolumeMounts }}
volumeMounts:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.catalog.extraVolumes }}
volumes:
{{- toYaml . | nindent 8 }}
{{- end }}
@@ -0,0 +1,69 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "iceberg-catalog.serviceAccountName" . }}
labels:
{{- include "iceberg-catalog.labels" . | nindent 4 }}
app.kubernetes.io/component: rbac
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
---
# Get jobs to detect if migrations finished
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ include "iceberg-catalog.fullname" . }}
labels:
{{- include "iceberg-catalog.labels" . | nindent 4 }}
app.kubernetes.io/component: rbac
rules:
- apiGroups:
- batch
resources:
- jobs
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "iceberg-catalog.fullname" . }}-rolebinding
labels:
{{- include "iceberg-catalog.labels" . | nindent 4 }}
app.kubernetes.io/component: rbac
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ include "iceberg-catalog.fullname" . }}
subjects:
- kind: ServiceAccount
name: {{ include "iceberg-catalog.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
{{- if .Values.auth.k8s.enabled }}
{{- if .Values.auth.k8s.createClusterRoleBinding }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ .Release.Namespace }}:{{ include "iceberg-catalog.fullname" . }}-token-review
labels:
{{- include "iceberg-catalog.labels" . | nindent 4 }}
app.kubernetes.io/component: rbac
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: {{ include "iceberg-catalog.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
{{- end }}
{{- end }}
{{- end }}
@@ -0,0 +1,46 @@
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "iceberg-catalog.fullname" . }}-test-bootstrap"
labels:
{{- include "iceberg-catalog.labels" . | nindent 4 }}
component: catalog
annotations:
"helm.sh/hook": test
spec:
serviceAccountName: {{ include "iceberg-catalog.serviceAccountName" . }}
containers:
- name: base
image: debian
command: ['bash', "-c"]
args:
- |
set -e
apt-get update -yqq
apt-get install -yqq curl
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
BOOTSTRAP_URL="http://{{ include "iceberg-catalog.fullname" . }}:8181/management/v1/bootstrap"
if [ -n "$TOKEN" ]; then
echo "Found K8s Service Account token"
else
echo "No K8s Service Account token found"
fi
for i in {1..45}; do
RESPONSE=$(curl --location "$BOOTSTRAP_URL" \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer $TOKEN" \
--data '{"accept-terms-of-use": true}' \
--write-out "HTTP_CODE:%{http_code}" --silent --output /dev/null)
if [[ "$RESPONSE" == *"HTTP_CODE:204"* ]]; then
echo "Bootstrapping successful"
exit 0
else
echo "Request failed with status code and response: $RESPONSE"
fi
sleep 2
done
echo "Failed to bootstrap within the given time"
exit 1
restartPolicy: Never