Skip to content

Latest commit

 

History

History
158 lines (118 loc) · 4.97 KB

File metadata and controls

158 lines (118 loc) · 4.97 KB

Python Scripts — Device Show Commands & Backup

Scripts in this directory are called directly by the NACC backend when a show command or backup is triggered from the UI. Each script SSHs to the target device, runs the appropriate command, and prints the result to stdout.


Script Interface Contract

Every script in this directory must follow this contract exactly.

Calling convention

python3 /opt/nacc/scripts/python/<script_name>.py <device_ip>

Arguments

Argument Source Description
sys.argv[1] Backend service Device IP address (always present)

Output

Stream Purpose Shown in UI
stdout Human-readable command output (print()) Frontend terminal
stderr Diagnostics / error messages (print(..., file=sys.stderr)) job.error field

Exit codes

Code Meaning Job status in UI
0 Success success
1+ Failure failed

Credentials (env vars — automatically inherited from .env)

Variable Used by
NETWORK_USERNAME All scripts (SSH)
NETWORK_PASSWORD All scripts (SSH)
GITEA_URL backup_config.py
GITEA_TOKEN backup_config.py
GITEA_USER backup_config.py
GITEA_REPO backup_config.py

Naming convention

The script filename must exactly match the command name registered in PYTHON_COMMANDS inside backend/src/routes/automation.ts:

show_version      →  show_version.py
show_interfaces   →  show_interfaces.py
backup_config     →  backup_config.py

Minimal Script Template

#!/usr/bin/env python3
"""
<script_name>.py — Brief description of what this script shows.

Usage:
    python3 <script_name>.py <device_ip>
"""
import sys
import os


def main():
    if len(sys.argv) < 2:
        print("Usage: <script_name>.py <device_ip>", file=sys.stderr)
        sys.exit(1)

    device_ip = sys.argv[1]
    username = os.environ.get('NETWORK_USERNAME', '')
    password = os.environ.get('NETWORK_PASSWORD', '')

    if not username or not password:
        print("NETWORK_USERNAME and NETWORK_PASSWORD must be set in .env", file=sys.stderr)
        sys.exit(1)

    try:
        # Example using netmiko:
        # from netmiko import ConnectHandler
        # conn = ConnectHandler(
        #     device_type='cisco_ios',
        #     host=device_ip,
        #     username=username,
        #     password=password,
        # )
        # output = conn.send_command('show version')
        # conn.disconnect()
        # print(output)
        pass
    except Exception as e:
        print(f"Error connecting to {device_ip}: {e}", file=sys.stderr)
        sys.exit(1)


if __name__ == '__main__':
    main()

backup_config.py — Gitea API Flow

This script is the full implementation of "Backup to Gitea". The Ansible playbook (ansible/playbooks/backup_config.yml) only saves to a local file and does not push to Gitea. The Python version completes the intended design.

Flow:

SSH to device
  → show running-config
  → base64-encode the output
  → PUT /api/v1/repos/{GITEA_USER}/{GITEA_REPO}/contents/{device_ip}.cfg
      (Gitea API — creates file if new, updates if exists)
  → print summary to stdout

Gitea API reference: PUT /api/v1/repos/{owner}/{repo}/contents/{filepath}

  • Returns 201 for new files, 200 for updates
  • Requires Authorization: token <GITEA_TOKEN> header
  • Body: { message: "...", content: "<base64>", sha: "<existing_sha_or_omit>" }

Adding a New Show Command

  1. Write the script here following the contract above.
  2. Add the command name to PYTHON_COMMANDS in backend/src/routes/automation.ts.
  3. Add a description in getPlaybookDescription() in the same file.
  4. Restart the backend.
  5. Optionally add a button in frontend/src/components/device/DeviceActions.tsx.

Current Scripts

Script Command Description
show_version.py show_version Device version and hardware info
show_interfaces.py show_interfaces Interface status and statistics
show_vlan.py show_vlan VLAN configuration
show_running.py show_running Running configuration
show_power_inline.py show_power_inline PoE power inline status
backup_config.py backup_config SSH → running config → Gitea API

(Add rows here as new scripts are created)