python-rundeck 2.0.0__tar.gz → 2.0.1__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-2.0.1/API_COVERAGE.md +88 -0
- python_rundeck-2.0.1/CHANGELOG.md +100 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/PKG-INFO +20 -7
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/README.md +15 -2
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/pyproject.toml +12 -8
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/const.py +3 -2
- python_rundeck-2.0.1/src/rundeck/v1/objects/acl.py +37 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/v1/objects/projects.py +4 -4
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/v1/objects/system.py +1 -4
- python_rundeck-2.0.0/src/rundeck/v1/objects/acl.py +0 -24
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/LICENSE +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/__init__.py +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/base.py +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/client.py +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/config.py +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/exceptions.py +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/py.typed +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/utils.py +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/v1/__init__.py +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/v1/objects/__init__.py +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/v1/objects/adhoc.py +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/v1/objects/authorizations.py +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/v1/objects/executions.py +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/v1/objects/features.py +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/v1/objects/jobs.py +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/v1/objects/key_storage.py +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/v1/objects/metrics.py +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/v1/objects/plugins.py +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/v1/objects/project_plugins.py +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/v1/objects/scheduler.py +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/v1/objects/scm.py +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/v1/objects/tokens.py +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/v1/objects/users.py +0 -0
- {python_rundeck-2.0.0 → python_rundeck-2.0.1}/src/rundeck/v1/objects/webhooks.py +0 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Rundeck Community API coverage
|
|
2
|
+
|
|
3
|
+
Audited against the Community source tag [v6.3.0](https://github.com/rundeck/rundeck/tree/v6.3.0)
|
|
4
|
+
and the [6.2.1–6.3.0 changes](https://github.com/rundeck/rundeck/compare/v6.2.1...v6.3.0),
|
|
5
|
+
the [API reference](https://docs.rundeck.com/docs/api/), the
|
|
6
|
+
[OpenAPI contract](https://docs.rundeck.com/docs/files/rundeck-api.yml), and the
|
|
7
|
+
[API version history](https://docs.rundeck.com/docs/api/rundeck-api-versions.html).
|
|
8
|
+
The package defaults to API v59 and retains explicit API v14+ selection; each row
|
|
9
|
+
describes the minimum version of the operation rather than the package's oldest
|
|
10
|
+
supported API version. API v60 can be selected explicitly on 6.3.0.
|
|
11
|
+
`Community` means the operation is part of Rundeck Community.
|
|
12
|
+
|
|
13
|
+
## Community 6.3.0 compatibility (2.0.1)
|
|
14
|
+
|
|
15
|
+
No new Community routes were introduced in the compared route mappings. API v60
|
|
16
|
+
promotes `/enterprise/cluster/info` and `/enterprise/cluster/member/{memberId}`;
|
|
17
|
+
both are excluded. The Community scheduler remains available.
|
|
18
|
+
|
|
19
|
+
| HTTP | Route | Minimum API | Edition | Python interface / change | Official source | Tests |
|
|
20
|
+
|---|---|---:|---|---|---|---|
|
|
21
|
+
| POST, PUT | `/system/acl/{name}`, `/project/{project}/acl/{name}` | 17 system / 13 project | Community | JSON `contents` writes; unchanged YAML reads | API ACL reference; RUN-4790 | `test_community_630.py`, `test_system_acl.py`, `test_project_acl.py` (unit); `test_acl_json_lifecycle`, `test_yaml_request_json_response_regression` (integration) |
|
|
22
|
+
| GET; GET, POST | `/job/{id}/meta`, `/project/{project}/jobs/browse` | 46 | Community | Preserve `executionAclValid` metadata, including false values; added in server 6.3.0 | `JobExecutionAclMetadataComponent` at v6.3.0 | `test_job_metadata_is_raw_for_get_and_browse` (unit); `test_job_acl_metadata` (integration) |
|
|
23
|
+
| GET | `/plugin/list`, `/plugin/detail/{service}/{provider}` | 14 / 49 | Community | Preserve `outputs` and property `outputMetadata` | `PluginApiService` at v6.3.0 | `test_plugin_fields_are_preserved` (unit); existing plugin integrations |
|
|
24
|
+
| PUT | `/project/{project}/import` | 14 | Community | Additional configure permission for configuration or node-source import in server 6.3.0 | `ProjectController.apiProjectImport`, PR #10650 | `test_archive_permission_error_keeps_false_options_and_details` (unit); `test_archive_import_requires_configure` (integration) |
|
|
25
|
+
| POST | `/webhook/{token}` | 30 | Community | Opaque public secret unchanged by server-side token hashing | `WebhookService` and `WebhookTokenSecureMigrationService` at v6.3.0 | `test_webhook_event_send_supports_json_and_data` (unit); `test_project_webhook_lifecycle_and_send` (integration) |
|
|
26
|
+
| GET | `/metrics/*`, `/monitoring/*` | legacy / unversioned | Community | Docker legacy metrics variable honored in server 6.3.0 | RUN-4859 | `test_legacy_metrics_enabled_by_docker_variable`, existing monitoring integrations |
|
|
27
|
+
|
|
28
|
+
Server-version features above are not gated on the selected API version. The
|
|
29
|
+
`executionAclValid` warning does not enforce execution permissions. The source
|
|
30
|
+
tag restores the `${job.serverUrl}` trailing slash (RUN-5051); no URL rewrite is
|
|
31
|
+
performed by this client. Session cookies follow requests' standard behavior.
|
|
32
|
+
|
|
33
|
+
## Added or corrected in 2.0.0
|
|
34
|
+
|
|
35
|
+
| HTTP | Route | Minimum API | Edition | Python interface | Official reference | Test |
|
|
36
|
+
|---|---|---:|---|---|---|---|
|
|
37
|
+
| GET | `/api/{v}/` | 14 | Community | `Rundeck.api_info()` | API root / API reference | `tests/unit/test_community_v59.py::test_api_info_and_default_api_version` |
|
|
38
|
+
| GET | `/api/{v}/home/summary` | 14 | Community | `rd.system.summary()` | System endpoints | `tests/unit/test_community_v59.py::test_system_summary_scheduler_and_expired_tokens_routes` |
|
|
39
|
+
| GET | `/api/{v}/scheduler/jobs` | 14 | Community | `rd.scheduler.jobs()` | Scheduler endpoints; v6.2.1 route mapping | `tests/unit/test_community_v59.py::test_system_summary_scheduler_and_expired_tokens_routes` |
|
|
40
|
+
| GET | `/api/{v}/scheduler/server/{uuid}/jobs` | 14 | Community | `rd.scheduler.jobs(server_uuid=...)` | Scheduler endpoints; v6.2.1 route mapping | `tests/unit/test_community_v59.py::test_system_summary_scheduler_and_expired_tokens_routes` |
|
|
41
|
+
| PUT | `/api/{v}/scheduler/takeover` | 14 | Community | `rd.scheduler.takeover(job_id=... or job_ids=[...])` | Scheduler endpoints; v6.2.1 route mapping | `tests/unit/test_scheduler.py` |
|
|
42
|
+
| POST | `/api/{v}/tokens/{user}/removeExpired` | 14 | Community | `rd.tokens.remove_expired(user)` | Tokens endpoints | `tests/unit/test_community_v59.py::test_system_summary_scheduler_and_expired_tokens_routes` |
|
|
43
|
+
| GET | `/monitoring/health/readiness` | n/a | Community | `rd.monitoring.readiness()` | Monitoring endpoints | `tests/unit/test_community_v59.py::test_async_export_post_uses_form_and_monitoring_readiness_is_unversioned` |
|
|
44
|
+
| POST | `/api/{v}/project/{project}/jobs/validateOption` | 47 | Community | `rd.jobs.validate_option(...)` / `project.jobs.validate_option(...)` | Jobs endpoints | `tests/unit/test_community_v59.py::test_option_validation_preserves_false_and_project_context` |
|
|
45
|
+
| POST | `/api/{v}/project/{project}/plugins/save` | 55 | Community | `project.plugins.save(...)` | Project plugin configuration | `tests/unit/test_community_v59.py::test_project_plugins_and_browse_post_contracts` |
|
|
46
|
+
| POST | `/api/{v}/project/{project}/jobs/browse` | 46 | Community | `rd.jobs.browse(..., use_post=True)` | Jobs browse endpoint | `tests/unit/test_community_v59.py::test_project_plugins_and_browse_post_contracts` |
|
|
47
|
+
| POST | `/api/{v}/project/{project}/export/async` | 14 | Community | `project.archive.export_async(..., use_post=True)` | Project archive endpoints | `tests/unit/test_community_v59.py::test_async_export_post_uses_form_and_monitoring_readiness_is_unversioned` |
|
|
48
|
+
| GET | `/api/{v}/authorizations/application/{kind}` | 14 | Community, experimental | `rd.authorizations.application_kind(...)` | Authorization evaluation endpoints | `tests/unit/test_community_v59.py::test_authorization_routes_repeat_actions_as_values` |
|
|
49
|
+
| GET | `/api/{v}/authorizations/application/{type}/{specifier}` | 14 | Community, experimental | `rd.authorizations.application_resource(...)` | Authorization evaluation endpoints | `tests/unit/test_community_v59.py::test_authorization_routes_repeat_actions_as_values` |
|
|
50
|
+
| GET | `/api/{v}/authorizations/project/{project}/{kind}` | 14 | Community, experimental | `rd.authorizations.project_kind(...)` | Authorization evaluation endpoints | `tests/unit/test_community_v59.py::test_authorization_routes_repeat_actions_as_values` |
|
|
51
|
+
| GET | `/api/{v}/authorizations/project/{project}/{type}/{specifier}` | 14 | Community, experimental | `rd.authorizations.project_resource(...)` | Authorization evaluation endpoints | `tests/unit/test_community_v59.py::test_authorization_routes_repeat_actions_as_values` |
|
|
52
|
+
| GET | `/api/{v}/authorizations/project/{project}/job/{id}` | 14 | Community, experimental | `rd.authorizations.project_job(...)` | Authorization evaluation endpoints | `tests/unit/test_community_v59.py::test_authorization_routes_repeat_actions_as_values` |
|
|
53
|
+
| GET | `/api/{v}/system/acl/{name}` | 14 | Community | `rd.system.acl.get(name)` (`Accept: application/yaml`) | System ACL endpoints | `tests/unit/test_system_acl.py` |
|
|
54
|
+
| GET | `/api/{v}/project/{project}/acl/{name}` | 14 | Community | `project.acl.get(name)` (`Accept: application/yaml`) | Project ACL endpoints | `tests/unit/test_project_acl.py` |
|
|
55
|
+
|
|
56
|
+
The authorization evaluation API is documented as experimental. `actions` is
|
|
57
|
+
sent as a repeated query parameter. Job browse POST keeps metadata and path
|
|
58
|
+
parameters in the query and sends search filters as JSON. Async archive POST
|
|
59
|
+
uses form encoding for execution IDs. `Execution.get_output()` returns the
|
|
60
|
+
server payload unchanged in both historical API v58 and compacted API v59 modes.
|
|
61
|
+
|
|
62
|
+
## Existing Community operations
|
|
63
|
+
|
|
64
|
+
The following endpoint families are also exposed by this package and are checked
|
|
65
|
+
by their focused unit tests. Paths below use `{v}` for the selected `/api/{v}`
|
|
66
|
+
prefix. See each test module for the supported verbs, request fields, response
|
|
67
|
+
handling, and pagination behavior.
|
|
68
|
+
|
|
69
|
+
| HTTP | Route(s) | Minimum API | Edition | Python interface | Official reference | Test |
|
|
70
|
+
|---|---|---:|---|---|---|---|
|
|
71
|
+
| GET, POST, PUT, DELETE | `/project`, `/project/{project}`, `/project/{project}/resources`, `/project/{project}/config`, `/project/{project}/readme`, `/project/{project}/motd`, `/project/{project}/history`, `/project/{project}/acl/{name}` | 14 | Community | `rd.projects` and nested project managers | Projects endpoints | `tests/unit/test_project_*.py`, `tests/unit/test_project_acl.py` |
|
|
72
|
+
| GET, POST, PUT, DELETE | `/project/{project}/jobs`, `/job/{id}`, `/job/{id}/run`, `/job/{id}/executions`, `/project/{project}/jobs/bulk`, `/project/{project}/jobs/delete`, `/project/{project}/jobs/browse` | 14 (browse 46) | Community | `rd.jobs`, `project.jobs`, `Job` | Jobs endpoints | `tests/unit/test_jobs.py`, `tests/unit/test_community_v59.py` |
|
|
73
|
+
| GET, POST, PUT, DELETE | `/execution/{id}`, `/execution/{id}/output`, `/execution/{id}/state`, `/execution/{id}/abort`, `/execution/{id}/retry`, `/project/{project}/executions` | 14 | Community | `rd.executions`, `Execution` | Executions endpoints | `tests/unit/test_executions.py` |
|
|
74
|
+
| GET, POST, PUT, DELETE | `/system/acl`, `/system/executions/{enable,disable,status}`, `/system/logstorage`, `/system/keys/{path}` | 14 | Community | `rd.system`, `rd.keys` | System, key storage endpoints | `tests/unit/test_system_*.py`, `tests/unit/test_key_storage.py` |
|
|
75
|
+
| GET, POST, DELETE | `/tokens`, `/tokens/{id}`, `/tokens/{user}/removeExpired`, `/user`, `/user/{login}` | 14 | Community | `rd.tokens`, `rd.users` | Tokens and user endpoints | `tests/unit/test_tokens.py`, `tests/unit/test_users.py` |
|
|
76
|
+
| GET, POST, PUT, DELETE | `/project/{project}/scm/{plugin}/{action}`, `/plugin/{service}/{name}`, `/project/{project}/webhooks` | 14 | Community | SCM, plugin, and webhook managers | SCM, plugins, webhooks endpoints | `tests/unit/test_project_scm.py`, `tests/unit/test_plugins.py`, `tests/unit/test_webhooks.py` |
|
|
77
|
+
| GET | `/metrics[/metrics|/healthcheck|/ping|/threads]`, `/monitoring[/metrics|/health|/info|/prometheus|/threaddump]` | 14 / unversioned | Community | `rd.metrics`, `rd.monitoring` | Metrics and monitoring endpoints | `tests/unit/test_metrics.py` |
|
|
78
|
+
| POST | `/run/command`, `/project/{project}/run/command` | 14 | Community | `rd.run_command`, `project.run_command` | Command execution endpoint | `tests/unit/test_adhoc.py` |
|
|
79
|
+
|
|
80
|
+
## Excluded commercial surfaces
|
|
81
|
+
|
|
82
|
+
| Removed interface / route | Reason | Verification |
|
|
83
|
+
|---|---|---|
|
|
84
|
+
| `rd.config_management` (`/config/...`) | Commercial Config Management product surface | `tests/unit/test_community_v59.py::test_api_info_and_default_api_version` |
|
|
85
|
+
| `Job.tags()` (`/job/{id}/tags`) | Commercial endpoint absent from the Community v6.2.1 contract | `tests/unit/test_jobs.py` |
|
|
86
|
+
|
|
87
|
+
Commercial-only calendars, runners, licenses, and other product-specific routes
|
|
88
|
+
are outside this client’s Community API coverage.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
7
|
+
|
|
8
|
+
## [2.0.1] - 2026-11-08
|
|
9
|
+
### Fixed
|
|
10
|
+
- Refresh vulnerable locked dependencies to their latest compatible stable releases;
|
|
11
|
+
require Requests 2.33+, Black 26.3.1+ and pytest 9.0.3+.
|
|
12
|
+
- Refresh the virtual environment's pip before auditing cached CI environments.
|
|
13
|
+
- ACL writes use the official JSON `contents` envelope and request JSON responses,
|
|
14
|
+
avoiding raw YAML response errors while retaining YAML reads and public return types.
|
|
15
|
+
- ACL reads unwrap older controllers' JSON envelopes even when YAML was requested.
|
|
16
|
+
- Integration webhook discovery now fails if the created resource disappears.
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- Rundeck Community 6.3.0 integration coverage in API v59 and v60, alongside
|
|
20
|
+
6.2.1/v59, 6.0.1/v58 and 5.18.0/v56 compatibility targets.
|
|
21
|
+
- Regression coverage for job execution ACL metadata, plugin output metadata,
|
|
22
|
+
archive import permissions, forwarded session cookies and legacy Docker metrics.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
- Current known API is v60; the default remains v59. Enterprise v60 endpoints remain excluded.
|
|
26
|
+
- Local integration image defaults to `rundeck/rundeck:6.3.0-20261022`.
|
|
27
|
+
- Integration containers are isolated by Compose project and cleaned up on failures.
|
|
28
|
+
- Gitflow feature branches run the integration and Python compatibility matrices.
|
|
29
|
+
|
|
30
|
+
## [2.0.0] - 2026-10-10
|
|
31
|
+
### Added
|
|
32
|
+
- Community API v59 support, including API discovery, system summary, scheduler job
|
|
33
|
+
listing, expired-token cleanup, monitoring readiness, option validation, project
|
|
34
|
+
plugin configuration, POST job browsing, and asynchronous archive export.
|
|
35
|
+
- Experimental authorization-evaluation endpoints and a Community API coverage matrix.
|
|
36
|
+
- Community integration defaults for Rundeck 6.2.1/API v59, with documented 6.0.1/v58
|
|
37
|
+
and 5.18.0/v56 compatibility runs.
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
- Default API version is now v59; explicitly selected older versions remain supported.
|
|
41
|
+
- System and project ACL reads explicitly request YAML. HTTP 422 responses map to
|
|
42
|
+
`RundeckValidationError` while retaining the response body.
|
|
43
|
+
- Scheduler cluster takeover accepts one or multiple job IDs. In Community without
|
|
44
|
+
cluster mode, takeover has no scheduling state to transfer.
|
|
45
|
+
|
|
46
|
+
### Removed
|
|
47
|
+
- Removed commercial Config Management interfaces and `Job.tags()`.
|
|
48
|
+
|
|
49
|
+
## [1.1.0] - 2026-07-25
|
|
50
|
+
### Added
|
|
51
|
+
- Support for `user_agent` and `config_section` parameters in the client configuration.
|
|
52
|
+
- API v57/v58 support: execution metrics, job browse, `metaExclude`, modern
|
|
53
|
+
monitoring endpoints, and v56/v57 response metadata coverage.
|
|
54
|
+
- Community endpoints for project history/meta/node tags, execution input and
|
|
55
|
+
output state, job executions, project SCM toggle, and current-user update.
|
|
56
|
+
|
|
57
|
+
### Changed
|
|
58
|
+
- `__version__` now resolves from the installed package metadata, with a local
|
|
59
|
+
fallback to `pyproject.toml` when the package is not installed.
|
|
60
|
+
- README configuration section updated to include `user_agent` and `config_section`.
|
|
61
|
+
- Default Rundeck API version updated to v58; the client retains v14
|
|
62
|
+
compatibility and documents the current server minimum v17 and v34 deprecation.
|
|
63
|
+
- Corrected Community routes and verbs for job forecasts, resource model
|
|
64
|
+
sources, bulk job actions, bulk job deletion, and job pagination.
|
|
65
|
+
- `Job.tags` and Config Management were incorrectly grouped with scheduler
|
|
66
|
+
cluster operations in this entry. The first two are commercial surfaces;
|
|
67
|
+
scheduler listing and takeover are Community endpoints and remain supported.
|
|
68
|
+
|
|
69
|
+
## [1.0.1] - 2026-01-21
|
|
70
|
+
### Changed
|
|
71
|
+
- CI: skip lint/tests on `main` and build only on tags.
|
|
72
|
+
- Classifier updated to `Development Status :: 5 - Production/Stable`.
|
|
73
|
+
|
|
74
|
+
## [1.0.0] - 2026-01-21
|
|
75
|
+
### Changed
|
|
76
|
+
- `Job.run` and `Job.retry` now return raw responses by default and support `as_execution=True` for `Execution`.
|
|
77
|
+
- `RundeckObject.refresh` and `Execution.refresh` now return `None` (in-place update).
|
|
78
|
+
- `User.update` now returns the raw response and updates the object in place.
|
|
79
|
+
- Key storage API now uses `StorageKey` objects for `create`/`update`, moves raw content access to `StorageKey.content()`, renames `get_metadata` to `get`, and supports updating via `StorageKey.update()`.
|
|
80
|
+
- System ACL policies are treated as resources and `SystemACL.update()` now updates the object in place.
|
|
81
|
+
- Project webhooks are treated as resources (`project.webhooks`), while event sending remains a utility manager.
|
|
82
|
+
|
|
83
|
+
## [0.3.0] - 2026-01-14
|
|
84
|
+
### Added
|
|
85
|
+
- README badges for PyPI version, supported Python versions, license, and downloads.
|
|
86
|
+
- Contributor dev setup note in README.
|
|
87
|
+
|
|
88
|
+
### Changed
|
|
89
|
+
- README translated to English.
|
|
90
|
+
- Installation section now targets PyPI installs.
|
|
91
|
+
- GitLab CI PyPI deployment uses verbose `twine upload`.
|
|
92
|
+
|
|
93
|
+
## [0.2.0] - 2026-01-12
|
|
94
|
+
### Added
|
|
95
|
+
- Project metadata URLs in `pyproject.toml` (Homepage, Repository, Documentation, Issues, Changelog).
|
|
96
|
+
- Changelog file to track releases.
|
|
97
|
+
|
|
98
|
+
## [0.1.0] - 2026-01-11
|
|
99
|
+
### Added
|
|
100
|
+
- Initial release of the python-rundeck client library.
|
|
@@ -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
|
--------------
|
|
@@ -5,7 +5,7 @@ python-rundeck
|
|
|
5
5
|

|
|
6
6
|

|
|
7
7
|
|
|
8
|
-
Python client for the Rundeck Community API (v14-
|
|
8
|
+
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).
|
|
9
9
|
|
|
10
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.
|
|
11
11
|
|
|
@@ -120,6 +120,16 @@ Utility managers:
|
|
|
120
120
|
Note: `project.webhooks.create(...)` returns the raw API response (e.g., `{"msg": "Saved webhook"}`)
|
|
121
121
|
because the Rundeck API does not return the created webhook object.
|
|
122
122
|
|
|
123
|
+
Compatibility with Community 6.3.0 (2.0.1)
|
|
124
|
+
---------------------------------------
|
|
125
|
+
- 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.
|
|
126
|
+
- 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.
|
|
127
|
+
- `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.
|
|
128
|
+
- 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`.
|
|
129
|
+
- Webhook tokens remain opaque public secrets. The server handles hashing and migration; callers must continue sending the original secret.
|
|
130
|
+
- Session authentication uses standard cookie handling; 6.3.0 fixes direct HTTP authentication when the public URL is HTTPS behind forwarded headers.
|
|
131
|
+
- 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.
|
|
132
|
+
|
|
123
133
|
Migration from 1.1.0
|
|
124
134
|
-------------------
|
|
125
135
|
- Set `api_version=59` explicitly when upgrading a server/client pair gradually; the default is now 59.
|
|
@@ -488,8 +498,11 @@ Development and testing
|
|
|
488
498
|
- Formatting/Lint: `black src/rundeck tests/`, `ruff check src/rundeck tests/`
|
|
489
499
|
- Typing: `mypy src/rundeck/`
|
|
490
500
|
- Tests: `pytest`
|
|
491
|
-
- Local integration tests: `scripts/run-integration.sh` starts
|
|
501
|
+
- 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`.
|
|
502
|
+
- 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).
|
|
503
|
+
- 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.
|
|
492
504
|
- 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.
|
|
505
|
+
- Run local compatibility targets sequentially, stopping each stack before starting the next. This keeps at most one Rundeck JVM and one PostgreSQL container active.
|
|
493
506
|
|
|
494
507
|
Code structure
|
|
495
508
|
--------------
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "python-rundeck"
|
|
3
|
-
version = "2.0.
|
|
4
|
-
description = "Python client for the Rundeck Community API (v14-v59)."
|
|
3
|
+
version = "2.0.1"
|
|
4
|
+
description = "Python client for the Rundeck Community API (v14-v60, default v59)."
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "Pascal Seckinger",email = "pascal.seckinger@protonmail.com"}
|
|
7
7
|
]
|
|
@@ -23,7 +23,7 @@ classifiers = [
|
|
|
23
23
|
"Typing :: Typed",
|
|
24
24
|
]
|
|
25
25
|
dependencies = [
|
|
26
|
-
"requests (>=2.
|
|
26
|
+
"requests (>=2.33.0,<3.0.0)"
|
|
27
27
|
]
|
|
28
28
|
|
|
29
29
|
[project.urls]
|
|
@@ -36,10 +36,10 @@ Changelog = "https://gitlab.com/pascal.seckinger/python-rundeck/-/blob/main/CHAN
|
|
|
36
36
|
[project.optional-dependencies]
|
|
37
37
|
dev = [
|
|
38
38
|
"bandit (>=1.7.9,<2.0.0)",
|
|
39
|
-
"black (>=
|
|
39
|
+
"black (>=26.3.1,<27.0.0)",
|
|
40
40
|
"flake8 (>=7.0.0,<8.0.0)",
|
|
41
41
|
"isort (>=7.0.0,<8.0.0)",
|
|
42
|
-
"pytest (>=9.0.
|
|
42
|
+
"pytest (>=9.0.3,<10.0.0)",
|
|
43
43
|
"pytest-cov (>=5.0.0,<6.0.0)",
|
|
44
44
|
"ruff (>=0.7.0,<1.0.0)",
|
|
45
45
|
"safety (>=3.2.0,<4.0.0)",
|
|
@@ -47,7 +47,11 @@ dev = [
|
|
|
47
47
|
|
|
48
48
|
[tool.poetry]
|
|
49
49
|
packages = [{include = "rundeck", from = "src"}]
|
|
50
|
-
include = [
|
|
50
|
+
include = [
|
|
51
|
+
"src/rundeck/py.typed",
|
|
52
|
+
{path = "API_COVERAGE.md", format = "sdist"},
|
|
53
|
+
{path = "CHANGELOG.md", format = "sdist"},
|
|
54
|
+
]
|
|
51
55
|
|
|
52
56
|
[build-system]
|
|
53
57
|
requires = ["poetry-core>=2.0.0,<3.0.0"]
|
|
@@ -56,10 +60,10 @@ build-backend = "poetry.core.masonry.api"
|
|
|
56
60
|
[dependency-groups]
|
|
57
61
|
dev = [
|
|
58
62
|
"bandit (>=1.7.9,<2.0.0)",
|
|
59
|
-
"black (>=
|
|
63
|
+
"black (>=26.3.1,<27.0.0)",
|
|
60
64
|
"flake8 (>=7.0.0,<8.0.0)",
|
|
61
65
|
"isort (>=7.0.0,<8.0.0)",
|
|
62
|
-
"pytest (>=9.0.
|
|
66
|
+
"pytest (>=9.0.3,<10.0.0)",
|
|
63
67
|
"pytest-cov (>=5.0.0,<6.0.0)",
|
|
64
68
|
"ruff (>=0.7.0,<1.0.0)",
|
|
65
69
|
"safety (>=3.2.0,<4.0.0)"
|
|
@@ -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
|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from rundeck.utils import build_headers
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class YamlPolicyMixin:
|
|
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
|
|
22
|
+
|
|
23
|
+
def _yaml_headers(self) -> dict[str, str]:
|
|
24
|
+
return (
|
|
25
|
+
build_headers(accept="application/json", content_type="application/json")
|
|
26
|
+
or {}
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
def _post_yaml(self, path: str, content: Any) -> Any:
|
|
30
|
+
return self.rd.http_post(
|
|
31
|
+
path, json={"contents": content}, headers=self._yaml_headers()
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
def _put_yaml(self, path: str, content: Any) -> Any:
|
|
35
|
+
return self.rd.http_put(
|
|
36
|
+
path, json={"contents": content}, headers=self._yaml_headers()
|
|
37
|
+
)
|
|
@@ -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,
|
|
@@ -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."""
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from typing import Any
|
|
4
|
-
|
|
5
|
-
from rundeck.utils import build_headers
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class YamlPolicyMixin:
|
|
9
|
-
_yaml_content_type = "application/yaml"
|
|
10
|
-
|
|
11
|
-
def _yaml_headers(self) -> dict[str, str]:
|
|
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
|
-
}
|
|
19
|
-
|
|
20
|
-
def _post_yaml(self, path: str, content: Any) -> Any:
|
|
21
|
-
return self.rd.http_post(path, data=content, headers=self._yaml_headers())
|
|
22
|
-
|
|
23
|
-
def _put_yaml(self, path: str, content: Any) -> Any:
|
|
24
|
-
return self.rd.http_put(path, data=content, headers=self._yaml_headers())
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|