Skip to content

feat: Volume/FIP Attach-Detach — Bidirectional Operations (#61)#61

Merged
bluejayA merged 14 commits into
mainfrom
feature/volume-fip-attach-detach
Apr 8, 2026
Merged

feat: Volume/FIP Attach-Detach — Bidirectional Operations (#61)#61
bluejayA merged 14 commits into
mainfrom
feature/volume-fip-attach-detach

Conversation

@bluejayA
Copy link
Copy Markdown
Owner

@bluejayA bluejayA commented Apr 8, 2026

Summary

  • Volume Attach/Detach + Force Detach + State Reset 워크플로우 추가
  • FloatingIP Associate/Disassociate 워크플로우 추가
  • Server 상세에서 양방향 진입점 (A/x/f 키)
  • SelectPopup 인라인 검색 (/ 키), ConfirmDialog 상세 정보 표시
  • CrossTenantGuard (all_tenants 차단 + break-glass)
  • TransitionGuard (전이 상태 키 비활성화)
  • AuditLogger 인프라 (JSON Lines + rotation)
  • Port 모델 + ActionKind::Attach/Detach RBAC

Changes (18 files, +3313 lines)

  • Action/AppEvent/PendingAction: 7/7/6개 변형 추가
  • Port layer: force_detach_volume, list_ports, Port 모델
  • VolumeModule: a/x/D/F/R 키 + 부트볼륨 보호
  • FloatingIpModule: a/x/D 키 + FetchPorts 비동기 2단계
  • ServerModule: A/x/f 키 + 양방향 진입
  • UI: SelectPopup 검색, ConfirmDialog detail_lines
  • Infra: CrossTenantGuard, TransitionGuard, ActionKind 확장

Test plan

  • 1017 tests passed (baseline 866 + 151 new)
  • cargo build 성공
  • DevStack 환경 실제 Attach/Detach 테스트
  • DevStack 환경 FIP Associate/Disassociate 테스트
  • 리뷰 후속: C-1(HTTP adapter stub 검증), C-3(PortsLoaded server_id 매칭), C-4(ServerModule cached_networks)

🤖 Generated with Claude Code

bluejayA and others added 2 commits April 8, 2026 09:02
Add bidirectional attach/detach/associate/disassociate operations for
cloud infrastructure operators. Includes safety guards, audit logging
infrastructure, and enhanced UI components.

Key changes:
- Volume: a(attach), x(detach), D(delete), F(force detach), R(state reset)
- FloatingIP: a(associate), x(disassociate), D(delete)
- Server detail: A(attach vol), x(detach vol), f(associate FIP)
- SelectPopup inline search (/ key with mode-aware navigation)
- ConfirmDialog detail_lines for rich confirmation context
- CrossTenantGuard: all_tenants CUD block + break-glass toggle
- TransitionGuard: attaching/detaching state key disable
- AuditLogger infrastructure (JSON Lines + rotation)
- Port model + CinderPort::force_detach + NeutronPort::list_ports
- ActionKind::Attach/Detach RBAC with preflight checks
- Keymap migration hints (d→D transition)

Tests: 866 → 1017 (+151)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…achVolume

- Move attach_volume/detach_volume from CinderPort stubs to NovaPort
  (Nova os-volume_attachments API is the correct endpoint)
- Add server_id field to DetachVolume/ForceDetachVolume Action/PendingAction
  (needed for Nova DELETE /servers/{id}/os-volume_attachments/{vol_id})
- Implement NovaHttpAdapter::attach_volume (POST) and detach_volume (DELETE)
- Add NovaPort mock implementations
- Fix all test pattern matches to include server_id

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
bluejayA and others added 12 commits April 8, 2026 10:56
- Add volumes_attached field to Server model (os-extended-volumes API)
- Add AttachedVolume model with id and delete_on_termination
- Display Volumes section in server detail with name, size, status, device
- Resolve volume details from cached_volumes for rich display

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resolve server_id to "server-name (uuid-prefix)" using cached_servers.
Operators can now identify attached servers without memorizing UUIDs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Displays volume count per server in the list view for quick visibility.
Shows "-" when no volumes attached, count number otherwise.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Display Server Name and Server ID as separate full columns instead of
truncated "name (uuid-prefix)" format. Operators need both for reference.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previously 404 errors discarded the response body, showing only
"Not found: " with empty fields. Now the body is preserved in the id
field so operators see the actual error (e.g. Neutron's
"ExternalGatewayForFloatingIPNotFound" message).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Parse NeutronError, badRequest, itemNotFound, etc. to extract the
"message" field instead of dumping raw JSON into toast messages.
Operators now see actionable error text instead of truncated JSON.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Show associated floating IPs with address mapping (FIP → fixed IP),
ID, and status. Matches FIPs from cached data by comparing floating
IP addresses in server.addresses with cached_floating_ips.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Admin UX principle: interconnected resources should show connection
points everywhere.

- Volume list "Attached To": show server name + device instead of UUID
- FIP list: replace "Network ID" column with "Associated Server" showing
  resolved server name via port_id → device_id → server name lookup

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ShowToast for 'd' key hint was sent via action_tx (worker channel) which
ignores it. Changed to return Some(Action::ShowToast) from handle_key
so App::dispatch_action processes it directly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update local FIP status/port_id immediately on event receipt for instant
visual feedback in the list view, before async FetchFloatingIps completes.
Move re-associate hint to generate_toast for proper display.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
App-level search mode was setting input_mode to Search but had no key
handling beyond Esc, causing the UI to freeze. Disabled it so '/' is
now only handled by SelectPopup when open.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… detach

P1 fixes from Codex review:

- PortsLoaded: track pending_ports_server_id and reject mismatched
  responses to prevent associating FIP with wrong server's ports
  (both ServerModule and FloatingIpModule)
- Server detail detach: apply same boot volume safeguard as VolumeModule
  (non-admin blocked, admin requires TypeToConfirm with warning)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@bluejayA bluejayA merged commit 84932c6 into main Apr 8, 2026
@bluejayA bluejayA deleted the feature/volume-fip-attach-detach branch April 13, 2026 08:18
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.

1 participant