# use this for backwards compatability
# fullnameOverride: ""

eck-operator:
  enabled: false
  installCRDs: false
  tolerations:
  - key: node-role.kubernetes.io/master
    effect: NoSchedule
  nodeSelector:
    node-role.kubernetes.io/master: ""

# Version for ElasticSearch and Kibana have to match so we define it at top-level
version: 7.13.4

elastic_password: "" # super_secret_elastic_password

es:
  nodeSets: []
  #- count: 2
  #  storage:
  #    size: 16Gi
  #    class: local-sc-xfs
  #  zone: us-west-2a
  #  nodeAffinity:
  #    key: node label name
  #    value: node label value
  s3Snapshot:
    enabled: false
    iamrole: "" # INSERT_CLOUDFORMATION_OUTPUT_ElasticSearchSnapshots

  prometheus: false

kibana:
  count: 1
  #servicename: kibana.example.com
  #nodeAffinity:
  #  key: node label name
  #  value: node label value
  istio:
    enabled: false
    gateway: "istio-system/ingressgateway"
    url: "" # kibana.example.com

fluentd:
  enabled: false
  image:
    repository: fluent/fluentd-kubernetes-daemonset
    tag: v1-debian-elasticsearch
  istio:
    enabled: false

  kind: Deployment
  replicaCount: 1

  #plugins:
  #- fluent-plugin-s3

  service:
    ports:
    - name: tcp-forward
      protocol: TCP
      containerPort: 24224
    - name: http-fluentd
      protocol: TCP
      containerPort: 9880

  metrics:
    serviceMonitor:
      enabled: false
      additionalLabels:
        release: metrics

  dashboards:
    enabled: false

  # No need for docker nor /var/log
  volumes:
  - name: etcfluentd-main
    configMap:
      name: fluentd-main
      defaultMode: 0777
  - name: etcfluentd-config
    configMap:
      name: fluentd-config
      defaultMode: 0777
  volumeMounts:
  - name: etcfluentd-main
    mountPath: /etc/fluent
  - name: etcfluentd-config
    mountPath: /etc/fluent/config.d/

  resources:
    requests:
      cpu: 200m
      memory: 256Mi
    limits:
      memory: 512Mi

  output:
    # Default should be "logging-kubezero-logging-es-http" if fullnameOverride is NOT used
    host: logging-es-http

  shared_key: "cloudbender"

  #  OUTPUT_USER: elastic
  #  OUTPUT_SSL_VERIFY: "false"

  env:
  - name: "FLUENTD_CONF"
    value: "../../etc/fluent/fluent.conf"
  # Same here the secret names change if fullnameOverride is not used !!
  - name: OUTPUT_PASSWORD
    valueFrom:
      secretKeyRef:
        name: logging-es-elastic-user
        key: elastic

  fileConfigs:
    00_system.conf: |-
      <system>
        root_dir /var/log/fluentd
        log_level info
        ignore_repeated_log_interval 60s
        ignore_same_log_interval 60s
        workers 2
      </system>
    01_sources.conf: |-
      <source>
        @type http
        @label @KUBERNETES
        port 9880
        bind 0.0.0.0
        keepalive_timeout 30
      </source>

      <source>
        @type forward
        @label @KUBERNETES
        port 24224
        bind 0.0.0.0
        # skip_invalid_event true
        send_keepalive_packet true
        <security>
          self_hostname "#{ENV['HOSTNAME']}"
          shared_key {{ .Values.shared_key }}
        </security>
      </source>

    02_filters.conf: |-
      <label @KUBERNETES>
        # prevent log feedback loops eg. ES has issues etc.
        # discard logs from our own pods
        <match kube.logging.fluentd>
          @type relabel
          @label @FLUENT_LOG
        </match>

        # Exclude current fluent-bit multiline noise
        <filter kube.logging.fluent-bit>
          @type grep
          <exclude>
            key log
            pattern /could not append content to multiline context/
          </exclude>
        </filter>

        <match **>
          @type relabel
          @label @DISPATCH
        </match>
      </label>

    04_outputs.conf: |-
      <label @OUTPUT>
        <match **>
          @id out_es
          @type elasticsearch
          # @log_level debug
          include_tag_key true
          id_key id
          remove_keys id

          # KubeZero pipeline incl. GeoIP etc.
          pipeline fluentd

          hosts "{{ .Values.output.host }}"
          port 9200
          scheme http
          user elastic
          password "#{ENV['OUTPUT_PASSWORD']}"

          log_es_400_reason
          logstash_format true
          reconnect_on_error true
          reload_on_failure true
          request_timeout 60s
          suppress_type_name true
          slow_flush_log_threshold 55.0

          # Retry failed bulk requests
          # https://github.com/uken/fluent-plugin-elasticsearch#unrecoverable-error-types
          unrecoverable_error_types ["out_of_memory_error"]
          bulk_message_request_threshold 2097152

          <buffer>
            @type file

            flush_mode interval
            flush_thread_count 1
            flush_interval 30s

            chunk_limit_size 8MB
            total_limit_size 2GB

            flush_at_shutdown true
            retry_type exponential_backoff
            retry_timeout 6h
            overflow_action drop_oldest_chunk
            disable_chunk_backup true
          </buffer>
        </match>
      </label>

fluent-bit:
  enabled: false

  image:
    #repository: public.ecr.aws/zero-downtime/fluent-bit
    tag: 1.8.3

  serviceMonitor:
    enabled: false
    selector:
      release: metrics

  tolerations:
  - key: node-role.kubernetes.io/master
    effect: NoSchedule
  - key: kubezero-workergroup
    effect: NoSchedule
    operator: Exists

  resources:
    requests:
      cpu: 20m
      memory: 32Mi
    limits:
      memory: 64Mi

  config:
    output:
      host: logging-fluentd
      sharedKey: cloudbender
      tls: false

    input:
      memBufLimit: 4MB
      refreshInterval: 10

    logLevel: info
    flushInterval: 5

    #extraRecords:
    #  source.clustername: MyKubeCluster

    service: |
      [SERVICE]
          Flush {{ .Values.config.flushInterval }}
          Daemon Off
          Log_Level {{ .Values.config.logLevel }}
          Parsers_File parsers.conf
          Parsers_File custom_parsers.conf
          HTTP_Server On
          HTTP_Listen 0.0.0.0
          HTTP_Port {{ .Values.service.port }}
    inputs: |
      [INPUT]
          Name tail
          Path /var/log/containers/*.log
          multiline.parser cri
          Tag cri.*
          Skip_Long_Lines On
          DB /var/log/flb_kube.db
          DB.Sync Normal
          DB.locking true
          # Buffer_Max_Size 1M
          {{- with .Values.config.input }}
          Mem_Buf_Limit {{ default "4MB" .memBufLimit }}
          Refresh_Interval {{ default 10 .refreshInterval }}
          {{- end }}

    filters: |
      [FILTER]
          Name parser
          Match cri.*
          Parser cri-log
          Key_Name log

      [FILTER]
          Name kubernetes
          Match cri.*
          Merge_Log On
          Merge_Log_Key kube
          Kube_Tag_Prefix cri.var.log.containers.
          Keep_Log Off
          K8S-Logging.Parser Off
          K8S-Logging.Exclude Off
          Kube_Meta_Cache_TTL 3600s
          Buffer_Size 0
          #Use_Kubelet true

      {{- if index .Values "config" "extraRecords" }}

      [FILTER]
          Name record_modifier
          Match cri.*
          {{- range $k,$v := index .Values "config" "extraRecords" }}
          Record {{ $k }} {{ $v }}
          {{- end }}
      {{- end }}

      [FILTER]
          Name rewrite_tag
          Match cri.*
          Emitter_Name kube_tag_rewriter
          Rule $kubernetes['pod_id'] .* kube.$kubernetes['namespace_name'].$kubernetes['container_name'] false

      [FILTER]
          Name    lua
          Match   kube.*
          script  /fluent-bit/scripts/kubezero.lua
          call    nest_k8s_ns

    outputs: |
      [OUTPUT]
          Match *
          Name forward
          Host {{ .Values.config.output.host }}
          Port 24224
          Shared_Key {{ .Values.config.output.sharedKey }}
          tls {{ ternary "on" "off" .Values.config.output.tls }}
          Send_options true
          Require_ack_response true

    customParsers: |
      [PARSER]
          Name cri-log
          Format regex
          Regex ^(?<time>.+) (?<stream>stdout|stderr) (?<logtag>F|P) (?<log>.*)$
          Time_Key    time
          Time_Format %Y-%m-%dT%H:%M:%S.%L%z

  luaScripts:
    kubezero.lua: |
      function nest_k8s_ns(tag, timestamp, record)
          if not record['kubernetes']['namespace_name'] then
              return 0, 0, 0
          end
          new_record = {}
          for key, val in pairs(record) do
              if key == 'kube' then
                  new_record[key] = {}
                  new_record[key][record['kubernetes']['namespace_name']] = record[key]
              else
                  new_record[key] = record[key]
              end
          end
          return 1, timestamp, new_record
      end

  daemonSetVolumes:
  - name: varlog
    hostPath:
      path: /var/log
  - name: etcmachineid
    hostPath:
      path: /etc/machine-id
      type: File

  daemonSetVolumeMounts:
  - name: varlog
    mountPath: /var/log
  - name: etcmachineid
    mountPath: /etc/machine-id
    readOnly: true
