%PDF- %PDF-
Direktori : /lib/python2.7/site-packages/salt/modules/ |
Current File : //lib/python2.7/site-packages/salt/modules/beacons.py |
# -*- coding: utf-8 -*- ''' Module for managing the Salt beacons on a minion .. versionadded:: 2015.8.0 ''' # Import Python libs from __future__ import absolute_import, print_function, unicode_literals import difflib import logging import os # Import Salt libs import salt.ext.six as six import salt.utils.event import salt.utils.files import salt.utils.yaml from salt.ext.six.moves import map # Get logging started log = logging.getLogger(__name__) default_event_wait = 60 __func_alias__ = { 'list_': 'list', 'reload_': 'reload' } def list_(return_yaml=True, include_pillar=True, include_opts=True, **kwargs): ''' List the beacons currently configured on the minion :param return_yaml: Whether to return YAML formatted output, default ``True`` :param include_pillar: Whether to include beacons that are configured in pillar, default is ``True``. :param include_opts: Whether to include beacons that are configured in opts, default is ``True``. :return: List of currently configured Beacons. CLI Example: .. code-block:: bash salt '*' beacons.list ''' beacons = None try: eventer = salt.utils.event.get_event('minion', opts=__opts__, listen=True) res = __salt__['event.fire']({'func': 'list', 'include_pillar': include_pillar, 'include_opts': include_opts}, 'manage_beacons') if res: event_ret = eventer.get_event( tag='/salt/minion/minion_beacons_list_complete', wait=kwargs.get('timeout', default_event_wait)) log.debug('event_ret %s', event_ret) if event_ret and event_ret['complete']: beacons = event_ret['beacons'] except KeyError: # Effectively a no-op, since we can't really return without an event system ret = {} ret['result'] = False ret['comment'] = 'Event module not available. Beacon add failed.' return ret if beacons: if return_yaml: tmp = {'beacons': beacons} return salt.utils.yaml.safe_dump(tmp, default_flow_style=False) else: return beacons else: return {'beacons': {}} def list_available(return_yaml=True, **kwargs): ''' List the beacons currently available on the minion :param return_yaml: Whether to return YAML formatted output, default ``True`` :return: List of currently configured Beacons. CLI Example: .. code-block:: bash salt '*' beacons.list_available ''' beacons = None try: eventer = salt.utils.event.get_event('minion', opts=__opts__, listen=True) res = __salt__['event.fire']({'func': 'list_available'}, 'manage_beacons') if res: event_ret = eventer.get_event( tag='/salt/minion/minion_beacons_list_available_complete', wait=kwargs.get('timeout', default_event_wait)) if event_ret and event_ret['complete']: beacons = event_ret['beacons'] except KeyError: # Effectively a no-op, since we can't really return without an event system ret = {} ret['result'] = False ret['comment'] = 'Event module not available. Beacon add failed.' return ret if beacons: if return_yaml: tmp = {'beacons': beacons} return salt.utils.yaml.safe_dump(tmp, default_flow_style=False) else: return beacons else: return {'beacons': {}} def add(name, beacon_data, **kwargs): ''' Add a beacon on the minion :param name: Name of the beacon to configure :param beacon_data: Dictionary or list containing configuration for beacon. :return: Boolean and status message on success or failure of add. CLI Example: .. code-block:: bash salt '*' beacons.add ps "[{'processes': {'salt-master': 'stopped', 'apache2': 'stopped'}}]" ''' ret = {'comment': 'Failed to add beacon {0}.'.format(name), 'result': False} if name in list_(return_yaml=False, **kwargs): ret['comment'] = 'Beacon {0} is already configured.'.format(name) return ret if name not in list_available(return_yaml=False, **kwargs): ret['comment'] = 'Beacon "{0}" is not available.'.format(name) return ret if 'test' in kwargs and kwargs['test']: ret['result'] = True ret['comment'] = 'Beacon: {0} would be added.'.format(name) else: try: # Attempt to load the beacon module so we have access to the validate function eventer = salt.utils.event.get_event('minion', opts=__opts__, listen=True) res = __salt__['event.fire']({'name': name, 'beacon_data': beacon_data, 'func': 'validate_beacon'}, 'manage_beacons') if res: event_ret = eventer.get_event( tag='/salt/minion/minion_beacon_validation_complete', wait=kwargs.get('timeout', default_event_wait)) valid = event_ret['valid'] vcomment = event_ret['vcomment'] if not valid: ret['result'] = False ret['comment'] = ('Beacon {0} configuration invalid, ' 'not adding.\n{1}'.format(name, vcomment)) return ret except KeyError: # Effectively a no-op, since we can't really return without an event system ret['comment'] = 'Event module not available. Beacon add failed.' try: res = __salt__['event.fire']({'name': name, 'beacon_data': beacon_data, 'func': 'add'}, 'manage_beacons') if res: event_ret = eventer.get_event( tag='/salt/minion/minion_beacon_add_complete', wait=kwargs.get('timeout', default_event_wait)) if event_ret and event_ret['complete']: beacons = event_ret['beacons'] if name in beacons and beacons[name] == beacon_data: ret['result'] = True ret['comment'] = 'Added beacon: {0}.'.format(name) else: ret['result'] = False ret['comment'] = event_ret['comment'] return ret except KeyError: # Effectively a no-op, since we can't really return without an event system ret['comment'] = 'Event module not available. Beacon add failed.' return ret def modify(name, beacon_data, **kwargs): ''' Modify an existing beacon :param name: Name of the beacon to configure :param beacon_data: Dictionary or list containing updated configuration for beacon. :return: Boolean and status message on success or failure of modify. CLI Example: .. code-block:: bash salt '*' beacons.modify ps "[{'salt-master': 'stopped'}, {'apache2': 'stopped'}]" ''' ret = {'comment': '', 'result': True} current_beacons = list_(return_yaml=False, **kwargs) if name not in current_beacons: ret['comment'] = 'Beacon {0} is not configured.'.format(name) return ret if 'test' in kwargs and kwargs['test']: ret['result'] = True ret['comment'] = 'Beacon: {0} would be added.'.format(name) else: try: # Attempt to load the beacon module so we have access to the validate function eventer = salt.utils.event.get_event('minion', opts=__opts__, listen=True) res = __salt__['event.fire']({'name': name, 'beacon_data': beacon_data, 'func': 'validate_beacon'}, 'manage_beacons') if res: event_ret = eventer.get_event( tag='/salt/minion/minion_beacon_validation_complete', wait=kwargs.get('timeout', default_event_wait)) valid = event_ret['valid'] vcomment = event_ret['vcomment'] if not valid: ret['result'] = False ret['comment'] = ('Beacon {0} configuration invalid, ' 'not adding.\n{1}'.format(name, vcomment)) return ret except KeyError: # Effectively a no-op, since we can't really return without an event system ret['comment'] = 'Event module not available. Beacon modify failed.' if not valid: ret['result'] = False ret['comment'] = ('Beacon {0} configuration invalid, ' 'not modifying.\n{1}'.format(name, vcomment)) return ret _current = current_beacons[name] _new = beacon_data if _new == _current: ret['comment'] = 'Job {0} in correct state'.format(name) return ret _current_lines = [] for _item in _current: _current_lines.extend(['{0}:{1}\n'.format(key, value) for (key, value) in six.iteritems(_item)]) _new_lines = [] for _item in _new: _new_lines.extend(['{0}:{1}\n'.format(key, value) for (key, value) in six.iteritems(_item)]) _diff = difflib.unified_diff(_current_lines, _new_lines) ret['changes'] = {} ret['changes']['diff'] = ''.join(_diff) try: eventer = salt.utils.event.get_event('minion', opts=__opts__, listen=True) res = __salt__['event.fire']({'name': name, 'beacon_data': beacon_data, 'func': 'modify'}, 'manage_beacons') if res: event_ret = eventer.get_event( tag='/salt/minion/minion_beacon_modify_complete', wait=kwargs.get('timeout', default_event_wait)) if event_ret and event_ret['complete']: beacons = event_ret['beacons'] if name in beacons and beacons[name] == beacon_data: ret['result'] = True ret['comment'] = 'Modified beacon: {0}.'.format(name) else: ret['result'] = False ret['comment'] = event_ret['comment'] return ret except KeyError: # Effectively a no-op, since we can't really return without an event system ret['comment'] = 'Event module not available. Beacon add failed.' return ret def delete(name, **kwargs): ''' Delete a beacon item :param name: Name of the beacon to delete :return: Boolean and status message on success or failure of delete. CLI Example: .. code-block:: bash salt '*' beacons.delete ps salt '*' beacons.delete load ''' ret = {'comment': 'Failed to delete beacon {0}.'.format(name), 'result': False} if 'test' in kwargs and kwargs['test']: ret['result'] = True ret['comment'] = 'Beacon: {0} would be deleted.'.format(name) else: try: eventer = salt.utils.event.get_event('minion', opts=__opts__, listen=True) res = __salt__['event.fire']({'name': name, 'func': 'delete'}, 'manage_beacons') if res: event_ret = eventer.get_event( tag='/salt/minion/minion_beacon_delete_complete', wait=kwargs.get('timeout', default_event_wait)) if event_ret and event_ret['complete']: beacons = event_ret['beacons'] if name not in beacons: ret['result'] = True ret['comment'] = 'Deleted beacon: {0}.'.format(name) return ret else: ret['result'] = False ret['comment'] = event_ret['comment'] except KeyError: # Effectively a no-op, since we can't really return without an event system ret['comment'] = 'Event module not available. Beacon add failed.' return ret def save(**kwargs): ''' Save all beacons on the minion :return: Boolean and status message on success or failure of save. CLI Example: .. code-block:: bash salt '*' beacons.save ''' ret = {'comment': [], 'result': True} beacons = list_(return_yaml=False, include_pillar=False, **kwargs) # move this file into an configurable opt sfn = os.path.join(__opts__['config_dir'], os.path.dirname(__opts__['default_include']), 'beacons.conf') if beacons: tmp = {'beacons': beacons} yaml_out = salt.utils.yaml.safe_dump(tmp, default_flow_style=False) else: yaml_out = '' try: with salt.utils.files.fopen(sfn, 'w+') as fp_: fp_.write(yaml_out) ret['comment'] = 'Beacons saved to {0}.'.format(sfn) except (IOError, OSError): ret['comment'] = 'Unable to write to beacons file at {0}. Check ' \ 'permissions.'.format(sfn) ret['result'] = False return ret def enable(**kwargs): ''' Enable all beacons on the minion Returns: bool: Boolean and status message on success or failure of enable. CLI Example: .. code-block:: bash salt '*' beacons.enable ''' ret = {'comment': [], 'result': True} if 'test' in kwargs and kwargs['test']: ret['comment'] = 'Beacons would be enabled.' else: try: eventer = salt.utils.event.get_event('minion', opts=__opts__, listen=True) res = __salt__['event.fire']({'func': 'enable'}, 'manage_beacons') if res: event_ret = eventer.get_event( tag='/salt/minion/minion_beacons_enabled_complete', wait=kwargs.get('timeout', default_event_wait)) if event_ret and event_ret['complete']: beacons = event_ret['beacons'] if 'enabled' in beacons and beacons['enabled']: ret['result'] = True ret['comment'] = 'Enabled beacons on minion.' else: ret['result'] = False ret['comment'] = 'Failed to enable beacons on minion.' return ret except KeyError: # Effectively a no-op, since we can't really return without an event system ret['comment'] = 'Event module not available. Beacons enable job failed.' return ret def disable(**kwargs): ''' Disable all beacons jobs on the minion :return: Boolean and status message on success or failure of disable. CLI Example: .. code-block:: bash salt '*' beacons.disable ''' ret = {'comment': [], 'result': True} if 'test' in kwargs and kwargs['test']: ret['comment'] = 'Beacons would be disabled.' else: try: eventer = salt.utils.event.get_event('minion', opts=__opts__, listen=True) res = __salt__['event.fire']({'func': 'disable'}, 'manage_beacons') if res: event_ret = eventer.get_event( tag='/salt/minion/minion_beacons_disabled_complete', wait=kwargs.get('timeout', default_event_wait)) log.debug('event_ret %s', event_ret) if event_ret and event_ret['complete']: beacons = event_ret['beacons'] if 'enabled' in beacons and not beacons['enabled']: ret['result'] = True ret['comment'] = 'Disabled beacons on minion.' else: ret['result'] = False ret['comment'] = 'Failed to disable beacons on minion.' return ret except KeyError: # Effectively a no-op, since we can't really return without an event system ret['comment'] = 'Event module not available. Beacons enable job failed.' return ret def _get_beacon_config_dict(beacon_config): beacon_config_dict = {} if isinstance(beacon_config, list): list(map(beacon_config_dict.update, beacon_config)) else: beacon_config_dict = beacon_config return beacon_config_dict def enable_beacon(name, **kwargs): ''' Enable beacon on the minion :name: Name of the beacon to enable. :return: Boolean and status message on success or failure of enable. CLI Example: .. code-block:: bash salt '*' beacons.enable_beacon ps ''' ret = {'comment': [], 'result': True} if not name: ret['comment'] = 'Beacon name is required.' ret['result'] = False return ret if 'test' in kwargs and kwargs['test']: ret['comment'] = 'Beacon {0} would be enabled.'.format(name) else: _beacons = list_(return_yaml=False, **kwargs) if name not in _beacons: ret['comment'] = 'Beacon {0} is not currently configured.'.format(name) ret['result'] = False return ret try: eventer = salt.utils.event.get_event('minion', opts=__opts__, listen=True) res = __salt__['event.fire']({'func': 'enable_beacon', 'name': name}, 'manage_beacons') if res: event_ret = eventer.get_event( tag='/salt/minion/minion_beacon_enabled_complete', wait=kwargs.get('timeout', default_event_wait)) if event_ret and event_ret['complete']: beacons = event_ret['beacons'] beacon_config_dict = _get_beacon_config_dict(beacons[name]) if 'enabled' in beacon_config_dict and beacon_config_dict['enabled']: ret['result'] = True ret['comment'] = 'Enabled beacon {0} on minion.'.format(name) else: ret['result'] = False ret['comment'] = 'Failed to enable beacon {0} on minion.'.format(name) else: ret['result'] = False ret['comment'] = event_ret['comment'] return ret except KeyError: # Effectively a no-op, since we can't really return without an event system ret['comment'] = 'Event module not available. Beacon enable job failed.' return ret def disable_beacon(name, **kwargs): ''' Disable beacon on the minion :name: Name of the beacon to disable. :return: Boolean and status message on success or failure of disable. CLI Example: .. code-block:: bash salt '*' beacons.disable_beacon ps ''' ret = {'comment': [], 'result': True} if not name: ret['comment'] = 'Beacon name is required.' ret['result'] = False return ret if 'test' in kwargs and kwargs['test']: ret['comment'] = 'Beacons would be enabled.' else: _beacons = list_(return_yaml=False, **kwargs) if name not in _beacons: ret['comment'] = 'Beacon {0} is not currently configured.'.format(name) ret['result'] = False return ret try: eventer = salt.utils.event.get_event('minion', opts=__opts__, listen=True) res = __salt__['event.fire']({'func': 'disable_beacon', 'name': name}, 'manage_beacons') if res: event_ret = eventer.get_event( tag='/salt/minion/minion_beacon_disabled_complete', wait=kwargs.get('timeout', default_event_wait)) if event_ret and event_ret['complete']: beacons = event_ret['beacons'] beacon_config_dict = _get_beacon_config_dict(beacons[name]) if 'enabled' in beacon_config_dict and not beacon_config_dict['enabled']: ret['result'] = True ret['comment'] = 'Disabled beacon {0} on minion.'.format(name) else: ret['result'] = False ret['comment'] = 'Failed to disable beacon on minion.' else: ret['result'] = False ret['comment'] = event_ret['comment'] return ret except KeyError: # Effectively a no-op, since we can't really return without an event system ret['comment'] = 'Event module not available. Beacon disable job failed.' return ret def reset(**kwargs): ''' Resest beacon configuration on the minion CLI Example: .. code-block:: bash salt '*' beacons.reset ''' ret = {'comment': [], 'result': True} if kwargs.get('test'): ret['comment'] = 'Beacons would be reset.' else: try: eventer = salt.utils.event.get_event('minion', opts=__opts__, listen=True) res = __salt__['event.fire']({'func': 'reset'}, 'manage_beacons') if res: wait = kwargs.get('timeout', default_event_wait) event_ret = eventer.get_event( tag='/salt/minion/minion_beacon_reset_complete', wait=wait) if event_ret and event_ret['complete']: ret['result'] = True ret['comment'] = 'Beacon configuration reset.' else: if event_ret is None: ret['result'] = False ret['comment'] = ( 'minion reset event not recieved after {} seconds' ).format(wait) else: ret['result'] = False ret['comment'] = event_ret['comment'] return ret except KeyError: # Effectively a no-op, since we can't really return without an event system ret['comment'] = 'Event module not available. Beacon disable job failed.' return ret