From 5dc45d2f9a632fb6066e356bd8cf457de7433773 Mon Sep 17 00:00:00 2001 From: Randy Blea <92941033+blearandy@users.noreply.github.com> Date: Tue, 28 Mar 2023 14:38:21 -0500 Subject: [PATCH 1/8] F/db/zoshost (#26) * Added zos_host command to both hardware_client.py and hardware_service.py * added a remove_zos_host command to both hardware_service and hardware_client --------- Co-authored-by: dblea0 <102998573+dblea0@users.noreply.github.com> --- pyCSM/clients/hardware_client.py | 42 +++++++++++++ .../hardware_service/hardware_service.py | 63 +++++++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/pyCSM/clients/hardware_client.py b/pyCSM/clients/hardware_client.py index 2435d46..1f1fedf 100644 --- a/pyCSM/clients/hardware_client.py +++ b/pyCSM/clients/hardware_client.py @@ -341,6 +341,48 @@ def update_connection_info(self, device_ip, device_password, device_username, device_password, device_username, connection_name) return resp + def add_zos_host(self, host_ip, password, username, host_port): + """ + This method will create a zos connection to the current IP + + Args: + host_ip (str): Primary IP address for the zos system. + password (str): Password for the zos system connection + username (str): Username for the zos system connection + host_port (str): Port for the zos system + + Returns: + JSON String representing the result of the command. + 'I' = successful, 'W' = warning, 'E' = error. + """ + resp = hardware_service.add_zos_host(self.base_url, self.tk, host_ip, + password, username, host_port) + if resp.status_code == 401: + self.tk = auth.get_token(self.base_url, self.username, self.password) + return hardware_service.add_zos_host(self.base_url, self.tk, host_ip, + password, username, host_port) + return resp + + def remove_zos_host(self, host_ip, host_port): + """ + This method will create a zos connection to the current IP + + Args: + host_ip (str): Primary IP address for the zos system. + host_port (str): Port for the zos system + + Returns: + JSON String representing the result of the command. + 'I' = successful, 'W' = warning, 'E' = error. + """ + resp = hardware_service.remove_zos_host(self.base_url, self.tk, host_ip, + host_port) + if resp.status_code == 401: + self.tk = auth.get_token(self.base_url, self.username, self.password) + return hardware_service.remove_zos_host(self.base_url, self.tk, host_ip, + host_port) + return resp + def get_volumes_by_wwn(self, wwn_name): """ Return the information for all volumes based on the list of WWNs passed in. diff --git a/pyCSM/services/hardware_service/hardware_service.py b/pyCSM/services/hardware_service/hardware_service.py index 25c98a0..2afb049 100644 --- a/pyCSM/services/hardware_service/hardware_service.py +++ b/pyCSM/services/hardware_service/hardware_service.py @@ -409,6 +409,69 @@ def update_connection_info(url, tk, device_ip, device_password, device_username, return requests.put(put_url, headers=headers, data=params, verify=properties["verify"], cert=properties["cert"]) +def add_zos_host(url, tk, host_ip, password, username, host_port): + """ + This method will create a zos connection to the current IP + + Args: + url (str): Base url of CSM server. ex. https://servername:port/CSM/web. + tk (str): Rest token for the CSM server. + host_ip (str): Primary IP address for the zos system. + password (str): Password for the zos system connection + username (str): Username for the zos system connection + host_port (str): Port for the zos system + + Returns: + JSON String representing the result of the command. + 'I' = successful, 'W' = warning, 'E' = error. + """ + put_url = f"{url}/storagedevices/zoshost" + headers = { + "Accept-Language": properties["language"], + "X-Auth-Token": str(tk), + "Content-Type": "application/x-www-form-urlencoded" + } + + params = { + "hostip": host_ip, + "password": password, + "username": username, + "hostport": host_port + } + + return requests.put(put_url, headers=headers, data=params, verify=properties["verify"], cert=properties["cert"]) + + +def remove_zos_host(url, tk, host_ip, host_port): + """ + This method will create a zos connection to the current IP + + Args: + url (str): Base url of CSM server. ex. https://servername:port/CSM/web. + tk (str): Rest token for the CSM server. + host_ip (str): Primary IP address for the zos system. + host_port (str): Port for the zos system + + Returns: + JSON String representing the result of the command. + 'I' = successful, 'W' = warning, 'E' = error. + """ + delete_url = f"{url}/storagedevices/zoshost" + headers = { + "Accept-Language": properties["language"], + "X-Auth-Token": str(tk), + "Content-Type": "application/x-www-form-urlencoded" + } + + params = { + "hostip": host_ip, + "hostport": host_port + } + + return requests.delete(delete_url, headers=headers, data=params, verify=properties["verify"], cert=properties["cert"]) + + + def get_volumes_by_wwn(url, tk, wwn_name): """ Return the information for all volumes based on the list of WWNs passed in. From 87b1e7fb4590213b62d3470031041ff0bad1c4c7 Mon Sep 17 00:00:00 2001 From: Randy Blea <92941033+blearandy@users.noreply.github.com> Date: Tue, 28 Mar 2023 14:40:19 -0500 Subject: [PATCH 2/8] Add set property interface to system services (#27) Signed-off-by: Randy Blea --- pyCSM/clients/system_client.py | 19 +++++++++++++++ .../services/system_service/system_service.py | 23 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/pyCSM/clients/system_client.py b/pyCSM/clients/system_client.py index d10d265..b041a8a 100644 --- a/pyCSM/clients/system_client.py +++ b/pyCSM/clients/system_client.py @@ -493,3 +493,22 @@ def get_volume_counts(self): self.tk = auth.get_token(self.base_url, self.username, self.password) return system_service.get_volume_counts(self.base_url, self.tk) return resp + + def set_property(self, file, property_name, value): + """ + This call will set the property provided to the value provide in the selected file + + Args: + file (str): One of the following files can be specified. "server", "bootstrap", "essniclient" or "zosclient" + property_name (str): name of the property to set ex. csm.server.extra_driver_debug + value (str): value to set the property to + + Returns: + JSON String representing the result of the command. + 'I' = successful, 'W' = warning, 'E' = error. + """ + resp = system_service.set_property(self.base_url, self.tk, file, property_name, value) + if resp.status_code == 401: + self.tk = auth.get_token(self.base_url, self.username, self.password) + return system_service.remove_active_or_standby_server(self.base_url, self.tk, file, property_name, value) + return resp diff --git a/pyCSM/services/system_service/system_service.py b/pyCSM/services/system_service/system_service.py index e8fa005..3defad1 100644 --- a/pyCSM/services/system_service/system_service.py +++ b/pyCSM/services/system_service/system_service.py @@ -512,3 +512,26 @@ def get_volume_counts(url, tk): "Content-Type": "application/x-www-form-urlencoded" } return requests.get(get_url, headers=headers, verify=properties["verify"], cert=properties["cert"]) + +def set_property(url, tk, file, property_name, value): + """ + This call will set the property provided to the value provide in the selected file + + Args: + url (str): Base url of CSM server. ex. https://servername:port/CSM/web. + tk (str): Rest token for the CSM server. + file (str): One of the following files can be specified. "server", "bootstrap", "essniclient" or "zosclient" + property_name (str): name of the property to set ex. csm.server.extra_driver_debug + value (str): value to set the property to + + Returns: + JSON String representing the result of the command. + 'I' = successful, 'W' = warning, 'E' = error. + """ + put_url = f"{url}/system/properties/{file}/{property_name}/{value}" + headers = { + "Accept-Language": properties["language"], + "X-Auth-Token": str(tk), + "Content-Type": "application/x-www-form-urlencoded" + } + return requests.put(put_url, headers=headers, verify=properties["verify"], cert=properties["cert"]) From 5893a695e941d1095a722e43a037817d46a1c945 Mon Sep 17 00:00:00 2001 From: Randy Blea <92941033+blearandy@users.noreply.github.com> Date: Tue, 28 Mar 2023 14:47:03 -0500 Subject: [PATCH 3/8] Dev (#28) (#29) * F/db/zoshost (#26) * Added zos_host command to both hardware_client.py and hardware_service.py * added a remove_zos_host command to both hardware_service and hardware_client --------- * Add set property interface to system services (#27) --------- Signed-off-by: Randy Blea Co-authored-by: dblea0 <102998573+dblea0@users.noreply.github.com> From e05f44bd7da7c45c88ab6ca33430169f6bd4a67d Mon Sep 17 00:00:00 2001 From: Randy Blea <92941033+blearandy@users.noreply.github.com> Date: Tue, 28 Mar 2023 14:53:00 -0500 Subject: [PATCH 4/8] Update version number for 1.0.2 Signed-off-by: Randy Blea --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 8376795..32c789c 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ description="CSM Python Client", long_description="CSM RESTful API Python Client.", author="Dominic Blea", - version='1.0.1', + version='1.0.2', author_email="dblea00@ibm.com", maintainer="Dominic Blea", keywords=["IBM", "CSM Storage"], From 33cca73c50dfe2be8c3970cb2a7b24f0e8ffde11 Mon Sep 17 00:00:00 2001 From: Randy Blea <92941033+blearandy@users.noreply.github.com> Date: Mon, 10 Jul 2023 10:14:19 -0500 Subject: [PATCH 5/8] F/db/zoshost (#31) * Added zos_host command to both hardware_client.py and hardware_service.py * added a remove_zos_host command to both hardware_service and hardware_client * Added methods for adding a z storage system and getting zos candidates * Added a command for get_zos_host() for the getzoshosts() method in CSM. --------- Co-authored-by: dblea0 <102998573+dblea0@users.noreply.github.com> --- pyCSM/clients/hardware_client.py | 50 +++++++++++++ .../hardware_service/hardware_service.py | 75 +++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/pyCSM/clients/hardware_client.py b/pyCSM/clients/hardware_client.py index 1f1fedf..c5db9c5 100644 --- a/pyCSM/clients/hardware_client.py +++ b/pyCSM/clients/hardware_client.py @@ -363,6 +363,36 @@ def add_zos_host(self, host_ip, password, username, host_port): password, username, host_port) return resp + + def get_zos_candidate(self): + """ + This method will query for the devices in REST that are attached to the zos system + + Returns: + JSON String representing the result of the command. + 'I' = successful, 'W' = warning, 'E' = error. + """ + resp = hardware_service.get_zos_candidate(self.base_url, self.tk) + if resp.status_code == 401: + self.tk = auth.get_token(self.base_url, self.username, self.password) + return hardware_service.get_zos_candidate(self.base_url, self.tk) + return resp + + def get_zos_host(self): + """ + This method will get the information for all zos host connections. + + Returns: + JSON String representing the result of the command. + 'I' = successful, 'W' = warning, 'E' = error. + """ + resp = hardware_service.get_zos_host(self.base_url, self.tk) + if resp.status_code == 401: + self.tk = auth.get_token(self.base_url, self.username, self.password) + return hardware_service.get_zos_host(self.base_url, self.tk) + return resp + + def remove_zos_host(self, host_ip, host_port): """ This method will create a zos connection to the current IP @@ -383,6 +413,26 @@ def remove_zos_host(self, host_ip, host_port): host_port) return resp + + def add_zos_device(self, device_id): + """ + This method will add a storage system through the zoshost connection. + + Args: + device_id (str): Storage system name in the format "DS8000:BOX:2107.KXZ91". + connection_type (str): type of connection + + Returns: + JSON String representing the result of the command. + 'I' = successful, 'W' = warning, 'E' = error. + """ + resp = hardware_service.add_zos_device(self.base_url, self.tk, device_id) + if resp.status_code == 401: + self.tk = auth.get_token(self.base_url, self.username, self.password) + return hardware_service.add_zos_device(self.base_url, self.tk, device_id) + return resp + + def get_volumes_by_wwn(self, wwn_name): """ Return the information for all volumes based on the list of WWNs passed in. diff --git a/pyCSM/services/hardware_service/hardware_service.py b/pyCSM/services/hardware_service/hardware_service.py index 2afb049..261b9d4 100644 --- a/pyCSM/services/hardware_service/hardware_service.py +++ b/pyCSM/services/hardware_service/hardware_service.py @@ -409,6 +409,32 @@ def update_connection_info(url, tk, device_ip, device_password, device_username, return requests.put(put_url, headers=headers, data=params, verify=properties["verify"], cert=properties["cert"]) +def get_zos_candidate(url, tk): + """ + This method will query for the devices in REST that are attached to the zos system. + + Args: + url (str): Base url of CSM server. ex. https://servername:port/CSM/web. + tk (str): Rest token for the CSM server. + + Returns: + JSON String representing the result of the command. + 'I' = successful, 'W' = warning, 'E' = error. + """ + get_url = f"{url}/storagedevices/zoscandidate" + headers = { + "Accept-Language": properties["language"], + "X-Auth-Token": str(tk), + "Content-Type": "application/x-www-form-urlencoded" + } + + params = { + } + + return requests.get(get_url, headers=headers, data=params, verify=properties["verify"], cert=properties["cert"]) + + + def add_zos_host(url, tk, host_ip, password, username, host_port): """ This method will create a zos connection to the current IP @@ -472,6 +498,55 @@ def remove_zos_host(url, tk, host_ip, host_port): +def add_zos_device(url, tk, device_id): + """ + This method will add a storage system through the zoshost connection. + + Args: + url (str): Base url of CSM server. ex. https://servername:port/CSM/web. + tk (str): Rest token for the CSM server. + device_id (str): Storage system name in the format "DS8000:BOX:2107.KXZ91". + + Returns: + JSON String representing the result of the command. + 'I' = successful, 'W' = warning, 'E' = error. + """ + put_url = f"{url}/storagedevices/zosdevice" + headers = { + "Accept-Language": properties["language"], + "X-Auth-Token": str(tk), + "Content-Type": "application/x-www-form-urlencoded" + } + + params = { + "deviceid": device_id + } + + return requests.put(put_url, headers=headers, data=params, verify=properties["verify"], cert=properties["cert"]) + + +def get_zos_host(url, tk): + """ + This method will get the information for all zos host connections. + + Args: + url (str): Base url of CSM server. ex. https://servername:port/CSM/web. + tk (str): Rest token for the CSM server. + + Returns: + JSON String representing the result of the command. + 'I' = successful, 'W' = warning, 'E' = error. + """ + get_url = f"{url}/storagedevices/zoshost" + headers = { + "Accept-Language": properties["language"], + "X-Auth-Token": str(tk), + "Content-Type": "application/x-www-form-urlencoded" + } + return requests.get(get_url, headers=headers, verify=properties["verify"], cert=properties["cert"]) + + + def get_volumes_by_wwn(url, tk, wwn_name): """ Return the information for all volumes based on the list of WWNs passed in. From c5e8ecd7aa7ce3d316f9ba108bd3cbebfcfd8be0 Mon Sep 17 00:00:00 2001 From: Randy Blea <92941033+blearandy@users.noreply.github.com> Date: Fri, 29 Sep 2023 14:18:07 -0500 Subject: [PATCH 6/8] Added methods for added a cert to zos by taking in the base url, token and file path of given cert. (#33) Co-authored-by: dblea0 <102998573+dblea0@users.noreply.github.com> --- pyCSM/clients/hardware_client.py | 17 +++++++++++++ .../hardware_service/hardware_service.py | 24 +++++++++++++++++++ requirements.txt | 2 +- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/pyCSM/clients/hardware_client.py b/pyCSM/clients/hardware_client.py index b5ff4b7..338779c 100644 --- a/pyCSM/clients/hardware_client.py +++ b/pyCSM/clients/hardware_client.py @@ -341,6 +341,23 @@ def update_connection_info(self, device_ip, device_password, device_username, device_password, device_username, connection_name) return resp + def add_zos_cert(self, file_path): + """ + This method will add a given cert to zos connection. + + Args: + file_path (str): path for given certificate file. + + Returns: + JSON String representing the result of the command. + 'I' = successful, 'W' = warning, 'E' = error. + """ + resp = hardware_service.add_zos_cert(self.base_url, self.tk, file_path) + if resp.status_code == 401: + self.tk = auth.get_token(self.base_url, self.username, self.password) + return hardware_service.add_zos_cert(self.base_url, self.tk, file_path) + return resp + def add_zos_host(self, host_ip, password, username, host_port): """ This method will create a zos connection to the current IP diff --git a/pyCSM/services/hardware_service/hardware_service.py b/pyCSM/services/hardware_service/hardware_service.py index b8a439a..3b27e9c 100644 --- a/pyCSM/services/hardware_service/hardware_service.py +++ b/pyCSM/services/hardware_service/hardware_service.py @@ -499,6 +499,30 @@ def remove_zos_host(url, tk, host_ip, host_port): return requests.delete(delete_url, headers=headers, data=params, verify=properties["verify"], cert=properties["cert"]) +def add_zos_cert(url, tk, file_path): + """ + This method will add a given cert to zos connection. + + Args: + url (str): Base url of CSM server. ex. https://servername:port/CSM/web. + tk (str): Rest token for the CSM server. + file_path (str): Path for given certificate file. + + Returns: + JSON String representing the result of the command. + 'I' = successful, 'W' = warning, 'E' = error. + """ + post_url = f"{url}/storagedevices/zoscert" + headers = { + "Accept-Language": properties["language"], + "X-Auth-Token": str(tk), + } + + files = { + "file": open(file_path, 'rb') + } + + return requests.post(post_url, headers=headers, files=files, verify=properties["verify"], cert=properties["cert"]) def add_zos_device(url, tk, device_id): diff --git a/requirements.txt b/requirements.txt index 4308c3b..074ffc6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ certifi==2022.6.15 -pip==22.1.2 +pip>=22.1.2 requests==2.28.0 urllib3==1.26.9 setuptools~=58.1.0 \ No newline at end of file From 02dc9efe2065c54c8612546cc7d5d49861ab614a Mon Sep 17 00:00:00 2001 From: Randy Blea Date: Fri, 29 Sep 2023 14:21:06 -0500 Subject: [PATCH 7/8] Update release to 1.0.4 Update for next release number --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 32c789c..99f157f 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ description="CSM Python Client", long_description="CSM RESTful API Python Client.", author="Dominic Blea", - version='1.0.2', + version='1.0.4', author_email="dblea00@ibm.com", maintainer="Dominic Blea", keywords=["IBM", "CSM Storage"], From 7920b8e8363297ef2c88e6eb87f8a8fbfd7ec68c Mon Sep 17 00:00:00 2001 From: Randy Blea Date: Thu, 12 Oct 2023 11:06:30 -0500 Subject: [PATCH 8/8] Update for new release number 1.0.5 Update for new release number 1.0.5 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 99f157f..df12dd7 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ description="CSM Python Client", long_description="CSM RESTful API Python Client.", author="Dominic Blea", - version='1.0.4', + version='1.0.5', author_email="dblea00@ibm.com", maintainer="Dominic Blea", keywords=["IBM", "CSM Storage"],