Skip to content

Commit

Permalink
Sync bitbucket and GitHub
Browse files Browse the repository at this point in the history
  • Loading branch information
carchi8py committed Jan 2, 2024
1 parent 17caa5b commit 20ffacb
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 8 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ The following modules do not have REST equivalent APIs. They will stop working o
- na_ontap_s3_services - create, modify S3 service returns `s3_service_info` in module output.
- na_ontap_nfs - fix error with `windows` in REST for ONTAP 9.10 or earlier.
- na_ontap_cluster_peer - added REST only support for modifying remote intercluster addresses in cluster peer relation.
- na_ontap_snapmirror - updated resync and resume operation for synchronous snapmirror relationship in REST.

### Bug Fixes
- na_ontap_snapshot_policy - fix issue with modifying snapshot policy in REST.
Expand Down
2 changes: 2 additions & 0 deletions changelogs/fragments/DEVOPS-6282.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- na_ontap_snapmirror - updated resync and resume operation for synchronous snapmirror relationship in REST.
16 changes: 10 additions & 6 deletions plugins/modules/na_ontap_snapmirror.py
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,7 @@ def __init__(self):

self.na_helper = NetAppModule()
self.parameters = self.na_helper.set_parameters(self.module.params)
self.policy_type = None
self.new_style = False
# when deleting, ignore previous errors, but report them if delete fails
self.previous_errors = []
Expand Down Expand Up @@ -1051,7 +1052,8 @@ def snapmirror_resync(self):
resync SnapMirror based on relationship state
"""
if self.use_rest:
self.snapmirror_mod_init_resync_break_quiesce_resume_rest(state="snapmirrored")
state = 'in_sync' if self.policy_type == 'sync' else 'snapmirrored'
self.snapmirror_mod_init_resync_break_quiesce_resume_rest(state=state)
else:
options = {'destination-location': self.parameters['destination_path']}
snapmirror_resync = netapp_utils.zapi.NaElement.create_node_with_children('snapmirror-resync', **options)
Expand All @@ -1067,7 +1069,8 @@ def snapmirror_resume(self):
resume SnapMirror based on relationship state
"""
if self.use_rest:
return self.snapmirror_mod_init_resync_break_quiesce_resume_rest(state="snapmirrored")
state = 'in_sync' if self.policy_type == 'sync' else 'snapmirrored'
return self.snapmirror_mod_init_resync_break_quiesce_resume_rest(state=state)

options = {'destination-location': self.parameters['destination_path']}
snapmirror_resume = netapp_utils.zapi.NaElement.create_node_with_children('snapmirror-resume', **options)
Expand Down Expand Up @@ -1482,7 +1485,7 @@ def snapmirror_get_rest(self, destination=None):
destination = self.parameters['destination_path']

api = 'snapmirror/relationships'
fields = 'uuid,state,transfer.state,transfer.uuid,policy.name,unhealthy_reason.message,healthy,source'
fields = 'uuid,state,transfer.state,transfer.uuid,policy.name,policy.type,unhealthy_reason.message,healthy,source'
if 'schedule' in self.parameters:
fields += ',transfer_schedule'
options = {'destination.path': destination, 'fields': fields}
Expand All @@ -1499,9 +1502,10 @@ def snapmirror_get_rest(self, destination=None):
snap_info['status'] = self.na_helper.safe_get(record, ['transfer', 'state'])
self.parameters['current_transfer_status'] = self.na_helper.safe_get(record, ['transfer', 'state'])
snap_info['policy'] = self.na_helper.safe_get(record, ['policy', 'name'])
self.policy_type = self.na_helper.safe_get(record, ['policy', 'type'])
# REST API supports only Extended Data Protection (XDP) SnapMirror relationship
snap_info['relationship_type'] = 'extended_data_protection'
# initilized to avoid name keyerror
# initialized to avoid name keyerror
snap_info['current_transfer_type'] = ""
snap_info['max_transfer_rate'] = ""
if 'unhealthy_reason' in record:
Expand Down Expand Up @@ -1741,8 +1745,8 @@ def apply(self):

def main():
"""Execute action"""
community_obj = NetAppONTAPSnapmirror()
community_obj.apply()
snapmirror_obj = NetAppONTAPSnapmirror()
snapmirror_obj.apply()


if __name__ == '__main__':
Expand Down
41 changes: 39 additions & 2 deletions tests/unit/plugins/modules/test_na_ontap_snapmirror.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
}


def sm_rest_info(state, healthy, transfer_state=None, destination_path=DEFAULT_ARGS['destination_path']):
def sm_rest_info(state, healthy, transfer_state=None, policy_type=None, destination_path=DEFAULT_ARGS['destination_path']):
record = {
'uuid': 'b5ee4571-5429-11ec-9779-005056b39a06',
'destination': {
Expand All @@ -63,6 +63,8 @@ def sm_rest_info(state, healthy, transfer_state=None, destination_path=DEFAULT_A
record['transfer']['uuid'] = 'xfer_uuid'
if healthy is False:
record['unhealthy_reason'] = 'this is why the relationship is not healthy.'
if policy_type:
record['policy']['type'] = policy_type
record['transfer_schedule'] = {'name': 'abc'}

return {
Expand Down Expand Up @@ -110,9 +112,12 @@ def sm_rest_info(state, healthy, transfer_state=None, destination_path=DEFAULT_A
'sm_get_uninitialized': (200, sm_rest_info('uninitialized', True), None),
'sm_get_uninitialized_xfering': (200, sm_rest_info('uninitialized', True, 'transferring'), None),
'sm_get_mirrored': (200, sm_rest_info('snapmirrored', True, 'success'), None),
'sm_sync_get_mirrored': (200, sm_rest_info('in_sync', True, 'success', 'sync'), None),
'sm_get_restore': (200, sm_rest_info('snapmirrored', True, 'success', destination_path=DEFAULT_ARGS['source_path']), None),
'sm_get_paused': (200, sm_rest_info('paused', True, 'success'), None),
'sm_sync_get_paused': (200, sm_rest_info('paused', True, 'success', 'sync'), None),
'sm_get_broken': (200, sm_rest_info('broken_off', True, 'success'), None),
'sm_sync_get_broken': (200, sm_rest_info('broken_off', True, 'success', 'sync'), None),
'sm_get_data_transferring': (200, sm_rest_info('transferring', True, 'transferring'), None),
'sm_get_abort': (200, sm_rest_info('sm_get_abort', False, 'failed'), None),
'sm_get_resync': (200, {
Expand Down Expand Up @@ -1181,12 +1186,28 @@ def test_rest_resync_when_state_is_broken(dont_sleep):
assert call_main(my_main, DEFAULT_ARGS, module_args)['changed']


@patch('time.sleep')
def test_rest_synchronous_sm_resync_when_state_is_broken(dont_sleep):
''' resync when snapmirror state is broken and relationship_state active '''
register_responses([
('GET', 'cluster', SRR['is_rest_9_8_0']),
('GET', 'snapmirror/relationships', SRR['sm_sync_get_broken']), # apply first sm_get with state broken_off
('PATCH', 'snapmirror/relationships/b5ee4571-5429-11ec-9779-005056b39a06', SRR['success']), # sm resync response
('GET', 'snapmirror/relationships', SRR['sm_sync_get_mirrored']), # check for idle
('GET', 'snapmirror/relationships', SRR['sm_sync_get_mirrored']), # check_health calls sm_get
])
module_args = {
"use_rest": "always",
}
assert call_main(my_main, DEFAULT_ARGS, module_args)['changed']


def test_rest_resume_when_state_quiesced():
''' resync when snapmirror state is broken and relationship_state active '''
register_responses([
('GET', 'cluster', SRR['is_rest_9_8_0']),
('GET', 'snapmirror/relationships', SRR['sm_get_paused']), # apply first sm_get with state quiesced
('PATCH', 'snapmirror/relationships/b5ee4571-5429-11ec-9779-005056b39a06', SRR['success']), # sm resync response
('PATCH', 'snapmirror/relationships/b5ee4571-5429-11ec-9779-005056b39a06', SRR['success']), # sm resume response
('GET', 'snapmirror/relationships', SRR['sm_get_mirrored']), # sm update calls sm_get
('POST', 'snapmirror/relationships/b5ee4571-5429-11ec-9779-005056b39a06/transfers', SRR['success']), # sm update response
('GET', 'snapmirror/relationships', SRR['sm_get_mirrored']), # check_health calls sm_get
Expand All @@ -1197,6 +1218,22 @@ def test_rest_resume_when_state_quiesced():
assert call_main(my_main, DEFAULT_ARGS, module_args)['changed']


def test_rest_synchronous_sm_resume_when_state_quiesced():
''' resync when snapmirror state is broken and relationship_state active '''
register_responses([
('GET', 'cluster', SRR['is_rest_9_8_0']),
('GET', 'snapmirror/relationships', SRR['sm_sync_get_paused']), # apply first sm_get with state quiesced
('PATCH', 'snapmirror/relationships/b5ee4571-5429-11ec-9779-005056b39a06', SRR['success']), # sm resume response
('GET', 'snapmirror/relationships', SRR['sm_sync_get_mirrored']), # sm update calls sm_get
# ('POST', 'snapmirror/relationships/b5ee4571-5429-11ec-9779-005056b39a06/transfers', SRR['success']), # sm update response
('GET', 'snapmirror/relationships', SRR['sm_sync_get_mirrored']), # check_health calls sm_get
])
module_args = {
"use_rest": "always",
}
assert call_main(my_main, DEFAULT_ARGS, module_args)['changed']


@patch('time.sleep')
def test_rest_snapmirror_delete(dont_sleep):
''' snapmirror delete '''
Expand Down

0 comments on commit 20ffacb

Please sign in to comment.