Skip to content
This repository was archived by the owner on Jul 13, 2026. It is now read-only.

OSC plugins#22

Open
Akrog wants to merge 5 commits into
openstack-lightspeed:mainfrom
Akrog:osc-plugins
Open

OSC plugins#22
Akrog wants to merge 5 commits into
openstack-lightspeed:mainfrom
Akrog:osc-plugins

Conversation

@Akrog

@Akrog Akrog commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

This commit changes our container image because it's currently missing
almost all the OSC plugins, unlike the openstackclient image.

In this patch we ensure the image includes the plugins by:

  • Adding the plugins to the project dependencies in the osc-plugin
    dependency group.

  • Changing the source for all our openstack related packages, so instead
    of using PyPi to install them we use RPMs by using the
    openstackclient container image as the base.

  • We use the Centos 10 base image of the openstackclient container so
    it has Python 3.12 instead of 3.9 that is in the Centos 9 container
    (quay.io/podified-antelope-centos9/openstack-openstackclient:current-podified)
    because the MCP python library has a minimum requirement of Python
    3.10.

This not only resolves the missing plugins, but also ensures that the
packages used are not coming from PyPi, facilitating a more
secure downstream release.

Available plugins are sent as part of the openstack-cli MCP tool
description to help LLMs know what is installed, as they may assume only
basic commands are available.

We also update the allowed commands on read-only mode.

In adition the PR includes a couple of minor improvements to the MCP tool.

Summary by CodeRabbit

  • New Features

    • OpenStack CLI tool help now lists detected installed plugins and provides clearer “not a shell / no pipes” usage guidance.
    • Runtime images now reuse a prepared environment and include the oc CLI for smoother startup.
  • Bug Fixes

    • Improved command execution so stderr is captured more reliably during help/version discovery and interactive runs.
    • Updated credential/TLS bundle copying to use the correct namespace.
    • Expanded allow/deny filtering to better ignore unsupported observability, placement, share, alarm, and rating commands.
  • Chores / Build

    • Refreshed image build to parameterize base images and prepare the venv once for reuse.

Akrog added 4 commits June 24, 2026 16:48
When an MCP request to OpenStack is received with incorrect arguments we
fail to return the error in the `stderr` field so it's always an empty
string.

This is because argparse ignores the `stderr` argument we pass to the
shell itself.

With this patch we fix it by ensuring we redirect the whole stderr when
running the command.
We are currently seeing some errors logged multiple times. With this
patch we remove the cliff log handlers when running commands removing
duplicated errors on the console.
Some LLMs don't understand that available tools are not shell commands,
so they send shell commands with pipes.

In this patch we try to guard against such explicitly errors by
explicitly stating that the tools are not shell.
The `get-crc-creds.sh` script expects the currently selected project to
be `openstack`, but that's unlikely to happen if we are doing things on
the `openstack-lightspeed` namespace.

In this patch we update the script so it explicit sets the namespace on
the `oc` commands.
@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Akrog, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 50 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cc58c2ae-4830-403f-ad23-f957cd327f99

📥 Commits

Reviewing files that changed from the base of the PR and between 1910b12 and e2300dc.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • Containerfile
  • pyproject.toml
  • scripts/allow-deny-list.py
  • scripts/allow-deny-list.yaml
  • src/rhos_ls_mcps/osc.py
📝 Walkthrough

Walkthrough

The PR parameterizes the container build, adds an OSC plugin dependency group, updates OpenStack CLI shell behavior for plugin discovery and stderr handling, expands command filtering for new plugin namespaces, and scopes CRC credential copies to the openstack namespace.

Changes

OSC Plugin Support and Container Build Restructure

Layer / File(s) Summary
Container build parameterization and osc-plugins dependency group
Containerfile, pyproject.toml
ARG BUILDER_IMAGE/ARG BASE_IMAGE replace hard-coded image references. uv sync now excludes openstackclient, python-openstackclient, and stevedore, a sed step enables include-system-site-packages = true in the venv, and the final stage copies .venv and oc from the builder. pyproject.toml adds an osc-plugins dependency group listing OSC plugin packages.
Dynamic plugin discovery and stderr/logging fixes
src/rhos_ls_mcps/osc.py
get_installed_plugins() enumerates openstack.cli.extension entry points and returns a docstring fragment. configure_logging() removes root logger handlers added by the parent. _do_run gains a redirect flag that temporarily assigns sys.stderr to the shell's buffer with finally-block restoration. _initialize_api_versions calls _do_run with redirect=False.
Tool docstrings and command filtering
src/rhos_ls_mcps/osc.py, src/rhos_ls_mcps/oc.py, scripts/allow-deny-list.py
openstack_cli_mcp_tool docstring embeds get_installed_plugins() output and revised usage guidance. REJECT_COMMANDS gains five new command names; IGNORE_COMMANDS gains five new prefix patterns for new plugin namespaces. oc.py tool docstring notes that pipes are unsupported.
Namespace-scoped credential copies
scripts/get-crc-creds.sh
All three oc cp commands are updated with -n openstack to scope TLS CA bundle and credential file copies to the openstack namespace.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is related to the change, but it is too generic to clearly convey the main update. Use a more specific title that mentions the OpenStackClient plugin support and image/runtime changes.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 85.71% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/rhos_ls_mcps/osc.py (1)

195-220: 🩺 Stability & Availability | 🟡 Minor

Restore a real docstring here

An f-string in the first statement does not populate __doc__, so the tool description and get_installed_plugins() output are dropped for docstring-based tool registration. Use a plain docstring and assign the rendered plugin text afterward, or set openstack_cli_mcp_tool.__doc__ explicitly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/rhos_ls_mcps/osc.py` around lines 195 - 220, The first statement in the
`openstack_cli_mcp_tool` definition is an f-string, so it does not become the
function’s `__doc__` and the tool registration loses the description and plugin
text. Change it to a plain docstring for the static documentation, then append
the `get_installed_plugins()` output separately or assign
`openstack_cli_mcp_tool.__doc__` explicitly after definition so the full tool
description is preserved.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/rhos_ls_mcps/osc.py`:
- Around line 156-195: Update the docstring in get_installed_plugins to fix the
wording typos: change “if there are not OSC plugins” to “if there are no OSC
plugins,” and make “The list ready to be injected” read “The list is ready to be
injected.” Keep the rest of the docstring unchanged and ensure the wording
remains clear and grammatical.
- Around line 183-190: The get_installed_plugins() logic in osc.py assumes every
entry point name exists in plugin_names, which can raise a KeyError for unknown
or future extensions. Update the list construction around
entry_points(group="openstack.cli.extension") to look up names safely and skip
or fall back for missing keys so only known plugin names are included. Keep the
existing return format in get_installed_plugins(), but ensure unknown entry
point names do not crash the docstring rendering path.

---

Outside diff comments:
In `@src/rhos_ls_mcps/osc.py`:
- Around line 195-220: The first statement in the `openstack_cli_mcp_tool`
definition is an f-string, so it does not become the function’s `__doc__` and
the tool registration loses the description and plugin text. Change it to a
plain docstring for the static documentation, then append the
`get_installed_plugins()` output separately or assign
`openstack_cli_mcp_tool.__doc__` explicitly after definition so the full tool
description is preserved.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b2695a13-b02c-4ee7-aa5e-83a1f83788c2

📥 Commits

Reviewing files that changed from the base of the PR and between b0c6d04 and 6ccd53f.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • Containerfile
  • pyproject.toml
  • scripts/allow-deny-list.py
  • scripts/allow-deny-list.yaml
  • scripts/get-crc-creds.sh
  • src/rhos_ls_mcps/oc.py
  • src/rhos_ls_mcps/osc.py

Comment thread src/rhos_ls_mcps/osc.py
Comment on lines +156 to +195
def get_installed_plugins():
"""List installed OSC plugins

Return a string with a list of installed OSC plugins in an LLM friendly
format. The list ready to be injected into a docstring.

Return an empty string if there are not OSC plugins.
"""

from importlib.metadata import entry_points

plugin_names = {
"metric": "AODH (metrics)",
"placement": "Placement",
"key_manager": "Barbican (key manager)",
"rating": "CloudKitty (rating)",
"dns": "Designate (DNS)",
"orchestration": "Heat (orchestration)",
"baremetal-introsp": "Ironic Inspector (baremetal introspection)",
"baremetal": "Ironic (baremetal)",
"share": "Manila (shared file systems)",
"neutronclient": "Neutron (networking)",
"observabilityclient": "Prometheus (observability)",
"load_balancer": "Octavia (load balancer)",
"infra_optim": "Watcher (infra optimization)",
}

names = [
plugin_names[ep.name]
for ep in entry_points(group="openstack.cli.extension")
]

if names:
return "\nInstalled extra plugins:\n- " + "\n- ".join(names)
return ""


@tool_logger
async def openstack_cli_mcp_tool(command_str: str, ctx: Context) -> str:
"""Run an OpenStackClient (OSC) CLI command
f"""Run an OpenStackClient (OSC) CLI command

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Minor: docstring typo — "if there are not OSC plugins" should read "if there are no OSC plugins", and "The list ready to be injected" should be "The list is ready to be injected".

🧰 Tools
🪛 GitHub Actions: Pre-commit checks / 0_pre-commit.txt

[error] 181-181: Pre-commit hook 'ruff-format' failed (files were modified). Ruff formatted code in this file and CI exited with code 1. Diff indicates a list-comprehension was reformatted.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/rhos_ls_mcps/osc.py` around lines 156 - 195, Update the docstring in
get_installed_plugins to fix the wording typos: change “if there are not OSC
plugins” to “if there are no OSC plugins,” and make “The list ready to be
injected” read “The list is ready to be injected.” Keep the rest of the
docstring unchanged and ensure the wording remains clear and grammatical.

Comment thread src/rhos_ls_mcps/osc.py
This commit changes our container image because it's currently missing
almost all the OSC plugins, unlike the `openstackclient` image.

In this patch we ensure the image includes the plugins by:

* Adding the plugins to the project dependencies in the `osc-plugin`
  dependency group.

* Changing the source for all our openstack related packages, so instead
  of using PyPi to install them we use RPMs by using the
  `openstackclient` container image as the base.

* We use the Centos 10 base image of the `openstackclient` container so
  it has Python 3.12 instead of 3.9 that is in the Centos 9 container
  (quay.io/podified-antelope-centos9/openstack-openstackclient:current-podified)
  because the MCP python library has a minimum requirement of Python
  3.10.

This not only resolves the missing plugins, but also ensures that the
packages used are not coming from PyPi, facilitating a more
secure downstream release.

Available plugins are sent as part of the `openstack-cli` MCP tool
description to help LLMs know what is installed, as they may assume only
basic commands are available.

We also update the allowed commands on read-only mode.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant