na_ontap_snapshot_policy: Add ability to multiple schedules (#57366)
This commit is contained in:
parent
5cc6486a2b
commit
a58570f1bc
2 changed files with 79 additions and 5 deletions
|
@ -43,10 +43,11 @@ options:
|
||||||
count:
|
count:
|
||||||
description:
|
description:
|
||||||
Retention count for the snapshots created by the schedule.
|
Retention count for the snapshots created by the schedule.
|
||||||
type: int
|
type: list
|
||||||
schedule:
|
schedule:
|
||||||
description:
|
description:
|
||||||
- schedule to be added inside the policy.
|
- schedule to be added inside the policy.
|
||||||
|
type: list
|
||||||
'''
|
'''
|
||||||
EXAMPLES = """
|
EXAMPLES = """
|
||||||
- name: create Snapshot policy
|
- name: create Snapshot policy
|
||||||
|
@ -61,6 +62,18 @@ EXAMPLES = """
|
||||||
hostname: "{{ netapp hostname }}"
|
hostname: "{{ netapp hostname }}"
|
||||||
https: False
|
https: False
|
||||||
|
|
||||||
|
- name: Create Snapshot policy with multiple schedules
|
||||||
|
na_ontap_snapshot_policy:
|
||||||
|
state: present
|
||||||
|
name: ansible2
|
||||||
|
schedule: ['hourly', 'daily', 'weekly', monthly', '5min']
|
||||||
|
count: [1, 2, 3, 4, 5]
|
||||||
|
enabled: True
|
||||||
|
username: "{{ netapp username }}"
|
||||||
|
password: "{{ netapp password }}"
|
||||||
|
hostname: "{{ netapp hostname }}"
|
||||||
|
https: False
|
||||||
|
|
||||||
- name: delete Snapshot policy
|
- name: delete Snapshot policy
|
||||||
na_ontap_snapshot_policy:
|
na_ontap_snapshot_policy:
|
||||||
state: absent
|
state: absent
|
||||||
|
@ -95,9 +108,10 @@ class NetAppOntapSnapshotPolicy(object):
|
||||||
'present', 'absent'], default='present'),
|
'present', 'absent'], default='present'),
|
||||||
name=dict(required=True, type="str"),
|
name=dict(required=True, type="str"),
|
||||||
enabled=dict(required=False, type="bool"),
|
enabled=dict(required=False, type="bool"),
|
||||||
count=dict(required=False, type="int"),
|
# count is a list of integers
|
||||||
|
count=dict(required=False, type="list", elements="int"),
|
||||||
comment=dict(required=False, type="str"),
|
comment=dict(required=False, type="str"),
|
||||||
schedule=dict(required=False, type="str")
|
schedule=dict(required=False, type="list", elements="str")
|
||||||
))
|
))
|
||||||
self.module = AnsibleModule(
|
self.module = AnsibleModule(
|
||||||
argument_spec=self.argument_spec,
|
argument_spec=self.argument_spec,
|
||||||
|
@ -138,16 +152,30 @@ class NetAppOntapSnapshotPolicy(object):
|
||||||
self.module.fail_json(msg=to_native(error), exception=traceback.format_exc())
|
self.module.fail_json(msg=to_native(error), exception=traceback.format_exc())
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def validate_parameters(self):
|
||||||
|
"""
|
||||||
|
Validate if each schedule has a count associated
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
if len(self.parameters['count']) > 5 or len(self.parameters['schedule']) > 5 or \
|
||||||
|
len(self.parameters['count']) != len(self.parameters['schedule']):
|
||||||
|
self.module.fail_json(msg="Error: A Snapshot policy can have up to a maximum of 5 schedules,"
|
||||||
|
"and a count representing maximum number of Snapshot copies for each schedule")
|
||||||
|
|
||||||
def create_snapshot_policy(self):
|
def create_snapshot_policy(self):
|
||||||
"""
|
"""
|
||||||
Creates a new snapshot policy
|
Creates a new snapshot policy
|
||||||
"""
|
"""
|
||||||
# set up required variables to create a snapshot policy
|
# set up required variables to create a snapshot policy
|
||||||
|
self.validate_parameters()
|
||||||
options = {'policy': self.parameters['name'],
|
options = {'policy': self.parameters['name'],
|
||||||
'enabled': str(self.parameters['enabled']),
|
'enabled': str(self.parameters['enabled']),
|
||||||
'count1': str(self.parameters['count']),
|
|
||||||
'schedule1': self.parameters['schedule']
|
|
||||||
}
|
}
|
||||||
|
# zapi attribute for first schedule is schedule1, second is schedule2 and so on
|
||||||
|
positions = [str(i) for i in range(1, len(self.parameters['schedule']) + 1)]
|
||||||
|
for schedule, count, position in zip(self.parameters['schedule'], self.parameters['count'], positions):
|
||||||
|
options['count' + position] = str(count)
|
||||||
|
options['schedule' + position] = schedule
|
||||||
snapshot_obj = netapp_utils.zapi.NaElement.create_node_with_children('snapshot-policy-create', **options)
|
snapshot_obj = netapp_utils.zapi.NaElement.create_node_with_children('snapshot-policy-create', **options)
|
||||||
|
|
||||||
# Set up optional variables to create a snapshot policy
|
# Set up optional variables to create a snapshot policy
|
||||||
|
|
|
@ -166,6 +166,21 @@ class TestMyModule(unittest.TestCase):
|
||||||
my_obj.apply()
|
my_obj.apply()
|
||||||
assert not exc.value.args[0]['changed']
|
assert not exc.value.args[0]['changed']
|
||||||
|
|
||||||
|
def test_validate_params(self):
|
||||||
|
data = self.set_default_args()
|
||||||
|
data['schedule'] = ['s1', 's2']
|
||||||
|
data['count'] = [1, 2, 3]
|
||||||
|
set_module_args(data)
|
||||||
|
my_obj = my_module()
|
||||||
|
my_obj.asup_log_for_cserver = Mock(return_value=None)
|
||||||
|
if not self.onbox:
|
||||||
|
my_obj.server = self.server
|
||||||
|
with pytest.raises(AnsibleFailJson) as exc:
|
||||||
|
my_obj.create_snapshot_policy()
|
||||||
|
msg = 'Error: A Snapshot policy can have up to a maximum of 5 schedules,and a ' \
|
||||||
|
'count representing maximum number of Snapshot copies for each schedule'
|
||||||
|
assert exc.value.args[0]['msg'] == msg
|
||||||
|
|
||||||
@patch('ansible.modules.storage.netapp.na_ontap_snapshot_policy.NetAppOntapSnapshotPolicy.delete_snapshot_policy')
|
@patch('ansible.modules.storage.netapp.na_ontap_snapshot_policy.NetAppOntapSnapshotPolicy.delete_snapshot_policy')
|
||||||
def test_successful_delete(self, delete_snapshot):
|
def test_successful_delete(self, delete_snapshot):
|
||||||
''' deleting snapshot policy and testing idempotency '''
|
''' deleting snapshot policy and testing idempotency '''
|
||||||
|
@ -189,6 +204,37 @@ class TestMyModule(unittest.TestCase):
|
||||||
my_obj.apply()
|
my_obj.apply()
|
||||||
assert not exc.value.args[0]['changed']
|
assert not exc.value.args[0]['changed']
|
||||||
|
|
||||||
|
def test_valid_schedule_count(self):
|
||||||
|
''' validate error when schedule has more than 5 elements '''
|
||||||
|
data = self.set_default_args()
|
||||||
|
data['schedule'] = ['hourly', 'daily', 'weekly', 'monthly', '5min']
|
||||||
|
data['count'] = [1, 2, 3, 4, 5]
|
||||||
|
set_module_args(data)
|
||||||
|
my_obj = my_module()
|
||||||
|
my_obj.asup_log_for_cserver = Mock(return_value=None)
|
||||||
|
if not self.onbox:
|
||||||
|
my_obj.server = self.server
|
||||||
|
my_obj.create_snapshot_policy()
|
||||||
|
create_xml = my_obj.server.xml_in
|
||||||
|
assert data['count'][2] == int(create_xml['count3'])
|
||||||
|
assert data['schedule'][4] == create_xml['schedule5']
|
||||||
|
|
||||||
|
def test_invalid_schedule_count(self):
|
||||||
|
''' validate error when schedule has more than 5 elements '''
|
||||||
|
data = self.set_default_args()
|
||||||
|
data['schedule'] = ['s1', 's2', 's3', 's4', 's5', 's6']
|
||||||
|
data['count'] = [1, 2, 3, 4, 5, 6]
|
||||||
|
set_module_args(data)
|
||||||
|
my_obj = my_module()
|
||||||
|
my_obj.asup_log_for_cserver = Mock(return_value=None)
|
||||||
|
if not self.onbox:
|
||||||
|
my_obj.server = self.server
|
||||||
|
with pytest.raises(AnsibleFailJson) as exc:
|
||||||
|
my_obj.create_snapshot_policy()
|
||||||
|
msg = 'Error: A Snapshot policy can have up to a maximum of 5 schedules,and a ' \
|
||||||
|
'count representing maximum number of Snapshot copies for each schedule'
|
||||||
|
assert exc.value.args[0]['msg'] == msg
|
||||||
|
|
||||||
def test_if_all_methods_catch_exception(self):
|
def test_if_all_methods_catch_exception(self):
|
||||||
module_args = {}
|
module_args = {}
|
||||||
module_args.update(self.set_default_args())
|
module_args.update(self.set_default_args())
|
||||||
|
|
Loading…
Reference in a new issue