diff --git a/zOSMF/README.md b/zOSMF/README.md index 2baea2e..77fc5d9 100644 --- a/zOSMF/README.md +++ b/zOSMF/README.md @@ -20,3 +20,6 @@ This directory contains z/OSMF documents that you might find to be helpful in le ## zmf_wxa4z This is a sample plugin for z/OSMF. It allows you to easily enable chat interface of IBM watsonx Assistant for Z in z/OSMF. + +## Zosmf-Python +This folder contains sample python scripts that drive z/OSMF REST APIs. diff --git a/zOSMF/Zosmf-Python/ParmlibAPITest.py b/zOSMF/Zosmf-Python/ParmlibAPITest.py new file mode 100644 index 0000000..747a4d1 --- /dev/null +++ b/zOSMF/Zosmf-Python/ParmlibAPITest.py @@ -0,0 +1,285 @@ +# ** Beginning of Copyright and License ** # +# # +# Copyright 2024 IBM Corp. # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +# # +# ** End of Copyright and License ** + +# +# This sample python script is designed to be invoked locally from z/OS # +# system. It's highly recommended to change verify=False to verify=True # +# while invoking REST API if script will be invoked from remote system. # +# + +import requests +import json +import sys +import argparse +import base64 +from requests import HTTPError +from requests import status_codes + +################################################# +# Begin : Read and validate command line argument +################################################# +if len(sys.argv) < 2: + print ("You failed to provide required input on the command line!") + sys.exit(1) + +print ('argument list', sys.argv) + +# Initialize parser +parser = argparse.ArgumentParser(description="z/OS Parmlib Validator", + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + +# Adding positional argument +parser.add_argument("ParmlibType", help = "(Required) Parmlib Type to Validate") + +# Adding optional argument +parser.add_argument("-host", "--Host", help = "(Required) z/OSMF hostname") +parser.add_argument("-port", "--Port", help = "(Required) z/OSMF port") +parser.add_argument("-u", "--Userid", help = "(Optional) z/OS Userid", default = "") +parser.add_argument("-p", "--Password", help = "(Optional) Password of user", default = "") +parser.add_argument("-cert", "--ClientCertFile", help = "(Optional) Client certificate file name", default = "") +parser.add_argument("-key", "--ClientCertKeyFile", help = "(Optional) Client certificate Key file name", default = "") +parser.add_argument("-o", "--Output", help = "(Optional) Output file to write validation results", + default="ParmlibTestResults.json") +parser.add_argument("-lD", "--LoadDataset", + help = "(Optional) Specify dataset name that contains LOADxx member for validation of non active LOAD", + default = "") +parser.add_argument("-lM", "--LoadMember", + help = "(Optional) Specify LOAD member name for validation of non active LOAD", + default = "") +parser.add_argument("-lV", "--LoadVolSer", + help = "(Optional) Specify VOLSER for LOAD dataset if the dataset is not cataloged", + default = "") +parser.add_argument("-s", "--System", + help = "(Optional) Specify z/OS System name for validation of parmlib from active LOAD", + default = "") +parser.add_argument("-dN", "--DatasetName", + help = "(Optional) Specify Dataset name for validation of speicifc parmlib from dataset", + default = "") +parser.add_argument("-mN", "--MemberName", + help = "(Optional) Specify Member name for validation of speicifc parmlib from dataset", + default = "") +parser.add_argument("-vN", "--VolumeSerialNumber", + help = "(Optional) Specify VOLSER of the parmlib dataset if the dataset is not cataloged", + default = "") +parser.add_argument("-dV", "--deepValidation", help = "(Optional) Specify 'true' to perform deep validation for specified LOAD. \ + Deep validation is not supported for parmlib type other than LOAD.", + default = "false") +# parser.add_argument("deep", help="Perform deep validation for LOAD or IEASYS") + + +# Read arguments from command line +args = parser.parse_args() + +if args.ParmlibType: + print("Performing Validation For: % s" % args.ParmlibType) + +if args.Host: + print("z/OSMF Host Name is: % s" % args.Host) +else: + print("z/OSMF Host name is required") + sys.exit(1) + +if args.Port: + print("z/OSMF Port number is: % s" % args.Port) +else: + print("z/OSMF Port number is required") + sys.exit(1) + +# Check for optional command line arguments + +if args.Userid and args.ClientCertFile: + print("Please specify either Userid or Certificate, both are not supported") + +if args.Userid: + print("z/OS Userid is: % s" % args.Userid) + if args.Password: + print("z/OS Password is: ******") + else: + print("Password is required") + sys.exit(1) + +if args.ClientCertFile: + print("Client Certificate File Name is: % s" % args.ClientCertFile) + certFile = args.ClientCertFile + if args.ClientCertKeyFile: + print("Client Certificate Key File Name is: % s" % args.ClientCertKeyFile) + keyFile = args.ClientCertKeyFile + else: + print("When Client Certificate file name is specified, Client Certificate key file name is also required") + sys.exit(1) +else: + if not args.Userid: + print("Either userid/password Or Client Certificate/Key file names are required") + sys.exit(1) + +if args.deepValidation =='true': + if args.ParmlibType != "LOAD": + print("Deep validation is not supported for parmlib type %s" % args.ParmlibType) + sys.exit(1) + else: + print("Performing deep validation of entire parmlib setup starting with LOAD member") + +if args.Output: + print("Output file for validation result: % s" % args.Output) + outputFile = args.Output +else: + print("Output file for validation result: ParmlibTestResults.json") + outputFile = "ParmlibTestResults.json" + +if args.LoadDataset: + if args.LoadMember: + print("Performing validation of LOAD %s(%s)" % (args.LoadDataset, args.LoadMember)) + else: + print("Load member name is required when Load dataset is specified") + sys.exit(1) + +if args.LoadMember: + if args.LoadDataset == "": + print("Load Dataset name is required when Load Member is specified") + sys.exit(1) + +if args.DatasetName: + if args.LoadDataset: + print("Both Load dataset name and dataset name are not allowed") + sys.exit(1) + if args.MemberName: + print("Performing validation of parmlib from Data set %s(%s)" % (args.DatasetName, args.MemberName)) + else: + print("Load member name is required when Load dataset is specified") + sys.exit(1) + +if args.MemberName: + if args.DatasetName == "": + print("Parmlib Dataset name is required when member name is specified") + sys.exit(1) + +############################################### +# End : Read and validate Command line argument +############################################### + +#################################################### +# Begin : Construct URL with command line arguments +#################################################### +from requests.auth import HTTPBasicAuth + +url = "https://" + args.Host + ":" + args.Port + + +reqUrl = url+f"/zosmf/parmlib/v1/" \ + f"{args.ParmlibType}/" \ + f"validate" + +if args.deepValidation == 'true': + reqUrl = reqUrl + "?deep=true" +else: + reqUrl = reqUrl + "?deep=false" + +if args.System != "": + reqUrl = reqUrl + "&system=" + f"{args.System}" + +if args.ParmlibType == "LOAD": + if args.LoadDataset != "": + reqUrl = reqUrl + "&memLOAD=" + f"{args.LoadMember}" + reqUrl = reqUrl + "&datasetLOAD=" + f"{args.LoadDataset}" + + +if args.ParmlibType == "LOAD": + if args.LoadDataset != "": + reqUrl = reqUrl + "&memLOAD=" + f"{args.LoadMember}" + reqUrl = reqUrl + "&datasetLOAD=" + f"{args.LoadDataset}" + if args.System != "": + reqUrl = reqUrl + "&system=" + f"{args.System}" + +if args.DatasetName != "": + reqUrl = reqUrl + "&member=" + f"{args.MemberName}" + reqUrl = reqUrl + "&dataset=" + f"{args.DatasetName}" + + +################################################## +# End : Construct URL with command line arguments +################################################## + +######################################################## +# Begin : Construct REST API Payload and invoke REST API +######################################################## +headersList = { + "Referer": url +} + +payload = "" +warningCount = 0 +try: + if args.Userid: + response = requests.request("PUT", reqUrl, data=payload, headers=headersList, + auth=HTTPBasicAuth(args.Userid, args.Password), + verify=False) + else: + cert = (certFile,keyFile) + response = requests.request("PUT", reqUrl, data=payload, headers=headersList, + cert=cert, + verify=False) +except HTTPError as e: + print("REST API failed with error code %s" %e) + sys.exit(1) + +######################################################## +# End : Construct REST API Payload and invoke REST API +######################################################## +##################################### +# Begin : Process REST API Resposnse +##################################### +if response.status_code != 200: + print("***************************************************************") + print("REST API failed with error status code %s : %s" % (response.status_code,status_codes._codes[response.status_code][0])) + print("***************************************************************") + sys.exit(1) + +with open(outputFile, "w") as f: + r = json.loads(response.text) + results = r['result'] + if (results == "failed"): + + f.write(json.dumps(r, sort_keys=True, indent=4)) + + failedCount = r['numberOfFailedMembers'] + jsonData = r['details'] + print("***************************************************************") + for record in jsonData: + if isinstance(jsonData[record], list): + for values in jsonData[record]: + if 'validationResult' in values: + if values["validationResult"] == "failed": + print("Failed member %s(%s)" % (values["dataset"], values["member"])) + if 'Warning' in values: + print("Warning is reported for default member %s" % (values["member"])) + warningCount = warningCount + 1 + if 'numOfFailure' in record: + print("Found %s failures in %s member" % (jsonData["numOfFailure"],jsonData["member"])) + + # else: + # if record["validationResult"] == "failed": + # print("%s Failure in member Name %s(%s)" % (record["numOfFailure"], record["member"])) + print("***************************************************************") + print("Summary : %s parmlib members detected errors, %s parmlib members detected warnings " % (failedCount, warningCount)) + print("Check %s file for details" % outputFile) + print("***************************************************************") + else : + f.write(json.dumps(r, sort_keys=True, indent=4)) + print("***************************************************************") + print("validation Successful, check %s for details" % outputFile) + print("***************************************************************") \ No newline at end of file diff --git a/zOSMF/Zosmf-Python/SecurityAPITest.py b/zOSMF/Zosmf-Python/SecurityAPITest.py new file mode 100644 index 0000000..abe9798 --- /dev/null +++ b/zOSMF/Zosmf-Python/SecurityAPITest.py @@ -0,0 +1,261 @@ +# ** Beginning of Copyright and License ** # +# # +# Copyright 2024 IBM Corp. # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +# # +# ** End of Copyright and License ** + +# +# This sample python script is designed to be invoked locally from z/OS # +# system. It's highly recommended to change verify=False to verify=True # +# while invoking REST API if script will be invoked from remote system. # +# # + +import requests +import json +import sys +import argparse +import inspect +import base64 +from requests import HTTPError +from requests import status_codes + +################################################# +# Begin : Read and validate command line argument +################################################# + +if len(sys.argv) < 2: + print ("You failed to provide required input on the command line!") + sys.exit(1) + +print ('argument list', sys.argv) + +# Initialize parser +parser = argparse.ArgumentParser(description="z/OS Security Configuration", + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + +# Adding positional argument +parser.add_argument("Action", help = "(Optional)Security Action to perform. Specify 'Validate' to validate permission or \ + 'Provision' to drive permit operation", + default = "Validate") + +# Adding optional argument +parser.add_argument("-host", "--Host", help = "(Required) z/OSMF hostname") +parser.add_argument("-port", "--Port", help = "(Required) z/OSMF port") +parser.add_argument("-u", "--Userid", help = "(Optional) z/OS Userid", default = "") +parser.add_argument("-p", "--Password", help = "(Optional) Password of user", default = "") +parser.add_argument("-cert", "--ClientCertFile", help = "(Optional) Client certificate file name", default = "") +parser.add_argument("-key", "--ClientCertKeyFile", help = "(Optional) Client certificate Key file name", default = "") +parser.add_argument("-o", "--Output", help = "(Optional) Output file to write validation results", + default="SecurityValidationResults.json") +parser.add_argument("-rP", "--ResourceProfile", + help = "(Required) Specify SAF resource profile name for access validation or permission", + default = "") +parser.add_argument("-rC", "--ResourceClass", + help = "(required) Specify SAF resource class name associated with resource name", + default = "") +parser.add_argument("-aT", "--AccessType", + help = "(Optional) Specify access type to be validated or permitted. Valid access types are \ + 'READ', 'UPDATE', 'CONTROL', 'ALTER'", + default = "READ") +parser.add_argument("-rU", "--RequestedUserid", + help = "(Required) Specify USERID for which SAF resource profile permission is validation or granted", + default = "") + + +args = parser.parse_args() + + +if args.Host: + print("z/OSMF Host Name is: % s" % args.Host) +else: + print("z/OSMF Host name is required") + sys.exit(1) + +if args.Port: + print("z/OSMF Port number is: % s" % args.Port) +else: + print("z/OSMF Port number is required") + sys.exit(1) + +# Check for optional command line arguments + +if args.Userid and args.ClientCertFile: + print("Please specify either Userid or Certificate, both are not supported") + +if args.Userid: + print("z/OS Userid is: % s" % args.Userid) + if args.Password: + print("z/OS Password is: ******") + else: + print("Password is required") + sys.exit(1) + +if args.ClientCertFile: + print("Client Certificate File Name is: % s" % args.ClientCertFile) + certFile = args.ClientCertFile + if args.ClientCertKeyFile: + print("Client Certificate Key File Name is: % s" % args.ClientCertKeyFile) + keyFile = args.ClientCertKeyFile + else: + print("When Client Certificate file name is specified, Client Certificate key file name is also required") + sys.exit(1) +else: + if not args.Userid: + print("Either userid/password Or Client Certificate/Key file names are required") + sys.exit(1) + +if args.Output: + print("Output file for validation result: % s" % args.Output) + outputFile = args.Output +else: + print("Output file for validation result: SecurityValidationResults.json") + outputFile = "SecurityValidationResults.json" + +if args.RequestedUserid: + if args.RequestedUserid == "": + print("Userid to validate or grant permission is required") + sys.exit(1) +else: + print("Requested userid is required") + sys.exit(1) + +if args.ResourceProfile: + if args.ResourceProfile == "": + print("SAF Resource Profile name is required") + sys.exit(1) +else: + print("SAF Resource Profile Name is required") + sys.exit(1) + +if args.ResourceClass: + if args.ResourceClass == "": + print("SAF Resource Class name is required") + sys.exit(1) +else: + print("SAF Resource Class name is required") + sys.exit(1) + +if args.AccessType: + if (args.AccessType == "READ" or args.AccessType == "ALTER" or + args.AccessType == "UPDATE" or args.AccessType == "CONTROL") : + print("Access type for validation is: % s" % args.AccessType) + else: + print("Access type value is incorrect. Valid values are 'NONE', 'READ', 'UPDATE', \ + 'CONTROL' or 'EXECUTE'") + sys.exit(1) +else: + print("Access Type is required") + sys.exit(1) + +if args.Action: + if args.Action == "validate" or args.Action == "provision" : + print("Performing %s action for SAF resource %s in Class %s for userid %s" % (args.Action, args.ResourceProfile, args.ResourceClass, args.RequestedUserid)) + else: + print("Only 'provision' or 'validate' actions are allowed") + sys.exit(1) + +############################################### +# End : Read and validate Command line argument +############################################### + +#################################################### +# Begin : Construct URL with command line arguments +#################################################### +from requests.auth import HTTPBasicAuth + +url = "https://" + args.Host + ":" + args.Port + + +reqUrl = url+f"/zosmf/config/security/v1/" \ + f"{args.Action}"f"?userid="f"{args.RequestedUserid}" + +################################################## +# End : Construct URL with command line arguments +################################################## + +######################################################## +# Begin : Construct REST API Payload and invoke REST API +######################################################## +headersList = { + "Accept": "*/*", + "Content-Type": "application/json", + "Referer": url +} + +payload = json.dumps({"resourceItems": [{ + "resourceProfile": f"{args.ResourceProfile}", + "resourceClass": f"{args.ResourceClass}", + "access": f"{args.AccessType}" + }] +}) + + +try: + if args.Userid: + response = requests.request("POST", reqUrl, data=payload, headers=headersList, + auth=HTTPBasicAuth(args.Userid, args.Password), + verify=False) + else: + cert = (certFile,keyFile) + response = requests.request("POST", reqUrl, data=payload, headers=headersList, + cert=cert, + verify=False) +except HTTPError as e: + print("REST API failed with error code %s" %e) + sys.exit(1) + +######################################################## +# End : Construct REST API Payload and invoke REST API +######################################################## +##################################### +# Begin : Process REST API Resposnse +##################################### + +if response.status_code != 200: + print("***************************************************************") + print("REST API failed with error status code %s : %s" % (response.status_code,status_codes._codes[response.status_code][0])) + if response.status_code == 400: + r = json.loads(response.text) + print("Additional Message %s" % (r['messageText'])) + print("***************************************************************") + sys.exit(1) + +with open(outputFile, "w") as f: + r = json.loads(response.text) + jsonData = r['resourceItems'] + print("*************************** Results ******************************") + + for record in jsonData: + if record["status"] == "failed" or record["status"] == "unknown": + f.write(json.dumps(r, sort_keys=True, indent=4)) + print(inspect.cleandoc("""UserId %s is not permitted for %s access to\n\ + resource profile %s in resource class %s""" % (args.RequestedUserid, + args.AccessType, + args.ResourceProfile, + args.ResourceClass))) + print("Check %s file for details" % outputFile) + else : + f.write(json.dumps(r, sort_keys=True, indent=4)) + print(inspect.cleandoc("""UserId %s is permitted for %s access to\n\ + resource profile %s in resource class %s""" % (args.RequestedUserid, + args.AccessType, + args.ResourceProfile, + args.ResourceClass))) + print("validation Successful, check %s for details" % outputFile) + print("***************************************************************") + +##################################### +# End : Process REST API Resposnse +##################################### \ No newline at end of file diff --git a/zOSMF/Zosmf-Python/StorageAPITest.py b/zOSMF/Zosmf-Python/StorageAPITest.py new file mode 100644 index 0000000..e5d573e --- /dev/null +++ b/zOSMF/Zosmf-Python/StorageAPITest.py @@ -0,0 +1,258 @@ +# ** Beginning of Copyright and License ** # +# # +# Copyright 2024 IBM Corp. # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +# # +# ** End of Copyright and License ** + +# +# This sample python script is designed to be invoked locally from z/OS # +# system. It's highly recommended to change verify=False to verify=True # +# while invoking REST API if script will be invoked from remote system. # +# + +import requests +import json +import sys +import argparse +import base64 +from requests import HTTPError +from requests import status_codes + +################################################# +# Begin : Read and validate command line argument +################################################# +if len(sys.argv) < 2: + print ("You failed to provide required input on the command line!") + sys.exit(1) + +print ('argument list', sys.argv) + +# Initialize parser +parser = argparse.ArgumentParser(description="z/OS Storage Management", + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + +# Adding positional argument +parser.add_argument("ObjectType", help = "(Required)Storage object type to retrieve. Valid values are \ + DC (Data class), SC (Storage Class), SG (Storage Group), VOL (Volume)") + +# Adding optional argument +parser.add_argument("-host", "--Host", help = "(Required) z/OSMF hostname") +parser.add_argument("-port", "--Port", help = "(Required) z/OSMF port") +parser.add_argument("-u", "--Userid", help = "(Optional) z/OS Userid", default = "") +parser.add_argument("-p", "--Password", help = "(Optional) Password of user", default = "") +parser.add_argument("-cert", "--ClientCertFile", help = "(Optional) Client certificate file name", default = "") +parser.add_argument("-key", "--ClientCertKeyFile", help = "(Optional) Client certificate Key file name", default = "") +parser.add_argument("-o", "--Output", help = "(Optional) Output file to write retrieved storage objects", + default="StorageMgmtObjects.json") +parser.add_argument("-sgName", "--StorageGroupName", + help = "(Optional) Specify storage group name to obtain \ + The value must meet the following criteria: \ + Contains 1 - 8 alphanumeric characters \ + Begins with an alphabetic or national character. National characters are $, #, and @ \ + This property is not case-sensitive \ + Wildcards are not allowed", + default = "") +parser.add_argument("-dcName", "--DataClassName", + help = "(Optional) Specify data class name to obtain \ + The value must meet the following criteria: \ + Contains 1 - 8 alphanumeric characters \ + Begins with an alphabetic or national character. National characters are $, #, and @ \ + This property is not case-sensitive \ + Wildcards are not allowed", + default = "") +parser.add_argument("-scName", "--StorageClassName", + help = "(Optional) Specify Storage class name to obtain \ + The value must meet the following criteria: \ + Contains 1 - 8 alphanumeric characters \ + Begins with an alphabetic or national character. National characters are $, #, and @ \ + This property is not case-sensitive \ + Wildcards are not allowed", + default = "") +parser.add_argument("-volser", "--VolumeSerialNumber", + help = "(Optional) Specify volume serial number to obtain \ + The value must be a complete serial number, 1 - 6 characters, no wildcard characters. \ + Partial volume numbers are not matched. The value is not case sensitive.", + default = "") +parser.add_argument("-detail", "--DetailData", + help = "(Optional) Specifies whether the response contains detailed information. \ + The value must be Y or N. A Y value requests detailed information. A N value requests summary information. \ + The default value is N", + default = "N") + +# Read arguments from command line +args = parser.parse_args() + +print("************************* Input Properties ********************************") +if args.ObjectType: + print("Obtaining storage object: % s" % args.ObjectType) + +if args.Host: + print("z/OSMF Host Name is: % s" % args.Host) +else: + print("z/OSMF Host name is required") + sys.exit(1) +if args.Port: + print("z/OSMF Port number is: % s" % args.Port) +else: + print("z/OSMF Port number is required") + sys.exit(1) + +# Check for optional command line arguments +if args.Userid: + print("z/OS Userid is: % s" % args.Userid) + if args.Password: + print("z/OS Password is: ******") + else: + print("Password is required") + sys.exit(1) + +if args.ClientCertFile: + print("Client Certificate File Name is: % s" % args.ClientCertFile) + certFile = args.ClientCertFile + if args.ClientCertKeyFile: + print("Client Certificate Key File Name is: % s" % args.ClientCertKeyFile) + keyFile = args.ClientCertKeyFile + else: + print("When Client Certificate file name is specified, Client Certificate key file name is also required") + sys.exit(1) +else: + if not args.Userid: + print("Either userid/password Or Client Certificate/Key file names are required") + sys.exit(1) + +if args.Output: + print("Output file to save storage object: % s" % args.Output) + outputFile = args.Output +else: + print("Output file to save storage object: StorageMgmtObjects.json") + outputFile = "StorageMgmtObjects.json" + +if args.ObjectType == "SG": + reqType = "storagegroups" + if args.StorageGroupName != "": + print("Obtain stroage objects for Storage Group %s" % (args.StorageGroupName)) + else: + print("Retrieving storage objects for all Storage Groups") + +if args.ObjectType == "SC": + reqType = "storageclasses" + if args.StorageClassName != "": + print("Obtain stroage objects for Storage class %s" % (args.StorageClassName)) + else: + print("Retrieving storage objects for all Storage classes") + +if args.ObjectType == "DC": + reqType = "dataclasses" + if args.DataClassName != "": + print("Obtain stroage objects for Data class %s" % (args.DataClassName)) + else: + print("Retrieving storage objects for all Data classes") + +if args.ObjectType == "VOL": + reqType = "volumes" + if args.VolumeSerialNumber != "": + print("Obtain stroage objects for Volume Serial %s" % (args.VolumeSerialNumber)) + else: + print("Retrieving storage objects for all SMS managed volume serial numbers") + +############################################### +# End : Read and validate Command line argument +############################################### + +#################################################### +# Begin : Construct URL with command line arguments +#################################################### +from requests.auth import HTTPBasicAuth + +url = "https://" + args.Host + ":" + args.Port + + +reqUrl = url+f"/zosmf/storage/rest/v1/" \ + f"{reqType}" + + +if args.ObjectType == "SG": + if args.StorageGroupName != "": + reqUrl = reqUrl + "/" + f"{args.StorageGroupName}" +else: + if args.ObjectType == "SC": + if args.StorageClassName != "": + reqUrl = reqUrl + "/" + f"{args.StorageClassName}" + else: + if args.ObjectType == "DC": + if args.DataClassName != "": + reqUrl = reqUrl + "/" + f"{args.DataClassName}" + else: + if args.ObjectType == "VOL": + if args.VolumeSerialNumber != "": + reqUrl = reqUrl + "/" + f"{args.VolumeSerialNumber}" + + +reqUrl = reqUrl + "?detail-data=" + f"{args.DetailData}" + +################################################## +# End : Construct URL with command line arguments +################################################## + +######################################################## +# Begin : Construct REST API Payload and invoke REST API +######################################################## + +headersList = { + "Referer": url +} + +payload = "" +try: + if args.Userid: + response = requests.request("GET", reqUrl, data=payload, headers=headersList, + auth=HTTPBasicAuth(args.Userid, args.Password), + verify=False) + else: + cert = (certFile,keyFile) + response = requests.request("GET", reqUrl, data=payload, headers=headersList, + cert=cert, + verify=False) +except HTTPError as e: + print("REST API failed with error code %s" %e) + sys.exit(1) + +######################################################## +# End : Construct REST API Payload and invoke REST API +######################################################## + +##################################### +# Begin : Process REST API Resposnse +##################################### + +if response.status_code != 200: + print("***************************************************************") + print("REST API failed with error status code %s : %s" % (response.status_code,status_codes._codes[response.status_code][0])) + print("***************************************************************") + sys.exit(1) + +with open(outputFile, "w") as f: + r = json.loads(response.text) + f.write(json.dumps(r, sort_keys=True, indent=4)) + print("****************************** Results ********************************") + print("Storage objects retrieved successfully, check %s for details" % outputFile) + + if args.ObjectType == "SG": + for record in r: + if record["spaceUsed"] > 0: + if record["spaceUsed"] * 100 / record["totalSpace"] > 85: + print("WARNING : Storage group %s is more than 85 percent Used" % (record["storageGroupName"])) + + print("*************************************************************************") \ No newline at end of file