Skip to content

Evaluate rules on our own again, or in tandem #406

@nilmerg

Description

@nilmerg

Transferring SQL Queries is… sub-optimal. Let's get rid of that.

Version 0.1.0 expected sources to include extra_tags so that rules match events with corresponding recipients. We want to get back to this behavior, but we also want to avoid their previous shortcomings.

The properties of an event that are relevant in 0.2.0 are:

{
  "extra_tags": <object>,
  "rules_version": <hash>,
  "rule_ids": <list-of-ints>
}

These are fully obsolete now and only a single new one is required:

{
  "relations": <object>
}

Example, in case of Icinga DB:

{
  "relations": {
    "host": {
      "name": "web-1-a",
      "vars": {
        "os": "Linux"
      }
    },
    "hostgroups": [
      {
        "name": "web-servers",
        "display_name": "Web Servers"
      }
    ]
  }
}

The basic assumption here is that relations always have the same structure, so there is no variation requiring conditional checks. Let's take a look at a service why that matters:

{
  "relations": {
    "host": {
      "name": "web-1-a",
      "vars": {
        "os": "Linux"
      }
    },
    "hostgroups": [
      {
        "name": "web-servers",
        "display_name": "Web Servers"
      }
    ],
    "services": [
      {
        "name": "nginx",
        "vars": {
          "http_ports": [80, 443]
        }
      }
    ],
    "servicegroups": []
  }
}

Note that this simply contains an additional services and servicegroups key, services with just a single entry. In case of a service event, it is always a list with a single entry. It can simply be extended to a multiple of services in case of a host and the structure didn't change.

Icinga Notifications Web will serialize rule filters in a format easy to parse for Icinga Notifications. Though, if that's not the query string syntax already in use, Web will need to be able to parse it back as well in order to present it back to the user.

Upon retrieval of an event, Icinga Notifications tries to match all rules with it. If any rule cannot match due to missing attributes, they're collected in a list. If this happens, Icinga Notifications needs to contact the source and tell it about those and the source needs to re-transmit either the full event again or updated relations. (That's up to the implementer to decide.) This is called attribute negotiation.

Important

Generic sources are not meant to support attribute negotiation, so whether a source is capable of this must be signaled somehow to Icinga Notifications. A request header for example.

The source may signal that some relations are already complete and an update cannot be delivered for them. This is done by using a request header: X-Icinga-Complete-Relations: hostgroups, services[*].vars

If the source cannot (will not or is unable to) provide an update, or the the update is incomplete, Icinga Notifications evaluates the rules as far as it can but generates a log entry for rules that couldn't be evaluated.

Let's say Icinga DB missed to include the hostgroups and service custom variables. In this case, Icinga Notifications will ask it for:

  • services[*].vars.http_ports
  • hostgroups

And if a group did not contain the display name:

  • hostgroups[*].display_name

The format used here is JSONpath. Its mature nature and widespread use should pose no problem for any source to understand.

The structure of said request and the expected response may look like this:

Request:

{
  "type": "attribute negotiation",
  "attributes": [
     "hostgroups",
     "services[*].vars.http_ports"
  ]
}

Response:

{
  "relations": {
    "hostgroups": [
      {
        "name": "web-servers",
        "display_name": "Web Servers"
      }
    ],
    "services": [
      {
        "vars": {
          "http_ports": [80, 443]
        }
      }
    ]
  }
}

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

Status

In progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions