Skip to content

feat: add device operations commands (dispatch/monitor jobs) #214

Description

@cdot65

Overview

Add scm operations command group for dispatching and monitoring asynchronous device jobs. Wraps the new client.device_operations service from SDK 0.13.0.

Context

SDK 0.13.0 adds client.device_operations supporting 7 operation types:

  • Route tables — retrieve device routing tables
  • FIB tables — retrieve forwarding information base
  • DNS proxy — query DNS proxy configuration/status
  • Network interfaces — retrieve interface status/config
  • Device rules — retrieve applied security rules
  • BGP policy export — export BGP routing policies
  • Logging service status — check logging service health

Each supports async (fire-and-forget, returns job ID) and sync (poll-to-completion) modes.

Dependencies

Design Decisions (from brainstorming session 2026-04-16)

  1. Top-level command group: scm operations <action> [options]
  2. Default sync, --async flag for fire-and-forget: Commands block and poll by default. --async returns the job ID immediately.
  3. Sync mode shows results; async mode shows job ID: When sync completes, display the operation results. When --async, print only the job ID for later follow-up.
  4. Job status check subcommand: scm operations status --job-id <id> to check on async jobs

Scope

  • In scope:
    • New command module: src/scm_cli/commands/operations.py
    • Subcommands for each operation type:
      • scm operations route-table --device <name>
      • scm operations fib-table --device <name>
      • scm operations dns-proxy --device <name>
      • scm operations interfaces --device <name>
      • scm operations device-rules --device <name>
      • scm operations bgp-export --device <name>
      • scm operations logging-status --device <name>
      • scm operations status --job-id <id> (check job status)
    • All commands support --async flag and --timeout <seconds> for sync mode
    • SDK client methods in sdk_client.py for each operation type
    • Mock mode support with realistic job dispatch/completion data
    • Register in main.py as top-level command group
    • Tests: tests/test_operations_commands.py
    • Documentation: docs/cli/operations/ pages
    • Update mkdocs.yml nav
  • Out of scope:

CLI Interface

# Sync (default) — blocks until complete, shows results
scm operations route-table --device fw-01

# Async — returns job ID immediately
scm operations route-table --device fw-01 --async

# Sync with custom timeout
scm operations fib-table --device fw-01 --timeout 120

# Check job status
scm operations status --job-id abc-123

# Mock mode
scm operations interfaces --device fw-01 --mock

Acceptance Criteria

  • src/scm_cli/commands/operations.py exists with subcommands for all 7 operation types + status
  • Default behavior is sync (poll to completion), results displayed in table format
  • --async flag returns job ID immediately without polling
  • --timeout flag controls sync polling timeout (default from SDK)
  • scm operations status --job-id <id> retrieves job status
  • JobTimeoutError handled gracefully — shows job ID and last state for manual follow-up
  • SDK client methods added for all 7 operation types
  • Mock mode returns realistic job dispatch/status/completion data
  • Unit tests covering: sync success, async dispatch, timeout error, status check, each operation type
  • Documentation pages created and linked in mkdocs.yml
  • make quality passes
  • Module follows style guide (191-char separators, Google docstrings, section organization)

Implementation Notes

  • SDK dispatch methods return a job object with job_id; sync mode internally polls until state == "completed"
  • JobTimeoutError has job_id and last_state attributes — surface both in error message: "Job {job_id} timed out in state '{last_state}'. Check status with: scm operations status --job-id {job_id}"
  • Table output for results varies by operation type (route tables have different columns than interface status)
  • Consider a shared --device option constant since all 7 operations require it
  • Follow commands/jobs.py for job-related output patterns

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions