Commit graph

171 commits

Author SHA1 Message Date
d23b5b7cb0 revert(managed-ne): keep bulk import NE-only
Remove hop columns from the import template and stop applying hop settings during import; use Batch add proxy instead.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-05 15:16:12 +08:00
7d74e7b3f4 feat(managed-ne): optional password and hop columns in import
Allow creating/importing NEs without target password for bastion-managed workflows, and support optional hop_* columns in bulk import templates.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-05 11:23:57 +08:00
bac4a609b1 docs(managed-ne): use placeholder IPs in bastion hop examples
Replace real site addresses with 1.1.1.1/2.2.2.2 and generic usernames in i18n hints and tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-05 10:59:32 +08:00
d3d7f62a02 feat(managed-ne): add bastion SSH protocol proxy hop type
Support composite-username bastion login for automated connect-test and exec, with bastion-managed or manual target credential modes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-05 10:47:52 +08:00
e62f4f2c74 fix(ume): block WSS until startup REST alarm sync completes
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-04 21:52:39 +08:00
7a729413ab fix(ume): prefer WSS at boot; defer REST grace and avoid parallel sync
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-04 21:47:26 +08:00
65e0713e94 fix(startup): defer alarm pull 60s; health probe accepts only HTTP 200
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-04 21:32:07 +08:00
f562f50953 fix(startup): defer UME alarm sync so /health is ready quickly
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-04 21:28:57 +08:00
0361472ede fix(ne-exec): allow only show/display CLI and harden agent injection
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-04 20:51:06 +08:00
1784d996dd fix(ume): dedupe WSS logs on disconnect and unchanged alarms
Throttle repeated connection-state logs, skip unchanged alarm notifications, and suppress duplicate subscription-lost and parse-ignore messages.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-01 19:33:15 +08:00
45ce9d3f7e feat(mcp): add netx-mcp package and HTTP stdio MCP
- Extract installable packages/netx-mcp (12 HTTP tools, mcp.json)

- Delegate netx_api.mcp to netx_mcp; keep legacy db_server shim

- Add docs/MCP.md, install payload, pyproject entry, tests

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-30 15:44:32 +08:00
981347b5b1 feat(ne): add managed NE read-only exec API
Add a guarded managed-ne exec endpoint for oclaw ops tools to login managed devices and run read-only CLI safely.
Include request schema and unit tests for command guardrails and execution flow.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 22:12:50 +08:00
dc17f9d15a feat(ne): connect detail, Huawei/Cisco hop, Cisco hostname probe
Persist full connect test logs (connect_detail) with NE UI detail modal.
Add Huawei/Cisco jump CLI templates and generic CLI hop session path.
Probe Cisco hostname via show configuration | include hostname (60s timeout).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 21:50:41 +08:00
778442dc57 feat(ne): batch delete selected managed network elements
Add POST /v1/managed-ne/batch-delete and toolbar button with confirmation on NE management page.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 19:02:16 +08:00
d3eae3351c feat(ne): add Linux SSH bastion hop type
Support hop_vendor=linux via Paramiko direct-tcpip tunnel; ZTE CLI hop unchanged. UI hop type selector and distinct list badges.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 17:38:37 +08:00
d395aa7174 feat(ne): batch apply jump proxy on selected NEs
Add POST /v1/managed-ne/batch-hop, shared HopProxyFields form, and toolbar button next to connectivity test.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 17:28:14 +08:00
4575fef523 feat(ne): ZTE jump host for connect test and collection
Add hop fields and encrypted credentials, unified Netmiko session factory with ZTE ssh/telnet CLI templates and secondary auth, wire connect/collect paths, and NE management UI with auto-suggested jump commands.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 17:14:49 +08:00
d512679425 fix(collect): stabilize start flow and default collapse create panel
Avoid false running-state conflicts when starting draft jobs, block overlapping NE runs across jobs, and default the create panel to collapsed for cleaner task-first operation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 10:58:17 +08:00
f1ed4fe753 feat(collect): draft jobs, merged create UI, and unified start
Create collection jobs without auto-running; add /start for first run and re-run. Merge create form with filterable NE picker and selected list.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 10:36:47 +08:00
fed7f56ad0 fix: collection first-run pending and module tab cross-nav
Defer collection scheduling to BackgroundTasks after commit; claim pending runs atomically with retries. Only handle focus-module broadcasts for the matching moduleId so opening one module does not rewrite other tabs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 10:22:11 +08:00
3413d5bf32 fix(collection): correct run status during jobs and add retry-failed
Fix pending mislabeled as fail due to timezone and queue stale checks, show full error details, sync live progress counts, and add retry-failed endpoint for failed NEs only.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 10:05:20 +08:00
3024e13812 feat(managed-ne): add bulk import template download with device_type reference sheet
Expose GET /v1/managed-ne/import/template and a workbench button to download xlsx/csv templates listing supported Netmiko device types.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 09:41:25 +08:00
042c015045 feat(ops): add managed NE management and batch CLI collection
Introduce workbench operations for multi-vendor NE CRUD/connect-test and Netmiko batch collection with job lifecycle controls, log downloads, and paginated run filters.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-27 23:34:29 +08:00
664775927b fix(ume): idle runtime tasks show running with last sync time; English labels and help hint
Show inventory/alarms schedulers as running with DB last_run_at during debounce; English interval labels; subscription help on ? click.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-27 10:15:22 +08:00
6701aee3c7 feat(ume): coordinate WSS with REST sync and sync before WSS on startup
WSS-primary current alarms with upsert/tombstone, skip scheduled REST when WSS active,
safe manual reconcile, startup REST baseline before WebSocket connect.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-27 09:57:33 +08:00
fb374a9c36 feat(ume): handle server-side subscription loss with local cleanup confirm
Detect missing UME subscriptions from WSS/DELETE errors, stop stale reconnects, and prompt to clear local state before re-establishing.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-25 16:50:37 +08:00
31e745ef95 fix(ume): show WSS connection state separately from alarm activity
Track ws_connection for UI pills, stop overwriting runtime last_error on alarm events, and wire pause/resume to reconnect WSS.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-23 11:19:00 +08:00
5bd83c58dc feat(ume): expose WSS runtime logs on subscription status UI
Ring-buffer ws_logs API, alarm raise/clear labels with alarmkey, and scrollable log panel on UME page.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 21:15:15 +08:00
635cd52d4f fix(ume): accept empty JSON body on successful delete-subscription
Parse 204/empty UME responses without JSONDecodeError; improve request error messages and orphan-delete failure reporting.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 21:01:24 +08:00
a8b359f60d fix(ume): cancel alarm subscription with DELETE and surface failures
Use DELETE delete-subscription, refresh token before cancel, recover orphan subs on establish, and keep local state when UME delete fails.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 20:47:59 +08:00
4f8735a83f feat(ume): real-time current alarms via WebSocket subscription
Add WS consumer, persisted subscription store, manual subscribe/cancel APIs, and UI controls; extend sync and tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 20:27:43 +08:00
21f7cfba41 feat(ume): denormalize host_name onto alarms for display and grouping
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-20 00:05:10 +08:00
95db646403 feat(ume): English protocol bucket labels via lang query param
Share protocol classification helpers and return en labels for diagnostics when lang=en.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 23:35:47 +08:00
47033f14ab fix(netx): order current alarms by time_created desc
Sort UME current alarms by time_created descending (newest first) with last_seen_at and alarm_key as tie-breakers to keep offset/limit pagination stable. Apply the same default ordering in the MCP tool listing.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 17:28:52 +08:00
16607db3cd fix(netx): prefer UUID net_id from ME{} in objectName
Only treat UUID-like values as net_id. Prefer extracting ME{uuid} from objectName and ignore ME{numeric} wrappers found in alarmkey so alarms join inventory correctly.

Also constrain legacy alarmkey split formats (#, csv, space) to UUID-like prefixes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 17:11:58 +08:00
15d9cb5db3 fix(netx): derive ne_id from objectName ME{net_id}
When alarmkey does not contain a net_id, fall back to extracting ME{net_id} from objectName so alarms can join inventory correctly. Add regression coverage for the ME{} objectName pattern.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 17:02:46 +08:00
626bb2b02e fix(netx): parse space-separated net id from alarmkey
Support UME alarmkey values like "<net_id> <x> <y>" when deriving ne_id so current alarms can join inventory correctly. Add regression coverage for hash, csv, and space-delimited alarmkey formats.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 16:29:19 +08:00
67f7e48597 fix(netx): surface scheduler startup init failures
Log startup exceptions for UME scheduler threads and set runtime task status to error with startup_thread_init_failed details instead of silently swallowing exceptions. This prevents tasks from staying in init without actionable diagnostics.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 16:05:05 +08:00
eebfbf25fa fix(netx): avoid alarm sync failures from long UME fields
Store UME alarm payload fields as TEXT and run startup ALTER COLUMN upgrades so large alarm records no longer fail with StringDataRightTruncation. Keep full values during sync while hashing only pathological ultra-long alarm keys to preserve idempotent primary keys.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 15:59:20 +08:00
b253ee7bff fix(netx): do not put debounce wait text in runtime last_error
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 11:36:30 +08:00
666541266b fix(netx): separate scheduler interval vars to avoid closure overwrite
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 11:25:03 +08:00
17cd469b1a netx: log netx.ume.schedule/sync INFO to stderr for prod log files
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 11:18:32 +08:00
936cee1aa2 UME scheduler: resume wakes debounce sleep + skip wait; pause clears hints; loop tick logs
- Event.wait debounce sleep so 开始 interrupts long interval wait\n- resume sets skip+event; wake path discards skip to avoid double-sync\n- pause clears skip/wake; boot resets debounce via _reset_runtime_pause_flags\n- loop tick + thread is_alive logging for netx.ume.schedule

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 11:10:07 +08:00
b17aef0eae UME schedule: interval from any finished job; drop trailing sleep; stale running cleanup; paging logs
- Use last ended_at (done or failed) for debounce; remove duplicate time.sleep after sync\n- On startup mark running+no ended_at jobs failed (crash/interrupt) so interval logic is not fooled\n- Log marker page progress every 25 pages\n- Log when alarm/inventory scheduler threads start

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 10:51:47 +08:00
7a9921b45b UME schedule: reset pause flags on boot; defer sync from DB last done time
- _reset_runtime_pause_flags() after create_all so pause state cannot survive process restart in memory\n- Before each alarms/inventory auto sync, wait until interval elapsed since last status=done job ended_at (any trigger); honor pause during wait\n- Helps avoid immediate duplicate sync on restart when DB was recently updated

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 10:35:38 +08:00
34ee677433 UME scheduled sync: commit running job before long UME pull; schedule logs
Makes schedule attempts visible in ume_sync_jobs while HTTP pagination runs; log iteration/sleep/finish for alarms_current and inventory auto loops.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 10:21:01 +08:00
61f6c99f93 Runtime tasks: refresh last_run_at when alarm/inventory sync starts
Avoid stale last_run_at when sync_alarms_current runs longer than interval; clarifying tooltip on UME page.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 10:18:30 +08:00
ea7931496c Fix deadlock: renew_token must not call login while holding _token_lock
Non-reentrant Lock caused /v1/ume/token/refresh to hang when handshake failed or token empty inside renew; UI stuck on 续期中.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 10:03:20 +08:00
0afc77c06b UME: renew token when expires_in is 0; token UI loading + toasts; sync thread status hint
- keepalive: call renew when has_token and (expires_in<=0 or below renew_before) so 0s stuck state self-heals\n- alarms/inventory auto loops: set last_error while pulling so table is not stuck at init with no hint\n- UmePage: warn pills for connected+需续期, spinners on token actions, toast ok/err from App, invalidate sync status after token ops

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 09:50:13 +08:00
def534e0a6 Fix UME token store sync: load token when expires_at is 0, clear stale memory
Previously exp>mem_exp blocked loading when both were 0 (restart + DB row with missing expiry). Also clear in-memory token when DB row is cleared so token/status matches store after disconnect.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 09:37:07 +08:00