Skip to content

Instantly share code, notes, and snippets.

@mzupan
Created February 5, 2016 14:51
Show Gist options
  • Save mzupan/24d59edf3755d7b4430b to your computer and use it in GitHub Desktop.
Save mzupan/24d59edf3755d7b4430b to your computer and use it in GitHub Desktop.
sensu salt module and state. Not 100% but it creates/deletes
# -*- coding: utf-8 -*-
'''
Support for Sensu
.. note::
The functions in here are generic functions designed to work with
all sensu.
'''
import logging
import os
import json
import difflib
import tempfile
import contextlib
from salt.utils import fopen
from salt.exceptions import CommandExecutionError
log = logging.getLogger(__name__)
def __virtual__():
'''
Only load the module if sensu is installed in the generic location
'''
if os.path.exists("/opt/sensu"):
return 'sensu'
return False
def version_server():
'''
Return server version (``/opt/sensu/bin/sensu-server -V``)
CLI Example:
.. code-block:: bash
salt '*' sensu.version_server
'''
cmd = '/opt/sensu/bin/sensu-server -V'
out = __salt__['cmd.run'](cmd).splitlines()
ret = out[0]
return ret
def version_client():
'''
Return server version (``/opt/sensu/bin/sensu-client -V``)
CLI Example:
.. code-block:: bash
salt '*' sensu.version_client
'''
cmd = '/opt/sensu/bin/sensu-client -V'
out = __salt__['cmd.run'](cmd).splitlines()
ret = out[0]
return ret
def delete(name):
'''
Create sensu check json file in /etc/sensu/conf.d/checks
name
File for the check json file you want to delete
CLI Example:
.. code-block:: bash
salt '*' sensu.delete check_loadavg"
'''
path = "/etc/sensu/conf.d/checks/{n}.json".format(n=name)
try:
#
# find out if its a client check or server
if 'standalone' in open(path).read():
os.remove(path)
cmd = '/etc/init.d/sensu-client restart'
out = __salt__['cmd.run'](cmd).splitlines()
else:
os.remove(path)
cmd = '/etc/init.d/sensu-server restart'
out = __salt__['cmd.run'](cmd).splitlines()
cmd = '/etc/init.d/sensu-api restart'
out = __salt__['cmd.run'](cmd).splitlines()
return True
except (OSError, IOError) as exc:
raise CommandExecutionError(
'Could not remove {0!r}: {1}'.format(path, exc)
)
return False
def check(name,
cmd=None,
interval=60,
subscribers=[],
handlers=[],
occurrences=1,
additional=[]):
'''
Create sensu check json file in /etc/sensu/conf.d/checks
name
File for the check json file
config
Sensu check options
.. note::
This function is not meant to be used from the command line.
Config is meant to be an ordered dict of all of the check options.
CLI Example:
.. code-block:: bash
salt '*' sensu.check check_loadavg config="{'cmd': '/path/to/check/script', 'interval': 30}"
'''
template = {
'checks': {
name: {
'command': None,
'interval': 60,
'subscribers': [],
'handlers': [],
'occurrences': 1,
'additional': []
}
}
}
template['checks'][name]['command'] = cmd
template['checks'][name]['interval'] = interval
if len(subscribers) > 0:
template['checks'][name]['subscribers'] = subscribers
else:
del(template['checks'][name]['subscribers'])
template['checks'][name]['standalone'] = True
template['checks'][name]['handlers'] = handlers
template['checks'][name]['occurrences'] = occurrences
#
# any additional add it to the template
for a in additional:
if not isinstance(a, dict):
continue
[(k, v)] = a.items()
template['checks'][name][k] = v
del(template['checks'][name]['additional'])
sfn = tempfile.NamedTemporaryFile(delete=False)
sfn.write(json.dumps(template, indent=4, sort_keys=True))
sfn.seek(0)
#
# open the new file
check_new = fopen(sfn.name, 'rb').readlines()
#
# do we have a file
try:
check_old = fopen('/etc/sensu/conf.d/checks/%s.json' % name, 'rb').readlines()
except:
check_old = []
diff = ''.join(difflib.unified_diff(check_old, check_new))
with open('/etc/sensu/conf.d/checks/%s.json' % name, 'w') as outfile:
json_out = json.dumps(template, indent=4, sort_keys=True)
outfile.write(json_out)
if diff:
#
# hacky fix for now
if len(subscribers) == 0:
cmd = 'servie sensu-client restart'
out = __salt__['cmd.run'](cmd).splitlines()
else:
cmd = 'service sensu-server restart'
out = __salt__['cmd.run'](cmd).splitlines()
cmd = 'service sensu-api restart'
out = __salt__['cmd.run'](cmd).splitlines()
return diff
return ''
# -*- coding: utf-8 -*-
'''
Sensu state
.. code-block:: yaml
/etc/sensu/conf.d/checks/check_name.json:
sensu.check:
- cmd: /path/to/check_app
- interval: 30
- subscribers:
- web
- lb
- handlers:
- mail
- irc
- occurrences: 5
- additional:
- playbook: http://domain.com/playbook/url
'''
# Import python libs
import os.path
# Import Salt libs
import salt.utils
from salt.exceptions import CommandExecutionError
def _error(ret, err_msg):
ret['result'] = False
ret['comment'] = err_msg
return ret
def delete(name):
ret = {'name': name,
'changes': {},
'result': True,
'comment': ''}
if not name:
return _error(ret, 'Must provide name to sensu.delete')
path = "/etc/sensu/conf.d/checks/{n}.json".format(n=name)
if os.path.isfile(path):
if __opts__['test']:
ret['result'] = None
ret['comment'] = 'File {0} is set for removal'.format(path)
return ret
try:
__salt__['sensu.delete'](name)
ret['comment'] = 'Removed file {0}'.format(path)
ret['changes']['removed'] = name
return ret
except CommandExecutionError as exc:
return _error(ret, '{0}'.format(exc))
ret['comment'] = 'File {0} is not present'.format(path)
return ret
def check(name,
cmd,
interval,
subscribers,
handlers,
occurrences,
additional):
ret = {'name': name,
'changes': {},
'result': None,
'comment': ''}
diff = __salt__['sensu.check'](name=name,
cmd=cmd,
interval=interval,
subscribers=subscribers,
handlers=handlers,
occurrences=occurrences,
additional=additional)
if diff:
ret['result'] = True
ret['comment'] = 'The file {0} is set to be changed'.format(name)
ret['changes']['diff'] = diff
else:
ret['result'] = True
ret['comment'] = 'The file {0} is in the correct state'.format(name)
return ret
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment