pyCSM 1.0.7__tar.gz → 1.0.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. pycsm-1.0.8/PKG-INFO +86 -0
  2. {pyCSM-1.0.7 → pycsm-1.0.8}/docs/conf.py +1 -1
  3. {pyCSM-1.0.7 → pycsm-1.0.8}/pyCSM/clients/session_client.py +63 -9
  4. {pyCSM-1.0.7 → pycsm-1.0.8}/pyCSM/clients/system_client.py +44 -1
  5. {pyCSM-1.0.7 → pycsm-1.0.8}/pyCSM/services/hardware_service/hardware_service.py +0 -52
  6. {pyCSM-1.0.7 → pycsm-1.0.8}/pyCSM/services/session_service/copyset_service.py +0 -47
  7. {pyCSM-1.0.7 → pycsm-1.0.8}/pyCSM/services/session_service/schedule_service.py +119 -0
  8. {pyCSM-1.0.7 → pycsm-1.0.8}/pyCSM/services/session_service/session_service.py +70 -23
  9. {pyCSM-1.0.7 → pycsm-1.0.8}/pyCSM/services/system_service/system_service.py +103 -0
  10. pycsm-1.0.8/pyCSM/test/test_copyset_service.py +237 -0
  11. pycsm-1.0.8/pyCSM/test/test_hardware_service.py +751 -0
  12. pycsm-1.0.8/pyCSM/test/test_schedule_service.py +551 -0
  13. pycsm-1.0.8/pyCSM/test/test_session_service.py +1157 -0
  14. pycsm-1.0.8/pyCSM/test/test_system_service.py +967 -0
  15. pycsm-1.0.8/pyCSM/util/__init__.py +0 -0
  16. pycsm-1.0.8/pyCSM.egg-info/PKG-INFO +86 -0
  17. {pyCSM-1.0.7 → pycsm-1.0.8}/pyCSM.egg-info/SOURCES.txt +7 -1
  18. pycsm-1.0.8/pyCSM.egg-info/requires.txt +3 -0
  19. {pyCSM-1.0.7 → pycsm-1.0.8}/pyCSM.egg-info/top_level.txt +1 -0
  20. pycsm-1.0.8/pyproject.toml +36 -0
  21. pyCSM-1.0.7/PKG-INFO +0 -23
  22. pyCSM-1.0.7/pyCSM.egg-info/PKG-INFO +0 -23
  23. pyCSM-1.0.7/pyCSM.egg-info/requires.txt +0 -5
  24. pyCSM-1.0.7/setup.py +0 -29
  25. {pyCSM-1.0.7 → pycsm-1.0.8}/LICENSE +0 -0
  26. {pyCSM-1.0.7 → pycsm-1.0.8}/README.md +0 -0
  27. {pyCSM-1.0.7 → pycsm-1.0.8}/docs/__init__.py +0 -0
  28. {pyCSM-1.0.7 → pycsm-1.0.8}/pyCSM/__init__.py +0 -0
  29. {pyCSM-1.0.7 → pycsm-1.0.8}/pyCSM/authorization/__init__.py +0 -0
  30. {pyCSM-1.0.7 → pycsm-1.0.8}/pyCSM/authorization/auth.py +0 -0
  31. {pyCSM-1.0.7 → pycsm-1.0.8}/pyCSM/clients/__init__.py +0 -0
  32. {pyCSM-1.0.7 → pycsm-1.0.8}/pyCSM/clients/hardware_client.py +0 -0
  33. {pyCSM-1.0.7 → pycsm-1.0.8}/pyCSM/services/__init__.py +0 -0
  34. {pyCSM-1.0.7 → pycsm-1.0.8}/pyCSM/services/hardware_service/__init__.py +0 -0
  35. {pyCSM-1.0.7 → pycsm-1.0.8}/pyCSM/services/session_service/__init__.py +0 -0
  36. {pyCSM-1.0.7 → pycsm-1.0.8}/pyCSM/services/system_service/__init__.py +0 -0
  37. {pyCSM-1.0.7/pyCSM/util → pycsm-1.0.8/pyCSM/test}/__init__.py +0 -0
  38. {pyCSM-1.0.7 → pycsm-1.0.8}/pyCSM/util/utility.py +0 -0
  39. {pyCSM-1.0.7 → pycsm-1.0.8}/pyCSM.egg-info/dependency_links.txt +0 -0
  40. {pyCSM-1.0.7 → pycsm-1.0.8}/setup.cfg +0 -0
pycsm-1.0.8/PKG-INFO ADDED
@@ -0,0 +1,86 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyCSM
3
+ Version: 1.0.8
4
+ Summary: CSM Python Client
5
+ Author-email: Dominic Blea <dblea00@ibm.com>
6
+ Maintainer-email: Dominic Blea <dblea00@ibm.com>
7
+ License-Expression: Apache-2.0
8
+ Keywords: IBM,CSM Storage
9
+ Classifier: Development Status :: 5 - Production/Stable
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Intended Audience :: System Administrators
12
+ Classifier: Environment :: Console
13
+ Classifier: Programming Language :: Python
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
+ Requires-Python: >=3.10
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: certifi>=2022.6.15
20
+ Requires-Dist: requests>=2.28.0
21
+ Requires-Dist: urllib3>=1.26.9
22
+ Dynamic: license-file
23
+
24
+ # CSM Python Client
25
+ [![Build Status](https://travis.ibm.com/pyCSM/pyCSM.svg?token=S4B3H6Vzv2oQaoCcyYeT&branch=main)](https://github.ibm.com/pyCSM/pyCSM)
26
+ [![Documentation Status](https://readthedocs.org/projects/pycsm/badge/?version=latest)](https://pycsm.readthedocs.io/en/latest/?badge=latest)
27
+ [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5999/badge)](https://bestpractices.coreinfrastructure.org/projects/5999)
28
+
29
+ This repository contains the IBM Python client for RESTful communication to an IBM Copy Services Manager server. The Python client enables full management and monitoring of the replication and the components necessary for replication in a Copy Services Manager environment.
30
+
31
+ The repository provides two options for implementations.
32
+ - **Clients** - The client classes are [session_client.py](pyCSM/clients/session_client.py), [hardware_client.py](pyCSM/clients/hardware_client.py), and [system_client.py](pyCSM/clients/system_client.py). These classes are designed to automatically obtain and manage a token to CSM for communication. A client class can be instantiated and then used to call the methods that perform the desired actions.
33
+ - **Services** - The service classes are located under [session_service](pyCSM/services/session_service), [hardware_service](pyCSM/services/hardware_service), and [system_service](pyCSM/services/system_service) and can be used if the caller wishes to manage the connection and token themselves. These are the same classes that are called from the client classes.
34
+
35
+
36
+ ## Python Compatibility
37
+ The content in this collection supports Python 3.6 and higher
38
+
39
+ ## Installation
40
+
41
+ Communication to the Copy Services Manager server uses the RESTful interface and thus does not require an installation of client code.
42
+ Clone the repository, and then add it to your PYTHONPATH directory. The Python client is then ready for import and use.
43
+
44
+ The pyCSM library can also be installed using pip.
45
+ ```text
46
+ pip install pyCSM
47
+ ```
48
+
49
+ ## Command Documentation
50
+ All commands, their usage and their parameters are documented on [read the docs](https://pycsm.readthedocs.io/en/latest/).
51
+
52
+ ## Usage examples
53
+ See documentation for examples on [read the docs](https://pycsm.readthedocs.io/en/latest/).
54
+
55
+ ## The CSM RESTful API
56
+ Details on the CSM RESTful API used by this python library can be found in the [Knowledgecenter](https://www.ibm.com/docs/en/csm/6.3.2?topic=reference-csm-rest-api-documentation) for the product.
57
+
58
+
59
+ ## Contributing
60
+ To contribute to this library, please see [CONTRIBUTING.md](CONTRIBUTING.md) and submit a contributor license agreement for either an individual or corporation, to those listed as maintainers [here](MAINTAINERS.md).
61
+
62
+ See [cla-individual.doc](cla-individual.doc) or [cla-corporate.doc](cla-corporate.doc) for templates of the contributor license agreement.
63
+
64
+ ## License
65
+
66
+ All source files must include a Copyright and License header.
67
+ ```text
68
+ #
69
+ # (c) Copyright contributors to the pyCSM project
70
+ #
71
+ ```
72
+
73
+ This project is licensed under the Apache License 2.0.
74
+ Click here to obtain a copy of the [License](http://www.apache.org/licenses/LICENSE-2.0).
75
+
76
+ It is a permissive license whose main conditions require preservation of
77
+ copyright and license notices. Contributors provide an express grant of
78
+ patent rights. Licensed works, modifications, and larger works may be
79
+ distributed under different terms and without source code.
80
+
81
+ The examples are provided for tutorial purposes only. A complete handling
82
+ of error conditions has not been shown or attempted, and the programs have
83
+ not been submitted to formal IBM testing. The programs are distributed on an
84
+ 'AS IS' basis without any warranties either expressed or implied.
85
+
86
+ If you would like to see the detailed LICENSE click [here](LICENSE).
@@ -19,7 +19,7 @@ sys.path.insert(0, os.path.abspath('..'))
19
19
  # -- Project information -----------------------------------------------------
20
20
 
21
21
  project = 'pyCSM'
22
- copyright = '2022, dblea00'
22
+ copyright = '2026, dblea00'
23
23
  author = 'dblea00'
24
24
 
25
25
 
@@ -237,10 +237,10 @@ class sessionClient:
237
237
  ses_name, state, minutes, debug)
238
238
  resp = result_dict["state_reached"]
239
239
  if resp.status_code == 401:
240
- minutes = (datetime.utcnow() - start_time).total_seconds()
240
+ elapsed_minutes = int((datetime.utcnow() - start_time).total_seconds() / 60)
241
241
  self.tk = auth.get_token(self.base_url, self.username, self.password)
242
242
  return session_service.wait_for_state(self.base_url, self.tk, ses_name,
243
- state, minutes, debug)
243
+ state, elapsed_minutes, debug)
244
244
  return result_dict
245
245
 
246
246
  def sgc_recover(self, ses_name, com_name, role, backup_id):
@@ -482,7 +482,7 @@ class sessionClient:
482
482
  roleorder)
483
483
  return resp
484
484
 
485
- def remove_copysets(self, name, copysets, force=None, soft=None):
485
+ def remove_copysets(self, name, copysets, force=False, soft=False):
486
486
  """
487
487
  Removes Copy Sets from the given session.
488
488
 
@@ -517,7 +517,7 @@ class sessionClient:
517
517
  resp = copyset_service.export_copysets(self.base_url, self.tk, name, file_name)
518
518
  if resp.status_code == 401:
519
519
  self.tk = auth.get_token(self.base_url, self.username, self.password)
520
- return copyset_service.export_copysets.export_cpyst(self.base_url, self.tk, name, file_name)
520
+ return copyset_service.export_copysets(self.base_url, self.tk, name, file_name)
521
521
  return resp
522
522
 
523
523
  def get_pair_info(self, name, rolepair):
@@ -538,7 +538,7 @@ class sessionClient:
538
538
  rolepair)
539
539
  if resp.status_code == 401:
540
540
  self.tk = auth.get_token(self.base_url, self.username, self.password)
541
- return copyset_service.get_pair_info.export_cpyst(self.base_url, self.tk, name,
541
+ return copyset_service.get_pair_info(self.base_url, self.tk, name,
542
542
  rolepair)
543
543
  return resp
544
544
 
@@ -554,11 +554,11 @@ class sessionClient:
554
554
  JSON String representing the result of the command.
555
555
  'I' = successful,'W' = warning, 'E' = error.
556
556
  """
557
- resp = copyset_service.enable_scheduled_task_at_time(self.base_url, self.tk, task_id,
557
+ resp = schedule_service.enable_scheduled_task_at_time(self.base_url, self.tk, task_id,
558
558
  start_time)
559
559
  if resp.status_code == 401:
560
560
  self.tk = auth.get_token(self.base_url, self.username, self.password)
561
- return copyset_service.enable_scheduled_task_at_time(self.base_url, self.tk, task_id,
561
+ return schedule_service.enable_scheduled_task_at_time(self.base_url, self.tk, task_id,
562
562
  start_time)
563
563
  return resp
564
564
 
@@ -574,11 +574,11 @@ class sessionClient:
574
574
  JSON String representing the result of the command.
575
575
  'I' = successful,'W' = warning, 'E' = error.
576
576
  """
577
- resp = copyset_service.run_scheduled_task_at_time(self.base_url, self.tk, task_id,
577
+ resp = schedule_service.run_scheduled_task_at_time(self.base_url, self.tk, task_id,
578
578
  start_time)
579
579
  if resp.status_code == 401:
580
580
  self.tk = auth.get_token(self.base_url, self.username, self.password)
581
- return copyset_service.run_scheduled_task_at_time(self.base_url, self.tk, task_id,
581
+ return schedule_service.run_scheduled_task_at_time(self.base_url, self.tk, task_id,
582
582
  start_time)
583
583
  return resp
584
584
 
@@ -769,3 +769,57 @@ class sessionClient:
769
769
  return session_service.get_rolepair_info(self.base_url, self.tk,
770
770
  name, rolepair)
771
771
  return resp
772
+
773
+ def delete_task(self, taskid):
774
+ """
775
+ Delete a scheduled task.
776
+ Args:
777
+ taskid (str): ID of the schedule task to enable.
778
+
779
+ Returns:
780
+ JSON String representing the result of the command.
781
+ 'I' = successful, 'W' = warning, 'E' = error.
782
+ """
783
+ resp = schedule_service.delete_task(self.base_url, self.tk, taskid)
784
+ if resp.status_code == 401:
785
+ self.tk = auth.get_token(self.base_url, self.username, self.password)
786
+ return schedule_service.delete_task(self.base_url, self.tk, taskid)
787
+
788
+ return resp
789
+
790
+ def cancel_task(self, taskid):
791
+ """
792
+ Cancel a running scheduled task.
793
+ Args:
794
+ taskid (str): ID of the schedule task to cancel.
795
+
796
+ Returns:
797
+ JSON String representing the result of the command.
798
+ 'I' = successful, 'W' = warning, 'E' = error.
799
+ """
800
+ resp = schedule_service.cancel_task(self.base_url, self.tk, taskid)
801
+ if resp.status_code == 401:
802
+ self.tk = auth.get_token(self.base_url, self.username, self.password)
803
+ return schedule_service.cancel_task(self.base_url, self.tk, taskid)
804
+
805
+ return resp
806
+
807
+ def run_task_now(self, taskid, synchronous=False, step=0):
808
+ """
809
+ Run a scheduled task immediately at a specific step.
810
+
811
+
812
+ Returns:
813
+ JSON String representing the result of the command.
814
+ 'I' = successful, 'W' = warning, 'E' = error.
815
+ """
816
+
817
+ resp = schedule_service.cancel_task(self.base_url, self.tk, taskid)
818
+ if resp.status_code == 401:
819
+ self.tk = auth.get_token(self.base_url, self.username, self.password)
820
+ resp = schedule_service.cancel_task(self.base_url, self.tk, taskid)
821
+
822
+ run_resp = schedule_service.run_task_now(url=self.base_url, tk=self.tk, taskid=taskid, step=step, synchronous=synchronous)
823
+
824
+ return run_resp
825
+
@@ -510,5 +510,48 @@ class systemClient:
510
510
  resp = system_service.set_property(self.base_url, self.tk, file, property_name, value)
511
511
  if resp.status_code == 401:
512
512
  self.tk = auth.get_token(self.base_url, self.username, self.password)
513
- return system_service.remove_active_or_standby_server(self.base_url, self.tk, file, property_name, value)
513
+ return system_service.remove_active_or_standby_server(self.base_url, self.tk, file)
514
514
  return resp
515
+
516
+ def put_email_notifications_enabled(self, enabled):
517
+ """
518
+ Enables or disables email alert notifications on the server.
519
+
520
+ Returns:
521
+ JSON String representing the result of the command.
522
+ 'I' = successful, 'W' = warning, 'E' = error.
523
+ """
524
+ resp = system_service.put_email_notifications_enabled(self.base_url, self.tk, enabled)
525
+ if resp.status_code == 401:
526
+ self.tk = auth.get_token(self.base_url, self.username, self.password)
527
+ return system_service.put_email_notifications_enabled(self.base_url, self.tk, enabled)
528
+ return resp
529
+
530
+ def get_email_recipients(self):
531
+ """
532
+ Get a summary of the volume usage on the server
533
+
534
+ Returns:
535
+ JSON String representing the result of the command.
536
+ 'I' = successful, 'W' = warning, 'E' = error.
537
+ """
538
+ resp = system_service.get_email_recipients(self.base_url, self.tk)
539
+ if resp.status_code == 401:
540
+ self.tk = auth.get_token(self.base_url, self.username, self.password)
541
+ return system_service.get_email_recipients(self.base_url, self.tk)
542
+ return resp
543
+
544
+ def add_email_recipients(self, addresses, alert_type, session_names):
545
+ """
546
+ Enables or disables email alert notifications on the server.
547
+
548
+ Returns:
549
+ JSON String representing the result of the command.
550
+ 'I' = successful, 'W' = warning, 'E' = error.
551
+ """
552
+ resp = system_service.add_email_recipients(self.base_url, self.tk, addresses, alert_type, session_names )
553
+ if resp.status_code == 401:
554
+ self.tk = auth.get_token(self.base_url, self.username, self.password)
555
+ return system_service.add_email_recipients(self.base_url, self.tk, addresses, alert_type, session_names)
556
+ return resp
557
+
@@ -524,58 +524,6 @@ def add_zos_cert(url, tk, file_path):
524
524
 
525
525
  return requests.post(post_url, headers=headers, files=files, verify=properties["verify"], cert=properties["cert"])
526
526
 
527
-
528
- def add_zos_device(url, tk, device_id):
529
- """
530
- This method will add a storage system through the zoshost connection.
531
-
532
- Args:
533
- url (str): Base url of CSM server. ex. https://servername:port/CSM/web.
534
- tk (str): Rest token for the CSM server.
535
- device_id (str): Storage system name in the format "DS8000:BOX:2107.KXZ91".
536
-
537
- Returns:
538
- JSON String representing the result of the command.
539
- 'I' = successful, 'W' = warning, 'E' = error.
540
- """
541
- put_url = f"{url}/storagedevices/zosdevice"
542
- headers = {
543
- "Accept-Language": properties["language"],
544
- "X-Auth-Token": str(tk),
545
- "Content-Type": "application/x-www-form-urlencoded"
546
- }
547
-
548
- params = {
549
- "deviceid": device_id
550
- }
551
-
552
- return requests.put(put_url, headers=headers, data=params, verify=properties["verify"], cert=properties["cert"])
553
-
554
-
555
- def get_zos_host(url, tk):
556
- """
557
- This method will get the information for all zos host connections.
558
-
559
- Args:
560
- url (str): Base url of CSM server. ex. https://servername:port/CSM/web.
561
- tk (str): Rest token for the CSM server.
562
-
563
- Returns:
564
- JSON String representing the result of the command.
565
- 'I' = successful, 'W' = warning, 'E' = error.
566
- """
567
- get_url = f"{url}/storagedevices/zoshost"
568
- headers = {
569
- "Accept-Language": properties["language"],
570
- "X-Auth-Token": str(tk),
571
- "Content-Type": "application/x-www-form-urlencoded"
572
- }
573
- return requests.get(get_url, headers=headers, verify=properties["verify"], cert=properties["cert"])
574
-
575
-
576
-
577
-
578
-
579
527
  def add_zos_device(url, tk, device_id):
580
528
  """
581
529
  This method will add a storage system through the zoshost connection.
@@ -172,50 +172,3 @@ def get_pair_info(url, tk, name, rolepair):
172
172
  }
173
173
  return requests.get(get_url, headers=headers, verify=properties["verify"], cert=properties["cert"])
174
174
 
175
-
176
- def enable_scheduled_task_at_time(url, tk, task_id, start_time):
177
- """
178
- Enable the task at the given time
179
-
180
- Args:
181
- url (str): Base url of csm server. ex. https://servername:port/CSM/web.
182
- tk (str): Rest token for the CSM server.
183
- task_id (int): ID of the schedule task to enable
184
- start_time (str): Time to enable the task.
185
- Format of yyyy-MM-dd'T'HH-mm.
186
-
187
- Returns:
188
- JSON String representing the result of the command.
189
- 'I' = successful,'W' = warning, 'E' = error.
190
- """
191
- post_url = f"{url}/sessions/scheduledtasks/enable/{task_id}/{start_time}"
192
- headers = {
193
- "Accept-Language": properties["language"],
194
- "X-Auth-Token": str(tk),
195
- "Content-Type": "application/x-www-form-urlencoded"
196
- }
197
- return requests.post(post_url, headers=headers, verify=properties["verify"], cert=properties["cert"])
198
-
199
-
200
- def run_scheduled_task_at_time(url, tk, task_id, start_time):
201
- """
202
- Run a scheduled task immediately.
203
-
204
- Args:
205
- url (str): Base url of csm server. ex. https://servername:port/CSM/web.
206
- tk (str): Rest token for the CSM server.
207
- task_id (int): ID of the schedule task to enable
208
- start_time (str): Time to enable the task.
209
- Format of yyyy-MM-dd'T'HH-mm.
210
-
211
- Returns:
212
- JSON String representing the result of the command.
213
- 'I' = successful,'W' = warning, 'E' = error.
214
- """
215
- post_url = f"{url}/sessions/scheduledtasks/{task_id}/runat/{start_time}"
216
- headers = {
217
- "Accept-Language": properties["language"],
218
- "X-Auth-Token": str(tk),
219
- "Content-Type": "application/x-www-form-urlencoded"
220
- }
221
- return requests.post(post_url, headers=headers, verify=properties["verify"], cert=properties["cert"])
@@ -193,3 +193,122 @@ def run_scheduled_task(url, tk, taskid, synchronous=False):
193
193
  "Content-Type": "application/x-www-form-urlencoded"
194
194
  }
195
195
  return requests.post(run_url, headers=headers, verify=properties["verify"], cert=properties["cert"])
196
+
197
+ def enable_scheduled_task_at_time(url, tk, task_id, start_time):
198
+ """
199
+ Enable the task at the given time
200
+
201
+ Args:
202
+ url (str): Base url of csm server. ex. https://servername:port/CSM/web.
203
+ tk (str): Rest token for the CSM server.
204
+ task_id (int): ID of the schedule task to enable
205
+ start_time (str): Time to enable the task.
206
+ Format of yyyy-MM-dd'T'HH-mm.
207
+
208
+ Returns:
209
+ JSON String representing the result of the command.
210
+ 'I' = successful,'W' = warning, 'E' = error.
211
+ """
212
+ post_url = f"{url}/sessions/scheduledtasks/enable/{task_id}/{start_time}"
213
+ headers = {
214
+ "Accept-Language": properties["language"],
215
+ "X-Auth-Token": str(tk),
216
+ "Content-Type": "application/x-www-form-urlencoded"
217
+ }
218
+ return requests.post(post_url, headers=headers, verify=properties["verify"], cert=properties["cert"])
219
+
220
+
221
+ def run_scheduled_task_at_time(url, tk, task_id, start_time):
222
+ """
223
+ Run a scheduled task immediately.
224
+
225
+ Args:
226
+ url (str): Base url of csm server. ex. https://servername:port/CSM/web.
227
+ tk (str): Rest token for the CSM server.
228
+ task_id (int): ID of the schedule task to enable
229
+ start_time (str): Time to enable the task.
230
+ Format of yyyy-MM-dd'T'HH-mm.
231
+
232
+ Returns:
233
+ JSON String representing the result of the command.
234
+ 'I' = successful,'W' = warning, 'E' = error.
235
+ """
236
+ post_url = f"{url}/sessions/scheduledtasks/{task_id}/runat/{start_time}"
237
+ headers = {
238
+ "Accept-Language": properties["language"],
239
+ "X-Auth-Token": str(tk),
240
+ "Content-Type": "application/x-www-form-urlencoded"
241
+ }
242
+ return requests.post(post_url, headers=headers, verify=properties["verify"], cert=properties["cert"])
243
+
244
+
245
+ def delete_task(url, tk, taskid):
246
+ """
247
+ This method is used to delete a schedualed task.
248
+
249
+ Args:
250
+ url (str): Base url of csm server. ex. https://servername:port/CSM/web.
251
+ tk (str): Rest token for the CSM server.
252
+ taskid (str): ID of the schedule task to enable.
253
+
254
+ Returns:
255
+ JSON String representing the result of the command.
256
+ 'I' = successful, 'W' = warning, 'E' = error.
257
+ """
258
+ delete_task_url = f"{url}/sessions/scheduledtasks/delete/{taskid}"
259
+
260
+ headers = {
261
+ "Accept-Language": properties["language"],
262
+ "X-Auth-Token": str(tk),
263
+ "Content-Type": "application/x-www-form-urlencoded"
264
+ }
265
+ return requests.post(delete_task_url, headers=headers, verify=properties["verify"], cert=properties["cert"])
266
+
267
+ def cancel_task(url, tk, taskid):
268
+ """
269
+ Cancel a running schedualed task.
270
+
271
+ Args:
272
+ url (str): Base url of csm server. ex. https://servername:port/CSM/web.
273
+ tk (str): Rest token for the CSM server.
274
+ taskid (str): ID of the schedule task to cancel.
275
+
276
+ Returns:
277
+ JSON String representing the result of the command.
278
+ 'I' = successful, 'W' = warning, 'E' = error.
279
+ """
280
+ cancel_task_url = f"{url}/sessions/scheduledtasks/cancel/{taskid}"
281
+
282
+ headers = {
283
+ "Accept-Language": properties["language"],
284
+ "X-Auth-Token": str(tk),
285
+ "Content-Type": "application/x-www-form-urlencoded"
286
+ }
287
+ return requests.post(cancel_task_url, headers=headers, verify=properties["verify"], cert=properties["cert"])
288
+
289
+
290
+ def run_task_now(url, tk, taskid, synchronous=False, step=0):
291
+ """
292
+ Run a scheduled task immediately at a specific step.
293
+
294
+ Args:
295
+ url (str): Base url of csm server. ex. https://servername:port/CSM/web.
296
+ tk (str): Rest token for the CSM server.
297
+ taskid (int/str): ID of the schedule task to run.
298
+ synchronous (bool): Whether to wait for the task to complete.
299
+ step (int): The specific step number to start from.
300
+
301
+ Returns:
302
+ Response object representing the result of the command.
303
+ """
304
+
305
+ # Updated to match @Path("/scheduledtasks/{taskid}/{synchronous}/step/{step}")
306
+ run_task_now_url = f"{url}/scheduledtasks/{taskid}/{str(synchronous).lower()}/step/{step}"
307
+
308
+ headers = {
309
+ "Accept-Language": properties["language"],
310
+ "X-Auth-Token": str(tk),
311
+ "Content-Type": "application/json"
312
+ }
313
+
314
+ return requests.post(run_task_now_url, headers=headers, verify=properties["verify"], cert=properties["cert"])
@@ -181,28 +181,6 @@ def get_available_commands(url, tk, name):
181
181
  return requests.get(getc_url, headers=headers, verify=properties["verify"], cert=properties["cert"])
182
182
 
183
183
 
184
- def get_session_options(url, tk, name):
185
- """
186
- Gets the options for the given session. The results returned
187
- from this method will vary depending on the session type.
188
-
189
- Args:
190
- url (str): Base url of CSM server. ex. https://servername:port/CSM/web.
191
- tk (str): Rest token for the CSM server.
192
- name (str): The name of the session.
193
-
194
- Returns:
195
- JSON String representing the result of the command.
196
- """
197
- geto_url = f"{url}/sessions/{name}/options"
198
- headers = {
199
- "Accept-Language": properties["language"],
200
- "X-Auth-Token": str(tk),
201
- "Content-Type": "application/x-www-form-urlencoded"
202
- }
203
- return requests.get(geto_url, headers=headers, verify=properties["verify"], cert=properties["cert"])
204
-
205
-
206
184
  def modify_session_description(url, tk, name, desc):
207
185
  """
208
186
  Changes the description field for a given session.
@@ -273,7 +251,7 @@ def wait_for_state(url, tk, ses_name, state, minutes=5, debug=False):
273
251
  and "session_info": JSON string representing the response of the command
274
252
  """
275
253
  start_time = datetime.utcnow()
276
- resp = get_session_info(url, tk, ses_name, verify=properties["verify"], cert=properties["cert"])
254
+ resp = get_session_info(url, tk, ses_name)
277
255
  time_passed = (datetime.utcnow() - start_time).total_seconds()
278
256
  while str(json.loads(resp.text)['state']) != state \
279
257
  and time_passed < minutes * 60:
@@ -617,3 +595,72 @@ def get_rolepair_info(url, tk, name, rolepair):
617
595
  "Content-Type": "application/x-www-form-urlencoded"
618
596
  }
619
597
  return requests.get(get_url, headers=headers, verify=properties["verify"], cert=properties["cert"])
598
+
599
+ def get_session_options(url, tk, name):
600
+ """
601
+ Gets the options for the given session. The results returned from this method will vary depending on the session type.
602
+
603
+ Args:
604
+ url (str): Base url of CSM server. ex. https://servername:port/CSM/web.
605
+ tk (str): Rest token for the CSM server.
606
+ name (str): The name of the session.
607
+
608
+ Returns:
609
+ JSON String representing the result of the command.
610
+ """
611
+ get_url = f"{url}/sessions/{name}/options"
612
+
613
+ headers = {
614
+ "Accept-Language": properties["language"],
615
+ "X-Auth-Token": str(tk),
616
+ "Content-Type": "application/json"
617
+ }
618
+
619
+ return requests.get(get_url, headers=headers, verify=properties["verify"], cert=properties.get("cert"))
620
+
621
+ def set_session_options(url, tk, name, options_str):
622
+ """
623
+ Sets Options for a given session.Call getOptions to get a list of the valid options for a session. The "type" field returned by getOptions is the name of the option to use in this restcall.
624
+
625
+ Args:
626
+ url (str): Base url of CSM server. ex. https://servername:port/CSM/web.
627
+ tk (str): Rest token for the CSM server.
628
+ name (str): The name of the session.
629
+ options (dict): JSON-serializable dictionary of options to set for the session.
630
+
631
+ Returns:
632
+ JSON String representing the result of the command.
633
+
634
+ """
635
+ set_url = f"{url}/sessions/{name}/options"
636
+ headers = {
637
+ "Accept-Language": properties["language"],
638
+ "X-Auth-Token": str(tk),
639
+ "Content-Type": "application/x-www-form-urlencoded"
640
+ }
641
+
642
+ payload = options_str
643
+ if not isinstance(payload, str):
644
+ if isinstance(payload, dict):
645
+ if isinstance(payload.get("properties"), dict):
646
+ payload["properties"] = [payload["properties"]]
647
+ payload = [payload]
648
+ elif isinstance(payload, list):
649
+ fixed = []
650
+ for opt in payload:
651
+ if isinstance(opt, dict):
652
+ props = opt.get("properties")
653
+ if isinstance(props, dict):
654
+ opt["properties"] = [props]
655
+ fixed.append(opt)
656
+ payload = fixed
657
+ else:
658
+ raise TypeError("options must be str|list|dict")
659
+
660
+ payload = json.dumps(payload)
661
+
662
+ params = {"options": payload}
663
+ return requests.put( set_url, headers=headers,data=params, verify=properties["verify"],cert=properties["cert"])
664
+
665
+
666
+