Skip to content

Instantly share code, notes, and snippets.

@hemebond
Last active July 1, 2017 05:28
Show Gist options
  • Save hemebond/a73d07c4fb4e9ac43b02c669f6065fe6 to your computer and use it in GitHub Desktop.
Save hemebond/a73d07c4fb4e9ac43b02c669f6065fe6 to your computer and use it in GitHub Desktop.
Saltstack Icinga2 API returner
# -*- coding: utf-8 -*-
'''
Return salt data to Icinga2 via the API
The following fields can be set in the minion conf file::
icinga2.url (required)
icinga2.service (optional)
icinga2.username (optional)
icinga2.password (optional)
icinga2.certificate (optional)
icinga2.key (optional)
Icinga2 settings may also be configured as::
icinga2:
url: http://icinga:5665
username: root
password: icinga
alternative.icinga2:
url: http://icinga:5665
certificate: /etc/icinga2/api.crt
key: /etc/icinga2/api.key
To use the Icinga2 API returner, append `--return icinga2` to the salt command. ex:
.. code-block:: bash
salt '*' test.ping --return icinga2
To use the alternative configuration, append `--return_config alternative` to the salt command. ex:
salt '*' test.ping --return icinga2 --return_config alternative
To override individual configuration items, append `--return_kwargs '{"key:": "value"}'` to the salt command.
.. versionadded:: 2016.3.0
.. code-block:: bash
salt '*' test.ping --return icinga2 --return_kwargs '{"service": "service-name"}'
'''
from __future__ import absolute_import
# Import python libs
import cgi
import logging
import json
import salt.returners
# pylint: disable=import-error,no-name-in-module,redefined-builtin
import salt.ext.six.moves.http_client
# pylint: enable=import-error,no-name-in-module,redefined-builtin
log = logging.getLogger(__name__)
__virtualname__ = 'icinga2'
def __virtual__():
return __virtualname__
def _get_options(ret=None):
"""
Get the requests options from salt.
"""
attrs = {
'url': 'url',
'service': 'service',
'username': 'username',
'password': 'password',
'certificate': 'certificate',
'key': 'key',
}
_options = salt.returners.get_returner_options(__virtualname__,
ret,
attrs,
__salt__=__salt__,
__opts__=__opts__)
log.debug('attrs {0}'.format(attrs))
return _options
def _post_data(options, ret):
"""
Post data to Icinga 2 API.
"""
url = '{}/v1/actions/process-check-result?service={}!{}'.format(options['url'], ret['id'], options['service'])
# cmd.run_all and nagios.run_all make the return attribute
# a dict instead of just a string
stderr = ''
if 'return' in ret:
r = ret.get('return', '')
if isinstance(ret['return'], dict):
stdout = ret['return']['stdout']
if ret['return']['stderr'] != '':
stderr = ret['return']['stderr']
else:
stdout = ret['return']
performance_data = []
try:
output, performance_data = stdout.split('|')
performance_data = performance_data.strip().split(' ')
except (ValueError, AttributeError):
output = str(stdout)
data = {
'exit_status': ret.get('retcode', ret['return']['retcode']),
'plugin_output': stderr or output,
'performance_data': performance_data,
'check_command': ret.get('fun_args', []),
'check_source': ret.get('id', ''),
}
log.debug(data)
query = {
'url': url,
'method': 'POST',
'data': json.dumps(data),
'verify_ssl': False,
'header_dict': {
'Accept': 'application/json',
},
'opts': __opts__,
}
log.debug(query)
if 'username' in options:
query['username'] = options['username']
query['password'] = options['password']
elif 'certificate' in options:
query['cert'] = (options['certificate'], options['key'])
res = salt.utils.http.query(**query)
return res
def returner(ret):
"""
Send a message to Nagios with the data.
"""
log.debug(ret)
_options = _get_options(ret)
log.debug('_options {0}'.format(_options))
_options['hostname'] = ret.get('id')
if 'url' not in _options or _options['url'] == '':
log.error('icinga2.url not defined in salt config')
return
if 'service' not in _options or _options['service'] == '':
log.error('icinga2.service not defined in salt config')
return
if not all(k in _options for k in ("username","password")):
if not all(k in _options for k in ("certificate", "key")):
log.error('Icinga2 returner requires either a username and password, or a certificate and key')
return
res = _post_data(_options, ret)
log.debug(res)
return res
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment