From dd529ef847bdb338ea37188fafa028f3d4f00959 Mon Sep 17 00:00:00 2001 From: Bhavneet-Sharma Date: Tue, 20 Sep 2022 12:51:56 +0530 Subject: [PATCH 1/3] Release 1.8.0 for PyPowerStore Python Library --- ChangeLog.md | 3 + ProgrammersGuideExamples/cluster_examples.py | 26 ++++ .../nas_server_examples.py | 3 +- PyPowerStore/__init__.py | 2 +- PyPowerStore/configuration.py | 103 ++++++++++++++++ PyPowerStore/provisioning.py | 111 +++++++++++++++++- .../tests/unit_tests/data/common_data.py | 23 +++- .../tests/unit_tests/entity/cluster.py | 11 ++ .../tests/unit_tests/entity/volume_group.py | 15 +++ PyPowerStore/tests/unit_tests/test_cluster.py | 20 ++++ .../tests/unit_tests/test_nas_server.py | 2 +- .../tests/unit_tests/test_volume_group.py | 14 +++ PyPowerStore/utils/constants.py | 30 +++++ docs/conf.py | 2 +- setup.py | 2 +- 15 files changed, 358 insertions(+), 9 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index ea151a2..5995b8b 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,8 @@ # PyPowerStore Change Log +## Version 1.8.0 - released on 27/09/22 +- Added configuration operations include validate create cluster attributes and create cluster. + ## Version 1.7.0 - released on 28/06/22 - Added configuration operations include LDAP domain and LDAP accounts and getting high level facts about the LDAP accounts. diff --git a/ProgrammersGuideExamples/cluster_examples.py b/ProgrammersGuideExamples/cluster_examples.py index 8ee043f..8c880dc 100644 --- a/ProgrammersGuideExamples/cluster_examples.py +++ b/ProgrammersGuideExamples/cluster_examples.py @@ -28,3 +28,29 @@ # Modify MTU and name of the cluster updated_cluster_details = CONN.config_mgmt.modify_cluster(cluster_id=cluster[0]['id'], physical_mtu=1500, name="AB-C1234") print(updated_cluster_details) + +# Validate create cluster +cluster = {"name": "test_cluster", "ignore_network_warnings": True} +appliances = [{"link_local_address": "4x.3x.2x.1x"}] +dns_servers = ["4x.3x.2x.1x"] +ntp_servers = ["4x.3x.2x.1x"] +networks = [ + { + "type": "Management", + "prefix_length": 24, + "addresses": ["4x.3x.2x.1x", "1xx.2xx.3xx.4xx"] + } +] +is_http_redirect_enabled = True +validate_resp = CONN.config_mgmt.cluster_create_validate( + cluster=cluster, appliances=appliances, dns_servers=dns_servers, + ntp_servers=ntp_servers, networks=networks, + is_http_redirect_enabled=is_http_redirect_enabled) +print(validate_resp) + +# Create Cluster +Create_resp = CONN.config_mgmt.cluster_create( + cluster=cluster, appliances=appliances, dns_servers=dns_servers, + ntp_servers=ntp_servers, networks=networks, + is_http_redirect_enabled=is_http_redirect_enabled) +print(Create_resp) diff --git a/ProgrammersGuideExamples/nas_server_examples.py b/ProgrammersGuideExamples/nas_server_examples.py index 9a226cd..02bb51a 100644 --- a/ProgrammersGuideExamples/nas_server_examples.py +++ b/ProgrammersGuideExamples/nas_server_examples.py @@ -14,7 +14,8 @@ MODIFY_PARAMS = { 'description': 'My Description', - 'current_unix_directory_service': 'Local_Files' + 'current_unix_directory_service': 'Local_Files', + 'protection_policy_id': 'samplepolicyid' } # Get nasserver list diff --git a/PyPowerStore/__init__.py b/PyPowerStore/__init__.py index 3e11b96..f465da9 100644 --- a/PyPowerStore/__init__.py +++ b/PyPowerStore/__init__.py @@ -2,6 +2,6 @@ """__init__.py.""" __title__ = 'PyPowerStore' -__version__ = '1.7.0.0' +__version__ = '1.8.0.0' __author__ = 'Dell Technologies or its subsidiaries' __copyright__ = 'Copyright 2019 Dell Technologies' diff --git a/PyPowerStore/configuration.py b/PyPowerStore/configuration.py index 9486716..d429414 100644 --- a/PyPowerStore/configuration.py +++ b/PyPowerStore/configuration.py @@ -520,6 +520,90 @@ def modify_cluster(self, cluster_id, physical_mtu=None, name=None): ) return self.get_cluster_details(cluster_id) + def cluster_create_validate(self, cluster, appliances, dns_servers, + ntp_servers, networks, + is_http_redirect_enabled, + physical_switches=None, vcenters=None): + """Validate the creation of cluster configuration + :param cluster: Dict containing parameters for the cluster + :type cluster: dict + :param appliances: List containing appliances + :type appliances: list[dict] + :param dns_servers: List containing IP addresses for DNS Servers + :type dns_servers: list[str] + :param ntp_servers: List containing IP addresses for NTP Servers + :type ntp_servers: list[dict] + :param physical_switches: List containing physical switches + :type physical_switches: list[dict] + :param networks: List containing networks + :type networks: list[dict] + :param vcenters: List of vCenters + :type vcenters: list[dict] + :param is_http_redirect_enabled: Whether to redirect the http requests + to https + :type is_http_redirect_enabled: bool + :return: None + :rtype: None + """ + LOG.info("Validating the create cluster configuration") + cluster_url = constants.CREATE_CLUSTER_VALIDATE_URL + + cluster_payload = self.\ + _prepare_create_cluster_payload(is_http_redirect_enabled=is_http_redirect_enabled, + cluster=cluster, + appliances=appliances, + dns_servers=dns_servers, + ntp_servers=ntp_servers, + physical_switches=physical_switches, + networks=networks, + vcenters=vcenters) + return self.config_client.request(constants.POST, + cluster_url.format(self.server_ip), + payload=cluster_payload) + + def cluster_create(self, cluster, appliances, dns_servers, ntp_servers, + networks, is_http_redirect_enabled, + physical_switches=None, vcenters=None, is_async=False): + """Create a Cluster of one or more appliances + :param cluster: Dict containing parameters for the cluster + :type cluster: dict + :param appliances: List containing appliances + :type appliances: list[dict] + :param dns_servers: List containing IP addresses for DNS Servers + :type dns_servers: list[str] + :param ntp_servers: List containing IP addresses for NTP Servers + :type ntp_servers: list[dict] + :param physical_switches: List containing physical switches + :type physical_switches: list[dict] + :param networks: List containing networks + :type networks: list[dict] + :param vcenters: List of vCenters + :type vcenters: list[dict] + :param is_http_redirect_enabled: Whether to redirect the http requests + to https + :type is_http_redirect_enabled: bool + :param is_async: Flag to indicate sync/async operation + :type is_async: bool + :return: Unique identifier of the new instance created + :rtype: str + """ + LOG.info("Creating new cluster configuration") + cluster_url = constants.CREATE_CLUSTER_URL + if is_async: + cluster_url = cluster_url + "?is_async=true" + cluster_payload = self.\ + _prepare_create_cluster_payload(is_http_redirect_enabled=is_http_redirect_enabled, + cluster=cluster, + appliances=appliances, + dns_servers=dns_servers, + ntp_servers=ntp_servers, + physical_switches=physical_switches, + networks=networks, + vcenters=vcenters) + return self.config_client.request(constants.POST, + cluster_url.format(self.server_ip), + payload=cluster_payload) + # Cluster operations end # CHAP config operations start @@ -1988,3 +2072,22 @@ def _prepare_add_remove_network_payload(**kwargs): if kwargs.get(argname) is not None: payload[argname] = kwargs[argname] return payload + + @staticmethod + def _prepare_create_cluster_payload(is_http_redirect_enabled, **kwargs): + """Prepare payload for creation of cluster + :return: Request body + :rtype: dict + """ + payload = dict() + for agrname in ('cluster', 'appliances', 'dns_servers', 'ntp_servers', + 'physical_switches', 'networks', 'vcenters'): + if kwargs.get(agrname) is not None: + payload[agrname] = kwargs[agrname] + + if is_http_redirect_enabled is not None: + security_config = dict() + security_config['is_http_redirect_enabled'] = is_http_redirect_enabled + payload['security_config'] = security_config + + return payload diff --git a/PyPowerStore/provisioning.py b/PyPowerStore/provisioning.py index 97b2c14..64cc783 100644 --- a/PyPowerStore/provisioning.py +++ b/PyPowerStore/provisioning.py @@ -875,6 +875,104 @@ def create_volume_group(self, name, description=None, constants.CREATE_VOLUME_GROUP_URL.format( self.server_ip), payload=payload) + def clone_volume_group(self, volume_group_id, name, description=None, protection_policy_id=None): + """Clone a volume group. + + :param volume_group_id: ID of the volume group to clone + :type volume_group_id: str + :param name: Unique name for the clone volume group. + :type name: str + :param description: (optional) Description for the clone volume group. + :type description: str + :param protection_policy_id: (optional) Unique identifier of the protection + policy to assign to the clone volume group + :type protection_policy_id: str + :return: Unique identifier of the new instance created if success else raise exception + :rtype: dict + """ + LOG.info("Cloning volumegroup: '%s'" % volume_group_id) + payload = self._prepare_clone_vg_payload(name, description, protection_policy_id) + return self.client.request( + constants.POST, + constants.CLONE_VOLUME_GROUP_URL.format(self.server_ip, + volume_group_id), + payload=payload) + + def refresh_volume_group(self, volume_group_id, src_vol_group, + create_backup_snap=None, backup_snap_profile=None): + """Refresh a volume group. + + :param volume_group_id: ID of the volume group to refresh + :type volume_group_id: str + :param src_vol_group: Unique identifier of the volume group to refresh from. + :type src_vol_group: str + :param create_backup_snap: (optional) specifies whether a backup snapshot set of the + target volume group needs to be created before refreshing it. + :type create_backup_snap: bool + :param backup_snap_profile: (optional) Backup profile of the snapshot set to be created. + :type backup_snap_profile: dict + :return: Unique identifier of the backup snapshot set or None if create_backup_snap is None + if success else raise exception + :rtype: dict + """ + LOG.info("Refreshing volumegroup: '%s'" % volume_group_id) + payload = self._prepare_vg_payload('refresh', src_vol_group, create_backup_snap, + backup_snap_profile) + return self.client.request( + constants.POST, + constants.REFRESH_VOLUME_GROUP_URL.format(self.server_ip, + volume_group_id), + payload=payload) + + def restore_volume_group(self, volume_group_id, src_snap_id, + create_backup_snap=None, backup_snap_profile=None): + """Restore a volume group. + + :param volume_group_id: ID of the volume group to restore + :type volume_group_id: str + :param src_snap_id: Unique identifier of the snapshot set to restore from. + :type src_snap_id: str + :param create_backup_snap: (optional) specifies whether a backup snapshot set of the + target volume group needs to be created before restore. + :type create_backup_snap: bool + :param backup_snap_profile: (optional) Backup profile of the snapshot set to be created. + :type backup_snap_profile: dict + :return: Unique identifier of the backup snapshot set or None if create_backup_snap is None + if success else raise exception + :rtype: dict + """ + LOG.info("Restoring volumegroup: '%s'" % volume_group_id) + payload = self._prepare_vg_payload('restore', src_snap_id, create_backup_snap, backup_snap_profile) + return self.client.request( + constants.POST, + constants.RESTORE_VOLUME_GROUP_URL.format(self.server_ip, + volume_group_id), + payload=payload) + + def _prepare_clone_vg_payload(self, name, description, protection_policy_id): + vol_group_clone = dict() + if name is not None: + vol_group_clone['name'] = name + if description is not None: + vol_group_clone['description'] = description + if protection_policy_id is not None: + vol_group_clone['protection_policy_id'] = protection_policy_id + return vol_group_clone + + def _prepare_vg_payload(self, action, src_vol_group, create_backup_snap, + backup_snap_profile): + vg_payload = dict() + if action == 'refresh': + vg_payload['from_object_id'] = src_vol_group + else: + vg_payload['from_snap_id'] = src_vol_group + if create_backup_snap is not None: + vg_payload['create_backup_snap'] = create_backup_snap + if backup_snap_profile: + vg_payload['backup_snap_profile'] = backup_snap_profile + + return vg_payload + def _prepare_create_vg_payload(self, name, description, volume_ids, is_write_order_consistent, protection_policy_id): @@ -1116,6 +1214,7 @@ def get_host_volume_mapping(self, volume_id): ) # NAS Server methods + def get_nas_servers(self, filter_dict=None, all_pages=False): """Get a list of nas servers. @@ -1146,13 +1245,17 @@ def get_nas_server_details(self, nas_server_id): :return: NAS server details :rtype: dict """ + querystring = constants.SELECT_ALL_NAS_SERVER + if helpers.is_foot_hill_prime_or_higher(): + querystring = constants.FHP_NAS_QUERYSTRING + LOG.info("Getting nasserver details by ID: '%s'" % nas_server_id) return self.client.request( constants.GET, constants.GET_NAS_SERVER_DETAILS_URL.format(self.server_ip, nas_server_id), payload=None, - querystring=constants.SELECT_ALL_NAS_SERVER) + querystring=querystring) def get_nas_server_by_name(self, nas_server_name): """Get details of a NAS Server by name. @@ -1162,13 +1265,17 @@ def get_nas_server_by_name(self, nas_server_name): :return: NAS server details :rtype: dict """ + querystring = constants.SELECT_ALL_NAS_SERVER + if helpers.is_foot_hill_prime_or_higher(): + querystring = constants.FHP_NAS_QUERYSTRING + LOG.info("Getting nasserver details by name: '%s'" % nas_server_name) return self.client.request( constants.GET, constants.GET_NAS_SERVER_DETAILS_BY_NAME_URL.format( self.server_ip), payload=None, querystring=helpers.prepare_querystring( - constants.SELECT_ALL_NAS_SERVER, + querystring, name=constants.EQUALS + nas_server_name ) ) diff --git a/PyPowerStore/tests/unit_tests/data/common_data.py b/PyPowerStore/tests/unit_tests/data/common_data.py index 6e8f057..308d769 100644 --- a/PyPowerStore/tests/unit_tests/data/common_data.py +++ b/PyPowerStore/tests/unit_tests/data/common_data.py @@ -56,6 +56,11 @@ class CommonData(object): vg_id2 = "007a5fad-7520-4f2a-a364-6c243d8d4ecf" vg_name2 = "my_vg2" + create_snapshot = True + snapshot_id = "008a5fad-7520-4f2a-a364-6c243d8d4ecf" + backup_snapshot_profile = {'name' : 'backup_snapshot_name', 'description': '', + 'expiration_timestamp': '2023-01-01 00:00:00'} + volumegroup_list = [{"id": vg_id1, "name": vg_name1}, {"id": vg_id2, "name": vg_name2}] @@ -324,7 +329,8 @@ class CommonData(object): 'operational_status': 'Started', 'operational_status_l10n': 'Started', 'production_IPv4_interface_id': None, - 'production_IPv6_interface_id': None} + 'production_IPv6_interface_id': None, + 'protection_policy_id': 'samplepolicyid'} nas_valid_param_list = [ 'name', 'description', 'current_node_id', 'preferred_node_id', @@ -332,7 +338,7 @@ class CommonData(object): 'default_windows_user', 'is_username_translation_enabled', 'is_auto_user_mapping_enabled', 'production_IPv4_interface_id', 'production_IPv6_interface_id', 'backup_IPv4_interface_id', - 'backup_IPv6_interface_id'] + 'backup_IPv6_interface_id', 'protection_policy_id'] nas_id_not_exist = "5f4a3017-0bad-899e-e1eb-c6f547282e66" nas_error = { @@ -1062,6 +1068,19 @@ class CommonData(object): "compatibility_level": 10, "state_l10n": "Configured" } + cluster = {"name": "test_cluster", "ignore_network_warnings": True} + appliances = [{"link_local_address": "4x.3x.2x.1x"}] + dns_servers = ["4x.3x.2x.1x"] + ntp_servers = ["4x.3x.2x.1x"] + networks = [ + { + "type": "Management", + "prefix_length": 24, + "addresses": ["4x.3x.2x.1x", "1xx.2xx.3xx.4xx"] + } + ] + is_http_redirect_enabled = True + invalid_cluster_id = '10' cluster_error = { 404: { diff --git a/PyPowerStore/tests/unit_tests/entity/cluster.py b/PyPowerStore/tests/unit_tests/entity/cluster.py index d21424c..a59d29c 100644 --- a/PyPowerStore/tests/unit_tests/entity/cluster.py +++ b/PyPowerStore/tests/unit_tests/entity/cluster.py @@ -22,6 +22,11 @@ def get_api_name(self): return self.get_cluster_details elif self.method == 'PATCH': return self.modify_cluster + elif self.method == 'POST': + if self.url.endswith('/validate_create'): + return self.cluster_create_validate + else: + return self.cluster_create def execute_api(self, api_name): status_code, response = api_name() @@ -42,3 +47,9 @@ def get_cluster_by_name(self): def modify_cluster(self): return 204, self.data.cluster_details_1 + def cluster_create(self): + return 201, self.data.cluster_id_1 + + def cluster_create_validate(self): + return 204, None + diff --git a/PyPowerStore/tests/unit_tests/entity/volume_group.py b/PyPowerStore/tests/unit_tests/entity/volume_group.py index 40183da..5832843 100644 --- a/PyPowerStore/tests/unit_tests/entity/volume_group.py +++ b/PyPowerStore/tests/unit_tests/entity/volume_group.py @@ -23,6 +23,12 @@ def get_api_name(self): elif self.method == 'POST': if self.url.endswith('/add_members'): return self.add_members_to_volume_group + elif self.url.endswith('/clone'): + return self.clone_volume_group + elif self.url.endswith('/restore'): + return self.restore_volume_group + elif self.url.endswith('/refresh'): + return self.refresh_volume_group return self.create_volume_group elif self.method == 'PATCH': return self.modify_volume_group @@ -61,3 +67,12 @@ def modify_volume_group(self): def delete_volume_group(self): return 204, None + + def clone_volume_group(self): + return self.status_code, self.data.vg_id2 + + def refresh_volume_group(self): + return self.status_code, self.data.snapshot_id + + def restore_volume_group(self): + return self.status_code, self.data.snapshot_id diff --git a/PyPowerStore/tests/unit_tests/test_cluster.py b/PyPowerStore/tests/unit_tests/test_cluster.py index 18091c3..90540df 100644 --- a/PyPowerStore/tests/unit_tests/test_cluster.py +++ b/PyPowerStore/tests/unit_tests/test_cluster.py @@ -29,3 +29,23 @@ def test_get_cluster_by_name(self): cluster_list = self.configuration.get_cluster_by_name( self.data.cluster_name_1) self.assertListEqual(cluster_list, self.data.cluster_list) + + def test_validate_cluster_create(self): + resp = self.configuration.\ + cluster_create_validate(cluster=self.data.cluster, + appliances=self.data.appliances, + dns_servers=self.data.dns_servers, + ntp_servers=self.data.ntp_servers, + networks=self.data.networks, + is_http_redirect_enabled=self.data.is_http_redirect_enabled) + self.assertIsNone(resp) + + def test_cluster_create(self): + resp = self.configuration.\ + cluster_create(cluster=self.data.cluster, + appliances=self.data.appliances, + dns_servers=self.data.dns_servers, + ntp_servers=self.data.ntp_servers, + networks=self.data.networks, + is_http_redirect_enabled=self.data.is_http_redirect_enabled) + self.assertEqual(resp, self.data.cluster_id_1) diff --git a/PyPowerStore/tests/unit_tests/test_nas_server.py b/PyPowerStore/tests/unit_tests/test_nas_server.py index b2558ac..c21a749 100644 --- a/PyPowerStore/tests/unit_tests/test_nas_server.py +++ b/PyPowerStore/tests/unit_tests/test_nas_server.py @@ -45,7 +45,7 @@ def test_get_nas_server_by_name(self): self.assertEqual(nas_detail, self.data.nas_detail) def test_modify_nasserver(self): - param = {'default_unix_user': '1', 'default_windows_user': '10'} + param = {'default_unix_user': '1', 'default_windows_user': '10', 'protection_policy_id': 'samplepolicyid'} resp = self.provisioning.modify_nasserver(self.data.nas_id1, param) self.assertIsNone(resp) # name will be skipped and will not be passed to request() diff --git a/PyPowerStore/tests/unit_tests/test_volume_group.py b/PyPowerStore/tests/unit_tests/test_volume_group.py index 8996c49..b07ed92 100644 --- a/PyPowerStore/tests/unit_tests/test_volume_group.py +++ b/PyPowerStore/tests/unit_tests/test_volume_group.py @@ -58,3 +58,17 @@ def test_add_invalid_volume_to_volume_group(self): def test_delete_volume_group(self): vg = self.provisioning.delete_volume_group(self.data.vg_id1) self.assertIsNone(vg) + + def test_clone_volume_group(self): + vg_clone_id = self.provisioning.clone_volume_group(self.data.vg_id1, self.data.vg_name2, None, self.data.pol_id) + self.assertEqual(vg_clone_id, self.data.vg_id2) + + def test_refresh_volume_group(self): + snapshot_id = self.provisioning.refresh_volume_group(self.data.vg_id1, self.data.vg_name2, + self.data.create_snapshot, self.data.backup_snapshot_profile) + self.assertEqual(snapshot_id, self.data.snapshot_id) + + def test_restore_volume_group(self): + snapshot_id = self.provisioning.restore_volume_group(self.data.vg_id1, self.data.vg_name2, + self.data.create_snapshot, self.data.backup_snapshot_profile) + self.assertEqual(snapshot_id, self.data.snapshot_id) diff --git a/PyPowerStore/utils/constants.py b/PyPowerStore/utils/constants.py index fc978e7..fe8431f 100644 --- a/PyPowerStore/utils/constants.py +++ b/PyPowerStore/utils/constants.py @@ -122,6 +122,31 @@ "creator_type_l10n,nas_server(name,id)," "protection_policy(name,id)"} + +FHP_NAS_QUERYSTRING = {"select": "id,name, description, operational_status," + "current_node_id,preferred_node_id," + "default_unix_user,default_windows_user," + "current_unix_directory_service," + "is_username_translation_enabled," + "is_auto_user_mapping_enabled," + "production_IPv4_interface_id," + "production_IPv6_interface_id," + "backup_IPv4_interface_id," + "backup_IPv6_interface_id," + "current_preferred_IPv4_interface_id," + "current_preferred_IPv6_interface_id," + "protection_policy_id," + "operational_status_l10n," + "current_unix_directory_service_l10n," + "file_interfaces(name,id,ip_address)," + "nfs_servers,smb_servers," + "file_ldaps,file_nises,file_systems(id,name)" + "file_events_publishing_mode," + "is_replication_destination," + "is_production_mode_enabled," + "current_unix_directory_service_l10n," + "file_events_publishing_mode_l10n"} + SELECT_ALL_NAS_SERVER = {"select": "id,name, description, operational_status," "current_node_id,preferred_node_id," "default_unix_user,default_windows_user," @@ -377,6 +402,9 @@ GET_VOLUME_GROUP_DETAILS_URL = 'https://{0}/api/rest/volume_group/{1}' MODIFY_VOLUME_GROUP_URL = GET_VOLUME_GROUP_DETAILS_URL DELETE_VOLUME_GROUP_URL = GET_VOLUME_GROUP_DETAILS_URL +CLONE_VOLUME_GROUP_URL = 'https://{0}/api/rest/volume_group/{1}/clone' +REFRESH_VOLUME_GROUP_URL = 'https://{0}/api/rest/volume_group/{1}/refresh' +RESTORE_VOLUME_GROUP_URL = 'https://{0}/api/rest/volume_group/{1}/restore' ADD_MEMBERS_TO_VOLUME_GROUP_URL = \ 'https://{0}/api/rest/volume_group/{1}/add_members' REMOVE_MEMBERS_FROM_VOLUME_GROUP_URL = \ @@ -496,6 +524,8 @@ GET_CLUSTER_DETAILS_URL = 'https://{0}/api/rest/cluster/{1}' GET_CLUSTER_LIST_URL = 'https://{0}/api/rest/cluster' MODIFY_CLUSTER_URL = GET_CLUSTER_DETAILS_URL +CREATE_CLUSTER_URL = GET_CLUSTER_LIST_URL +CREATE_CLUSTER_VALIDATE_URL = 'https://{0}/api/rest/cluster/validate_create' # CHAP config endpoints GET_CHAP_CONFIG_LIST_URL = 'https://{0}/api/rest/chap_config' diff --git a/docs/conf.py b/docs/conf.py index 3461458..8f28f60 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -22,7 +22,7 @@ author = 'Dell' # The full version, including alpha/beta/rc tags -release = '1.6.0' +release = '1.8.0' # -- General configuration --------------------------------------------------- diff --git a/setup.py b/setup.py index 8c20406..10e8144 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ setup(name='PyPowerStore', - version='1.7.0.0', + version='1.8.0.0', description='Python Library for Dell PowerStore', author='Ansible Team at Dell', author_email='ansible.team@dell.com', From 8a656d12bf4ca98313e91855e0ad837dfb330510 Mon Sep 17 00:00:00 2001 From: Bhavneet-Sharma Date: Tue, 20 Sep 2022 13:00:17 +0530 Subject: [PATCH 2/3] Release 1.8.0 for PyPowerStore Python Library --- ChangeLog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index 5995b8b..65dfce0 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,7 +1,7 @@ # PyPowerStore Change Log ## Version 1.8.0 - released on 27/09/22 -- Added configuration operations include validate create cluster attributes and create cluster. +- Added configuration operations include validate create cluster attributes and create cluster, clone/restore/refresh a volume group, support for protection_policy_id for NAS server for FHP and above. ## Version 1.7.0 - released on 28/06/22 - Added configuration operations include LDAP domain and LDAP accounts and getting high level facts about the LDAP accounts. From d65d3e7b32b8041a34f6ae04b3da186c8cc9b1f1 Mon Sep 17 00:00:00 2001 From: Bhavneet-Sharma Date: Tue, 20 Sep 2022 13:49:44 +0530 Subject: [PATCH 3/3] Release 1.8.0 for PyPowerStore Python Library --- ChangeLog.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index 65dfce0..8d6c0ce 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,7 +1,9 @@ # PyPowerStore Change Log ## Version 1.8.0 - released on 27/09/22 -- Added configuration operations include validate create cluster attributes and create cluster, clone/restore/refresh a volume group, support for protection_policy_id for NAS server for FHP and above. +- Added configuration operations include validate create cluster attributes and create cluster. +- Added support for clone, restore, and refresh a volume group. +- Added support for protection_policy_id for NAS server for FHP and above. ## Version 1.7.0 - released on 28/06/22 - Added configuration operations include LDAP domain and LDAP accounts and getting high level facts about the LDAP accounts.