SSH Server Management Without the Ansible Overhead

python ssh cli devops
Published on Hacker News · GitHub

πŸ“š ζ–‡ζ‘£δΈ­εΏƒ API 参考

You SSH into 10 servers to check disk space. You write a quick for loop. A typo crashes one session. You're not sure which ones you've already checked. By the time you're done, 20 minutes are gone and you have a terminal full of scrollback you need to piece together.

There's a better way.

The Problem

Most developers SSH into servers one at a time. When you need to run the same command across multiple machines, your options are:

  1. Open 10 terminals β€” error-prone, slow, no audit trail
  2. Write a shell loop β€” for host in web-01 web-02 ...; do ssh $host "df -h"; done β€” works until a host is down and your loop breaks
  3. Ansible β€” powerful, but you need to learn YAML DSL, write playbooks, manage inventory files. Overkill for "check disk space"
  4. Fabric β€” good Python library, but no built-in host management or CLI

None of these give you a simple CLI that just works out of the box.

Meet remote-cmd

remote-cmd is a Python CLI + API for SSH server management. It gives you:

Quick Demo

$ pip install remote_cmd_manager

$ remote-cmd host add web-01 192.168.1.10 ubuntu --key ~/.ssh/id_rsa

$ remote-cmd run web-01 "uptime"
β†’ 14:32:10 up 45 days,  2:15,  1 user,  load average: 0.08, 0.03, 0.05

$ remote-cmd host add web-02 192.168.1.11 ubuntu --key ~/.ssh/id_rsa --tag production
$ remote-cmd host add db-01 192.168.1.20 ubuntu --key ~/.ssh/id_rsa --tag production --tag database

$ remote-cmd batch-run web-01 web-02 db-01 "df -h /"
βœ“ web-01  β†’ Disk: 32G/100G (32%)
βœ“ web-02  β†’ Disk: 45G/100G (45%)
βœ“ db-01   β†’ Disk: 12G/50G  (24%)

Real-World Use Cases

Incident Response

$ remote-cmd batch-run web-01 web-02 "journalctl -xe -n 50 | grep -i error"

Deploy Code

$ cat deploy.py
from remote_cmd.repository.json_host_repository import JsonHostRepository
from remote_cmd.service.host_service import HostService

repo = JsonHostRepository("hosts.json")
manager = HostService(repository=repo)
for host in manager.list_hosts(tag="staging"):
    with manager.connect_to_host(host.name) as client:
        client.execute("cd /app && git pull")
        client.execute("pip install -r requirements.txt")
        client.execute_sudo("systemctl restart app", password="sudopass")

Config Update

$ remote-cmd upload web-01 ./nginx.conf /tmp/nginx.conf
$ remote-cmd run web-01 "sudo cp /tmp/nginx.conf /etc/nginx/nginx.conf && sudo nginx -t && sudo systemctl reload nginx"

How It Stacks Up

remote-cmdssh + shellAnsibleFabric
Setup time10 secondsNone (you know ssh)30 min+5 min
Host managementBuilt-inManualInventory YAMLManual
CLIYesYesansible cmdfab cmd
Python APIYesNoNo (YAML)Yes
Ideal forAd-hoc + scriptsOne-offConfig mgmtPython scripts

Getting Started

$ pip install remote_cmd_manager

$ remote-cmd --help

$ remote-cmd host add my-server 192.168.1.100 ubuntu --key ~/.ssh/id_rsa
$ remote-cmd run my-server "uptime"

The project is in beta, the core API is stable, and contributions are welcome.

If you SSH into more than a couple servers regularly, give it a try. It'll save you the "which servers did I check again?" moment.