Skip to content

Commit

Permalink
Merge pull request #4 from dell/release_1.3.0
Browse files Browse the repository at this point in the history
release version 1.3.0 for PyPowerFlex library
  • Loading branch information
shenda1 authored Mar 18, 2022
2 parents 8167377 + cb4b509 commit 29b26e0
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 10 deletions.
10 changes: 10 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# PyPowerFlex Change Log

## Version 1.3.0 - released on 25/03/22
- Added block provisioning operations includes managing protection domain and getting high level facts about this entity.

## Version 1.2.0 - released on 24/09/21
- Added block provisioning operations includes managing SDS, device, acceleration pool and getting high level facts about all these entities.

## Version 1.1.0 - released on 24/03/21
- Added block provisioning operations includes managing volume, snapshot, snapshot policy, storage pool, SDC and getting high level facts about all these entities.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright 2020 Dell EMC
Copyright 2020 Dell Technologies

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
115 changes: 113 additions & 2 deletions PyPowerFlex/objects/protection_domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,18 @@
LOG = logging.getLogger(__name__)


class RFCacheOperationMode:
"""RFcache operation mode."""

none = 'None'
read = 'Read'
write = 'Write'
read_and_write = 'ReadAndWrite'
write_miss = 'WriteMiss'


class ProtectionDomain(base_client.EntityRequest):
def activate(self, protection_domain_id, force=None):
def activate(self, protection_domain_id, force=False):
"""Activate PowerFlex protection domain.
:type protection_domain_id: str
Expand Down Expand Up @@ -107,7 +117,7 @@ def delete(self, protection_domain_id):

return self._delete_entity(protection_domain_id)

def inactivate(self, protection_domain_id, force=None):
def inactivate(self, protection_domain_id, force=False):
"""Inactivate PowerFlex protection domain.
:type protection_domain_id: str
Expand Down Expand Up @@ -151,3 +161,104 @@ def rename(self, protection_domain_id, name):
)

return self._rename_entity(action, protection_domain_id, params)

def network_limits(self, protection_domain_id, rebuild_limit=None,
rebalance_limit=None, vtree_migration_limit=None,
overall_limit=None):
"""
Setting the Network limits of the protection domain.
:type protection_domain_id: str
:type rebuild_limit: int
:type rebalance_limit: int
:type vtree_migration_limit: int
:type overall_limit: int
:rtype dict
"""

action = "setSdsNetworkLimits"

params = dict(
rebuildLimitInKbps=rebuild_limit,
rebalanceLimitInKbps=rebalance_limit,
vtreeMigrationLimitInKbps=vtree_migration_limit,
overallLimitInKbps=overall_limit
)
r, response = self.send_post_request(self.base_action_url,
action=action,
entity=self.entity,
entity_id=protection_domain_id,
params=params)

if r.status_code != requests.codes.ok:
msg = ('Failed to update the network limits of PowerFlex {entity}'
' with id {_id}. Error: {response}'
.format(entity=self.entity, _id=protection_domain_id,
response=response))
LOG.error(msg)
raise exceptions.PowerFlexClientException(msg)

return self.get(entity_id=protection_domain_id)

def set_rfcache_enabled(self, protection_domain_id, enable_rfcache=None):
"""
Enable/Disable the RFcache in the Protection Domain.
:type protection_domain_id: str
:type enable_rfcache: bool
:rtype dict
"""

action = "disableSdsRfcache"
if enable_rfcache:
action = "enableSdsRfcache"

r, response = self.send_post_request(self.base_action_url,
action=action,
entity=self.entity,
entity_id=protection_domain_id)
if r.status_code != requests.codes.ok:
msg = ('Failed to enable/disable RFcache in PowerFlex {entity} '
' with id {_id}. Error: {response}'
.format(entity=self.entity, _id=protection_domain_id,
response=response))
LOG.error(msg)
raise exceptions.PowerFlexClientException(msg)

return self.get(entity_id=protection_domain_id)

def rfcache_parameters(self, protection_domain_id, page_size=None,
max_io_limit=None, pass_through_mode=None):
"""
Set RF cache parameters of the protection domain.
:type protection_domain_id: str
:type page_size: int
:type max_io_limit: int
:type pass_through_mode: str
:rtype dict
"""

action = "setRfcacheParameters"

params = dict(
pageSizeKb=page_size,
maxIOSizeKb=max_io_limit,
rfcacheOperationMode=pass_through_mode
)

r, response = self.send_post_request(self.base_action_url,
action=action,
entity=self.entity,
entity_id=protection_domain_id,
params=params)

if r.status_code != requests.codes.ok:
msg = ('Failed to set RFcache parameters in PowerFlex {entity} '
' with id {_id}. Error: {response}'
.format(entity=self.entity, _id=protection_domain_id,
response=response))
LOG.error(msg)
raise exceptions.PowerFlexClientException(msg)

return self.get(entity_id=protection_domain_id)
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# PyPowerFlex

Python SDK for Dell EMC PowerFlex.
Python SDK for Dell PowerFlex.

Supports PowerFlex (VxFlex OS) version 3.0 and later.

Expand Down
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@

setup(
name='PyPowerFlex',
version='1.2.0',
description='Python library for Dell EMC PowerFlex',
author='Ansible Team at Dell EMC',
version='1.3.0',
description='Python library for Dell PowerFlex',
author='Ansible Team at Dell',
author_email='[email protected]',
install_requires=[
'packaging==20.4',
Expand Down
14 changes: 13 additions & 1 deletion tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class PyPowerFlexTestCase(TestCase):
RESPONSE_MODE.Valid: {
'/login': 'token',
'/version': '3.5',
'/logout': '',
},
RESPONSE_MODE.Invalid: {
'/version': '2.5',
Expand All @@ -80,6 +81,12 @@ class PyPowerFlexTestCase(TestCase):
'errorCode': 2,
'message': 'Test version bad status',
}, 400
),
'/logout': MockResponse(
{
'errorCode': 3,
'message': 'Test logout bad status',
}, 400
)
}
}
Expand Down Expand Up @@ -127,7 +134,12 @@ def get_mock_response(self, url, mode=None, *args, **kwargs):
mode = self.__http_response_mode
api_path = url.split('/api')[1]
try:
response = self.MOCK_RESPONSES[mode][api_path]
if api_path == "/login":
response = self.RESPONSE_MODE.Valid[0]
elif api_path == "/logout":
response = self.RESPONSE_MODE.Valid[2]
else:
response = self.MOCK_RESPONSES[mode][api_path]
except KeyError:
try:
response = self.DEFAULT_MOCK_RESPONSES[mode][api_path]
Expand Down
52 changes: 52 additions & 0 deletions tests/test_protection_domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
# under the License.

from PyPowerFlex import exceptions
from PyPowerFlex.objects import protection_domain
import tests


Expand Down Expand Up @@ -47,6 +48,18 @@ def setUp(self):
'/instances/ProtectionDomain::{}'
'/action/setProtectionDomainName'.format(self.fake_pd_id):
{},
'/instances/ProtectionDomain::{}'
'/action/setSdsNetworkLimits'.format(self.fake_pd_id):
{},
'/instances/ProtectionDomain::{}'
'/action/enableSdsRfcache'.format(self.fake_pd_id):
{},
'/instances/ProtectionDomain::{}'
'/action/disableSdsRfcache'.format(self.fake_pd_id):
{},
'/instances/ProtectionDomain::{}'
'/action/setRfcacheParameters'.format(self.fake_pd_id):
{},
},
self.RESPONSE_MODE.Invalid: {
'/types/ProtectionDomain/instances':
Expand Down Expand Up @@ -123,3 +136,42 @@ def test_protection_domain_rename_bad_status(self):
self.client.protection_domain.rename,
self.fake_pd_id,
name='new_name')

def test_protection_domain_network_limits(self):
self.client.protection_domain.network_limits(self.fake_pd_id,
rebuild_limit=10240,
rebalance_limit=10240,
vtree_migration_limit=
10240,
overall_limit=10240)

def test_protection_domain_network_limits_bad_status(self):
with self.http_response_mode(self.RESPONSE_MODE.BadStatus):
self.assertRaises(exceptions.PowerFlexClientException,
self.client.protection_domain.network_limits,
self.fake_pd_id)

def test_protection_domain_set_rfcache_enabled(self):
self.client.protection_domain.set_rfcache_enabled(self.fake_pd_id,
enable_rfcache=True)

def test_protection_domain_set_rfcache_enabled_bad_status(self):
with self.http_response_mode(self.RESPONSE_MODE.BadStatus):
self.assertRaises(exceptions.PowerFlexClientException,
self.client.protection_domain.set_rfcache_enabled,
self.fake_pd_id)

def test_protection_domain_rfcache_parameters(self):
self.client.protection_domain.rfcache_parameters(self.fake_pd_id,
page_size=16,
max_io_limit=128,
pass_through_mode=
protection_domain.
RFCacheOperationMode.
write)

def test_protection_domain_rfcache_parameters_bad_status(self):
with self.http_response_mode(self.RESPONSE_MODE.BadStatus):
self.assertRaises(exceptions.PowerFlexClientException,
self.client.protection_domain.
rfcache_parameters, self.fake_pd_id)
4 changes: 2 additions & 2 deletions tests/test_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def setUp(self):

def test_system_api_version(self):
self.client.system.api_version()
self.assertEqual(1, self.get_mock.call_count)
self.assertEqual(3, self.get_mock.call_count)

def test_system_api_version_bad_status(self):
with self.http_response_mode(self.RESPONSE_MODE.BadStatus):
Expand All @@ -61,7 +61,7 @@ def test_system_api_version_cached(self):
self.client.system.api_version()
self.client.system.api_version()
self.client.system.api_version()
self.assertEqual(1, self.get_mock.call_count)
self.assertEqual(3, self.get_mock.call_count)

def test_system_remove_cg_snapshots(self):
self.client.system.remove_cg_snapshots(self.fake_system_id,
Expand Down

0 comments on commit 29b26e0

Please sign in to comment.