#!/usr/bin/python # (c) 2017, NetApp, Inc # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function __metaclass__ = type DOCUMENTATION = ''' module: sf_snapshot_schedule_manager deprecated: removed_in: 2.0.0 # was Ansible 2.11 why: This Module has been replaced alternative: please use M(netapp.elementsw.na_elementsw_snapshot_schedule) short_description: Manage SolidFire snapshot schedules extends_documentation_fragment: - community.general._netapp.solidfire author: Sumit Kumar (@timuster) description: - Create, destroy, or update accounts on SolidFire options: state: description: - Whether the specified schedule should exist or not. required: true choices: ['present', 'absent'] paused: description: - Pause / Resume a schedule. required: false recurring: description: - Should the schedule recur? required: false time_interval_days: description: Time interval in days. required: false default: 1 time_interval_hours: description: Time interval in hours. required: false default: 0 time_interval_minutes: description: Time interval in minutes. required: false default: 0 name: description: - Name for the snapshot schedule. required: true snapshot_name: description: - Name for the created snapshots. required: false volumes: description: - Volume IDs that you want to set the snapshot schedule for. - At least 1 volume ID is required for creating a new schedule. - required when C(state=present) required: false retention: description: - Retention period for the snapshot. - Format is 'HH:mm:ss'. required: false schedule_id: description: - The schedule ID for the schedule that you want to update or delete. required: false starting_date: description: - Starting date for the schedule. - Required when C(state=present). - Please use two '-' in the above format, or you may see an error- TypeError, is not JSON serializable description. - "Format: C(2016--12--01T00:00:00Z)" required: false ''' EXAMPLES = """ - name: Create Snapshot schedule sf_snapshot_schedule_manager: hostname: "{{ solidfire_hostname }}" username: "{{ solidfire_username }}" password: "{{ solidfire_password }}" state: present name: Schedule_A time_interval_days: 1 starting_date: 2016--12--01T00:00:00Z volumes: 7 - name: Update Snapshot schedule sf_snapshot_schedule_manager: hostname: "{{ solidfire_hostname }}" username: "{{ solidfire_username }}" password: "{{ solidfire_password }}" state: present schedule_id: 6 recurring: True snapshot_name: AnsibleSnapshots - name: Delete Snapshot schedule sf_snapshot_schedule_manager: hostname: "{{ solidfire_hostname }}" username: "{{ solidfire_username }}" password: "{{ solidfire_password }}" state: absent schedule_id: 6 """ RETURN = """ schedule_id: description: Schedule ID of the newly created schedule returned: success type: str """ import traceback from ansible.module_utils.basic import AnsibleModule from ansible.module_utils._text import to_native import ansible_collections.community.general.plugins.module_utils._netapp as netapp_utils HAS_SF_SDK = netapp_utils.has_sf_sdk() class SolidFireSnapShotSchedule(object): def __init__(self): self.argument_spec = netapp_utils.ontap_sf_host_argument_spec() self.argument_spec.update(dict( state=dict(required=True, choices=['present', 'absent']), name=dict(required=True, type='str'), time_interval_days=dict(required=False, type='int', default=1), time_interval_hours=dict(required=False, type='int', default=0), time_interval_minutes=dict(required=False, type='int', default=0), paused=dict(required=False, type='bool'), recurring=dict(required=False, type='bool'), starting_date=dict(type='str'), snapshot_name=dict(required=False, type='str'), volumes=dict(required=False, type='list'), retention=dict(required=False, type='str'), schedule_id=dict(type='int'), )) self.module = AnsibleModule( argument_spec=self.argument_spec, required_if=[ ('state', 'present', ['starting_date', 'volumes']) ], supports_check_mode=True ) p = self.module.params # set up state variables self.state = p['state'] self.name = p['name'] # self.interval = p['interval'] self.time_interval_days = p['time_interval_days'] self.time_interval_hours = p['time_interval_hours'] self.time_interval_minutes = p['time_interval_minutes'] self.paused = p['paused'] self.recurring = p['recurring'] self.starting_date = p['starting_date'] if self.starting_date is not None: self.starting_date = self.starting_date.replace("--", "-") self.snapshot_name = p['snapshot_name'] self.volumes = p['volumes'] self.retention = p['retention'] self.schedule_id = p['schedule_id'] self.create_schedule_result = None if HAS_SF_SDK is False: self.module.fail_json(msg="Unable to import the SolidFire Python SDK") else: self.sfe = netapp_utils.create_sf_connection(module=self.module) def get_schedule(self): schedule_list = self.sfe.list_schedules() for schedule in schedule_list.schedules: if schedule.name == self.name: # Update self.schedule_id: if self.schedule_id is not None: if schedule.schedule_id == self.schedule_id: return schedule else: self.schedule_id = schedule.schedule_id return schedule return None def create_schedule(self): try: sched = netapp_utils.Schedule() # if self.interval == 'time_interval': sched.frequency = netapp_utils.TimeIntervalFrequency(days=self.time_interval_days, hours=self.time_interval_hours, minutes=self.time_interval_minutes) # Create schedule sched.name = self.name sched.schedule_info = netapp_utils.ScheduleInfo( volume_ids=self.volumes, snapshot_name=self.snapshot_name, retention=self.retention ) sched.paused = self.paused sched.recurring = self.recurring sched.starting_date = self.starting_date self.create_schedule_result = self.sfe.create_schedule(schedule=sched) except Exception as e: self.module.fail_json(msg='Error creating schedule %s: %s' % (self.name, to_native(e)), exception=traceback.format_exc()) def delete_schedule(self): try: get_schedule_result = self.sfe.get_schedule(schedule_id=self.schedule_id) sched = get_schedule_result.schedule sched.to_be_deleted = True self.sfe.modify_schedule(schedule=sched) except Exception as e: self.module.fail_json(msg='Error deleting schedule %s: %s' % (self.name, to_native(e)), exception=traceback.format_exc()) def update_schedule(self): try: get_schedule_result = self.sfe.get_schedule(schedule_id=self.schedule_id) sched = get_schedule_result.schedule # Update schedule properties # if self.interval == 'time_interval': temp_frequency = netapp_utils.TimeIntervalFrequency(days=self.time_interval_days, hours=self.time_interval_hours, minutes=self.time_interval_minutes) if sched.frequency.days != temp_frequency.days or \ sched.frequency.hours != temp_frequency.hours \ or sched.frequency.minutes != temp_frequency.minutes: sched.frequency = temp_frequency sched.name = self.name if self.volumes is not None: sched.schedule_info.volume_ids = self.volumes if self.retention is not None: sched.schedule_info.retention = self.retention if self.snapshot_name is not None: sched.schedule_info.snapshot_name = self.snapshot_name if self.paused is not None: sched.paused = self.paused if self.recurring is not None: sched.recurring = self.recurring if self.starting_date is not None: sched.starting_date = self.starting_date # Make API call self.sfe.modify_schedule(schedule=sched) except Exception as e: self.module.fail_json(msg='Error updating schedule %s: %s' % (self.name, to_native(e)), exception=traceback.format_exc()) def apply(self): changed = False schedule_exists = False update_schedule = False schedule_detail = self.get_schedule() if schedule_detail: schedule_exists = True if self.state == 'absent': changed = True elif self.state == 'present': # Check if we need to update the account if self.retention is not None and schedule_detail.schedule_info.retention != self.retention: update_schedule = True changed = True elif schedule_detail.name != self.name: update_schedule = True changed = True elif self.snapshot_name is not None and schedule_detail.schedule_info.snapshot_name != self.snapshot_name: update_schedule = True changed = True elif self.volumes is not None and schedule_detail.schedule_info.volume_ids != self.volumes: update_schedule = True changed = True elif self.paused is not None and schedule_detail.paused != self.paused: update_schedule = True changed = True elif self.recurring is not None and schedule_detail.recurring != self.recurring: update_schedule = True changed = True elif self.starting_date is not None and schedule_detail.starting_date != self.starting_date: update_schedule = True changed = True elif self.time_interval_minutes is not None or self.time_interval_hours is not None \ or self.time_interval_days is not None: temp_frequency = netapp_utils.TimeIntervalFrequency(days=self.time_interval_days, hours=self.time_interval_hours, minutes=self.time_interval_minutes) if schedule_detail.frequency.days != temp_frequency.days or \ schedule_detail.frequency.hours != temp_frequency.hours \ or schedule_detail.frequency.minutes != temp_frequency.minutes: update_schedule = True changed = True else: if self.state == 'present': changed = True if changed: if self.module.check_mode: # Skip changes pass else: if self.state == 'present': if not schedule_exists: self.create_schedule() elif update_schedule: self.update_schedule() elif self.state == 'absent': self.delete_schedule() if self.create_schedule_result is not None: self.module.exit_json(changed=changed, schedule_id=self.create_schedule_result.schedule_id) else: self.module.exit_json(changed=changed) def main(): v = SolidFireSnapShotSchedule() v.apply() if __name__ == '__main__': main()