Merge pull request #44771 from garethgreenaway/42676_backport_44071

[2017.7] Back porting #44071
This commit is contained in:
Nicole Thomas 2017-12-05 12:16:05 -05:00 committed by GitHub
commit 10442d9211
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 191 additions and 35 deletions

View file

@ -186,19 +186,60 @@ class Beacon(object):
else:
self.opts['beacons'][name].append({'enabled': enabled_value})
def list_beacons(self):
def _get_beacons(self,
include_opts=True,
include_pillar=True):
'''
Return the beacons data structure
'''
beacons = {}
if include_pillar:
pillar_beacons = self.opts.get('pillar', {}).get('beacons', {})
if not isinstance(pillar_beacons, dict):
raise ValueError('Beacons must be of type dict.')
beacons.update(pillar_beacons)
if include_opts:
opts_beacons = self.opts.get('beacons', {})
if not isinstance(opts_beacons, dict):
raise ValueError('Beacons must be of type dict.')
beacons.update(opts_beacons)
return beacons
def list_beacons(self,
include_pillar=True,
include_opts=True):
'''
List the beacon items
include_pillar: Whether to include beacons that are
configured in pillar, default is True.
include_opts: Whether to include beacons that are
configured in opts, default is True.
'''
beacons = self._get_beacons(include_pillar, include_opts)
# Fire the complete event back along with the list of beacons
evt = salt.utils.event.get_event('minion', opts=self.opts)
b_conf = self.functions['config.merge']('beacons')
self.opts['beacons'].update(b_conf)
evt.fire_event({'complete': True, 'beacons': self.opts['beacons']},
evt.fire_event({'complete': True, 'beacons': beacons},
tag='/salt/minion/minion_beacons_list_complete')
return True
def list_available_beacons(self):
'''
List the available beacons
'''
_beacons = ['{0}'.format(_beacon.replace('.beacon', ''))
for _beacon in 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 add_beacon(self, name, beacon_data):
'''
Add a beacon item
@ -207,16 +248,23 @@ class Beacon(object):
data = {}
data[name] = beacon_data
if name in self.opts['beacons']:
log.info('Updating settings for beacon '
'item: {0}'.format(name))
if name in self._get_beacons(include_opts=False):
comment = 'Cannot update beacon item {0}, ' \
'because it is configured in pillar.'.format(name)
complete = False
else:
log.info('Added new beacon item {0}'.format(name))
self.opts['beacons'].update(data)
if name in self.opts['beacons']:
comment = 'Updating settings for beacon ' \
'item: {0}'.format(name)
else:
comment = 'Added new beacon item: {0}'.format(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
@ -229,15 +277,21 @@ class Beacon(object):
data = {}
data[name] = beacon_data
log.info('Updating settings for beacon '
'item: {0}'.format(name))
self.opts['beacons'].update(data)
if name in self._get_beacons(include_opts=False):
comment = 'Cannot modify beacon item {0}, ' \
'it is configured in pillar.'.format(name)
complete = False
else:
comment = 'Updating settings for beacon ' \
'item: {0}'.format(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
def delete_beacon(self, name):
@ -245,13 +299,22 @@ class Beacon(object):
Delete a beacon item
'''
if name in self.opts['beacons']:
log.info('Deleting beacon item {0}'.format(name))
del self.opts['beacons'][name]
if name in self._get_beacons(include_opts=False):
comment = 'Cannot delete beacon item {0}, ' \
'it is configured in pillar.'.format(name)
complete = False
else:
if name in self.opts['beacons']:
del self.opts['beacons'][name]
comment = 'Deleting beacon item: {0}'.format(name)
else:
comment = 'Beacon item {0} not found.'.format(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
@ -289,11 +352,19 @@ class Beacon(object):
Enable a beacon
'''
self._update_enabled(name, True)
if name in self._get_beacons(include_opts=False):
comment = 'Cannot enable beacon item {0}, ' \
'it is configured in pillar.'.format(name)
complete = False
else:
self._update_enabled(name, True)
comment = 'Enabling beacon item {0}'.format(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
@ -303,11 +374,19 @@ class Beacon(object):
Disable a beacon
'''
self._update_enabled(name, False)
if name in self._get_beacons(include_opts=False):
comment = 'Cannot disable beacon item {0}, ' \
'it is configured in pillar.'.format(name)
complete = False
else:
self._update_enabled(name, False)
comment = 'Disabling beacon item {0}'.format(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

@ -1896,6 +1896,8 @@ class Minion(MinionBase):
func = data.get('func', None)
name = data.get('name', None)
beacon_data = data.get('beacon_data', None)
include_pillar = data.get(u'include_pillar', None)
include_opts = data.get(u'include_opts', None)
if func == 'add':
self.beacons.add_beacon(name, beacon_data)
@ -1912,7 +1914,9 @@ class Minion(MinionBase):
elif func == 'disable_beacon':
self.beacons.disable_beacon(name)
elif func == 'list':
self.beacons.list_beacons()
self.beacons.list_beacons(include_opts, include_pillar)
elif func == u'list_available':
self.beacons.list_available_beacons()
def environ_setenv(self, tag, data):
'''

View file

@ -27,12 +27,22 @@ __func_alias__ = {
}
def list_(return_yaml=True):
def list_(return_yaml=True,
include_pillar=True,
include_opts=True):
'''
List the beacons currently configured on the minion
:param return_yaml: Whether to return YAML formatted output, default True
:return: List of currently configured Beacons.
: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:
@ -45,7 +55,10 @@ 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,
'include_opts': include_opts},
'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))
@ -69,6 +82,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
@ -91,6 +145,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)
@ -130,7 +188,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.'
@ -215,7 +276,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.'
@ -257,6 +321,9 @@ def delete(name, **kwargs):
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.'
@ -279,7 +346,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'],
@ -332,7 +399,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.'
@ -372,7 +439,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.'
@ -435,7 +502,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.'
@ -488,7 +558,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.'