diff --git a/.ci/chart_test.sh b/.ci/chart_test.sh index 7e7b0328..e91f3d1b 100755 --- a/.ci/chart_test.sh +++ b/.ci/chart_test.sh @@ -27,6 +27,7 @@ VALUES_FILE=$1 TLS=${TLS:-"false"} SYMMETRIC=${SYMMETRIC:-"false"} FUNCTION=${FUNCTION:-"false"} +MANAGER=${MANAGER:-"false"} source ${PULSAR_HOME}/.ci/helm.sh @@ -40,6 +41,10 @@ if [[ "x${SYMMETRIC}" == "xtrue" ]]; then extra_opts="-s" fi +if [[ "x${EXTRA_SUPERUSERS}" != "x" ]]; then + extra_opts="${extra_opts} --pulsar-superusers proxy-admin,broker-admin,admin,${EXTRA_SUPERUSERS}" +fi + install_type="install" test_action="produce-consume" if [[ "$UPGRADE_FROM_VERSION" != "" ]]; then diff --git a/.ci/clusters/values-jwt-asymmetric.yaml b/.ci/clusters/values-jwt-asymmetric.yaml index 13344f01..d2f37f75 100644 --- a/.ci/clusters/values-jwt-asymmetric.yaml +++ b/.ci/clusters/values-jwt-asymmetric.yaml @@ -17,6 +17,7 @@ # under the License. # + auth: authentication: enabled: true @@ -35,3 +36,9 @@ auth: proxy: "proxy-admin" # pulsar-admin client to broker/proxy communication client: "admin" + # pulsar-manager to broker communication + manager: "manager-admin" + +components: + pulsar_manager: true + diff --git a/.ci/clusters/values-jwt-symmetric.yaml b/.ci/clusters/values-jwt-symmetric.yaml index 76faf737..d9fb9f85 100644 --- a/.ci/clusters/values-jwt-symmetric.yaml +++ b/.ci/clusters/values-jwt-symmetric.yaml @@ -17,6 +17,7 @@ # under the License. # + auth: authentication: enabled: true @@ -35,3 +36,8 @@ auth: proxy: "proxy-admin" # pulsar-admin client to broker/proxy communication client: "admin" + # pulsar manager to broker + manager: "manager-admin" + +components: + pulsar_manager: true diff --git a/.ci/clusters/values-tls.yaml b/.ci/clusters/values-tls.yaml index 66ead807..cbd09cce 100644 --- a/.ci/clusters/values-tls.yaml +++ b/.ci/clusters/values-tls.yaml @@ -17,6 +17,7 @@ # under the License. # + # enable TLS tls: enabled: true diff --git a/.ci/helm.sh b/.ci/helm.sh index 73775255..9945d199 100644 --- a/.ci/helm.sh +++ b/.ci/helm.sh @@ -112,7 +112,7 @@ function ci::install_pulsar_chart() { local install_type=$1 local common_value_file=$2 local value_file=$3 - local extra_opts=$4 + local extra_opts="$4 $5 $6 $7 $8" local install_args if [[ "${install_type}" == "install" ]]; then @@ -374,7 +374,7 @@ function ci::test_pulsar_manager() { -sS -D headers.txt \ -d '{"username": "pulsar", "password": "'${PASSWORD}'"}' LOGIN_TOKEN=$(${KUBECTL} exec -n ${NAMESPACE} ${podname} -- grep "token:" headers.txt | sed 's/^.*: //') - LOGIN_JSESSSIONID=$(${KUBECTL} exec -n ${NAMESPACE} ${podname} -- grep -o "JSESSIONID=[a-zA-Z0-9_]*" headers.txt | sed 's/^.*=//') + LOGIN_JSESSIONID=$(${KUBECTL} exec -n ${NAMESPACE} ${podname} -- grep -o "JSESSIONID=[a-zA-Z0-9_]*" headers.txt | sed 's/^.*=//') echo "Checking environment" envs=$(${KUBECTL} exec -n ${NAMESPACE} ${podname} -- curl -X GET http://localhost:9527/pulsar-manager/environments \ @@ -382,11 +382,29 @@ function ci::test_pulsar_manager() { -H "token: $LOGIN_TOKEN" \ -H "X-XSRF-TOKEN: $CSRF_TOKEN" \ -H "username: pulsar" \ - -H "Cookie: XSRF-TOKEN=$CSRF_TOKEN; JSESSIONID=$LOGIN_JSESSSIONID;") + -H "Cookie: XSRF-TOKEN=$CSRF_TOKEN; JSESSIONID=$LOGIN_JSESSIONID;") + echo "$envs" number_of_envs=$(echo $envs | jq '.total') if [ "$number_of_envs" -ne 1 ]; then echo "Error: Did not find expected environment" exit 1 fi -} + # Force manager to query broker for tenant info. This will require use of the manager's JWT, if JWT authentication is enabled. + echo "Checking tenants" + pulsar_env=$(echo $envs | jq -r '.data[0].name') + tenants=$(${KUBECTL} exec -n ${NAMESPACE} ${podname} -- curl -X GET http://localhost:9527/pulsar-manager/admin/v2/tenants \ + -H 'Content-Type: application/json' \ + -H "token: $LOGIN_TOKEN" \ + -H "X-XSRF-TOKEN: $CSRF_TOKEN" \ + -H "username: pulsar" \ + -H "tenant: pulsar" \ + -H "environment: ${pulsar_env}" \ + -H "Cookie: XSRF-TOKEN=$CSRF_TOKEN; JSESSIONID=$LOGIN_JSESSIONID;") + echo "$tenants" + number_of_tenants=$(echo $tenants | jq '.total') + if [ "$number_of_tenants" -lt 1 ]; then + echo "Error: Found no tenants!" + exit 1 + fi +} diff --git a/.github/workflows/pulsar-helm-chart-ci.yaml b/.github/workflows/pulsar-helm-chart-ci.yaml index bb0932c2..4e4f05ed 100644 --- a/.github/workflows/pulsar-helm-chart-ci.yaml +++ b/.github/workflows/pulsar-helm-chart-ci.yaml @@ -302,6 +302,10 @@ jobs: case "${{ matrix.testScenario.shortname }}" in "jwt-symmetric") export SYMMETRIC=true + export EXTRA_SUPERUSERS=manager-admin + ;; + "jwt-asymmetric") + export EXTRA_SUPERUSERS=manager-admin ;; esac if [[ "${{ matrix.testScenario.type || 'install' }}" == "upgrade" ]]; then diff --git a/charts/pulsar/templates/broker-configmap.yaml b/charts/pulsar/templates/broker-configmap.yaml index 10106506..6994e222 100644 --- a/charts/pulsar/templates/broker-configmap.yaml +++ b/charts/pulsar/templates/broker-configmap.yaml @@ -163,11 +163,10 @@ data: authenticationEnabled: "true" {{- if .Values.auth.authorization.enabled }} authorizationEnabled: "true" - superUserRoles: {{ .Values.auth.superUsers | values | sortAlpha | join "," }} + superUserRoles: {{ .Values.auth.superUsers | values | compact | sortAlpha | join "," }} {{- if .Values.auth.useProxyRoles }} proxyRoles: {{ .Values.auth.superUsers.proxy }} {{- end }} - {{- end }} {{- if eq .Values.auth.authentication.provider "jwt" }} # token authentication configuration diff --git a/charts/pulsar/templates/proxy-configmap.yaml b/charts/pulsar/templates/proxy-configmap.yaml index 0d82d8b8..f28a3fdb 100644 --- a/charts/pulsar/templates/proxy-configmap.yaml +++ b/charts/pulsar/templates/proxy-configmap.yaml @@ -65,9 +65,9 @@ data: authorizationEnabled: "false" forwardAuthorizationCredentials: "true" {{- if .Values.auth.useProxyRoles }} - superUserRoles: {{ omit .Values.auth.superUsers "proxy" | values | sortAlpha | join "," }} + superUserRoles: {{ omit .Values.auth.superUsers "proxy" | values | compact | sortAlpha | join "," }} {{- else }} - superUserRoles: {{ .Values.auth.superUsers | values | sortAlpha | join "," }} + superUserRoles: {{ .Values.auth.superUsers | values | compact | sortAlpha | join "," }} {{- end }} {{- end }} {{- if eq .Values.auth.authentication.provider "jwt" }} diff --git a/charts/pulsar/templates/pulsar-manager-statefulset.yaml b/charts/pulsar/templates/pulsar-manager-statefulset.yaml index 9bf7ca86..01896fa7 100644 --- a/charts/pulsar/templates/pulsar-manager-statefulset.yaml +++ b/charts/pulsar/templates/pulsar-manager-statefulset.yaml @@ -69,6 +69,12 @@ spec: volumeMounts: - name: "{{ template "pulsar.fullname" . }}-{{ .Values.pulsar_manager.component }}-{{ .Values.pulsar_manager.volumes.data.name }}" mountPath: /data + {{- if .Values.auth.authentication.enabled }} + {{- if eq .Values.auth.authentication.provider "jwt" }} + - name: pulsar-manager-keys + mountPath: /pulsar-manager/keys + {{- end }} + {{- end }} envFrom: - configMapRef: name: "{{ template "pulsar.fullname" . }}-{{ .Values.pulsar_manager.component }}" @@ -87,8 +93,50 @@ spec: key: DB_PASSWORD - name: PULSAR_MANAGER_OPTS value: "$(PULSAR_MANAGER_OPTS) -Dlog4j2.formatMsgNoLookups=true" - {{- include "pulsar.imagePullSecrets" . | nindent 6 }} + {{- if .Values.auth.authentication.enabled }} + {{- if eq .Values.auth.authentication.provider "jwt" }} + {{- if .Values.auth.superUsers.manager }} + - name: JWT_TOKEN + valueFrom: + secretKeyRef: + key: TOKEN + name: "{{ .Release.Name }}-token-{{ .Values.auth.superUsers.manager }}" + {{- end }} + {{- if .Values.auth.authentication.jwt.usingSecretKey }} + - name: SECRET_KEY + value: file:///pulsar-manager/keys/token/secret.key + {{- else }} + - name: PRIVATE_KEY + value: file:///pulsar-manager/keys/token/private.key + - name: PUBLIC_KEY + value: file:///pulsar-manager/keys/token/public.key + {{- end }} + {{- end }} + {{- end }} + {{- include "pulsar.imagePullSecrets" . | nindent 6}} volumes: + {{- if .Values.auth.authentication.enabled }} + {{- if eq .Values.auth.authentication.provider "jwt" }} + - name: pulsar-manager-keys + secret: + defaultMode: 420 + {{- if .Values.auth.authentication.jwt.usingSecretKey }} + secretName: "{{ .Release.Name }}-token-symmetric-key" + {{- else }} + secretName: "{{ .Release.Name }}-token-asymmetric-key" + {{- end }} + items: + {{- if .Values.auth.authentication.jwt.usingSecretKey }} + - key: SECRETKEY + path: token/secret.key + {{- else }} + - key: PRIVATEKEY + path: token/private.key + - key: PUBLICKEY + path: token/public.key + {{- end }} + {{- end }} + {{- end }} {{- if not (and (and .Values.persistence .Values.volumes.persistence) .Values.pulsar_manager.volumes.persistence) }} - name: "{{ template "pulsar.fullname" . }}-{{ .Values.pulsar_manager.component }}-{{ .Values.pulsar_manager.volumes.data.name }}" emptyDir: {} @@ -113,4 +161,4 @@ spec: {{- end }} {{- end }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/charts/pulsar/values.yaml b/charts/pulsar/values.yaml index 4d2ae4cf..6df457b4 100644 --- a/charts/pulsar/values.yaml +++ b/charts/pulsar/values.yaml @@ -253,6 +253,8 @@ auth: proxy: "proxy-admin" # pulsar-admin client to broker/proxy communication client: "admin" + # pulsar-manager to broker communication. If left empty, no jwt setup will be performed in the manager + manager: "" # omits the above proxy role from superusers on the proxy # and configures it as a proxy role on the broker in addition to the superusers useProxyRoles: true @@ -1311,12 +1313,6 @@ pulsar_manager: DRIVER_CLASS_NAME: org.postgresql.Driver URL: jdbc:postgresql://127.0.0.1:5432/pulsar_manager LOG_LEVEL: DEBUG - ## If you enabled authentication support - ## JWT_TOKEN: - ## SECRET_KEY: data:base64, - - # the pulsar manager image relies on these variables, if they are not set the backend will keep crashing - # however, feel free to overwrite them SPRING_CONFIGURATION_FILE: "/pulsar-manager/pulsar-manager/application.properties" PULSAR_MANAGER_OPTS: " -Dlog4j2.formatMsgNoLookups=true" volumes: