Channels¶
After Icinga Notifications decides to send a notification of any kind, it is passed to a channel plugin. Such a plugin submits the notification event to a domain-specific channel, such as email or a chat client.
Icinga Notifications comes packed with channels, but also enables you to develop your own channels.
To make these channels available to Icinga Notifications, they must be placed in the channels directory, which is done automatically during package installations. At startup, Icinga Notifications scans this directory, starts each channel once to query its configuration options and stores those options in the database. Using this information, Icinga Notifications Web allows channels to be configured, which are then started, configured, and finally used to send notification events from Icinga Notifications.
Technical Channel Description¶
Warning
As this is still an early preview version, things might change. There may still be severe bugs and incompatible changes may happen without any notice.
Channel plugins are independent processes that run continuously, started and supervised by Icinga Notifications.
They receive JSON-formatted requests on stdin
and reply with JSON-formatted responses on stdout
.
For logging or debugging purposes, channels can write to stderr
,
which is being forwarded to the Icinga Notifications log.
RPC Architecture¶
The request and response structure is inspired by JSON-RPC. Both the general anatomy of requests and responses as well as the specific methods are described below. Note that fields marked as optional must be omitted from the JSON object if they do not have a value.
This documentation uses beautified JSON for ease of reading.
Request¶
A channel receives a request as a JSON object with the following fields:
Field | Type | Description |
---|---|---|
method |
String | Required. Request method to call. |
params |
JSON object | Optional. Params for the request method. |
id |
Unsigned integer | Required. Unique identifier. |
The params
field is optional because some methods do not require parameters.
If they are required for a particular method,
they are specified along with the expected value type in the method description below.
Each request contains a unique id
that must be echoed back in the channel’s response.
This allows Icinga Notifications to associate a response with its request.
Examples:
- Simple request without any
params
:{ "method": "Simple", "id": 1000 }
- Request with
params
of different types:{ "method": "WithParams", "params": { "foo": 23, "bar": "hello" }, "id": 1000 }
Response¶
Each request must be answered by the channel with a JSON object of the following fields:
Field | Type | Description |
---|---|---|
result |
JSON value (any) | Optional. Output of a successful method call. |
error |
String | Optional. Error message. |
id |
Unsigned integer | Required. Request id . |
The result
and the error
fields are mutually exclusive.
A result
can be omitted when the method does not return a value, i.e., for setter calls.
However, in case of a present error
value, the result
field must be omitted.
Thus, a successful response without a result
contains only an id
field.
Examples:
- Successful response without a
result
message:{ "id": 1000 }
- Successful response with a
result
:{ "result": "hello world", "id": 1000 }
- Response with an error:
{ "error": "unknown method: 'Foo'", "id": 1000 }
RPC Methods¶
The following methods must be implemented by a channel.
GetInfo¶
The parameterless GetInfo
method returns information about the channel.
Its result
is expected to be a JSON object with the json
fields defined in the
Info
type.
The config_attrs
field must be an array of JSON objects according to the
ConfigOption
type.
These attributes define configuration options for the channel to be set by the SetConfig
method.
They are also used for channel configuration in Icinga Notifications Web.
Example GetInfo Request¶
{
"method": "GetInfo",
"id": 1
}
Example GetInfo Response¶
{
"result": {
"name": "Minified Webhook",
"version": "0.0.0-gf369a11-dirty",
"author": "Icinga GmbH",
"config_attrs": [
{
"name": "url_template",
"type": "string",
"label": {
"de_DE": "URL-Template",
"en_US": "URL Template"
},
"help": {
"de_DE": "URL, optional als Go-Template über das zu verarbeitende plugin.NotificationRequest.",
"en_US": "URL, optionally as a Go template over the current plugin.NotificationRequest."
},
"required": true,
"min": null,
"max": null
},
{
"name": "response_status_codes",
"type": "string",
"label": {
"de_DE": "Antwort-Status-Codes",
"en_US": "Response Status Codes"
},
"help": {
"de_DE": "Kommaseparierte Liste erwarteter Status-Code der HTTP-Antwort, z.B.: 200,201,202,208,418",
"en_US": "Comma separated list of expected HTTP response status code, e.g., 200,201,202,208,418"
},
"default": "200",
"min": null,
"max": null
}
]
},
"id": 1
}
SetConfig¶
The SetConfig
method configures the channel.
The Icinga Notifications daemon will call this method at least once on each channel before sending the first notifications to initialize the channel plugin.
The passed JSON object in the request’s param
field reflects the objects from GetInfo
‘s config_attrs
.
Each object in the config_attrs
array must be configurable,
using its name
attribute as a key together along with the desired configuration value,
which must be of the type specified in the type
field.
To illustrate, the URL template from the above output is configurable with the following JSON object passed in params
:
{
"url_template": "http://localhost:8000/update/{{.Incident.Id}}"
}
If the channel plugin has successfully configured itself, a response without a result
must be returned.
Otherwise, if the channel decides that the provided configuration is incorrect, an error
must be returned.
This may happen if, for example, an invalid configuration value was given.
Example SetConfig Request¶
{
"method": "SetConfig",
"params": {
"url_template": "http://localhost:8000/update/{{.Incident.Id}}",
"response_status_codes": "200"
},
"id": 2
}
Example SetConfig Response¶
{
"id": 2
}
SendNotification¶
The SendNotification
method requests the channel to dispatch notifications.
Within the request’s params
, a JSON object representing a
NotificationRequest
is passed.
If the channel is unable to send a notification, an error
must be returned.
This may be due to channel-specific reasons, such as an email channel where the SMTP server is unavailable,
or if the channel is missing required configuration values.
Example SendNotification Request¶
{
"method": "SendNotification",
"params": {
"contact": {
"full_name": "icingaadmin",
"addresses": [
{
"type": "email",
"address": "icingaaadmin@example.com"
}
]
},
"object": {
"name": "dummy-816!random fortune",
"url": "http://localhost/icingaweb2/icingadb/service?name=random%20fortune&host.name=dummy-816",
"tags": {
"host": "dummy-816",
"service": "random fortune"
},
"extra_tags": {
"hostgroup/app-mobile": "",
"hostgroup/department-dev": "",
"hostgroup/env-prod": "",
"hostgroup/location-rome": "",
"servicegroup/app-storage": "",
"servicegroup/department-ps": "",
"servicegroup/env-prod": "",
"servicegroup/location-rome": ""
}
},
"incident": {
"id": 1437,
"url": "http://localhost/icingaweb2/notifications/incident?id=1437",
"severity": "crit"
},
"event": {
"time": "2024-07-12T10:47:30.445439055Z",
"type": "state",
"username": "",
"message": "Q:\tWhat looks like a cat, flies like a bat, brays like a donkey, and\n\tplays like a monkey?\nA:\tNothing."
}
},
"id": 3
}
Example SendNotification Response¶
{
"id": 3
}
Channel Configuration¶
A channel offers its configuration options through its response to the GetInfo
method call.
Each configuration option is described by a
ConfigOption
entry
in the config_attrs
array.
Those information will be queried once by Icinga Notifications upon startup and stored in the database.
Depending on the ConfigOption
‘s type, Icinga Notifications Web will render different form element.
For example, a text
will result in an input box, while options
will result in a multi-select list.
When a user configures a Channel in Icinga Notifications Web, the configuration will be stored in the database as JSON.
More specifically, a JSON object mapping config_attrs.name
to the configured value is stored,
as expected as the params
for the SetConfig
method.
Since ConfigOption
s may have defaults defined,
Icinga Notifications Web will not add unchanged defaults to the configuration JSON object.
Therefore, the channel plugin is expected to use their offered default value if the key-value pair is absent.
A SetConfig
implementation may follow this logic by first setting its defaults and
then overwriting its state based on the configuration received via the params
.
Finally, Icinga Notifications will start a new process for this channel and
pass the stored JSON object to the channel by calling the SetConfig
method.
The process is kept alive and receives occasional SendNotification
method calls.
Writing Channel Plugins¶
Tip
Icinga Notifications comes with a Webhook channel plugin. Consider using this channel if your transport uses HTTP instead of writing a custom channel.
Tip
When developing custom channels, consider naming them with a unique prefix,
as additional channels will be added to Icinga Notifications in the future.
For example, name your channel x_irc
or my_irc
instead of irc
.
The channels that ship with Icinga Notifications can only cover some use cases. Therefore, we encourage you to develop your own channels that cover your specific needs.
Writing Channel Plugins in Go¶
Warning
As this is still an early preview version, things might change. There may still be severe bugs and incompatible changes may happen without any notice.
Since Icinga Notifications and all of its channels are written in the Go programming language,
libraries already used internally can be reused.
In particular, the Plugin
interface must be implemented, requesting methods for all the RPC methods described above.
To respect the channel configuration logic described above,
an implementation of SetConfig
should start by calling
PopulateDefaults
.
The channel plugin’s main
function should call
the RunPlugin
function,
taking care about calling the RPC method implementations.
For concrete examples, there are the implemented channels in the Icinga Notifications repository at
./cmd/channels
.