python-rundeck 2.0.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-2.0.0.dist-info → python_rundeck-2.0.1.dist-info}/METADATA +20 -7
- {python_rundeck-2.0.0.dist-info → python_rundeck-2.0.1.dist-info}/RECORD +8 -8
- rundeck/const.py +3 -2
- rundeck/v1/objects/acl.py +22 -9
- rundeck/v1/objects/projects.py +4 -4
- rundeck/v1/objects/system.py +1 -4
- {python_rundeck-2.0.0.dist-info → python_rundeck-2.0.1.dist-info}/WHEEL +0 -0
- {python_rundeck-2.0.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: 2.0.
|
|
4
|
-
Summary: Python client for the Rundeck Community API (v14-v59).
|
|
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,7 @@ python-rundeck
|
|
|
43
43
|

|
|
44
44
|

|
|
45
45
|
|
|
46
|
-
Python client for the Rundeck Community 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
47
|
|
|
48
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.
|
|
49
49
|
|
|
@@ -158,6 +158,16 @@ Utility managers:
|
|
|
158
158
|
Note: `project.webhooks.create(...)` returns the raw API response (e.g., `{"msg": "Saved webhook"}`)
|
|
159
159
|
because the Rundeck API does not return the created webhook object.
|
|
160
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
|
+
|
|
161
171
|
Migration from 1.1.0
|
|
162
172
|
-------------------
|
|
163
173
|
- Set `api_version=59` explicitly when upgrading a server/client pair gradually; the default is now 59.
|
|
@@ -526,8 +536,11 @@ Development and testing
|
|
|
526
536
|
- Formatting/Lint: `black src/rundeck tests/`, `ruff check src/rundeck tests/`
|
|
527
537
|
- Typing: `mypy src/rundeck/`
|
|
528
538
|
- Tests: `pytest`
|
|
529
|
-
- 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.
|
|
530
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.
|
|
531
544
|
|
|
532
545
|
Code structure
|
|
533
546
|
--------------
|
|
@@ -2,13 +2,13 @@ rundeck/__init__.py,sha256=M413mLKjB08nWuo5godsAmk2ly9vEYw5Xzc-Pt4Pqds,951
|
|
|
2
2
|
rundeck/base.py,sha256=TGqxLj9F4Y0x7nQGqkjuw7xitzxWOa2fn4apkjpckwE,7119
|
|
3
3
|
rundeck/client.py,sha256=r3LNO9TDqjiwT-XZI_xFQeWXaajPV9AxFtBUlqe-pOc,11433
|
|
4
4
|
rundeck/config.py,sha256=bVCuqD6Nk6RDS-WAt81uMh6PfQ2ocZDN51Aspjnhjxc,5331
|
|
5
|
-
rundeck/const.py,sha256=
|
|
5
|
+
rundeck/const.py,sha256=uDE6Qt1_RrpzuRG9xHIlv5q4tKVtpuN_zKrZYMpqVPo,1681
|
|
6
6
|
rundeck/exceptions.py,sha256=3XVZi9mnsDYPqmFI-yV0wxNaTy3bdsrTRwWJKt8rqf8,4778
|
|
7
7
|
rundeck/py.typed,sha256=3Q9vdii9v-_pbj9sglgDzJAIelvARaYaDJlB2u-NDqg,38
|
|
8
8
|
rundeck/utils.py,sha256=L4ohGScvN1lj3HM0A1mdxEEEm3GMJ3ISm_UjBPeXQmo,940
|
|
9
9
|
rundeck/v1/__init__.py,sha256=stKy-CO4DYAq_xa35LOgghZQ6LtrDcZ5WkuffNPGR0I,13
|
|
10
10
|
rundeck/v1/objects/__init__.py,sha256=5n01WuyYDbuLLGGKoqO342Nb15Qgk3s5MUpJKp-o8Ko,21
|
|
11
|
-
rundeck/v1/objects/acl.py,sha256=
|
|
11
|
+
rundeck/v1/objects/acl.py,sha256=sTdOxdmsb0DL3OAQNtzZvdxDdTRkKIRZm_UpipMdpI4,1227
|
|
12
12
|
rundeck/v1/objects/adhoc.py,sha256=E5cYrQfI1_fi4ReVTRAX6zcP8fZn77uc3K4XICc2E_4,2787
|
|
13
13
|
rundeck/v1/objects/authorizations.py,sha256=dugrkboWxkQ0phv15CTXTwTfaJKwRRi9UK8zPWoVlmo,1751
|
|
14
14
|
rundeck/v1/objects/executions.py,sha256=amX2zYZkEqwGwLXOGDoA0gdtpS57xzO-pTtvdgPvF_Q,14752
|
|
@@ -18,14 +18,14 @@ rundeck/v1/objects/key_storage.py,sha256=mPZYqgqeeI_ujvwXHGLjTwxbgoMk_Pw7ND-dlob
|
|
|
18
18
|
rundeck/v1/objects/metrics.py,sha256=Q4amOwyZyRQltozxCiYYLWxhCdps7kN74nXDmSz2FFI,2909
|
|
19
19
|
rundeck/v1/objects/plugins.py,sha256=a2vGsiQGz8V5gXNepj2KP98M926zzxRpksddKtZy5N8,1124
|
|
20
20
|
rundeck/v1/objects/project_plugins.py,sha256=Ecy-kWIlUKuFspXbcH8neTYu_0qr2_XE0Pb8DzVnfBc,871
|
|
21
|
-
rundeck/v1/objects/projects.py,sha256=
|
|
21
|
+
rundeck/v1/objects/projects.py,sha256=0D1BAzBrHzTV0pcHa1wzA5skOGGEqmV5_OsQ2NkZzQU,18645
|
|
22
22
|
rundeck/v1/objects/scheduler.py,sha256=yUG_vF5SdP7g0nEkwQ5D4WfA7xeer3blAaHdp7LsnVs,2033
|
|
23
23
|
rundeck/v1/objects/scm.py,sha256=Fobtecr-7GH71nTCn5Jf-6RANMVdnVQDzoFaFsrH9y8,7940
|
|
24
|
-
rundeck/v1/objects/system.py,sha256=
|
|
24
|
+
rundeck/v1/objects/system.py,sha256=h1sJ2fXxKp9PLL4Mz1fxMYjUe0oyjsXMSbMD20ExTas,4897
|
|
25
25
|
rundeck/v1/objects/tokens.py,sha256=R36R7z8jSsRUYDmuihE8b9er7uYcyoQw3n5HbveAE5E,2578
|
|
26
26
|
rundeck/v1/objects/users.py,sha256=hJFMvO1_L_Qql2_K3VvS3EXOxZow4ucQ8yLijziOL8s,3870
|
|
27
27
|
rundeck/v1/objects/webhooks.py,sha256=F_HzNvlBRPvS_viu2reCRc7ECqRSUhp5RfD_G3r-ZZk,3358
|
|
28
|
-
python_rundeck-2.0.
|
|
29
|
-
python_rundeck-2.0.
|
|
30
|
-
python_rundeck-2.0.
|
|
31
|
-
python_rundeck-2.0.
|
|
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/const.py
CHANGED
|
@@ -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/v1/objects/acl.py
CHANGED
|
@@ -6,19 +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
|
-
accept=
|
|
24
|
+
return (
|
|
25
|
+
build_headers(accept="application/json", content_type="application/json")
|
|
26
|
+
or {}
|
|
14
27
|
)
|
|
15
|
-
return headers or {
|
|
16
|
-
"Accept": self._yaml_content_type,
|
|
17
|
-
"Content-Type": self._yaml_content_type,
|
|
18
|
-
}
|
|
19
28
|
|
|
20
29
|
def _post_yaml(self, path: str, content: Any) -> Any:
|
|
21
|
-
return self.rd.http_post(
|
|
30
|
+
return self.rd.http_post(
|
|
31
|
+
path, json={"contents": content}, headers=self._yaml_headers()
|
|
32
|
+
)
|
|
22
33
|
|
|
23
34
|
def _put_yaml(self, path: str, content: Any) -> Any:
|
|
24
|
-
return self.rd.http_put(
|
|
35
|
+
return self.rd.http_put(
|
|
36
|
+
path, json={"contents": content}, headers=self._yaml_headers()
|
|
37
|
+
)
|
rundeck/v1/objects/projects.py
CHANGED
|
@@ -193,10 +193,7 @@ class ProjectACLManager(YamlPolicyMixin, RundeckObjectManager):
|
|
|
193
193
|
def get(self, policy_name: str) -> str:
|
|
194
194
|
"""Récupère une politique ACL projet (contenu texte)."""
|
|
195
195
|
path = self._build_path(policy_name)
|
|
196
|
-
|
|
197
|
-
path, raw=True, headers={"Accept": "application/yaml"}
|
|
198
|
-
)
|
|
199
|
-
return response.text
|
|
196
|
+
return self._get_yaml(path)
|
|
200
197
|
|
|
201
198
|
def create(self, policy_name: str, content: str) -> dict[str, Any]:
|
|
202
199
|
"""Crée une politique ACL projet."""
|
|
@@ -484,6 +481,9 @@ class ProjectArchiveManager(RundeckObjectManager):
|
|
|
484
481
|
) -> Any:
|
|
485
482
|
"""
|
|
486
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.
|
|
487
487
|
"""
|
|
488
488
|
params = compact(
|
|
489
489
|
component_options,
|
rundeck/v1/objects/system.py
CHANGED
|
@@ -67,10 +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
|
-
path, raw=True, headers={"Accept": "application/yaml"}
|
|
72
|
-
)
|
|
73
|
-
return self._wrap({"name": policy_name, "content": response.text})
|
|
70
|
+
return self._wrap({"name": policy_name, "content": self._get_yaml(path)})
|
|
74
71
|
|
|
75
72
|
def create(self, policy_name: str, content: str) -> SystemACL:
|
|
76
73
|
"""Crée une politique ACL système."""
|
|
File without changes
|
|
File without changes
|