cetic / helm-nifi

Helm Chart for Apache Nifi
Apache License 2.0
215 stars 228 forks source link

Persistent volumes not used when LDAP or OIDC are enabled #211

Closed leshibily closed 2 years ago

leshibily commented 2 years ago

Hello folks,

I would like to educate myself here on why persistent volumes like data, auth-conf, config-data, flowfile-repository etc are not mounted (volumeMounts) when ldap or oidc are not enabled. See statefulset.yaml snippet below.

{{- if or (.Values.auth.ldap.enabled) (.Values.auth.oidc.enabled) }}
          - name: "data"
            mountPath: /opt/nifi/data
          - name: "auth-conf"
            mountPath: /opt/nifi/nifi-current/auth-conf/
          - name: "config-data"
            mountPath: /opt/nifi/nifi-current/config-data
          - name: "flowfile-repository"
            mountPath: /opt/nifi/flowfile_repository
          - name: "content-repository"
            mountPath: /opt/nifi/content_repository
          - name: "provenance-repository"
            mountPath: /opt/nifi/provenance_repository
          - name: "bootstrap-conf"
            mountPath: /opt/nifi/nifi-current/conf/bootstrap.conf
            subPath: "bootstrap.conf"
          - name: "nifi-properties"
            mountPath: /opt/nifi/nifi-current/conf/nifi.temp
            subPath: "nifi.temp"
          - name: "authorizers-temp"
            mountPath: /opt/nifi/nifi-current/conf/authorizers.temp
            subPath: "authorizers.temp"
          - name: "authorizers-empty"
            mountPath: /opt/nifi/nifi-current/conf/authorizers.empty
            subPath: "authorizers.empty"
          - name: "bootstrap-notification-services-xml"
            mountPath: /opt/nifi/nifi-current/conf/bootstrap-notification-services.xml
            subPath: "bootstrap-notification-services.xml"
          - name: "login-identity-providers-xml"
            mountPath: /opt/nifi/nifi-current/conf/login-identity-providers.xml
            subPath: "login-identity-providers.xml"
          - name: "state-management-xml"
            mountPath: /opt/nifi/nifi-current/conf/state-management.xml
            subPath: "state-management.xml"
          - name: "zookeeper-properties"
            mountPath: /opt/nifi/nifi-current/conf/zookeeper.properties
            subPath: "zookeeper.properties"
          - name: "flow-content"
            mountPath: /opt/nifi/data/flow.xml
            subPath: "flow.xml"
          {{- range $secret := .Values.secrets }}
            {{- if $secret.mountPath }}
              {{- if $secret.keys }}
                {{- range $key := $secret.keys }}
          - name: {{ include "apache-nifi.fullname" $ }}-{{ $secret.name }}
            mountPath: {{ $secret.mountPath }}/{{ $key }}
            subPath: {{ $key }}
            readOnly: true
                {{- end }}
              {{- else }}
          - name: {{ include "apache-nifi.fullname" $ }}-{{ $secret.name }}
            mountPath: {{ $secret.mountPath }}
            readOnly: true
              {{- end }}
            {{- end }}
          {{- end }}
          {{- range $configmap := .Values.configmaps }}
            {{- if $configmap.mountPath }}
              {{- if $configmap.keys }}
                {{- range $key := $configmap.keys }}
          - name: {{ include "apache-nifi.fullname" $ }}-{{ $configmap.name }}
            mountPath: {{ $configmap.mountPath }}/{{ $key }}
            subPath: {{ $key }}
            readOnly: true
                {{- end }}
              {{- else }}
          - name: {{ include "apache-nifi.fullname" $ }}-{{ $configmap.name }}
            mountPath: {{ $configmap.mountPath }}
            readOnly: true
              {{- end }}
            {{- end }}
          {{- end }}
          {{- if .Values.extraVolumeMounts }}
{{ toYaml .Values.extraVolumeMounts | indent 10 }}
          {{- end }}
{{- end }}

But volumes are attached when persistence.enabled is true.

{{- if .Values.persistence.enabled }}
  volumeClaimTemplates:
    - metadata:
        name: logs
      spec:
        accessModes:
        {{- range .Values.persistence.accessModes }}
          - {{ . | quote }}
        {{- end }}
        storageClassName: {{ .Values.persistence.storageClass | quote }}
        resources:
          requests:
            storage: {{ .Values.persistence.logStorage.size }}
    - metadata:
        name: "config-data"
      spec:
        accessModes: ["ReadWriteOnce"]
        storageClassName: {{ .Values.persistence.storageClass | quote }}
        resources:
          requests:
            storage: {{ .Values.persistence.configStorage.size }}
    - metadata:
        name: data
      spec:
        accessModes:
        {{- range .Values.persistence.accessModes }}
          - {{ . | quote }}
        {{- end }}
        storageClassName: {{ .Values.persistence.storageClass | quote }}
        resources:
          requests:
            storage: {{ .Values.persistence.dataStorage.size }}
    - metadata:
        name: flowfile-repository
      spec:
        accessModes:
        {{- range .Values.persistence.accessModes }}
          - {{ . | quote }}
        {{- end }}
        storageClassName: {{ .Values.persistence.storageClass | quote }}
        resources:
          requests:
            storage: {{ .Values.persistence.flowfileRepoStorage.size }}
    - metadata:
        name: content-repository
      spec:
        accessModes:
        {{- range .Values.persistence.accessModes }}
          - {{ . | quote }}
        {{- end }}
        storageClassName: {{ .Values.persistence.storageClass | quote }}
        resources:
          requests:
            storage: {{ .Values.persistence.contentRepoStorage.size }}
    - metadata:
        name: provenance-repository
      spec:
        accessModes:
        {{- range .Values.persistence.accessModes }}
          - {{ . | quote }}
        {{- end }}
        storageClassName: {{ .Values.persistence.storageClass | quote }}
        resources:
          requests:
            storage: {{ .Values.persistence.provenanceRepoStorage.size }}
    - metadata:
        name: auth-conf
      spec:
        accessModes:
        {{- range .Values.persistence.accessModes }}
          - {{ . | quote }}
        {{- end }}
        storageClassName: {{ .Values.persistence.storageClass | quote }}
        resources:
          requests:
            storage: {{ .Values.persistence.authconfStorage.size }}
{{- end }}

I am really confused here. Any help would be appreciated.

Versions: Nifi: 1.14.0 Helm chart: 1.0.3

leshibily commented 2 years ago

I have also noticed nifi.properties config map is not used when ldap or oidc aren't enabled.

{{- if or (.Values.auth.ldap.enabled) (.Values.auth.oidc.enabled) }}
      - name: "bootstrap-conf"
        configMap:
          name: {{ template "apache-nifi.fullname" . }}-config
          items:
            - key: "bootstrap.conf"
              path: "bootstrap.conf"
      - name: "nifi-properties"
        configMap:
          name: {{ template "apache-nifi.fullname" . }}-config
          items:
            - key: "nifi.properties"
              path: "nifi.temp"
      - name: "authorizers-temp"
        configMap:
          name: {{ template "apache-nifi.fullname" . }}-config
          items:
            - key: "authorizers.xml"
              path: "authorizers.temp"
      - name: "authorizers-empty"
        configMap:
          name: {{ template "apache-nifi.fullname" . }}-config
          items:
            - key: "authorizers-empty.xml"
              path: "authorizers.empty"
      - name: "bootstrap-notification-services-xml"
        configMap:
          name: {{ template "apache-nifi.fullname" . }}-config
          items:
            - key: "bootstrap-notification-services.xml"
              path: "bootstrap-notification-services.xml"
      - name: "login-identity-providers-xml"
        configMap:
          name: {{ template "apache-nifi.fullname" . }}-config
          items:
            - key: "login-identity-providers.xml"
              path: "login-identity-providers.xml"
      - name: "state-management-xml"
        configMap:
          name: {{ template "apache-nifi.fullname" . }}-config
          items:
            - key: "state-management.xml"
              path: "state-management.xml"
      - name: "zookeeper-properties"
        configMap:
          name: {{ template "apache-nifi.fullname" . }}-config
          items:
            - key: "zookeeper.properties"
              path: "zookeeper.properties"
      - name: "flow-content"
        configMap:
          name: {{ template "apache-nifi.fullname" . }}-config
          items:
            - key: "flow.xml"
              path: "flow.xml"
      {{- range .Values.secrets }}
      - name: {{ include "apache-nifi.fullname" $ }}-{{ .name }}
        secret:
          secretName: {{ .name }}
      {{- end }}
      {{- range .Values.configmaps }}
      - name: {{ include "apache-nifi.fullname" $ }}-{{ .name }}
        configMap:
          name: {{ .name }}
      {{- end }}
{{- end }}

Also, command section is ignored when oidc or ldap are disabled.

{{- if or (.Values.auth.ldap.enabled) (.Values.auth.oidc.enabled) }}        
        command:
        - bash
        - -ce
        - |
          prop_replace () {
            target_file=${NIFI_HOME}/conf/${3:-nifi.properties}
            echo "updating ${1} in ${target_file}"
            if egrep "^${1}=" ${target_file} &> /dev/null; then
              sed -i -e "s|^$1=.*$|$1=$2|"  ${target_file}
            else
              echo ${1}=${2} >> ${target_file}
            fi
          }
          mkdir -p ${NIFI_HOME}/config-data/conf
{{- if .Values.sts.useHostNetwork }}
          FQDN="0.0.0.0"
{{- else }}
          FQDN=$(hostname -f)
{{- end }}

          cat "${NIFI_HOME}/conf/nifi.temp" > "${NIFI_HOME}/conf/nifi.properties"

{{- if .Values.auth.ldap.enabled }}
            cat "${NIFI_HOME}/conf/authorizers.temp" > "${NIFI_HOME}/conf/authorizers.xml"
{{- else }}
            cat "${NIFI_HOME}/conf/authorizers.empty" > "${NIFI_HOME}/conf/authorizers.xml"
{{- end }}

          if ! test -f /opt/nifi/data/flow.xml.gz && test -f /opt/nifi/data/flow.xml; then
            gzip /opt/nifi/data/flow.xml
          fi

          prop_replace nifi.remote.input.host ${FQDN}
          prop_replace nifi.cluster.node.address ${FQDN}
          prop_replace nifi.zookeeper.connect.string ${NIFI_ZOOKEEPER_CONNECT_STRING}
          prop_replace nifi.web.http.host ${FQDN}

{{- if .Values.properties.webProxyHost }}
          # Update nifi.properties for web ui proxy hostname
          prop_replace nifi.web.proxy.host {{ .Values.properties.webProxyHost }}
{{- else }}
          prop_replace nifi.web.proxy.host {{ template "apache-nifi.fullname" . }}.{{ .Release.Namespace }}.svc
{{- end }}

{{- if .Values.properties.safetyValve }}
  {{- range $prop, $val := .Values.properties.safetyValve }}
          prop_replace {{ $prop }} "{{ $val }}" nifi.properties
  {{- end }}
{{- end }}

          exec bin/nifi.sh run & nifi_pid="$!"

          function offloadNode() {
              FQDN=$(hostname -f)
              echo "disconnecting node '$FQDN'"
              baseUrl=https://${FQDN}:{{ .Values.properties.httpsPort }}

              keystore=${NIFI_HOME}/config-data/certs/keystore.jks
              keystorePasswd=$(jq -r .keyStorePassword ${NIFI_HOME}/config-data/certs/config.json)
              keyPasswd=$(jq -r .keyPassword ${NIFI_HOME}/config-data/certs/config.json)
              truststore=${NIFI_HOME}/config-data/certs/truststore.jks
              truststorePasswd=$(jq -r .trustStorePassword ${NIFI_HOME}/config-data/certs/config.json)

              secureArgs=" --truststore ${truststore} --truststoreType JKS --truststorePasswd ${truststorePasswd} --keystore ${keystore} --keystoreType JKS --keystorePasswd ${keystorePasswd} --proxiedEntity "{{ .Values.auth.admin }}""

              echo baseUrl ${baseUrl}
              echo "gracefully disconnecting node '$FQDN' from cluster"
              ${NIFI_TOOLKIT_HOME}/bin/cli.sh nifi get-nodes -ot json -u ${baseUrl} ${secureArgs} > nodes.json
              nnid=$(jq --arg FQDN "$FQDN" '.cluster.nodes[] | select(.address==$FQDN) | .nodeId' nodes.json)
              echo "disconnecting node ${nnid}"
              ${NIFI_TOOLKIT_HOME}/bin/cli.sh nifi disconnect-node -nnid $nnid -u ${baseUrl} ${secureArgs}
              echo ""
              echo "get a connected node"
              connectedNode=$(jq -r 'first(.cluster.nodes|=sort_by(.address)| .cluster.nodes[] | select(.status=="CONNECTED")) | .address' nodes.json)
              baseUrl=https://${connectedNode}:{{ .Values.properties.httpsPort }}
              echo baseUrl ${baseUrl}
              echo ""
              echo "wait until node has state 'DISCONNECTED'"
              while [[ "${node_state}" != "DISCONNECTED" ]]; do
                  sleep 1
                  ${NIFI_TOOLKIT_HOME}/bin/cli.sh nifi get-nodes -ot json -u ${baseUrl} ${secureArgs} > nodes.json
                  node_state=$(jq -r --arg FQDN "$FQDN" '.cluster.nodes[] | select(.address==$FQDN) | .status' nodes.json)
                  echo "state is '${node_state}'"
              done
              echo ""
              echo "node '${nnid}' was disconnected"
              echo "offloading node"
              ${NIFI_TOOLKIT_HOME}/bin/cli.sh nifi offload-node -nnid $nnid -u ${baseUrl} ${secureArgs}
              echo ""
              echo "wait until node has state 'OFFLOADED'"
              while [[ "${node_state}" != "OFFLOADED" ]]; do
                  sleep 1
                  ${NIFI_TOOLKIT_HOME}/bin/cli.sh nifi get-nodes -ot json -u ${baseUrl} ${secureArgs} > nodes.json
                  node_state=$(jq -r --arg FQDN "$FQDN" '.cluster.nodes[] | select(.address==$FQDN) | .status' nodes.json)
                  echo "state is '${node_state}'"
              done
          }

          deleteNode() {
              echo "deleting node"
              ${NIFI_TOOLKIT_HOME}/bin/cli.sh nifi delete-node -nnid ${nnid} -u ${baseUrl} ${secureArgs}
              echo "node deleted"
          }

          trap 'echo Received trapped signal, beginning shutdown...;offloadNode;./bin/nifi.sh stop;deleteNode;exit 0;' TERM HUP INT;
          trap ":" EXIT

          echo NiFi running with PID ${nifi_pid}.
          wait ${nifi_pid}
        {{- if .Values.auth.ldap.enabled }}
          /opt/nifi/nifi-toolkit-current/bin/tls-toolkit.sh standalone -n '{{.Release.Name}}-nifi-0.{{.Release.Name}}-nifi-headless.{{.Release.Namespace}}.svc.cluster.local' -C '{{.Values.auth.ldap.admin}}' -o '/opt/nifi/nifi-current/conf/' -P {{.Values.auth.SSL.truststorePasswd}}  -S {{.Values.auth.SSL.keystorePasswd}}  --nifiPropertiesFile /opt/nifi/nifi-current/conf/nifi.properties
          exec bin/nifi.sh run
        {{- end }}
{{- end }}