update lakekeeper/0.11.0

- chart 0.8.1 → 0.11.0 (appVersion 0.10.4 → 0.12.2)
- deps: postgres 1.5.8 → 1.5.13, openfga 0.2.44 → 0.2.62
- ingress: Kong → APISIX (use-regex + path /.*, cluster-issuer)
- openfga.playground 비활성화 (preshared 인증 패닉 방지)
- breaking=false, custom-values 키 전부 호환

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
wbsong111
2026-06-15 09:13:31 +09:00
parent 1ab3d4d31c
commit f4d287abef
217 changed files with 23584 additions and 0 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.12.1, community=v0.12.2 */ -}}
{{- if .Values.catalog.image.tag -}}
{{- $tag = .Values.catalog.image.tag -}}
{{- else if $isPlus -}}
{{- $tag = "v0.12.1-distroless" -}}
{{- else -}}
{{- $tag = "v0.12.2" -}}
{{- 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 }}
{{ tpl (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 -}}
{{- tpl (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,257 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "iceberg-catalog.fullname" . }}
namespace: {{ .Release.Namespace }}
{{- 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.OPABridge.enabled }}
checksum/opa-config: {{ include (print $.Template.BasePath "/config/opa-bridge-config-secret.yaml") . | sha256sum }}
checksum/opa-policies: {{ include (print $.Template.BasePath "/config/opa-bridge-policies.yaml") . | sha256sum }}
{{- end }}
{{- 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: {{ .Values.catalog.prometheus.port | quote }}
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 -}}
{{- tpl (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.OPABridge.enabled }}
- name: opa
image: {{ .Values.OPABridge.image.repository }}:{{ .Values.OPABridge.image.tag }}
imagePullPolicy: {{ .Values.OPABridge.image.pullPolicy }}
securityContext:
runAsUser: {{ .Values.OPABridge.image.uid }}
runAsGroup: {{ .Values.OPABridge.image.gid }}
readOnlyRootFilesystem: false
env:
- name: TRINO_ALLOW_UNMANAGED_CATALOGS
value: {{ .Values.OPABridge.allowUnmanagedCatalogs | quote }}
- name: LAKEKEEPER_URL
value: {{ .Values.OPABridge.lakekeeper.url | quote }}
- name: LAKEKEEPER_MAX_BATCH_CHECK_SIZE
value: {{ .Values.OPABridge.maxBatchCheckSize | quote }}
{{- if .Values.OPABridge.adminUsers }}
- name: TRINO_ADMIN_USERS
value: {{ .Values.OPABridge.adminUsers | join "," | quote }}
{{- end }}
{{- if .Values.OPABridge.lakekeeper.existingSecret }}
{{- /* Read credentials from existing secret */ -}}
- name: LAKEKEEPER_TOKEN_ENDPOINT
valueFrom:
secretKeyRef:
name: {{ .Values.OPABridge.lakekeeper.existingSecret }}
key: {{ .Values.OPABridge.lakekeeper.tokenEndpointSecretKey }}
- name: LAKEKEEPER_CLIENT_ID
valueFrom:
secretKeyRef:
name: {{ .Values.OPABridge.lakekeeper.existingSecret }}
key: {{ .Values.OPABridge.lakekeeper.clientIdSecretKey }}
- name: LAKEKEEPER_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: {{ .Values.OPABridge.lakekeeper.existingSecret }}
key: {{ .Values.OPABridge.lakekeeper.clientSecretSecretKey }}
- name: LAKEKEEPER_SCOPE
valueFrom:
secretKeyRef:
name: {{ .Values.OPABridge.lakekeeper.existingSecret }}
key: {{ .Values.OPABridge.lakekeeper.scopeSecretKey }}
{{- else }}
{{- /* Read credentials from values */ -}}
{{- if .Values.OPABridge.lakekeeper.tokenEndpoint }}
- name: LAKEKEEPER_TOKEN_ENDPOINT
value: {{ .Values.OPABridge.lakekeeper.tokenEndpoint | quote }}
{{- end }}
{{- if .Values.OPABridge.lakekeeper.clientId }}
- name: LAKEKEEPER_CLIENT_ID
value: {{ .Values.OPABridge.lakekeeper.clientId | quote }}
{{- end }}
{{- if .Values.OPABridge.lakekeeper.clientSecret }}
- name: LAKEKEEPER_CLIENT_SECRET
value: {{ .Values.OPABridge.lakekeeper.clientSecret | quote }}
{{- end }}
{{- if .Values.OPABridge.lakekeeper.scope }}
- name: LAKEKEEPER_SCOPE
value: {{ .Values.OPABridge.lakekeeper.scope | quote }}
{{- end }}
{{- end }}
{{- with .Values.OPABridge.extraEnv }}
{{- tpl (toYaml .) $ | nindent 12 }}
{{- end }}
{{- if .Values.OPABridge.extraEnvFrom }}
envFrom:
{{- tpl (toYaml .Values.OPABridge.extraEnvFrom) . | nindent 12 }}
{{- end }}
args:
- "run"
- "--server"
- "--ignore=.*" # exclude hidden dirs created by Kubernetes
- "--addr=:8282"
- "--config-file=/etc/opa/opa-config.yaml"
{{- range .Values.OPABridge.extraArgs }}
- {{ . | quote }}
{{- end }}
- "/policies"
ports:
- name: opa
containerPort: 8282
protocol: TCP
livenessProbe:
httpGet:
path: /health
scheme: HTTP
port: 8282
initialDelaySeconds: 5
periodSeconds: 5
readinessProbe:
httpGet:
path: /health
scheme: HTTP
port: 8282
initialDelaySeconds: 5
periodSeconds: 5
resources:
{{- toYaml .Values.OPABridge.resources | nindent 12 }}
volumeMounts:
- name: opa-config
mountPath: /etc/opa
readOnly: true
- name: opa-policies
mountPath: /policies
readOnly: true
- name: opa-var-run
mountPath: /var/run/secrets
{{- end }}
{{- if .Values.catalog.extraContainers }}
{{- toYaml .Values.catalog.extraContainers | nindent 8 }}
{{- end }}
{{- if or .Values.OPABridge.enabled .Values.catalog.extraVolumes }}
volumes:
{{- if .Values.OPABridge.enabled }}
- name: opa-config
secret:
secretName: {{ include "iceberg-catalog.fullname" . }}-opa-config
- name: opa-policies
configMap:
name: {{ include "iceberg-catalog.fullname" . }}-opa-policies
- name: opa-var-run
emptyDir: {}
{{- end }}
{{- with .Values.catalog.extraVolumes }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
@@ -0,0 +1,19 @@
{{- if (.Values.catalog.autoscaling.enabled) }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "iceberg-catalog.fullname" . }}
namespace: {{ .Release.Namespace }}
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,40 @@
{{- if .Values.catalog.ingress.enabled}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "iceberg-catalog.fullname" . }}
namespace: {{ .Release.Namespace }}
{{- 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,21 @@
{{- if .Values.catalog.podDisruptionBudget.enabled }}
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: {{ include "iceberg-catalog.fullname" . }}
namespace: {{ .Release.Namespace }}
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,48 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "iceberg-catalog.fullname" . }}
namespace: {{ .Release.Namespace }}
{{- 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
{{- if .Values.catalog.prometheus.setScrapeAnnotations }}
- port: {{ .Values.catalog.prometheus.port }}
targetPort: metrics
protocol: TCP
{{- if and (eq .Values.catalog.service.type "NodePort") (.Values.catalog.service.nodePort.metrics) }}
nodePort: {{ .Values.catalog.service.nodePort.metrics }}
{{- end }}
name: metrics
{{- end }}
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,41 @@
{{- if .Values.OPABridge.enabled }}
apiVersion: v1
kind: Service
metadata:
name: {{ include "iceberg-catalog.fullname" . }}-opa
namespace: {{ .Release.Namespace }}
{{- if .Values.OPABridge.service.annotations }}
annotations:
{{- toYaml .Values.OPABridge.service.annotations | nindent 4 }}
{{- end }}
labels:
{{- include "iceberg-catalog.labels" . | nindent 4 }}
app.kubernetes.io/component: opa-bridge
spec:
type: {{ .Values.OPABridge.service.type }}
sessionAffinity: {{ .Values.OPABridge.service.sessionAffinity }}
{{- if .Values.OPABridge.service.sessionAffinityConfig }}
sessionAffinityConfig:
{{- toYaml .Values.OPABridge.service.sessionAffinityConfig | nindent 4 }}
{{- end }}
ports:
- port: {{ .Values.OPABridge.service.externalPort | default 8282 }}
targetPort: opa
protocol: TCP
{{- if and (eq .Values.OPABridge.service.type "NodePort") (.Values.OPABridge.service.nodePort.opa) }}
nodePort: {{ .Values.OPABridge.service.nodePort.opa }}
{{- end }}
name: opa
selector:
{{- include "iceberg-catalog.selectorLabels" . | nindent 4 }}
app.kubernetes.io/component: catalog
{{- if eq .Values.OPABridge.service.type "LoadBalancer" }}
{{- if .Values.OPABridge.service.loadBalancerIP }}
loadBalancerIP: {{ .Values.OPABridge.service.loadBalancerIP | quote }}
{{- end }}
{{- if .Values.OPABridge.service.loadBalancerSourceRanges }}
loadBalancerSourceRanges:
{{- toYaml .Values.OPABridge.service.loadBalancerSourceRanges | nindent 4 }}
{{- end }}
{{- end }}
{{- end }}
@@ -0,0 +1,21 @@
{{- 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 }}
namespace: {{ .Release.Namespace }}
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,14 @@
{{- if .Values.OPABridge.enabled }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "iceberg-catalog.fullname" . }}-opa-config
namespace: {{ .Release.Namespace }}
labels:
{{- include "iceberg-catalog.labels" . | nindent 4 }}
app.kubernetes.io/component: opa-bridge
type: Opaque
stringData:
opa-config.yaml: |
{{- toYaml .Values.OPABridge.opaConfig | nindent 4 }}
{{- end }}
@@ -0,0 +1,34 @@
{{- if .Values.OPABridge.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "iceberg-catalog.fullname" . }}-opa-policies
namespace: {{ .Release.Namespace }}
labels:
{{- include "iceberg-catalog.labels" . | nindent 4 }}
app.kubernetes.io/component: opa-bridge
data:
{{- range $path, $content := .Files.Glob "opa-bridge/v0.11/policies/**.rego" }}
{{ trimPrefix "opa-bridge/v0.11/policies/" $path | replace "/" "." }}: |2
{{ regexReplaceAll "[ \t]+\n" ($content | toString) "\n" | indent 4 }}
{{- end }}
catalogs.rego: |
# This file contains Trino catalog to Lakekeeper warehouse mappings.
# Generated from Helm values.
package configuration
trino_catalog := [
{{- range .Values.OPABridge.catalogs }}
{
"name": {{ .trinoCatalog | quote }},
"lakekeeper_id": "default",
"lakekeeper_warehouse": {{ .lakekeeperWarehouse | quote }}
},
{{- end }}
]
{{- range $filename, $content := .Values.OPABridge.customPolicies }}
{{ $filename }}: |
{{ $content | indent 4 }}
{{- end }}
{{- end }}
@@ -0,0 +1,128 @@
{{/* 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
namespace: {{ .Release.Namespace }}
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,96 @@
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "iceberg-catalog.fullname" . }}-db-migration-{{ .Release.Revision }}
namespace: {{ .Release.Namespace }}
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 -}}
{{- tpl (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,80 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "iceberg-catalog.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
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" . }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "iceberg-catalog.labels" . | nindent 4 }}
app.kubernetes.io/component: rbac
rules:
- apiGroups:
- batch
resources:
- jobs
verbs:
- get
- list
- watch
{{- if eq .Values.authz.backend "cedar" }}
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
{{- end }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "iceberg-catalog.fullname" . }}-rolebinding
namespace: {{ .Release.Namespace }}
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,45 @@
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "iceberg-catalog.fullname" . }}-test-bootstrap"
namespace: {{ .Release.Namespace }}
labels:
{{- include "iceberg-catalog.labels" . | nindent 4 }}
component: catalog
annotations:
"helm.sh/hook": test
spec:
serviceAccountName: {{ include "iceberg-catalog.serviceAccountName" . }}
containers:
- name: base
image: curlimages/curl:latest
command: ['sh', "-c"]
args:
- |
set -e
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