#!/usr/bin/python # Copyright: (c) 2020, Dell Technologies # Apache License version 2.0 (see MODULE-LICENSE or http://www.apache.org/licenses/LICENSE-2.0.txt) """Ansible module for managing snapshot schedules on Unity""" from __future__ import absolute_import, division, print_function __metaclass__ = type DOCUMENTATION = r""" module: snapshotschedule version_added: '1.1.0' short_description: Manage snapshot schedules on Unity storage system description: - Managing snapshot schedules on Unity storage system includes creating new snapshot schedule, getting details of snapshot schedule, modifying attributes of snapshot schedule, and deleting snapshot schedule. extends_documentation_fragment: - dellemc.unity.unity author: - Akash Shendge (@shenda1) options: name: description: - The name of the snapshot schedule. - Name is mandatory for a create operation. - Specify either I(name) or I(id) (but not both) for any operation. type: str id: description: - The ID of the snapshot schedule. type: str type: description: - Type of the rule to be included in snapshot schedule. - Type is mandatory for any create or modify operation. - Once the snapshot schedule is created with one type it can be modified. type: str choices: ['every_n_hours', 'every_day', 'every_n_days', 'every_week', 'every_month'] interval: description: - Number of hours between snapshots. - Applicable only when rule type is C(every_n_hours). type: int hours_of_day: description: - Hours of the day when the snapshot will be taken. - Applicable only when rule type is C(every_day). type: list elements: int day_interval: description: - Number of days between snapshots. - Applicable only when rule type is C(every_n_days). type: int days_of_week: description: - Days of the week for which the snapshot schedule rule applies. - Applicable only when rule type is C(every_week). type: list elements: str choices: ['SUNDAY', 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY'] day_of_month: description: - Day of the month for which the snapshot schedule rule applies. - Applicable only when rule type is C(every_month). - Value should be [1, 31]. type: int hour: description: - The hour when the snapshot will be taken. - Applicable for C(every_n_days), C(every_week), C(every_month) rule types. - For create operation, if I(hour) parameter is not specified, value will be taken as C(0). - Value should be [0, 23]. type: int minute: description: - Minute offset from the hour when the snapshot will be taken. - Applicable for all rule types. - For a create operation, if I(minute) parameter is not specified, value will be taken as C(0). - Value should be [0, 59]. type: int desired_retention: description: - The number of days/hours for which snapshot will be retained. - When I(auto_delete) is C(true), I(desired_retention) cannot be specified. - Maximum desired retention supported is 31 days or 744 hours. type: int retention_unit: description: - The retention unit for the snapshot. default: 'hours' type: str choices: ['hours' , 'days'] auto_delete: description: - Indicates whether the system can automatically delete the snapshot. type: bool state: description: - Define whether the snapshot schedule should exist or not. type: str required: true choices: [absent, present] notes: - Snapshot schedule created through Ansible will have only one rule. - Modification of rule type is not allowed. Within the same type, other parameters can be modified. - If an existing snapshot schedule has more than 1 rule in it, only get and delete operation is allowed. - The I(check_mode) is not supported. """ EXAMPLES = r""" - name: Create snapshot schedule (Rule Type - every_n_hours) dellemc.unity.snapshotschedule: unispherehost: "{{unispherehost}}" validate_certs: "{{validate_certs}}" username: "{{username}}" password: "{{password}}" name: "Ansible_Every_N_Hours_Testing" type: "every_n_hours" interval: 6 desired_retention: 24 state: "{{state_present}}" - name: Create snapshot schedule (Rule Type - every_day) dellemc.unity.snapshotschedule: unispherehost: "{{unispherehost}}" validate_certs: "{{validate_certs}}" username: "{{username}}" password: "{{password}}" name: "Ansible_Every_Day_Testing" type: "every_day" hours_of_day: - 8 - 14 auto_delete: True state: "{{state_present}}" - name: Create snapshot schedule (Rule Type - every_n_days) dellemc.unity.snapshotschedule: unispherehost: "{{unispherehost}}" validate_certs: "{{validate_certs}}" username: "{{username}}" password: "{{password}}" name: "Ansible_Every_N_Day_Testing" type: "every_n_days" day_interval: 2 desired_retention: 16 retention_unit: "days" state: "{{state_present}}" - name: Create snapshot schedule (Rule Type - every_week) dellemc.unity.snapshotschedule: unispherehost: "{{unispherehost}}" validate_certs: "{{validate_certs}}" username: "{{username}}" password: "{{password}}" name: "Ansible_Every_Week_Testing" type: "every_week" days_of_week: - MONDAY - FRIDAY hour: 12 minute: 30 desired_retention: 200 state: "{{state_present}}" - name: Create snapshot schedule (Rule Type - every_month) dellemc.unity.snapshotschedule: unispherehost: "{{unispherehost}}" validate_certs: "{{validate_certs}}" username: "{{username}}" password: "{{password}}" name: "Ansible_Every_Month_Testing" type: "every_month" day_of_month: 17 auto_delete: True state: "{{state_present}}" - name: Get snapshot schedule details using name dellemc.unity.snapshotschedule: unispherehost: "{{unispherehost}}" validate_certs: "{{validate_certs}}" username: "{{username}}" password: "{{password}}" name: "Ansible_Every_N_Hours_Testing" state: "{{state_present}}" - name: Get snapshot schedule details using id dellemc.unity.snapshotschedule: unispherehost: "{{unispherehost}}" validate_certs: "{{validate_certs}}" username: "{{username}}" password: "{{password}}" id: "{{id}}" state: "{{state_present}}" - name: Modify snapshot schedule details id dellemc.unity.snapshotschedule: unispherehost: "{{unispherehost}}" validate_certs: "{{validate_certs}}" username: "{{username}}" password: "{{password}}" id: "{{id}}" type: "every_n_hours" interval: 8 state: "{{state_present}}" - name: Modify snapshot schedule using name dellemc.unity.snapshotschedule: unispherehost: "{{unispherehost}}" validate_certs: "{{validate_certs}}" username: "{{username}}" password: "{{password}}" name: "Ansible_Every_Day_Testing" type: "every_day" desired_retention: 200 auto_delete: False state: "{{state_present}}" - name: Delete snapshot schedule using id dellemc.unity.snapshotschedule: unispherehost: "{{unispherehost}}" validate_certs: "{{validate_certs}}" username: "{{username}}" password: "{{password}}" id: "{{id}}" state: "{{state_absent}}" - name: Delete snapshot schedule using name dellemc.unity.snapshotschedule: unispherehost: "{{unispherehost}}" validate_certs: "{{validate_certs}}" username: "{{username}}" password: "{{password}}" name: "Ansible_Every_Day_Testing" state: "{{state_absent}}" """ RETURN = r""" changed: description: Whether or not the resource has changed. returned: always type: bool sample: True snapshot_schedule_details: description: Details of the snapshot schedule. returned: When snapshot schedule exists type: dict contains: id: description: The system ID given to the snapshot schedule. type: str name: description: The name of the snapshot schedule. type: str luns: description: Details of volumes for which snapshot schedule applied. type: dict contains: UnityLunList: description: List of volumes for which snapshot schedule applied. type: list contains: UnityLun: description: Detail of volume. type: dict contains: id: description: The system ID given to volume. type: str rules: description: Details of rules that apply to snapshot schedule. type: list contains: id: description: The system ID of the rule. type: str interval: description: Number of days or hours between snaps, depending on the rule type. type: int hours: description: Hourly frequency for the snapshot schedule rule. type: list minute: description: Minute frequency for the snapshot schedule rule. type: int days_of_week: description: Days of the week for which the snapshot schedule rule applies. type: dict contains: DayOfWeekEnumList: description: Enumeration of days of the week. type: list days_of_month: description: Days of the month for which the snapshot schedule rule applies. type: list retention_time: description: Period of time in seconds for which to keep the snapshot. type: int retention_time_in_hours: description: Period of time in hours for which to keep the snapshot. type: int rule_type: description: Type of the rule applied to snapshot schedule. type: str is_auto_delete: description: Indicates whether the system can automatically delete the snapshot based on pool automatic-deletion thresholds. type: bool storage_resources: description: Details of storage resources for which snapshot. schedule applied. type: dict contains: UnityStorageResourceList: description: List of storage resources for which snapshot schedule applied. type: list contains: UnityStorageResource: description: Detail of storage resource. type: dict contains: id: description: The system ID given to storage resource. type: str sample: { "existed": true, "hash": 8742032390151, "id": "snapSch_63", "is_default": false, "is_modified": null, "is_sync_replicated": false, "luns": null, "modification_time": "2021-12-14 21:37:47.905000+00:00", "name": "SS7_empty_hour_SS", "rules": [ { "access_type": "FilesystemSnapAccessTypeEnum.CHECKPOINT", "days_of_month": null, "days_of_week": { "DayOfWeekEnumList": [] }, "existed": true, "hash": 8742032280772, "hours": [ 0 ], "id": "SchedRule_109", "interval": 2, "is_auto_delete": false, "minute": 0, "retention_time": 86400, "retention_time_in_hours": 24, "rule_type": "every_n_days", "type": "ScheduleTypeEnum.N_DAYS_AT_HHMM" } ], "storage_resources": null, "version": "ScheduleVersionEnum.LEGACY" } """ import logging from ansible.module_utils.basic import AnsibleModule from ansible_collections.dellemc.unity.plugins.module_utils.storage.dell \ import utils LOG = utils.get_logger('snapshotschedule') application_type = "Ansible/1.6.0" class SnapshotSchedule(object): """Class with snapshot schedule operations""" def __init__(self): """Define all parameters required by this module""" self.module_params = utils.get_unity_management_host_parameters() self.module_params.update(get_snapshotschedule_parameters()) mutually_exclusive = [['name', 'id'], ['interval', 'hour'], ['hours_of_day', 'hour'], ['interval', 'hours_of_day', 'day_interval', 'days_of_week', 'day_of_month']] required_one_of = [['name', 'id']] # initialize the Ansible module self.module = AnsibleModule( argument_spec=self.module_params, supports_check_mode=False, mutually_exclusive=mutually_exclusive, required_one_of=required_one_of ) utils.ensure_required_libs(self.module) self.unity_conn = utils.get_unity_unisphere_connection( self.module.params, application_type) def schedule_modify_required(self, schedule_details): """Check if the desired snapshot schedule state is different from existing snapshot schedule state :param schedule_details: The dict containing snapshot schedule details :return: Boolean value to indicate if modification is needed """ # Check if existing snapshot schedule has auto_delete = True and # playbook sets desired retention without mentioning auto_delete if schedule_details['rules'][0]['is_auto_delete'] and\ self.module.params['desired_retention']\ and self.module.params['auto_delete'] is None: self.module.fail_json(msg="Desired retention cannot be " "specified when auto_delete is true" ) if schedule_details['rules'][0]['retention_time'] and \ self.module.params['auto_delete']: self.module.fail_json(msg="auto_delete cannot be specified when" " existing desired retention is set") desired_rule_type = get_schedule_value(self.module.params['type']) existing_rule_string = schedule_details['rules'][0][ 'type'].split(".")[1] existing_rule_type = utils.ScheduleTypeEnum[ existing_rule_string]._get_properties()['value'] modified = False # Check if rule type is modified if desired_rule_type != existing_rule_type: self.module.fail_json(msg="Modification of rule type is not" " allowed.") # Convert desired retention to seconds duration_in_sec = convert_retention_to_seconds( self.module.params['desired_retention'], self.module.params['retention_unit']) if not duration_in_sec: duration_in_sec = schedule_details['rules'][0]['retention_time'] # Check if common parameters for the rules getting modified if (duration_in_sec and duration_in_sec != schedule_details[ 'rules'][0]['retention_time']): modified = True elif (self.module.params['auto_delete'] is not None and self.module.params['auto_delete'] != schedule_details['rules'] [0]['is_auto_delete']): modified = True if (self.module.params['minute'] is not None and self.module.params[ 'minute'] != schedule_details['rules'][0]['minute']): modified = True if not modified and desired_rule_type == 0: if (self.module.params['interval'] and self.module.params[ 'interval'] != schedule_details['rules'][0]['interval']): modified = True elif not modified and desired_rule_type == 1: if (self.module.params['hours_of_day'] and set(self.module.params['hours_of_day']) != set(schedule_details['rules'][0]['hours'])): modified = True elif not modified and desired_rule_type == 2: if (self.module.params['day_interval'] and self.module.params[ 'day_interval'] != schedule_details['rules'][0]['interval'])\ or (self.module.params['hour'] is not None and self.module.params['hour'] != schedule_details[ 'rules'][0]['hours'][0]): modified = True elif not modified and desired_rule_type == 3: days = schedule_details['rules'][0]['days_of_week'][ 'DayOfWeekEnumList'] existing_days = list() for day in days: temp = day.split(".") existing_days.append(temp[1]) if (self.module.params['days_of_week'] and set(self.module.params['days_of_week']) != set(existing_days)) or\ (self.module.params['hour'] is not None and self.module.params['hour'] != schedule_details['rules'][ 0]['hours'][0]): modified = True elif not modified and desired_rule_type == 4: if (self.module.params['day_of_month'] and self.module.params[ 'day_of_month'] != schedule_details['rules'][0][ 'days_of_month'][0]) or\ (self.module.params['hour'] is not None and self.module.params['hour'] != schedule_details['rules'][ 0]['hours'][0]): modified = True LOG.info("Modify Flag: %s", modified) return modified def get_days_of_week_enum(self, days_of_week): """Get the enum for days of week. :param days_of_week: The list of days of week :return: The list of days_of_week enum """ days_of_week_enum = [] for day in days_of_week: if day in utils.DayOfWeekEnum.__members__: days_of_week_enum.append(utils.DayOfWeekEnum[day]) else: errormsg = "Invalid choice {0} for days of week".format(day) LOG.error(errormsg) self.module.fail_json(msg=errormsg) return days_of_week_enum def create_rule(self, type, interval, hours_of_day, day_interval, days_of_week, day_of_month, hour, minute, desired_retention, retention_unit, auto_delete, schedule_details=None): """Create the rule.""" duration_in_sec = None if desired_retention: duration_in_sec = convert_retention_to_seconds(desired_retention, retention_unit) if not duration_in_sec and schedule_details: duration_in_sec = schedule_details['rules'][0]['retention_time'] if hour is None and schedule_details is None: hour = 0 if hour is None and schedule_details: if schedule_details['rules'][0]['hours'] is not None: hour = schedule_details['rules'][0]['hours'][0] if minute is None and schedule_details is None: minute = 0 if minute is None and schedule_details: minute = schedule_details['rules'][0]['minute'] try: if type == "every_n_hours": if not interval: interval = schedule_details['rules'][0]['interval'] rule_dict = utils.snap_schedule.UnitySnapScheduleRule.\ every_n_hours(hour_interval=interval, minute=minute, retention_time=duration_in_sec, is_auto_delete=auto_delete) elif type == "every_day": if not hours_of_day: hours_of_day = schedule_details['rules'][0]['hours'] rule_dict = utils.snap_schedule.UnitySnapScheduleRule.\ every_day(hours=hours_of_day, minute=minute, retention_time=duration_in_sec, is_auto_delete=auto_delete) elif type == "every_n_days": if not day_interval: day_interval = schedule_details['rules'][0]['interval'] rule_dict = utils.snap_schedule.UnitySnapScheduleRule.\ every_n_days(day_interval=day_interval, hour=hour, minute=minute, retention_time=duration_in_sec, is_auto_delete=auto_delete) elif type == "every_week": if days_of_week: days_of_week_enum = self.get_days_of_week_enum(days_of_week) else: days = schedule_details['rules'][0]['days_of_week'][ 'DayOfWeekEnumList'] existing_days = list() for day in days: temp = day.split(".") existing_days.append(temp[1]) days_of_week_enum = self.get_days_of_week_enum(days_of_week) rule_dict = utils.snap_schedule.UnitySnapScheduleRule.\ every_week(days_of_week=days_of_week_enum, hour=hour, minute=minute, retention_time=duration_in_sec, is_auto_delete=auto_delete) else: if day_of_month: day_of_month_list = [day_of_month] else: day_of_month_list = schedule_details['rules'][0][ 'days_of_month'] rule_dict = utils.snap_schedule.UnitySnapScheduleRule.\ every_month(days_of_month=day_of_month_list, hour=hour, minute=minute, retention_time=duration_in_sec, is_auto_delete=auto_delete) return rule_dict except Exception as e: errormsg = "Create operation of snapshot schedule rule " \ " failed with error {0}".format(str(e)) LOG.error(errormsg) self.module.fail_json(msg=errormsg) def create_snapshot_schedule(self, name, rule_dict): """Create snapshot schedule. :param name: The name of the snapshot schedule :param rule_dict: The dict of the rule :return: Boolean value to indicate if snapshot schedule created """ try: utils.snap_schedule.UnitySnapSchedule.create( cli=self.unity_conn._cli, name=name, rules=[rule_dict]) return True except Exception as e: errormsg = "Create operation of snapshot schedule {0} failed" \ " with error {1}".format(name, str(e)) LOG.error(errormsg) self.module.fail_json(msg=errormsg) def validate_desired_retention(self, desired_retention, retention_unit): """Validates the specified desired retention. :param desired_retention: Desired retention of the snapshot schedule :param retention_unit: Retention unit for the snapshot schedule """ if retention_unit == 'hours' and (desired_retention < 1 or desired_retention > 744): self.module.fail_json(msg="Please provide a valid integer as the" " desired retention between 1 and 744.") elif retention_unit == 'days' and (desired_retention < 1 or desired_retention > 31): self.module.fail_json(msg="Please provide a valid integer as the" " desired retention between 1 and 31.") def return_schedule_instance(self, id): """Return the snapshot schedule instance :param id: The id of the snapshot schedule :return: Instance of the snapshot schedule """ try: obj_schedule = utils.snap_schedule.UnitySnapSchedule.get( self.unity_conn._cli, id) return obj_schedule except Exception as e: error_msg = "Failed to get the snapshot schedule {0} instance" \ " with error {1}".format(id, str(e)) LOG.error(error_msg) self.module.fail_json(msg=error_msg) def delete_snapshot_schedule(self, id): """Delete snapshot schedule. :param id: The ID of the snapshot schedule :return: The boolean value to indicate if snapshot schedule deleted """ try: obj_schedule = self.return_schedule_instance(id=id) obj_schedule.delete() return True except Exception as e: errormsg = "Delete operation of snapshot schedule id:{0} failed" \ " with error {1}".format(id, str(e)) LOG.error(errormsg) self.module.fail_json(msg=errormsg) def modify_snapshot_schedule(self, id, schedule_details): """Modify snapshot schedule details. :param id: The id of the snapshot schedule :param schedule_details: The dict containing schedule details :return: The boolean value to indicate if snapshot schedule modified """ try: obj_schedule = self.return_schedule_instance(id=id) rule_id = schedule_details['rules'][0]['id'] if self.module.params['auto_delete'] is None: auto_delete = schedule_details['rules'][0]['is_auto_delete'] else: auto_delete = self.module.params['auto_delete'] if schedule_details['rules'][0]['is_auto_delete'] and\ self.module.params['desired_retention'] and\ self.module.params['auto_delete'] is False: auto_delete = False elif schedule_details['rules'][0]['retention_time']: auto_delete = None rule_dict = self.create_rule( self.module.params['type'], self.module.params['interval'], self.module.params['hours_of_day'], self.module.params['day_interval'], self.module.params['days_of_week'], self.module.params['day_of_month'], self.module.params['hour'], self.module.params['minute'], self.module.params['desired_retention'], self.module.params['retention_unit'], auto_delete, schedule_details) obj_schedule.modify(add_rules=[rule_dict], remove_rule_ids=[rule_id]) return True except Exception as e: errormsg = "Modify operation of snapshot schedule id:{0} failed" \ " with error {1}".format(id, str(e)) LOG.error(errormsg) self.module.fail_json(msg=errormsg) def get_details(self, id=None, name=None): """Get snapshot schedule details. :param id: The id of the snapshot schedule :param name: The name of the snapshot schedule :return: Dict containing snapshot schedule details if exists """ id_or_name = id if id else name errormsg = "Failed to get details of snapshot schedule {0} with" \ " error {1}" try: if not id: details = utils.snap_schedule.UnitySnapScheduleList.get( self.unity_conn._cli, name=name) if details: id = details[0].id if id: details = self.unity_conn.get_snap_schedule(_id=id) if id and details.existed: rule_list = [rules._get_properties() for rules in details.rules] for rule in rule_list: rule['retention_time_in_hours'] = int( rule['retention_time'] / 3600) rule['rule_type'] = get_rule_type(rule['type']) schedule_details = details._get_properties() schedule_details['rules'] = rule_list return schedule_details else: LOG.info("Failed to get the snapshot schedule %s", id_or_name) return None except utils.HttpError as e: if e.http_status == 401: auth_err = "Incorrect username or password, {0}".format( e.message) msg = errormsg.format(id_or_name, auth_err) LOG.error(msg) self.module.fail_json(msg=msg) else: msg = errormsg.format(id_or_name, str(e)) LOG.error(msg) self.module.fail_json(msg=msg) except utils.UnityResourceNotFoundError as e: msg = errormsg.format(id_or_name, str(e)) LOG.error(msg) return None except Exception as e: msg = errormsg.format(id_or_name, str(e)) LOG.error(msg) self.module.fail_json(msg=msg) def validate_parameters(self): """Validate the parameters.""" try: if self.module.params['interval'] is not None and\ self.module.params['interval'] <= 0: self.module.fail_json(msg="Interval can not be less than or" " equal to 0.") param_list = ['day_interval', 'day_of_month'] for param in param_list: if self.module.params[param] is not None and\ self.module.params[param] == 0: self.module.fail_json(msg="{0} can not be 0.".format( param)) except Exception as e: errormsg = "Failed to validate the module param with error" \ " {0}".format(str(e)) LOG.error(errormsg) self.module.fail_json(msg=errormsg) def perform_module_operation(self): """ Perform different actions on snapshot schedule module based on parameters chosen in playbook """ name = self.module.params['name'] id = self.module.params['id'] type = self.module.params['type'] interval = self.module.params['interval'] hours_of_day = self.module.params['hours_of_day'] day_interval = self.module.params['day_interval'] days_of_week = self.module.params['days_of_week'] day_of_month = self.module.params['day_of_month'] hour = self.module.params['hour'] minute = self.module.params['minute'] desired_retention = self.module.params['desired_retention'] retention_unit = self.module.params['retention_unit'] auto_delete = self.module.params['auto_delete'] state = self.module.params['state'] # result is a dictionary that contains changed status and snapshot # schedule details result = dict( changed=False, snapshot_schedule_details={} ) self.validate_parameters() if desired_retention is not None: self.validate_desired_retention(desired_retention, retention_unit) if auto_delete and desired_retention: self.module.fail_json(msg="Desired retention cannot be " "specified when auto_delete is true" ) schedule_details = self.get_details(name=name, id=id) if not id and schedule_details: id = schedule_details['id'] if state == 'present' and not schedule_details: if not name: msg = "The parameter name length is 0. It is too short." \ " The min length is 1." self.module.fail_json(msg=msg) if not type: self.module.fail_json(msg="Rule type is necessary to create" " snapshot schedule") if type == "every_n_hours" and interval is None: self.module.fail_json(msg="To create snapshot schedule with" " rule type every_n_hours, interval" " is the mandatory parameter.") elif type == "every_day" and hours_of_day is None: self.module.fail_json(msg="To create snapshot schedule with" " rule type every_day, hours_of_day" " is the mandatory parameter.") elif type == "every_n_days" and day_interval is None: self.module.fail_json(msg="To create snapshot schedule with" " rule type every_n_days," " day_interval is the mandatory" " parameter.") elif type == "every_week" and days_of_week is None: self.module.fail_json(msg="To create snapshot schedule with" " rule type every_week," " days_of_week is the mandatory" " parameter.") elif type == "every_month" and day_of_month is None: self.module.fail_json(msg="To create snapshot schedule with" " rule type every_month," " day_of_month is the mandatory" " parameter.") rule_dict = self.create_rule(type, interval, hours_of_day, day_interval, days_of_week, day_of_month, hour, minute, desired_retention, retention_unit, auto_delete) result['changed'] = self.create_snapshot_schedule(name, rule_dict) elif state == 'absent' and schedule_details: result['changed'] = self.delete_snapshot_schedule(id) if state == 'present' and type and schedule_details and\ len(schedule_details['rules']) == 1: if (self.schedule_modify_required(schedule_details)): result['changed'] = self.modify_snapshot_schedule( id, schedule_details) result['snapshot_schedule_details'] = self.get_details(name=name, id=id) self.module.exit_json(**result) def get_rule_type(type): """Get the rule type of schedule. :param type: The schedule type enum :return: The rule type of snapshot schedule """ schedule_type = { "ScheduleTypeEnum.N_HOURS_AT_MM": "every_n_hours", "ScheduleTypeEnum.DAY_AT_HHMM": "every_day", "ScheduleTypeEnum.N_DAYS_AT_HHMM": "every_n_days", "ScheduleTypeEnum.SELDAYS_AT_HHMM": "every_week", "ScheduleTypeEnum.NTH_DAYOFMONTH_AT_HHMM": "every_month" } return schedule_type.get(type) def get_schedule_value(type): """Get the enum for schedule. :param type: The type of rule :return: The enum value for rule """ rule_type = { "every_n_hours": 0, "every_day": 1, "every_n_days": 2, "every_week": 3, "every_month": 4 } return rule_type.get(type) def convert_retention_to_seconds(desired_retention, retention_unit): """Convert desired retention to seconds. :param desired_retention: The desired retention for snapshot schedule :param retention_unit: The retention unit for snapshot schedule :return: The integer value in seconds """ duration_in_sec = None if desired_retention: if retention_unit == 'hours': duration_in_sec = desired_retention * 60 * 60 else: duration_in_sec = desired_retention * 24 * 60 * 60 return duration_in_sec def get_snapshotschedule_parameters(): """This method provide parameters required for the ansible snapshot schedule module on Unity""" return dict( name=dict(type='str'), id=dict(type='str'), type=dict(type='str', choices=['every_n_hours', 'every_day', 'every_n_days', 'every_week', 'every_month']), interval=dict(type='int'), hours_of_day=dict(type='list', elements='int'), day_interval=dict(type='int'), days_of_week=dict(type='list', elements='str', choices=['SUNDAY', 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY']), day_of_month=dict(type='int'), hour=dict(type='int'), minute=dict(type='int'), desired_retention=dict(type='int'), retention_unit=dict(type='str', choices=['hours', 'days'], default='hours'), auto_delete=dict(type='bool'), state=dict(required=True, type='str', choices=['present', 'absent']) ) def main(): """ Create Unity snapshot schedule object and perform action on it based on user input from playbook""" obj = SnapshotSchedule() obj.perform_module_operation() if __name__ == '__main__': main()