python-rundeck 1.1.0__py3-none-any.whl → 2.0.1__py3-none-any.whl
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.dist-info → python_rundeck-2.0.1.dist-info}/METADATA +58 -29
- python_rundeck-2.0.1.dist-info/RECORD +31 -0
- {python_rundeck-1.1.0.dist-info → python_rundeck-2.0.1.dist-info}/WHEEL +1 -1
- rundeck/client.py +6 -2
- rundeck/const.py +4 -3
- rundeck/exceptions.py +1 -1
- rundeck/v1/objects/acl.py +23 -5
- rundeck/v1/objects/authorizations.py +45 -0
- rundeck/v1/objects/jobs.py +26 -13
- rundeck/v1/objects/metrics.py +4 -0
- rundeck/v1/objects/project_plugins.py +29 -0
- rundeck/v1/objects/projects.py +28 -4
- rundeck/v1/objects/scheduler.py +16 -7
- rundeck/v1/objects/system.py +5 -2
- rundeck/v1/objects/tokens.py +4 -0
- python_rundeck-1.1.0.dist-info/RECORD +0 -30
- rundeck/v1/objects/config_management.py +0 -64
- {python_rundeck-1.1.0.dist-info → python_rundeck-2.0.1.dist-info}/licenses/LICENSE +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.1
|
|
4
|
+
Summary: Python client for the Rundeck Community API (v14-v60, default v59).
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Keywords: rundeck,api,client
|
|
@@ -21,12 +21,12 @@ Classifier: Topic :: System :: Systems Administration
|
|
|
21
21
|
Classifier: Typing :: Typed
|
|
22
22
|
Provides-Extra: dev
|
|
23
23
|
Requires-Dist: bandit (>=1.7.9,<2.0.0) ; extra == "dev"
|
|
24
|
-
Requires-Dist: black (>=
|
|
24
|
+
Requires-Dist: black (>=26.3.1,<27.0.0) ; extra == "dev"
|
|
25
25
|
Requires-Dist: flake8 (>=7.0.0,<8.0.0) ; extra == "dev"
|
|
26
26
|
Requires-Dist: isort (>=7.0.0,<8.0.0) ; extra == "dev"
|
|
27
|
-
Requires-Dist: pytest (>=9.0.
|
|
27
|
+
Requires-Dist: pytest (>=9.0.3,<10.0.0) ; extra == "dev"
|
|
28
28
|
Requires-Dist: pytest-cov (>=5.0.0,<6.0.0) ; extra == "dev"
|
|
29
|
-
Requires-Dist: requests (>=2.
|
|
29
|
+
Requires-Dist: requests (>=2.33.0,<3.0.0)
|
|
30
30
|
Requires-Dist: ruff (>=0.7.0,<1.0.0) ; extra == "dev"
|
|
31
31
|
Requires-Dist: safety (>=3.2.0,<4.0.0) ; extra == "dev"
|
|
32
32
|
Project-URL: Changelog, https://gitlab.com/pascal.seckinger/python-rundeck/-/blob/main/CHANGELOG.md
|
|
@@ -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-v60), inspired by the python-gitlab architecture. Rundeck Community 6.3.0 is the integration reference. The default API version remains v59; use `api_version=60` explicitly with 6.3.0. 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,23 @@ 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
|
+
Compatibility with Community 6.3.0 (2.0.1)
|
|
162
|
+
---------------------------------------
|
|
163
|
+
- API v60 is recognized; the default stays v59 to retain compatibility with Community 6.2.1. The new v60 cluster endpoints are Enterprise-only and excluded.
|
|
164
|
+
- ACL creation and updates send the YAML text inside a JSON `contents` envelope and request JSON responses. Reads still request YAML and unwrap legacy JSON responses from older project ACL controllers. Python signatures and resource return conventions are unchanged.
|
|
165
|
+
- `job.meta(meta="executionAclValid")` and `project.jobs.browse(meta="executionAclValid")` expose the server's saved-user authorization warning. It does not block execution. Plugin `outputs` and property `outputMetadata` are preserved when returned by the server.
|
|
166
|
+
- Archive imports with `importConfig=True` or `importNodesSources=True` also require project `configure` authorization on 6.3.0. Use explicit `False` values for jobs-only imports. Authorization failures retain the server response in `RundeckAuthenticationError.response_body`.
|
|
167
|
+
- Webhook tokens remain opaque public secrets. The server handles hashing and migration; callers must continue sending the original secret.
|
|
168
|
+
- Session authentication uses standard cookie handling; 6.3.0 fixes direct HTTP authentication when the public URL is HTTPS behind forwarded headers.
|
|
169
|
+
- The stable 6.3.0 sources restore the trailing slash on `${job.serverUrl}` (RUN-5051), despite the earlier release-note wording. The client does not rewrite job context URLs.
|
|
170
|
+
|
|
171
|
+
Migration from 1.1.0
|
|
172
|
+
-------------------
|
|
173
|
+
- Set `api_version=59` explicitly when upgrading a server/client pair gradually; the default is now 59.
|
|
174
|
+
- Remove calls to `rd.config_management` and `job.tags()`: their endpoints are only available in commercial Rundeck products.
|
|
175
|
+
- `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.
|
|
176
|
+
- `rd.authorizations` wraps experimental endpoints and can change with Rundeck releases.
|
|
177
|
+
|
|
159
178
|
Example:
|
|
160
179
|
```python
|
|
161
180
|
job = rd.jobs.get("job-id") # -> Job (object)
|
|
@@ -468,17 +487,6 @@ if features:
|
|
|
468
487
|
print(first.name, status.enabled)
|
|
469
488
|
```
|
|
470
489
|
|
|
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
490
|
Monitoring
|
|
483
491
|
----------
|
|
484
492
|
```python
|
|
@@ -490,6 +498,24 @@ thread_dump = rd.monitoring.thread_dump()
|
|
|
490
498
|
|
|
491
499
|
# Legacy metrics require rundeck.metrics.legacy.enabled=true on Rundeck 6.0.
|
|
492
500
|
legacy_threads = rd.metrics.threads()
|
|
501
|
+
ready = rd.monitoring.readiness()
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
Community additions
|
|
505
|
+
-------------------
|
|
506
|
+
```python
|
|
507
|
+
api_info = rd.api_info()
|
|
508
|
+
summary = rd.system.summary()
|
|
509
|
+
scheduled_jobs = rd.scheduler.jobs()
|
|
510
|
+
rd.tokens.remove_expired("admin") # use "*" with suitable administrator rights
|
|
511
|
+
|
|
512
|
+
project = rd.projects.get("demo")
|
|
513
|
+
project.plugins.save("ResourceModelSource", "resources.source", plugins=[])
|
|
514
|
+
project.archive.export_async(execution_ids=["1", "2"], use_post=True)
|
|
515
|
+
project.jobs.validate_option(option_data, job_was_scheduled=False)
|
|
516
|
+
|
|
517
|
+
# Experimental authorization API; actions are repeated query parameters.
|
|
518
|
+
permissions = rd.authorizations.application_kind("job", ["read", "run"])
|
|
493
519
|
```
|
|
494
520
|
|
|
495
521
|
Pagination
|
|
@@ -510,13 +536,16 @@ Development and testing
|
|
|
510
536
|
- Formatting/Lint: `black src/rundeck tests/`, `ruff check src/rundeck tests/`
|
|
511
537
|
- Typing: `mypy src/rundeck/`
|
|
512
538
|
- Tests: `pytest`
|
|
513
|
-
- Local integration tests: `scripts/run-integration.sh` starts
|
|
539
|
+
- Local integration tests: `scripts/run-integration.sh` starts `rundeck/rundeck:6.3.0-20261022` with API v59. Each run has an isolated Compose project and cleans up even when tests fail. With `KEEP_STACK=1`, the script prints the project name needed by `scripts/stop-integration.sh`.
|
|
540
|
+
- GitLab runs five integration targets: 6.3.0/API 59, 6.3.0/API 60, 6.2.1/API 59, 6.0.1/API 58 and 5.18.0/API 56. Set `RUNDECK_IMAGE` and `RUNDECK_API_VERSION` to run each target locally. Python compatibility tests retain 3.11–3.15 (3.15-rc Docker image).
|
|
541
|
+
- To exercise the 6.3.0 session regression and legacy metrics: `RUNDECK_PUBLIC_URL=https://rundeck.example.invalid RUNDECK_METRICS_LEGACY_ENABLED=true scripts/run-integration.sh`. The client still connects to `RUNDECK_URL` (default `http://localhost:4440`). The public URL defaults to the client URL, ensuring session redirects also work on older servers. Optional `RUNDECK_HTTP_PORT` changes the published port; set `RUNDECK_URL` accordingly.
|
|
514
542
|
- 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.
|
|
543
|
+
- Run local compatibility targets sequentially, stopping each stack before starting the next. This keeps at most one Rundeck JVM and one PostgreSQL container active.
|
|
515
544
|
|
|
516
545
|
Code structure
|
|
517
546
|
--------------
|
|
518
547
|
- `src/rundeck/base.py`: generic objects/managers, `_build_path` helpers, pagination, CRUD.
|
|
519
548
|
- `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
|
|
549
|
+
- `src/rundeck/v1/objects/`: Community domain managers and objects (projects, jobs, executions, system, tokens, users, authorizations).
|
|
550
|
+
- 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
551
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
rundeck/__init__.py,sha256=M413mLKjB08nWuo5godsAmk2ly9vEYw5Xzc-Pt4Pqds,951
|
|
2
|
+
rundeck/base.py,sha256=TGqxLj9F4Y0x7nQGqkjuw7xitzxWOa2fn4apkjpckwE,7119
|
|
3
|
+
rundeck/client.py,sha256=r3LNO9TDqjiwT-XZI_xFQeWXaajPV9AxFtBUlqe-pOc,11433
|
|
4
|
+
rundeck/config.py,sha256=bVCuqD6Nk6RDS-WAt81uMh6PfQ2ocZDN51Aspjnhjxc,5331
|
|
5
|
+
rundeck/const.py,sha256=uDE6Qt1_RrpzuRG9xHIlv5q4tKVtpuN_zKrZYMpqVPo,1681
|
|
6
|
+
rundeck/exceptions.py,sha256=3XVZi9mnsDYPqmFI-yV0wxNaTy3bdsrTRwWJKt8rqf8,4778
|
|
7
|
+
rundeck/py.typed,sha256=3Q9vdii9v-_pbj9sglgDzJAIelvARaYaDJlB2u-NDqg,38
|
|
8
|
+
rundeck/utils.py,sha256=L4ohGScvN1lj3HM0A1mdxEEEm3GMJ3ISm_UjBPeXQmo,940
|
|
9
|
+
rundeck/v1/__init__.py,sha256=stKy-CO4DYAq_xa35LOgghZQ6LtrDcZ5WkuffNPGR0I,13
|
|
10
|
+
rundeck/v1/objects/__init__.py,sha256=5n01WuyYDbuLLGGKoqO342Nb15Qgk3s5MUpJKp-o8Ko,21
|
|
11
|
+
rundeck/v1/objects/acl.py,sha256=sTdOxdmsb0DL3OAQNtzZvdxDdTRkKIRZm_UpipMdpI4,1227
|
|
12
|
+
rundeck/v1/objects/adhoc.py,sha256=E5cYrQfI1_fi4ReVTRAX6zcP8fZn77uc3K4XICc2E_4,2787
|
|
13
|
+
rundeck/v1/objects/authorizations.py,sha256=dugrkboWxkQ0phv15CTXTwTfaJKwRRi9UK8zPWoVlmo,1751
|
|
14
|
+
rundeck/v1/objects/executions.py,sha256=amX2zYZkEqwGwLXOGDoA0gdtpS57xzO-pTtvdgPvF_Q,14752
|
|
15
|
+
rundeck/v1/objects/features.py,sha256=bVMLB86HIZF7dhN3EpqMVP_Yo_J2_hqtbJjZFb7BMxU,1283
|
|
16
|
+
rundeck/v1/objects/jobs.py,sha256=9UPmkZn_NNEjGkbY9ysS4vL_QXXYACucOyE2D-UxLe8,14166
|
|
17
|
+
rundeck/v1/objects/key_storage.py,sha256=mPZYqgqeeI_ujvwXHGLjTwxbgoMk_Pw7ND-dlob2WAY,3807
|
|
18
|
+
rundeck/v1/objects/metrics.py,sha256=Q4amOwyZyRQltozxCiYYLWxhCdps7kN74nXDmSz2FFI,2909
|
|
19
|
+
rundeck/v1/objects/plugins.py,sha256=a2vGsiQGz8V5gXNepj2KP98M926zzxRpksddKtZy5N8,1124
|
|
20
|
+
rundeck/v1/objects/project_plugins.py,sha256=Ecy-kWIlUKuFspXbcH8neTYu_0qr2_XE0Pb8DzVnfBc,871
|
|
21
|
+
rundeck/v1/objects/projects.py,sha256=0D1BAzBrHzTV0pcHa1wzA5skOGGEqmV5_OsQ2NkZzQU,18645
|
|
22
|
+
rundeck/v1/objects/scheduler.py,sha256=yUG_vF5SdP7g0nEkwQ5D4WfA7xeer3blAaHdp7LsnVs,2033
|
|
23
|
+
rundeck/v1/objects/scm.py,sha256=Fobtecr-7GH71nTCn5Jf-6RANMVdnVQDzoFaFsrH9y8,7940
|
|
24
|
+
rundeck/v1/objects/system.py,sha256=h1sJ2fXxKp9PLL4Mz1fxMYjUe0oyjsXMSbMD20ExTas,4897
|
|
25
|
+
rundeck/v1/objects/tokens.py,sha256=R36R7z8jSsRUYDmuihE8b9er7uYcyoQw3n5HbveAE5E,2578
|
|
26
|
+
rundeck/v1/objects/users.py,sha256=hJFMvO1_L_Qql2_K3VvS3EXOxZow4ucQ8yLijziOL8s,3870
|
|
27
|
+
rundeck/v1/objects/webhooks.py,sha256=F_HzNvlBRPvS_viu2reCRc7ECqRSUhp5RfD_G3r-ZZk,3358
|
|
28
|
+
python_rundeck-2.0.1.dist-info/METADATA,sha256=AfKPQ4AREsjZHliQ3N0LbNPWrAClq45e0CyMiBt_WmQ,23062
|
|
29
|
+
python_rundeck-2.0.1.dist-info/WHEEL,sha256=L-WvLdSBvJWHXv5zrQxDvNRnIgoBzLUpcbuiw19KCuQ,88
|
|
30
|
+
python_rundeck-2.0.1.dist-info/licenses/LICENSE,sha256=3X-BjvCzow8iLfLMykDaEAXjE9JvDrEHPkH9UK7MMMA,1073
|
|
31
|
+
python_rundeck-2.0.1.dist-info/RECORD,,
|
rundeck/client.py
CHANGED
|
@@ -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."""
|
rundeck/const.py
CHANGED
|
@@ -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,13 +40,14 @@ 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 = "60"
|
|
44
44
|
API_VERSION_MIN = "14"
|
|
45
45
|
API_VERSION_SERVER_MIN = "17"
|
|
46
46
|
API_VERSION_DEPRECATION = "34"
|
|
47
47
|
|
|
48
48
|
# Defaults
|
|
49
|
-
|
|
49
|
+
# v60 adds Enterprise endpoints only; keep the Community-compatible default.
|
|
50
|
+
DEFAULT_API_VERSION = "59"
|
|
50
51
|
DEFAULT_TIMEOUT = 30
|
|
51
52
|
USER_AGENT = "python-rundeck"
|
|
52
53
|
|
rundeck/exceptions.py
CHANGED
|
@@ -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)
|
rundeck/v1/objects/acl.py
CHANGED
|
@@ -6,14 +6,32 @@ from rundeck.utils import build_headers
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class YamlPolicyMixin:
|
|
9
|
-
|
|
9
|
+
def _get_yaml(self, path: str) -> str:
|
|
10
|
+
response = self.rd.http_get(
|
|
11
|
+
path, raw=True, headers={"Accept": "application/yaml"}
|
|
12
|
+
)
|
|
13
|
+
# Some older project ACL controllers return a JSON envelope despite Accept.
|
|
14
|
+
if (
|
|
15
|
+
"application/json"
|
|
16
|
+
in getattr(response, "headers", {}).get("Content-Type", "").lower()
|
|
17
|
+
):
|
|
18
|
+
result = response.json()
|
|
19
|
+
if isinstance(result, dict) and isinstance(result.get("contents"), str):
|
|
20
|
+
return result["contents"]
|
|
21
|
+
return response.text
|
|
10
22
|
|
|
11
23
|
def _yaml_headers(self) -> dict[str, str]:
|
|
12
|
-
|
|
13
|
-
|
|
24
|
+
return (
|
|
25
|
+
build_headers(accept="application/json", content_type="application/json")
|
|
26
|
+
or {}
|
|
27
|
+
)
|
|
14
28
|
|
|
15
29
|
def _post_yaml(self, path: str, content: Any) -> Any:
|
|
16
|
-
return self.rd.http_post(
|
|
30
|
+
return self.rd.http_post(
|
|
31
|
+
path, json={"contents": content}, headers=self._yaml_headers()
|
|
32
|
+
)
|
|
17
33
|
|
|
18
34
|
def _put_yaml(self, path: str, content: Any) -> Any:
|
|
19
|
-
return self.rd.http_put(
|
|
35
|
+
return self.rd.http_put(
|
|
36
|
+
path, json={"contents": content}, headers=self._yaml_headers()
|
|
37
|
+
)
|
|
@@ -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"]
|
rundeck/v1/objects/jobs.py
CHANGED
|
@@ -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."""
|
rundeck/v1/objects/metrics.py
CHANGED
|
@@ -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"]
|
rundeck/v1/objects/projects.py
CHANGED
|
@@ -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,8 +193,7 @@ 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
|
-
|
|
191
|
-
return response.text
|
|
196
|
+
return self._get_yaml(path)
|
|
192
197
|
|
|
193
198
|
def create(self, policy_name: str, content: str) -> dict[str, Any]:
|
|
194
199
|
"""Crée une politique ACL projet."""
|
|
@@ -429,9 +434,25 @@ class ProjectArchiveManager(RundeckObjectManager):
|
|
|
429
434
|
)
|
|
430
435
|
return self.rd.http_get(path, params=params or None, raw=True)
|
|
431
436
|
|
|
432
|
-
def export_async(
|
|
433
|
-
|
|
437
|
+
def export_async(
|
|
438
|
+
self,
|
|
439
|
+
*,
|
|
440
|
+
execution_ids: list[str] | None = None,
|
|
441
|
+
use_post: bool = False,
|
|
442
|
+
**params: Any,
|
|
443
|
+
) -> Any:
|
|
444
|
+
"""Lance une export async, en POST pour les longues listes d'IDs."""
|
|
434
445
|
path = self._build_path("export/async")
|
|
446
|
+
if use_post:
|
|
447
|
+
form = {"executionIds": execution_ids} if execution_ids else None
|
|
448
|
+
return self.rd.http_post(
|
|
449
|
+
path,
|
|
450
|
+
params=params or None,
|
|
451
|
+
data=form,
|
|
452
|
+
headers=build_headers(content_type="application/x-www-form-urlencoded"),
|
|
453
|
+
)
|
|
454
|
+
if execution_ids:
|
|
455
|
+
params["executionIds"] = execution_ids
|
|
435
456
|
return self.rd.http_get(path, params=params or None)
|
|
436
457
|
|
|
437
458
|
def export_status(self, token: str) -> Any:
|
|
@@ -460,6 +481,9 @@ class ProjectArchiveManager(RundeckObjectManager):
|
|
|
460
481
|
) -> Any:
|
|
461
482
|
"""
|
|
462
483
|
Importe une archive ZIP dans le projet.
|
|
484
|
+
|
|
485
|
+
Community 6.3+ exige aussi le droit configure lorsque importConfig ou
|
|
486
|
+
importNodesSources est activé. Les options et refus sont transmis tels quels.
|
|
463
487
|
"""
|
|
464
488
|
params = compact(
|
|
465
489
|
component_options,
|
rundeck/v1/objects/scheduler.py
CHANGED
|
@@ -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"]
|
rundeck/v1/objects/system.py
CHANGED
|
@@ -67,8 +67,7 @@ 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
|
-
|
|
71
|
-
return self._wrap({"name": policy_name, "content": response.text})
|
|
70
|
+
return self._wrap({"name": policy_name, "content": self._get_yaml(path)})
|
|
72
71
|
|
|
73
72
|
def create(self, policy_name: str, content: str) -> SystemACL:
|
|
74
73
|
"""Crée une politique ACL système."""
|
|
@@ -143,3 +142,7 @@ class SystemManager(RundeckObjectManager):
|
|
|
143
142
|
"""
|
|
144
143
|
path = self._build_path("info")
|
|
145
144
|
return self.rd.http_get(path)
|
|
145
|
+
|
|
146
|
+
def summary(self) -> dict[str, Any]:
|
|
147
|
+
"""Récupère le résumé des exécutions et projets."""
|
|
148
|
+
return self.rd.http_get("/home/summary")
|
rundeck/v1/objects/tokens.py
CHANGED
|
@@ -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,30 +0,0 @@
|
|
|
1
|
-
rundeck/__init__.py,sha256=M413mLKjB08nWuo5godsAmk2ly9vEYw5Xzc-Pt4Pqds,951
|
|
2
|
-
rundeck/base.py,sha256=TGqxLj9F4Y0x7nQGqkjuw7xitzxWOa2fn4apkjpckwE,7119
|
|
3
|
-
rundeck/client.py,sha256=0q7weqAXvl5JDriFol9GVBnqK1NVaOhP_8iMw6QfUzc,11290
|
|
4
|
-
rundeck/config.py,sha256=bVCuqD6Nk6RDS-WAt81uMh6PfQ2ocZDN51Aspjnhjxc,5331
|
|
5
|
-
rundeck/const.py,sha256=RNAix0dcldqI3PhvoZn8F0OmpuNu9ReG21u_ZNxjCec,1619
|
|
6
|
-
rundeck/exceptions.py,sha256=HV5c-YDf0XmV3ia-4kC0iukonsZYLBK1R8X8w05Iw2w,4771
|
|
7
|
-
rundeck/py.typed,sha256=3Q9vdii9v-_pbj9sglgDzJAIelvARaYaDJlB2u-NDqg,38
|
|
8
|
-
rundeck/utils.py,sha256=L4ohGScvN1lj3HM0A1mdxEEEm3GMJ3ISm_UjBPeXQmo,940
|
|
9
|
-
rundeck/v1/__init__.py,sha256=stKy-CO4DYAq_xa35LOgghZQ6LtrDcZ5WkuffNPGR0I,13
|
|
10
|
-
rundeck/v1/objects/__init__.py,sha256=5n01WuyYDbuLLGGKoqO342Nb15Qgk3s5MUpJKp-o8Ko,21
|
|
11
|
-
rundeck/v1/objects/acl.py,sha256=Rt8BFnOi_z_x4RpT-2G7Tf4SVcrCCUh8vLd1j5GIHZk,637
|
|
12
|
-
rundeck/v1/objects/adhoc.py,sha256=E5cYrQfI1_fi4ReVTRAX6zcP8fZn77uc3K4XICc2E_4,2787
|
|
13
|
-
rundeck/v1/objects/config_management.py,sha256=Z5WiqmvPHVsrW65XDmingwar-KGKguyPZAjAP8emnB0,1946
|
|
14
|
-
rundeck/v1/objects/executions.py,sha256=amX2zYZkEqwGwLXOGDoA0gdtpS57xzO-pTtvdgPvF_Q,14752
|
|
15
|
-
rundeck/v1/objects/features.py,sha256=bVMLB86HIZF7dhN3EpqMVP_Yo_J2_hqtbJjZFb7BMxU,1283
|
|
16
|
-
rundeck/v1/objects/jobs.py,sha256=I58FF3-3P5O1dqmpr9AwQH6pGPYqrbR-KK2Gx9vTQyw,13630
|
|
17
|
-
rundeck/v1/objects/key_storage.py,sha256=mPZYqgqeeI_ujvwXHGLjTwxbgoMk_Pw7ND-dlob2WAY,3807
|
|
18
|
-
rundeck/v1/objects/metrics.py,sha256=ipe5WhP1yd3LKqTGPBDFLDG3cjaWPHkkPxw0KGPpDos,2709
|
|
19
|
-
rundeck/v1/objects/plugins.py,sha256=a2vGsiQGz8V5gXNepj2KP98M926zzxRpksddKtZy5N8,1124
|
|
20
|
-
rundeck/v1/objects/projects.py,sha256=eMxKxvTGkmZi-SptJEMKS9kA4YnaXQ8jCOZSk1233Us,17730
|
|
21
|
-
rundeck/v1/objects/scheduler.py,sha256=g16YsnA_QoCH81NtCEgPS31CNFyk5aLZhCMKnfoVTC0,1496
|
|
22
|
-
rundeck/v1/objects/scm.py,sha256=Fobtecr-7GH71nTCn5Jf-6RANMVdnVQDzoFaFsrH9y8,7940
|
|
23
|
-
rundeck/v1/objects/system.py,sha256=x34Cvc8VzaxtbXMzxHPUIxV2YkvFXLI8IiwV4cyvt6A,4786
|
|
24
|
-
rundeck/v1/objects/tokens.py,sha256=OWnfs1QUTpJbsaKf7r0Y7w3VYxxGZxBDead8JAoPKck,2373
|
|
25
|
-
rundeck/v1/objects/users.py,sha256=hJFMvO1_L_Qql2_K3VvS3EXOxZow4ucQ8yLijziOL8s,3870
|
|
26
|
-
rundeck/v1/objects/webhooks.py,sha256=F_HzNvlBRPvS_viu2reCRc7ECqRSUhp5RfD_G3r-ZZk,3358
|
|
27
|
-
python_rundeck-1.1.0.dist-info/METADATA,sha256=11iEODsK7GFF9BqT6g03rp62GZALh9rWl7WntRCwqxg,19406
|
|
28
|
-
python_rundeck-1.1.0.dist-info/WHEEL,sha256=EGEvSphFYqXKs23-kQBeyNoJP1nrT8ZJKQoi5p5DYL8,88
|
|
29
|
-
python_rundeck-1.1.0.dist-info/licenses/LICENSE,sha256=3X-BjvCzow8iLfLMykDaEAXjE9JvDrEHPkH9UK7MMMA,1073
|
|
30
|
-
python_rundeck-1.1.0.dist-info/RECORD,,
|
|
@@ -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
|