From 8cea3ac2b0314eea9a96bace470b24e1d678e624 Mon Sep 17 00:00:00 2001 From: "Gareth J. Greenaway" Date: Wed, 22 Apr 2015 14:18:32 -0700 Subject: [PATCH] Verify that various schedule management functions were successfull using events --- salt/modules/schedule.py | 248 ++++++++++++++++++++++++++++----------- salt/utils/schedule.py | 40 +++++++ 2 files changed, 217 insertions(+), 71 deletions(-) diff --git a/salt/modules/schedule.py b/salt/modules/schedule.py index 546416c009..12b31b8795 100644 --- a/salt/modules/schedule.py +++ b/salt/modules/schedule.py @@ -116,7 +116,7 @@ def purge(**kwargs): ''' ret = {'comment': [], - 'result': True} + 'result': False} schedule = __opts__['schedule'].copy() if 'schedule' in __pillar__: @@ -129,14 +129,25 @@ def purge(**kwargs): continue if 'test' in kwargs and kwargs['test']: + ret['result'] = True ret['comment'].append('Job: {0} would be deleted from schedule.'.format(name)) else: - out = __salt__['event.fire']({'name': name, 'func': 'delete'}, 'manage_schedule') - if out: - ret['comment'].append('Deleted job: {0} from schedule.'.format(name)) - else: - ret['comment'].append('Failed to delete job {0} from schedule.'.format(name)) - ret['result'] = False + try: + eventer = salt.utils.event.get_event('minion', opts=__opts__) + res = __salt__['event.fire']({'name': name, 'func': 'delete'}, 'manage_schedule') + if res: + event_ret = eventer.get_event(tag='/salt/minion/minion_schedule_delete_complete', wait=30) + if event_ret and event_ret['complete']: + schedule = event_ret['schedule'] + if name not in schedule: + ret['result'] = True + ret['comment'].append('Deleted job: {0} from schedule.'.format(name)) + else: + ret['comment'].append('Failed to delete job {0} from schedule.'.format(name)) + return ret + except KeyError: + # Effectively a no-op, since we can't really return without an event system + ret['comment'] = 'Event module not available. Schedule add failed.' return ret @@ -151,36 +162,55 @@ def delete(name, **kwargs): salt '*' schedule.delete job1 ''' - ret = {'comment': [], - 'result': True} + ret = {'comment': 'Failed to delete job {0} from schedule.'.format(name), + 'result': False} if not name: ret['comment'] = 'Job name is required.' - ret['result'] = False if name in __opts__['schedule']: if 'test' in kwargs and kwargs['test']: ret['comment'] = 'Job: {0} would be deleted from schedule.'.format(name) + ret['result'] = True else: - out = __salt__['event.fire']({'name': name, 'func': 'delete'}, 'manage_schedule') - if out: - ret['comment'] = 'Deleted Job {0} from schedule.'.format(name) - else: - ret['comment'] = 'Failed to delete job {0} from schedule.'.format(name) - ret['result'] = False + try: + eventer = salt.utils.event.get_event('minion', opts=__opts__) + res = __salt__['event.fire']({'name': name, 'func': 'delete'}, 'manage_schedule') + if res: + event_ret = eventer.get_event(tag='/salt/minion/minion_schedule_delete_complete', wait=30) + if event_ret and event_ret['complete']: + schedule = event_ret['schedule'] + if name not in schedule: + ret['result'] = True + ret['comment'] = 'Deleted Job {0} from schedule.'.format(name) + else: + ret['comment'] = 'Failed to delete job {0} from schedule.'.format(name) + return ret + except KeyError: + # Effectively a no-op, since we can't really return without an event system + ret['comment'] = 'Event module not available. Schedule add failed.' elif 'schedule' in __pillar__ and name in __pillar__['schedule']: if 'test' in kwargs and kwargs['test']: ret['comment'] = 'Job: {0} would be deleted from schedule.'.format(name) else: - out = __salt__['event.fire']({'name': name, 'where': 'pillar', 'func': 'delete'}, 'manage_schedule') - if out: - ret['comment'] = 'Deleted Job {0} from schedule.'.format(name) - else: - ret['comment'] = 'Failed to delete job {0} from schedule.'.format(name) - ret['result'] = False + try: + eventer = salt.utils.event.get_event('minion', opts=__opts__) + res = __salt__['event.fire']({'name': name, 'where': 'pillar', 'func': 'delete'}, 'manage_schedule') + if res: + event_ret = eventer.get_event(tag='/salt/minion/minion_schedule_delete_complete', wait=30) + if event_ret and event_ret['complete']: + schedule = event_ret['schedule'] + if name not in schedule: + ret['result'] = True + ret['comment'] = 'Deleted Job {0} from schedule.'.format(name) + else: + ret['comment'] = 'Failed to delete job {0} from schedule.'.format(name) + return ret + except KeyError: + # Effectively a no-op, since we can't really return without an event system + ret['comment'] = 'Event module not available. Schedule add failed.' else: ret['comment'] = 'Job {0} does not exist.'.format(name) - ret['result'] = False return ret @@ -283,8 +313,8 @@ def add(name, **kwargs): salt '*' schedule.add job2 function='cmd.run' job_args=['date >> /tmp/date.log'] seconds=60 ''' - ret = {'comment': [], - 'result': True} + ret = {'comment': 'Failed to add job {0} to schedule.'.format(name), + 'result': False} current_schedule = __opts__['schedule'].copy() if 'schedule' in __pillar__: @@ -307,29 +337,35 @@ def add(name, **kwargs): time_conflict = True if time_conflict: - ret['result'] = False ret['comment'] = 'Error: Unable to use "seconds", "minutes", "hours", or "days" with "when" or "cron" options.' return ret if 'when' in kwargs and 'cron' in kwargs: - ret['result'] = False ret['comment'] = 'Unable to use "when" and "cron" options together. Ignoring.' return ret _new = build_schedule_item(name, **kwargs) - schedule = {} - schedule[name] = _new + schedule_data = {} + schedule_data[name] = _new if 'test' in kwargs and kwargs['test']: ret['comment'] = 'Job: {0} would be added to schedule.'.format(name) else: - out = __salt__['event.fire']({'name': name, 'schedule': schedule, 'func': 'add'}, 'manage_schedule') - if out: - ret['comment'] = 'Added job: {0} to schedule.'.format(name) - else: - ret['comment'] = 'Failed to modify job {0} to schedule.'.format(name) - ret['result'] = False + try: + eventer = salt.utils.event.get_event('minion', opts=__opts__) + res = __salt__['event.fire']({'name': name, 'schedule': schedule_data, 'func': 'add'}, 'manage_schedule') + if res: + event_ret = eventer.get_event(tag='/salt/minion/minion_schedule_add_complete', wait=30) + if event_ret and event_ret['complete']: + schedule = event_ret['schedule'] + if name in schedule: + ret['result'] = True + ret['comment'] = 'Added job: {0} to schedule.'.format(name) + return ret + except KeyError: + # Effectively a no-op, since we can't really return without an event system + ret['comment'] = 'Event module not available. Schedule add failed.' return ret @@ -487,22 +523,46 @@ def enable_job(name, **kwargs): if 'test' in __opts__ and __opts__['test']: ret['comment'] = 'Job: {0} would be enabled in schedule.'.format(name) else: - out = __salt__['event.fire']({'name': name, 'func': 'enable_job'}, 'manage_schedule') - if out: - ret['comment'] = 'Enabled Job {0} in schedule.'.format(name) - else: - ret['comment'] = 'Failed to enable job {0} from schedule.'.format(name) - ret['result'] = False + try: + eventer = salt.utils.event.get_event('minion', opts=__opts__) + res = __salt__['event.fire']({'name': name, 'func': 'enable_job'}, 'manage_schedule') + if res: + event_ret = eventer.get_event(tag='/salt/minion/minion_schedule_enabled_job_complete', wait=30) + if event_ret and event_ret['complete']: + schedule = event_ret['schedule'] + # check item exists in schedule and is enabled + if name in schedule and schedule[name]['enabled']: + ret['result'] = True + ret['comment'] = 'Enabled Job {0} in schedule.'.format(name) + else: + ret['result'] = False + ret['comment'] = 'Failed to enable job {0} in schedule.'.format(name) + return ret + except KeyError: + # Effectively a no-op, since we can't really return without an event system + ret['comment'] = 'Event module not available. Schedule enable job failed.' elif 'schedule' in __pillar__ and name in __pillar__['schedule']: if 'test' in kwargs and kwargs['test']: ret['comment'].append('Job: {0} would be enabled in schedule.'.format(name)) else: - out = __salt__['event.fire']({'name': name, 'where': 'pillar', 'func': 'enable_job'}, 'manage_schedule') - if out: - ret['comment'] = 'Enabled Job {0} in schedule.'.format(name) - else: - ret['comment'] = 'Failed to enable job {0} from schedule.'.format(name) - ret['result'] = False + try: + eventer = salt.utils.event.get_event('minion', opts=__opts__) + res = __salt__['event.fire']({'name': name, 'where': 'pillar', 'func': 'enable_job'}, 'manage_schedule') + if res: + event_ret = eventer.get_event(tag='/salt/minion/minion_schedule_enabled_job_complete', wait=30) + if event_ret and event_ret['complete']: + schedule = event_ret['schedule'] + # check item exists in schedule and is enabled + if name in schedule and schedule[name]['enabled']: + ret['result'] = True + ret['comment'] = 'Enabled Job {0} in schedule.'.format(name) + else: + ret['result'] = False + ret['comment'] = 'Failed to enable job {0} in schedule.'.format(name) + return ret + except KeyError: + # Effectively a no-op, since we can't really return without an event system + ret['comment'] = 'Event module not available. Schedule enable job failed.' else: ret['comment'] = 'Job {0} does not exist.'.format(name) ret['result'] = False @@ -531,22 +591,46 @@ def disable_job(name, **kwargs): if 'test' in kwargs and kwargs['test']: ret['comment'] = 'Job: {0} would be disabled in schedule.'.format(name) else: - out = __salt__['event.fire']({'name': name, 'func': 'disable_job'}, 'manage_schedule') - if out: - ret['comment'] = 'Disabled Job {0} in schedule.'.format(name) - else: - ret['comment'] = 'Failed to disable job {0} from schedule.'.format(name) - ret['result'] = False + try: + eventer = salt.utils.event.get_event('minion', opts=__opts__) + res = __salt__['event.fire']({'name': name, 'func': 'disable_job'}, 'manage_schedule') + if res: + event_ret = eventer.get_event(tag='/salt/minion/minion_schedule_disabled_job_complete', wait=30) + if event_ret and event_ret['complete']: + schedule = event_ret['schedule'] + # check item exists in schedule and is enabled + if name in schedule and not schedule[name]['enabled']: + ret['result'] = True + ret['comment'] = 'Disabled Job {0} in schedule.'.format(name) + else: + ret['result'] = False + ret['comment'] = 'Failed to disable job {0} in schedule.'.format(name) + return ret + except KeyError: + # Effectively a no-op, since we can't really return without an event system + ret['comment'] = 'Event module not available. Schedule enable job failed.' elif 'schedule' in __pillar__ and name in __pillar__['schedule']: if 'test' in kwargs and kwargs['test']: ret['comment'].append('Job: {0} would be disabled in schedule.'.format(name)) else: - out = __salt__['event.fire']({'name': name, 'where': 'pillar', 'func': 'disable_job'}, 'manage_schedule') - if out: - ret['comment'] = 'Disabled Job {0} in schedule.'.format(name) - else: - ret['comment'] = 'Failed to disable job {0} from schedule.'.format(name) - ret['result'] = False + try: + eventer = salt.utils.event.get_event('minion', opts=__opts__) + res = __salt__['event.fire']({'name': name, 'where': 'pillar', 'func': 'disable_job'}, 'manage_schedule') + if res: + event_ret = eventer.get_event(tag='/salt/minion/minion_schedule_disabled_job_complete', wait=30) + if event_ret and event_ret['complete']: + schedule = event_ret['schedule'] + # check item exists in schedule and is enabled + if name in schedule and not schedule[name]['enabled']: + ret['result'] = True + ret['comment'] = 'Disabled Job {0} in schedule.'.format(name) + else: + ret['result'] = False + ret['comment'] = 'Failed to disable job {0} in schedule.'.format(name) + return ret + except KeyError: + # Effectively a no-op, since we can't really return without an event system + ret['comment'] = 'Event module not available. Schedule enable job failed.' else: ret['comment'] = 'Job {0} does not exist.'.format(name) ret['result'] = False @@ -604,12 +688,23 @@ def enable(**kwargs): if 'test' in kwargs and kwargs['test']: ret['comment'] = 'Schedule would be enabled.' else: - out = __salt__['event.fire']({'func': 'enable'}, 'manage_schedule') - if out: - ret['comment'] = 'Enabled schedule on minion.' - else: - ret['comment'] = 'Failed to enable schedule on minion.' - ret['result'] = False + try: + eventer = salt.utils.event.get_event('minion', opts=__opts__) + res = __salt__['event.fire']({'func': 'enable'}, 'manage_schedule') + if res: + event_ret = eventer.get_event(tag='/salt/minion/minion_schedule_enabled_complete', wait=30) + if event_ret and event_ret['complete']: + schedule = event_ret['schedule'] + if 'enabled' in schedule and schedule['enabled']: + ret['result'] = True + ret['comment'] = 'Enabled schedule on minion.' + else: + ret['result'] = False + ret['comment'] = 'Failed to enable schedule 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. Schedule enable job failed.' return ret @@ -630,12 +725,23 @@ def disable(**kwargs): if 'test' in kwargs and kwargs['test']: ret['comment'] = 'Schedule would be disabled.' else: - out = __salt__['event.fire']({'func': 'disable'}, 'manage_schedule') - if out: - ret['comment'] = 'Disabled schedule on minion.' - else: - ret['comment'] = 'Failed to disable schedule on minion.' - ret['result'] = False + try: + eventer = salt.utils.event.get_event('minion', opts=__opts__) + res = __salt__['event.fire']({'func': 'disable'}, 'manage_schedule') + if res: + event_ret = eventer.get_event(tag='/salt/minion/minion_schedule_disabled_complete', wait=30) + if event_ret and event_ret['complete']: + schedule = event_ret['schedule'] + if 'enabled' in schedule and not schedule['enabled']: + ret['result'] = True + ret['comment'] = 'Disabled schedule on minion.' + else: + ret['result'] = False + ret['comment'] = 'Failed to disable schedule 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. Schedule enable job failed.' return ret diff --git a/salt/utils/schedule.py b/salt/utils/schedule.py index ba766b7393..1c90e5781f 100644 --- a/salt/utils/schedule.py +++ b/salt/utils/schedule.py @@ -323,11 +323,18 @@ class Schedule(object): # ensure job exists, then delete it if name in self.opts['schedule']: del self.opts['schedule'][name] + schedule = self.opts['schedule'] else: # If job is in pillar, delete it there too if 'schedule' in self.opts['pillar']: if name in self.opts['pillar']['schedule']: del self.opts['pillar']['schedule'][name] + schedule = self.opts['pillar']['schedule'] + + # Fire the complete event back along with updated list of schedule + evt = salt.utils.event.get_event('minion', opts=self.opts) + evt.fire_event({'complete': True, 'schedule': schedule}, + tag='/salt/minion/minion_schedule_delete_complete') # remove from self.intervals if name in self.intervals: @@ -354,7 +361,14 @@ class Schedule(object): 'job: {0}'.format(new_job)) else: log.info('Added new job {0} to scheduler'.format(new_job)) + self.opts['schedule'].update(data) + + # Fire the complete event back along with updated list of schedule + evt = salt.utils.event.get_event('minion', opts=self.opts) + evt.fire_event({'complete': True, 'schedule': self.opts['schedule']}, + tag='/salt/minion/minion_schedule_add_complete') + self.persist() def enable_job(self, name, where=None): @@ -363,8 +377,16 @@ class Schedule(object): ''' if where == 'pillar': self.opts['pillar']['schedule'][name]['enabled'] = True + schedule = self.opts['pillar']['schedule'] else: self.opts['schedule'][name]['enabled'] = True + schedule = self.opts['schedule'] + + # Fire the complete event back along with updated list of schedule + evt = salt.utils.event.get_event('minion', opts=self.opts) + evt.fire_event({'complete': True, 'schedule': schedule}, + tag='/salt/minion/minion_schedule_enabled_job_complete') + log.info('Enabling job {0} in scheduler'.format(name)) def disable_job(self, name, where=None): @@ -373,8 +395,16 @@ class Schedule(object): ''' if where == 'pillar': self.opts['pillar']['schedule'][name]['enabled'] = False + schedule = self.opts['pillar']['schedule'] else: self.opts['schedule'][name]['enabled'] = False + schedule = self.opts['schedule'] + + # Fire the complete event back along with updated list of schedule + evt = salt.utils.event.get_event('minion', opts=self.opts) + evt.fire_event({'complete': True, 'schedule': schedule}, + tag='/salt/minion/minion_schedule_disabled_job_complete') + log.info('Disabling job {0} in scheduler'.format(name)) def modify_job(self, name, schedule, where=None): @@ -434,12 +464,22 @@ class Schedule(object): ''' self.opts['schedule']['enabled'] = True + # Fire the complete event back along with updated list of schedule + evt = salt.utils.event.get_event('minion', opts=self.opts) + evt.fire_event({'complete': True, 'schedule': self.opts['schedule']}, + tag='/salt/minion/minion_schedule_enabled_complete') + def disable_schedule(self): ''' Disable the scheduler. ''' self.opts['schedule']['enabled'] = False + # Fire the complete event back along with updated list of schedule + evt = salt.utils.event.get_event('minion', opts=self.opts) + evt.fire_event({'complete': True, 'schedule': self.opts['schedule']}, + tag='/salt/minion/minion_schedule_disabled_complete') + def reload(self, schedule): ''' Reload the schedule from saved schedule file.