Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion PyPowerFlex/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,9 @@ def add_objects_common(self):
self.__add_storage_entity('host', common.Host)
self.__add_storage_entity('utility', common.PowerFlexUtility)


def add_objects_gen1(self):
"""Add gen1 objects here."""
self.__add_storage_entity('system', gen1.System)
self.__add_storage_entity('device', gen1.Device)
self.__add_storage_entity(
'fault_set', gen1.FaultSet)
Expand All @@ -157,9 +157,11 @@ def add_objects_gen1(self):

def add_objects_gen2(self):
"""Add gen2 objects here."""
self.__add_storage_entity('system', gen2.System)
self.__add_storage_entity('storage_node', gen2.StorageNode)
self.__add_storage_entity('protection_domain', gen2.ProtectionDomain)
self.__add_storage_entity('storage_pool', gen2.StoragePool)
self.__add_storage_entity('snapshot_policy', gen2.SnapshotPolicy)
self.__add_storage_entity('device', gen2.Device)
self.__add_storage_entity('device_group', gen2.DeviceGroup)
self.__add_storage_entity('volume', gen2.Volume)
16 changes: 16 additions & 0 deletions PyPowerFlex/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,22 @@ class VolumeConstants:
"childVolumeIds",
"userDataSdcWriteLatency"]

class VolumeConstantsGen2:
"""
This class holds constants related to Volume.
"""
DEFAULT_STATISTICS_METRICS = [
"host_trim_bandwidth",
"host_trim_iops",
"avg_host_write_latency",
"logical_provisioned",
"avg_host_read_latency",
"host_read_bandwidth",
"host_read_iops",
"logical_used",
"host_write_bandwidth",
"host_write_iops",
"avg_host_trim_latency"]

class RCGConstants:
"""
Expand Down
40 changes: 0 additions & 40 deletions PyPowerFlex/objects/common/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,46 +119,6 @@ def remove_cg_snapshots(self, system_id, cg_id, allow_ext_managed=None):

return response

def snapshot_volumes(self,
system_id,
snapshot_defs,
access_mode=None,
retention_period=None,
allow_ext_managed=None):
"""Create snapshots of PowerFlex volumes.

:type retention_period: str
:type access_mode: str
:type system_id: str
:type snapshot_defs: list[dict]
:type allow_ext_managed: bool
:rtype: dict
"""

action = 'snapshotVolumes'

params = {
'snapshotDefs': snapshot_defs,
'allowOnExtManagedVol': allow_ext_managed,
'accessModeLimit': access_mode,
'retentionPeriodInMin': retention_period
}

r, response = self.send_post_request(self.base_action_url,
action=action,
entity=self.entity,
entity_id=system_id,
params=params)
if r.status_code != requests.codes.ok:
msg = (
f"Failed to snapshot volumes on PowerFlex {self.entity} "
f"with id {system_id}. Error: {response}"
)
LOG.error(msg)
raise exceptions.PowerFlexClientException(msg)

return response

def add_standby_mdm(self, mdm_ips, role, management_ips=None, port=None,
mdm_name=None, allow_multiple_ips=None, clean=None,
virtual_interface=None):
Expand Down
11 changes: 11 additions & 0 deletions PyPowerFlex/objects/common/utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from PyPowerFlex.constants import (
StoragePoolConstants,
VolumeConstants,
VolumeConstantsGen2,
SnapshotPolicyConstants,
StorageNodeConstants
)
Expand Down Expand Up @@ -111,6 +112,16 @@ def get_statistics_for_all_volumes(self, ids=None, properties=None):

return response

def query_metrics_for_all_volumes_gen2(self, ids=None, metrics=None):
"""list volume statistics for PowerFlex 5.0+.

:param ids: list
:param metrics: list
:return: dict
"""
metrics = metrics or VolumeConstantsGen2.DEFAULT_STATISTICS_METRICS

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When reviewing Tao's PR, I just realized that passing empty metrics will return all metrics, but it is fine.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this design looks convenient.

return self.query_metrics('volume', ids, metrics)

def get_statistics_for_all_snapshot_policies(
self, ids=None, properties=None):
"""list snapshot policy statistics for PowerFlex.
Expand Down
2 changes: 2 additions & 0 deletions PyPowerFlex/objects/gen1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from PyPowerFlex.objects.gen1.sds import Sds
from PyPowerFlex.objects.gen1.snapshot_policy import SnapshotPolicy
from PyPowerFlex.objects.gen1.storage_pool import StoragePool
from PyPowerFlex.objects.gen1.system import System
from PyPowerFlex.objects.gen1.acceleration_pool import AccelerationPool
from PyPowerFlex.objects.gen1.volume import Volume
from PyPowerFlex.objects.gen1.replication_consistency_group import ReplicationConsistencyGroup
Expand All @@ -38,6 +39,7 @@
'Sds',
'SnapshotPolicy',
'StoragePool',
'System',
'AccelerationPool',
'Volume',
'ReplicationConsistencyGroup',
Expand Down
70 changes: 70 additions & 0 deletions PyPowerFlex/objects/gen1/system.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Copyright (c) 2024 Dell Inc. or its subsidiaries.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

"""Module for doing system-related operations."""

# pylint: disable=no-member,too-many-arguments,too-many-positional-arguments,duplicate-code

import logging

import requests

from PyPowerFlex import exceptions
from PyPowerFlex.objects.common.system import System as SystemCommon

LOG = logging.getLogger(__name__)


class System(SystemCommon):
"""Client for system operations"""
def snapshot_volumes(self,
system_id,
snapshot_defs,
access_mode=None,
retention_period=None,
allow_ext_managed=None):
"""Create snapshots of PowerFlex volumes.

:type retention_period: str
:type access_mode: str
:type system_id: str
:type snapshot_defs: list[dict]
:type allow_ext_managed: bool
:rtype: dict
"""

action = 'snapshotVolumes'

params = {
'snapshotDefs': snapshot_defs,
'allowOnExtManagedVol': allow_ext_managed,
'accessModeLimit': access_mode,
'retentionPeriodInMin': retention_period
}

r, response = self.send_post_request(self.base_action_url,
action=action,
entity=self.entity,
entity_id=system_id,
params=params)
if r.status_code != requests.codes.ok:
msg = (
f"Failed to snapshot volumes on PowerFlex {self.entity} "
f"with id {system_id}. Error: {response}"
)
LOG.error(msg)
raise exceptions.PowerFlexClientException(msg)

return response
4 changes: 4 additions & 0 deletions PyPowerFlex/objects/gen2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
from PyPowerFlex.objects.gen2.snapshot_policy import SnapshotPolicy
from PyPowerFlex.objects.gen2.device import Device
from PyPowerFlex.objects.gen2.device_group import DeviceGroup
from PyPowerFlex.objects.gen2.volume import Volume
from PyPowerFlex.objects.gen2.system import System

__all__ = [
'StorageNode',
Expand All @@ -29,4 +31,6 @@
'SnapshotPolicy',
'Device',
'DeviceGroup',
'Volume',
'System'
]
82 changes: 82 additions & 0 deletions PyPowerFlex/objects/gen2/system.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Copyright (c) 2024 Dell Inc. or its subsidiaries.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

"""Module for doing system-related operations."""

# pylint: disable=no-member,too-many-arguments,too-many-positional-arguments,duplicate-code

import logging
import requests

from PyPowerFlex import exceptions
from PyPowerFlex.objects.common.system import System as SystemCommon

LOG = logging.getLogger(__name__)


class System(SystemCommon):
"""Client for system operations"""

def create_snapshot(self,
system_id,
snapshot_defs,
retention_period=None):
"""Create a snapshot in Gen2."""
action = 'createSnapshot'

params = {
'snapshotDefs': snapshot_defs,
'retentionPeriodInMin': retention_period
}

r, response = self.send_post_request(self.base_action_url,
action=action,
entity=self.entity,
entity_id=system_id,
params=params)
if r.status_code != requests.codes.ok:
msg = (
f"Failed to create snapshot on PowerFlex {self.entity} "
f"with id {system_id}. Error: {response}"
)
LOG.error(msg)
raise exceptions.PowerFlexClientException(msg)

return response

def create_thin_clone(self,
system_id,
snapshot_defs):
"""Create a thin clone in Gen2."""
action = 'createThinClone'

params = {
'snapshotDefs': snapshot_defs
}

r, response = self.send_post_request(self.base_action_url,
action=action,
entity=self.entity,
entity_id=system_id,
params=params)
if r.status_code != requests.codes.ok:
msg = (
f"Failed to create thin clone on PowerFlex {self.entity} "
f"with id {system_id}. Error: {response}"
)
LOG.error(msg)
raise exceptions.PowerFlexClientException(msg)

return response
Loading