Various fixes to beacons to handle situations when beacons are stored in pillar. Updating execution module to report that beacons stored in pillar can not be managed via module. Updating add function to ensure beacon is available before attempting to add it. Updaitng unit tests to include new beacon is available check.

This commit is contained in:
Gareth J. Greenaway 2017-10-12 10:22:17 -07:00
parent 9dacbf69b9
commit a89c26c88e
No known key found for this signature in database
GPG key ID: 10B62F8A7CAD7A41
4 changed files with 99 additions and 33 deletions

View file

@ -199,13 +199,16 @@ class Beacon(object):
else:
self.opts['beacons'][name].append({'enabled': enabled_value})
def list_beacons(self):
def list_beacons(self, include_pillar):
'''
List the beacon items
'''
# 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': self.opts['beacons']},
_beacons = self.opts['beacons']
if include_pillar and 'beacons' in self.opts['pillar']:
_beacons.update(self.opts['pillar']['beacons'])
evt.fire_event({'complete': True, 'beacons': _beacons},
tag='/salt/minion/minion_beacons_list_complete')
return True
@ -236,8 +239,8 @@ class Beacon(object):
del beacon_data['enabled']
valid, vcomment = self.beacons[validate_str](beacon_data)
else:
log.info('Beacon %s does not have a validate'
' function, skipping validation.', name)
vcomment = ('Beacon %s does not have a validate'
' function, skipping validation.', name)
valid = True
# Fire the complete event back along with the list of beacons
@ -257,16 +260,23 @@ class Beacon(object):
data = {}
data[name] = beacon_data
if name in self.opts['beacons']:
log.info('Updating settings for beacon '
'item: %s', name)
if name in self.opts.get('pillar', {}).get('beacons', {}):
comment = ('Cannot update beacon item %s, '
'it is in pillar.', name)
complete = False
else:
log.info('Added new beacon item %s', name)
self.opts['beacons'].update(data)
if name in self.opts['beacons']:
comment = ('Updating settings for beacon '
'item: %s', name)
else:
comment = ('Added new beacon item %s', name)
complete = True
self.opts['beacons'].update(data)
# Fire the complete event back along with updated list of beacons
evt = salt.utils.event.get_event('minion', opts=self.opts)
evt.fire_event({'complete': True, 'beacons': self.opts['beacons']},
evt.fire_event({'complete': complete, 'comment': comment,
'beacons': self.opts['beacons']},
tag='/salt/minion/minion_beacon_add_complete')
return True
@ -279,13 +289,20 @@ class Beacon(object):
data = {}
data[name] = beacon_data
log.info('Updating settings for beacon '
'item: %s', name)
self.opts['beacons'].update(data)
if name in self.opts.get('pillar', {}).get('beacons', {}):
comment = ('Cannot modify beacon item %s, '
'it is in pillar.', name)
complete = False
else:
comment = ('Updating settings for beacon '
'item: %s', name)
complete = True
self.opts['beacons'].update(data)
# Fire the complete event back along with updated list of beacons
evt = salt.utils.event.get_event('minion', opts=self.opts)
evt.fire_event({'complete': True, 'beacons': self.opts['beacons']},
evt.fire_event({'complete': complete, 'comment': comment,
'beacons': self.opts['beacons']},
tag='/salt/minion/minion_beacon_modify_complete')
return True
@ -295,13 +312,22 @@ class Beacon(object):
Delete a beacon item
'''
if name in self.opts['beacons']:
log.info('Deleting beacon item %s', name)
del self.opts['beacons'][name]
if name in self.opts.get('pillar', {}).get('beacons', {}):
comment = ('Cannot delete beacon item 5s, '
'it is in pillar.', name)
complete = False
else:
if name in self.opts['beacons']:
del self.opts['beacons'][name]
comment = ('Deleting beacon item %s', name)
else:
comment = ('Beacon item %s not found.', name)
complete = True
# Fire the complete event back along with updated list of beacons
evt = salt.utils.event.get_event('minion', opts=self.opts)
evt.fire_event({'complete': True, 'beacons': self.opts['beacons']},
evt.fire_event({'complete': complete, 'comment': comment,
'beacons': self.opts['beacons']},
tag='/salt/minion/minion_beacon_delete_complete')
return True
@ -339,11 +365,19 @@ class Beacon(object):
Enable a beacon
'''
self._update_enabled(name, True)
if name in self.opts.get('pillar', {}).get('beacons', {}):
comment = ('Cannot enable beacon item %s, '
'it is in pillar.', name)
complete = False
else:
self._update_enabled(name, True)
comment = ('Enabling beacon item %s', name)
complete = True
# Fire the complete event back along with updated list of beacons
evt = salt.utils.event.get_event('minion', opts=self.opts)
evt.fire_event({'complete': True, 'beacons': self.opts['beacons']},
evt.fire_event({'complete': complete, 'comment': comment,
'beacons': self.opts['beacons']},
tag='/salt/minion/minion_beacon_enabled_complete')
return True
@ -353,11 +387,19 @@ class Beacon(object):
Disable a beacon
'''
self._update_enabled(name, False)
if name in self.opts.get('pillar', {}).get('beacons', {}):
comment = ('Cannot disable beacon item %s, '
'it is in pillar.', name)
complete = False
else:
self._update_enabled(name, False)
comment = ('Disabling beacon item %s', name)
complete = True
# Fire the complete event back along with updated list of beacons
evt = salt.utils.event.get_event('minion', opts=self.opts)
evt.fire_event({'complete': True, 'beacons': self.opts['beacons']},
evt.fire_event({'complete': complete, 'comment': comment,
'beacons': self.opts['beacons']},
tag='/salt/minion/minion_beacon_disabled_complete')
return True

View file

@ -2063,6 +2063,7 @@ class Minion(MinionBase):
func = data.get(u'func', None)
name = data.get(u'name', None)
beacon_data = data.get(u'beacon_data', None)
include_pillar = data.get(u'include_pillar', None)
if func == u'add':
self.beacons.add_beacon(name, beacon_data)
@ -2079,7 +2080,7 @@ class Minion(MinionBase):
elif func == u'disable_beacon':
self.beacons.disable_beacon(name)
elif func == u'list':
self.beacons.list_beacons()
self.beacons.list_beacons(include_pillar)
elif func == u'list_available':
self.beacons.list_available_beacons()
elif func == u'validate_beacon':

View file

@ -28,7 +28,7 @@ __func_alias__ = {
}
def list_(return_yaml=True):
def list_(return_yaml=True, include_pillar=True):
'''
List the beacons currently configured on the minion
@ -46,7 +46,9 @@ def list_(return_yaml=True):
try:
eventer = salt.utils.event.get_event('minion', opts=__opts__)
res = __salt__['event.fire']({'func': 'list'}, 'manage_beacons')
res = __salt__['event.fire']({'func': 'list',
'include_pillar': include_pillar},
'manage_beacons')
if res:
event_ret = eventer.get_event(tag='/salt/minion/minion_beacons_list_complete', wait=30)
log.debug('event_ret {0}'.format(event_ret))
@ -133,6 +135,10 @@ def add(name, beacon_data, **kwargs):
ret['comment'] = 'Beacon {0} is already configured.'.format(name)
return ret
if name not in list_available(return_yaml=False):
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)
@ -170,7 +176,10 @@ def add(name, beacon_data, **kwargs):
if name in beacons and beacons[name] == beacon_data:
ret['result'] = True
ret['comment'] = 'Added beacon: {0}.'.format(name)
return ret
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.'
@ -262,7 +271,10 @@ def modify(name, beacon_data, **kwargs):
if name in beacons and beacons[name] == beacon_data:
ret['result'] = True
ret['comment'] = 'Modified beacon: {0}.'.format(name)
return ret
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.'
@ -299,12 +311,14 @@ def delete(name, **kwargs):
if res:
event_ret = eventer.get_event(tag='/salt/minion/minion_beacon_delete_complete', wait=30)
if event_ret and event_ret['complete']:
log.debug('== event_ret {} =='.format(event_ret))
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.'
@ -327,7 +341,7 @@ def save():
ret = {'comment': [],
'result': True}
beacons = list_(return_yaml=False)
beacons = list_(return_yaml=False, include_pillar=False)
# move this file into an configurable opt
sfn = '{0}/{1}/beacons.conf'.format(__opts__['config_dir'],
@ -380,7 +394,7 @@ def enable(**kwargs):
else:
ret['result'] = False
ret['comment'] = 'Failed to enable beacons on minion.'
return ret
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.'
@ -420,7 +434,7 @@ def disable(**kwargs):
else:
ret['result'] = False
ret['comment'] = 'Failed to disable beacons on minion.'
return ret
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.'
@ -483,7 +497,10 @@ def enable_beacon(name, **kwargs):
else:
ret['result'] = False
ret['comment'] = 'Failed to enable beacon {0} on minion.'.format(name)
return ret
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.'
@ -536,7 +553,10 @@ def disable_beacon(name, **kwargs):
else:
ret['result'] = False
ret['comment'] = 'Failed to disable beacon on minion.'
return ret
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.'

View file

@ -59,6 +59,9 @@ class BeaconsTestCase(TestCase, LoaderModuleMockMixin):
event_returns = [{'complete': True,
'tag': '/salt/minion/minion_beacons_list_complete',
'beacons': {}},
{'complete': True,
'tag': '/salt/minion/minion_beacons_list_available_complete',
'beacons': ['ps']},
{'complete': True,
'valid': True,
'vcomment': '',