python-rundeck 1.1.0__tar.gz → 2.0.0__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.
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/PKG-INFO +42 -26
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/README.md +40 -24
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/pyproject.toml +2 -2
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/client.py +6 -2
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/const.py +2 -2
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/exceptions.py +1 -1
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/v1/objects/acl.py +7 -2
- python_rundeck-2.0.0/src/rundeck/v1/objects/authorizations.py +45 -0
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/v1/objects/jobs.py +26 -13
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/v1/objects/metrics.py +4 -0
- python_rundeck-2.0.0/src/rundeck/v1/objects/project_plugins.py +29 -0
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/v1/objects/projects.py +27 -3
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/v1/objects/scheduler.py +16 -7
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/v1/objects/system.py +7 -1
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/v1/objects/tokens.py +4 -0
- python_rundeck-1.1.0/src/rundeck/v1/objects/config_management.py +0 -64
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/LICENSE +0 -0
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/__init__.py +0 -0
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/base.py +0 -0
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/config.py +0 -0
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/py.typed +0 -0
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/utils.py +0 -0
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/v1/__init__.py +0 -0
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/v1/objects/__init__.py +0 -0
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/v1/objects/adhoc.py +0 -0
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/v1/objects/executions.py +0 -0
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/v1/objects/features.py +0 -0
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/v1/objects/key_storage.py +0 -0
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/v1/objects/plugins.py +0 -0
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/v1/objects/scm.py +0 -0
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/v1/objects/users.py +0 -0
- {python_rundeck-1.1.0 → python_rundeck-2.0.0}/src/rundeck/v1/objects/webhooks.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-rundeck
|
|
3
|
-
Version:
|
|
4
|
-
Summary: Python client for the Rundeck API (v14-
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: Python client for the Rundeck Community API (v14-v59).
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Keywords: rundeck,api,client
|
|
@@ -43,7 +43,9 @@ python-rundeck
|
|
|
43
43
|

|
|
44
44
|

|
|
45
45
|
|
|
46
|
-
Python client for the Rundeck API (v14-
|
|
46
|
+
Python client for the Rundeck Community API (v14-v59), inspired by the python-gitlab architecture. The default API version is v59; current Rundeck servers require v17 or later and versions below v34 are deprecated. Provides typed managers for Community resources (projects, jobs, executions, tokens, users, system) and SCM (import/export).
|
|
47
|
+
|
|
48
|
+
Version 2.0 removes commercial-only Config Management and job-tag endpoints. Cluster schedule listing and takeover are Community operations and remain available. The authorization-evaluation endpoints are experimental in Rundeck and are exposed as such by this client.
|
|
47
49
|
|
|
48
50
|
Contents
|
|
49
51
|
--------
|
|
@@ -69,9 +71,9 @@ Quick start
|
|
|
69
71
|
```python
|
|
70
72
|
from rundeck.client import Rundeck
|
|
71
73
|
|
|
72
|
-
rd = Rundeck(url="https://rundeck.example.com", token="MY_TOKEN"
|
|
74
|
+
rd = Rundeck(url="https://rundeck.example.com", token="MY_TOKEN")
|
|
73
75
|
# Password auth (session cookie) if no token
|
|
74
|
-
rd = Rundeck(url="https://rundeck.example.com", username="admin", password="admin"
|
|
76
|
+
rd = Rundeck(url="https://rundeck.example.com", username="admin", password="admin")
|
|
75
77
|
|
|
76
78
|
# List projects
|
|
77
79
|
projects = rd.projects.list()
|
|
@@ -94,7 +96,7 @@ Main parameters:
|
|
|
94
96
|
- `url`: Rundeck URL (e.g. `https://rundeck.example.com`)
|
|
95
97
|
- `token`: API token (header `X-Rundeck-Auth-Token`)
|
|
96
98
|
- `username` / `password`: Session authentication (j_security_check) if no token is provided.
|
|
97
|
-
- `api_version`: API version (default: `
|
|
99
|
+
- `api_version`: API version (default: `59`; older versions can be selected explicitly)
|
|
98
100
|
- `timeout`: Request timeout (float, seconds)
|
|
99
101
|
- `ssl_verify`: TLS verification (bool or CA path)
|
|
100
102
|
- `user_agent`: Custom HTTP User-Agent (string)
|
|
@@ -105,7 +107,7 @@ Useful env vars (client config):
|
|
|
105
107
|
- `RUNDECK_URL`: Base URL
|
|
106
108
|
- `RUNDECK_TOKEN`: API token (header `X-Rundeck-Auth-Token`)
|
|
107
109
|
- `RUNDECK_USERNAME` / `RUNDECK_PASSWORD`: Session auth (if no token)
|
|
108
|
-
- `RUNDECK_API_VERSION`: API version (
|
|
110
|
+
- `RUNDECK_API_VERSION`: API version (default `59`; older server versions can be selected explicitly)
|
|
109
111
|
- `RUNDECK_TIMEOUT`: Request timeout (seconds)
|
|
110
112
|
- `RUNDECK_SSL_VERIFY`: TLS verification (bool or CA path)
|
|
111
113
|
- `RUNDECK_USER_AGENT`: HTTP User-Agent
|
|
@@ -120,14 +122,14 @@ Available resources
|
|
|
120
122
|
- `tokens` (`TokenManager`): list, get, create, delete.
|
|
121
123
|
- `users` (`UserManager`): user operations (per current implementation).
|
|
122
124
|
- `metrics` (`MetricsManager`): legacy `/api/V/metrics` endpoints (list/data/healthcheck/ping/threads).
|
|
123
|
-
- `monitoring` (`MonitoringManager`): modern non-versioned `/monitoring/*` endpoints (Prometheus, metrics, health, info, thread dump).
|
|
125
|
+
- `monitoring` (`MonitoringManager`): modern non-versioned `/monitoring/*` endpoints (Prometheus, metrics, health, readiness, info, thread dump).
|
|
126
|
+
- `authorizations` (`AuthorizationsManager`): experimental authorization evaluation endpoints.
|
|
124
127
|
- `plugins` (`PluginManager`): list installed plugins (`/plugin/list`).
|
|
125
128
|
- `webhooks` (`WebhookEventManager` + `ProjectWebhookManager`): project webhook management and sending via token.
|
|
126
129
|
- `key_storage` (`StorageKeyManager`): key storage management `/storage/keys`.
|
|
127
130
|
- `adhoc` (`AdhocManager`, via `project.adhoc`): run AdHoc commands/scripts.
|
|
128
|
-
- `system` (`SystemManager`): system info, executions enable/disable, logstorage, ACL.
|
|
129
|
-
- `
|
|
130
|
-
- `scheduler` (`SchedulerManager`): cluster scheduler takeover (commercial, deprecated and scheduled for removal in 2.0).
|
|
131
|
+
- `system` (`SystemManager`): system info and summary, executions enable/disable, logstorage, ACL.
|
|
132
|
+
- `scheduler` (`SchedulerManager`): scheduled job listing and cluster schedule takeover (Community).
|
|
131
133
|
- `scm` (via `project.scm` and `job.scm`): import/export plugins, setup, enable/disable, status, actions (commit/import/export...).
|
|
132
134
|
|
|
133
135
|
Return types policy
|
|
@@ -148,7 +150,7 @@ Factory managers:
|
|
|
148
150
|
Returns `Execution` objects (execution factory).
|
|
149
151
|
|
|
150
152
|
Utility managers:
|
|
151
|
-
- `system`, `
|
|
153
|
+
- `system`, `metrics`, `scheduler`, `webhooks` (event send), `authorizations` (experimental).
|
|
152
154
|
- `scm` (via `project.scm` and `job.scm`), and project sub-managers like
|
|
153
155
|
`project.config`, `project.resources`, `project.sources`, `project.readme`,
|
|
154
156
|
`project.archive`, `project.acl`.
|
|
@@ -156,6 +158,13 @@ Utility managers:
|
|
|
156
158
|
Note: `project.webhooks.create(...)` returns the raw API response (e.g., `{"msg": "Saved webhook"}`)
|
|
157
159
|
because the Rundeck API does not return the created webhook object.
|
|
158
160
|
|
|
161
|
+
Migration from 1.1.0
|
|
162
|
+
-------------------
|
|
163
|
+
- Set `api_version=59` explicitly when upgrading a server/client pair gradually; the default is now 59.
|
|
164
|
+
- Remove calls to `rd.config_management` and `job.tags()`: their endpoints are only available in commercial Rundeck products.
|
|
165
|
+
- `rd.scheduler.takeover()` and scheduler job listing remain supported by Community. On a non-cluster server, takeover returns a successful response indicating that no action was performed.
|
|
166
|
+
- `rd.authorizations` wraps experimental endpoints and can change with Rundeck releases.
|
|
167
|
+
|
|
159
168
|
Example:
|
|
160
169
|
```python
|
|
161
170
|
job = rd.jobs.get("job-id") # -> Job (object)
|
|
@@ -468,17 +477,6 @@ if features:
|
|
|
468
477
|
print(first.name, status.enabled)
|
|
469
478
|
```
|
|
470
479
|
|
|
471
|
-
Global configuration `/config`
|
|
472
|
-
```python
|
|
473
|
-
# Commercial compatibility surface; deprecated and removed in 2.0.
|
|
474
|
-
cfg = rd.config_management
|
|
475
|
-
all_configs = cfg.list()
|
|
476
|
-
cfg.save([{"key": "ui.banner", "value": "Hello"}])
|
|
477
|
-
cfg.delete("ui.banner", strata="default")
|
|
478
|
-
cfg.refresh()
|
|
479
|
-
cfg.restart()
|
|
480
|
-
```
|
|
481
|
-
|
|
482
480
|
Monitoring
|
|
483
481
|
----------
|
|
484
482
|
```python
|
|
@@ -490,6 +488,24 @@ thread_dump = rd.monitoring.thread_dump()
|
|
|
490
488
|
|
|
491
489
|
# Legacy metrics require rundeck.metrics.legacy.enabled=true on Rundeck 6.0.
|
|
492
490
|
legacy_threads = rd.metrics.threads()
|
|
491
|
+
ready = rd.monitoring.readiness()
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
Community additions
|
|
495
|
+
-------------------
|
|
496
|
+
```python
|
|
497
|
+
api_info = rd.api_info()
|
|
498
|
+
summary = rd.system.summary()
|
|
499
|
+
scheduled_jobs = rd.scheduler.jobs()
|
|
500
|
+
rd.tokens.remove_expired("admin") # use "*" with suitable administrator rights
|
|
501
|
+
|
|
502
|
+
project = rd.projects.get("demo")
|
|
503
|
+
project.plugins.save("ResourceModelSource", "resources.source", plugins=[])
|
|
504
|
+
project.archive.export_async(execution_ids=["1", "2"], use_post=True)
|
|
505
|
+
project.jobs.validate_option(option_data, job_was_scheduled=False)
|
|
506
|
+
|
|
507
|
+
# Experimental authorization API; actions are repeated query parameters.
|
|
508
|
+
permissions = rd.authorizations.application_kind("job", ["read", "run"])
|
|
493
509
|
```
|
|
494
510
|
|
|
495
511
|
Pagination
|
|
@@ -510,13 +526,13 @@ Development and testing
|
|
|
510
526
|
- Formatting/Lint: `black src/rundeck tests/`, `ruff check src/rundeck tests/`
|
|
511
527
|
- Typing: `mypy src/rundeck/`
|
|
512
528
|
- Tests: `pytest`
|
|
513
|
-
- Local integration tests: `scripts/run-integration.sh` starts Rundeck Community 6.
|
|
529
|
+
- Local integration tests: `scripts/run-integration.sh` starts Rundeck Community 6.2.1 by default with API v59. Use `RUNDECK_IMAGE=rundeck/rundeck:6.0.1 RUNDECK_API_VERSION=58` or `RUNDECK_IMAGE=rundeck/rundeck:5.18.0 RUNDECK_API_VERSION=56` for compatibility runs. Add `KEEP_STACK=1` to keep the instance running after tests. Dedicated teardown script: `scripts/stop-integration.sh`.
|
|
514
530
|
- The docker compose stack mounts `tokens.properties` at the repo root to seed a local admin token for integration tests. This file is only intended for local testing.
|
|
515
531
|
|
|
516
532
|
Code structure
|
|
517
533
|
--------------
|
|
518
534
|
- `src/rundeck/base.py`: generic objects/managers, `_build_path` helpers, pagination, CRUD.
|
|
519
535
|
- `src/rundeck/client.py`: HTTP client, `http_get/post/put/delete/list` methods.
|
|
520
|
-
- `src/rundeck/v1/objects/`: domain managers and objects (projects, jobs, executions, system, tokens, users,
|
|
521
|
-
- Managers/objects schema: we apply the manager -> object pattern wherever the API exposes an identifiable resource (jobs, projects, users, tokens, executions, etc.). For
|
|
536
|
+
- `src/rundeck/v1/objects/`: Community domain managers and objects (projects, jobs, executions, system, tokens, users, authorizations).
|
|
537
|
+
- Managers/objects schema: we apply the manager -> object pattern wherever the API exposes an identifiable resource (jobs, projects, users, tokens, executions, etc.). For global or utility endpoints without a resource (e.g., `/system`, `/scheduler`, `/metrics`), we use dedicated sub-managers rather than forcing an artificial object.
|
|
522
538
|
|
|
@@ -5,7 +5,9 @@ python-rundeck
|
|
|
5
5
|

|
|
6
6
|

|
|
7
7
|
|
|
8
|
-
Python client for the Rundeck API (v14-
|
|
8
|
+
Python client for the Rundeck Community API (v14-v59), inspired by the python-gitlab architecture. The default API version is v59; current Rundeck servers require v17 or later and versions below v34 are deprecated. Provides typed managers for Community resources (projects, jobs, executions, tokens, users, system) and SCM (import/export).
|
|
9
|
+
|
|
10
|
+
Version 2.0 removes commercial-only Config Management and job-tag endpoints. Cluster schedule listing and takeover are Community operations and remain available. The authorization-evaluation endpoints are experimental in Rundeck and are exposed as such by this client.
|
|
9
11
|
|
|
10
12
|
Contents
|
|
11
13
|
--------
|
|
@@ -31,9 +33,9 @@ Quick start
|
|
|
31
33
|
```python
|
|
32
34
|
from rundeck.client import Rundeck
|
|
33
35
|
|
|
34
|
-
rd = Rundeck(url="https://rundeck.example.com", token="MY_TOKEN"
|
|
36
|
+
rd = Rundeck(url="https://rundeck.example.com", token="MY_TOKEN")
|
|
35
37
|
# Password auth (session cookie) if no token
|
|
36
|
-
rd = Rundeck(url="https://rundeck.example.com", username="admin", password="admin"
|
|
38
|
+
rd = Rundeck(url="https://rundeck.example.com", username="admin", password="admin")
|
|
37
39
|
|
|
38
40
|
# List projects
|
|
39
41
|
projects = rd.projects.list()
|
|
@@ -56,7 +58,7 @@ Main parameters:
|
|
|
56
58
|
- `url`: Rundeck URL (e.g. `https://rundeck.example.com`)
|
|
57
59
|
- `token`: API token (header `X-Rundeck-Auth-Token`)
|
|
58
60
|
- `username` / `password`: Session authentication (j_security_check) if no token is provided.
|
|
59
|
-
- `api_version`: API version (default: `
|
|
61
|
+
- `api_version`: API version (default: `59`; older versions can be selected explicitly)
|
|
60
62
|
- `timeout`: Request timeout (float, seconds)
|
|
61
63
|
- `ssl_verify`: TLS verification (bool or CA path)
|
|
62
64
|
- `user_agent`: Custom HTTP User-Agent (string)
|
|
@@ -67,7 +69,7 @@ Useful env vars (client config):
|
|
|
67
69
|
- `RUNDECK_URL`: Base URL
|
|
68
70
|
- `RUNDECK_TOKEN`: API token (header `X-Rundeck-Auth-Token`)
|
|
69
71
|
- `RUNDECK_USERNAME` / `RUNDECK_PASSWORD`: Session auth (if no token)
|
|
70
|
-
- `RUNDECK_API_VERSION`: API version (
|
|
72
|
+
- `RUNDECK_API_VERSION`: API version (default `59`; older server versions can be selected explicitly)
|
|
71
73
|
- `RUNDECK_TIMEOUT`: Request timeout (seconds)
|
|
72
74
|
- `RUNDECK_SSL_VERIFY`: TLS verification (bool or CA path)
|
|
73
75
|
- `RUNDECK_USER_AGENT`: HTTP User-Agent
|
|
@@ -82,14 +84,14 @@ Available resources
|
|
|
82
84
|
- `tokens` (`TokenManager`): list, get, create, delete.
|
|
83
85
|
- `users` (`UserManager`): user operations (per current implementation).
|
|
84
86
|
- `metrics` (`MetricsManager`): legacy `/api/V/metrics` endpoints (list/data/healthcheck/ping/threads).
|
|
85
|
-
- `monitoring` (`MonitoringManager`): modern non-versioned `/monitoring/*` endpoints (Prometheus, metrics, health, info, thread dump).
|
|
87
|
+
- `monitoring` (`MonitoringManager`): modern non-versioned `/monitoring/*` endpoints (Prometheus, metrics, health, readiness, info, thread dump).
|
|
88
|
+
- `authorizations` (`AuthorizationsManager`): experimental authorization evaluation endpoints.
|
|
86
89
|
- `plugins` (`PluginManager`): list installed plugins (`/plugin/list`).
|
|
87
90
|
- `webhooks` (`WebhookEventManager` + `ProjectWebhookManager`): project webhook management and sending via token.
|
|
88
91
|
- `key_storage` (`StorageKeyManager`): key storage management `/storage/keys`.
|
|
89
92
|
- `adhoc` (`AdhocManager`, via `project.adhoc`): run AdHoc commands/scripts.
|
|
90
|
-
- `system` (`SystemManager`): system info, executions enable/disable, logstorage, ACL.
|
|
91
|
-
- `
|
|
92
|
-
- `scheduler` (`SchedulerManager`): cluster scheduler takeover (commercial, deprecated and scheduled for removal in 2.0).
|
|
93
|
+
- `system` (`SystemManager`): system info and summary, executions enable/disable, logstorage, ACL.
|
|
94
|
+
- `scheduler` (`SchedulerManager`): scheduled job listing and cluster schedule takeover (Community).
|
|
93
95
|
- `scm` (via `project.scm` and `job.scm`): import/export plugins, setup, enable/disable, status, actions (commit/import/export...).
|
|
94
96
|
|
|
95
97
|
Return types policy
|
|
@@ -110,7 +112,7 @@ Factory managers:
|
|
|
110
112
|
Returns `Execution` objects (execution factory).
|
|
111
113
|
|
|
112
114
|
Utility managers:
|
|
113
|
-
- `system`, `
|
|
115
|
+
- `system`, `metrics`, `scheduler`, `webhooks` (event send), `authorizations` (experimental).
|
|
114
116
|
- `scm` (via `project.scm` and `job.scm`), and project sub-managers like
|
|
115
117
|
`project.config`, `project.resources`, `project.sources`, `project.readme`,
|
|
116
118
|
`project.archive`, `project.acl`.
|
|
@@ -118,6 +120,13 @@ Utility managers:
|
|
|
118
120
|
Note: `project.webhooks.create(...)` returns the raw API response (e.g., `{"msg": "Saved webhook"}`)
|
|
119
121
|
because the Rundeck API does not return the created webhook object.
|
|
120
122
|
|
|
123
|
+
Migration from 1.1.0
|
|
124
|
+
-------------------
|
|
125
|
+
- Set `api_version=59` explicitly when upgrading a server/client pair gradually; the default is now 59.
|
|
126
|
+
- Remove calls to `rd.config_management` and `job.tags()`: their endpoints are only available in commercial Rundeck products.
|
|
127
|
+
- `rd.scheduler.takeover()` and scheduler job listing remain supported by Community. On a non-cluster server, takeover returns a successful response indicating that no action was performed.
|
|
128
|
+
- `rd.authorizations` wraps experimental endpoints and can change with Rundeck releases.
|
|
129
|
+
|
|
121
130
|
Example:
|
|
122
131
|
```python
|
|
123
132
|
job = rd.jobs.get("job-id") # -> Job (object)
|
|
@@ -430,17 +439,6 @@ if features:
|
|
|
430
439
|
print(first.name, status.enabled)
|
|
431
440
|
```
|
|
432
441
|
|
|
433
|
-
Global configuration `/config`
|
|
434
|
-
```python
|
|
435
|
-
# Commercial compatibility surface; deprecated and removed in 2.0.
|
|
436
|
-
cfg = rd.config_management
|
|
437
|
-
all_configs = cfg.list()
|
|
438
|
-
cfg.save([{"key": "ui.banner", "value": "Hello"}])
|
|
439
|
-
cfg.delete("ui.banner", strata="default")
|
|
440
|
-
cfg.refresh()
|
|
441
|
-
cfg.restart()
|
|
442
|
-
```
|
|
443
|
-
|
|
444
442
|
Monitoring
|
|
445
443
|
----------
|
|
446
444
|
```python
|
|
@@ -452,6 +450,24 @@ thread_dump = rd.monitoring.thread_dump()
|
|
|
452
450
|
|
|
453
451
|
# Legacy metrics require rundeck.metrics.legacy.enabled=true on Rundeck 6.0.
|
|
454
452
|
legacy_threads = rd.metrics.threads()
|
|
453
|
+
ready = rd.monitoring.readiness()
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
Community additions
|
|
457
|
+
-------------------
|
|
458
|
+
```python
|
|
459
|
+
api_info = rd.api_info()
|
|
460
|
+
summary = rd.system.summary()
|
|
461
|
+
scheduled_jobs = rd.scheduler.jobs()
|
|
462
|
+
rd.tokens.remove_expired("admin") # use "*" with suitable administrator rights
|
|
463
|
+
|
|
464
|
+
project = rd.projects.get("demo")
|
|
465
|
+
project.plugins.save("ResourceModelSource", "resources.source", plugins=[])
|
|
466
|
+
project.archive.export_async(execution_ids=["1", "2"], use_post=True)
|
|
467
|
+
project.jobs.validate_option(option_data, job_was_scheduled=False)
|
|
468
|
+
|
|
469
|
+
# Experimental authorization API; actions are repeated query parameters.
|
|
470
|
+
permissions = rd.authorizations.application_kind("job", ["read", "run"])
|
|
455
471
|
```
|
|
456
472
|
|
|
457
473
|
Pagination
|
|
@@ -472,12 +488,12 @@ Development and testing
|
|
|
472
488
|
- Formatting/Lint: `black src/rundeck tests/`, `ruff check src/rundeck tests/`
|
|
473
489
|
- Typing: `mypy src/rundeck/`
|
|
474
490
|
- Tests: `pytest`
|
|
475
|
-
- Local integration tests: `scripts/run-integration.sh` starts Rundeck Community 6.
|
|
491
|
+
- Local integration tests: `scripts/run-integration.sh` starts Rundeck Community 6.2.1 by default with API v59. Use `RUNDECK_IMAGE=rundeck/rundeck:6.0.1 RUNDECK_API_VERSION=58` or `RUNDECK_IMAGE=rundeck/rundeck:5.18.0 RUNDECK_API_VERSION=56` for compatibility runs. Add `KEEP_STACK=1` to keep the instance running after tests. Dedicated teardown script: `scripts/stop-integration.sh`.
|
|
476
492
|
- The docker compose stack mounts `tokens.properties` at the repo root to seed a local admin token for integration tests. This file is only intended for local testing.
|
|
477
493
|
|
|
478
494
|
Code structure
|
|
479
495
|
--------------
|
|
480
496
|
- `src/rundeck/base.py`: generic objects/managers, `_build_path` helpers, pagination, CRUD.
|
|
481
497
|
- `src/rundeck/client.py`: HTTP client, `http_get/post/put/delete/list` methods.
|
|
482
|
-
- `src/rundeck/v1/objects/`: domain managers and objects (projects, jobs, executions, system, tokens, users,
|
|
483
|
-
- Managers/objects schema: we apply the manager -> object pattern wherever the API exposes an identifiable resource (jobs, projects, users, tokens, executions, etc.). For
|
|
498
|
+
- `src/rundeck/v1/objects/`: Community domain managers and objects (projects, jobs, executions, system, tokens, users, authorizations).
|
|
499
|
+
- Managers/objects schema: we apply the manager -> object pattern wherever the API exposes an identifiable resource (jobs, projects, users, tokens, executions, etc.). For global or utility endpoints without a resource (e.g., `/system`, `/scheduler`, `/metrics`), we use dedicated sub-managers rather than forcing an artificial object.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "python-rundeck"
|
|
3
|
-
version = "
|
|
4
|
-
description = "Python client for the Rundeck API (v14-
|
|
3
|
+
version = "2.0.0"
|
|
4
|
+
description = "Python client for the Rundeck Community API (v14-v59)."
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "Pascal Seckinger",email = "pascal.seckinger@protonmail.com"}
|
|
7
7
|
]
|
|
@@ -81,7 +81,7 @@ class Rundeck:
|
|
|
81
81
|
def _init_managers(self) -> None:
|
|
82
82
|
"""Initialise les managers d'objets."""
|
|
83
83
|
# Import paresseux pour éviter les boucles d'import.
|
|
84
|
-
from rundeck.v1.objects.
|
|
84
|
+
from rundeck.v1.objects.authorizations import AuthorizationsManager
|
|
85
85
|
from rundeck.v1.objects.executions import ExecutionManager
|
|
86
86
|
from rundeck.v1.objects.features import FeatureManager
|
|
87
87
|
from rundeck.v1.objects.jobs import JobManager
|
|
@@ -98,7 +98,7 @@ class Rundeck:
|
|
|
98
98
|
self.projects = ProjectManager(self)
|
|
99
99
|
self.jobs = JobManager(self)
|
|
100
100
|
self.executions = ExecutionManager(self)
|
|
101
|
-
self.
|
|
101
|
+
self.authorizations = AuthorizationsManager(self)
|
|
102
102
|
self.metrics = MetricsManager(self)
|
|
103
103
|
self.monitoring = MonitoringManager(self)
|
|
104
104
|
self.plugins = PluginManager(self)
|
|
@@ -110,6 +110,10 @@ class Rundeck:
|
|
|
110
110
|
self.tokens = TokenManager(self)
|
|
111
111
|
self.users = UserManager(self)
|
|
112
112
|
|
|
113
|
+
def api_info(self) -> dict[str, Any]:
|
|
114
|
+
"""Récupère les informations de l'API utilisée par ce client."""
|
|
115
|
+
return self.http_get("/")
|
|
116
|
+
|
|
113
117
|
@property
|
|
114
118
|
def url(self) -> str:
|
|
115
119
|
"""URL fournie par l'utilisateur."""
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Constantes partagées pour le client Rundeck.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
import tomllib
|
|
5
6
|
from importlib.metadata import PackageNotFoundError, version
|
|
6
7
|
from pathlib import Path
|
|
7
|
-
import tomllib
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
# Package metadata
|
|
@@ -40,7 +40,7 @@ FORMAT_JSON = "json"
|
|
|
40
40
|
|
|
41
41
|
# API versions. The library remains compatible with legacy Rundeck servers
|
|
42
42
|
# using v14, while current Rundeck servers require at least v17.
|
|
43
|
-
API_VERSION_CURRENT = "
|
|
43
|
+
API_VERSION_CURRENT = "59"
|
|
44
44
|
API_VERSION_MIN = "14"
|
|
45
45
|
API_VERSION_SERVER_MIN = "17"
|
|
46
46
|
API_VERSION_DEPRECATION = "34"
|
|
@@ -131,7 +131,7 @@ def raise_for_status(response: requests.Response) -> None:
|
|
|
131
131
|
raise RundeckAuthenticationError(message, error_code, response)
|
|
132
132
|
if code_lower == "api-version-unsupported":
|
|
133
133
|
raise RundeckApiVersionUnsupportedError(message, error_code, response)
|
|
134
|
-
if status
|
|
134
|
+
if status in (400, 422):
|
|
135
135
|
raise RundeckValidationError(message, error_code, response)
|
|
136
136
|
if status in (401, 403):
|
|
137
137
|
raise RundeckAuthenticationError(message, error_code, response)
|
|
@@ -9,8 +9,13 @@ class YamlPolicyMixin:
|
|
|
9
9
|
_yaml_content_type = "application/yaml"
|
|
10
10
|
|
|
11
11
|
def _yaml_headers(self) -> dict[str, str]:
|
|
12
|
-
headers = build_headers(
|
|
13
|
-
|
|
12
|
+
headers = build_headers(
|
|
13
|
+
accept=self._yaml_content_type, content_type=self._yaml_content_type
|
|
14
|
+
)
|
|
15
|
+
return headers or {
|
|
16
|
+
"Accept": self._yaml_content_type,
|
|
17
|
+
"Content-Type": self._yaml_content_type,
|
|
18
|
+
}
|
|
14
19
|
|
|
15
20
|
def _post_yaml(self, path: str, content: Any) -> Any:
|
|
16
21
|
return self.rd.http_post(path, data=content, headers=self._yaml_headers())
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""Endpoints expérimentaux d'évaluation des autorisations."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from rundeck.base import RundeckObjectManager
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AuthorizationsManager(RundeckObjectManager):
|
|
9
|
+
"""Évalue les droits du sujet courant (API expérimentale)."""
|
|
10
|
+
|
|
11
|
+
_path = "/authorizations"
|
|
12
|
+
|
|
13
|
+
def _check(self, path: str, actions: list[str]) -> Any:
|
|
14
|
+
return self.rd.http_get(path, params={"actions": actions})
|
|
15
|
+
|
|
16
|
+
def application_kind(self, kind: str, actions: list[str]) -> Any:
|
|
17
|
+
"""Vérifie des actions sur un type de ressource de l'application."""
|
|
18
|
+
return self._check(f"/authorizations/application/{kind}", actions)
|
|
19
|
+
|
|
20
|
+
def application_resource(
|
|
21
|
+
self, resource_type: str, specifier: str, actions: list[str]
|
|
22
|
+
) -> Any:
|
|
23
|
+
"""Vérifie des actions sur une ressource de l'application."""
|
|
24
|
+
return self._check(
|
|
25
|
+
f"/authorizations/application/{resource_type}/{specifier}", actions
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
def project_kind(self, project: str, kind: str, actions: list[str]) -> Any:
|
|
29
|
+
"""Vérifie des actions sur un type de ressource du projet."""
|
|
30
|
+
return self._check(f"/authorizations/project/{project}/{kind}", actions)
|
|
31
|
+
|
|
32
|
+
def project_resource(
|
|
33
|
+
self, project: str, resource_type: str, specifier: str, actions: list[str]
|
|
34
|
+
) -> Any:
|
|
35
|
+
"""Vérifie des actions sur une ressource du projet."""
|
|
36
|
+
return self._check(
|
|
37
|
+
f"/authorizations/project/{project}/{resource_type}/{specifier}", actions
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
def project_job(self, project: str, job_id: str, actions: list[str]) -> Any:
|
|
41
|
+
"""Vérifie des actions sur un job du projet."""
|
|
42
|
+
return self._check(f"/authorizations/project/{project}/job/{job_id}", actions)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
__all__ = ["AuthorizationsManager"]
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Gestion des jobs Rundeck
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
import warnings
|
|
6
5
|
from typing import Any, Iterator
|
|
7
6
|
|
|
8
7
|
from rundeck.base import RundeckObject, RundeckObjectManager
|
|
@@ -114,16 +113,6 @@ class Job(RundeckObject):
|
|
|
114
113
|
path = self._job_path("meta")
|
|
115
114
|
return self.rd.http_get(path, params=params or None)
|
|
116
115
|
|
|
117
|
-
def tags(self) -> list[str]:
|
|
118
|
-
"""Retourne les tags du job (commercial, endpoint /job/{id}/tags)."""
|
|
119
|
-
warnings.warn(
|
|
120
|
-
"Job.tags() cible un endpoint commercial et sera retiré en 2.0.",
|
|
121
|
-
DeprecationWarning,
|
|
122
|
-
stacklevel=2,
|
|
123
|
-
)
|
|
124
|
-
path = self._job_path("tags")
|
|
125
|
-
return self.rd.http_get(path)
|
|
126
|
-
|
|
127
116
|
def executions(
|
|
128
117
|
self,
|
|
129
118
|
status: str | None = None,
|
|
@@ -327,18 +316,42 @@ class JobManager(RundeckObjectManager[Job]):
|
|
|
327
316
|
meta: str | None = None,
|
|
328
317
|
meta_exclude: str | None = None,
|
|
329
318
|
breakpoint: int | None = None,
|
|
319
|
+
use_post: bool = False,
|
|
330
320
|
**filters: Any,
|
|
331
321
|
) -> dict[str, Any]:
|
|
332
322
|
"""Parcourt un groupe de jobs et ses sous-groupes (API v46+)."""
|
|
333
323
|
project_path = self._project_path(project)
|
|
334
|
-
|
|
324
|
+
query = compact(meta=meta, metaExclude=meta_exclude, breakpoint=breakpoint)
|
|
325
|
+
browse_path = f"{project_path}/browse"
|
|
326
|
+
if use_post:
|
|
327
|
+
if path is not None:
|
|
328
|
+
query["path"] = path
|
|
329
|
+
return self.rd.http_post(browse_path, params=query or None, json=filters)
|
|
330
|
+
query = compact(
|
|
335
331
|
filters,
|
|
336
332
|
path=path,
|
|
337
333
|
meta=meta,
|
|
338
334
|
metaExclude=meta_exclude,
|
|
339
335
|
breakpoint=breakpoint,
|
|
340
336
|
)
|
|
341
|
-
return self.rd.http_get(
|
|
337
|
+
return self.rd.http_get(browse_path, params=query or None)
|
|
338
|
+
|
|
339
|
+
def validate_option(
|
|
340
|
+
self,
|
|
341
|
+
option_data: dict[str, Any],
|
|
342
|
+
*,
|
|
343
|
+
job_was_scheduled: bool,
|
|
344
|
+
project: str | None = None,
|
|
345
|
+
) -> Any:
|
|
346
|
+
"""Valide une option de job (API v47+)."""
|
|
347
|
+
project_name = project or (self.parent.id if self.parent else None)
|
|
348
|
+
if not project_name:
|
|
349
|
+
raise ValueError("Le paramètre project est requis")
|
|
350
|
+
return self.rd.http_post(
|
|
351
|
+
f"/project/{project_name}/jobs/validateOption",
|
|
352
|
+
params={"jobWasScheduled": job_was_scheduled},
|
|
353
|
+
json=option_data,
|
|
354
|
+
)
|
|
342
355
|
|
|
343
356
|
def get(self, id: str) -> "Job":
|
|
344
357
|
"""Récupère un job par identifiant."""
|
|
@@ -65,6 +65,10 @@ class MonitoringManager(RundeckObjectManager):
|
|
|
65
65
|
"""Récupère l'état de santé de l'application."""
|
|
66
66
|
return self.rd.http_get(self._monitoring_path("health"))
|
|
67
67
|
|
|
68
|
+
def readiness(self) -> dict[str, Any]:
|
|
69
|
+
"""Récupère l'état de disponibilité pour les sondes de readiness."""
|
|
70
|
+
return self.rd.http_get(self._monitoring_path("health/readiness"))
|
|
71
|
+
|
|
68
72
|
def info(self) -> dict[str, Any]:
|
|
69
73
|
"""Récupère les informations applicatives."""
|
|
70
74
|
return self.rd.http_get(self._monitoring_path("info"))
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Configuration des plugins au niveau d'un projet."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from rundeck.base import RundeckObjectManager
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ProjectPluginsManager(RundeckObjectManager):
|
|
9
|
+
"""Sauvegarde les configurations de plugins d'un projet (API v55+)."""
|
|
10
|
+
|
|
11
|
+
_path = "/project/{parent}/plugins"
|
|
12
|
+
|
|
13
|
+
def save(
|
|
14
|
+
self,
|
|
15
|
+
service_name: str,
|
|
16
|
+
config_prefix: str,
|
|
17
|
+
plugins: list[dict[str, Any]],
|
|
18
|
+
removed_plugins: list[dict[str, Any]] | None = None,
|
|
19
|
+
) -> Any:
|
|
20
|
+
"""Crée, modifie ou retire des configurations de plugins projet."""
|
|
21
|
+
path = self._build_path("save")
|
|
22
|
+
return self.rd.http_post(
|
|
23
|
+
path,
|
|
24
|
+
params={"serviceName": service_name, "configPrefix": config_prefix},
|
|
25
|
+
json={"plugins": plugins, "removedPlugins": removed_plugins or []},
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
__all__ = ["ProjectPluginsManager"]
|
|
@@ -10,6 +10,7 @@ from rundeck.v1.objects.acl import YamlPolicyMixin
|
|
|
10
10
|
from rundeck.v1.objects.adhoc import AdhocManager
|
|
11
11
|
from rundeck.v1.objects.executions import ExecutionManager
|
|
12
12
|
from rundeck.v1.objects.jobs import JobManager
|
|
13
|
+
from rundeck.v1.objects.project_plugins import ProjectPluginsManager
|
|
13
14
|
from rundeck.v1.objects.scm import ProjectSCMManager
|
|
14
15
|
from rundeck.v1.objects.webhooks import ProjectWebhookManager
|
|
15
16
|
|
|
@@ -65,6 +66,11 @@ class Project(RundeckObject):
|
|
|
65
66
|
"""Accès aux opérations SCM du projet (import/export)."""
|
|
66
67
|
return ProjectSCMManager(self.rd, parent=self)
|
|
67
68
|
|
|
69
|
+
@property
|
|
70
|
+
def plugins(self) -> ProjectPluginsManager:
|
|
71
|
+
"""Accès à la configuration des plugins du projet."""
|
|
72
|
+
return ProjectPluginsManager(self.rd, parent=self)
|
|
73
|
+
|
|
68
74
|
@property
|
|
69
75
|
def webhooks(self) -> ProjectWebhookManager:
|
|
70
76
|
"""Accès aux webhooks du projet."""
|
|
@@ -187,7 +193,9 @@ class ProjectACLManager(YamlPolicyMixin, RundeckObjectManager):
|
|
|
187
193
|
def get(self, policy_name: str) -> str:
|
|
188
194
|
"""Récupère une politique ACL projet (contenu texte)."""
|
|
189
195
|
path = self._build_path(policy_name)
|
|
190
|
-
response = self.rd.http_get(
|
|
196
|
+
response = self.rd.http_get(
|
|
197
|
+
path, raw=True, headers={"Accept": "application/yaml"}
|
|
198
|
+
)
|
|
191
199
|
return response.text
|
|
192
200
|
|
|
193
201
|
def create(self, policy_name: str, content: str) -> dict[str, Any]:
|
|
@@ -429,9 +437,25 @@ class ProjectArchiveManager(RundeckObjectManager):
|
|
|
429
437
|
)
|
|
430
438
|
return self.rd.http_get(path, params=params or None, raw=True)
|
|
431
439
|
|
|
432
|
-
def export_async(
|
|
433
|
-
|
|
440
|
+
def export_async(
|
|
441
|
+
self,
|
|
442
|
+
*,
|
|
443
|
+
execution_ids: list[str] | None = None,
|
|
444
|
+
use_post: bool = False,
|
|
445
|
+
**params: Any,
|
|
446
|
+
) -> Any:
|
|
447
|
+
"""Lance une export async, en POST pour les longues listes d'IDs."""
|
|
434
448
|
path = self._build_path("export/async")
|
|
449
|
+
if use_post:
|
|
450
|
+
form = {"executionIds": execution_ids} if execution_ids else None
|
|
451
|
+
return self.rd.http_post(
|
|
452
|
+
path,
|
|
453
|
+
params=params or None,
|
|
454
|
+
data=form,
|
|
455
|
+
headers=build_headers(content_type="application/x-www-form-urlencoded"),
|
|
456
|
+
)
|
|
457
|
+
if execution_ids:
|
|
458
|
+
params["executionIds"] = execution_ids
|
|
435
459
|
return self.rd.http_get(path, params=params or None)
|
|
436
460
|
|
|
437
461
|
def export_status(self, token: str) -> Any:
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Gestion des endpoints /scheduler
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
import warnings
|
|
6
5
|
from typing import Any
|
|
7
6
|
|
|
8
7
|
from rundeck.base import RundeckObjectManager
|
|
@@ -20,24 +19,24 @@ class SchedulerManager(RundeckObjectManager):
|
|
|
20
19
|
all_servers: bool = False,
|
|
21
20
|
project: str | None = None,
|
|
22
21
|
job_id: str | None = None,
|
|
22
|
+
job_ids: list[str] | None = None,
|
|
23
23
|
) -> dict[str, Any]:
|
|
24
24
|
"""
|
|
25
|
-
Reprend le planning des jobs
|
|
25
|
+
Reprend le planning des jobs. Sur un serveur sans mode cluster,
|
|
26
|
+
l'API est disponible, mais aucun planning distant n'est transféré.
|
|
26
27
|
|
|
27
28
|
Args:
|
|
28
29
|
server_uuid: UUID du serveur cible.
|
|
29
30
|
all_servers: True pour reprendre tous les serveurs.
|
|
30
31
|
project: Projet concerné (optionnel).
|
|
31
32
|
job_id: Job spécifique (optionnel).
|
|
33
|
+
job_ids: Liste de jobs (exclusif avec job_id).
|
|
32
34
|
|
|
33
35
|
Returns:
|
|
34
36
|
Résultat de la reprise.
|
|
35
37
|
"""
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
DeprecationWarning,
|
|
39
|
-
stacklevel=2,
|
|
40
|
-
)
|
|
38
|
+
if job_id is not None and job_ids is not None:
|
|
39
|
+
raise ValueError("job_id et job_ids ne peuvent pas être utilisés ensemble")
|
|
41
40
|
path = self._build_path("takeover")
|
|
42
41
|
|
|
43
42
|
server = None
|
|
@@ -50,9 +49,19 @@ class SchedulerManager(RundeckObjectManager):
|
|
|
50
49
|
server=server,
|
|
51
50
|
project=project if project else None,
|
|
52
51
|
job={"id": job_id} if job_id else None,
|
|
52
|
+
jobs=[{"id": item} for item in job_ids] if job_ids else None,
|
|
53
53
|
)
|
|
54
54
|
|
|
55
55
|
return self.rd.http_put(path, json=data)
|
|
56
56
|
|
|
57
|
+
def jobs(self, server_uuid: str | None = None) -> Any:
|
|
58
|
+
"""Liste les jobs planifiés sur le serveur courant ou le serveur donné."""
|
|
59
|
+
path = (
|
|
60
|
+
f"/scheduler/server/{server_uuid}/jobs"
|
|
61
|
+
if server_uuid
|
|
62
|
+
else "/scheduler/jobs"
|
|
63
|
+
)
|
|
64
|
+
return self.rd.http_get(path)
|
|
65
|
+
|
|
57
66
|
|
|
58
67
|
__all__ = ["SchedulerManager"]
|
|
@@ -67,7 +67,9 @@ class SystemACLManager(YamlPolicyMixin, RundeckObjectManager[SystemACL]):
|
|
|
67
67
|
def get(self, policy_name: str) -> SystemACL:
|
|
68
68
|
"""Récupère une politique ACL (contenu texte)."""
|
|
69
69
|
path = self._build_path(policy_name)
|
|
70
|
-
response = self.rd.http_get(
|
|
70
|
+
response = self.rd.http_get(
|
|
71
|
+
path, raw=True, headers={"Accept": "application/yaml"}
|
|
72
|
+
)
|
|
71
73
|
return self._wrap({"name": policy_name, "content": response.text})
|
|
72
74
|
|
|
73
75
|
def create(self, policy_name: str, content: str) -> SystemACL:
|
|
@@ -143,3 +145,7 @@ class SystemManager(RundeckObjectManager):
|
|
|
143
145
|
"""
|
|
144
146
|
path = self._build_path("info")
|
|
145
147
|
return self.rd.http_get(path)
|
|
148
|
+
|
|
149
|
+
def summary(self) -> dict[str, Any]:
|
|
150
|
+
"""Récupère le résumé des exécutions et projets."""
|
|
151
|
+
return self.rd.http_get("/home/summary")
|
|
@@ -100,3 +100,7 @@ class TokenManager(RundeckObjectManager):
|
|
|
100
100
|
"""
|
|
101
101
|
path = self._token_path(token_id)
|
|
102
102
|
self._delete(token_id, path=path)
|
|
103
|
+
|
|
104
|
+
def remove_expired(self, user: str) -> Any:
|
|
105
|
+
"""Supprime les tokens expirés d'un utilisateur ou de tous (``*``)."""
|
|
106
|
+
return self.rd.http_post(self._build_path(f"{user}/removeExpired"))
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
"""Gestion de la configuration Rundeck (instance globale)."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import warnings
|
|
6
|
-
|
|
7
|
-
from rundeck.base import RundeckObjectManager
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class ConfigManagementManager(RundeckObjectManager):
|
|
11
|
-
"""
|
|
12
|
-
Gestion des configurations globales (plugin/custom) via /config.
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
-
_path = "/config"
|
|
16
|
-
|
|
17
|
-
@staticmethod
|
|
18
|
-
def _warn_commercial() -> None:
|
|
19
|
-
warnings.warn(
|
|
20
|
-
"Config Management est une surface commerciale et sera retirée en 2.0.",
|
|
21
|
-
DeprecationWarning,
|
|
22
|
-
stacklevel=3,
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
def list(self) -> list[dict[str, str]]:
|
|
26
|
-
"""Liste toutes les configs et propriétés."""
|
|
27
|
-
self._warn_commercial()
|
|
28
|
-
path = self._build_path("list")
|
|
29
|
-
return self.rd.http_get(path)
|
|
30
|
-
|
|
31
|
-
def save(self, entries: list[dict[str, str]]) -> dict[str, str | list[str]]:
|
|
32
|
-
"""
|
|
33
|
-
Crée ou met à jour des configs (payload: liste de dicts {key, value, strata?}).
|
|
34
|
-
"""
|
|
35
|
-
self._warn_commercial()
|
|
36
|
-
path = self._build_path("save")
|
|
37
|
-
return self.rd.http_post(path, json=entries)
|
|
38
|
-
|
|
39
|
-
def delete(self, key: str, strata: str | None = None) -> None:
|
|
40
|
-
"""
|
|
41
|
-
Supprime une config via /config/delete avec payload JSON.
|
|
42
|
-
"""
|
|
43
|
-
self._warn_commercial()
|
|
44
|
-
payload: dict[str, str] = {"key": key}
|
|
45
|
-
if strata:
|
|
46
|
-
payload["strata"] = strata
|
|
47
|
-
path = self._build_path("delete")
|
|
48
|
-
self.rd.http_delete(path, json=payload)
|
|
49
|
-
|
|
50
|
-
def refresh(self) -> dict[str, str]:
|
|
51
|
-
"""
|
|
52
|
-
Recharge les configurations depuis les fichiers de propriétés.
|
|
53
|
-
"""
|
|
54
|
-
self._warn_commercial()
|
|
55
|
-
path = self._build_path("refresh")
|
|
56
|
-
return self.rd.http_post(path)
|
|
57
|
-
|
|
58
|
-
def restart(self) -> dict[str, str]:
|
|
59
|
-
"""
|
|
60
|
-
Redémarre le serveur Rundeck.
|
|
61
|
-
"""
|
|
62
|
-
self._warn_commercial()
|
|
63
|
-
path = self._build_path("restart")
|
|
64
|
-
return self.rd.http_post(path)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|