mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Adding list_available to show loaded & available beacons on the minion. Swapping out the way we validate beacon configuration to be able to support adding & modifying custom beacons.
This commit is contained in:
parent
d5abd98406
commit
803247f842
3 changed files with 117 additions and 59 deletions
|
@ -214,26 +214,42 @@ class Beacon(object):
|
|||
|
||||
return True
|
||||
|
||||
def list_available_beacons(self):
|
||||
'''
|
||||
List the available beacons
|
||||
'''
|
||||
_beacons = ['{0}'.format(_beacon.replace('.beacon', ''))
|
||||
for _beacon in list(self.beacons) if '.beacon' in _beacon]
|
||||
|
||||
# Fire the complete event back along with the list of beacons
|
||||
evt = salt.utils.event.get_event('minion', opts=self.opts)
|
||||
evt.fire_event({'complete': True, 'beacons': _beacons},
|
||||
tag='/salt/minion/minion_beacons_list_available_complete')
|
||||
|
||||
return True
|
||||
|
||||
def validate_beacon(self, name, beacon_data):
|
||||
'''
|
||||
Return available beacon functions
|
||||
'''
|
||||
validate_str = '{}.validate'
|
||||
validate_str = '{}.validate'.format(name)
|
||||
# Run the validate function if it's available,
|
||||
# otherwise there is a warning about it being missing
|
||||
if validate_str in self.beacons:
|
||||
valid, vcomment = self.beacons[validate_str](b_config[mod])
|
||||
|
||||
if not valid:
|
||||
log.info('Beacon %s configuration invalid, '
|
||||
'not running.\n%s', mod, vcomment)
|
||||
continue
|
||||
if 'enabled' in beacon_data:
|
||||
del beacon_data['enabled']
|
||||
valid, vcomment = self.beacons[validate_str](beacon_data)
|
||||
else:
|
||||
log.info('Beacon {0} does not have a validate'
|
||||
' function, skipping validation.'.format(name))
|
||||
valid = True
|
||||
|
||||
# Fire the complete event back along with the list of beacons
|
||||
evt = salt.utils.event.get_event('minion', opts=self.opts)
|
||||
log.debug('=== self.beacons {} ==='.format(list(self.beacons)))
|
||||
evt.fire_event({'complete': True, 'beacons': list(self.beacons)},
|
||||
tag='/salt/minion/minion_available_beacons')
|
||||
evt.fire_event({'complete': True,
|
||||
'vcomment': vcomment,
|
||||
'valid': valid},
|
||||
tag='/salt/minion/minion_beacon_validation_complete')
|
||||
|
||||
return True
|
||||
|
||||
|
|
|
@ -1930,6 +1930,8 @@ class Minion(MinionBase):
|
|||
self.beacons.disable_beacon(name)
|
||||
elif func == u'list':
|
||||
self.beacons.list_beacons()
|
||||
elif func == u'list_available':
|
||||
self.beacons.list_available_beacons()
|
||||
elif func == u'validate_beacon':
|
||||
self.beacons.validate_beacon(name, beacon_data)
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ from __future__ import absolute_import
|
|||
import difflib
|
||||
import logging
|
||||
import os
|
||||
import six
|
||||
import yaml
|
||||
|
||||
# Import Salt libs
|
||||
|
@ -69,6 +70,47 @@ def list_(return_yaml=True):
|
|||
return {'beacons': {}}
|
||||
|
||||
|
||||
def list_available(return_yaml=True):
|
||||
'''
|
||||
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__)
|
||||
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=30)
|
||||
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}
|
||||
yaml_out = yaml.safe_dump(tmp, default_flow_style=False)
|
||||
return yaml_out
|
||||
else:
|
||||
return beacons
|
||||
else:
|
||||
return {'beacons': {}}
|
||||
|
||||
|
||||
def add(name, beacon_data, **kwargs):
|
||||
'''
|
||||
Add a beacon on the minion
|
||||
|
@ -95,43 +137,34 @@ def add(name, beacon_data, **kwargs):
|
|||
ret['result'] = True
|
||||
ret['comment'] = 'Beacon: {0} would be added.'.format(name)
|
||||
else:
|
||||
# Attempt to load the beacon module so we have access to the validate function
|
||||
try:
|
||||
# Attempt to load the beacon module so we have access to the validate function
|
||||
eventer = salt.utils.event.get_event('minion', opts=__opts__)
|
||||
res = __salt__['event.fire']({'name': name, 'func': 'available_beacons'}, 'manage_beacons')
|
||||
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_available_beacons', wait=30)
|
||||
log.debug('=== event_ret {} ==='.format(event_ret))
|
||||
event_ret = eventer.get_event(tag='/salt/minion/minion_beacon_validation_complete', wait=30)
|
||||
valid = event_ret['valid']
|
||||
vcomment = event_ret['vcomment']
|
||||
|
||||
beacon_module = __import__('salt.beacons.' + name, fromlist=['validate'])
|
||||
log.debug('Successfully imported beacon.')
|
||||
except ImportError:
|
||||
ret['comment'] = 'Beacon {0} does not exist'.format(name)
|
||||
return ret
|
||||
if not valid:
|
||||
ret['result'] = False
|
||||
ret['comment'] = ('Beacon {0} configuration invalid, '
|
||||
'not adding.\n{1}'.format(name, vcomment))
|
||||
return ret
|
||||
|
||||
# Attempt to validate
|
||||
if hasattr(beacon_module, 'validate'):
|
||||
_beacon_data = beacon_data
|
||||
if 'enabled' in _beacon_data:
|
||||
del _beacon_data['enabled']
|
||||
valid, vcomment = beacon_module.validate(_beacon_data)
|
||||
else:
|
||||
log.info('Beacon {0} does not have a validate'
|
||||
' function, skipping validation.'.format(name))
|
||||
valid = True
|
||||
|
||||
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:
|
||||
eventer = salt.utils.event.get_event('minion', opts=__opts__)
|
||||
res = __salt__['event.fire']({'name': name, 'beacon_data': beacon_data, 'func': 'add'}, 'manage_beacons')
|
||||
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=30)
|
||||
log.debug('=== event_ret {} ==='.format(event_ret))
|
||||
if event_ret and event_ret['complete']:
|
||||
beacons = event_ret['beacons']
|
||||
if name in beacons and beacons[name] == beacon_data:
|
||||
|
@ -171,29 +204,32 @@ def modify(name, beacon_data, **kwargs):
|
|||
ret['result'] = True
|
||||
ret['comment'] = 'Beacon: {0} would be added.'.format(name)
|
||||
else:
|
||||
# Attempt to load the beacon module so we have access to the validate function
|
||||
try:
|
||||
beacon_module = __import__('salt.beacons.' + name, fromlist=['validate'])
|
||||
log.debug('Successfully imported beacon.')
|
||||
except ImportError:
|
||||
ret['comment'] = 'Beacon {0} does not exist'.format(name)
|
||||
return ret
|
||||
# Attempt to load the beacon module so we have access to the validate function
|
||||
eventer = salt.utils.event.get_event('minion', opts=__opts__)
|
||||
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=30)
|
||||
valid = event_ret['valid']
|
||||
vcomment = event_ret['vcomment']
|
||||
|
||||
# Attempt to validate
|
||||
if hasattr(beacon_module, 'validate'):
|
||||
_beacon_data = beacon_data
|
||||
if 'enabled' in _beacon_data:
|
||||
del _beacon_data['enabled']
|
||||
valid, vcomment = beacon_module.validate(_beacon_data)
|
||||
else:
|
||||
log.info('Beacon {0} does not have a validate'
|
||||
' function, skipping validation.'.format(name))
|
||||
valid = True
|
||||
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 adding.\n{1}'.format(name, vcomment))
|
||||
'not modifying.\n{1}'.format(name, vcomment))
|
||||
return ret
|
||||
|
||||
_current = current_beacons[name]
|
||||
|
@ -203,10 +239,14 @@ def modify(name, beacon_data, **kwargs):
|
|||
ret['comment'] = 'Job {0} in correct state'.format(name)
|
||||
return ret
|
||||
|
||||
_current_lines = ['{0}:{1}\n'.format(key, value)
|
||||
for (key, value) in sorted(_current.items())]
|
||||
_new_lines = ['{0}:{1}\n'.format(key, value)
|
||||
for (key, value) in sorted(_new.items())]
|
||||
_current_lines = []
|
||||
for _item in _current:
|
||||
_current_lines.extend(['{0}:{1}\n'.format(key, value)
|
||||
for (key, value) in six.iteritems(_current[0])])
|
||||
_new_lines = []
|
||||
for _item in _new:
|
||||
_new_lines.extend(['{0}:{1}\n'.format(key, value)
|
||||
for (key, value) in six.iteritems(_new[0])])
|
||||
_diff = difflib.unified_diff(_current_lines, _new_lines)
|
||||
|
||||
ret['changes'] = {}
|
||||
|
|
Loading…
Add table
Reference in a new issue