diff --git a/ChangeLog.md b/ChangeLog.md index 1130dea..ea151a2 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,8 @@ # PyPowerStore Change Log +## 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. + ## Version 1.6.0 - released on 25/03/22 - Added configuration operations includes SMTP configuration, email notification, NTP servers, DNS servers, remote support and remote support contacts and getting high level facts about all these entities. diff --git a/ProgrammersGuideExamples/appliance_examples.py b/ProgrammersGuideExamples/appliance_examples.py index d0510f7..ea6e5a0 100644 --- a/ProgrammersGuideExamples/appliance_examples.py +++ b/ProgrammersGuideExamples/appliance_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2021, Dell EMC +# Copyright: (c) 2021, Dell Technologies """ Appliance operations""" diff --git a/ProgrammersGuideExamples/certificate_examples.py b/ProgrammersGuideExamples/certificate_examples.py index 8f003ca..8b4f0e1 100644 --- a/ProgrammersGuideExamples/certificate_examples.py +++ b/ProgrammersGuideExamples/certificate_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2021, Dell EMC +# Copyright: (c) 2021, Dell Technologies """ Certificate operations""" diff --git a/ProgrammersGuideExamples/chap_config_examples.py b/ProgrammersGuideExamples/chap_config_examples.py index b893ee3..49cddea 100644 --- a/ProgrammersGuideExamples/chap_config_examples.py +++ b/ProgrammersGuideExamples/chap_config_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2021, Dell EMC +# Copyright: (c) 2021, Dell Technologies """ CHAP config operations""" diff --git a/ProgrammersGuideExamples/cluster_examples.py b/ProgrammersGuideExamples/cluster_examples.py index 008320e..8ee043f 100644 --- a/ProgrammersGuideExamples/cluster_examples.py +++ b/ProgrammersGuideExamples/cluster_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2021, Dell EMC +# Copyright: (c) 2021, Dell Technologies """ Cluster Operations""" from PyPowerStore import powerstore_conn diff --git a/ProgrammersGuideExamples/dns_examples.py b/ProgrammersGuideExamples/dns_examples.py index 4470706..c604394 100644 --- a/ProgrammersGuideExamples/dns_examples.py +++ b/ProgrammersGuideExamples/dns_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2022, Dell EMC +# Copyright: (c) 2022, Dell Technologies """ DNS operations""" diff --git a/ProgrammersGuideExamples/email_examples.py b/ProgrammersGuideExamples/email_examples.py index f09f46a..30db2dd 100644 --- a/ProgrammersGuideExamples/email_examples.py +++ b/ProgrammersGuideExamples/email_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2022, Dell EMC +# Copyright: (c) 2022, Dell Technologies """ Email operations""" diff --git a/ProgrammersGuideExamples/file_system_examples.py b/ProgrammersGuideExamples/file_system_examples.py index ed1ed6b..b2692db 100644 --- a/ProgrammersGuideExamples/file_system_examples.py +++ b/ProgrammersGuideExamples/file_system_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2020, Dell EMC +# Copyright: (c) 2020, Dell Technologies """ File System Operations""" from PyPowerStore import powerstore_conn diff --git a/ProgrammersGuideExamples/file_tree_quota_examples.py b/ProgrammersGuideExamples/file_tree_quota_examples.py index ec29118..419fb72 100644 --- a/ProgrammersGuideExamples/file_tree_quota_examples.py +++ b/ProgrammersGuideExamples/file_tree_quota_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2020, Dell EMC +# Copyright: (c) 2020, Dell Technologies """ File Tree Quota Operations""" from PyPowerStore import powerstore_conn diff --git a/ProgrammersGuideExamples/file_user_quota_examples.py b/ProgrammersGuideExamples/file_user_quota_examples.py index a3845d1..e940aa0 100644 --- a/ProgrammersGuideExamples/file_user_quota_examples.py +++ b/ProgrammersGuideExamples/file_user_quota_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2020, Dell EMC +# Copyright: (c) 2020, Dell Technologies """ File User Quota Operations""" from PyPowerStore import powerstore_conn diff --git a/ProgrammersGuideExamples/gather_facts_examples.py b/ProgrammersGuideExamples/gather_facts_examples.py deleted file mode 100644 index 80ee9da..0000000 --- a/ProgrammersGuideExamples/gather_facts_examples.py +++ /dev/null @@ -1,126 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright: (c) 2019-2021, Dell EMC - -""" Gather Facts Module Operations""" - -from PyPowerStore import powerstore_conn - -CONN = powerstore_conn.PowerStoreConn(username="", - password="", - server_ip="", - verify=False, - application_type="", - timeout=180.0) -print(CONN) - -# Get volume list -filter_dict = {'name': 'ilike.*vol*'} -VOL_LIST = CONN.provisioning.get_volumes(all_pages=True, - filter_dict=filter_dict) -print(VOL_LIST) - -# Get list of Host Groups -RESP = CONN.provisioning.get_host_group_list() -print(RESP) - -# Get Host list -filter_dict = {'os_type': 'neq.Linux'} -RESP = CONN.provisioning.get_hosts(filter_dict=filter_dict) -print(RESP) - -# Get Volume Group list -RESP = CONN.provisioning.get_volume_group_list() -print(RESP) - -# Get Nodes -RESP = CONN.provisioning.get_nodes() -print(RESP) - -# Get cluster list -RESP = CONN.provisioning.get_cluster_list() -print(RESP) - -# Get snapshot rules list -filter_dict = {'desired_retention': ['gt.100', 'lt.500']} -RESP = CONN.protection.get_snapshot_rules(filter_dict=filter_dict) -print(RESP) - -# Get protection policies list -RESP = CONN.protection.get_protection_policies() -print(RESP) - -# Get file systems list -RESP = CONN.provisioning.get_file_systems() -print(RESP) - -# Get NAS servers list -RESP = CONN.provisioning.get_nas_servers() -print(RESP) - -# Get NFS exports list -RESP = CONN.provisioning.get_nfs_exports() -print(RESP) - -# Get SMB shares list -RESP = CONN.provisioning.get_smb_shares() -print(RESP) - -# Get tree quotas list -RESP = CONN.provisioning.get_file_tree_quotas() -print(RESP) - -# Get user quotas list -RESP = CONN.provisioning.get_file_user_quotas() -print(RESP) - -# Get replication rules list -RESP = CONN.protection.get_replication_rules() -print(RESP) - -# Get replication sessions list -RESP = CONN.protection.get_replication_sessions() -print(RESP) - -# Get remote systems list -RESP = CONN.protection.get_remote_systems() -print(RESP) - -# Get networks list -RESP = CONN.config_mgmt.get_networks() -print(RESP) - -# Get clusters list -RESP = CONN.config_mgmt.get_clusters() -print(RESP) - -# Get local users list -RESP = CONN.config_mgmt.get_local_users() -print(RESP) - -# Get roles list -RESP = CONN.config_mgmt.get_roles() -print(RESP) - -# Get appliances list -RESP = CONN.config_mgmt.get_appliances() -print(RESP) - -# Get ip pool addresses list -RESP = CONN.config_mgmt.get_ip_pool_address() -print(RESP) - -# Get chap configs list -RESP = CONN.config_mgmt.get_chap_configs() -print(RESP) - -# Get service configs list -RESP = CONN.config_mgmt.get_service_configs() -print(RESP) - -# Get service users list -RESP = CONN.config_mgmt.get_service_users() -print(RESP) - -# Get vcenters list -RESP = CONN.config_mgmt.get_vcenters() -print(RESP) diff --git a/ProgrammersGuideExamples/host_examples.py b/ProgrammersGuideExamples/host_examples.py index c430c34..bdbae76 100644 --- a/ProgrammersGuideExamples/host_examples.py +++ b/ProgrammersGuideExamples/host_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2019, Dell EMC +# Copyright: (c) 2019, Dell Technologies """ Host Module Operations""" diff --git a/ProgrammersGuideExamples/host_group_examples.py b/ProgrammersGuideExamples/host_group_examples.py index 7c3f603..b3c5833 100644 --- a/ProgrammersGuideExamples/host_group_examples.py +++ b/ProgrammersGuideExamples/host_group_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2019, Dell EMC +# Copyright: (c) 2019, Dell Technologies """ Host Group Module Operations""" diff --git a/ProgrammersGuideExamples/info_examples.py b/ProgrammersGuideExamples/info_examples.py index 3bf2a7d..0c59aa0 100644 --- a/ProgrammersGuideExamples/info_examples.py +++ b/ProgrammersGuideExamples/info_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2019-2021, Dell EMC +# Copyright: (c) 2019-2021, Dell Technologies """ Info Module Operations""" diff --git a/ProgrammersGuideExamples/ip_pool_address_examples.py b/ProgrammersGuideExamples/ip_pool_address_examples.py index 714719c..484d26e 100644 --- a/ProgrammersGuideExamples/ip_pool_address_examples.py +++ b/ProgrammersGuideExamples/ip_pool_address_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2021, Dell EMC +# Copyright: (c) 2021, Dell Technologies """ IP Pool Address Operations""" from PyPowerStore import powerstore_conn diff --git a/ProgrammersGuideExamples/ip_port_examples.py b/ProgrammersGuideExamples/ip_port_examples.py index e5b14d3..377fc99 100644 --- a/ProgrammersGuideExamples/ip_port_examples.py +++ b/ProgrammersGuideExamples/ip_port_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2021, Dell EMC +# Copyright: (c) 2021, Dell Technologies """ IP Port Operations""" from PyPowerStore import powerstore_conn diff --git a/ProgrammersGuideExamples/ldap_account_examples.py b/ProgrammersGuideExamples/ldap_account_examples.py new file mode 100644 index 0000000..73b4d90 --- /dev/null +++ b/ProgrammersGuideExamples/ldap_account_examples.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Copyright: (c) 2022, Dell Technologies + +""" LDAP Account operations""" + +from PyPowerStore import powerstore_conn + +CONN = powerstore_conn.PowerStoreConn(username="", + password="", + server_ip="", + verify=False, + timeout=180.0) +print(CONN) + +# Create LDAP account +create_dict = { + + "domain_id": "2", + "name": "ldap_test_user_1", + "type": "User", + "role_id": "1" + +} +resp = CONN.config_mgmt.create_ldap_account(create_dict) +print(resp) + +# Modify LDAP account +modify_dict = { + "role_id": "2" +} +resp = CONN.config_mgmt.modify_ldap_account_details(resp['id'], modify_dict) +print(resp) + +# Get LDAP account list +ldap_account_list = CONN.config_mgmt.get_ldap_account_list() +print(ldap_account_list) + +# Get LDAP account details +ldap_account_details = CONN.config_mgmt.get_ldap_account_details(ldap_account_list[0]['id']) +print(ldap_account_details) + +# Get LDAP account details by name +ldap_account_details = CONN.config_mgmt.get_ldap_account_details_by_name(ldap_account_list[0]['name']) +print(ldap_account_details) + +# Delete LDAP domain configuration +resp = CONN.config_mgmt.delete_ldap_account(ldap_account_details['id']) +print(resp) diff --git a/ProgrammersGuideExamples/ldap_domain_examples.py b/ProgrammersGuideExamples/ldap_domain_examples.py new file mode 100644 index 0000000..6f65394 --- /dev/null +++ b/ProgrammersGuideExamples/ldap_domain_examples.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright: (c) 2022, Dell Technologies + +""" LDAP domain operations""" + +from PyPowerStore import powerstore_conn + +CONN = powerstore_conn.PowerStoreConn(username="", + password="", + server_ip="", + verify=False, + application_type="", + timeout=180.0) +print(CONN) + +# Create LDAP domain configuration +create_dict = { + "domain_name": "<>", + "ldap_servers": [ + "<>" + ], + "protocol": "LDAP", + "ldap_server_type": "OpenLDAP", + "bind_user": "<>", + "bind_password": "<>", + "is_global_catalog": False, + "user_search_path": "cn=Users", + "group_search_path": "cn=Users" +} +resp = CONN.config_mgmt.create_ldap_domain_configuration(create_dict) +print(resp) + +# Verify LDAP domain configuration +print(CONN.config_mgmt.verify_ldap_domain_configuration(resp['id'])) + +# Modify LDAP domain configuration +modify_dict = { + "ldap_server_type": "AD" +} +resp = CONN.config_mgmt.modify_ldap_domain_configuration(resp['id'], modify_dict) +print(resp) + +# Get LDAP domain configuration list +ldap_domain_list = CONN.config_mgmt.get_ldap_domain_configuration_list() +print(ldap_domain_list) + +# Get LDAP domain configuration details +ldap_domain_details = CONN.config_mgmt.get_ldap_domain_configuration_details(ldap_domain_list[0]['id']) +print(ldap_domain_details) + +# Get LDAP domain configuration details by name +ldap_domain_details = CONN.config_mgmt.get_ldap_domain_configuration_details_by_name(ldap_domain_details['domain_name']) +print(ldap_domain_details) + +# Delete LDAP domain configuration +resp = CONN.config_mgmt.delete_ldap_domain_configuration(resp['id']) +print(resp) diff --git a/ProgrammersGuideExamples/local_user_examples.py b/ProgrammersGuideExamples/local_user_examples.py index 1c7d3b5..effc983 100644 --- a/ProgrammersGuideExamples/local_user_examples.py +++ b/ProgrammersGuideExamples/local_user_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2021, Dell EMC +# Copyright: (c) 2021, Dell Technologies """ Local User Operations""" from PyPowerStore import powerstore_conn diff --git a/ProgrammersGuideExamples/nas_server_examples.py b/ProgrammersGuideExamples/nas_server_examples.py index f25151c..9a226cd 100644 --- a/ProgrammersGuideExamples/nas_server_examples.py +++ b/ProgrammersGuideExamples/nas_server_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2020, Dell EMC +# Copyright: (c) 2020, Dell Technologies """ NAS Server Operations""" from PyPowerStore import powerstore_conn diff --git a/ProgrammersGuideExamples/network_examples.py b/ProgrammersGuideExamples/network_examples.py index e6a78f2..2b8db1c 100644 --- a/ProgrammersGuideExamples/network_examples.py +++ b/ProgrammersGuideExamples/network_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2021, Dell EMC +# Copyright: (c) 2021, Dell Technologies """ Network Operations""" from PyPowerStore import powerstore_conn diff --git a/ProgrammersGuideExamples/nfs_export_examples.py b/ProgrammersGuideExamples/nfs_export_examples.py index 40313d6..36df5f9 100644 --- a/ProgrammersGuideExamples/nfs_export_examples.py +++ b/ProgrammersGuideExamples/nfs_export_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2020, Dell EMC +# Copyright: (c) 2020, Dell Technologies """ NFS Export Operations""" from PyPowerStore import powerstore_conn diff --git a/ProgrammersGuideExamples/ntp_examples.py b/ProgrammersGuideExamples/ntp_examples.py index b5d48de..3e4b4c7 100644 --- a/ProgrammersGuideExamples/ntp_examples.py +++ b/ProgrammersGuideExamples/ntp_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2022, Dell EMC +# Copyright: (c) 2022, Dell Technologies """ NTP operations""" diff --git a/ProgrammersGuideExamples/protection_examples.py b/ProgrammersGuideExamples/protection_examples.py index 9adfd69..d14f0c0 100644 --- a/ProgrammersGuideExamples/protection_examples.py +++ b/ProgrammersGuideExamples/protection_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2019, Dell EMC +# Copyright: (c) 2019, Dell Technologies """ Protection Policy Module Operations""" diff --git a/ProgrammersGuideExamples/remote_support_contact_examples.py b/ProgrammersGuideExamples/remote_support_contact_examples.py index 7e66890..c7de72f 100644 --- a/ProgrammersGuideExamples/remote_support_contact_examples.py +++ b/ProgrammersGuideExamples/remote_support_contact_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2022, Dell EMC +# Copyright: (c) 2022, Dell Technologies """ Remote Support Contact operations""" diff --git a/ProgrammersGuideExamples/remote_support_examples.py b/ProgrammersGuideExamples/remote_support_examples.py index 96c6beb..f2b8d99 100644 --- a/ProgrammersGuideExamples/remote_support_examples.py +++ b/ProgrammersGuideExamples/remote_support_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2022, Dell EMC +# Copyright: (c) 2022, Dell Technologies """ Remote Support operations""" diff --git a/ProgrammersGuideExamples/remote_system_examples.py b/ProgrammersGuideExamples/remote_system_examples.py index 633881f..0d18df3 100644 --- a/ProgrammersGuideExamples/remote_system_examples.py +++ b/ProgrammersGuideExamples/remote_system_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2021, Dell EMC +# Copyright: (c) 2021, Dell Technologies """ Remote system operations""" diff --git a/ProgrammersGuideExamples/replication_session_examples.py b/ProgrammersGuideExamples/replication_session_examples.py index 857a88d..a213e0c 100644 --- a/ProgrammersGuideExamples/replication_session_examples.py +++ b/ProgrammersGuideExamples/replication_session_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2021, Dell EMC +# Copyright: (c) 2021, Dell Technologies """ Replication session Operations""" diff --git a/ProgrammersGuideExamples/role_examples.py b/ProgrammersGuideExamples/role_examples.py index 4a88824..3e78251 100644 --- a/ProgrammersGuideExamples/role_examples.py +++ b/ProgrammersGuideExamples/role_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2021, Dell EMC +# Copyright: (c) 2021, Dell Technologies """ Role operations""" diff --git a/ProgrammersGuideExamples/security_config_examples.py b/ProgrammersGuideExamples/security_config_examples.py index 5e691ae..d16874e 100644 --- a/ProgrammersGuideExamples/security_config_examples.py +++ b/ProgrammersGuideExamples/security_config_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2021, Dell EMC +# Copyright: (c) 2021, Dell Technologies """ Security config operations""" diff --git a/ProgrammersGuideExamples/service_config_examples.py b/ProgrammersGuideExamples/service_config_examples.py index 5af2e9b..3022034 100644 --- a/ProgrammersGuideExamples/service_config_examples.py +++ b/ProgrammersGuideExamples/service_config_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2021, Dell EMC +# Copyright: (c) 2021, Dell Technologies """ Service config operations""" diff --git a/ProgrammersGuideExamples/service_user_examples.py b/ProgrammersGuideExamples/service_user_examples.py index 5e8b7e3..d167683 100644 --- a/ProgrammersGuideExamples/service_user_examples.py +++ b/ProgrammersGuideExamples/service_user_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2021, Dell EMC +# Copyright: (c) 2021, Dell Technologies """ Service user module operations""" diff --git a/ProgrammersGuideExamples/smb_share_examples.py b/ProgrammersGuideExamples/smb_share_examples.py index c25c51e..a6cd2e0 100644 --- a/ProgrammersGuideExamples/smb_share_examples.py +++ b/ProgrammersGuideExamples/smb_share_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2020, Dell EMC +# Copyright: (c) 2020, Dell Technologies """ SMB Share Operations""" from PyPowerStore import powerstore_conn diff --git a/ProgrammersGuideExamples/smtp_config_examples.py b/ProgrammersGuideExamples/smtp_config_examples.py index 37599af..05e95ee 100644 --- a/ProgrammersGuideExamples/smtp_config_examples.py +++ b/ProgrammersGuideExamples/smtp_config_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2022, Dell EMC +# Copyright: (c) 2022, Dell Technologies """ SMTP Config operations""" diff --git a/ProgrammersGuideExamples/snapshot_examples.py b/ProgrammersGuideExamples/snapshot_examples.py index c338a47..77061a9 100644 --- a/ProgrammersGuideExamples/snapshot_examples.py +++ b/ProgrammersGuideExamples/snapshot_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2019, Dell EMC +# Copyright: (c) 2019, Dell Technologies """ Snapshot Module Operations""" diff --git a/ProgrammersGuideExamples/vcenter_examples.py b/ProgrammersGuideExamples/vcenter_examples.py index d19dfa1..0176ddd 100644 --- a/ProgrammersGuideExamples/vcenter_examples.py +++ b/ProgrammersGuideExamples/vcenter_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2021, Dell EMC +# Copyright: (c) 2021, Dell Technologies """ Vcenter Operations""" from PyPowerStore import powerstore_conn diff --git a/ProgrammersGuideExamples/volume_examples.py b/ProgrammersGuideExamples/volume_examples.py index eca8540..c769713 100644 --- a/ProgrammersGuideExamples/volume_examples.py +++ b/ProgrammersGuideExamples/volume_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2019, Dell EMC +# Copyright: (c) 2019, Dell Technologies """ Volume Module Operations""" diff --git a/ProgrammersGuideExamples/volume_group_examples.py b/ProgrammersGuideExamples/volume_group_examples.py index 8c3ee2d..7909f52 100644 --- a/ProgrammersGuideExamples/volume_group_examples.py +++ b/ProgrammersGuideExamples/volume_group_examples.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2019, Dell EMC +# Copyright: (c) 2019, Dell Technologies """ Volume Group Module Operations""" diff --git a/PyPowerStore/__init__.py b/PyPowerStore/__init__.py index ea2b2dc..3e11b96 100644 --- a/PyPowerStore/__init__.py +++ b/PyPowerStore/__init__.py @@ -2,6 +2,6 @@ """__init__.py.""" __title__ = 'PyPowerStore' -__version__ = '1.6.0.0' -__author__ = 'Dell EMC or its subsidiaries' -__copyright__ = 'Copyright 2019 Dell EMC' +__version__ = '1.7.0.0' +__author__ = 'Dell Technologies or its subsidiaries' +__copyright__ = 'Copyright 2019 Dell Technologies' diff --git a/PyPowerStore/client.py b/PyPowerStore/client.py index b5c9742..ca209cd 100644 --- a/PyPowerStore/client.py +++ b/PyPowerStore/client.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2019-2021, Dell EMC +# Copyright: (c) 2019, Dell Technologies """Client module for PowerStore""" @@ -21,7 +21,8 @@ # Codes VALID_CODES = [200, 201, 202, 204, 206, 207] -ENGVIS_LIST = ["remote_support"] +ENGVIS_LIST = ["remote_support", "node", "volume_group"] + class Client(): """Client class for PowerStore""" diff --git a/PyPowerStore/configuration.py b/PyPowerStore/configuration.py index 9dc97ea..9486716 100644 --- a/PyPowerStore/configuration.py +++ b/PyPowerStore/configuration.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2021, Dell EMC +# Copyright: (c) 2021, Dell Technologies """Collection of configuration related functions for PowerStore""" @@ -1283,7 +1283,7 @@ def create_destination_email(self, create_params): # smtp operations start def get_smtp_configs(self, filter_dict=None, all_pages=None): - """Get all SMTP configurationss. + """Get all SMTP configurations. :param filter_dict: (optional) Filter details :type filter_dict: dict @@ -1606,7 +1606,7 @@ def test_remote_support_config(self, remote_support_id): # Remote Support operations end - # Remote Support conatct operations start + # Remote Support contact operations start def get_remote_support_contact_list(self, filter_dict=None, all_pages=None): """Get all remote support contacts available on array. @@ -1686,7 +1686,281 @@ def modify_remote_support_contact_details(self, remote_support_contact_id, modif payload=modify_parameters) raise Exception("Not supported for PowerStore versions less than 2.0.0.0") - # Remote Support conatct operations end + # Remote Support contact operations end + + # LDAP Domain operations start + + def get_ldap_domain_configuration_list(self, filter_dict=None, all_pages=None): + """Get all LDAP domain configurations available on array. + + :param filter_dict: (optional) Filter details + :type filter_dict: dict + :param all_pages: (optional) Indicates whether to return all ldap + domain configurations or not + :type all_pages: bool + :return: List of ldap domain configurations on array + :rtype: list[dict] + """ + LOG.info( + "Getting all ldap domain with filter: '%s' and all_pages: '%s'" + % (filter_dict, all_pages)) + + if all_pages: + raise Exception("Pagination is not supported for LDAP domain.") + if not filter_dict: + querystring = helpers.prepare_querystring( + constants.LDAP_DOMAIN_DETAILS_QUERY) + return self.config_client.request( + constants.GET, constants.GET_LDAP_DOMAIN_LIST_URL.format( + self.server_ip), querystring=querystring, all_pages=False) + + resp = self.config_client.request( + constants.GET, + constants.GET_LDAP_DOMAIN_LIST_URL.format(self.server_ip), + querystring=constants.LDAP_DOMAIN_DETAILS_QUERY, all_pages=False) + + filterable_keys = ['domain_name', 'id', 'protocol', 'ldap_server_type'] + ldap_domain_resp = helpers.filtered_details(filterable_keys, filter_dict, + resp, 'ldap_domain') + + if ldap_domain_resp: + filter_list = [] + ldap_domain_dict = self.get_ldap_domain_configuration_details(ldap_domain_resp[0]['id']) + filter_list.append(ldap_domain_dict) + return filter_list + return ldap_domain_resp + + def get_ldap_domain_configuration_details(self, ldap_domain_id): + """ Get details of a ldap domain instance. + + :param ldap_domain_id: Unique identifier of the ldap domain + :type ldap_domain_id: str + :return: ldap domain details + :rtype: dict + """ + LOG.info("Getting ldap domain details by ID: '%s'" % ldap_domain_id) + + return self.config_client.request( + constants.GET, + constants.GET_LDAP_DOMAIN_DETAILS_URL.format( + self.server_ip, ldap_domain_id), + querystring=constants.LDAP_DOMAIN_DETAILS_QUERY) + + def get_ldap_domain_configuration_details_by_name(self, ldap_domain_name): + """ Get details of a ldap domain instance. + + :param ldap_domain_name: LDAP domain name + :type ldap_domain_name: str + :return: ldap domain details + :rtype: dict + """ + LOG.info("Getting ldap domain details by name") + + resp = self.config_client.request( + constants.GET, + constants.GET_LDAP_DOMAIN_LIST_URL.format( + self.server_ip, ldap_domain_name), + querystring=helpers.prepare_querystring( + constants.LDAP_DOMAIN_DETAILS_QUERY, + name=constants.EQUALS + ldap_domain_name) + ) + + filterable_keys = ['domain_name', 'id', 'protocol', 'ldap_server_type'] + filter_dict = {'domain_name': 'eq.{0}'.format(ldap_domain_name)} + resp = helpers.filtered_details(filterable_keys, filter_dict, + resp, 'ldap_domain') + if resp: + return self.get_ldap_domain_configuration_details(resp[0]['id']) + + def create_ldap_domain_configuration(self, create_parameters): + """ Create LDAP domain configuration. + + :param create_parameters: Parameters for creating LDAP domain + :type create_parameters: dict + :return: Unique identifier of the new LDAP domain instance created + :rtype: dict + """ + LOG.info("creating LDAP domain") + + return self.config_client.request( + constants.POST, + constants.CREATE_LDAP_DOMAIN_URL.format( + self.server_ip), payload=create_parameters) + + def modify_ldap_domain_configuration(self, ldap_domain_id, modify_parameters): + """ Modify LDAP domain configuration. + + :param ldap_domain_id: Unique ID of the LDAP domain instance + :type ldap_domain_id: str + :param modify_parameters: Parameters for modifying LDAP domain + :type modify_parameters: dict + :return: None + :rtype: None + """ + LOG.info("Modifying LDAP domain configuration id: '%s'" % ldap_domain_id) + + return self.config_client.request( + constants.PATCH, + constants.MODIFY_LDAP_DOMAIN_URL.format( + self.server_ip, ldap_domain_id), payload=modify_parameters) + + def delete_ldap_domain_configuration(self, ldap_domain_id): + """ Delete LDAP domain configuration. + + :param ldap_domain_id: Unique ID of the LDAP domain instance + :type ldap_domain_id: str + :return: None + :rtype: None + """ + LOG.info("Deleting LDAP domain configuration id: '%s'" % ldap_domain_id) + + return self.config_client.request( + constants.DELETE, + constants.DELETE_LDAP_DOMAIN_URL.format( + self.server_ip, ldap_domain_id)) + + def verify_ldap_domain_configuration(self, ldap_domain_id): + """ Verify LDAP domain configuration. + + :param ldap_domain_id: Unique ID of the LDAP domain instance + :type ldap_domain_id: str + :return: None + :rtype: None + """ + LOG.info("Verifying LDAP domain configuration id: '%s'" % ldap_domain_id) + + return self.config_client.request( + constants.POST, + constants.VERIFY_LDAP_DOMAIN_URL.format( + self.server_ip, ldap_domain_id)) + + # LDAP Domain operations end + + # LDAP Account operations begin + + def get_ldap_account_list(self, filter_dict=None, all_pages=None): + """Get all LDAP accounts available on array. + + :param filter_dict: (optional) Filter details + :type filter_dict: dict + :param all_pages: (optional) Indicates whether to return all LDAP + accounts or not + :type all_pages: bool + :return: List of LDAP accounts on array + :rtype: list[dict] + """ + LOG.info( + "Getting all ldap accounts with filter: '%s' and all_pages: '%s'" + % (filter_dict, all_pages)) + + if all_pages: + raise Exception("Pagination is not supported for LDAP accounts.") + if not filter_dict: + querystring = helpers.prepare_querystring( + constants.LDAP_ACCOUNT_DETAILS_QUERY) + return self.config_client.request( + constants.GET, constants.GET_LDAP_ACCOUNT_LIST_URL.format( + self.server_ip), querystring=querystring, all_pages=False) + + resp = self.config_client.request( + constants.GET, + constants.GET_LDAP_ACCOUNT_LIST_URL.format(self.server_ip), + querystring=constants.LDAP_ACCOUNT_DETAILS_QUERY, all_pages=False) + + filterable_keys = ['name', 'id', 'role_id', 'type'] + ldap_account_resp = helpers.filtered_details(filterable_keys, filter_dict, + resp, 'ldap_accounts') + + # Return all the details for each LDAP account + if ldap_account_resp: + resp_list = [] + for resp in ldap_account_resp: + resp_dict = self.get_ldap_account_details(resp['id']) + resp_list.append(resp_dict) + return resp_list + return ldap_account_resp + + def get_ldap_account_details(self, ldap_account_id): + """ Get details of a LDAP account instance. + + :param ldap_account_id: Unique identifier of the LDAP Account + :type ldap_account_id: str + :return: LDAP account details + :rtype: dict + """ + LOG.info("Getting LDAP account details by ID: '%s'" % ldap_account_id) + + return self.config_client.request( + constants.GET, + constants.GET_LDAP_ACCOUNT_DETAILS_URL.format( + self.server_ip, ldap_account_id), + querystring=constants.LDAP_ACCOUNT_DETAILS_QUERY) + + def get_ldap_account_details_by_name(self, ldap_account_name): + """ Get details of an ldap account instance. + + :param ldap_account_name: LDAP account name + :type ldap_account_name: str + :return: ldap account details + :rtype: dict + """ + LOG.info("Getting LDAP Account details by name: '%s'" % ldap_account_name) + resp = self.get_ldap_account_list() + + for account in resp: + if account['name'] == ldap_account_name: + return self.get_ldap_account_details(account['id']) + + + def create_ldap_account(self, create_parameters): + """ Create LDAP account configuration. + + :param create_parameters: Parameters for creating LDAP account + :type create_parameters: dict + :return: Unique identifier of the new LDAP account instance created + :rtype: dict + """ + LOG.info("creating LDAP account") + + return self.config_client.request( + constants.POST, + constants.CREATE_LDAP_ACCOUNT_URL.format( + self.server_ip), payload=create_parameters) + + def modify_ldap_account_details(self, ldap_account_id, modify_parameters): + """ Modify LDAP account configuration. + + :param ldap_account_id: Unique ID of the LDAP account instance + :type ldap_account_id: str + :param modify_parameters: Parameters for modifying LDAP account + :type modify_parameters: dict + :return: None + :rtype: None + """ + LOG.info("Modifying LDAP account id: '%s'" % ldap_account_id) + + return self.config_client.request( + constants.PATCH, + constants.MODIFY_LDAP_ACCOUNT_URL.format( + self.server_ip, ldap_account_id), payload=modify_parameters) + + def delete_ldap_account(self, ldap_account_id): + """ Delete LDAP account. + + :param ldap_account_id: Unique ID of the LDAP account instance + :type ldap_account_id: str + :return: None + :rtype: None + """ + LOG.info("Deleting LDAP account configuration id: '%s'" % ldap_account_id) + + return self.config_client.request( + constants.DELETE, + constants.DELETE_LDAP_ACCOUNT_URL.format( + self.server_ip, ldap_account_id)) + + + # LDAP Account operations end @staticmethod def _prepare_local_user_payload(**kwargs): diff --git a/PyPowerStore/powerstore_conn.py b/PyPowerStore/powerstore_conn.py index 9912b56..31a9cbd 100644 --- a/PyPowerStore/powerstore_conn.py +++ b/PyPowerStore/powerstore_conn.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2019-2021, Dell EMC +# Copyright: (c) 2019, Dell Technologies """Module for establishing connection with PowerStore""" diff --git a/PyPowerStore/protection.py b/PyPowerStore/protection.py index cb41ed7..047da71 100644 --- a/PyPowerStore/protection.py +++ b/PyPowerStore/protection.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2019-2021, Dell EMC -# Copyright: (c) 2019-2021, Ivan Pchelintsev +# Copyright: (c) 2019, Dell Technologies +# Copyright: (c) 2019, Ivan Pchelintsev """Collection of protection related functions for PowerStore""" diff --git a/PyPowerStore/provisioning.py b/PyPowerStore/provisioning.py index a9f7ca1..97b2c14 100644 --- a/PyPowerStore/provisioning.py +++ b/PyPowerStore/provisioning.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2019-2021, Dell EMC +# Copyright: (c) 2019, Dell Technologies """Collection of provisioning related functions for PowerStore""" @@ -351,8 +351,11 @@ def get_volume_details(self, volume_id): """ LOG.info("Getting volume details by ID: '%s'" % volume_id) querystring = constants.SELECT_ALL_VOLUME - if helpers.is_foot_hill_or_higher(): + if helpers.is_foot_hill_prime_or_higher(): + querystring = constants.FHP_VOLUME_DETAILS_QUERY + elif helpers.is_foot_hill_or_higher(): querystring = constants.FHC_VOLUME_DETAILS_QUERY + resp = self.client.request(constants.GET, constants.GET_VOLUME_DETAILS_URL.format (self.server_ip, volume_id), payload=None, @@ -373,12 +376,17 @@ def get_volume_by_name(self, volume_name): :rtype: dict """ LOG.info("Getting volume details by name: '%s'" % volume_name) + querystring = constants.SELECT_ALL_VOLUME + if helpers.is_foot_hill_prime_or_higher(): + querystring = constants.FHP_VOLUME_DETAILS_QUERY + elif helpers.is_foot_hill_or_higher(): + querystring = constants.FHC_VOLUME_DETAILS_QUERY + resp = self.client.request( constants.GET, constants.GET_VOLUME_BY_NAME_URL.format(self.server_ip), payload=None, querystring=helpers.prepare_querystring( - constants.SELECT_ALL_VOLUME, - name=constants.EQUALS + volume_name + querystring, name=constants.EQUALS + volume_name ) ) diff --git a/PyPowerStore/tests/unit_tests/base_test.py b/PyPowerStore/tests/unit_tests/base_test.py index f246db8..b8d392d 100644 --- a/PyPowerStore/tests/unit_tests/base_test.py +++ b/PyPowerStore/tests/unit_tests/base_test.py @@ -14,6 +14,7 @@ from PyPowerStore.tests.unit_tests.data.ntp_data import NtpData from PyPowerStore.tests.unit_tests.data.remote_support_data import RemoteSupportData from PyPowerStore.tests.unit_tests.data.remote_support_contact_data import RemoteSupportContactData +from PyPowerStore.tests.unit_tests.data.ldap_account_data import LdapAccountData from unittest import mock class TestBase(TestCase): @@ -31,6 +32,7 @@ def setUp(self): self.ntp_data = NtpData() self.remote_support_data = RemoteSupportData() self.remote_support_contact_data = RemoteSupportContactData() + self.ldap_account_data = LdapAccountData() self.conf = PowerStoreConfig() self.mock_client = mock.patch('PyPowerStore.provisioning.Client', new=MockClient) diff --git a/PyPowerStore/tests/unit_tests/common_data.py b/PyPowerStore/tests/unit_tests/common_data.py deleted file mode 100644 index 859cae0..0000000 --- a/PyPowerStore/tests/unit_tests/common_data.py +++ /dev/null @@ -1,1162 +0,0 @@ -class CommonData(object): - size_used = 1623195648 - size_total = 5368709120 - uuid = "5f474e2d-1a45-5980-5175-9245647c527e" - - # Volume - vol_id1 = "007a5fad-7520-4f2a-a364-6c243d8d4ecf" - vol_name1 = "my_vol1" - size = 1048576 - - vol_id2 = "00c2c300-cf6e-4cf0-9bf4-037173496913" - vol_name2 = "my_vol2" - - volume_list = [{"id": vol_id1, "name": vol_name1}, - {"id": vol_id2, "name": vol_name2}] - - create_volume = {"id": vol_id1} - - hlu_details = [] - - volume1 = {'appliance_id': 'A1', 'creation_timestamp': '2020-08-10T13:' - '20:57.899845+00:00', - 'description': '', 'hlu_details': - hlu_details, 'host': [], 'host_group': [], 'id': vol_id1, - 'is_replication_destination': False, 'location_history': None, - 'migration_session_id': None, 'name': vol_name1, - 'performance_policy_id': 'default_medium', - 'protection_data': { - 'copy_signature': '1a482103-0476-4530-b209-7e0bf483ad0a', - 'created_by_rule_id': None, 'created_by_rule_name': None, - 'creator_type': 'System', 'creator_type_l10n': 'System', - 'expiration_timestamp': None, 'is_app_consistent': None, - 'family_id': '60b27a31-4121-42b7-97c6-fb24c4074864', - 'parent_id': '60b27a31-4121-42b7-97c6-fb24c4074864', - 'source_id': '60b27a31-4121-42b7-97c6-fb24c4074864', - 'source_timestamp': '2020-08-10T13:20:57.899845+00:00'}, - 'protection_policy_id': None, 'size': 1073741824, - 'type': 'Snapshot', 'state_l10n': 'Ready', - 'type_l10n': 'Snapshot', 'volume_groups': [], 'wwn': None, - 'state': 'Ready'} - - vol_snap_id = uuid - - create_vol_snap = {'id': vol_snap_id} - - vol_snap_detail = volume1 - - volume_snap_list = volume_list - - # Volume End - - # VolumeGroup - vg_id1 = "007a5fad-7520-4f2a-a364-6c243d8d4ecf" - vg_name1 = "my_vg1" - - vg_id2 = "007a5fad-7520-4f2a-a364-6c243d8d4ecf" - vg_name2 = "my_vg2" - - volumegroup_list = [{"id": vg_id1, "name": vg_name1}, - {"id": vg_id2, "name": vg_name2}] - - volume_group1 = {'type': 'Primary', 'protection_policy': None, - 'is_protectable': True, 'is_importing': False, - 'creation_timestamp': '2020-08-27T02:47:57.467+00:00', - 'protection_policy_id': None, - 'placement_rule': 'Same_Appliance', - 'protection_data': { - 'created_by_rule_name': None, - 'family_id': '530fe228-30ce-4e20-a529-8532b28f31e8', - 'source_id': None, 'source_timestamp': None, - 'creator_type_l10n': 'User', 'creator_type': 'User', - 'created_by_rule_id': None, 'copy_signature': None, - 'parent_id': None, 'is_app_consistent': False, - 'expiration_timestamp': None}, - 'volumes': [ - { - 'name': vol_name1, - 'id': vol_id1 - } - ], - 'name': vg_name1, - 'is_write_order_consistent': True, - 'migration_session_id': None, 'type_l10n': 'Primary', - 'is_replication_destination': False, - 'description': None, 'location_history': None, - 'id': vg_id1 - } - - invalid_vol_id = vol_id1[:len(vol_id1) - 3] + 'x' * 3 - volume_error = { - 404: {'messages': [{'arguments': ['{0}'.format(invalid_vol_id)], - 'code': '0xE0A07001000C', - 'message_l10n': 'The volume {0} is not ' - 'found.'.format(invalid_vol_id), - 'severity': 'Error'}]} - } - - # VolumeGroup End - - # Host - host_id1 = "ce15c82e-6e01-45ac-9886-49e3c55cca3c" - host_name1 = "my_host1" - - host_id2 = "ccceadef-4c04-4b1b-a242-718eb68da7f8" - host_name2 = "my_host2" - - host_list = [{"id": host_id1, "name": host_name1}, - {"id": host_id2, "name": host_name2}] - - lun = 1 - - initiator1 = "iqn.1998-01.com.vmware:lgloc1.52d1" - create_host = {"id": host_id1} - host1 = {'description': None, 'host_group_id': None, - 'os_type_l10n': 'ESXi', 'os_type': 'ESXi', - 'host_initiators': [ - {'port_type': 'iSCSI', - 'active_sessions': [], - 'chap_single_username': '', - 'chap_mutual_username': '', - 'port_name': initiator1} - ], - 'name': host_name1, - 'id': host_id1 - } - - invalid_initiator = { - "name": "iqn.1998-01.com.vmware:lgloc187-4cfa37z6", - "port_type": "iSCSI" - } - - add_invalid_initiator_error = { - 400: {'messages': [{ - 'code': '0xE0A01001000C', - 'message_l10n': 'Cannot add iqn since it already exists as part ' - 'of the host', - 'severity': 'Error' - }]}} - - remove_invalid_initiator_error = { - 400: {'messages': [{ - 'code': '0xE0A010010014', - 'message_l10n': 'Cannot remove the specified iqn since it does ' - 'not exist as part of the host.', - 'severity': 'Error' - }]}} - - # Host End - - # HostGroup - hg_id1 = "6066230c-cb5a-4cf2-90c6-92c5948af3d2" - hg_name1 = "my_hostgroup1" - - hg_id2 = "938434c6-8bd3-4552-b540-702eab2a91e1" - hg_name2 = "my_hostgroup2" - - hg_list = [{"id": hg_id1, "name": hg_name1}, - {"id": hg_id2, "name": hg_name2}] - - create_hg = {"id": hg_id1} - hg1 = { - 'description': None, 'name': hg_name1, - 'hosts': [ - {'name': host_name1, - 'id': host_id1} - ], - 'id': hg_id1 - } - - existing_hg_name = "Ansible_hg" - invalid_host_id = host_id1[:len(host_id1) - 3] + 'x' * 3 - - invalid_rename_error = { - 400: { - 'messages': [{'arguments': ['{0}'.format(existing_hg_name)], - 'code': '0xE0A030010010', - 'message_l10n': 'Host Group with name {0} already' - ' exists'.format(existing_hg_name), - 'severity': 'Error' - }]}} - - add_invalid_host_error = { - 400: { - 'messages': [{ - 'arguments': ['{0}'.format(invalid_host_id)], - 'code': '0xE0A030010001', - 'message_l10n': 'Invalid host IDs provided ' - '{0}'.format(invalid_host_id) - }]}} - - # HostGroup End - - # ProtectionPolicy - pol_id = "a78c08b0-d956-405f-aff8-d1d4c416a54d" - - pol_id1 = "f2803de5-e01f-4fd0-b3f3-aabf6d828a33" - pol_name1 = "my_pp1" - - pol_id2 = "fdc44636-e735-42bc-8d93-e5855c32d71f" - pol_name2 = "my_pp2" - - pol_list = [{"id": pol_id1, "name": pol_name1}, - {"id": pol_id2, "name": pol_name2}] - - invalid_pol_id = pol_id1[:len(pol_id1) - 3] + 'x' * 3 - - policy_error = { - 404: {'messages': [{'arguments': ['{0}'.format(invalid_pol_id)], - 'code': '0xE0A090010001', - 'message_l10n': 'Unable to find the policy with ID ' - '{0}'.format(invalid_pol_id), - 'severity': 'Error'}]}} - - pol_snap_rule_id = "f24c1295-f73f-48f3-8e82-3e45c5444fcc" - pol_snap_rule_name = "my_sn_rule1" - invalid_sr_id = pol_snap_rule_id[:len(pol_snap_rule_id) - 3] + 'x' * 3 - modify_description = "policy modified" - - protection_policy1 = {'type': 'Protection', 'description': '', - 'replication_rules': [], - 'name': pol_name1, - 'id': pol_id1, - 'snapshot_rules': [ - {'name': pol_snap_rule_name, - 'id': pol_snap_rule_id}] - } - - protection_policy1_modified = {'type': 'Protection', - 'description': modify_description, - 'replication_rules': [], - 'name': pol_name1, - 'id': pol_id1, - 'snapshot_rules': [ - { - 'name': pol_snap_rule_name, - 'id': pol_snap_rule_id}] - } - - add_invalid_sr_error = { - 404: {'messages': [{'arguments': ['{0}'.format(invalid_sr_id)], - 'code': '0xE0203001000B', - 'message_l10n': 'The specified snapshot ' - 'rule {0} is not found'.format( - invalid_sr_id), - 'severity': 'Error'}]} - } - - remove_invalid_sr_error = { - 404: {'messages': [{'arguments': ['{0}'.format(invalid_sr_id)], - 'code': '0xE02020010007', - 'message_l10n': 'Rule {0} does not exist in the ' - 'policy'.format(invalid_sr_id), - 'severity': 'Error'}]} - } - - # ProtectionPolicy End - - # SnapshotRule - snap_rule_id1 = "f24c1295-f73f-48f3-8e82-3e45c5444fcc" - snap_rule_name1 = "my_sn_rule1" - - snap_rule_id2 = "f9362134-7f2a-43f0-98c4-48ad4ab2214f" - snap_rule_name2 = "my_sn_rule2" - - snap_rule_list = [{"id": snap_rule_id1, "name": snap_rule_name1}, - {"id": snap_rule_id2, "name": snap_rule_name2}] - - desired_retention1 = 40 - desired_retention2 = 72 - interval = "One_Day" - invalid_interval = "Ten_Minutes" - - snap_rule1 = {'interval': interval, 'time_of_day': None, - 'policies': [], - 'desired_retention': desired_retention1, - 'id': snap_rule_id1, - 'name': snap_rule_name1, - 'days_of_week': ['Sunday', 'Monday', 'Tuesday', - 'Wednesday', 'Thursday', 'Friday', - 'Saturday']} - - snap_rule1_modified = {'interval': interval, 'time_of_day': None, - 'policies': [], - 'desired_retention': desired_retention2, - 'id': snap_rule_id1, 'name': snap_rule_name1, - 'days_of_week': ['Sunday', 'Monday', 'Tuesday', - 'Wednesday', 'Thursday', - 'Friday', 'Saturday']} - - interval_error = { - 400: {'messages': [{ - 'severity': 'Error', 'message_l10n': 'Invalid REST request.', - 'code': '0xE04040010005' - }]}} - - # SnapshotRule End - - # NASServer - nas_id1 = "5ef3ade5-b532-27a5-1f2d-3286ff9e3ccf" - nas_name1 = "my_nas1" - - nas_id2 = "fdc44636-e735-42bc-8d93-e5855c32d71f" - nas_name2 = "my_pp2" - - nas_list = [{"id": nas_id1, "name": nas_name1}, - {"id": nas_id2, "name": nas_name2}] - - nas_detail = {'backup_IPv4_interface_id': None, 'id': nas_id1, - 'backup_IPv6_interface_id': None, 'name': nas_name1, - 'current_node_id': 'WN-D0169-appliance-1-node-B', - 'current_preferred_IPv4_interface_id': uuid, - 'current_preferred_IPv6_interface_id': None, - 'current_unix_directory_service': 'Local_Files', - 'current_unix_directory_service_l10n': 'Local Files', - 'default_unix_user': 'admin1', 'description': '', - 'default_windows_user': 'admin1', 'file_nises': [], - 'file_interfaces': [{'id': uuid, 'ip_address': '1.1.1.1', - 'name': 'test_name'}], - 'file_ldaps': [{'id': uuid}], 'smb_servers': [{'id': uuid}], - 'file_systems': [{'id': uuid, 'name': 'test_name'}], - 'is_auto_user_mapping_enabled': True, - 'is_username_translation_enabled': False, - 'nfs_servers': [{'id': uuid}], 'preferred_node_id': 'A', - 'operational_status': 'Started', - 'operational_status_l10n': 'Started', - 'production_IPv4_interface_id': None, - 'production_IPv6_interface_id': None} - - nas_valid_param_list = [ - 'name', 'description', 'current_node_id', 'preferred_node_id', - 'current_unix_directory_service', 'default_unix_user', - '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'] - - nas_id_not_exist = "5f4a3017-0bad-899e-e1eb-c6f547282e66" - nas_error = { - 400: {'messages': [{'arguments': ['Object instance has properties ' - 'which are not allowed by the ' - 'schema.'], - 'code': '0xE04040030001', - 'message_l10n': 'Validation failed: Object ' - 'instance has properties which ' - 'are not allowed by the schema.', - 'severity': 'Error'}]}, - 404: {'messages': [{'code': '0xE080100D0001', - 'message_l10n': 'Operation failed because ' - 'NAS Server ID is invalid.', - 'severity': 'Error'}]} - } - - # NASServer End - - # NFSExport - nfs_id1 = "5f3510ba-8691-5793-a9c3-3ec8892935fb" - nfs_name1 = "my_nfs1" - - nfs_id2 = "5f351150-76c7-f0cf-fcc8-3ec8892935fb" - nfs_name2 = "my_nfs2" - - nfs_list = [{"id": nfs_id1, "name": nfs_name1}, - {"id": nfs_id2, "name": nfs_name2}] - - create_nfs = {'id': nfs_id1} - - invalid_nfs = nfs_id1[:len(nfs_id1) - 3] + 'x' * 3 - - nfs_detail = {'anonymous_GID': -2, 'anonymous_UID': -2, - 'default_access': 'Root', 'default_access_l10n': 'Root', - 'description': None, - 'file_system': {'filesystem_type': 'Primary', - 'id': uuid, - 'name': 'nfs_ans_filesystem_sub', - 'nas_server': {'id': uuid, - 'name': 'my_nas'}}, - 'id': nfs_id1, 'is_no_SUID': False, 'min_security': 'Sys', - 'min_security_l10n': 'Sys', 'name': nfs_name1, - 'nfs_owner_username': '0', 'no_access_hosts': [], - 'path': '/nfs_ans_filesystem_sub', 'read_only_hosts': [], - 'read_only_root_hosts': [], 'read_write_hosts': [], - 'read_write_root_hosts': []} - - nfs_error = { - 400: {'messages': [{'arguments': ['Object instance has properties ' - 'which are not allowed by the ' - 'schema.'], - 'code': '0xE04040030001', - 'message_l10n': 'Validation failed: Object ' - 'instance has properties which ' - 'are not allowed by the schema.', - 'severity': 'Error'}]}, - 404: {'messages': [{'code': '0xE080100F0001', - 'message_l10n': 'Operation failed because NFS ' - 'Export ID is invalid. Enter a ' - 'valid NFS Export ID and ' - 'try again.', - 'severity': 'Error'}]} - } - - nfs_valid_param = ( - 'description', 'default_access', 'min_security', 'no_access_hosts', - 'add_no_access_hosts', 'remove_no_access_hosts', 'read_only_hosts', - 'add_read_only_hosts', 'remove_read_only_hosts', 'anonymous_GID', - 'read_only_root_hosts', 'add_read_only_root_hosts', 'anonymous_UID', - 'remove_read_only_root_hosts', 'read_write_hosts', 'is_no_SUID', - 'add_read_write_hosts', 'remove_read_write_hosts', - 'read_write_root_hosts', 'add_read_write_root_hosts', - 'remove_read_write_root_hosts') - - # NFSExport End - - # SMBShare - smb_id1 = "5efc3ec5-ea0d-58d9-e21b-42079d64ae37" - smb_name1 = "my_smb1" - - smb_id2 = "5f293c02-4466-8e0b-14df-024f80ecffb0" - smb_name2 = "my_smb2" - - smb_list = [{"id": smb_id1, "name": smb_name1}, - {"id": smb_id2, "name": smb_name2}] - - create_smb = {'id': smb_id1} - - invalid_smb_id = smb_id1[:len(smb_id1) - 3] + 'x' * 3 - - smb_detail = {'description': None, 'id': smb_id1, 'name': smb_name1, - 'file_system': {'filesystem_type': 'Primary', - 'id': uuid, 'name': 'sample_test', - 'nas_server': {'id': uuid, 'name': 'test'}}, - 'is_ABE_enabled': False, 'is_branch_cache_enabled': False, - 'is_continuous_availability_enabled': True, 'umask': '022', - 'is_encryption_enabled': False, 'path': '/sample', - 'offline_availability': 'Manual'} - - smb_error = { - 404: {'messages': [{'code': '0xE08010140001', - 'message_l10n': 'Operation failed because SMB ' - 'Share ID is invalid. Enter a ' - 'valid SMB Share ID and ' - 'try again.', - 'severity': 'Error'}]} - } - - # SMBShare End - - # FileSystem - fs_id1 = "5efc3ec5-ea0d-58d9-e21b-42079d64ae37" - fs_name1 = "my_fs1" - - fs_id2 = "5f293c02-4466-8e0b-14df-024f80ecffb0" - fs_name2 = "my_fs2" - - fs_list = [{"id": fs_id1, "name": fs_name1}, - {"id": fs_id2, "name": fs_name2}] - - create_filesystem = {'id': fs_id1} - fs_detail = {'access_policy': 'Native', 'access_policy_l10n': 'Native', - 'access_type': None, 'access_type_l10n': None, - 'creation_timestamp': None, 'creator_type': None, - 'creator_type_l10n': None, 'default_hard_limit': 0, - 'default_soft_limit': 0, 'description': None, - 'expiration_timestamp': None, 'filesystem_type': 'Primary', - 'filesystem_type_l10n': 'Primary File system', - 'folder_rename_policy': 'All_Forbidden', - 'folder_rename_policy_l10n': 'All Renames Forbidden', - 'grace_period': 604800, 'id': fs_id1, - 'is_async_MTime_enabled': False, 'is_modified': None, - 'is_quota_enabled': False, 'is_smb_no_notify_enabled': False, - 'is_smb_notify_on_access_enabled': False, - 'is_smb_notify_on_write_enabled': False, - 'is_smb_op_locks_enabled': True, - 'is_smb_sync_writes_enabled': False, - 'last_refresh_timestamp': None, 'parent_id': None, - 'last_writable_timestamp': None, - 'locking_policy': 'Advisory', 'name': fs_name1, - 'locking_policy_l10n': 'Advisory', - 'nas_server': {'id': nas_id1, 'name': nas_name1}, - 'protection_policy': None, 'size_total': size_total, - 'size_used': size_used, 'smb_notify_on_change_dir_depth': 512} - - fs_snap_id = "5efc3ec5-ea0d-58d9-e21b-42079d64ae37" - fs_snap_name = "my_fs_snap" - create_filesystem_snap = {'id': fs_snap_id} - fs_snap_detail = fs_detail - fs_snap_list = [{'id': fs_snap_id, 'name': fs_snap_name}] - - # fs which does not exists - invalid_fs_id = fs_id1[:len(fs_id1) - 3] + 'x' * 3 - # fs which has snapshot created on it - fs_id_with_snap = "5f488eb1-c75e-a704-e53a-c6f547282e76" - fs_error = { - 404: {'messages': [{'code': '0xE08010080001', - 'message_l10n': 'Operation failed because File ' - 'System ID is invalid. Enter a valid File System ' - 'ID and try again.', - 'severity': 'Error'}]}, - 422: {'messages': [{'arguments': ['[File system delete rejected due ' - 'to existing snap(s).]'], - 'code': '0xE08010080003', - 'message_l10n': 'Deletion of File System failed ' - 'as, [File system delete rejected ' - 'due to existing snap (s).]', - 'severity': 'Error'}]}} - - # FileSystem End - - # TreeQuota - tq_id1 = "00000004-05eb-0000-0d00-000000000000" - tq_path1 = "/my_tq1" - - tq_id2 = "00000004-05eb-0000-0e00-000000000000" - tq_path2 = "/my_tq2" - - tq_list = [{"id": tq_id1, "name": tq_path1}, - {"id": tq_id2, "name": tq_path2}] - - create_tree_quota = {'id': tq_id1} - - invalid_tq_id = tq_id1[:len(tq_id1) - 3] + 'x' * 3 - - tq_valid_param = ('file_system_id', 'path', 'description', 'hard_limit', - 'soft_limit', 'is_user_quotas_enforced') - - tq_error = { - 400: {'messages': [{'arguments': ['Object instance has properties ' - 'which are not allowed by the ' - 'schema'], - 'code': '0xE04040030001', - 'message_l10n': 'Validation failed: Object ' - 'instance has properties which ' - 'are not allowed by the schema', - 'severity': 'Error'}]}, - 404: {'messages': [{'code': '0xE08010090001', - 'message_l10n': 'Operation failed because File ' - 'Tree Quota ID is invalid. Enter ' - 'a valid File Tree Quota id and ' - 'try again.', - 'severity': 'Error'}]} - } - - tq_detail = {'description': 'sample', 'hard_limit': 0, 'id': tq_id1, - 'file_system': {'filesystem_type': 'Primary', - 'id': uuid, - 'name': 'f1s', - 'nas_server': {'id': uuid, 'name': 'nas1'}}, - 'is_user_quotas_enforced': False, 'path': '/sample', - 'remaining_grace_period': -1, 'size_used': 0, - 'soft_limit': 0, 'state': 'Ok'} - - # TreeQuota End - - # UserQuota - uq_id1 = "00000003-0066-0000-0100-000039300000" - uq_id2 = "00000003-0066-0000-0100-0000d2040000" - - uq_list = [{'id': uq_id1}, {'id': uq_id2}] - - create_user_quota = {'id': uq_id1} - - uq_valid_param = ('file_system_id', 'tree_quota_id', 'uid', 'unix_name', - 'windows_name', 'windows_sid', 'hard_limit', - 'soft_limit') - - uq_error = { - 400: {'messages': [{'arguments': ['Object instance has properties ' - 'which are not allowed by the ' - 'schema'], - 'code': '0xE04040030001', - 'message_l10n': 'Validation failed: Object ' - 'instance has properties which ' - 'are not allowed by the schema', - 'severity': 'Error'}]} - } - - uq_detail = {'file_system': {'filesystem_type': 'Primary', 'id': uuid, - 'name': 'sample', - 'nas_server': {'id': uuid, 'name': 'nas1'}}, - 'hard_limit': 0, 'id': uq_id1, 'remaining_grace_period': -1, - 'size_used': 2097152, 'soft_limit': 4194304, 'state': 'Ok', - 'state_l10n': 'Ok', 'tree_quota': None, 'tree_quota_id': None, - 'uid': 1, 'unix_name': None, 'windows_name': None, - 'windows_sid': None} - - # Replication session - rep_session_id_1 = "2754bad0-cfcd-4796-a06b-78368bad1cd7" - rep_session_id_2 = "3186cad5-brej-8016-s53c-69457cad3ej9" - - rep_session_list = [{'id': rep_session_id_1}, {'id': rep_session_id_2}] - - rep_session_valid_param = ('volume_group', 'volume', 'session_id', - 'session_state') - rep_session_error = { - - 400: {"messages": [{"code": "0xE04040030001", "severity": "Error", - "message_l10n": "Validation failed: Object instance" - " has properties which are not " - "allowed by the schema: [dupe_is" - "_planned].", - "arguments": ["Object instance has properties w" - "hich are not allowed by the schema:" - " [dupe_is_planned]"]}]}, - 404: {"messages": [{ - "code": "0xE04040020009", - "severity": "Error", - "message_l10n": "Instance with id " - "2754bad0-cfcd-4796-a06b-78368bad1cd " - "was not found.", - "arguments": [ - "2754bad0-cfcd-4796-a06b-78368bad1cd" - ]}]} - } - rep_session_id_not_exist = "5f4a3017-0bad-899e-e1eb-c6f547282e66" - - rep_session_details_1 = { - "id": "2754bad0-cfcd-4796-a06b-78368bad1cd7", - "state": "OK", - "role": "Source", - "resource_type": "volume_group", - "last_sync_timestamp": "2021-06-11T02:16:22.909+00:00", - "local_resource_id": "aa352e0d-8048-423f-b50a-8b61f482365e", - "remote_resource_id": "21f7ae54-0639-4b09-af4f-183d26b31237", - "remote_system_id": "f07be373-dafd-4a46-8b21-f7cf790c287f", - "progress_percentage": None, - "estimated_completion_timestamp": None, - "replication_rule_id": "55d14477-de22-4d39-b24d-07cf08ba329f", - "last_sync_duration": 218, - "next_sync_timestamp": None, - "storage_element_pairs": None, - "failover_test_in_progress": None, - "state_l10n": "OK", - "role_l10n": "Source", - "resource_type_l10n": "Volume Group", - "replication_rule": { - "name": "ansible_rep_rule", - "id": "55d14477-de22-4d39-b24d-07cf08ba329f" - }, - "migration_session": None, - "remote_system": { - "name": "WN-D8978", - "id": "f07be373-dafd-4a46-8b21-f7cf790c287f" - } - } - - # replication session end - - # replication rule start - rep_rule_id_1 = "55d14477-de22-4d39-b24d-07cf08ba329f" - rep_rule_name_1 = "ansible_rep_rule_1" - - rep_rule_id_2 = "20242441-4d8b-424f-b6b3-058ad02f5f9d" - rep_rule_name_2 = "ansible_rep_rule_2" - - rep_rule_list = [{"id": rep_rule_id_1, "name": rep_rule_name_1}, - {"id": rep_rule_id_2, "name": rep_rule_name_2}] - - create_rep_rule = {'id': rep_rule_id_1} - - alert_threshold = 30 - invalid_alert_threshold = "36" - new_alert_threshold = 40 - remote_system_id = "f07be373-dafd-4a46-8b21-f7cf790c287f" - rpo = "One_Hour" - - rep_rule_error = { - 400: {"messages": [{"code": "0xE04040030001", - "severity": "Error", - "message_l10n": - "Validation failed: [Path '/alert_threshold'] " - "Instance type (string) does not match any " - "allowed primitive type (allowed: [integer])." - , "arguments": - ["[Path '/alert_threshold'] Instance type " - "(string) does not match any allowed " - "primitive type (allowed: [integer])"]}]} - } - - rep_rule_details_1 = { - "id": "55d14477-de22-4d39-b24d-07cf08ba329f", - "name": "ansible_rep_rule", - "rpo": "One_Hour", - "remote_system_id": "f07be373-dafd-4a46-8b21-f7cf790c287f", - "is_replica": False, - "alert_threshold": 30, - "rpo_l10n": "One Hour" - } - # replication rule end - - # network start - - network_id2 = "NW1" - network_name2 = "Default Management Network" - - network_id1 = "NW2" - network_name1 = "Default Storage Network" - network_list = [ - {"id": network_id1, "name": network_name1}, - {"id": network_id2, "name": network_name2} - ] - - add_ip_ports = ["IP9"] - - network_details_1 = { - "id": "NW2", - "type": "Storage", - "name": "Default Storage Network", - "ip_version": "IPv4", - "purposes": [ - "ISCSI" - ], - "vlan_id": 0, - "prefix_length": 24, - "gateway": "10.****.****.1", - "mtu": 1400, - "type_l10n": "Storage", - "ip_version_l10n": "IPv4", - "purposes_l10n": [ - "iSCSI" - ] - } - - network_valid_param_list = [ - 'name', 'vlan_id', 'gateway', 'prefix_length', 'mtu', - 'new_cluster_mgmt_address', 'storage_discovery_address', 'addresses', - 'ports', 'vasa_provider_credentials', 'esxi_credentials', - 'add_port_ids', 'remove_port_ids'] - - network_does_not_exist = 'NW20' - network_error = { - 400: {'messages': [{'arguments': ['Object instance has properties ' - 'which are not allowed by the ' - 'schema.'], - 'code': '0xE04040030001', - 'message_l10n': 'Validation failed: Object ' - 'instance has properties which ' - 'are not allowed by the schema.', - 'severity': 'Error'}]}, - 404: {'messages': [{'code': '0xE04040020009', - 'message_l10n': 'Instance with id NW20 was not ' - 'found.', - 'severity': 'Error'}]} - } - # network end - - # installed software start - - software_list = [{'release_version': '2.0.0.0'}, - {'release_version': '2.0.0.0'}] - - # installed software end - - # job start - - job_id1 = 'dfb47ef3-7ade-4b75-951a-34163c4e55d6' - job_does_not_exist = 'dfb47ef3-7ade-4b75-951a-34163c4e55d9' - job_details = { - "id": "dfb47ef3-7ade-4b75-951a-34163c4e55d6", - "resource_action": "modify", - "resource_type": "network", - "resource_id": "NW1", - "resource_name": None, - "description_l10n": "Modify network parameters.", - "state": "COMPLETED", - "start_time": "2021-08-30T06:06:25.846+00:00", - "phase": "Completed", - "end_time": "2021-08-30T06:06:46.828+00:00", - "estimated_completion_time": None, - "progress_percentage": 100, - "parent_id": None, - "root_id": "dfb47ef3-7ade-4b75-951a-34163c4e55d6", - "user": "admin", - "response_body": None, - "response_status": None, - "step_order": 2093821, - "resource_action_l10n": "modify", - "resource_type_l10n": "network", - "state_l10n": "Completed", - "phase_l10n": "Completed", - "response_status_l10n": None - } - - job_error = { - 404: { - 'messages': - [{'code': '0xE04040020009', - 'message_l10n': 'Instance with id ' - 'dfb47ef3-7ade-4b75-951a-34163c4e55d9 was ' - 'not found.', - 'severity': 'Error'}]} - } - # job end - - # vcenter start - - vcenter_id1 = '42d08c86-f958-4fbb-82f0-3ce1a5d99d1e' - vcenter_list = [{"id": '42d08c86-f958-4fbb-82f0-3ce1a5d99d1e'}] - vasa_provider_credentials = { - "username": "vmadmin", - "password": "Password123!" - } - vcenter_details = { - "id": "42d08c86-f958-4fbb-82f0-3ce1a5d99d1e", - "instance_uuid": "3b33039f-908f-4d1a-a0ca-1d2fd050a09b", - "address": "vpi2197.pie.lab.emc.com", - "username": "administrator@vsphere.local", - "vendor_provider_status": "Online", - "vendor_provider_status_l10n": "Online" - } - - # vcenter end - - # IP pool address start - - ip_pool_list = [ - {'id': 'IP16', 'name': 'iSCI (10.***.***.***)', 'network_id': 'NW6', - 'ip_port_id': 'IP_PORT16', 'appliance_id': 'A1', 'node_id': 'N2', - 'address': '10.***.***.***', - 'purposes': ['Storage_Iscsi_Target', 'External_Replication_Iscsi'], - 'purposes_l10n': ['Storage Iscsi Target', - 'External Replication iSCSI Port']}, - {'id': 'IP17', 'name': 'iSCI (10.***.***.***)', 'network_id': 'NW6', - 'ip_port_id': 'IP_PORT6', 'appliance_id': 'A1', 'node_id': 'N1', - 'address': '10.***.***.***', - 'purposes': ['Storage_Iscsi_Target', 'External_Replication_Iscsi'], - 'purposes_l10n': ['Storage Iscsi Target', - 'External Replication iSCSI Port']}, - {'id': 'IP22', 'name': 'iSCI (10.***.***.***)', 'network_id': 'NW6', - 'ip_port_id': 'IP_PORT8', 'appliance_id': 'A1', 'node_id': 'N2', - 'address': '10.***.***.***', 'purposes': ['Storage_Iscsi_Target'], - 'purposes_l10n': ['Storage Iscsi Target']}, - {'id': 'IP23', 'name': 'iSCI (10.***.***.***)', 'network_id': 'NW6', - 'ip_port_id': 'IP_PORT15', 'appliance_id': 'A1', 'node_id': 'N1', - 'address': '10.***.***.***', 'purposes': ['Storage_Iscsi_Target'], - 'purposes_l10n': ['Storage Iscsi Target']} - ] - - # IP pool address end - - # IP port start - - ip_port_id = "IP_PORT1" - ip_port_details = { - "id": "IP_PORT1", - "partner_id": "IP_PORT14", - "target_iqn": "iqn.2015-10.com.dell:dellemc-powerstore-fnm00194601320-a-2fa9868f", - "available_usages": [ - "ISCSI" - ], - "current_usages": [], - "bond_id": None, - "eth_port_id": "c16f9febf1704297a0a3c721e71864d0", - "veth_port_id": None, - "available_usages_l10n": [ - "iSCSI" - ], - "current_usages_l10n": None - } - - # IP port end - - # Local user start - - local_user_id1 = "7" - local_user_name1 = "ansibleuser7" - - local_user_id2 = "8" - local_user_name2 = "ansibleuser8" - - local_user_does_not_exist = "20" - local_user_list = [ - {"id": local_user_id1, "name": local_user_name1}, - {"id": local_user_id2, "name": local_user_name2} - ] - - local_user_details = { - "id": "7", - "name": "ansibleuser7", - "is_built_in": False, - "is_locked": True, - "is_default_password": False, - "local_domain_id": "1", - "role_id": "3", - "user_preference": None - } - - local_user_create_params = { - "name": "ansibleuser7", - "password": "Password123!", - "role_id": "3" - } - - local_user_create_response = { - "id": local_user_id1 - } - - local_user_valid_param_list = [ - 'role_id', 'is_locked', 'current_password', 'password' - ] - - local_user_error = { - 404: { - "messages": [ - { - "code": "0xE09040040001", - "severity": "Error", - "message_l10n": "Error while getting local users!" - } - ] - }, - - 400: { - "messages": [{"code": "0xE04040030001", "severity": "Error", - "message_l10n": "Validation failed: Object instance" - " has properties which are not " - "allowed by the schema: " - "[\"invalid_key\"].", - "arguments": [ - "Object instance has properties which are not " - "allowed by the schema: [\"invalid_key\"]"]}] - } - } - - # Local user end - - # role start - - role_id2 = "1" - role_name2 = "Administrator" - - role_id1 = "2" - role_name1 = "Storage Administrator" - role_list = [ - {"id": role_id1, "name": role_name1}, - {"id": role_id2, "name": role_name2} - ] - - role_details_1 = { - "id": "2", - "name": "Storage Administrator", - "is_built_in": True, - "description": "Can view status and performance information and can" - " modify most systemsettings, but cannot configure new" - " storage hosts or manage local user" - } - - role_does_not_exist = '20' - role_error = { - 404: { - "messages": [ - { - "code": "0xE09040050001", - "severity": "Error", - "message_l10n": "Role object does not exist!" - } - ] - } - } - # role end - - # appliance start - appliance_id1 = "A1" - appliance_name1 = "Appliance-WND8977" - appliance_list = [ - {"id": appliance_id1, "name": appliance_name1} - ] - appliance_details_1 = { - "id": "A1", - "name": "Appliance-WND8977", - "service_tag": "FX60643", - "express_service_code": "34657204467", - "model": "PowerStore 1000T", - "nodes": [ - { - "id": "N1" - }, - { - "id": "N2" - } - ], - "veth_ports": [], - "maintenance_windows": [ - { - "id": "1" - } - ], - "fc_ports": [ - { - "id": "303c29acbe394e26b297e6da808cd076" - } - ], - "sas_ports": [ - { - "id": "69227e02e17046c4a35d930010a12a71" - } - ], - "eth_ports": [ - { - "id": "7dd7a6f96af6430aaffe58ecd187909a" - } - ], - "software_installed": [ - { - "id": "8027d12c-db31-4c0f-9dcb-b9ee105bc753" - } - ], - "virtual_volumes": [ - { - "id": "2f22931c-5fdb-49f3-a733-85dacd389191" - } - ], - "hardware": [ - { - "id": "d594e3856aa145cba6af2f2c80856f7f" - } - ], - "volumes": [ - { - "id": "3a1666b1-8d72-42d2-9d58-fe2f4bf8e288" - } - - ], - "ip_pool_addresses": [ - { - "id": "IP16" - } - ] - } - - appliance_does_not_exist = 'A2' - appliance_error = { - 404: { - "messages": [ - { - "code": "0xE04040020009", - "severity": "Error", - "message_l10n": "Instance with id A2 was not found.", - "arguments": [ - "A2" - ] - } - ] - } - } - # appliance end - # cluster start - cluster_name_1 = "WN-D8977" - cluster_id_1 = "0" - cluster_list = [ - {"id": cluster_id_1, "name": cluster_name_1} - ] - cluster_details_1 = { - "id": "0", - "global_id": "PS00d01e1bb312", - "name": "WN-D8977", - "physical_mtu": 1500, - "master_appliance_id": "A1", - "state": "Configured", - "appliance_count": 1, - "management_address": "10***.***.***", - "is_encryption_enabled": True, - "storage_discovery_address": "10.***.***.***", - "compatibility_level": 10, - "state_l10n": "Configured" - } - invalid_cluster_id = '10' - cluster_error = { - 404: { - "messages": [ - { - "code": "0xE0C01003000E", - "severity": "Error", - "message_l10n": "Invalid Cluster ID provided," - " Cluster ID: 10", - "arguments": [ - "10" - ] - } - ] - } - } - - # cluster end - - # service config start - service_config_id_1 = "A1" - service_config_appliance_id = 'A1' - service_config_list = [ - {"id": service_config_id_1} - ] - service_config_details_1 = { - "id": "A1", - "appliance_id": "A1", - "is_ssh_enabled": True - } - invalid_service_config_id = '10' - service_config_error = { - 404: { - "messages": [ - { - "code": "0xE09030010003", - "severity": "Error", - "message_l10n": "Appliance id does not exist" - } - ] - } - } - # service config end - - # service user start - service_user_id_1 = "1" - service_user_name_1 = 'service' - service_user_list = [ - {"id": service_user_id_1, 'name': service_user_name_1} - ] - service_user_details_1 = { - "id": "1", - "name": "service", - "is_built_in": True, - "is_default_password": False - } - invalid_service_user_id = '10' - service_user_error = { - 404: { - "messages": [ - { - "code": "0xE09040070001", - "severity": "Error", - "message_l10n": "Service User object with given id " - "does not exist!" - } - ] - } - } - # service user end - - # chap config start - chap_config_id_1 = "0" - chap_config_list = [ - {"id": chap_config_id_1} - ] - chap_config_details_1 = { - "id": "0", - "mode": "Disabled", - "mode_l10n": "Disabled" - } - invalid_chap_config_id = '3' - chap_config_error = { - 404: { - "messages": [ - { - "code": "0xE0C01003000D", - "severity": "Error", - "message_l10n": "CHAP Configuration 3 not found", - "arguments": [ - "3" - ] - } - ] - } - } - - # chap config end diff --git a/PyPowerStore/tests/unit_tests/data/common_data.py b/PyPowerStore/tests/unit_tests/data/common_data.py index b0c40ea..6e8f057 100644 --- a/PyPowerStore/tests/unit_tests/data/common_data.py +++ b/PyPowerStore/tests/unit_tests/data/common_data.py @@ -744,8 +744,8 @@ class CommonData(object): # installed software start - software_list = [{'release_version': '2.0.0.0'}, - {'release_version': '2.0.0.0'}] + software_list = [{'release_version': '2.1.0.0'}, + {'release_version': '2.1.0.0'}] # installed software end diff --git a/PyPowerStore/tests/unit_tests/data/ldap_account_data.py b/PyPowerStore/tests/unit_tests/data/ldap_account_data.py new file mode 100644 index 0000000..a6d7712 --- /dev/null +++ b/PyPowerStore/tests/unit_tests/data/ldap_account_data.py @@ -0,0 +1,37 @@ +class LdapAccountData(): + ldap_account_list = [ + "37b76535-612b-456a-a694-1389f17632c7", "37b76535-612b-456a-a694-1389f17632c" + ] + + ldap_account_list = [{ + "id": "2", + "role_id": "1", + "domain_id": "2", + "name": "ldap_test_user_1", + "type": "User", + "type_l10n": "User", + "dn": "cn=ldap_test_user_1,dc=ansildap,dc=com" + }] + + ldap_account_details1 = { + "id": "2", + "role_id": "1", + "domain_id": "2", + "name": "ldap_test_user_1", + "type": "User", + "type_l10n": "User", + "dn": "cn=ldap_test_user_1,dc=ansildap,dc=com" + } + + create_ldap_account_dict = { + "domain_id": "2", + "name": "ldap_test_user_1", + "type": "User", + "role_id": "1" + } + + modify_ldap_account_dict = { + "role_id": "2" + } + + create_ldap_account_response = {'id': '2'} diff --git a/PyPowerStore/tests/unit_tests/data/ldap_data.py b/PyPowerStore/tests/unit_tests/data/ldap_data.py index b3be55c..611e1f0 100644 --- a/PyPowerStore/tests/unit_tests/data/ldap_data.py +++ b/PyPowerStore/tests/unit_tests/data/ldap_data.py @@ -2,3 +2,67 @@ class LdapData(): ldap_list = [ "37b76535-612b-456a-a694-1389f17632c7", "37b76535-612b-456a-a694-1389f17632c" ] + + ldap_domain_list = [{ + 'protocol_l10n': 'LDAP', + 'ldap_timeout': 30000, + 'is_global_catalog': False, + 'ldap_servers': ['xx.xxx.x.xx'], + 'domain_name': "ldap.com", + 'ldap_server_type': 'AD', + 'user_object_class': 'user', + 'ldap_server_type_l10n': 'AD', + 'protocol': 'LDAP', + 'user_search_path': 'cn=Users', + 'group_object_class': 'group', + 'user_id_attribute': 'sAMAccountName', + 'port': 389, + 'group_search_level': 0, + 'group_search_path': 'cn=Users', + 'id': '3', + 'group_member_attribute': 'member', + 'bind_user': 'cn=admin,dc=ldap,dc=com', + 'group_name_attribute': 'cn' + }] + + ldap_domain_details1 = { + 'protocol_l10n': 'LDAP', + 'ldap_timeout': 30000, + 'is_global_catalog': False, + 'ldap_servers': ['xx.xxx.x.xx'], + 'domain_name': "ldap.com", + 'ldap_server_type': 'AD', + 'user_object_class': 'user', + 'ldap_server_type_l10n': 'AD', + 'protocol': 'LDAP', + 'user_search_path': 'cn=Users', + 'group_object_class': 'group', + 'user_id_attribute': 'sAMAccountName', + 'port': 389, + 'group_search_level': 0, + 'group_search_path': 'cn=Users', + 'id': '3', + 'group_member_attribute': 'member', + 'bind_user': 'cn=admin,dc=ldap,dc=com', + 'group_name_attribute': 'cn' + } + + create_ldap_domain_dict = { + "domain_name": "<>", + "ldap_servers": [ + "<>" + ], + "protocol": "LDAP", + "ldap_server_type": "AD", + "bind_user": "<>", + "bind_password": "<>", + "is_global_catalog": False, + "user_search_path": "cn=Users", + "group_search_path": "cn=Users" + } + + modify_ldap_domain_dict = { + "ldap_server_type": "OpenLDAP" + } + + create_ldap_domain_response = {'id': '3'} diff --git a/PyPowerStore/tests/unit_tests/entity/ldap_account.py b/PyPowerStore/tests/unit_tests/entity/ldap_account.py new file mode 100644 index 0000000..3be62f4 --- /dev/null +++ b/PyPowerStore/tests/unit_tests/entity/ldap_account.py @@ -0,0 +1,44 @@ +from PyPowerStore.tests.unit_tests.entity.base_abstract import Entity +from PyPowerStore.tests.unit_tests.data.ldap_account_data import LdapAccountData + + +class LDAPAccountResponse(Entity): + + def __init__(self, method, url, **kwargs): + self.method = method + self.url = url + self.kwargs = kwargs + self.ldap_account_data = LdapAccountData() + self.status_code = 200 + + def get_api_name(self): + if self.method == 'GET': + if self.url.endswith('/ldap_account'): + return self.get_ldap_account_list + else: + return self.get_ldap_account_details + elif self.method == 'POST': + return self.create_ldap_account + elif self.method == "PATCH": + return self.modify_ldap_account_details + elif self.method == "DELETE": + return self.delete_ldap_account + + def execute_api(self, api_name): + status_code, response = api_name() + return status_code, response + + def get_ldap_account_list(self): + return self.status_code, self.ldap_account_data.ldap_account_list + + def get_ldap_account_details(self): + return self.status_code, self.ldap_account_data.ldap_account_details1 + + def create_ldap_account(self): + return self.status_code, self.ldap_account_data.create_ldap_account_response + + def modify_ldap_account_details(self): + return 204, None + + def delete_ldap_account(self): + return 204, None diff --git a/PyPowerStore/tests/unit_tests/entity/ldap_domain.py b/PyPowerStore/tests/unit_tests/entity/ldap_domain.py new file mode 100644 index 0000000..4137748 --- /dev/null +++ b/PyPowerStore/tests/unit_tests/entity/ldap_domain.py @@ -0,0 +1,50 @@ +from PyPowerStore.tests.unit_tests.entity.base_abstract import Entity +from PyPowerStore.tests.unit_tests.data.ldap_data import LdapData + + +class LDAPDomainResponse(Entity): + + def __init__(self, method, url, **kwargs): + self.method = method + self.url = url + self.kwargs = kwargs + self.ldap_domain_data = LdapData() + self.status_code = 200 + + def get_api_name(self): + if self.method == 'GET': + if self.url.endswith('/ldap_domain'): + return self.get_ldap_domain_configuration_list + else: + return self.get_ldap_domain_configuration_details + elif self.method == 'POST': + if self.url.endswith('/verify'): + return self.verify_ldap_domain_configuration + else: + return self.create_ldap_domain_configuration + elif self.method == "PATCH": + return self.modify_ldap_domain_configuration + elif self.method == "DELETE": + return self.delete_ldap_domain_configuration + + def execute_api(self, api_name): + status_code, response = api_name() + return status_code, response + + def get_ldap_domain_configuration_list(self): + return self.status_code, self.ldap_domain_data.ldap_domain_list + + def get_ldap_domain_configuration_details(self): + return self.status_code, self.ldap_domain_data.ldap_domain_details1 + + def create_ldap_domain_configuration(self): + return self.status_code, self.ldap_domain_data.create_ldap_domain_response + + def modify_ldap_domain_configuration(self): + return 204, None + + def verify_ldap_domain_configuration(self): + return 204, None + + def delete_ldap_domain_configuration(self): + return 204, None diff --git a/PyPowerStore/tests/unit_tests/entity/volume.py b/PyPowerStore/tests/unit_tests/entity/volume.py index f31f82b..119df2f 100644 --- a/PyPowerStore/tests/unit_tests/entity/volume.py +++ b/PyPowerStore/tests/unit_tests/entity/volume.py @@ -28,7 +28,7 @@ def get_api_name(self): # its a GET request if self.url.endswith('/volume'): if self.kwargs.get('params', {}).get('select') == \ - constants.SELECT_ALL_VOLUME.get('select'): + constants.FHC_VOLUME_DETAILS_QUERY.get('select'): return self.get_volume_by_name else: return self.get_volume_list diff --git a/PyPowerStore/tests/unit_tests/myrequests.py b/PyPowerStore/tests/unit_tests/myrequests.py index f8b43fa..48a2e05 100644 --- a/PyPowerStore/tests/unit_tests/myrequests.py +++ b/PyPowerStore/tests/unit_tests/myrequests.py @@ -37,6 +37,8 @@ from PyPowerStore.tests.unit_tests.entity.ntp import NtpResponse from PyPowerStore.tests.unit_tests.entity.remote_support import RemoteSupportResponse from PyPowerStore.tests.unit_tests.entity.remote_support_contact import RemoteSupportContactResponse +from PyPowerStore.tests.unit_tests.entity.ldap_domain import LDAPDomainResponse +from PyPowerStore.tests.unit_tests.entity.ldap_account import LDAPAccountResponse import json # map the entity class name with the url resource name @@ -79,7 +81,9 @@ 'dns': DnsResponse, 'ntp': NtpResponse, 'remote_support': RemoteSupportResponse, - 'remote_support_contact': RemoteSupportContactResponse + 'remote_support_contact': RemoteSupportContactResponse, + 'ldap_domain': LDAPDomainResponse, + 'ldap_account': LDAPAccountResponse } diff --git a/PyPowerStore/tests/unit_tests/test_ldap_account.py b/PyPowerStore/tests/unit_tests/test_ldap_account.py new file mode 100644 index 0000000..02729ce --- /dev/null +++ b/PyPowerStore/tests/unit_tests/test_ldap_account.py @@ -0,0 +1,34 @@ +from PyPowerStore.utils import constants +from PyPowerStore.tests.unit_tests.base_test import TestBase +from PyPowerStore.utils.exception import PowerStoreException +from unittest import mock + + +class TestLDAPAccount(TestBase): + def test_get_ldap_accounts(self): + ldap_account_list = self.configuration.get_ldap_account_list() + self.assertListEqual(ldap_account_list, self.ldap_account_data.ldap_account_list) + + def test_get_ldap_account_details(self): + resp = self.configuration.get_ldap_account_details( + self.ldap_account_data.ldap_account_list[0]['id']) + self.assertEqual(resp, self.ldap_account_data.ldap_account_details1) + + def test_get_ldap_account_details_by_name(self): + resp = self.configuration.get_ldap_account_details_by_name( + self.ldap_account_data.ldap_account_details1['name']) + self.assertEqual(resp, self.ldap_account_data.ldap_account_details1) + + def test_create_ldap_account(self): + resp = self.configuration.create_ldap_account(self.ldap_account_data.create_ldap_account_dict) + self.assertEqual(resp, self.ldap_account_data.create_ldap_account_response) + + def test_modify_ldap_account_details(self): + resp = self.configuration.modify_ldap_account_details( + self.ldap_account_data.ldap_account_list[0]['id'], self.ldap_account_data.modify_ldap_account_dict) + self.assertIsNone(resp) + + def test_delete_ldap_account(self): + resp = self.configuration.delete_ldap_account(self.ldap_account_data.ldap_account_list[0]['id']) + self.assertIsNone(resp) + diff --git a/PyPowerStore/tests/unit_tests/test_ldap_domain.py b/PyPowerStore/tests/unit_tests/test_ldap_domain.py new file mode 100644 index 0000000..55442c3 --- /dev/null +++ b/PyPowerStore/tests/unit_tests/test_ldap_domain.py @@ -0,0 +1,38 @@ +from PyPowerStore.utils import constants +from PyPowerStore.tests.unit_tests.base_test import TestBase +from PyPowerStore.utils.exception import PowerStoreException +from unittest import mock + + +class TestLDAPDomain(TestBase): + def test_get_ldap_domains(self): + ldap_domain_list = self.configuration.get_ldap_domain_configuration_list() + self.assertListEqual(ldap_domain_list, self.ldap_data.ldap_domain_list) + + def test_get_ldap_domain_details(self): + resp = self.configuration.get_ldap_domain_configuration_details( + self.ldap_data.ldap_domain_list[0]['id']) + self.assertEqual(resp, self.ldap_data.ldap_domain_details1) + + def test_get_ldap_domain_details_by_name(self): + resp = self.configuration.get_ldap_domain_configuration_details( + self.ldap_data.ldap_domain_details1['domain_name']) + self.assertEqual(resp, self.ldap_data.ldap_domain_details1) + + def test_create_ldap_domain_configuration(self): + resp = self.configuration.create_ldap_domain_configuration(self.ldap_data.create_ldap_domain_dict) + self.assertEqual(resp, self.ldap_data.create_ldap_domain_response) + + def test_modify_ldap_domain_configuration(self): + resp = self.configuration.modify_ldap_domain_configuration( + self.ldap_data.ldap_domain_list[0]['id'], self.ldap_data.modify_ldap_domain_dict) + self.assertIsNone(resp) + + def test_verify_ldap_domain_configuration(self): + resp = self.configuration.verify_ldap_domain_configuration(self.ldap_data.ldap_domain_list[0]['id']) + self.assertIsNone(resp) + + def test_delete_ldap_domain_configuration(self): + resp = self.configuration.delete_ldap_domain_configuration(self.ldap_data.ldap_domain_list[0]['id']) + self.assertIsNone(resp) + diff --git a/PyPowerStore/tests/unit_tests/test_remote_support_conatct.py b/PyPowerStore/tests/unit_tests/test_remote_support_contact.py similarity index 100% rename from PyPowerStore/tests/unit_tests/test_remote_support_conatct.py rename to PyPowerStore/tests/unit_tests/test_remote_support_contact.py diff --git a/PyPowerStore/tests/unit_tests/test_volume.py b/PyPowerStore/tests/unit_tests/test_volume.py index 65b7ba2..dc73caf 100644 --- a/PyPowerStore/tests/unit_tests/test_volume.py +++ b/PyPowerStore/tests/unit_tests/test_volume.py @@ -1,8 +1,7 @@ from PyPowerStore.utils import constants from PyPowerStore.tests.unit_tests.base_test import TestBase from PyPowerStore.utils.exception import PowerStoreException - -import mock +from unittest import mock class TestVolume(TestBase): diff --git a/PyPowerStore/utils/constants.py b/PyPowerStore/utils/constants.py index 2b21789..fc978e7 100644 --- a/PyPowerStore/utils/constants.py +++ b/PyPowerStore/utils/constants.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2019, Dell EMC +# Copyright: (c) 2019, Dell Technologies """Module for PowerStore constants""" @@ -46,6 +46,17 @@ "node_affinity,node_affinity_l10n" } +FHP_VOLUME_DETAILS_QUERY = { + "select": "id,name,description,type,wwn,appliance_id,state,size," + "creation_timestamp,protection_policy_id,performance_policy_id," + "protection_policy(name,id),performance_policy(name,id)," + "is_replication_destination," + "protection_data,location_history,type_l10n,state_l10n," + "host_group(name,id),volume_groups(name,id)," + "mapped_volumes(id,logical_unit_number),nsid,nguid," + "node_affinity,node_affinity_l10n" +} + # Host Query SELECT_ALL_HOST = {"select": "id,name,description,os_type," "host_group_id," @@ -307,6 +318,18 @@ REMOTE_SUPPORT_CONTACT_DETAILS_QUERY = { 'select': 'id,email,first_name,last_name,phone' } + +# LDAP Domain details +LDAP_DOMAIN_DETAILS_QUERY = { + 'select': 'id,domain_name,ldap_servers,port,ldap_server_type,protocol,bind_user,ldap_timeout,' + 'is_global_catalog,user_id_attribute,user_object_class,user_search_path,' + 'group_name_attribute,group_member_attribute,group_object_class,' + 'group_search_path,group_search_level,ldap_server_type_l10n,protocol_l10n' +} +# LDAP Account details +LDAP_ACCOUNT_DETAILS_QUERY = { + 'select': 'id,role_id,domain_id,name,type,type_l10n,dn' +} # Select all Snapshot EQUALS = 'eq.' @@ -565,3 +588,18 @@ GET_REMOTE_SUPPORT_CONTACT_LIST_URL = 'https://{0}/api/rest/remote_support_contact' GET_REMOTE_SUPPORT_CONTACT_DETAILS_URL = 'https://{0}/api/rest/remote_support_contact/{1}' MODIFY_REMOTE_SUPPORT_CONTACT_URL = GET_REMOTE_SUPPORT_CONTACT_DETAILS_URL + +# LDAP Domain endpoints +GET_LDAP_DOMAIN_LIST_URL = 'https://{0}/api/rest/ldap_domain' +GET_LDAP_DOMAIN_DETAILS_URL = 'https://{0}/api/rest/ldap_domain/{1}' +CREATE_LDAP_DOMAIN_URL = GET_LDAP_DOMAIN_LIST_URL +MODIFY_LDAP_DOMAIN_URL = GET_LDAP_DOMAIN_DETAILS_URL +DELETE_LDAP_DOMAIN_URL = GET_LDAP_DOMAIN_DETAILS_URL +VERIFY_LDAP_DOMAIN_URL = 'https://{0}/api/rest/ldap_domain/{1}/verify' + +# LDAP Account endpoints +GET_LDAP_ACCOUNT_LIST_URL = 'https://{0}/api/rest/ldap_account' +GET_LDAP_ACCOUNT_DETAILS_URL = 'https://{0}/api/rest/ldap_account/{1}' +CREATE_LDAP_ACCOUNT_URL = GET_LDAP_ACCOUNT_LIST_URL +MODIFY_LDAP_ACCOUNT_URL = GET_LDAP_ACCOUNT_DETAILS_URL +DELETE_LDAP_ACCOUNT_URL = GET_LDAP_ACCOUNT_DETAILS_URL diff --git a/PyPowerStore/utils/exception.py b/PyPowerStore/utils/exception.py index a28169c..2271022 100644 --- a/PyPowerStore/utils/exception.py +++ b/PyPowerStore/utils/exception.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2019-2021, Dell EMC +# Copyright: (c) 2019, Dell Technologies """PowerStore exceptions""" diff --git a/PyPowerStore/utils/helpers.py b/PyPowerStore/utils/helpers.py index 53bef8c..65ece28 100644 --- a/PyPowerStore/utils/helpers.py +++ b/PyPowerStore/utils/helpers.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2019-2021, Dell EMC +# Copyright: (c) 2019, Dell Technologies """Helper module for PowerStore""" import logging @@ -61,6 +61,20 @@ def is_foot_hill_or_higher(): return False +def is_foot_hill_prime_or_higher(): + """Return a true if the array version is foothill prime or higher. + + :return: True if foothill prime or higher + :rtype: bool + """ + foot_hill_prime_version = '3.0.0.0' + array_version = provisioning_obj.get_array_version() + if array_version and ( + parse_version(array_version[0:7]) >= parse_version(foot_hill_prime_version)): + return True + return False + + def filtered_details(filterable_keys, filter_dict, resource_list, resource_name): """ @@ -94,7 +108,7 @@ def filtered_details(filterable_keys, filter_dict, resource_list, temp_dict['id'] = resource['id'] # check if resource has 'name' parameter or not. if resource_name not in ["CHAP config", "service config", - "security config", "remote_support_contact"]: + "security config", "remote_support_contact", "ldap_domain"]: temp_dict['name'] = resource['name'] response.append(temp_dict) return response @@ -105,6 +119,19 @@ def apply_operators(filter_dict, key, resource, count): Returns the count for the filters applied on the keys """ split_list = filter_dict[key].split(".") + if len(split_list) > 2: + search_string = "" + for item in range(1, len(split_list)): + if item == len(split_list) - 1: + search_string += split_list[item] + else: + search_string += str(split_list[item] + ".") + + if split_list[0] == 'eq' and str(resource[key]) == search_string: + count += 1 + elif split_list[0] == 'neq' and str(resource[key]) != search_string: + count += 1 + if split_list[0] == 'eq' and str(resource[key]) == str(split_list[1]): count += 1 elif split_list[0] == 'neq' and str(resource[key]) != str(split_list[1]): diff --git a/README.md b/README.md index 9760a3e..1bda1ec 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ The library docs are available under 'docs' folder. This library uses python's "requests" library. -PyPowerStore officially supports Python 3.7, 3.8 and 3.9. +PyPowerStore officially supports Python 3.8, 3.9 and 3.10. ## Support diff --git a/docs/source/conf.py b/docs/source/conf.py deleted file mode 100644 index f1ff416..0000000 --- a/docs/source/conf.py +++ /dev/null @@ -1,54 +0,0 @@ -"""Configuration file for the Sphinx documentation builder.""" -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -import os -import sys -sys.path.insert(0, os.path.abspath('../..')) - - -# -- Project information ----------------------------------------------------- - -PROJECT = 'PyPowerStore' -COPYRIGHT = 'Dell EMC' -AUTHOR = 'Prashant Rakheja' - -# The full version, including alpha/beta/rc tags -RELEASE = '1.0' - - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -EXTENSIONS = ['sphinx.ext.todo', 'sphinx.ext.viewcode', 'sphinx.ext.autodoc'] - -# Add any paths that contain templates here, relative to this directory. -TEMPLATES_PATH = ['_templates'] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -EXCLUDE_PATTERNS = [] - - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -HTML_THEME = 'default' - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -HTML_STATIC_PATH = ['_static'] diff --git a/docs/source/index.rst b/docs/source/index.rst deleted file mode 100644 index a877999..0000000 --- a/docs/source/index.rst +++ /dev/null @@ -1,46 +0,0 @@ -.. PyPowerStore documentation master file, created by - sphinx-quickstart on Mon Sep 16 05:50:22 2019. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to PyPowerStore's documentation! -======================================== - -.. toctree:: - :maxdepth: 2 - :caption: Contents: - -Overview --------- -PyPowerStore is a python library which lets you -manage Dell EMC PowerStore. - - -Installation ------------- -Go to the root of the project where setup.py file is present, and execute: - -`pip install .` - - -Requirements ------------- -This library uses python's "requests" library. - -PyPowerStore officially supports Python 2.7 & 3.5. - -PyPowerStore provisioning -------------------------- -.. automodule:: PyPowerStore.provisioning - :members: - -PyPowerStore protection ------------------------ -.. automodule:: PyPowerStore.protection - :members: - - - - - - diff --git a/setup.py b/setup.py index 102d7b7..8c20406 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright: (c) 2019, Dell EMC +# Copyright: (c) 2019, Dell Technologies """Setup file for PowerStore SDK""" @@ -10,7 +10,7 @@ setup(name='PyPowerStore', - version='1.6.0.0', + version='1.7.0.0', description='Python Library for Dell PowerStore', author='Ansible Team at Dell', author_email='ansible.team@dell.com',