Skip to content
This repository has been archived by the owner on Feb 24, 2022. It is now read-only.

Commit

Permalink
Sync bitbucket and Github
Browse files Browse the repository at this point in the history
  • Loading branch information
carchi8py committed Jun 2, 2020
1 parent ebaccb2 commit 3032cf1
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 15 deletions.
9 changes: 6 additions & 3 deletions ansible_collections/netapp/ontap/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,13 @@ SSL certificate authentication requires python2.7 or 3.x.
- na_ontap_user: `privacy_password` option specifies password for the privacy protocol of SNMPv3 user.
- na_ontap_user: `privacy_protocol` option specifies privacy protocol of SNMPv3 user.
- na_ontap_user: `remote_switch_ipaddress` option specifies the IP Address of the remote switch of SNMPv3 user.
- na_ontap_volume: `check_interval` option check if a volume move has been completed and then waits this number of seconds before checking again.
- na_ontap_volume: `check_interval` option checks if a volume move has been completed and then waits this number of seconds before checking again.
- na_ontap_volume: `auto_remap_luns` option controls automatic mapping of LUNs during volume rehost.
- na_ontap_volume: `force_restore` option forces volume to restore even if the volume has one or more newer Snapshotcopies.
- na_ontap_volume: `force_unmap_luns` option controls automatic unmapping of LUNs during volume rehost.
- na_ontap_volume: `from_vserver` option allows volume rehost from one vserver to another.
- na_ontap_volume: `auto_remap_luns` option control automatic mapping of LUNs during volume rehost.
- na_ontap_volume: `force_unmap_luns` option control automatic unmapping of LUNs during volume rehost.
- na_ontap_volume: `preserve_lun_ids` option controls LUNs in the volume being restored will remain mapped and their identities preserved.
- na_ontap_volume: `snapshot_restroe` option specifies name of snapshot to restore from.
- all modules: `cert_filepath`, `key_filepath` to enable SSL certificate authentication (python 2.7 or 3.x).

### Bug Fixes
Expand Down
75 changes: 65 additions & 10 deletions ansible_collections/netapp/ontap/plugins/modules/na_ontap_volume.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,32 @@
- Flag to control automatic unmap of LUNs.
type: bool
version_added: '20.6.0'
force_restore:
description:
- If this field is set to "true", the Snapshot copy is restored even if the volume has one or more newer Snapshot
copies which are currently used as reference Snapshot copy by SnapMirror. If a restore is done in this
situation, this will cause future SnapMirror transfers to fail.
- Option should only be used along with snapshot_restore.
type: bool
version_added: '20.6.0'
preserve_lun_ids:
description:
- If this field is set to "true", LUNs in the volume being restored will remain mapped and their identities
preserved such that host connectivity will not be disrupted during the restore operation. I/O's to the LUN will
be fenced during the restore operation by placing the LUNs in an unavailable state. Once the restore operation
has completed, hosts will be able to resume I/O access to the LUNs.
- Option should only be used along with snapshot_restore.
type: bool
version_added: '20.6.0'
snapshot_restore:
description:
- Name of snapshot to restore from.
- Not supported on Infinite Volume.
type: str
version_added: '20.6.0'
'''

EXAMPLES = """
Expand Down Expand Up @@ -485,8 +511,6 @@
https: False
- name: Modify volume with snapshot auto delete options
tags:
- auto_delete
na_ontap_volume:
state: present
name: vol_auto_delete
Expand All @@ -505,8 +529,6 @@
https: False
- name: Move volume with force cutover action
tags:
- move
na_ontap_volume:
name: ansible_vol
aggregate_name: aggr_ansible
Expand All @@ -518,8 +540,6 @@
https: false
- name: Rehost volume to another vserver auto remap luns
tags:
- rehost
na_ontap_volume:
name: ansible_vol
from_vserver: ansible
Expand All @@ -531,8 +551,6 @@
https: false
- name: Rehost volume to another vserver force unmap luns
tags:
- rehost
na_ontap_volume:
name: ansible_vol
from_vserver: ansible
Expand All @@ -543,6 +561,17 @@
password: "{{ netapp_password }}"
https: false
- name: Snapshot restore volume
na_ontap_volume:
name: ansible_vol
vserver: ansible
snapshot_restore: 2020-05-24-weekly
force_restore: true
preserve_lun_ids: true
hostname: "{{ netapp_hostname }}"
username: "{{ netapp_username }}"
password: "{{ netapp_password }}"
https: false
"""

RETURN = """
Expand Down Expand Up @@ -620,7 +649,10 @@ def __init__(self):
check_interval=dict(required=False, type='int', default=30),
from_vserver=dict(required=False, type='str'),
auto_remap_luns=dict(required=False, type='bool'),
force_unmap_luns=dict(required=False, type='bool')
force_unmap_luns=dict(required=False, type='bool'),
force_restore=dict(required=False, type='bool'),
preserve_lun_ids=dict(required=False, type='bool'),
snapshot_restore=dict(required=False, type='str')
))
self.module = AnsibleModule(
argument_spec=self.argument_spec,
Expand Down Expand Up @@ -1552,18 +1584,37 @@ def rehost_volume(self):
% (self.parameters['name'], to_native(error)),
exception=traceback.format_exc())

def snapshot_restore_volume(self):
snapshot_restore = netapp_utils.zapi.NaElement.create_node_with_children(
'snapshot-restore-volume', **{'snapshot': self.parameters['snapshot_restore'],
'volume': self.parameters['name']})
if self.parameters.get('force_restore') is not None:
snapshot_restore.add_new_child('force', str(self.parameters['force_restore']))
if self.parameters.get('preserve_lun_ids') is not None:
snapshot_restore.add_new_child('preserve-lun-ids', str(self.parameters['preserve_lun_ids']))
try:
self.server.invoke_successfully(snapshot_restore, enable_tunneling=True)
self.ems_log_event("snapshot-restore-volume")
except netapp_utils.zapi.NaApiError as error:
self.module.fail_json(msg='Error restoring volume %s: %s'
% (self.parameters['name'], to_native(error)),
exception=traceback.format_exc())

def apply(self):
'''Call create/modify/delete operations'''
efficiency_policy_modify = None
current = self.get_volume()
self.volume_style = self.get_volume_style(current)
# rename and create are mutually exclusive
rename, rehost, cd_action, modify = None, None, None, None
rename, rehost, snapshot_restore, cd_action, modify = None, None, None, None, None
if self.parameters.get('from_name'):
rename = self.na_helper.is_rename_action(self.get_volume(self.parameters['from_name']), current)
elif self.parameters.get('from_vserver'):
rehost = True
self.na_helper.changed = True
elif self.parameters.get('snapshot_restore'):
snapshot_restore = True
self.na_helper.changed = True
else:
cd_action = self.na_helper.get_cd_action(current, self.parameters)
if self.parameters.get('unix_permissions') is not None:
Expand Down Expand Up @@ -1596,6 +1647,8 @@ def apply(self):
self.rename_volume()
if rehost:
self.rehost_volume()
if snapshot_restore:
self.snapshot_restore_volume()
if cd_action == 'create':
self.create_volume()
# if we create, and modify only variable are set (snapdir_access or atime_update) we need to run a modify
Expand Down Expand Up @@ -1631,6 +1684,8 @@ def ems_log_event(self, state):
str(self.parameters['size']) + str(self.parameters['size_unit'])
elif state == 'volume-rehost':
message = "A Volume has been rehosted"
elif state == 'snapshot-restore-volume':
message = "A Volume has been restored by snapshot"
elif state == 'volume-change':
message = "A Volume state has been changed"
else:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -328,16 +328,16 @@ def get_volume_mock_object(self, kind=None, job_error=None):
"""
vol_obj = vol_module()
vol_obj.ems_log_event = Mock(return_value=None)
vol_obj.cluster = Mock()
vol_obj.cluster.invoke_successfully = Mock()
vol_obj.get_efficiency_policy = Mock(return_value='test_efficiency')
vol_obj.volume_style = None
if kind is None:
vol_obj.server = MockONTAPConnection()
elif kind == 'job_info':
vol_obj.server = MockONTAPConnection(kind='job_info', data=self.mock_vol, job_error=job_error)
vol_obj.cluster = MockONTAPConnection(kind='job_info', data=self.mock_vol, job_error=job_error)
else:
vol_obj.server = MockONTAPConnection(kind=kind, data=self.mock_vol)
vol_obj.cluster = MockONTAPConnection(kind=kind, data=self.mock_vol)

return vol_obj

Expand Down Expand Up @@ -1061,3 +1061,59 @@ def test_error_modify_snapshot_auto_delete(self):
with pytest.raises(AnsibleFailJson) as exc:
self.get_volume_mock_object('zapi_error').set_snapshot_auto_delete()
assert exc.value.args[0]['msg'] == 'Error setting snapshot auto delete options for volume test_vol: NetApp API failed. Reason - test:error'

def test_successful_volume_rehost(self):
data = {
'hostname': 'test',
'username': 'test_user',
'password': 'test_pass!',
'name': 'test_vol',
'vserver': 'dest_vserver',
'from_vserver': 'source_vserver'
}
set_module_args(data)
with pytest.raises(AnsibleExitJson) as exc:
self.get_volume_mock_object('volume').apply()
assert exc.value.args[0]['changed']

def test_error_volume_rehost(self):
data = {
'hostname': 'test',
'username': 'test_user',
'password': 'test_pass!',
'name': 'test_vol',
'vserver': 'dest_vserver',
'from_vserver': 'source_vserver'
}
set_module_args(data)
with pytest.raises(AnsibleFailJson) as exc:
self.get_volume_mock_object('zapi_error').rehost_volume()
assert exc.value.args[0]['msg'] == 'Error rehosting volume test_vol: NetApp API failed. Reason - test:error'

def test_successful_volume_restore(self):
data = {
'hostname': 'test',
'username': 'test_user',
'password': 'test_pass!',
'name': 'test_vol',
'vserver': 'test_vserver',
'snapshot_restore': 'snapshot_copy'
}
set_module_args(data)
with pytest.raises(AnsibleExitJson) as exc:
self.get_volume_mock_object('volume').apply()
assert exc.value.args[0]['changed']

def test_error_volume_restore(self):
data = {
'hostname': 'test',
'username': 'test_user',
'password': 'test_pass!',
'name': 'test_vol',
'vserver': 'test_vserver',
'snapshot_restore': 'snapshot_copy'
}
set_module_args(data)
with pytest.raises(AnsibleFailJson) as exc:
self.get_volume_mock_object('zapi_error').snapshot_restore_volume()
assert exc.value.args[0]['msg'] == 'Error restoring volume test_vol: NetApp API failed. Reason - test:error'

0 comments on commit 3032cf1

Please sign in to comment.