Metadata-Version: 2.4
Name: grass-remote-cli
Version: 0.1.1
Summary: Remote command execution library for SSH-based cluster operations. Execute commands on multiple servers concurrently with retry logic, error classification, and Slack notifications.
Author: Alex
License-Expression: MIT
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: System :: Systems Administration
Classifier: Topic :: System :: Clustering
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: paramiko>=3.0.0
Requires-Dist: loguru>=0.7.0
Provides-Extra: inventory
Requires-Dist: ansible>=2.15.0; extra == "inventory"
Provides-Extra: notifications
Requires-Dist: requests>=2.28.0; extra == "notifications"
Provides-Extra: all
Requires-Dist: grass-remote-cli[inventory,notifications]; extra == "all"
Provides-Extra: dev
Requires-Dist: grass-remote-cli[all]; extra == "dev"
Requires-Dist: pytest>=7.0; extra == "dev"
Dynamic: license-file

# grass-remote-cli

Remote command execution library for SSH-based cluster operations.

## Features

- **ClusterCmd**: Execute commands on multiple servers concurrently
- **SshCmd**: Single-server SSH execution with retry logic
- **StderrClassifier**: Intelligent error classification (real errors vs innocent warnings)
- **Notifications**: Slack integration for alerts (optional)
- **AnsibleInventory**: Parse Ansible inventory files (optional)

## Installation

```bash
# Core (SSH execution)
pip install grass-remote-cli

# With Ansible inventory support
pip install grass-remote-cli[inventory]

# With Slack notifications
pip install grass-remote-cli[notifications]

# Everything
pip install grass-remote-cli[all]
```

## Quick Start

```python
from grass_remote_cli import ClusterCmd

# Execute command on multiple servers
cluster = ClusterCmd(
    servers_ips=["<ip1>", "<ip2>", "<ip3>"],
    username="<ssh_user>",
    password="<ssh_password>",
    timeout_in_sec=300,
)
results, timed_out = cluster.execute("docker ps")

for ip, (_, stdout, stderr) in results:
    print(f"{ip}: {stdout}")
```

## Single Server Execution

```python
from grass_remote_cli import SshCmd

ssh = SshCmd()
ip, stdout, stderr = ssh.execute(
    host_ip="<server_ip>",
    username="<ssh_user>",
    password="<ssh_password>",
    commands="hostname && uptime"
)
print(stdout)
```

## With Ansible Inventory

```python
from grass_remote_cli import ClusterCmd
from grass_remote_cli.inventory import AnsibleInventory

# Load servers from Ansible inventory
inventory = AnsibleInventory("/path/to/ansible/inventories")
hosts = inventory.get_hosts_by_cluster("<cluster_name>")

# Deploy to cluster
ips = [host[1] for host in hosts]  # Extract IPs
cluster = ClusterCmd(ips, username="<ssh_user>", password="<ssh_password>")
results, _ = cluster.execute("docker pull <image>")
```

## Error Classification

The library intelligently classifies stderr output:

```python
from grass_remote_cli.stderr_classifier import StderrClassifier

classifier = StderrClassifier()
result = classifier.classify(stderr_output)

if result['is_error']:
    print(f"Real error: {result['summary']}")
else:
    print("Innocent warning, safe to ignore")
```

## Slack Notifications

```python
import os
from grass_remote_cli.notifications import post_to_slack

# Set webhook via environment variable
os.environ["SLACK_WEBHOOK_URL"] = "https://hooks.slack.com/services/..."

post_to_slack("Deployment complete!", channel="#deployments")

# Or pass webhook directly
post_to_slack(
    "Deployment complete!",
    channel="#deployments",
    webhook_url="https://hooks.slack.com/services/..."
)
```

## Environment Variables

| Variable | Description |
|----------|-------------|
| `SLACK_WEBHOOK_URL` | Slack webhook URL for notifications |
| `SSH_AUTH_TIMEOUT` | SSH authentication timeout (default: 120s) |
| `SSH_EXEC_TIMEOUT` | Command execution timeout (default: 900s) |
| `SSH_MAX_RETRIES` | Connection retry attempts (default: 3) |
| `SSH_MAX_WORKERS` | Concurrent SSH connections (default: 50) |

## License

MIT
