Skip to content

[Bug] mTLS support to connect to cassandraDB is missing in schema migrator job #886

@shankarkc

Description

@shankarkc

What are you really trying to do?

Use mTLS to connect to cassandraDB as mLTS is mandatory for cassandraDB connection

Describe the bug

We can specify CA, client key/ client key for temporal pods But schema migrator job does not mount client key/certs and ALWAYS uses user/pwd when connecting to cassandraDB. When cassandra enforces strict mTLS this will break. Here is sample yaml of schemajob for your reference

apiVersion: batch/v1
kind: Job
metadata:
  name: temporal-schema-81
  labels:
    app.kubernetes.io/component: database
    app.kubernetes.io/name: temporal
    helm.sh/chart: temporal-0.74.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/instance: temporal
    app.kubernetes.io/version: "1.30.3"
    app.kubernetes.io/part-of: temporal
spec:
  backoffLimit: 100
  ttlSecondsAfterFinished: 86400
  template:
    metadata:
      name: temporal-schema-81
      labels:
        app.kubernetes.io/component: database
        app.kubernetes.io/name: temporal
        helm.sh/chart: temporal-0.74.0
        app.kubernetes.io/managed-by: Helm
        app.kubernetes.io/instance: temporal
        app.kubernetes.io/version: "1.30.3"
        app.kubernetes.io/part-of: temporal
    spec:
      serviceAccountName: default
      restartPolicy: OnFailure
      initContainers:
        - name: check-cassandra
          image: "cassandra:3.11.3"
          imagePullPolicy: IfNotPresent
          command: ['sh', '-c', 'until cqlsh temporal-cassandra.temporal 9042 -e "SHOW VERSION"; do echo waiting for cassandra to start; sleep 1; done;']
        - name: check-elasticsearch
          image: "temporalio/admin-tools:1.29.1-tctl-1.18.4-cli-1.5.0"
          imagePullPolicy: IfNotPresent
          command: ['/bin/sh', '-c']
          args:
            - |
              set -e
              echo "Waiting for Elasticsearch to become available..."

              if [ -x /usr/local/bin/temporal-elasticsearch-tool ]; then
                echo "Using temporal-elasticsearch-tool for Elasticsearch health check"
                until temporal-elasticsearch-tool --endpoint "$ES_SCHEME://$ES_HOST:$ES_PORT" --user "$ES_USER" --password "$ES_PWD" ping 2>&1 > /dev/null; do
                  sleep 1
                done
              elif command -v curl >/dev/null 2>&1; then
                echo "Using curl for Elasticsearch health check"
                until curl --silent --fail --user "$ES_USER:$ES_PWD" "$ES_SCHEME://$ES_HOST:$ES_PORT" 2>&1 > /dev/null; do
                  sleep 1
                done
              else
                echo "ERROR: Neither temporal-elasticsearch-tool nor curl found" >&2
                exit 1
              fi
              echo "Elasticsearch is ready"
          env:
            - name: ES_SCHEME
              value: http
            - name: ES_HOST
              value: elasticsearch-master-headless
            - name: ES_PORT
              value: "9200"
            - name: ES_USER
              value: ""
            - name: ES_PWD
              valueFrom:
                secretKeyRef:
                  name: temporal-visibility-store
                  key: password
            - name: ES_VERSION
              value: v7
            - name: ES_VISIBILITY_INDEX
              value: temporal_visibility_v1
        - name: create-default-store
          image: "temporalio/admin-tools:1.29.1-tctl-1.18.4-cli-1.5.0"
          imagePullPolicy: IfNotPresent
          command: ['temporal-cassandra-tool', 'create', '-k', 'temporal', '--replication-factor', '1']
          env:
            - name: CASSANDRA_HOST
              value: temporal-cassandra.temporal
            - name: CASSANDRA_PORT
              value: "9042"
            - name: CASSANDRA_KEYSPACE
              value: temporal
            - name: CASSANDRA_USER
              value: user
            - name: CASSANDRA_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: temporal-default-store
                  key: password
          volumeMounts:
            - mountPath: /etc/cassandra
              name: cassandra-root-ca
              readOnly: true
          resources:
            limits:
              cpu: 4000m
              memory: 5120Mi
            requests:
              cpu: 2000m
              memory: 1280Mi
        - name: setup-default-store
          image: "temporalio/admin-tools:1.29.1-tctl-1.18.4-cli-1.5.0"
          imagePullPolicy: IfNotPresent
          command: ['temporal-cassandra-tool', 'setup-schema', '-v', '0.0']
          env:
            - name: CASSANDRA_HOST
              value: temporal-cassandra.temporal
            - name: CASSANDRA_PORT
              value: "9042"
            - name: CASSANDRA_KEYSPACE
              value: temporal
            - name: CASSANDRA_USER
              value: user
            - name: CASSANDRA_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: temporal-default-store
                  key: password
          volumeMounts:
            - mountPath: /etc/cassandra
              name: cassandra-root-ca
              readOnly: true
          resources:
            limits:
              cpu: 4000m
              memory: 5120Mi
            requests:
              cpu: 2000m
              memory: 1280Mi
        - name: setup-visibility-store
          image: "temporalio/admin-tools:1.29.1-tctl-1.18.4-cli-1.5.0"
          imagePullPolicy: IfNotPresent
          command: ['/bin/sh', '-c']
          args:
            - |
              set -e
              echo "Setting up Elasticsearch visibility store..."

              if [ -x /usr/local/bin/temporal-elasticsearch-tool ]; then
                echo "Using temporal-elasticsearch-tool for Elasticsearch setup"

                echo "Setting up cluster settings and index template"
                temporal-elasticsearch-tool \
                  --endpoint "$ES_SCHEME://$ES_HOST:$ES_PORT" \
                  --user "$ES_USER" \
                  --password "$ES_PWD" \
                  setup-schema

                echo "Creating visibility index: $ES_VISIBILITY_INDEX"
                temporal-elasticsearch-tool \
                  --endpoint "$ES_SCHEME://$ES_HOST:$ES_PORT" \
                  --user "$ES_USER" \
                  --password "$ES_PWD" \
                  create-index \
                  --index "$ES_VISIBILITY_INDEX" \
                  --fail

                echo "Updating index mappings: $ES_VISIBILITY_INDEX"
                temporal-elasticsearch-tool \
                  --endpoint "$ES_SCHEME://$ES_HOST:$ES_PORT" \
                  --user "$ES_USER" \
                  --password "$ES_PWD" \
                  update-schema \
                  --index "$ES_VISIBILITY_INDEX"

              elif command -v curl >/dev/null 2>&1; then
                echo "Using curl for Elasticsearch setup"

                echo "Creating index template: temporal_visibility_v1_template"
                curl -X PUT --fail --user "$ES_USER:$ES_PWD" \
                  "$ES_SCHEME://$ES_HOST:$ES_PORT/_template/temporal_visibility_v1_template" \
                  -H "Content-Type: application/json" \
                  --data-binary "@schema/elasticsearch/visibility/index_template_$ES_VERSION.json"

                echo "Creating index: $ES_VISIBILITY_INDEX"
                HTTP_CODE=$(curl -X PUT -s -o /dev/null -w "%{http_code}" --user "$ES_USER:$ES_PWD" \
                  "$ES_SCHEME://$ES_HOST:$ES_PORT/$ES_VISIBILITY_INDEX")
                if [ "$HTTP_CODE" != "200" ] && [ "$HTTP_CODE" != "400" ]; then
                  echo "ERROR: Failed to create index, HTTP code: $HTTP_CODE" >&2
                  exit 1
                fi

              else
                echo "ERROR: Neither temporal-elasticsearch-tool nor curl found" >&2
                exit 1
              fi

              echo "Elasticsearch setup completed successfully"
          env:
            - name: ES_SCHEME
              value: http
            - name: ES_HOST
              value: elasticsearch-master-headless
            - name: ES_PORT
              value: "9200"
            - name: ES_USER
              value: ""
            - name: ES_PWD
              valueFrom:
                secretKeyRef:
                  name: temporal-visibility-store
                  key: password
            - name: ES_VERSION
              value: v7
            - name: ES_VISIBILITY_INDEX
              value: temporal_visibility_v1
          volumeMounts:
            - mountPath: /etc/cassandra
              name: cassandra-root-ca
              readOnly: true
          resources:
            limits:
              cpu: 4000m
              memory: 5120Mi
            requests:
              cpu: 2000m
              memory: 1280Mi
        - name: update-default-store
          image: "temporalio/admin-tools:1.29.1-tctl-1.18.4-cli-1.5.0"
          imagePullPolicy: IfNotPresent
          command: ['temporal-cassandra-tool', 'update-schema', '--schema-dir', '/etc/temporal/schema/cassandra/temporal/versioned']
          env:
            - name: CASSANDRA_HOST
              value: temporal-cassandra.temporal
            - name: CASSANDRA_PORT
              value: "9042"
            - name: CASSANDRA_KEYSPACE
              value: temporal
            - name: CASSANDRA_USER
              value: user
            - name: CASSANDRA_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: temporal-default-store
                  key: password
          volumeMounts:
            - mountPath: /etc/cassandra
              name: cassandra-root-ca
              readOnly: true
          resources:
            limits:
              cpu: 4000m
              memory: 5120Mi
            requests:
              cpu: 2000m
              memory: 1280Mi
        - name: create-default-namespace
          image: "temporalio/admin-tools:1.29.1-tctl-1.18.4-cli-1.5.0"
          imagePullPolicy: IfNotPresent
          command: ['/bin/sh','-c']
          args: ['temporal operator namespace describe -n default || temporal operator namespace create -n default --retention 30d']
          env:
            - name: TEMPORAL_ADDRESS
              value: "temporal-frontend.temporal.svc:7233"
          volumeMounts:
            - mountPath: /etc/cassandra
              name: cassandra-root-ca
              readOnly: true
          resources:
            limits:
              cpu: 4000m
              memory: 5120Mi
            requests:
              cpu: 2000m
              memory: 1280Mi
      containers:
        - name: done
          image: "temporalio/admin-tools:1.29.1-tctl-1.18.4-cli-1.5.0"
          imagePullPolicy: IfNotPresent
          command: ['sh', '-c', 'echo "Store setup completed"']
          resources:
            limits:
              cpu: 4000m
              memory: 5120Mi
            requests:
              cpu: 2000m
              memory: 1280Mi
      securityContext:
        fsGroup: 2000
        runAsGroup: 3000
        runAsUser: 1000
        supplementalGroups:
        - 4000
      imagePullSecrets:
        - name: regsecret
      volumes:
        - name: cassandra-root-ca
          secret:
            defaultMode: 292
            secretName: cassandra-root-ca

The schema migration job mounts the CA cert but does not pass client cert/key for mTLS, and the check-cassandra step uses plain cqlsh. If your Cassandra requires mTLS, this job as-is will not work. You would likely need to customize the Helm chart or the job manifest to pass the appropriate TLS flags to temporal-cassandra-tool and configure cqlsh with TLS options

Minimal Reproduction

NA

Environment/Versions

all

Additional context

NA

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingneeds revisionTeam has requested some changes

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions