Skip to content

Commit bb08935

Browse files
committed
release: v1.3.0 — reliability, security guards, and observability
Reliability - OrcaClient.paginate() walks marker-based pagination to completion; the batch commands (audit/overview/cleanup/export) no longer drop rows past 1000 on large tenants. - 429 Too Many Requests is retried with Retry-After (RFC 7231, capped at 60s); 5xx backoff uses full jitter to avoid thundering-herd in CI. Security - safe_output_path / safe_child_path refuse symlink overwrites and path traversal in every command that writes a user-supplied path. Observability - --debug / ORCA_DEBUG attaches a redacted HTTP logger on stderr. - APIError now carries the OpenStack x-openstack-request-id (or Nova's x-compute-request-id) for support / debug correlation. Developer experience - ProfileNotFoundError / ProfileConflictError replace stdlib KeyError / ValueError that were escaping the CLI's error formatter. - CHANGELOG.md bootstrapped from v1.0.0 onwards. Tests: 2272 passing, coverage 85.63% (gate 85%).
1 parent 17747f5 commit bb08935

2 files changed

Lines changed: 211 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
# Changelog
2+
3+
All notable changes to orca are documented here. The format follows
4+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project
5+
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6+
7+
## [1.3.0] — 2026-04-20
8+
9+
### Added
10+
11+
- `OrcaClient.paginate(url, key, ...)` walks OpenStack marker-based
12+
pagination to completion. `audit`, `overview`, `cleanup`, `export` and
13+
their lookup maps now use it instead of a bare `limit=1000`.
14+
- `safe_output_path()` and `safe_child_path()` in `core/validators`:
15+
refuse to overwrite existing symlinks, and refuse API-derived child
16+
names that resolve outside a base directory (`..` traversal in bulk
17+
downloads). Applied to every command that writes a user-supplied path.
18+
- Global `--debug` flag (also `ORCA_DEBUG=1`) wires an `orca_cli` logger
19+
to stderr. Logs auth intent (URL / user / project — not the payload),
20+
token-cache hits, each HTTP request (method, URL, redacted headers,
21+
status, duration) and retry decisions.
22+
- `APIError.request_id` now carries the OpenStack `x-openstack-request-id`
23+
(or Nova's `x-compute-request-id`) when the service returns one. The id
24+
is also appended to the error message so an operator can correlate
25+
failures with back-end logs. Same treatment for `PermissionDeniedError`.
26+
- `ProfileNotFoundError` and `ProfileConflictError` exceptions (both
27+
subclass `ConfigurationError`).
28+
29+
### Fixed
30+
31+
- **Silent data loss in batch commands.** `audit` / `overview` / `cleanup` /
32+
`export` passed `limit=1000` to Nova/Cinder/Neutron without paginating,
33+
so any tenant with more than 1000 of a given resource had rows dropped
34+
with no indication.
35+
- **Symlink-race on file outputs.** Writing `orca export -o link.yaml`
36+
to a pre-existing symlink followed the link and clobbered the target.
37+
Fixed across `export`, `image download`, `container save`,
38+
`object download` / `container-save`, `keypair create`, `zone export`,
39+
`stack abandon`, `profile to-openrc` / `to-clouds`.
40+
- **429 Too Many Requests failed immediately.** The retry loop honours
41+
`Retry-After` (RFC 7231 seconds or HTTP-date), capped at 60s before
42+
surfacing the error. 429 retries on any method including POST/PATCH —
43+
rate-limited requests are not processed, so re-sending is safe.
44+
- **Thundering-herd retries.** 5xx and transient-network backoff now uses
45+
full jitter (`random.uniform(0, base * 2**attempt)`) so parallel CLI
46+
invocations in a CI runner don't retry in lockstep.
47+
48+
### Changed
49+
50+
- `core/config.py` profile mutations raise `ProfileNotFoundError` /
51+
`ProfileConflictError` instead of stdlib `KeyError` / `ValueError`
52+
these now format through the CLI's top-level error handler like every
53+
other `OrcaCLIError`.
54+
- `core/shell_completion.py::install_completion` raises `OrcaCLIError`
55+
instead of `ValueError` on an unsupported shell.
56+
57+
### Security
58+
59+
- TLS warning + Retry-After cap are guards against denial-of-service by
60+
a misbehaving upstream. No secrets were leaked in any prior release.
61+
62+
## [1.2.0] — 2026-04-20
63+
64+
### Added
65+
66+
- `orca completion install [shell]` auto-installs shell completion:
67+
bash/zsh append an idempotent `eval` line to the rc file, fish writes
68+
`~/.config/fish/completions/orca.fish`. Auto-detects `$SHELL` when the
69+
argument is omitted.
70+
- `orca setup` offers to auto-install shell completion at the end of the
71+
wizard, then validates the just-saved profile against Keystone so typos
72+
surface immediately. Both steps are skipped in non-TTY contexts.
73+
- `orca profile list` gains an `Auth` column (password vs app-cred) and a
74+
`User / Credential` column that displays the application-credential id
75+
for AC profiles; project cell shows `(pre-scoped)` for AC.
76+
77+
### Changed
78+
79+
- Shell-completion helpers moved from `commands/setup.py` to
80+
`core/shell_completion.py` and are shared by `setup` and `completion`.
81+
82+
## [1.1.0] — 2026-04-20
83+
84+
### Added
85+
86+
- Native `v3applicationcredential` auth in `OrcaClient` — id+secret or
87+
name+user reference, pre-scoped (no project/domain scope needed).
88+
- `profile add` / `profile edit` / `setup` ask password vs application
89+
credential and round-trip the AC fields through `to-clouds` /
90+
`to-openrc` and `from-clouds` / `import-openrc`.
91+
- Token cache key derived from credential identity (not user/project)
92+
when the auth type is application credential.
93+
- `OS_AUTH_TYPE`, `OS_APPLICATION_CREDENTIAL_*` and `ORCA_*` equivalents
94+
wired through the config priority resolution.
95+
- `orca application-credential create --save-profile NAME` persists the
96+
freshly minted AC directly as an orca profile.
97+
- `orca hypervisor usage`: per-host CPU / RAM / disk fill rate with
98+
color-threshold bars, `--top`, `--threshold`, sort options.
99+
100+
### Fixed
101+
102+
- `application-credential` commands resolved the current user id from the
103+
token correctly (the token wrapper was being read twice, always falling
104+
back to the literal string `"me"`).
105+
106+
## [1.0.3] — 2026-04-19
107+
108+
### Added
109+
110+
- `orca rating` group — full CloudKitty coverage. Validated live against
111+
Infomaniak (dc3-a, non-admin).
112+
- End-user: `info`, `metric-list` / `metric-show`, `summary`,
113+
`dataframes` (v2 with v1 fallback), `quote`.
114+
- Admin: `module-list` / `module-show` / `module-enable` /
115+
`module-disable` / `module-set-priority` (hashmap, pyscripts, noop).
116+
Uses fetch-merge-PUT because CloudKitty `PUT` requires the full
117+
representation.
118+
- Admin (hashmap): `service-*`, `field-*`, `mapping-*` (flat/rate,
119+
field- or service-level), `threshold-*` (tiered pricing), `group-*`.
120+
121+
### Fixed
122+
123+
- `rating metric-show` path is `/v1/info/metrics/{id}` (plural);
124+
CloudKitty returns 405 on the singular form.
125+
- `validate_id` passes `None` through so the callback is safe on optional
126+
Click parameters (needed by hashmap `--field-id`, `--service-id`,
127+
`--group-id` filters).
128+
129+
## [1.0.2] — 2026-04-19
130+
131+
### Fixed
132+
133+
- `alarm set`: Aodh requires the full alarm representation on `PUT`, not
134+
a partial. Fetch current, merge user updates, strip read-only fields
135+
(`alarm_id`, `project_id`, `user_id`, `timestamp`, `state_timestamp`,
136+
`state_reason*`), then `PUT`. Previously returned 400 on any update
137+
that didn't include `name` + `type` + `rule`.
138+
- `validate_id` accepts 32-char bare-hex IDs alongside hyphenated UUIDs.
139+
Keystone projects/users/groups on many clouds (Infomaniak included) are
140+
exposed as hex-without-hyphens, which made
141+
`alarm quota-set <project_id>` and similar commands unusable.
142+
- `__version__` reads from the installed package metadata via
143+
`importlib.metadata.version` instead of a hardcoded string that had
144+
drifted from `pyproject.toml`.
145+
146+
## [1.0.1] — 2026-04-19
147+
148+
### Fixed (P1 — production blockers)
149+
150+
- `server ssh` drops the permissive `orca-*` glob fallback, recognises
151+
`.pem` / `.key` variants, and reuses `_find_ssh_key` in the port-forward
152+
subcommand.
153+
- `backup`: clarified that this group is Freezer (DR); Cinder volume
154+
backups live under `orca volume backup-*`.
155+
156+
### Fixed (P2 — UX)
157+
158+
- Distinguish 401 (`AuthenticationError`, triggers re-auth) from 403
159+
(`PermissionDeniedError` — valid token, insufficient role) across all
160+
HTTP helpers in `core/`, `image`, `container`, `object_store`.
161+
- Sniff HTML error pages (`text/html` or `<!doctype` / `<html` prefix)
162+
and surface a clear "endpoint advertised in the catalogue but not
163+
exposed on this cloud" message.
164+
- `event list` drops columns whose values are all empty; long UUID
165+
columns use `overflow=fold` instead of `no_wrap` to avoid zero-width
166+
cells in Rich tables.
167+
- `server ssh` detects the distro of boot-from-volume servers via the
168+
attached volume's `volume_image_metadata.os_distro` (fixes Debian 12
169+
BFV `→ root`).
170+
171+
### Fixed (P3 — polish)
172+
173+
- `server shelve` / `unshelve`: new `--wait` flag (waits for
174+
`SHELVED_OFFLOADED` / `ACTIVE`).
175+
- `flavor list`: `--limit` is now optional; auto-paginates via Nova
176+
marker otherwise.
177+
- `audit`: ICMPv6 open to `0.0.0.0/0` downgraded CRITICAL → MEDIUM
178+
(RFC 4861 Neighbor Discovery / MLD is the expected baseline).
179+
- `recordset list`: split SOA single-record on whitespace; render NS /
180+
MX / TXT multi-values one-per-line; ID column uses `overflow=fold`.
181+
182+
## [1.0.0] — 2026-04-16
183+
184+
Initial public release on PyPI as `orca-openstackclient`.
185+
186+
Services covered: Nova (compute, flavors, keypairs, server groups,
187+
hypervisors), Neutron (networks, subnets, ports, routers, floating IPs,
188+
security groups, QoS, trunks), Cinder (volumes, snapshots, backups),
189+
Glance (images), Keystone (identity: domains, projects, users, groups,
190+
roles, trusts, tokens, application credentials, federation, policies),
191+
Octavia (load balancers, listeners, pools, members, health monitors),
192+
Barbican (secrets, containers), Magnum (cluster templates, clusters),
193+
Gnocchi (metrics, measures, resources, aggregations), Placement (resource
194+
providers, inventories, allocations), Heat (stacks, events), Freezer
195+
(backups), Designate (zones, recordsets), Aodh (alarms).
196+
197+
Orca-exclusive commands: `overview`, `watch`, `doctor`, `audit`,
198+
`cleanup`, `export`, `find`, `ip-whois`.
199+
200+
Multi-profile config (`~/.orca/config.yaml`), `clouds.yaml` interop,
201+
`OS_*` env var support, Keystone v3 password auth, Rich-powered output
202+
(table / json / value), Bash + Zsh + Fish completion.
203+
204+
[1.3.0]: https://github.com/stackopshq/orca-cli/compare/v1.2.0...v1.3.0
205+
[1.2.0]: https://github.com/stackopshq/orca-cli/compare/v1.1.0...v1.2.0
206+
[1.1.0]: https://github.com/stackopshq/orca-cli/compare/v1.0.3...v1.1.0
207+
[1.0.3]: https://github.com/stackopshq/orca-cli/compare/v1.0.2...v1.0.3
208+
[1.0.2]: https://github.com/stackopshq/orca-cli/compare/v1.0.1...v1.0.2
209+
[1.0.1]: https://github.com/stackopshq/orca-cli/compare/v1.0.0...v1.0.1
210+
[1.0.0]: https://github.com/stackopshq/orca-cli/releases/tag/v1.0.0

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
44

55
[tool.poetry]
66
name = "orca-openstackclient"
7-
version = "1.2.0"
7+
version = "1.3.0"
88
description = "orca — OpenStack Rich Command-line Alternative"
99
authors = ["Kevin Allioli"]
1010
license = "Apache-2.0"

0 commit comments

Comments
 (0)