Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions helm/templates/_jaas.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
{{/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/}}

{{/*
Renders the env entries for the JAAS init container: secretKeyRef for each
Secret-sourced credential, literal `value:` for each values-sourced one.
Usage:
include "fluss.security.jaas.initContainer.env" .
*/}}
{{- define "fluss.security.jaas.initContainer.env" -}}
{{- $internalMechanism := include "fluss.security.listener.mechanism" (dict "context" .Values "listener" "internal") -}}
{{- $clientMechanism := include "fluss.security.listener.mechanism" (dict "context" .Values "listener" "client") -}}
{{- $zkEnabled := include "fluss.security.zookeeper.sasl.enabled" . -}}
{{- /* internal */ -}}
{{- if and (include "fluss.security.sasl.plain.enabled" .) (eq $internalMechanism "plain") }}
- name: {{ include "fluss.security.sasl.plain.internal.envVarName" "username" }}
{{- $ref := .Values.security.internal.sasl.plain.existingSecret | default (dict) }}
{{- if $ref.name }}
valueFrom:
secretKeyRef:
name: {{ $ref.name }}
key: {{ $ref.usernameKey | default "username" }}
{{- else }}
value: {{ include "fluss.security.sasl.plain.internal.username" . | quote }}
{{- end }}
- name: {{ include "fluss.security.sasl.plain.internal.envVarName" "password" }}
{{- if $ref.name }}
valueFrom:
secretKeyRef:
name: {{ $ref.name }}
key: {{ $ref.passwordKey | default "password" }}
{{- else }}
value: {{ include "fluss.security.sasl.plain.internal.password" . | quote }}
{{- end }}
{{- end }}
{{- /* client */ -}}
{{- if and (include "fluss.security.sasl.plain.enabled" .) (eq $clientMechanism "plain") }}
{{- range $idx, $user := .Values.security.client.sasl.plain.users | default (list) }}
{{- $ref := $user.existingSecret | default (dict) }}
- name: {{ include "fluss.security.sasl.plain.client.envVarName" (dict "field" "username" "idx" $idx) }}
{{- if $ref.name }}
valueFrom:
secretKeyRef:
name: {{ $ref.name }}
key: {{ $ref.usernameKey | default "username" }}
{{- else }}
value: {{ $user.username | quote }}
{{- end }}
- name: {{ include "fluss.security.sasl.plain.client.envVarName" (dict "field" "password" "idx" $idx) }}
{{- if $ref.name }}
valueFrom:
secretKeyRef:
name: {{ $ref.name }}
key: {{ $ref.passwordKey | default "password" }}
{{- else }}
value: {{ $user.password | quote }}
{{- end }}
{{- end }}
{{- end }}
{{- /* zookeeper */ -}}
{{- if $zkEnabled }}
- name: {{ include "fluss.security.sasl.plain.zookeeper.envVarName" "username" }}
{{- $zkRef := .Values.security.zookeeper.sasl.plain.existingSecret | default (dict) }}
{{- if $zkRef.name }}
valueFrom:
secretKeyRef:
name: {{ $zkRef.name }}
key: {{ $zkRef.usernameKey | default "username" }}
{{- else }}
value: {{ .Values.security.zookeeper.sasl.plain.username | quote }}
{{- end }}
- name: {{ include "fluss.security.sasl.plain.zookeeper.envVarName" "password" }}
{{- if $zkRef.name }}
valueFrom:
secretKeyRef:
name: {{ $zkRef.name }}
key: {{ $zkRef.passwordKey | default "password" }}
{{- else }}
value: {{ .Values.security.zookeeper.sasl.plain.password | quote }}
{{- end }}
{{- end }}
{{- end -}}

{{/*
Init container spec: mounts the rendered JAAS template ConfigMap at /tmpl,
resolves credential placeholders via envsubst, writes the result to the
shared emptyDir at /jaas, and chmods it 0400.
Usage:
include "fluss.security.jaas.initContainer" .
*/}}
{{- define "fluss.security.jaas.initContainer" -}}
- name: render-jaas-config
image: {{ include "fluss.image" . }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
{{- include "fluss.security.jaas.initContainer.env" . | nindent 4 }}
command:
- /bin/sh
- -ec
- |
umask 077
envsubst < /tmpl/jaas.conf > /jaas/jaas.conf
chmod 0400 /jaas/jaas.conf
{{- if include "fluss.security.zookeeper.sasl.enabled" . }}
cp /tmpl/zookeeper-client.properties /jaas/zookeeper-client.properties
chmod 0400 /jaas/zookeeper-client.properties
{{- end }}
volumeMounts:
- name: sasl-template
mountPath: /tmpl
readOnly: true
- name: sasl-config
mountPath: /jaas
{{- end -}}

{{/*
Pod-level volumes for the JAAS render path: the template ConfigMap (input)
and an in-memory emptyDir (output, shared with the main container).
Usage:
include "fluss.security.jaas.volumes" .
*/}}
{{- define "fluss.security.jaas.volumes" -}}
- name: sasl-template
configMap:
name: {{ include "fluss.security.jaas.configName" . }}
- name: sasl-config
emptyDir:
medium: Memory
sizeLimit: 1Mi
{{- end -}}
98 changes: 87 additions & 11 deletions helm/templates/_security.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ Usage:
{{- end -}}

{{/*
Validates that the client PLAIN mechanism block contains the required users.
Validates security.client.sasl.plain.users. Each entry is either a literal
{username, password} pair OR {existingSecret: {name, usernameKey?, passwordKey?}}.
Mixing the two shapes within one entry is not allowed.
Returns an error message if invalid, empty string otherwise.
Usage:
include "fluss.security.sasl.validateClientPlainUsers" .
Expand All @@ -130,11 +132,22 @@ Usage:
{{- if eq (len $users) 0 -}}
{{- print "security.client.sasl.plain.users must contain at least one user when security.client.sasl.mechanism is plain" -}}
{{- else -}}
{{- $errs := list -}}
{{- range $idx, $user := $users -}}
{{- if or (empty $user.username) (empty $user.password) -}}
{{- printf "security.client.sasl.plain.users[%d] must set both username and password" $idx -}}
{{- $ref := $user.existingSecret | default (dict) -}}
{{- $hasLiteral := or (not (empty $user.username)) (not (empty $user.password)) -}}
{{- $hasRef := not (empty $ref.name) -}}
{{- if and $hasLiteral $hasRef -}}
{{- $errs = append $errs (printf "security.client.sasl.plain.users[%d] cannot set username/password and existingSecret" $idx) -}}
{{- else if $hasRef -}}
{{/* existingSecret path — name is the only required field */}}
{{- else -}}
{{- if or (empty $user.username) (empty $user.password) -}}
{{- $errs = append $errs (printf "security.client.sasl.plain.users[%d] must set both username and password (or existingSecret)" $idx) -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- join "\n" $errs -}}
{{- end -}}
{{- end -}}
{{- end -}}
Expand Down Expand Up @@ -166,26 +179,36 @@ Usage:
{{- end -}}

{{/*
Validates that ZooKeeper SASL username is not empty when ZK SASL is enabled.
Validates that ZooKeeper SASL username is provided when ZK SASL is enabled,
either as a literal or via existingSecret.
Returns an error message if invalid, empty string otherwise.
Usage:
include "fluss.security.zookeeper.sasl.validateUsername" .
*/}}
{{- define "fluss.security.zookeeper.sasl.validateUsername" -}}
{{- if and (include "fluss.security.zookeeper.sasl.enabled" .) (not .Values.security.zookeeper.sasl.plain.username) -}}
{{- print "security.zookeeper.sasl.plain.username must not be empty when security.zookeeper.sasl.mechanism is plain" -}}
{{- if include "fluss.security.zookeeper.sasl.enabled" . -}}
{{- if not (include "fluss.security.sasl.plain.zookeeper.fromSecret" .) -}}
{{- if not .Values.security.zookeeper.sasl.plain.username -}}
{{- print "security.zookeeper.sasl.plain.username must not be empty when security.zookeeper.sasl.mechanism is plain (or set security.zookeeper.sasl.plain.existingSecret)" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}

{{/*
Validates that ZooKeeper SASL password is not empty when ZK SASL is enabled.
Validates that ZooKeeper SASL password is provided when ZK SASL is enabled,
either as a literal or via existingSecret.
Returns an error message if invalid, empty string otherwise.
Usage:
include "fluss.security.zookeeper.sasl.validatePassword" .
*/}}
{{- define "fluss.security.zookeeper.sasl.validatePassword" -}}
{{- if and (include "fluss.security.zookeeper.sasl.enabled" .) (not .Values.security.zookeeper.sasl.plain.password) -}}
{{- print "security.zookeeper.sasl.plain.password must not be empty when security.zookeeper.sasl.mechanism is plain" -}}
{{- if include "fluss.security.zookeeper.sasl.enabled" . -}}
{{- if not (include "fluss.security.sasl.plain.zookeeper.fromSecret" .) -}}
{{- if not .Values.security.zookeeper.sasl.plain.password -}}
{{- print "security.zookeeper.sasl.plain.password must not be empty when security.zookeeper.sasl.mechanism is plain (or set security.zookeeper.sasl.plain.existingSecret)" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}

Expand Down Expand Up @@ -245,8 +268,10 @@ Usage:
{{- if (include "fluss.security.sasl.enabled" .) -}}
{{- $internalMechanism := include "fluss.security.listener.mechanism" (dict "context" .Values "listener" "internal") -}}
{{- if eq $internalMechanism "plain" -}}
{{- if and (not .Values.security.internal.sasl.plain.username) (not .Values.security.internal.sasl.plain.password) -}}
{{- print "You are using AUTO-GENERATED SASL credentials for internal communication.\n It is strongly recommended to set the following values in production:\n - security.internal.sasl.plain.username\n - security.internal.sasl.plain.password" -}}
{{- if not (include "fluss.security.sasl.plain.internal.fromSecret" .) -}}
{{- if and (not .Values.security.internal.sasl.plain.username) (not .Values.security.internal.sasl.plain.password) -}}
{{- print "You are using AUTO-GENERATED SASL credentials for internal communication.\n It is strongly recommended to set the following values in production:\n - security.internal.sasl.plain.username\n - security.internal.sasl.plain.password\n Or source from an existing Secret via security.internal.sasl.plain.existingSecret" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
Expand Down Expand Up @@ -294,3 +319,54 @@ Usage:
{{- define "fluss.security.jaas.configName" -}}
{{ include "fluss.fullname" . }}-sasl-jaas-config
{{- end -}}

{{/*
Returns "true" if internal SASL credentials come from an existingSecret.
Usage:
include "fluss.security.sasl.plain.internal.fromSecret" .
*/}}
{{- define "fluss.security.sasl.plain.internal.fromSecret" -}}
{{- $ref := .Values.security.internal.sasl.plain.existingSecret | default (dict) -}}
{{- if $ref.name -}}true{{- end -}}
{{- end -}}

{{/*
Returns "true" if ZooKeeper SASL credentials come from an existingSecret.
Usage:
include "fluss.security.sasl.plain.zookeeper.fromSecret" .
*/}}
{{- define "fluss.security.sasl.plain.zookeeper.fromSecret" -}}
{{- $ref := .Values.security.zookeeper.sasl.plain.existingSecret | default (dict) -}}
{{- if $ref.name -}}true{{- end -}}
{{- end -}}

{{/*
Returns the env-var name for an internal SASL credential field.
Usage:
include "fluss.security.sasl.plain.internal.envVarName" "username"
include "fluss.security.sasl.plain.internal.envVarName" "password"
*/}}
{{- define "fluss.security.sasl.plain.internal.envVarName" -}}
{{- printf "FLUSS_JAAS_INTERNAL_%s" (upper .) -}}
{{- end -}}

{{/*
Returns the env-var name for a ZooKeeper SASL credential field.
Usage:
include "fluss.security.sasl.plain.zookeeper.envVarName" "username"
include "fluss.security.sasl.plain.zookeeper.envVarName" "password"
*/}}
{{- define "fluss.security.sasl.plain.zookeeper.envVarName" -}}
{{- printf "FLUSS_JAAS_ZOOKEEPER_%s" (upper .) -}}
{{- end -}}

{{/*
Returns the env-var name for a client user credential field at a given index.
Usage:
include "fluss.security.sasl.plain.client.envVarName" (dict "field" "username" "idx" 2)
=> FLUSS_JAAS_CLIENT_USERNAME_2
*/}}
{{- define "fluss.security.sasl.plain.client.envVarName" -}}
{{- printf "FLUSS_JAAS_CLIENT_%s_%d" (upper .field) (int .idx) -}}
{{- end -}}

Original file line number Diff line number Diff line change
Expand Up @@ -19,43 +19,40 @@
{{ if (include "fluss.security.jaas.required" .) }}
{{- $internalMechanism := include "fluss.security.listener.mechanism" (dict "context" .Values "listener" "internal") -}}
{{- $clientMechanism := include "fluss.security.listener.mechanism" (dict "context" .Values "listener" "client") -}}
{{- $internalUsername := include "fluss.security.sasl.plain.internal.username" . -}}
{{- $internalPassword := include "fluss.security.sasl.plain.internal.password" . -}}
apiVersion: v1
kind: Secret
kind: ConfigMap
metadata:
name: {{ include "fluss.security.jaas.configName" . }}
labels:
{{- include "fluss.labels" . | nindent 4 }}
type: Opaque
stringData:
data:
jaas.conf: |
{{- if (include "fluss.security.sasl.plain.enabled" .) }}
{{- if eq $internalMechanism "plain" }}
internal.FlussServer {
org.apache.fluss.security.auth.sasl.plain.PlainLoginModule required
user_{{ $internalUsername }}="{{ $internalPassword }}";
user_${FLUSS_JAAS_INTERNAL_USERNAME}="${FLUSS_JAAS_INTERNAL_PASSWORD}";
};
FlussClient {
org.apache.fluss.security.auth.sasl.plain.PlainLoginModule required
username="{{ $internalUsername }}"
password="{{ $internalPassword }}";
username="${FLUSS_JAAS_INTERNAL_USERNAME}"
password="${FLUSS_JAAS_INTERNAL_PASSWORD}";
};
{{- end }}
{{- if eq $clientMechanism "plain" }}
client.FlussServer {
org.apache.fluss.security.auth.sasl.plain.PlainLoginModule required
{{- range .Values.security.client.sasl.plain.users | default (list) }}
user_{{ .username }}="{{ .password }}"
{{- range $idx, $user := .Values.security.client.sasl.plain.users | default (list) }}
user_${FLUSS_JAAS_CLIENT_USERNAME_{{ $idx }}}="${FLUSS_JAAS_CLIENT_PASSWORD_{{ $idx }}}"
{{- end }};
};
{{- end }}
{{- end }}
{{- if (include "fluss.security.zookeeper.sasl.enabled" .) }}
ZookeeperClient {
{{ .Values.security.zookeeper.sasl.plain.loginModuleClass }} required
username="{{ .Values.security.zookeeper.sasl.plain.username }}"
password="{{ .Values.security.zookeeper.sasl.plain.password }}";
username="${FLUSS_JAAS_ZOOKEEPER_USERNAME}"
password="${FLUSS_JAAS_ZOOKEEPER_PASSWORD}";
};
{{- end }}
{{- if (include "fluss.security.zookeeper.sasl.enabled" .) }}
Expand Down
11 changes: 7 additions & 4 deletions helm/templates/sts-coordinator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,14 @@ spec:
topologySpreadConstraints:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.coordinator.initContainers }}
{{- if or (include "fluss.security.jaas.required" .) .Values.coordinator.initContainers }}
initContainers:
{{- if include "fluss.security.jaas.required" . }}
{{- include "fluss.security.jaas.initContainer" . | nindent 8 }}
{{- end }}
{{- with .Values.coordinator.initContainers }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
containers:
- name: {{ .Chart.Name }}-coordinator
Expand Down Expand Up @@ -156,9 +161,7 @@ spec:
emptyDir: {}
{{- end }}
{{- if (include "fluss.security.jaas.required" .) }}
- name: sasl-config
secret:
secretName: {{ include "fluss.security.jaas.configName" . }}
{{- include "fluss.security.jaas.volumes" . | nindent 8 }}
{{- end }}
{{- with .Values.coordinator.extraVolumes }}
{{- toYaml . | nindent 8 }}
Expand Down
11 changes: 7 additions & 4 deletions helm/templates/sts-tablet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,14 @@ spec:
topologySpreadConstraints:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tablet.initContainers }}
{{- if or (include "fluss.security.jaas.required" .) .Values.tablet.initContainers }}
initContainers:
{{- if include "fluss.security.jaas.required" . }}
{{- include "fluss.security.jaas.initContainer" . | nindent 8 }}
{{- end }}
{{- with .Values.tablet.initContainers }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
containers:
- name: {{ .Chart.Name }}-tablet
Expand Down Expand Up @@ -153,9 +158,7 @@ spec:
emptyDir: {}
{{- end }}
{{- if (include "fluss.security.jaas.required" .) }}
- name: sasl-config
secret:
secretName: {{ include "fluss.security.jaas.configName" . }}
{{- include "fluss.security.jaas.volumes" . | nindent 8 }}
{{- end }}
{{- with .Values.tablet.extraVolumes }}
{{- toYaml . | nindent 8 }}
Expand Down
Loading