Skip to content

Commit 0c8d85a

Browse files
author
Michael McAleer
authored
Merge pull request #108 from dell/metro_dr_fix
92/Metro DR fixes
2 parents c7ec31e + 2300d33 commit 0c8d85a

File tree

15 files changed

+101
-57
lines changed

15 files changed

+101
-57
lines changed

ChangeLog

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
PyU4V Change Log
22
================
33

4+
Version 9.2.0.4 - released 9/12/20
5+
==================================
6+
- Fix for metro_dr delete function
7+
- Fix for metro_dr added recover option
8+
- Fix for CI tests:
9+
- PyU4V.tests.ci_tests.test_pyu4v_ci_system.CITestSystem._test_get_health_check_details
10+
- PyU4V.tests.ci_tests.test_pyu4v_ci_system.CITestSystem.test_get_ip_interface_list
11+
- PyU4V.tests.ci_tests.test_pyu4v_ci_system.CITestSystem.test_get_ip_interface
12+
- Added Force Option to metro dr restore
13+
- Application-Type header is now set by default to 'PyU4V-{version}'
14+
415
Version 9.2.0.3 - released 7/12/20
516
==================================
617
- Masking View performance support has been added to performance.py

PyU4V/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from .univmax_conn import U4VConn # noqa: F401
2424

2525
__title__ = 'pyu4v'
26-
__version__ = '9.2.0.3'
26+
__version__ = '9.2.0.4'
2727
__author__ = 'Dell EMC or its subsidiaries'
2828
__license__ = 'Apache 2.0'
2929
__copyright__ = 'Copyright 2020 Dell EMC Inc'

PyU4V/common.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ def delete_resource(self, *args, **kwargs):
454454
target_uri = self._build_uri(*args, **kwargs)
455455
message, status_code = self.request(
456456
target_uri, DELETE, request_object=kwargs.get('payload'),
457-
params=kwargs.get('payload'))
457+
params=kwargs.get('params'))
458458
resource_type = None
459459
if args:
460460
resource_type = args[2]

PyU4V/metro_dr.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ def convert_to_metrodr_environment(
197197
return response
198198

199199
def delete_metrodr_environment(
200-
self, environment_name, remove_r1_dr_rdfg=False,
200+
self, environment_name, remove_r1_dr_rdfg=False, force=False,
201201
metro_r1_array_id=None):
202202
"""Deletes Metro DR Environment.
203203
@@ -212,6 +212,7 @@ def delete_metrodr_environment(
212212
characters-- str
213213
:param remove_r1_dr_rdfg: override default behavior and delete R11-R2
214214
RDFG from metro R1 side -- bool
215+
:param force: required True if deleting R1 DR group -- bool
215216
:param metro_r1_array_id: 12 Digit Serial of Metro R1 source
216217
array -- str
217218
"""
@@ -224,7 +225,7 @@ def delete_metrodr_environment(
224225
category=REPLICATION, resource_level=SYMMETRIX,
225226
resource_level_id=array_id, resource_type=METRO_DR,
226227
resource_type_id=environment_name, params={
227-
'remove_r1_dr_rdfg': remove_r1_dr_rdfg})
228+
'remove_r1_dr_rdfg': remove_r1_dr_rdfg, 'force': force})
228229

229230
def modify_metrodr_environment(
230231
self, environment_name, action, metro=False,
@@ -262,7 +263,7 @@ def modify_metrodr_environment(
262263
else:
263264
msg = (
264265
'SRDF Action must be one of [Establish, Split, Suspend, '
265-
'Restore, Resume, Failover, Failback, Update_R1, '
266+
'Recover, Restore, Resume, Failover, Failback, Update_R1, '
266267
'SetMode]')
267268
LOG.exception(msg)
268269
raise exception.VolumeBackendAPIException(data=msg)

PyU4V/tests/ci_tests/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ def setup_credentials(self):
4747
"""Set REST credentials."""
4848
self.conn = univmax_conn.U4VConn()
4949
self.assertTrue(self.conn.rest_client.headers.get('user-agent'))
50+
self.assertTrue(self.conn.rest_client.headers.get('application-type'))
5051

5152
def create_volume(self):
5253
"""Create a test volume.

PyU4V/tests/ci_tests/test_pyu4v_ci_system.py

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,11 @@ def _test_get_health_check_details(self):
126126
health_check = self.system.get_health_check_details(
127127
health_check_id=health_check_id)
128128
self.assertIsInstance(health_check_list, dict)
129-
run_checks = health_check.get(TEST_RES)
130-
self.assertEqual(len(run_checks), 9)
129+
run_checks = health_check.get(TEST_RES, list())
130+
try:
131+
self.assertEqual(len(run_checks), 9)
132+
except AssertionError:
133+
self.assertEqual(len(run_checks), 8)
131134

132135
def _test_delete_health_check(self):
133136
"""Test delete_health_check."""
@@ -552,43 +555,55 @@ def test_get_director_port_list_iscsi_target_set(self):
552555

553556
def test_get_ip_interface_list(self):
554557
"""Test get_ip_interface_list."""
558+
found_ip_list = False
559+
555560
iscsi_dir_list = self.system.get_director_list(iscsi_only=True)
556561
if not iscsi_dir_list:
557562
self.skipTest('No iSCSI Directors available in CI environment.')
558-
director_id = random.choice(iscsi_dir_list)
559-
560-
iscsi_port_list = self.system.get_director_port_list(
561-
director_id=director_id, iscsi_target=False)
562-
if not iscsi_port_list:
563-
self.skipTest('No IP interface ports available in CI environment.')
564-
port = random.choice(iscsi_port_list)
565-
port_id = port.get('portId')
566-
567-
ip_interface_list = self.system.get_ip_interface_list(
568-
director_id=director_id, port_id=port_id)
569-
self.assertTrue(ip_interface_list)
570-
self.assertIsInstance(ip_interface_list, list)
563+
for dir_id in iscsi_dir_list:
564+
port_list = self.system.get_director_port_list(
565+
director_id=dir_id, iscsi_target=False)
566+
if not port_list:
567+
continue
568+
for port in port_list:
569+
port_id = port.get('portId')
570+
ip_interface_list = self.system.get_ip_interface_list(
571+
director_id=dir_id, port_id=port_id)
572+
if not ip_interface_list:
573+
continue
574+
575+
self.assertTrue(ip_interface_list)
576+
self.assertIsInstance(ip_interface_list, list)
577+
found_ip_list = True
578+
579+
if not found_ip_list:
580+
self.skipTest('No IP interfaces available in CI environment.')
571581

572582
def test_get_ip_interface(self):
573583
"""Test get_ip_interface."""
584+
found_ip = False
585+
574586
iscsi_dir_list = self.system.get_director_list(iscsi_only=True)
575587
if not iscsi_dir_list:
576588
self.skipTest('No iSCSI Directors available in CI environment.')
577-
director_id = random.choice(iscsi_dir_list)
578-
579-
iscsi_port_list = self.system.get_director_port_list(
580-
director_id=director_id, iscsi_target=False)
581-
if not iscsi_port_list:
582-
self.skipTest('No IP interface ports available in CI environment.')
583-
port = random.choice(iscsi_port_list)
584-
port_id = port.get('portId')
585-
586-
ip_interface_list = self.system.get_ip_interface_list(
587-
director_id=director_id, port_id=port_id)
588-
ip_interface = random.choice(ip_interface_list)
589-
590-
ip_interface_details = self.system.get_ip_interface(
591-
director_id=director_id, port_id=port_id,
592-
interface_id=ip_interface)
593-
self.assertTrue(ip_interface_details)
594-
self.assertIsInstance(ip_interface_details, dict)
589+
for dir_id in iscsi_dir_list:
590+
port_list = self.system.get_director_port_list(
591+
director_id=dir_id, iscsi_target=False)
592+
if not port_list:
593+
continue
594+
for port in port_list:
595+
port_id = port.get('portId')
596+
ip_interface_list = self.system.get_ip_interface_list(
597+
director_id=dir_id, port_id=port_id)
598+
if not ip_interface_list:
599+
continue
600+
601+
ip_interface_details = self.system.get_ip_interface(
602+
director_id=dir_id, port_id=port_id,
603+
interface_id=ip_interface_list[0])
604+
self.assertTrue(ip_interface_details)
605+
self.assertIsInstance(ip_interface_details, dict)
606+
found_ip = True
607+
608+
if not found_ip:
609+
self.skipTest('No IP interfaces available in CI environment.')

PyU4V/tests/unit_tests/test_pyu4v_metro_dr.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,3 +166,11 @@ def test_modify_metrodr_environment_restore_both(self):
166166
exception.InvalidInputException,
167167
self.metro_dr.modify_metrodr_environment, action='restore',
168168
environment_name='PyU4V', metro=True, dr=True)
169+
170+
def test_modify_metrodr_environment_recover(self):
171+
"""Test create_metrodr_environment."""
172+
with mock.patch.object(
173+
self.metro_dr, 'modify_resource') as mock_put:
174+
self.metro_dr.modify_metrodr_environment(
175+
action='recover', environment_name='PyU4V')
176+
mock_put.assert_called_once()

PyU4V/tests/unit_tests/test_pyu4v_requests.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,11 @@ def setUp(self):
4242
'PyU4V/{pv} ({plat}; version {rel}) Python {python}'.format(
4343
pv=pyu4v_version, plat=sys_platform,
4444
rel=sys_platform_release, python=python_version))
45+
self.app_type = 'PyU4V-{v}'.format(v=pyu4v_version)
4546
self.rest = rest_requests.RestRequests(
4647
username='smc', password='smc', verify=False,
4748
base_url='http://10.10.10.10:8443/univmax/restapi',
48-
interval=1, retries=3, application_type='pyu4v')
49+
interval=1, retries=3)
4950

5051
def test_rest_requests_init(self):
5152
"""Test class RestRequests __init__."""
@@ -59,7 +60,7 @@ def test_rest_requests_init(self):
5960
self.assertEqual(self.rest.timeout, 120)
6061
ref_headers = {'content-type': 'application/json',
6162
'accept': 'application/json',
62-
'application-type': 'pyu4v',
63+
'application-type': None,
6364
'user-agent': self.ua_details}
6465
self.assertEqual(self.rest.headers, ref_headers)
6566
self.assertIsInstance(self.rest.session,
@@ -69,12 +70,17 @@ def test_establish_rest_session(self):
6970
"""Test establish REST session."""
7071
ref_headers = {'content-type': 'application/json',
7172
'accept': 'application/json',
72-
'application-type': 'pyu4v',
73+
'application-type': 'test_app',
7374
'user-agent': self.ua_details}
74-
self.assertEqual(ref_headers, self.rest.session.headers)
75-
self.assertEqual('smc', self.rest.session.auth.username)
76-
self.assertEqual('smc', self.rest.session.auth.password)
77-
self.assertEqual(False, self.rest.session.verify)
75+
temp_rest = rest_requests.RestRequests(
76+
username='smc', password='smc', verify=False,
77+
base_url='http://10.10.10.10:8443/univmax/restapi',
78+
interval=1, retries=3, application_type='test_app')
79+
80+
self.assertEqual(ref_headers, temp_rest.session.headers)
81+
self.assertEqual('smc', temp_rest.session.auth.username)
82+
self.assertEqual('smc', temp_rest.session.auth.password)
83+
self.assertEqual(False, temp_rest.session.verify)
7884

7985
def test_establish_rest_session_with_headers(self):
8086
"""Test establish_rest_session with headers."""

PyU4V/univmax_conn.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333

3434

3535
file_path = None
36+
app_type = 'PyU4V-{v}'.format(v=constants.PYU4V_VERSION)
37+
3638
LOG = logging.getLogger(__name__)
3739

3840
SETUP = constants.SETUP
@@ -53,7 +55,7 @@ def __init__(self, username=None, password=None, server_ip=None,
5355
port=None, verify=None,
5456
u4v_version=constants.UNISPHERE_VERSION,
5557
interval=5, retries=200, array_id=None,
56-
application_type=None, remote_array=None,
58+
application_type=app_type, remote_array=None,
5759
remote_array_2=None):
5860
"""__init__."""
5961
config = config_handler.set_logger_and_config(file_path)

PyU4V/utils/constants.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
APP_MPART = 'multipart/form-data'
4040

4141
# Unisphere REST URI constants
42-
PYU4V_VERSION = '9.2.0.3'
42+
PYU4V_VERSION = '9.2.0.4'
4343
UNISPHERE_VERSION = '92'
4444
VERSION = 'version'
4545
ITERATOR = 'Iterator'
@@ -107,6 +107,7 @@
107107
ESTABLISH = 'Establish'
108108
FAILBACK = 'Failback'
109109
FAILOVER = 'Failover'
110+
RECOVER = 'Recover'
110111
RESTORE = 'Restore'
111112
RESUME = 'Resume'
112113
SETBIAS = 'SetBias'
@@ -122,10 +123,9 @@
122123
'REMOVE_PORTS': 'remove_ports', 'SET_LABEL': 'set_label'}
123124
METRO_DR_ACTIONS = {
124125
'ESTABLISH': ESTABLISH, 'SPLIT': SPLIT, 'SUSPEND': SUSPEND,
125-
'RESTORE': RESTORE, 'FAILOVER': FAILOVER, 'FAILBACK': FAILBACK,
126-
'SETMODE': SETMODE, 'UPDATER1': UPDATE_R1
126+
'RECOVER': RECOVER, 'RESTORE': RESTORE, 'FAILOVER': FAILOVER,
127+
'FAILBACK': FAILBACK, 'SETMODE': SETMODE, 'UPDATER1': UPDATE_R1
127128
}
128-
129129
METRO_DR_ACTION_PARAMS = {
130130
'ESTABLISH': 'establish', 'SPLIT': 'split', 'SUSPEND': 'suspend',
131131
'RESTORE': 'restore', 'FAILOVER': 'failover',

README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ PyU4V Version 9.2
2626
+-------------------------------+----------------------------+
2727
| **Author** | Dell EMC |
2828
+-------------------------------+----------------------------+
29-
| **PyU4V Version** | 9.2.0.3 |
29+
| **PyU4V Version** | 9.2.0.4 |
3030
+-------------------------------+----------------------------+
3131
| **Minimum Unisphere Version** | 9.2.0.1 |
3232
+-------------------------------+----------------------------+
@@ -80,7 +80,7 @@ specifying ``PyU4V`` as the install package for ``pip``::
8080

8181
$ pip install PyU4V
8282
# Install a specific version
83-
$ pip install PyU4V==9.2.0.3
83+
$ pip install PyU4V==9.2.0.4
8484

8585
Copy the sample ``PyU4V.conf`` provided with PyU4V to either your working
8686
directory or within a directory named ``.PyU4V`` in your current users home

docs/source/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
# The short X.Y version.
2727
version = u'9.2'
2828
# The full version, including alpha/beta/rc tags
29-
release = '9.2.0.3'
29+
release = '9.2.0.4'
3030

3131
# The suffix(es) of source filenames.
3232
# You can specify multiple suffix as a list of string:

docs/source/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ Supported PyU4V Versions
3535
------------------------
3636

3737
+-------------------------------+----------------------------------------+
38-
| **PyU4V Version** | 9.2.0.3 |
38+
| **PyU4V Version** | 9.2.0.4 |
3939
+-------------------------------+----------------------------------------+
4040
| **Minimum Unisphere Version** | 9.2.0.1 |
4141
+-------------------------------+----------------------------------------+

docs/source/installation.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Requirements
55
------------
66

77
+-------------------------------+----------------------------------------+
8-
| **PyU4V Version** | 9.2.0.3 |
8+
| **PyU4V Version** | 9.2.0.4 |
99
+-------------------------------+----------------------------------------+
1010
| **Minimum Unisphere Version** | 9.2.0.1 |
1111
+-------------------------------+----------------------------------------+
@@ -66,7 +66,7 @@ specifying ``PyU4V`` as the install package for ``pip``:
6666
6767
$ pip install PyU4V
6868
# Install a specific version
69-
$ pip install PyU4V==9.2.0.3
69+
$ pip install PyU4V==9.2.0.4
7070
7171
.. URL LINKS
7272

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
setuptools.setup(
2121
name='PyU4V',
22-
version='9.2.0.3',
22+
version='9.2.0.4',
2323
url='https://github.com/dell/PyU4V/',
2424
author='Dell Inc. or its subsidiaries',
2525
author_email='Michael.Mcaleer@dell.com',

0 commit comments

Comments
 (0)