[Phase 2] Implement Plan/Apply CLI Commands #29

Open
opened 2026-01-30 13:14:03 +00:00 by Damien · 0 comments
Owner

Description

Implement fabric-orch plan and fabric-orch apply CLI commands that provide a Terraform-like experience for managing fabric configuration.

Context

These are the primary user-facing commands that bring together intent retrieval from InfraHub, diff computation, and change application via gNMI into a cohesive workflow.

Tasks

  • Implement fabric-orch plan command
  • Implement fabric-orch apply command
  • Add --device filter to target specific devices
  • Add --resource-type filter (vlans, interfaces, bgp, etc.)
  • Add --auto-approve flag for non-interactive apply
  • Add --branch flag to use InfraHub branch (test changes before merge)
  • Implement colored diff output with Rich
  • Add --output json for machine-readable output
  • Save plan to file for later apply

CLI Interface

# Show what would change across the entire fabric
fabric-orch plan

# Plan for a specific device
fabric-orch plan --device leaf1

# Plan only VLAN changes
fabric-orch plan --resource-type vlans

# Plan using an InfraHub branch (test before merge)
fabric-orch plan --branch feature/add-vlan-100

# Save plan to file
fabric-orch plan --out plan.json

# Apply with interactive confirmation
fabric-orch apply

# Apply a saved plan
fabric-orch apply plan.json

# Apply without confirmation (for automation)
fabric-orch apply --auto-approve

# Apply only to specific device
fabric-orch apply --device leaf1

Example Output

$ fabric-orch plan --device leaf1

🔍 Retrieving intent from InfraHub (branch: main)...
📡 Fetching current state via gNMI...
📊 Computing diff...

Fabric Orchestrator Plan - leaf1
═══════════════════════════════════════════════════════════════

  ~ VLAN 40 (update)
      name: "prod" → "production"

  + VLAN 50 (create)
      name: "staging"
      vni: 100050

  - VLAN 99 (delete)
      name: "deprecated"

───────────────────────────────────────────────────────────────
Plan: 1 to create, 1 to update, 1 to delete

Run 'fabric-orch apply' to apply these changes.

Implementation

@cli.command()
@click.option("--device", "-d", help="Target specific device")
@click.option("--resource-type", "-r", help="Filter by resource type")
@click.option("--branch", "-b", default="main", help="InfraHub branch to use")
@click.option("--out", "-o", type=click.Path(), help="Save plan to file")
@click.option("--output", type=click.Choice(["pretty", "json"]), default="pretty")
def plan(device, resource_type, branch, out, output):
    """Generate execution plan showing required changes."""
    from src.infrahub.client import get_fabric_intent
    from src.gnmi.client import get_device_state
    from src.reconciler.diff import compute_diff
    
    # 1. Get intent from InfraHub
    intent = get_fabric_intent(device=device, branch=branch)
    
    # 2. Get current state via gNMI
    current = get_device_state(device=device)
    
    # 3. Compute diff
    changes = compute_diff(want=intent, have=current)
    
    # 4. Display or save
    ...


@cli.command()
@click.argument("plan_file", required=False, type=click.Path(exists=True))
@click.option("--device", "-d", help="Target specific device")
@click.option("--auto-approve", is_flag=True, help="Skip confirmation")
def apply(plan_file, device, auto_approve):
    """Apply changes to converge fabric state with intent."""
    pass

Output Files

  • src/cli.py (extend existing)
  • src/reconciler/__init__.py
  • src/reconciler/diff.py
  • src/reconciler/plan.py

Acceptance Criteria

  • Plan shows clear, colored diff output
  • Apply prompts for confirmation by default
  • --branch flag allows testing InfraHub branches before merge
  • Commands work for single device or entire fabric
  • JSON output format for CI/CD integration
  • Error handling with helpful messages

Dependencies

  • Requires: InfraHub client (#41 - to be created)
  • Requires: Diff engine (part of this issue or separate)
  • Uses: Existing gNMI client (src/gnmi/client.py)
  • Enables: #38 (Prefect Integration)
  • Enables: #36 (Drift Detection)
## Description Implement `fabric-orch plan` and `fabric-orch apply` CLI commands that provide a Terraform-like experience for managing fabric configuration. ## Context These are the primary user-facing commands that bring together intent retrieval from InfraHub, diff computation, and change application via gNMI into a cohesive workflow. ## Tasks - [ ] Implement `fabric-orch plan` command - [ ] Implement `fabric-orch apply` command - [ ] Add `--device` filter to target specific devices - [ ] Add `--resource-type` filter (vlans, interfaces, bgp, etc.) - [ ] Add `--auto-approve` flag for non-interactive apply - [ ] Add `--branch` flag to use InfraHub branch (test changes before merge) - [ ] Implement colored diff output with Rich - [ ] Add `--output json` for machine-readable output - [ ] Save plan to file for later apply ## CLI Interface ```bash # Show what would change across the entire fabric fabric-orch plan # Plan for a specific device fabric-orch plan --device leaf1 # Plan only VLAN changes fabric-orch plan --resource-type vlans # Plan using an InfraHub branch (test before merge) fabric-orch plan --branch feature/add-vlan-100 # Save plan to file fabric-orch plan --out plan.json # Apply with interactive confirmation fabric-orch apply # Apply a saved plan fabric-orch apply plan.json # Apply without confirmation (for automation) fabric-orch apply --auto-approve # Apply only to specific device fabric-orch apply --device leaf1 ``` ## Example Output ``` $ fabric-orch plan --device leaf1 🔍 Retrieving intent from InfraHub (branch: main)... 📡 Fetching current state via gNMI... 📊 Computing diff... Fabric Orchestrator Plan - leaf1 ═══════════════════════════════════════════════════════════════ ~ VLAN 40 (update) name: "prod" → "production" + VLAN 50 (create) name: "staging" vni: 100050 - VLAN 99 (delete) name: "deprecated" ─────────────────────────────────────────────────────────────── Plan: 1 to create, 1 to update, 1 to delete Run 'fabric-orch apply' to apply these changes. ``` ## Implementation ```python @cli.command() @click.option("--device", "-d", help="Target specific device") @click.option("--resource-type", "-r", help="Filter by resource type") @click.option("--branch", "-b", default="main", help="InfraHub branch to use") @click.option("--out", "-o", type=click.Path(), help="Save plan to file") @click.option("--output", type=click.Choice(["pretty", "json"]), default="pretty") def plan(device, resource_type, branch, out, output): """Generate execution plan showing required changes.""" from src.infrahub.client import get_fabric_intent from src.gnmi.client import get_device_state from src.reconciler.diff import compute_diff # 1. Get intent from InfraHub intent = get_fabric_intent(device=device, branch=branch) # 2. Get current state via gNMI current = get_device_state(device=device) # 3. Compute diff changes = compute_diff(want=intent, have=current) # 4. Display or save ... @cli.command() @click.argument("plan_file", required=False, type=click.Path(exists=True)) @click.option("--device", "-d", help="Target specific device") @click.option("--auto-approve", is_flag=True, help="Skip confirmation") def apply(plan_file, device, auto_approve): """Apply changes to converge fabric state with intent.""" pass ``` ## Output Files - `src/cli.py` (extend existing) - `src/reconciler/__init__.py` - `src/reconciler/diff.py` - `src/reconciler/plan.py` ## Acceptance Criteria - Plan shows clear, colored diff output - Apply prompts for confirmation by default - `--branch` flag allows testing InfraHub branches before merge - Commands work for single device or entire fabric - JSON output format for CI/CD integration - Error handling with helpful messages ## Dependencies - Requires: InfraHub client (#41 - to be created) - Requires: Diff engine (part of this issue or separate) - Uses: Existing gNMI client (`src/gnmi/client.py`) ## Related - Enables: #38 (Prefect Integration) - Enables: #36 (Drift Detection)
Damien added the phase-2-minimal-reconciler label 2026-01-30 13:14:33 +00:00
Damien added this to the Fabric Orchestrator project 2026-02-05 09:05:56 +00:00
Sign in to join this conversation.