Add an osism openstack command that wraps the OpenStack CLI#2392
Open
berendt wants to merge 3 commits into
Open
Add an osism openstack command that wraps the OpenStack CLI#2392berendt wants to merge 3 commits into
berendt wants to merge 3 commits into
Conversation
The new `osism openstack` command shells out to the `openstack` CLI, which ships with python-openstackclient. The binary was not a declared dependency (only the openstacksdk library was), so the feature would be non-functional in the image without it. Pin to 9.0.0, the highest release compatible with the pinned openstacksdk==4.10.0 (it requires openstacksdk>=4.6.0; 10.x requires >=4.12.0/>=4.14.0). Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Christian Berendt <berendt@osism.tech>
There was a problem hiding this comment.
Hey - I've found 1 security issue, 1 other issue, and left some high level feedback:
Security issues:
- Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. (link)
General comments:
- In
Run.take_action, whensetup_cloud_environmentreturnssuccess=Falseyou return early and never callcleanup_cloud_environment, which may leave temp files or the working directory in an inconsistent state ifsetup_cloud_environmentpartially succeeded; consider always invokingcleanup_cloud_environment(e.g. via atry/finally) once setup has been called. - The wrapper unconditionally injects
--os-cloud <cloud>before the passthrough arguments; if a user also supplies their own--os-cloudinarguments, the resulting behavior may be confusing or order-dependent—consider explicitly rejecting or documenting conflicting--os-cloudusage to avoid ambiguity.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `Run.take_action`, when `setup_cloud_environment` returns `success=False` you return early and never call `cleanup_cloud_environment`, which may leave temp files or the working directory in an inconsistent state if `setup_cloud_environment` partially succeeded; consider always invoking `cleanup_cloud_environment` (e.g. via a `try/finally`) once setup has been called.
- The wrapper unconditionally injects `--os-cloud <cloud>` before the passthrough arguments; if a user also supplies their own `--os-cloud` in `arguments`, the resulting behavior may be confusing or order-dependent—consider explicitly rejecting or documenting conflicting `--os-cloud` usage to avoid ambiguity.
## Individual Comments
### Comment 1
<location path="CHANGELOG.md" line_range="11" />
<code_context>
+## [Unreleased]
+
+### Added
+- `osism openstack` command that runs the OpenStack CLI against a configured cloud (default `admin`), reusing the flavor-/image-manager cloud credential handling (osism/python-osism#2391)
+
## [v0.20260319.0] - 2026-03-19
</code_context>
<issue_to_address>
**suggestion (typo):** Consider clarifying the phrase "flavor-/image-manager" for readability.
The hyphen before the slash makes this hard to parse. Consider alternatives like “flavor and image manager”, “flavor/image manager”, or explicitly “flavor-manager/image-manager” to improve readability.
```suggestion
- `osism openstack` command that runs the OpenStack CLI against a configured cloud (default `admin`), reusing the flavor and image manager cloud credential handling (osism/python-osism#2391)
```
</issue_to_address>
### Comment 2
<location path="osism/commands/openstack.py" line_range="49" />
<code_context>
result = subprocess.run(command, check=False)
</code_context>
<issue_to_address>
**security (python.lang.security.audit.dangerous-subprocess-use-audit):** Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'.
*Source: opengrep*
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
3bd12f4 to
42a9f48
Compare
Add an `osism openstack` command that transparently wraps the OpenStack CLI: it passes all subcommands and parameters straight through to the `openstack` client and propagates its exit code. Credentials are loaded the same way the flavor-manager and image-manager do, via setup_cloud_environment/get_cloud_helpers from osism.tasks.openstack, which decrypts secrets.yml from the configuration repository. This removes the need for a separate openstack container that cannot read the encrypted secure.yml. The command defaults to the admin cloud and selects it explicitly with --cloud; --os-cloud is injected so the client picks the profile whose password setup_cloud_environment wrote into the temporary clouds.yaml. Register both `openstack` and the existing `openstack stress` entry points; cliff resolves the longest matching command prefix, so `openstack stress` keeps routing to OpenStackStress while `openstack server list` routes to the new command. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Christian Berendt <berendt@osism.tech>
Cover argument passthrough with the default admin cloud, --cloud selection, the setup-failure short circuit, exit-code propagation, a missing openstack binary, and cliff longest-prefix routing that keeps `openstack stress` working alongside the new command. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Christian Berendt <berendt@osism.tech>
42a9f48 to
8c88427
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an
osism openstackcommand that transparently wraps the OpenStackCLI from inside the osism container image. It passes all subcommands and
parameters straight through to the
openstackclient, defaults to theadmincloud, and lets the cloud be selected with--cloud.Credentials are loaded the same way the flavor-manager and image-manager
do — via
setup_cloud_environment/get_cloud_helpersfromosism/tasks/openstack.py, which decryptssecrets.yml/secure.ymlfrom the configuration repository. This removes the need for a separate
openstack container that cannot read the encrypted
secure.yml.The command runs the client in-process (
subprocess.run), structurallymirroring the existing
osism openstack stresscommand, so stdout/stderrand the exit code pass through unmodified — the behaviour an operator
expects from a transparent wrapper.
Closes #2391
Changes (in commit order)
python-openstackclientruntime dependency —requirements.txt. Theopenstackbinary the command shells out toships with
python-openstackclient, which was not a declareddependency (only the
openstacksdklibrary was). Pinned to9.0.0,the highest release compatible with the pinned
openstacksdk==4.10.0(it requires
openstacksdk>=4.6.0; 10.x requires>=4.12.0/>=4.14.0and would conflict).
osism openstackpassthrough command —osism/commands/openstack.py+setup.cfg. The command and its entrypoint land together so the CLI is never half-registered.
--os-cloudis injected so the client selects the profile whose password
setup_cloud_environmentwrote into the temporaryclouds.yaml.Both
openstackand the existingopenstack stressentry points areregistered; cliff resolves the longest matching command prefix, so
openstack stresskeeps routing toOpenStackStresswhileopenstack server listroutes to the new command.tests/unit/commands/test_openstack.py. Coverargument passthrough with the default
admincloud,--cloudselection, the setup-failure short circuit, exit-code propagation, a
missing
openstackbinary, and the cliff routing coexistence withopenstack stress.osism openstackin CHANGELOG —CHANGELOG.md.Notes for reviewers
flavor-manager and image-manager do," which dispatch a Celery task on
the
openstackworker queue. This change reuses the same credentialhelpers but runs the client in-process (like
osism openstack stress) rather than via a Celery task. Only the in-process modeldelivers a true transparent wrapper — real exit codes and stdio/TTY
passthrough; a Celery round-trip would stream output through Redis and
lose exit-code/interactivity transparency.
stressis now a reserved word underosism openstack. Plainopenstackhas nostresssubcommand, so nothing real is lost.setup_cloud_environmentos.chdir("/tmp"), sorelative paths in passed-through commands resolve against
/tmp. Thisis pre-existing behaviour shared with
stress/the managers, notintroduced here.
Drafted by planwerk-review e69a237 with Claude:claude-opus-4-8