events

command module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 24, 2022 License: MIT Imports: 1 Imported by: 0

README

Events

Http service which implements an endpoint to listen events in Kubernetes cluster (webhook), as well as alerts from Alertmanager. By receiving events and alerts, the service processes them based on their kind and generates human readable message which sends to Kafka, Telegram, Slack or Workchat.

GoDoc go report codecov build status

Features

  • Consume events from Kubernetes API, support kinds: Namespace, Node, ReplicaSet, StatefulSet, DaemonSet, Secret, Ingress, CronJob, Job, ConfigMap, Role, Deployment, Service, Pod
  • Consume alerts from Alertmanager and render alert images based on Grafana
  • Support golang templates as patterns of messages for channels and channel selectors
  • Template functions: regexReplaceAll, regexMatch, replaceAll, toLower, toTitle, toUpper, toJSON, split, join, isEmpty, getEnv, getVar, timeFormat, jsonEscape, toString
  • Support channels like: Kafka, Telegram, Slack, Workchat. All templates in place
  • Provide SRE metrics, logs, traces out of the box (see devopsext/sre)

Build

Set proper GOROOT and PATH variables

export GOROOT="$HOME/go/root/1.17.4"
export PATH="$PATH:$GOROOT/bin"

Clone repository

git clone https://github.com/devopsext/events.git
cd events/
go build

Example

Create Kubernetes API event json file
cat <<EOF > k8s.json
{
  "kind": "AdmissionReview",
  "apiVersion": "admission.k8s.io/v1beta1",
  "request": {
    "uid": "23172a7a-f4c6-11e9-953e-0050568aa55b",
    "kind": {
      "group": "",
      "version": "v1",
      "kind": "Pod"
    },
    "resource": {
      "group": "",
      "version": "v1",
      "resource": "pods"
    },
    "namespace": "nodegroup",
    "operation": "CREATE",
    "userInfo": {
      "username": "some-user",
      "uid": "380bb127-e96f-11e8-ae7d-0050568a9a8e",
      "groups": [
        "system:serviceaccounts",
        "system:serviceaccounts:kube-system",
        "system:authenticated"
      ]
    },
    "object": {
      "metadata": {
        "name": "someservice-php-order-1571746740-glbhp",
        "generateName": "someservice-php-order-1571746740-",
        "namespace": "nodegroup",
        "uid": "23171eb4-f4c6-11e9-953e-0050568aa55b",
        "creationTimestamp": "2019-10-22T12:19:04Z",
        "labels": {
          "controller-uid": "231132ee-f4c6-11e9-953e-0050568aa55b",
          "job-name": "someservice-php-order-1571746740",
          "k8s-app": "someservice-php-order",
          "platform.collector/injected": "true",
          "version": "v0.4"
        },
        "annotations": {
          "app": "someservice-php-order",
          "prometheus.io/path": "/metrics",
          "prometheus.io/port": "60000",
          "prometheus.io/scrape": "true"
        },
        "ownerReferences": [
          {
            "apiVersion": "batch/v1",
            "kind": "Job",
            "name": "someservice-php-order-1571746740",
            "uid": "231132ee-f4c6-11e9-953e-0050568aa55b",
            "controller": true,
            "blockOwnerDeletion": true
          }
        ]
      },
      "spec": {
        "volumes": [
          {
            "name": "someservice-php-env-file-volume",
            "configMap": {
              "name": "someservice-php-env-file",
              "defaultMode": 420
            }
          },
          {
            "name": "default-token-mn7zd",
            "secret": {
              "secretName": "default-token-mn7zd",
              "defaultMode": 420
            }
          },
          {
            "name": "dockersock",
            "hostPath": {
              "path": "/var/run/docker.sock",
              "type": ""
            }
          },
          {
            "name": "platform-collector-token",
            "secret": {
              "secretName": "platform-collector-token",
              "defaultMode": 420
            }
          }
        ],
        "containers": [
          {
            "name": "someservice-php-order",
            "image": "someregistry.com/someservice-php:v0.4",
            "command": [
              "/bin/bash",
              "-c",
              "cd /var/www ; php -d memory_limit=512M artisan transform:order; echo \"Done\"; sleep 3"
            ],
            "env": [
              {
                "name": "POD_NAME",
                "valueFrom": {
                  "fieldRef": {
                    "apiVersion": "v1",
                    "fieldPath": "metadata.name"
                  }
                }
              }
            ],
            "resources": {
              "limits": {
                "cpu": "1",
                "memory": "200Mi"
              },
              "requests": {
                "cpu": "500m",
                "memory": "150Mi"
              }
            },
            "volumeMounts": [
              {
                "name": "someservice-php-env-file-volume",
                "mountPath": "/env"
              },
              {
                "name": "default-token-mn7zd",
                "readOnly": true,
                "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
              }
            ],
            "terminationMessagePath": "/dev/termination-log",
            "terminationMessagePolicy": "File",
            "imagePullPolicy": "IfNotPresent"
          },
          {
            "name": "collector",
            "image": "collector/pod:1.9.3.11-1.1.0",
            "env": [
              {
                "name": "KAFKA_BROKERS",
                "value": "broker:9092"
              },
              {
                "name": "POD_NAME",
                "valueFrom": {
                  "fieldRef": {
                    "apiVersion": "v1",
                    "fieldPath": "metadata.name"
                  }
                }
              },
              {
                "name": "COLLECTOR_GLOBAL_TAGS_ORCHESTRATION",
                "value": "k8s.test.env"
              }
            ],
            "resources": {},
            "volumeMounts": [
              {
                "name": "platform-collector-token",
                "readOnly": true,
                "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
              },
              {
                "name": "dockersock",
                "readOnly": true,
                "mountPath": "/var/run/docker.sock"
              }
            ],
            "terminationMessagePath": "/dev/termination-log",
            "terminationMessagePolicy": "File",
            "imagePullPolicy": "Always"
          }
        ],
        "restartPolicy": "Never",
        "terminationGracePeriodSeconds": 30,
        "dnsPolicy": "ClusterFirst",
        "nodeSelector": {
          "platform.isolation/nodegroup": "nodegroup"
        },
        "serviceAccountName": "default",
        "serviceAccount": "default",
        "securityContext": {},
        "imagePullSecrets": [
          {
            "name": "registry.exness.io"
          }
        ],
        "schedulerName": "default-scheduler",
        "tolerations": [
          {
            "key": "node.kubernetes.io/not-ready",
            "operator": "Exists",
            "effect": "NoExecute",
            "tolerationSeconds": 300
          },
          {
            "key": "node.kubernetes.io/unreachable",
            "operator": "Exists",
            "effect": "NoExecute",
            "tolerationSeconds": 300
          }
        ],
        "priority": 0
      },
      "status": {
        "phase": "Pending",
        "qosClass": "Burstable"
      }
    },
    "oldObject": null,
    "dryRun": false
  }
}
EOF
Create Alertmanager alert json file
cat <<EOF > alertmanager.json
{
  "receiver": "events",
  "status": "firing",
  "alerts": [
    {
      "status": "firing",
      "labels": {
        "alertname": "Process Open FDS 2",
        "app": "prometheus",
        "instance": "10.42.0.5:9090",
        "kubernetes_namespace": "default",
        "kubernetes_pod_name": "prometheus-0",
        "severity": "some",
        "unit": "short",
        "minutes": "10",
        "statefulset_kubernetes_io_pod_name": "prometheus-0"
      },
      "annotations": {
        "summary": "High process Open FDS"
      },
      "startsAt": "2020-12-22T16:42:47.056441315Z",
      "endsAt": "0001-01-01T00:00:00Z",
      "generatorURL": "http://prometheus-0:9090/graph?g0.expr=rate(process_cpu_seconds_total[1m]) > 0.004&g0.tab=1",
      "fingerprint": "f8767e67485c740c"
    }
  ],
  "groupLabels": {
    "alertname": "Process Open FDS"
  },
  "commonLabels": {
    "alertname": "Process Open FDS",
    "app": "prometheus",
    "instance": "10.42.0.5:9090",
    "kubernetes_namespace": "default",
    "kubernetes_pod_name": "prometheus-0",
    "severity": "some",
    "statefulset_kubernetes_io_pod_name": "prometheus-0"
  },
  "commonAnnotations": {
    "summary": "High process Open FDS"
  },
  "externalURL": "http://alertmanager-db66d4578-dm696:9093",
  "version": "4",
  "groupKey": "{}/{}:{alertname=\"Process Open FDS\"}"
}
EOF
Provide environment common variable
In a case of Grafana images based on alert rules which come from Alertmanager, setup environment variables for convinience. You can use command switches for that, but for the sake of simplicity, environment variables should be provided.
export EVENTS_GRAFANA_URL="Place Grafana URL in case of Alertmanger images or leave it empty"
export EVENTS_GRAFANA_API_KEY="Place Grafana API key"
export EVENTS_STDOUT_FORMAT="template"
export EVENTS_STDOUT_LEVEL="debug"
export EVENTS_STDOUT_TEMPLATE="{{.msg}}"
Run Events with Telegram channel
export TELEGRAM_BOT="Place Telegram bot"
export TELEGRAM_CHAT_ID="Place Telegram chat ID"
./events --http-listen :8081 --http-k8s-url /k8s --http-alertmanager-url /alertmanager \
         --telegram-url "https://api.telegram.org/bot${TELEGRAM_BOT}/sendMessage?chat_id=${TELEGRAM_CHAT_ID}" \
         --telegram-message-template "{{- define \"telegram-message\"}}{{ toJSON . }}{{- end}}"

or

./events --http-listen :8081 --http-k8s-url /k8s --http-alertmanager-url /alertmanager \
         --telegram-url "https://api.telegram.org/bot${TELEGRAM_BOT}/sendMessage?chat_id=${TELEGRAM_CHAT_ID}" \
         --telegram-message-template "telegram.message"
Run Events with Slack channel
export SLACK_TOKEN="Place Slack token"
export SLACK_CHANNELS="Place Slack channels"
./events --http-listen :8081 --http-k8s-url /k8s --http-alertmanager-url /alertmanager \
         --slack-url "https://slack.com/api/files.upload?token=${SLACK_TOKEN}&channels=${SLACK_CHANNELS}" \
         --slack-message-template "{{- define \"slack-message\"}}{{ toJSON . }}{{- end}}"

or

./events --http-listen :8081 --http-k8s-url /k8s --http-alertmanager-url /alertmanager \
         --slack-url "https://slack.com/api/files.upload?token=${SLACK_TOKEN}&channels=${SLACK_CHANNELS}" \
         --slack-message-template "slack.message"
Run Events with Workchat channel
export WORKCHAT_TOKEN="Place Workchat access token"
export WORKCHAT_RECIPIENT="Place Wotkchat thread group"
./events --http-listen :8081 --http-k8s-url /k8s --http-alertmanager-url /alertmanager \
         --workchat-url "https://graph.workplace.com/v9.0/me/messages?access_token=${WORKCHAT_TOKEN}&recipient=%7B%22thread_key%22%3A%22${WORKCHAT_RECIPIENT}%22%7D" \
         --workchat-message-template "{{- define \"workchat-message\"}}{{ replaceAll \"\\\"\" \"\" (toJSON .) }}{{- end}}"

or

./events --http-listen :8081 --http-k8s-url /k8s --http-alertmanager-url /alertmanager \
         --workchat-url "https://graph.workplace.com/v9.0/me/messages?access_token=${WORKCHAT_TOKEN}&recipient=%7B%22thread_key%22%3A%22${WORKCHAT_RECIPIENT}%22%7D" \
         --workchat-message-template "workchat.message"
Run Events with Telegram, Slack and Workchat simultaniously
./events --http-listen :8081 --http-k8s-url /k8s --http-alertmanager-url /alertmanager \
         --telegram-url "https://api.telegram.org/bot${TELEGRAM_BOT}/sendMessage?chat_id=${TELEGRAM_CHAT_ID}" \
         --telegram-message-template "telegram.message" \
         --slack-url "https://slack.com/api/files.upload?token=${SLACK_TOKEN}&channels=${SLACK_CHANNELS}" \
         --slack-message-template "slack.message" \
         --workchat-url "https://graph.workplace.com/v9.0/me/messages?access_token=${WORKCHAT_TOKEN}&recipient=%7B%22thread_key%22%3A%22${WORKCHAT_RECIPIENT}%22%7D" \
         --workchat-message-template "workchat.message"
Test Alertmanager endpoint
curl -X POST -H 'Content-type: application/json' -d @alertmanager.json http://127.0.0.1:8081/alertmanager
{"Message":"OK"}
Test Kubernetes API endpoint
curl -X POST -H 'Content-type: application/json' -d @k8s.json http://127.0.0.1:8081/k8s
{"response":{"uid":"23172a7a-f4c6-11e9-953e-0050568aa55b","allowed":true}}

Usage


Usage:
  events [flags]
  events [command]

Available Commands:
  help        Help about any command
  version     Print the version number

Flags:
      --datadog-debug                            DataDog debug
      --datadog-environment string               DataDog environment (default "none")
      --datadog-logger-agent-host string         DataDog logger agent host
      --datadog-logger-agent-port int            Datadog logger agent port (default 10518)
      --datadog-logger-level string              DataDog logger level: info, warn, error, debug, panic (default "info")
      --datadog-meter-agent-host string          DataDog meter agent host
      --datadog-meter-agent-port int             Datadog meter agent port (default 10518)
      --datadog-meter-prefix string              DataDog meter prefix (default "events")
      --datadog-service-name string              DataDog service name (default "events")
      --datadog-tags string                      DataDog tags
      --datadog-tracer-agent-host string         DataDog tracer agent host
      --datadog-tracer-agent-port int            Datadog tracer agent port (default 8126)
      --grafana-api-key string                   Grafana API key (default "admin:admin")
      --grafana-datasource string                Grafana datasource (default "Prometheus")
      --grafana-image-height int                 Grafan image height (default 640)
      --grafana-image-width int                  Grafan image width (default 1280)
      --grafana-org string                       Grafana org (default "1")
      --grafana-period int                       Grafana period in minutes (default 60)
      --grafana-timeout int                      Grafan timeout (default 60)
      --grafana-url string                       Grafana URL
  -h, --help                                     help for events
      --http-alertmanager-url string             Http Alertmanager url
      --http-cert string                         Http cert file or content
      --http-chain string                        Http CA chain file or content
      --http-header-trace-id string              Http trace ID header (default "X-Trace-ID")
      --http-k8s-url string                      Http K8s url
      --http-key string                          Http key file or content
      --http-listen string                       Http listen (default ":80")
      --http-rancher-url string                  Http Rancher url
      --http-tls                                 Http TLS
      --jaeger-agent-host string                 Jaeger agent host
      --jaeger-agent-port int                    Jaeger agent port (default 6831)
      --jaeger-buffer-flush-interval int         Jaeger buffer flush interval
      --jaeger-endpoint string                   Jaeger endpoint
      --jaeger-password string                   Jaeger password
      --jaeger-queue-size int                    Jaeger queue size
      --jaeger-service-name string               Jaeger service name (default "events")
      --jaeger-tags string                       Jaeger tags, comma separated list of name=value
      --jaeger-user string                       Jaeger user
      --kafka-brokers string                     Kafka brokers
      --kafka-client-id string                   Kafka client id (default "events_kafka")
      --kafka-flush-frequency int                Kafka Producer flush frequency (default 1)
      --kafka-flush-max-messages int             Kafka Producer flush max messages (default 100)
      --kafka-message-template string            Kafka message template
      --kafka-net-dial-timeout int               Kafka Net dial timeout (default 30)
      --kafka-net-max-open-requests int          Kafka Net max open requests (default 5)
      --kafka-net-read-timeout int               Kafka Net read timeout (default 30)
      --kafka-net-write-timeout int              Kafka Net write timeout (default 30)
      --kafka-topic string                       Kafka topic (default "events")
      --logs strings                             Log providers: stdout, datadog (default [stdout])
      --metrics strings                          Metric providers: prometheus, datadog, opentelemetry (default [prometheus])
      --opentelemetry-attributes string          Opentelemetry attributes
      --opentelemetry-environment string         Opentelemetry environment (default "none")
      --opentelemetry-meter-agent-host string    Opentelemetry meter agent host
      --opentelemetry-meter-agent-port int       Opentelemetry meter agent port (default 4317)
      --opentelemetry-meter-prefix string        Opentelemetry meter prefix (default "events")
      --opentelemetry-service-name string        Opentelemetry service name (default "events")
      --opentelemetry-tracer-agent-host string   Opentelemetry tracer agent host
      --opentelemetry-tracer-agent-port int      Opentelemetry tracer agent port (default 4317)
      --prometheus-listen string                 Prometheus listen (default "127.0.0.1:8080")
      --prometheus-prefix string                 Prometheus prefix (default "events")
      --prometheus-url string                    Prometheus endpoint url (default "/metrics")
      --slack-alert-expression string            Slack alert expression (default "g0.expr")
      --slack-message-template string            Slack message template
      --slack-selector-template string           Slack selector template
      --slack-timeout int                        Slack timeout (default 30)
      --slack-url string                         Slack URL
      --stdout-format string                     Stdout format: json, text, template (default "stdout")
      --stdout-level string                      Stdout level: info, warn, error, debug, panic (default "debug")
      --stdout-template string                   Stdout template (default "{{.file}} {{.msg}}")
      --stdout-text-colors                       Stdout text colors (default true)
      --stdout-timestamp-format string           Stdout timestamp format (default "2006-01-02T15:04:05.999999999Z07:00")
      --telegram-alert-expression string         Telegram alert expression (default "g0.expr")
      --telegram-disable-notification string     Telegram disable notification (default "false")
      --telegram-message-template string         Telegram message template
      --telegram-selector-template string        Telegram selector template
      --telegram-timeout int                     Telegram timeout (default 30)
      --telegram-url string                      Telegram URL
      --template-time-format string              Template time format (default "2006-01-02T15:04:05.999Z")
      --traces strings                           Trace providers: jaeger, datadog, opentelemetry
      --workchat-alert-expression string         Workchat alert expression (default "g0.expr")
      --workchat-message-template string         Workchat message template
      --workchat-notification-type string        Workchat notification type (default "REGULAR")
      --workchat-selector-template string        Workchat selector template
      --workchat-timeout int                     Workchat timeout (default 30)
      --workchat-url string                      Workchat URL
Environment variables
For containerization purpose all command switches have environment variables analogs.
  • EVENTS_LOGS

  • EVENTS_METRICS

  • EVENTS_TRACES

  • EVENTS_TEMPLATE_TIME_FORMAT

  • EVENTS_STDOUT_FORMAT

  • EVENTS_STDOUT_LEVEL

  • EVENTS_STDOUT_TEMPLATE

  • EVENTS_STDOUT_TIMESTAMP_FORMAT

  • EVENTS_STDOUT_TEXT_COLORS

  • EVENTS_PROMETHEUS_URL

  • EVENTS_PROMETHEUS_LISTEN

  • EVENTS_PROMETHEUS_PREFIX

  • EVENTS_HTTP_K8S_URL

  • EVENTS_HTTP_RANCHER_URL

  • EVENTS_HTTP_ALERTMANAGER_URL

  • EVENTS_HTTP_LISTEN

  • EVENTS_HTTP_TLS

  • EVENTS_HTTP_CERT

  • EVENTS_HTTP_KEY

  • EVENTS_HTTP_CHAIN

  • EVENTS_HTTP_HEADER_TRACE_ID

  • EVENTS_COLLECTOR_ADDRESS

  • EVENTS_COLLECTOR_MESSAGE_TEMPLATE

  • EVENTS_KAFKA_CLIEND_ID

  • EVENTS_KAFKA_MESSAGE_TEMPLATE

  • EVENTS_KAFKA_BROKERS

  • EVENTS_KAFKA_TOPIC

  • EVENTS_KAFKA_FLUSH_FREQUENCY

  • EVENTS_KAFKA_FLUSH_MAX_MESSAGES

  • EVENTS_KAFKA_NET_MAX_OPEN_REQUESTS

  • EVENTS_KAFKA_NET_DIAL_TIMEOUT

  • EVENTS_KAFKA_NET_READ_TIMEOUT

  • EVENTS_KAFKA_NET_WRITE_TIMEOUT

  • EVENTS_TELEGRAM_MESSAGE_TEMPLATE

  • EVENTS_TELEGRAM_SELECTOR_TEMPLATE

  • EVENTS_TELEGRAM_URL

  • EVENTS_TELEGRAM_TIMEOUT

  • EVENTS_TELEGRAM_ALERT_EXPRESSION

  • EVENTS_TELEGRAM_DISABLE_NOTIFICATION

  • EVENTS_SLACK_MESSAGE_TEMPLATE

  • EVENTS_SLACK_SELECTOR_TEMPLATE

  • EVENTS_SLACK_URL

  • EVENTS_SLACK_TIMEOUT

  • EVENTS_SLACK_ALERT_EXPRESSION

  • EVENTS_WORKCHAT_MESSAGE_TEMPLATE

  • EVENTS_WORKCHAT_SELECTOR_TEMPLATE

  • EVENTS_WORKCHAT_URL

  • EVENTS_WORKCHAT_TIMEOUT

  • EVENTS_WORKCHAT_ALERT_EXPRESSION

  • EVENTS_WORKCHAT_NOTIFICATION_TYPE

  • EVENTS_GRAFANA_URL

  • EVENTS_GRAFANA_TIMEOUT

  • EVENTS_GRAFANA_DATASOURCE

  • EVENTS_GRAFANA_API_KEY

  • EVENTS_GRAFANA_ORG

  • EVENTS_GRAFANA_PERIOD

  • EVENTS_GRAFANA_IMAGE_WIDTH

  • EVENTS_GRAFANA_IMAGE_HEIGHT

  • EVENTS_JAEGER_SERVICE_NAME

  • EVENTS_JAEGER_AGENT_HOST

  • EVENTS_JAEGER_AGENT_PORT

  • EVENTS_JAEGER_ENDPOINT

  • EVENTS_JAEGER_USER

  • EVENTS_JAEGER_PASSWORD

  • EVENTS_JAEGER_BUFFER_FLUSH_INTERVAL

  • EVENTS_JAEGER_QUEUE_SIZE

  • EVENTS_JAEGER_TAGS

  • EVENTS_DATADOG_SERVICE_NAME

  • EVENTS_DATADOG_ENVIRONMENT

  • EVENTS_DATADOG_TAGS

  • EVENTS_DATADOG_TRACER_HOST

  • EVENTS_DATADOG_TRACER_PORT

  • EVENTS_DATADOG_LOGGER_HOST

  • EVENTS_DATADOG_LOGGER_PORT

  • EVENTS_DATADOG_LOGGER_LEVEL

  • EVENTS_DATADOG_METER_HOST

  • EVENTS_DATADOG_METER_PORT

  • EVENTS_DATADOG_METER_PREFIX

  • EVENTS_OPENTELEMETRY_SERVICE_NAME

  • EVENTS_OPENTELEMETRY_ENVIRONMENT

  • EVENTS_OPENTELEMETRY_ATTRIBUTES

  • EVENTS_OPENTELEMETRY_TRACER_HOST

  • EVENTS_OPENTELEMETRY_TRACER_PORT,

  • EVENTS_OPENTELEMETRY_METER_HOST

  • EVENTS_OPENTELEMETRY_METER_PORT

  • EVENTS_OPENTELEMETRY_METER_PREFIX

  • EVENTS_OPENTELEMETRY_METER_COLLECT_PERIOD

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL