Skip to content

Commit

Permalink
Merge pull request #205 from dell/10.2
Browse files Browse the repository at this point in the history
10.2
  • Loading branch information
rawstorage authored Oct 17, 2024
2 parents cff81ae + 10e6fcd commit 6a8f2d1
Show file tree
Hide file tree
Showing 31 changed files with 376 additions and 830 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,7 @@ dmypy.json

# IDE
.idea/

PyU4V.conf
PyU4V/tests/ci_tests/PyU4V.conf
PyU4V/tests/ci_tests/PyU4V.log
80 changes: 78 additions & 2 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,81 @@
PyU4V Change Log
================
Version 10.2.0.0

metro_dr.py
Added Reverse flag to PUT payload.

Add WLP Flags to storage group create and modify functions.
IP Storage configuration Library

replication.py
added bothsides option to create_storage_group_snapshot function

system.py
Added configure_ldap_authentication
Added get_ldap_configuration

provisioning.py
Added reset_volume_wwn function and tests

performance.py
BugFix, added includeRealTimeTraceOnCritical Key to update
performance thresholds payload and parameters.

Deprecated functions removed in v10.2.
====================================
Please ensure if you are using any of
these functions please ensure you have updated your code to use the replacement
function. These functions have been marked for depreciation for previous 2
releases and will have provided a warning error during that time to update.

- Removed PyU4V.performance.get_cloud_provider_keys and
get_cloud_provider_stats

- Old: PyU4V.performance.is_array_performance_registered
New: PyU4V.performance.is_array_diagnostic_performance_registered

- Old: PyU4V.performance.get_iscsi_target_keys
- New: PyU4V.performance.get_endpoint_keys

- Old: PyU4V.performance.get_iscsi_target_stats
- New: PyU4V.performance.get_endpoint_stats

- Old: PyU4V.performance.PerformanceFunctions.get_iscsi_target_stats
- New: PyU4V.performance.PerformanceFunctions.get_endpoint_stats

- Old: PyU4V.performance.PerformanceFunctions.get_iscsi_target_keys
- New: PyU4V.performance.PerformanceFunctions.get_endpoint_keys

- Old: PyU4V.provisioning.ProvisioningFunctions.get_director
- New: PyU4V.system.SystemFunctions.get_director

- Old: PyU4V.provisioning.ProvisioningFunctions.get_director_list
- New: PyU4V.system.SystemFunctions.get_director_list

- Old: PyU4V.provisioning.ProvisioningFunctions.get_director_port
- New: PyU4V.system.SystemFunctions.get_director_port

- Old: PyU4V.provisioning.ProvisioningFunctions.get_director_port_list
- New: PyU4V.system.SystemFunctions.get_director_port_list

- Old: PyU4V.provisioning.ProvisioningFunctions.get_port_identifier
- New: PyU4V.system.SystemFunctions.get_port_identifier

- Old: PyU4V.provisioning.ProvisioningFunctions.get_fa_directors
- New: PyU4V.system.SystemFunctions.get_fa_directors

- Old: PyU4V.provisioning.ProvisioningFunctions.get_iscsi_ip_address_and_iqn
- New: PyU4V.system.SystemFunctions.get_iscsi_ip_address_and_iqn

- Old: PyU4V.provisioning.ProvisioningFunctions.get_any_director_port
- New: PyU4V.system.SystemFunctions.get_any_director_port

- Old: PyU4V.provisioning.ProvisioningFunctions.create_multiport_port_group
- New: PyU4V.provisioning.ProvisioningFunctions.create_new_port_group

- Old: PyU4V.provisioning.ProvisioningFunctions.create_port_group
- New: PyU4V.provisioning.ProvisioningFunctions.create_new_port_group

Version 10.1.0.2 and backport to Version 10.0.0.20
====================================
Expand Down Expand Up @@ -229,8 +305,8 @@ Building URI with args deprecated
This functionality as provided by PyU4V.common.CommonFunctions._build_uri_args
has been marked for deprecation since PyU4V 9.1 and has been fully removed in
the 10.0 release. The impact of this is such that the following methods must
be called with kwargs to form target URIs if you are using them for access
to custom REST endpoints.
be called with kwargs or specify target uri to form target URIs if you are
using them for access to custom REST endpoints.
- PyU4V.common.CommonFunctions.get_resource
- PyU4V.common.CommonFunctions.create_resource
- PyU4V.common.CommonFunctions.modify_resource
Expand Down
4 changes: 2 additions & 2 deletions 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__ = '10.1.0.2'
__version__ = '10.2.0.0'
__author__ = 'Dell EMC or its subsidiaries'
__license__ = 'Apache 2.0'
__copyright__ = 'Copyright 2021 Dell EMC Inc'
__copyright__ = 'Copyright 2023 Dell EMC Inc'
15 changes: 10 additions & 5 deletions PyU4V/metro_dr.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ def delete_metrodr_environment(
def modify_metrodr_environment(
self, environment_name, action, metro=False,
dr=False, keep_r2=False, force=False, symforce=False,
_async=False, dr_replication_mode=None):
_async=False, dr_replication_mode=None, reverse=False):
"""Performs Functions to modify state of MetroDR environment.
:param environment_name: name of Metro Dr Environment up to 16
Expand All @@ -258,6 +258,7 @@ def modify_metrodr_environment(
synchronously -- bool
:param dr_replication_mode: set mode of DR link, AdaptiveCopyDisk or
Asynchronous -- str
:param reverse: reverse the direction of the link -- bool
:returns: details of metro dr environment and state -- dict
"""
metro_dr_action = constants.METRO_DR_ACTIONS.get(action.upper())
Expand Down Expand Up @@ -292,10 +293,14 @@ def modify_metrodr_environment(
'SRDF leg, please choice either Metro or DR not both')
LOG.exception(msg)
raise exception.InvalidInputException(message=msg)

payload.update({action_params: {
'metro': metro, 'force': force, 'dr': dr,
'symforce': symforce}})
if metro and not dr and metro_dr_action == 'Establish':
payload.update({action_params: {
'metro': metro, 'force': force, 'dr': dr,
'symforce': symforce, 'reverse': reverse}})
else:
payload.update({action_params: {
'metro': metro, 'force': force, 'dr': dr,
'symforce': symforce}})
elif metro_dr_action == 'SetMode':
payload.update({
action_params: {
Expand Down
141 changes: 21 additions & 120 deletions PyU4V/performance.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@
import re
import socket
import time

from PyU4V import common
from PyU4V import real_time
from PyU4V.utils import decorators
from PyU4V.utils import exception
from PyU4V.utils import file_handler
from PyU4V.utils import performance_constants as pc
Expand Down Expand Up @@ -66,25 +64,6 @@ def set_recency(self, minutes):
"""
self.recency = minutes

@decorators.refactoring_notice(
'PyU4V.performance',
'PyU4V.performance.is_array_diagnostic_performance_registered',
9.2, 10.1)
def is_array_performance_registered(self, array_id=None):
"""Check if an array is registered for diagnostic performance data.
DEPRECATION NOTICE:
PerformanceFunctions.is_array_performance_registered() will be
refactored in PyU4V version 10.1 in favour of
PerformanceFunctions.is_array_diagnostic_performance_registered().
For further information please consult PyU4V 9.2 release notes.
:param array_id: array id -- str
:returns: is diagnostic registered -- bool
"""
array_id = self.array_id if not array_id else array_id
return self.is_array_diagnostic_performance_registered(array_id)

def is_array_diagnostic_performance_registered(self, array_id=None):
"""Check if an array is registered for diagnostic performance data.
Expand Down Expand Up @@ -242,7 +221,8 @@ def disable_real_time_data_collection(self, array_id=None):

if self.is_array_real_time_performance_registered(array_id):
# Retain the existing diagnostic performance setting
diag_reg = self.is_array_performance_registered(array_id)
diag_reg = self.is_array_diagnostic_performance_registered(
array_id)

response = self.post_request(
category=pc.PERFORMANCE, resource_level=pc.ARRAY,
Expand Down Expand Up @@ -860,7 +840,8 @@ def update_threshold_settings(
first_threshold_samples=5,
first_threshold_severity=pc.WARN_LVL,
second_threshold_occurrences=3, second_threshold_samples=5,
second_threshold_severity=pc.CRIT_LVL):
second_threshold_severity=pc.CRIT_LVL,
include_realtime_trace=False):
"""Edit an existing global threshold across all arrays.
:param category: category id -- str
Expand All @@ -878,19 +859,23 @@ def update_threshold_settings(
:param second_threshold_severity: error severity, valid values are
'INFORMATION', 'WARNING', and
'CRITICAL' -- str
:param include_realtime_trace: if threshold is breached in addition
to alert a performance
:returns: operation success details -- dict
"""
payload = dict()
payload[pc.METRIC] = metric
payload[pc.ALERT] = alert
payload[pc.FIRST_THRESH] = str(first_threshold)
payload[pc.FIRST_THRESH_OCC] = str(first_threshold_occurrences)
payload[pc.FIRST_THRESH_SAMP] = str(first_threshold_samples)
payload[pc.FIRST_THRESH_SEV] = first_threshold_severity
payload[pc.SEC_THRESH] = str(second_threshold)
payload[pc.SEC_THRESH_OCC] = str(second_threshold_occurrences)
payload[pc.SEC_THRESH_SAMP] = str(second_threshold_samples)
payload[pc.SEC_THRESH_SEV] = second_threshold_severity
payload = {
"metric": metric,
"firstThreshold": str(first_threshold),
"secondThreshold": str(second_threshold),
"alert": alert,
"firstThresholdOccurrrences": str(first_threshold_occurrences),
"firstThresholdSamples": str(first_threshold_samples),
"firstThresholdSeverity": str(first_threshold_severity),
"secondThresholdOccurrrences": str(second_threshold_occurrences),
"secondThresholdSamples": str(second_threshold_samples),
"secondThresholdSeverity": str(second_threshold_severity),
"includeRealTimeTraceOnCritical": include_realtime_trace
}

return self.put_request(
category=pc.PERFORMANCE, resource_level=pc.THRESHOLD,
Expand Down Expand Up @@ -964,7 +949,8 @@ def _str_to_bool(str_in):
self.update_threshold_settings(
category=category_list[i], metric=metric_list[i],
alert=notify_list[i], first_threshold=f_threshold_list[i],
second_threshold=s_threshold_list[i])
second_threshold=s_threshold_list[i],
include_realtime_trace=False)

def get_array_keys(self):
"""List Arrays registered for performance data collection.
Expand Down Expand Up @@ -1160,41 +1146,6 @@ def get_cache_partition_perf_stats(
data_format=data_format, request_body=request_body,
start_time=start_time, end_time=end_time, recency=recency)

def get_cloud_provider_keys(self, array_id=None):
"""List cache partitions for the given array.
:param array_id: array id -- str
:returns: cache partition 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.CLOUD_PROVIDER,
array_id=array_id)
return key_list.get(
pc.CLOUD_PROVIDER_INFO, list()) if key_list else list()

def get_cloud_provider_stats(
self, cloud_provider_id, metrics, array_id=None,
data_format=pc.AVERAGE, start_time=None, end_time=None,
recency=None):
"""List time range performance data for given cache partition.
:param cloud_provider_id: cache partition 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.CLOUD_PROVIDER_ID: cloud_provider_id}
return self.get_performance_stats(
array_id=array_id, category=pc.CLOUD_PROVIDER, metrics=metrics,
data_format=data_format, request_body=request_body,
start_time=start_time, end_time=end_time, recency=recency)

def get_device_group_keys(self, array_id=None):
"""List device groups for the given array.
Expand Down Expand Up @@ -1793,26 +1744,6 @@ def get_ip_interface_stats(
data_format=data_format, request_body=request_body,
start_time=start_time, end_time=end_time, recency=recency)

@decorators.refactoring_notice(
'PyU4V.performance', 'get_endpoint_keys', 10.0, 10.2)
def get_iscsi_target_keys(self, array_id=None):
"""List iSCSI targets for the given array.
DEPRECATION NOTICE:
PerformanceFunctions.get_iscsi_target_keys() will be
refactored in PyU4V version 10.2 in favour of
PerformanceFunctions.get_endpoint_keys().
For further information please consult PyU4V 10.0 release notes.
:param array_id: array_id: array id -- str
:returns: iSCSI interfaces 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.ENDPOINT,
array_id=array_id)
return key_list.get(pc.ENDPOINT_INFO, list()) if key_list else list()

def get_endpoint_keys(self, array_id=None):
"""List endpoints for the given array.
Expand All @@ -1825,36 +1756,6 @@ def get_endpoint_keys(self, array_id=None):
array_id=array_id)
return key_list.get(pc.ENDPOINT_INFO, list()) if key_list else list()

@decorators.refactoring_notice(
'PyU4V.performance', 'get_endpoint_stats', 10.0, 10.2)
def get_iscsi_target_stats(
self, iscsi_target_id, metrics, array_id=None,
data_format=pc.AVERAGE, start_time=None, end_time=None,
recency=None):
"""List time range performance data for given iSCSI target.
DEPRECATION NOTICE:
PerformanceFunctions.get_iscsi_target_keys() will be
refactored in PyU4V version 10.2 in favour of
PerformanceFunctions.get_endpoint_stats().
For further information please consult PyU4V 10.0 release notes.
:param iscsi_target_id: iSCSI target 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.ENDPOINT_ID_METRICS: iscsi_target_id}
return self.get_performance_stats(
array_id=array_id, category=pc.ENDPOINT, metrics=metrics,
data_format=data_format, request_body=request_body,
start_time=start_time, end_time=end_time, recency=recency)

def get_endpoint_stats(
self, endpoint_id, metrics, array_id=None,
data_format=pc.AVERAGE, start_time=None, end_time=None,
Expand Down
Loading

0 comments on commit 6a8f2d1

Please sign in to comment.