<source>
  @type secure_forward
  @id mux-secure-forward
  @label @MUX
  port "#{ENV['FORWARD_LISTEN_PORT'] || '24284'}"
  # bind 0.0.0.0 # default
  log_level "#{ENV['FORWARD_INPUT_LOG_LEVEL'] || ENV['LOG_LEVEL'] || 'warn'}"
  self_hostname "#{ENV['FORWARD_LISTEN_HOST'] || 'mux.example.com'}"
  shared_key    "#{File.open('/etc/fluent/muxkeys/shared_key') do |f| f.readline end.rstrip}"

  secure yes

  cert_path        /etc/fluent/muxkeys/cert
  private_key_path /etc/fluent/muxkeys/key
  private_key_passphrase not_used_key_is_unencrypted
</source>

<label @MUX>
  # these are usually coming as raw logs from an openshift fluentd acting
  # as a collector only
  # specifically - an openshift fluentd collector configured to use secure_forward as
  # described in https://github.com/openshift/origin-aggregated-logging/pull/264/files

  # raw record from fluentd MUX_CLIENT_MODE=minimal - redirect to normal processing
  <match journal>
    @type relabel
    @label @INGRESS
  </match>

  # mux hardcodes USE_JOURNAL=true to force the k8s-meta plugin to look for
  # CONTAINER_NAME instead of the tag to extract the k8s metadata - logs coming
  # from a fluentd using json-file will usually not have this field, so add it
  <filter kubernetes.var.log.containers.**>
    @type record_transformer
    enable_ruby
    <record>
      CONTAINER_NAME ${record['CONTAINER_NAME'] || (md = /var\.log\.containers\.(?<pod_name>[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)_(?<namespace>[^_]+)_(?<container_name>.+)-(?<docker_id>[a-z0-9]+)\.log(?:\.raw)?$/.match(tag); "k8s_" + md["container_name"] + ".0_" + md["pod_name"] + "_" + md["namespace"] + "_0_01234567")}
      CONTAINER_ID_FULL ${record['CONTAINER_ID_FULL'] || (md = /var\.log\.containers\.(?<pod_name>[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)_(?<namespace>[^_]+)_(?<container_name>.+)-(?<docker_id>[a-z0-9]+)\.log(?:\.raw)?$/.match(tag); md["docker_id"])}
    </record>
  </filter>

  # raw record from fluentd MUX_CLIENT_MODE=minimal - redirect to normal processing
  <match **.raw>
    @type relabel
    @label @INGRESS
  </match>

  # If this record has already been processed by fluentd e.g. in MUX_CLIENT_MODE=maximal
  # then tag it so that it will be processed by the k8s plugin (if kubernetes.**)
  # and have an index name created for it, but it will not be processed in any other way.
  # Assume that if the record has the @timestamp field then it has already been
  # processed, and tag it with ".mux".  Otherwise, assume it is a raw record, tag
  # it with ".raw", and redirect to INGRESS processing.
  <match system.var.log.messages** kubernetes.** journal.container** journal.system** audit.log**>
    @type rewrite_tag_filter
    @label @INGRESS
    rewriterule1 CONTAINER_NAME ^k8s_kube-eventrouter ${tag}.raw
    rewriterule2 @timestamp .+ ${tag}.mux
    rewriterule3 @timestamp !.+ ${tag}.raw
  </match>

  # If we got here, then these are external logs.  The namespace to use
  # will be encoded in either the namespace_name field, or in the tag.  The filter below
  # will set the values/tag needed in filter-pre-mux.conf.
  # If the record already has k8s metadata, there will be a kubernetes.namespace_id
  # field.  If not, then the record will be tagged that k8s metadata processing is needed.
  # This filter will also ensure that the record has some sort of time field.
  <filter **>
    @type record_transformer
    enable_ruby
    <record>
      mux_namespace_name ${record['namespace_name'] || (tag_parts[0] == "project" && tag_parts[1]) || ENV["MUX_UNDEFINED_NAMESPACE"] || ".orphaned"}
      mux_need_k8s_meta ${(record['namespace_uuid'] || record.fetch('kubernetes', Hash.new)['namespace_id'].nil?) ? "true" : "false"}
      kubernetes {"namespace_name":"${record['namespace_name'] || (tag_parts[0] == 'project' && tag_parts[1]) || ENV['MUX_UNDEFINED_NAMESPACE'] || '.orphaned'}","namespace_id":"${record['namespace_uuid'] || record.fetch('kubernetes', Hash.new)['namespace_id'] || 'orphaned'}"}
      time ${record['@timestamp'] || record['time'] || time.utc.to_datetime.rfc3339(6)}
    </record>
  </filter>

  # if the record already has k8s metadata (e.g. record forwarded from another
  # openshift or mux) then tag so that k8s meta will be skipped
  # the `mux` tag will skip all operation and app specific filtering
  # the kubernetes.mux.** tag will match the k8s-meta but no other ops and apps filtering
  # the kubernetes.mux.** tag will be processed by filter-pre-mux.conf
  # This tag was chosen because it will be processed by the k8s meta plugin, but will
  # bypass all other filtering.
  <match **>
    @type rewrite_tag_filter
    @label @INGRESS
    rewriterule1 mux_need_k8s_meta ^false$ mux
    rewriterule2 mux_namespace_name "#{ENV['MUX_UNDEFINED_NAMESPACE']}" mux
    rewriterule3 mux_namespace_name .orphaned mux
    rewriterule4 mux_namespace_name (.+) kubernetes.var.log.containers.mux-mux.mux-mux_$1_mux-0123456789012345678901234567890123456789012345678901234567890123.log.mux
  </match>
</label>
