Skip to content

feat: close network/server flag-parity gaps found by a cleanup script - #31

Merged
ftarasenko merged 3 commits into
masterfrom
claude/stoic-brahmagupta-py29py
Sep 22, 2026
Merged

ftarasenko merged 3 commits into
masterfrom
claude/stoic-brahmagupta-py29py

Conversation

@ftarasenko

Copy link
Copy Markdown
Owner

Closes the koc/openstack flag gaps that a real cleanup script hit. Each gap forced a separate code path in the script, and one of them silently skipped every router. All flag names and behaviour were checked against python-openstackclient 10.3.0's parsers.

Changes

router list (internal/cli/network/router.go)

  • New flags: --project/--project-domain, --enable/--disable, --tags/--any-tags/--not-tags/--not-any-tags, --long, --agent <id>. Before this, the only flag was --name, so --project failed with a usage error (exit 2).
  • Distributed and HA columns appear whenever neutron returns those fields, which matches upstream (neutron only returns them to admins). --long adds Routes, External gateway info, Availability zones (only when the router_availability_zone extension reports them) and Tags.
  • --agent lists the routers from /agents/{id}/l3-routers. That endpoint accepts no query filters, so the other filters are applied client-side.

router show: adds upstream's interfaces_info, built the same way upstream builds it: list the router's ports by device_id, skip the gateway port, and add one entry per fixed IP.

security group list (internal/cli/network/securitygroup.go)

  • New flags: --project/--project-domain, the four tag filters, --share/--no-share, plus an exact --name that is koc-only (upstream has no name filter). Before this there were no filters at all.
  • Adds upstream's Tags and Shared columns.
  • gophercloud's groups.List has no shared option and no ExtractGroupsInto, so the pager is built in a small separate helper (listSecGroups).

--all-projects on both list verbs is a koc-only no-op that honours ALL_PROJECTS and is refused with --project. It works like the existing port list one: neutron has no cross-project switch, and both tables already show Project. It exists so a script that passes it gets a listing instead of a usage error.

server delete (internal/cli/server/server.go, state.go)

  • --wait/--wait-timeout sends every DELETE first, then polls each server until nova returns 404, and prints Deleted server X only after that.
  • A SOFT_DELETED server fails the wait immediately and suggests --force, rather than waiting until the timeout while the server still holds its ports.
  • --force sends nova's forceDelete action, as upstream does.

Docs: docs/coverage.md and the README "Known limitations" section now cover the new koc-only flags. The command count doesn't change: no commands were added or removed.

Deliberately not changed: -f value keeps its tab separator. docs/coverage.md records that as a deliberate deviation, and changing it needs a separate decision.

Verification

  • go test ./..., go vet, golangci-lint v2.13.2 (the version CI pins): 0 issues. gofmt is clean, and the offline static build (-mod=vendor, GOPROXY=off) succeeds.
  • New tests: the full query string for every filter, interfaces_info shape and key order, column presence rules for --long and admin-only fields, client-side filtering for --agent, --share/--no-share, server delete --wait (all DELETEs before any polling, confirmation only after 404), fail-fast on SOFT_DELETED, and --force sending only the action.
  • Ran the built koc end-to-end against a local mock of keystone, neutron and nova, and checked the request log for each new flag. Not run against a real cloud.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RCegCom2HEfpHM4H58tBfa


Generated by Claude Code

… interfaces_info

`router list` accepted only --name, so `--project` exited 2 with a usage
error; it now takes upstream's --project/--project-domain, --enable/--disable
and the tag filters. `security group list` took no filters at all; it now
takes --project/--project-domain, the tag filters and a koc-native exact
--name, and shows upstream's Tags column.

Both also accept --all-projects (defaulting from ALL_PROJECTS, exclusive with
--project). Neutron has no cross-project switch and both tables already show
the Project column, so it changes nothing; it exists so a script carrying it
gets a listing instead of a usage error.

`router show` now emits upstream's interfaces_info: one entry per fixed IP of
each non-gateway port with device_id=<router>, the same extra port list
upstream does, so callers no longer need their own `port list --router`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RCegCom2HEfpHM4H58tBfa
`server delete --wait` issues every DELETE, then polls each server until
nova answers 404 — the point its ports are released — and prints the
confirmation only then, so cleanup scripts no longer need their own poll
loop. --wait-timeout bounds it per server. A SOFT_DELETED server fails the
wait immediately (nova's reclaim window would outlast any timeout) and points
at --force, which sends nova's forceDelete action as upstream's does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RCegCom2HEfpHM4H58tBfa
… --share/--no-share

`router list --long` adds upstream's Routes, External gateway info,
Availability zones (when the router_availability_zone extension reports
them) and Tags columns; Distributed and HA now appear whenever neutron
returned them, as upstream shows them. `--agent <id>` lists the L3 agent's
hosted routers and re-applies the other filters client-side, since that
subresource takes no query parameters.

`security group list --share/--no-share` sends neutron's `shared` filter,
and the list gains upstream's Shared column. gophercloud's groups.List has
no builder or shared field, so the pager is built by a small isolated helper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RCegCom2HEfpHM4H58tBfa
@ftarasenko
ftarasenko merged commit 0762385 into master Sep 22, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants