Skip to content

Commit

Permalink
Merge pull request #106 from dell/92/splunk_support_functions
Browse files Browse the repository at this point in the history
92/Splunk support functions
  • Loading branch information
Michael McAleer authored Dec 9, 2020
2 parents 59c201a + 6b1d7bf commit c7ec31e
Show file tree
Hide file tree
Showing 30 changed files with 501 additions and 26 deletions.
21 changes: 21 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
PyU4V Change Log
================

Version 9.2.0.3 - released 7/12/20
==================================
- Masking View performance support has been added to performance.py
- PyU4V.performance.PerformanceFunctions.get_masking_view_keys
- PyU4V.performance.PerformanceFunctions.get_masking_view_stats
- Director list, Port list, IP interface list, and get IP interface details
have been added to system.py
- PyU4V.system.SystemFunctions.get_director_list
- PyU4V.system.SystemFunctions.get_director_port_list
- PyU4V.system.SystemFunctions.get_ip_interface_list
- PyU4V.system.SystemFunctions.get_ip_interface
- Array storage level details are now available via provisioning.py
- PyU4V.provisioning.ProvisioningFunctions.get_array
- Array level WLP capabilities are now accessible in workload_planner.py
- PyU4V.workload_planner.WLPFunctions.get_capabilities
- array_id is now an optional parameter for the following functions:
- PyU4V.replication.ReplicationFunctions.get_array_replication_capabilities
- PyU4V.migration.MigrationFunctions.get_migration_info
- PyU4V.migration.MigrationFunctions.get_array_migration_capabilities


Version 9.2.0.2 - released 14/10/20
===================================
- When generating threshold CSV files from
Expand Down
2 changes: 1 addition & 1 deletion PyU4V/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from .univmax_conn import U4VConn # noqa: F401

__title__ = 'pyu4v'
__version__ = '9.2.0.2'
__version__ = '9.2.0.3'
__author__ = 'Dell EMC or its subsidiaries'
__license__ = 'Apache 2.0'
__copyright__ = 'Copyright 2020 Dell EMC Inc'
10 changes: 6 additions & 4 deletions PyU4V/migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,15 @@ def __init__(self, array_id, rest_client):
self.modify_resource = self.common.modify_resource
self.delete_resource = self.common.delete_resource

def get_migration_info(self):
def get_migration_info(self, array_id=None):
"""Return migration information for an array.
:returns: migration info -- dict
"""
array_id = array_id if array_id else self.array_id
return self.get_resource(
category=MIGRATION,
resource_level=SYMMETRIX, resource_level_id=self.array_id)
resource_level=SYMMETRIX, resource_level_id=array_id)

def create_migration_environment(self, target_array_id):
"""Create a new migration environment between two arrays.
Expand Down Expand Up @@ -77,11 +78,12 @@ def delete_migration_environment(self, target_array_id):
resource_level=SYMMETRIX, resource_level_id=self.array_id,
resource_type=ENVIRONMENT, resource_type_id=target_array_id)

def get_array_migration_capabilities(self):
def get_array_migration_capabilities(self, array_id=None):
"""Check what migration facilities are available.
:returns: array capabilities -- dict
"""
array_id = array_id if array_id else self.array_id
capabilities = self.get_resource(
category=MIGRATION, resource_level=CAPABILITIES,
resource_type=SYMMETRIX)
Expand All @@ -90,7 +92,7 @@ def get_array_migration_capabilities(self):
'storageArrayCapability', list()) if capabilities else list())
array_capabilities = dict()
for symm in symm_list:
if symm['arrayId'] == self.array_id:
if symm['arrayId'] == array_id:
array_capabilities = symm
break
return array_capabilities
Expand Down
37 changes: 35 additions & 2 deletions PyU4V/performance.py
Original file line number Diff line number Diff line change
Expand Up @@ -1809,11 +1809,44 @@ def get_iscsi_target_stats(
data_format=data_format, request_body=request_body,
start_time=start_time, end_time=end_time, recency=recency)

def get_masking_view_keys(self, array_id=None):
"""List masking views for the given array.
:param array_id: array id -- str
:returns: masking view info with first and last available dates -- list
"""
array_id = self.array_id if not array_id else array_id
key_list = self.get_performance_key_list(category=pc.MV,
array_id=array_id)
return key_list.get(pc.MV_INFO, list()) if key_list else list()

def get_masking_view_stats(
self, masking_view_id, metrics, array_id=None,
data_format=pc.AVERAGE, start_time=None, end_time=None,
recency=None):
"""List time range performance data for given masking view.
:param masking_view_id: masking view id -- str
:param metrics: performance metrics to retrieve -- str or list
:param array_id: array id -- str
:param data_format: response data format 'Average' or 'Maximum' -- str
:param start_time: timestamp in milliseconds since epoch -- str
:param end_time: timestamp in milliseconds since epoch -- str
:param recency: check recency of timestamp in minutes -- int
:returns: performance metrics -- dict
"""
array_id = self.array_id if not array_id else array_id
request_body = {pc.MV_ID: masking_view_id}
return self.get_performance_stats(
array_id=array_id, category=pc.MV, metrics=metrics,
data_format=data_format, request_body=request_body,
start_time=start_time, end_time=end_time, recency=recency)

def get_port_group_keys(self, array_id=None):
"""List port group for the given array.
:param array_id: array_id: array id -- str
:returns: port group info with first and last available
:param array_id: array id -- str
:returns: port group info with first and last available dates -- list
"""
array_id = self.array_id if not array_id else array_id
key_list = self.get_performance_key_list(category=pc.PG,
Expand Down
12 changes: 12 additions & 0 deletions PyU4V/provisioning.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ def __init__(self, array_id, rest_client):
self.modify_resource = self.common.modify_resource
self.delete_resource = self.common.delete_resource

def get_array(self, array_id=None):
"""Query for details of an array from SLOPROVISIONING endpoint.
:param array_id: array serial number -- str
:returns: array details -- dict
"""
array_id = array_id if array_id else self.array_id
response = self.get_resource(
category=SLOPROVISIONING, resource_level=SYMMETRIX,
resource_level_id=array_id)
return response if response else dict()

def get_director(self, director):
"""Query for details of a director for a symmetrix.
Expand Down
5 changes: 3 additions & 2 deletions PyU4V/replication.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,20 @@ def get_replication_info(self):
category=REPLICATION, resource_level=SYMMETRIX,
resource_level_id=self.array_id)

def get_array_replication_capabilities(self):
def get_array_replication_capabilities(self, array_id=None):
"""Check what replication facilities are available.
:returns: replication capability details -- dict
"""
array_id = array_id if array_id else self.array_id
capabilities = self.get_resource(
category=REPLICATION, resource_level=CAPABILITIES,
resource_type=SYMMETRIX)
symm_list = capabilities.get(
'symmetrixCapability', list()) if capabilities else list()
array_capabilities = dict()
for symm in symm_list:
if symm['symmetrixId'] == self.array_id:
if symm['symmetrixId'] == array_id:
array_capabilities = symm
break
return array_capabilities
Expand Down
89 changes: 89 additions & 0 deletions PyU4V/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"""system.py."""

import logging
import re
import time

from datetime import datetime
Expand Down Expand Up @@ -74,6 +75,11 @@
SUCCESS = constants.SUCCESS
AUDIT_RECORD_TIME = constants.AUDIT_RECORD_TIME
STR_TIME_FORMAT = constants.STR_TIME_FORMAT
DIRECTOR = constants.DIRECTOR
DIRECTOR_ID = constants.DIRECTOR_ID
PORT = constants.PORT
IP_INTERFACE = constants.IP_INTERFACE
IP_INTERFACE_ID = constants.IP_INTERFACE_ID


class SystemFunctions(object):
Expand Down Expand Up @@ -835,3 +841,86 @@ def download_audit_log_record(self, array_id=None, return_binary=False,
LOG.info('The audit log download request was successful.')

return return_dict

def get_director_list(self, array_id=None, iscsi_only=False):
"""Get a list of directors for a given array.
:param array_id: array serial number -- str
:param iscsi_only: return only iSCSI directors -- bool
:returns: iSCSI directors -- list
"""
array_id = array_id if array_id else self.array_id
dir_list = self.common.get_resource(
category=SYSTEM,
resource_level=SYMMETRIX, resource_level_id=array_id,
resource_type=DIRECTOR)
response_dir_list = list()
for director in dir_list.get(DIRECTOR_ID, list()):
if iscsi_only and re.match(r'^SE-\d[A-Z]$', director):
response_dir_list.append(director)
elif not iscsi_only:
response_dir_list.append(director)

return response_dir_list

def get_director_port_list(self, director_id, array_id=None,
iscsi_target=None):
"""Get a list of director ports for a specified director.
:param director_id: director id -- str
:param array_id: array id -- str
:param iscsi_target: if the port is an iSCSI target, applicable to
front-end SE directors only, default to not set
-- bool
:returns: director ports -- list
"""
array_id = array_id if array_id else self.array_id

filters = dict()
if isinstance(iscsi_target, bool):
filters['iscsi_target'] = iscsi_target

port_list = self.common.get_resource(
category=SYSTEM,
resource_level=SYMMETRIX, resource_level_id=array_id,
resource_type=DIRECTOR, resource_type_id=director_id,
resource=PORT, params=filters)
return port_list.get(
'symmetrixPortKey', list()) if port_list else list()

def get_ip_interface_list(self, director_id, port_id, array_id=None):
"""Get a list of IP interfaces for a given array.
:param director_id: director id -- str
:param port_id: port id -- str
:param array_id: array id -- str
:returns: IP interfaces -- list
"""
array_id = array_id if array_id else self.array_id
ip_list = self.common.get_resource(
category=SYSTEM,
resource_level=SYMMETRIX, resource_level_id=array_id,
resource_type=DIRECTOR, resource_type_id=director_id,
resource=PORT, resource_id=port_id, object_type=IP_INTERFACE)

return ip_list.get(IP_INTERFACE_ID, list()) if ip_list else list()

def get_ip_interface(self, director_id, port_id, interface_id,
array_id=None):
"""Get IP interface details
:param director_id: director id -- str
:param port_id: port id -- str
:param interface_id: interface id -- str
:param array_id: array id -- str
:returns: IP interface details -- dict
"""
array_id = array_id if array_id else self.array_id
interface = self.common.get_resource(
category=SYSTEM,
resource_level=SYMMETRIX, resource_level_id=array_id,
resource_type=DIRECTOR, resource_type_id=director_id,
resource=PORT, resource_id=port_id,
object_type=IP_INTERFACE, object_type_id=interface_id)

return interface if interface else dict()
6 changes: 4 additions & 2 deletions PyU4V/tests/ci_tests/test_pyu4v_ci_migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ def setUp(self):

def test_get_migration_info(self):
"""Test get_migration_info."""
migration_info = self.migration.get_migration_info()
migration_info = self.migration.get_migration_info(
array_id=self.conn.array_id)
self.assertEqual(4, len(migration_info.keys()))
self.assertEqual(self.conn.array_id, migration_info.get('arrayId'))
self.assertTrue(migration_info.get('local'))
Expand All @@ -37,7 +38,8 @@ def test_get_migration_info(self):

def test_get_array_migration_capabilities(self):
"""Test get_array_migration_capabilities."""
array_capabilities = self.migration.get_array_migration_capabilities()
array_capabilities = self.migration.get_array_migration_capabilities(
array_id=self.conn.array_id)
self.assertTrue(array_capabilities)
self.assertEqual(6, len(array_capabilities.keys()))
self.assertEqual(self.conn.array_id, array_capabilities.get('arrayId'))
Expand Down
9 changes: 9 additions & 0 deletions PyU4V/tests/ci_tests/test_pyu4v_ci_performance.py
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,15 @@ def test_iscsi_target_performance_function(self):
self.run_performance_test_asserts(category, id_tag, key_func,
metrics_func)

def test_masking_view_performance_function(self):
"""Test Masking View performance function."""
category = pc.MV
id_tag = pc.MV_ID
key_func = self.perf.get_masking_view_keys
metrics_func = self.perf.get_masking_view_stats
self.run_performance_test_asserts(category, id_tag, key_func,
metrics_func)

def test_port_group_performance_function(self):
"""Test port group performance function."""
category = pc.PG
Expand Down
8 changes: 8 additions & 0 deletions PyU4V/tests/ci_tests/test_pyu4v_ci_provisioning.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ def setUp(self):
super(CITestProvisioning, self).setUp()
self.provisioning = self.conn.provisioning

def test_get_array(self):
"""Test get_array."""
response = self.provisioning.get_array(array_id=self.conn.array_id)
self.assertTrue(response)
self.assertIsInstance(response, dict)
self.assertEqual(response.get('symmetrixId'), self.conn.array_id)
self.assertTrue(response.get('local'))

def test_get_director(self):
"""Test get_director."""
availability = 'availability'
Expand Down
5 changes: 3 additions & 2 deletions PyU4V/tests/ci_tests/test_pyu4v_ci_replication.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ def setUp(self):

def test_get_array_replication_capabilities(self):
"""Test get_array_replication_capabilities."""
rep_info = self.conn.replication.get_array_replication_capabilities()
rep_info = self.conn.replication.get_array_replication_capabilities(
array_id=self.conn.array_id)
self.assertEqual(9, len(rep_info.keys()))
assert 'symmetrixId' in rep_info
assert 'snapVxCapable' in rep_info
Expand Down Expand Up @@ -449,7 +450,7 @@ def test_get_rdf_group(self):
self.assertIn('remoteSymmetrix', rdfg_details)

def test_get_rdf_group_list(self):
"""Test get_migration_info."""
"""Test get_rdf_group_list."""
rdf_number = self.replication.get_rdf_group_list()
self.assertIsInstance(rdf_number, list)

Expand Down
Loading

0 comments on commit c7ec31e

Please sign in to comment.