apiVersion: v1
kind: Namespace
metadata:
  labels:
    app: collectorforkubernetes
  name: collectorforkubernetes
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: configurations.collectord.io
spec:
  group: collectord.io
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              additionalProperties: true
            force:
              type: boolean
  scope: Cluster
  names:
    plural: configurations
    singular: configuration
    kind: Configuration
---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app: collectorforkubernetes
  name: collectorforkubernetes
  namespace: collectorforkubernetes
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: collectorforkubernetes-critical
value: 1000000000
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    app: collectorforkubernetes
  name: collectorforkubernetes
rules:
- apiGroups: ['extensions']
  resources: ['podsecuritypolicies']
  verbs:     ['use']
  resourceNames:
  - privileged
- apiGroups:
  - ""
  - apps
  - batch
  - extensions
  - rbac.authorization.k8s.io
  - collectord.io
  resources:
  - alertmanagers
  - cronjobs
  - daemonsets
  - deployments
  - endpoints
  - events
  - jobs
  - namespaces
  - nodes
  - nodes/metrics
  - nodes/proxy
  - pods
  - replicasets
  - replicationcontrollers
  - scheduledjobs
  - services
  - statefulsets
  - persistentvolumeclaims
  - configurations
  - resourcequotas
  - clusterroles
  - secrets
  - configmaps
  verbs:
  - get
  - list
  - watch
- nonResourceURLs:
  - /metrics
  verbs:
  - get
  apiGroups: []
  resources: []
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    app: collectorforkubernetes
  name: collectorforkubernetes
  namespace: collectorforkubernetes
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: collectorforkubernetes
subjects:
  - kind: ServiceAccount
    name: collectorforkubernetes
    namespace: collectorforkubernetes
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: collectorforkubernetes-elasticsearch
  namespace: collectorforkubernetes
  labels:
    app: collectorforkubernetes-elasticsearch
data:
  001-general.conf: |
    # The general configuration is used for all deployments
    #
    # Run collector with the flag -conf and specify location of the configuration files.
    #
    # You can override all the values using environment variables with the format like
    #   COLLECTOR__<ANYNAME>=<section>__<key>=<value>
    # As an example you can set dataPath in [general] section as
    #   COLLECTOR__DATAPATH=general__dataPath=C:\\some\\path\\data.db
    # This parameter can be configured using -env-override, set it to empty string to disable this feature

    [general]
    # Please review license https://www.outcoldsolutions.com/docs/license-agreement/
    # and accept license by changing the value to *true*
    acceptLicense = false

    # Location for the database
    # Collector stores positions of the files and internal state
    dataPath = ./data/

    # log level (accepted values are trace, debug, info, warn, error, fatal)
    logLevel = info

    # http server gives access to two endpoints
    # /healthz
    # /metrics/json
    # /metrics/prometheus
    httpServerBinding =

    # telemetry report endpoint, set it to empty string to disable telemetry
    telemetryEndpoint = https://license.outcold.solutions/telemetry/

    # license check endpoint
    licenseEndpoint = https://license.outcold.solutions/license/

    # license server through proxy
    licenseServerProxyUrl =

    # authentication with basic authorization (user:password)
    licenseServerProxyBasicAuth =

    # license key
    license =

    # Environment variable $KUBERNETES_NODENAME is used by default to setup hostname
    # Use value below to override specific name
    # hostname = ${KUBERNETES_NODENAME}.second

    # Default output for events, logs and metrics
    # valid values: elasticsearch and devnull
    # Use devnull by default if you don't want to redirect data
    defaultOutput = elasticsearch

    # Default buffer size for file input
    fileInputBufferSize = 256b

    # Maximum size of one line the file reader can read
    fileInputLineMaxSize = 1mb

    # Include custom fields to attach to every event, in example below every event sent to elasticsearch will have
    # indexed field my_environment=dev. Fields names should match to ^[a-z][_a-z0-9\.]*$
    # Better way to configure that is to specify labels for Kubernetes Nodes.
    # ; fields.my_environment = dev
    # Identify the cluster if you are planning to monitor multiple clusters
    # For ElasticSearch look at the ECS (Elastic Common Schema) documentation https://www.elastic.co/guide/en/ecs/current/ecs-field-reference.html
    fields.ecs.version = 8.0.0

    fields.orchestrator.cluster.name = -
    fields.orchestrator.type = kubernetes

    fields.agent.type = collectord
    fields.agent.version = ${COLLECTORD_VERSION}
    fields.agent.ephemeral_id = ${COLLECTORD_INSTANCE_RUNTIME_ID}
    fields.agent.id = ${COLLECTORD_INSTANCE_ID}
    fields.agent.name = ${KUBERNETES_NODENAME}

    fields.host.name = ${KUBERNETES_NODENAME}
    fields.host.hostname = ${KUBERNETES_NODENAME}
    fields.host.architecture = ${COLLECTORD_ARCH}

    # Include EC2 Metadata (see list of possible fields https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)
    # Should be in format ec2Metadata.{desired_field_name} = {url path to read the value}
    # ec2Metadata.cloud.instance.id = /latest/meta-data/instance-id
    # ec2Metadata.cloud.machine.type = /latest/meta-data/instance-type

    # subdomain for the annotations added to the pods, workloads, namespaces or containers, like elasticsearch.collectord.io/..
    annotationsSubdomain = elasticsearch

    # configure global thruput per second for forwarded logs (metrics are not included)
    # for example if you set `thruputPerSecond = 512Kb`, that will limit amount of logs forwarded
    # from the single Collectord instance to 512Kb per second.
    # You can configure thruput individually for the logs (including specific for container logs) below
    thruputPerSecond =
    ; thruputPerSecond = 512Kb

    # Configure events that are too old to be forwarded, for example 168h (7 days) - that will drop all events
    # older than 7 days
    tooOldEvents =

    # Configure events that are too new to be forwarded, for example 1h - that will drop all events that are 1h in future
    tooNewEvents =

    [license.client]
    # point to the license located on the HTTP web server, or a hosted by the Collectord running as license server
    url =
    # basic authentication for the HTTP server
    basicAuth =
    # if SSL, ignore the certificate verification
    insecure = false
    # CA Path for the Server certificate
    capath =
    # CA Name fot the Server certificate
    caname =
    # license server through proxy
    proxyUrl =
    # authentication with basic authorization (user:password)
    proxyBasicAuth =

    # connection to kubernetes api
    [general.kubernetes]

    # Override service URL for Kubernetes (default is ${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT})
    serviceURL =

    # Environment variable $KUBERNETES_NODENAME is used by default to setup nodeName
    # Use it only when you need to override it
    nodeName =

    # Configuration to access the API server,
    # see https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/#accessing-the-api-from-a-pod
    # for details
    tokenPath = /var/run/secrets/kubernetes.io/serviceaccount/token
    certPath = /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

    # Default timeout for http responses. The streaming/watch requests depend on this timeout.
    timeout = 30m

    # How long to keep the cache for the recent calls to API server (to limit number of calls when collector discovers new pods)
    metadataTTL = 30s

    # path to the kubelet root location (use it to discover application logs for emptyDir)
    # the expected format is `pods/{pod-id}/volumes/kubernetes.io~empty-dir/{volume-name}/_data/`
    volumesRootDir = /rootfs/var/lib/kubelet/

    # You can attach annotations as a metadata, using the format
    #   includeAnnotations.{key} = {regexp}
    # For example if you want to include all annotations that starts with `prometheus.io` or `example.com` you can include
    # the following format:
    #   includeAnnotations.1 = ^prometheus\.io.*
    #   includeAnnotations.2 = ^example\.com.*

    # watch for changes (annotations) in the objects
    watch.namespaces = v1/namespace
    watch.deployments = apps/v1/deployment
    watch.configurations = collectord.io/v1/configuration

    # Collectord can review the assigned ClusterRole and traverse metadata for the Pods only for the Owner objects
    # that are defined in the ClusterRole, ignoring anything else, it does not have access to.
    # This way Collectord does not generate 403 requests on API Server
    clusterRole = collectorforkubernetes

    # Alternative of telling Collectord about the ClusterRole is to manually list the objects.
    # You can define which objects Collectord should traverse when it sees Owners.
    ; traverseOwnership.namespaces = v1/namespace


    # ElasticSearch output
    [output.elasticsearch]

    # Default data stream name
    dataStream = logs-collectord-{{agent.version}}
    dataStreamFailedEvents = logs-collectord-failed-{{agent.version}}

    # ElasticSearch Scheme Host and Port
    host =

    # You can specify multiple hosts with
    #
    # hosts.0 = https://es0:9200
    # hosts.1 = https://es1:9200
    # hosts.2 = https://es2:9200

    # Specify how Hosts should be picked up (in case if multiple is used)
    # * random - choose random url on first selection and after each failure (connection or HTTP status code >= 500)
    # * round-robin - choose url starting from first one and bump on each failure (connection or HTTP status code >= 500)
    # * random-with-round-robin - choose random url on first selection and after that in round-robin on each
    #                             failure (connection or HTTP status code >= 500)
    hostSelection = random-with-round-robin

    # Configuration for basic authorization
    authorizationBasicUsername =
    authorizationBasicPassword =

    # additional headers
    headers.Content-Type = application/json
    headers.Accept = application/json

    # Allow invalid SSL server certificate
    insecure = false

    # Path to CA certificate
    caPath =

    # CA Name to verify
    caName =

    # path for client certificate (if required)
    clientCertPath =

    # path for a client key (if required)
    clientKeyPath =

    # Events are batched with the maximum size set by batchSize and staying in pipeline for not longer
    # than set by frequency
    frequency = 5s
    batchSize = 768K
    # limit by the number of events (0 value has no limit on the number of events)
    events = 50

    # elasticsearch through proxy
    proxyUrl =

    # authentication with basic authorization (user:password)
    proxyBasicAuth =

    # Timeout specifies a time limit for requests made by collectord.
    # The timeout includes connection time, any
    # redirects, and reading the response body.
    timeout = 30s

    # gzip compression level (nocompression, default, 1...9)
    compressionLevel = default

    # number of dedicated elasticsearch output threads (to increase throughput above 4k events per second)
    threads = 2
    # Default algorithm between threads is roundrobin, but you can change it to weighted
    threadsAlgorithm = roundrobin

    # Submit objects to elasticsearch
    put._ilm/policy/logs-collectord = /config/es-default-index-lifecycle-management-policy.json
    put._index_template/logs-collectord-${COLLECTORD_VERSION} = /config/es-default-index-template.json
    put._index_template/logs-collectord-failed-${COLLECTORD_VERSION} = /config/es-failed-index-template.json

    # Dedicated queue size for the output, default is 1024, larger queue sizes will require more memory,
    # but will allow to handle more events in case of network issues
    queueSize = 1024

    # Configure multiple outputs
    #    [output.elasticsearch::app1]
    #    host = http://esapp1:9200

  002-daemonset.conf: |
    # DaemonSet configuration is used for Nodes and Masters.

    // connection to CRIO
    [general.cri-o]

    # url for CRIO API, only unix socket is supported
    url = unix:///rootfs/var/run/crio/crio.sock

    # Timeout for http responses to docker client. The streaming requests depend on this timeout.
    timeout = 1m

    [general.containerd]

    runtimePath = /rootfs/var/run/containerd
    namespace = k8s.io

    # Container Log files
    [input.files]

    # disable container logs monitoring
    disabled = false

    # root location of docker log files
    # logs are expected in standard docker format like {containerID}/{containerID}-json.log
    # rotated files
    path = /rootfs/var/lib/docker/containers/
    # root location of CRI-O (including Containerd) files
    # logs are expected in Kubernetes format, like {podID}/{containerName}/0.log
    crioPath = /rootfs/var/log/pods/

    # files are read using polling schema, when reach the EOF how often to check if files got updated
    pollingInterval = 250ms

    # how often to look for the new files under logs path
    walkingInterval = 5s

    # override type
    type = container

    # override datastream
    elasticsearch.datastream =

    # docker splits events when they are larger than 10-100k (depends on the docker version)
    # we join them together by default and forward to elasticsearch as one event
    joinPartialEvents = true

    # In case if your containers report messages with terminal colors or other escape sequences
    # you can enable strip for all the containers in one place.
    # Better is to enable it only for required container with the label collectord.io/strip-terminal-escape-sequences=true
    stripTerminalEscapeSequences = false
    # Regexp used for stripping terminal colors, it does not stip all the escape sequences
    # Read http://man7.org/linux/man-pages/man4/console_codes.4.html for more information
    stripTerminalEscapeSequencesRegex = (\x1b\[\d{1,3}(;\d{1,3})*m)|(\x07)|(\x1b]\d+(\s\d)?;[^\x07]+\x07)|(.*\x1b\[K)

    # sample output (-1 does not sample, 20 - only 20% of the logs should be forwarded)
    samplingPercent = -1

    # sampling key for hash based sampling (should be regexp with the named match pattern `key`)
    samplingKey =

    # set output (elasticsearch or devnull, default is [general]defaultOutput)
    output =

    # configure default thruput per second for each container log
    # for example if you set `thruputPerSecond = 128Kb`, that will limit amount of logs forwarded
    # from the single container to 128Kb per second.
    thruputPerSecond =

    # Configure events that are too old to be forwarded, for example 168h (7 days) - that will drop all events
    # older than 7 days
    tooOldEvents =

    # Configure events that are too new to be forwarded, for example 1h - that will drop all events that are 1h in future
    tooNewEvents =


    # Application Logs
    [input.app_logs]

    # disable container application logs monitoring
    disabled = false

    # root location of mounts (applies to hostPath mounts only), if the hostPath differs inside container from the path on host
    root = /rootfs/

    # how often to review list of available volumes
    syncInterval = 5s

    # glob matching pattern for log files
    glob = *.log*

    # files are read using polling schema, when reach the EOF how often to check if files got updated
    pollingInterval = 250ms

    # how often to look for the new files under logs path
    walkingInterval = 5s

    # include verbose fields in events (file offset)
    verboseFields = false

    # override type
    type = container.file

    # override datastream
    elasticsearch.datastream =

    # we split files using new line character, with this configuration you can specify what defines the new event
    # after new line
    eventPatternRegex = ^[^\s]
    # Maximum interval of messages in pipeline
    eventPatternMaxInterval = 100ms
    # Maximum time to wait for the messages in pipeline
    eventPatternMaxWait = 1s
    # Maximum message size
    eventPatternMaxSize = 1MB

    # sample output (-1 does not sample, 20 - only 20% of the logs should be forwarded)
    samplingPercent = -1

    # sampling key for hash based sampling (should be regexp with the named match pattern `key`)
    samplingKey =

    # set output (elasticsearch or devnull, default is [general]defaultOutput)
    output =

    # configure default thruput per second for for each container log
    # for example if you set `thruputPerSecond = 128Kb`, that will limit amount of logs forwarded
    # from the single container to 128Kb per second.
    thruputPerSecond =

    # Configure events that are too old to be forwarded, for example 168h (7 days) - that will drop all events
    # older than 7 days
    tooOldEvents =

    # Configure events that are too new to be forwarded, for example 1h - that will drop all events that are 1h in future
    tooNewEvents =

    # Configure how long Collectord should keep the file descriptors open for files, that has not been forwarded yet
    # When using PVC, and if pipeline is lagging behind, Collectord holding open fd for files, can cause long termination
    # of pods, as kubelet cannot unmount the PVC volume from the system
    maxHoldAfterClose = 1800s


    # Host logs. Input syslog(.\d+)? files
    [input.files::syslog]

    # disable host level logs
    disabled = false

    # root location of docker files
    path = /rootfs/var/log/

    # regex matching pattern
    match = ^(syslog|messages)(.\d+)?$

    # limit search only on one level
    recursive = false

    # files are read using polling schema, when reach the EOF how often to check if files got updated
    pollingInterval = 250ms

    # how often o look for the new files under logs path
    walkingInterval = 5s

    # include verbose fields in events (file offset)
    verboseFields = false

    # override type
    type = file

    # override datastream
    elasticsearch.datastream =

    # field extraction
    extraction = ^(?P<timestamp>[A-Za-z]+\s+\d+\s\d+:\d+:\d+)\s(?P<log__syslog__hostname>[^\s]+)\s(?P<log__syslog__appname>[^:\[]+)(\[(?P<log__syslog__procid>\d+)\])?: (.+)$
    # extractionMessageField =

    # timestamp field
    timestampField = timestamp

    # format for timestamp
    # the layout defines the format by showing how the reference time, defined to be `Mon Jan 2 15:04:05 -0700 MST 2006`
    timestampFormat = Jan 2 15:04:05

    # Adjust date, if month/day aren't set in format
    timestampSetMonth = false
    timestampSetDay = false

    # timestamp location (if not defined by format)
    timestampLocation = Local

    # sample output (-1 does not sample, 20 - only 20% of the logs should be forwarded)
    samplingPercent = -1

    # sampling key for hash based sampling (should be regexp with the named match pattern `key`)
    samplingKey =

    # set output (elasticsearch or devnull, default is [general]defaultOutput)
    output =

    # configure default thruput per second for this files group
    # for example if you set `thruputPerSecond = 128Kb`, that will limit amount of logs forwarded
    # from the files in this group to 128Kb per second.
    thruputPerSecond =

    # Configure events that are too old to be forwarded, for example 168h (7 days) - that will drop all events
    # older than 7 days
    tooOldEvents =

    # Configure events that are too new to be forwarded, for example 1h - that will drop all events that are 1h in future
    tooNewEvents =

    # by default every new event should start from not space symbol
    eventPattern = ^[^\s]

    # Blacklisting and whitelisting the logs
    # whitelist.0 = ^regexp$
    # blacklist.0 = ^regexp$


    # Host logs. Input all *.log(.\d+)? files
    [input.files::logs]

    # disable host level logs
    disabled = false

    # root location of log files
    path = /rootfs/var/log/

    # regex matching pattern
    match = ^(([\w\-.]+\.log(.[\d\-]+)?)|(docker))$

    # files are read using polling schema, when reach the EOF how often to check if files got updated
    pollingInterval = 250ms

    # how often o look for the new files under logs path
    walkingInterval = 5s

    # include verbose fields in events (file offset)
    verboseFields = false

    # override type
    type = file

    # override datastream
    elasticsearch.datastream =

    # field extraction
    extraction =

    # timestamp field
    timestampField =

    # format for timestamp
    # the layout defines the format by showing how the reference time, defined to be `Mon Jan 2 15:04:05 -0700 MST 2006`
    timestampFormat =

    # timestamp location (if not defined by format)
    timestampLocation =

    # sample output (-1 does not sample, 20 - only 20% of the logs should be forwarded)
    samplingPercent = -1

    # sampling key for hash based sampling (should be regexp with the named match pattern `key`)
    samplingKey =

    # set output (elasticsearch or devnull, default is [general]defaultOutput)
    output =

    # configure default thruput per second for this files group
    # for example if you set `thruputPerSecond = 128Kb`, that will limit amount of logs forwarded
    # from the files in this group to 128Kb per second.
    thruputPerSecond =

    # Configure events that are too old to be forwarded, for example 168h (7 days) - that will drop all events
    # older than 7 days
    tooOldEvents =

    # Configure events that are too new to be forwarded, for example 1h - that will drop all events that are 1h in future
    tooNewEvents =

    # by default every new event should start from not space symbol
    eventPattern = ^[^\s]

    # Blacklisting and whitelisting the logs
    # whitelist.0 = ^regexp$
    # blacklist.0 = ^regexp$


    [input.journald]

    # disable host level logs
    disabled = false

    # root location of log files
    path.persistent = /rootfs/var/log/journal/
    path.volatile = /rootfs/run/log/journal/

    # when reach end of journald, how often to pull
    pollingInterval = 250ms

    # if you don't want to forward journald from the beginning,
    # set the oldest event in relative value, like -14h or -30m or -30s (h/m/s supported)
    startFromRel =

    # override type
    type = journald

    # override datastream
    elasticsearch.datastream =

    # sample output (-1 does not sample, 20 - only 20% of the logs should be forwarded)
    samplingPercent = -1

    # sampling key (should be regexp with the named match pattern `key`)
    samplingKey =

    # how often to reopen the journald to free old files
    reopenInterval = 1h

    # set output (elasticsearch or devnull, default is [general]defaultOutput)
    output =

    # configure default thruput per second for journald
    # for example if you set `thruputPerSecond = 128Kb`, that will limit amount of logs forwarded
    # from the journald to 128Kb per second.
    thruputPerSecond =

    # Configure events that are too old to be forwarded, for example 168h (7 days) - that will drop all events
    # older than 7 days
    tooOldEvents =

    # Configure events that are too new to be forwarded, for example 1h - that will drop all events that are 1h in future
    tooNewEvents =

    # by default every new event should start from not space symbol
    eventPattern = ^[^\s]

    # Blacklisting and whitelisting the logs
    # whitelist.0 = ^regexp$
    # blacklist.0 = ^regexp$

    # Pipe to join events (container logs only)
    [pipe.join]

    # disable joining event
    disabled = false

    # Maximum interval of messages in pipeline
    maxInterval = 100ms

    # Maximum time to wait for the messages in pipeline
    maxWait = 1s

    # Maximum message size
    maxSize = 1MB

    # Default pattern to indicate new message (should start not from space)
    patternRegex = ^[^\s]

    # You can configure global replace rules for the events, which can help to remove sensitive data
    # from logs before they are sent to Splunk. Those rules will be applied to all pipelines for container logs, host logs,
    # application logs and events.
    # In the following example we replace password=TEST with password=********
    ; [pipe.replace::name]
    ; patternRegex = (password=)([^\s]+)
    ; replace = $1********

  004-addon.conf: |
    [ general ]

    # addons can be run in parallel with agents
    addon = true

    [input.kubernetes_events]

    # disable events
    disabled = false

    # override type
    type = events

    # override datastream
    elasticsearch.datastream =

    # set output (elasticsearch or devnull, default is [general]defaultOutput)
    output =

    # exclude managed fields from the metadata
    excludeManagedFields = true

    [input.kubernetes_watch::pods]

    # disable events
    disabled = false

    # Set the timeout for how often watch request should refresh the whole list
    refresh = 10m

    apiVersion = v1
    kind = pod
    namespace =
    excludeManagedFields = true

    # override type
    type = objects

    # override datastream
    elasticsearch.datastream =

    # set output (elasticsearch or devnull, default is [general]defaultOutput)
    output =

    # you can remove or hash some values in the events (after modifyValues you can define path in the JSON object,
    # and the value can be hash:{hashFunction}, or remove to remove the object )
    ; modifyValues.object.data.* = hash:sha256
    ; modifyValues.object.metadata.annotations.* = remove

    # You can exclude events by namespace with blacklist or whitelist only required namespaces
    # blacklist.kubernetes_namespace = ^namespace0$
    # whitelist.kubernetes_namespace = ^((namespace1)|(namespace2))$

    [input.kubernetes_watch::deployments]

    # disable events
    disabled = false

    # Set the timeout for how often watch request should refresh the whole list
    refresh = 10m

    apiVersion = apps/v1
    kind = deployment
    namespace =
    excludeManagedFields = true

    # override type
    type = objects

    # override datastream
    elasticsearch.datastream =

    # set output (elasticsearch or devnull, default is [general]defaultOutput)
    output =

  es-default-index-lifecycle-management-policy.json: |
    {
      "policy": {
        "_meta": {
          "description": "Default policy for Collectord indexes",
          "version": 1
        },
        "phases": {
          "hot": {
            "min_age": "0ms",
            "actions": {
              "rollover": {
                "max_primary_shard_size": "50gb",
                "max_age": "30d"
              }
            }
          }
        }
      }
    }
  es-default-index-template.json: |
    {
      "version": 1,
      "data_stream": {},
      "_meta": {
        "description": "Default template for Collectord indexes"
      },
      "priority": 500,
      "template": {
        "settings": {
          "index": {
            "lifecycle": {
              "name": "logs-collectord"
            },
            "refresh_interval": "5s",
            "mapping": {
              "total_fields": {
                "limit": "10000"
              }
            },
            "max_docvalue_fields_search": "200"
          },
          "query": {
            "default_field": [
              "message",
              "container.name",
              "container.image.name",
              "host.name",
              "orchestrator.namespace",
              "orchestrator.cluster.name",
              "container.name",
              "kubernetes.pod.name",
              "kubernetes.pod.id",
              "kubernetes.pod.ip",
              "kubernetes.namespace.name",
              "kubernetes.node.name",
              "kubernetes.cluster.name",
              "kubernetes.replicaset.name",
              "kubernetes.deployment.name",
              "kubernetes.statefulset.name",
              "kubernetes.daemonset.name",
              "kubernetes.job.name",
              "kubernetes.cronjob.name"
            ]
          }
        },
        "mappings": {
          "dynamic_templates": [
            {
              "kubernetes.pod.labels.*": {
                "path_match": "kubernetes.pod.labels.*",
                "mapping": {  "type": "keyword" },
                "match_mapping_type": "*"
              }
            },
            {
              "kubernetes.namespace.labels.*": {
                "path_match": "kubernetes.namespace.labels.*",
                "mapping": { "type": "keyword" },
                "match_mapping_type": "*"
              }
            },
            {
              "kubernetes.node.labels.*": {
                "path_match": "kubernetes.node.labels.*",
                "mapping": { "type": "keyword" },
                "match_mapping_type": "*"
              }
            },
            {
              "kubernetes.daemonset.labels.*": {
                "path_match": "kubernetes.daemonset.labels.*",
                "mapping": { "type": "keyword" },
                "match_mapping_type": "*"
              }
            },
            {
              "kubernetes.replicaset.labels.*": {
                "path_match": "kubernetes.replicaset.labels.*",
                "mapping": { "type": "keyword" },
                "match_mapping_type": "*"
              }
            },
            {
              "kubernetes.deployment.labels.*": {
                "path_match": "kubernetes.deployment.labels.*",
                "mapping": { "type": "keyword" },
                "match_mapping_type": "*"
              }
            },
            {
              "kubernetes.statefulset.labels.*": {
                "path_match": "kubernetes.statefulset.labels.*",
                "mapping": { "type": "keyword" },
                "match_mapping_type": "*"
              }
            },
            {
              "kubernetes.job.labels.*": {
                "path_match": "kubernetes.job.labels.*",
                "mapping": { "type": "keyword" },
                "match_mapping_type": "*"
              }
            },
            {
              "kubernetes.cronjob.labels.*": {
                "path_match": "kubernetes.cronjob.labels.*",
                "mapping": { "type": "keyword" },
                "match_mapping_type": "*"
              }
            },
            {
              "strings_as_keyword": {
                "mapping": { "ignore_above": 1024, "type": "keyword" },
                "match_mapping_type": "string"
              }
            }
          ],
          "properties": {
            "@timestamp": { "type": "date"},
            "message":{"type":"match_only_text"},
            "collectord_errors": {"type": "keyword","ignore_above": 1024},
            "input":{"properties":{"type":{"ignore_above":1024,"type":"keyword"}}},
            "container": {"properties": {
              "name": { "ignore_above": 1024, "type": "keyword"},
              "id": { "ignore_above": 1024, "type": "keyword"},
              "runtime": {"ignore_above": 1024, "type": "keyword"},
              "image": {"properties": {
                "name": { "ignore_above": 1024, "type": "keyword"}
              }}
            }
            },
            "event": {"properties": {
              "id": {"ignore_above": 1024, "type": "keyword"}
            }},
            "host": {"properties": {
              "name": {"ignore_above": 1024, "type": "keyword"},
              "architecture": {"ignore_above": 1024, "type": "keyword"},
              "hostname": {"ignore_above": 1024, "type": "keyword"}
            }},
            "log": { "properties": {
              "file": { "properties": {
                "path": {"ignore_above": 1024, "type": "keyword"}
              }},
              "offset": {"type": "long"},
              "syslog": {"properties": {
                "appname": {"ignore_above": 1024, "type": "keyword"},
                "facility": {"properties": {
                  "code": {"type": "long"}
                }},
                "priority": {"type": "long"},
                "procid": {"type": "long"},
                "hostname": {"ignore_above": 1024, "type": "keyword"}
              }}
            }},
            "orchestrator": {"properties": {
              "cluster": {"properties": {
                "name": {"ignore_above": 1024, "type": "keyword"}
              }},
              "namespace": {"properties": {
                "name":{"path":"kubernetes.namespace.name","type":"alias"}
              }},
              "type": {"ignore_above": 1024, "type": "keyword"}
            }},
            "stream": {"ignore_above": 1024, "type": "keyword"},
            "agent":{"properties":{
              "hostname":{"path":"agent.name","type":"alias"},
              "name":{"ignore_above":1024,"type":"keyword"},
              "id":{"ignore_above":1024,"type":"keyword"},
              "type":{"ignore_above":1024,"type":"keyword"},
              "ephemeral_id":{"ignore_above":1024,"type":"keyword"},
              "version":{"ignore_above":1024,"type":"keyword"}
            }},
            "ecs":{"properties":{"version":{"ignore_above":1024,"type":"keyword"}}},
            "kubernetes": { "properties": {
              "container": {"properties": {
                "imageid": {"ignore_above": 1024, "type": "keyword"}
              }},
              "host": {"properties": {
                "ip": {"type": "ip"}
              }},
              "namespace": {"properties": {
                "name": {"ignore_above": 1024, "type": "keyword"}
              }},
              "node": { "properties": {
                "id": {"ignore_above": 1024, "type": "keyword"},
                "name": {"ignore_above": 1024,"type": "keyword"}
              }},
              "pod": {"properties": {
                "id": {"ignore_above": 1024,"type": "keyword"},
                "ip": {"type": "ip"},
                "name": {"ignore_above": 1024,"type": "keyword"}
              }},
              "statefulset": { "properties": {
                "id": {"ignore_above": 1024,"type": "keyword"},
                "name": {"ignore_above": 1024,"type": "keyword"}
              }},
              "replicaset": {"properties": {
                "id": {"ignore_above": 1024,"type": "keyword"},
                "name": {"ignore_above": 1024, "type": "keyword"}
              }},
              "deployment": { "properties": {
                "id": {"ignore_above": 1024,"type": "keyword"},
                "name": {"ignore_above": 1024,"type": "keyword" }
              }},
              "cronjob": {"properties": {
                "id": {"ignore_above": 1024,"type": "keyword"},
                "name": {"ignore_above": 1024, "type": "keyword"}
              }},
              "job": {"properties": {
                "id": {"ignore_above": 1024,"type": "keyword"},
                "name": {"ignore_above": 1024, "type": "keyword"}
              }}
            }},
            "volume": {"properties": {
                "name": {"ignore_above": 1024,"type": "keyword"}
            }}
          }
        }
      },
      "index_patterns": ["logs-collectord-${COLLECTORD_VERSION}"]
    }
  es-failed-index-template.json: |
    {
      "version": 1,
      "data_stream": {},
      "_meta": {
        "description": "Default template for Collectord indexes for events that failed to be ingested"
      },
      "priority": 1000,
      "template": {
        "settings": {
          "index": {
            "lifecycle": {
              "name": "logs-collectord"
            },
            "refresh_interval": "5s",
            "mapping": {
              "total_fields": {
                "limit": "10000"
              }
            },
            "max_docvalue_fields_search": "200"
          },
          "query": {
            "default_field": [
              "message"
            ]
          }
        },
        "mappings": {
          "properties": {
            "@timestamp": {
              "type": "date"},
            "message": {
              "type": "match_only_text"}
          }
        }
      },
      "index_patterns": [
        "logs-collectord-failed-${COLLECTORD_VERSION}"]
    }
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: collectorforkubernetes-elasticsearch
  namespace: collectorforkubernetes
  labels:
    app: collectorforkubernetes-elasticsearch
spec:
  updateStrategy:
    type: RollingUpdate

  selector:
    matchLabels:
      daemon: collectorforkubernetes-elasticsearch

  template:
    metadata:
      name: collectorforkubernetes-elasticsearch
      labels:
        daemon: collectorforkubernetes-elasticsearch
    spec:
      priorityClassName: collectorforkubernetes-critical
      dnsPolicy: ClusterFirstWithHostNet
      hostNetwork: true
      serviceAccountName: collectorforkubernetes
      tolerations:
      - operator: "Exists"
        effect: "NoSchedule"
      - operator: "Exists"
        effect: "NoExecute"
      containers:
      - name: collectorforkubernetes
        image: docker.io/outcoldsolutions/collectorforkubernetes:5.24.440
        imagePullPolicy: Always
        securityContext:
          runAsUser: 0
          privileged: true
        # Define your resources if you need. Defaults should be fine for most.
        # You can lower or increase based on your hosts.
        resources:
          limits:
            cpu: 2000m
            memory: 512Mi
          requests:
            cpu: 200m
            memory: 192Mi
        env:
        - name: KUBERNETES_NODENAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        volumeMounts:
        # We store state in /data folder (file positions)
        - name: collectorforkubernetes-state
          mountPath: /data
        # Configuration file deployed with ConfigMap
        - name: collectorforkubernetes-config
          mountPath: /config/
          readOnly: true
        # Rootfs
        - name: rootfs
          mountPath: /rootfs/
          readOnly: false
          mountPropagation: HostToContainer
        # correct timezone
        - name: localtime
          mountPath: /etc/localtime
          readOnly: true
      volumes:
      # We store state directly on host, change this location, if
      # your persistent volume is somewhere else
      - name: collectorforkubernetes-state
        hostPath:
          path: /var/lib/collectorforkubernetes-elasticsearch/data/
          type: DirectoryOrCreate
      # Location of docker root (for container logs and metadata)
      - name: rootfs
        hostPath:
          path: /
      # correct timezone
      - name: localtime
        hostPath:
          path: /etc/localtime
      # configuration from ConfigMap
      - name: collectorforkubernetes-config
        configMap:
          name: collectorforkubernetes-elasticsearch
          items:
            - key: 001-general.conf
              path: 001-general.conf
            - key: 002-daemonset.conf
              path: 002-daemonset.conf
            - key: es-default-index-template.json
              path: es-default-index-template.json
            - key: es-default-index-lifecycle-management-policy.json
              path: es-default-index-lifecycle-management-policy.json
            - key: es-failed-index-template.json
              path: es-failed-index-template.json
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: collectorforkubernetes-elasticsearch-addon
  namespace: collectorforkubernetes
  labels:
    app: collectorforkubernetes-elasticsearch
spec:
  replicas: 1

  selector:
    matchLabels:
      daemon: collectorforkubernetes-elasticsearch

  template:
    metadata:
      name: collectorforkubernetes-elasticsearch-addon
      labels:
        daemon: collectorforkubernetes-elasticsearch
    spec:
      priorityClassName: collectorforkubernetes-critical
      serviceAccountName: collectorforkubernetes
      containers:
        - name: collectorforkubernetes
          image: docker.io/outcoldsolutions/collectorforkubernetes:5.24.440
          imagePullPolicy: Always
          securityContext:
            runAsUser: 0
            privileged: true
          resources:
            limits:
              cpu: 500m
              memory: 256Mi
            requests:
              cpu: 50m
              memory: 64Mi
          env:
            - name: KUBERNETES_NODENAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
          volumeMounts:
            - name: collectorforkubernetes-state
              mountPath: /data
            - name: collectorforkubernetes-config
              mountPath: /config/
              readOnly: true
      volumes:
        - name: collectorforkubernetes-state
          hostPath:
            path: /var/lib/collectorforkubernetes-elasticsearch/data/
            type: Directory
        - name: collectorforkubernetes-config
          configMap:
            name: collectorforkubernetes-elasticsearch
            items:
              - key: 001-general.conf
                path: 001-general.conf
              - key: 004-addon.conf
                path: 004-addon.conf
              - key: es-default-index-template.json
                path: es-default-index-template.json
              - key: es-default-index-lifecycle-management-policy.json
                path: es-default-index-lifecycle-management-policy.json
              - key: es-failed-index-template.json
                path: es-failed-index-template.json