servonaut 2.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- servonaut-2.1.0/.github/PULL_REQUEST_TEMPLATE.md +31 -0
- servonaut-2.1.0/.github/workflows/ci.yml +38 -0
- servonaut-2.1.0/.github/workflows/publish.yml +46 -0
- servonaut-2.1.0/.gitignore +51 -0
- servonaut-2.1.0/CLAUDE.md +113 -0
- servonaut-2.1.0/CONTRIBUTING.md +45 -0
- servonaut-2.1.0/LICENSE +21 -0
- servonaut-2.1.0/PKG-INFO +175 -0
- servonaut-2.1.0/README.md +142 -0
- servonaut-2.1.0/docs/architecture.md +125 -0
- servonaut-2.1.0/docs/configuration.md +185 -0
- servonaut-2.1.0/docs/troubleshooting.md +106 -0
- servonaut-2.1.0/install.ps1 +264 -0
- servonaut-2.1.0/install.sh +413 -0
- servonaut-2.1.0/pyproject.toml +54 -0
- servonaut-2.1.0/src/servonaut/__init__.py +3 -0
- servonaut-2.1.0/src/servonaut/app.css +758 -0
- servonaut-2.1.0/src/servonaut/app.py +75 -0
- servonaut-2.1.0/src/servonaut/config/__init__.py +14 -0
- servonaut-2.1.0/src/servonaut/config/manager.py +344 -0
- servonaut-2.1.0/src/servonaut/config/migration.py +92 -0
- servonaut-2.1.0/src/servonaut/config/schema.py +94 -0
- servonaut-2.1.0/src/servonaut/main.py +63 -0
- servonaut-2.1.0/src/servonaut/screens/__init__.py +25 -0
- servonaut-2.1.0/src/servonaut/screens/command_overlay.py +417 -0
- servonaut-2.1.0/src/servonaut/screens/command_picker.py +195 -0
- servonaut-2.1.0/src/servonaut/screens/file_browser.py +136 -0
- servonaut-2.1.0/src/servonaut/screens/help.py +159 -0
- servonaut-2.1.0/src/servonaut/screens/instance_list.py +396 -0
- servonaut-2.1.0/src/servonaut/screens/key_management.py +330 -0
- servonaut-2.1.0/src/servonaut/screens/main_menu.py +169 -0
- servonaut-2.1.0/src/servonaut/screens/scan_results.py +163 -0
- servonaut-2.1.0/src/servonaut/screens/scp_transfer.py +205 -0
- servonaut-2.1.0/src/servonaut/screens/server_actions.py +283 -0
- servonaut-2.1.0/src/servonaut/screens/settings.py +286 -0
- servonaut-2.1.0/src/servonaut/services/__init__.py +39 -0
- servonaut-2.1.0/src/servonaut/services/aws_service.py +137 -0
- servonaut-2.1.0/src/servonaut/services/cache_service.py +158 -0
- servonaut-2.1.0/src/servonaut/services/command_history.py +163 -0
- servonaut-2.1.0/src/servonaut/services/connection_service.py +181 -0
- servonaut-2.1.0/src/servonaut/services/interfaces.py +388 -0
- servonaut-2.1.0/src/servonaut/services/keyword_store.py +159 -0
- servonaut-2.1.0/src/servonaut/services/scan_service.py +241 -0
- servonaut-2.1.0/src/servonaut/services/scp_service.py +159 -0
- servonaut-2.1.0/src/servonaut/services/ssh_service.py +284 -0
- servonaut-2.1.0/src/servonaut/services/terminal_service.py +321 -0
- servonaut-2.1.0/src/servonaut/utils/__init__.py +25 -0
- servonaut-2.1.0/src/servonaut/utils/formatting.py +90 -0
- servonaut-2.1.0/src/servonaut/utils/match_utils.py +53 -0
- servonaut-2.1.0/src/servonaut/utils/platform_utils.py +72 -0
- servonaut-2.1.0/src/servonaut/utils/ssh_utils.py +72 -0
- servonaut-2.1.0/src/servonaut/widgets/__init__.py +17 -0
- servonaut-2.1.0/src/servonaut/widgets/command_output.py +56 -0
- servonaut-2.1.0/src/servonaut/widgets/instance_table.py +109 -0
- servonaut-2.1.0/src/servonaut/widgets/progress_indicator.py +30 -0
- servonaut-2.1.0/src/servonaut/widgets/remote_tree.py +342 -0
- servonaut-2.1.0/src/servonaut/widgets/status_bar.py +84 -0
- servonaut-2.1.0/tests/__init__.py +0 -0
- servonaut-2.1.0/tests/conftest.py +87 -0
- servonaut-2.1.0/tests/test_cache_service.py +104 -0
- servonaut-2.1.0/tests/test_command_history.py +121 -0
- servonaut-2.1.0/tests/test_config_manager.py +132 -0
- servonaut-2.1.0/tests/test_config_migration.py +48 -0
- servonaut-2.1.0/tests/test_config_schema.py +93 -0
- servonaut-2.1.0/tests/test_connection_service.py +198 -0
- servonaut-2.1.0/tests/test_formatting.py +76 -0
- servonaut-2.1.0/tests/test_keyword_store.py +109 -0
- servonaut-2.1.0/tests/test_match_utils.py +73 -0
- servonaut-2.1.0/tests/test_platform_utils.py +40 -0
- servonaut-2.1.0/tests/test_scp_service.py +93 -0
- servonaut-2.1.0/tests/test_ssh_service.py +204 -0
- servonaut-2.1.0/tests/test_ssh_utils.py +69 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
Thank you for contributing to Servonaut!
|
|
2
|
+
|
|
3
|
+
Please provide a clear description of your changes and link to any relevant issues.
|
|
4
|
+
|
|
5
|
+
**Before submitting, please ensure you have:**
|
|
6
|
+
- [ ] Read the [CONTRIBUTING.md](https://github.com/zb-ss/ec2-ssh/blob/master/CONTRIBUTING.md) guide.
|
|
7
|
+
- [ ] Based your changes on the `main` branch (or the relevant development branch).
|
|
8
|
+
- [ ] Ensured your code follows the project's coding style.
|
|
9
|
+
- [ ] Added tests for your changes (if applicable).
|
|
10
|
+
- [ ] Updated documentation (e.g., `README.md`) if your changes require it.
|
|
11
|
+
- [ ] Added a clear and descriptive title for your pull request.
|
|
12
|
+
- [ ] Written a clear summary of the changes in the "Description" section below.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
**Description of Changes:**
|
|
17
|
+
|
|
18
|
+
*(Please provide a detailed description of the changes you've made.)*
|
|
19
|
+
|
|
20
|
+
**Related Issues:**
|
|
21
|
+
|
|
22
|
+
*(Link to any relevant issues using `#issue_number`)*
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
**Checklist for Reviewers (Optional - for maintainer use):**
|
|
27
|
+
- [ ] Code is well-formatted and easy to understand.
|
|
28
|
+
- [ ] Changes achieve the intended purpose.
|
|
29
|
+
- [ ] Tests pass (if applicable).
|
|
30
|
+
- [ ] Documentation is updated (if applicable).
|
|
31
|
+
- [ ] No new major issues are introduced.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [master]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.8", "3.10", "3.12", "3.13"]
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
19
|
+
uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: ${{ matrix.python-version }}
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: pip install -e ".[test]"
|
|
25
|
+
|
|
26
|
+
- name: Run tests
|
|
27
|
+
run: pytest --tb=short -q
|
|
28
|
+
|
|
29
|
+
- name: Run tests with coverage
|
|
30
|
+
if: matrix.python-version == '3.12'
|
|
31
|
+
run: pytest --cov=servonaut --cov-report=term-missing --cov-report=xml
|
|
32
|
+
|
|
33
|
+
- name: Upload coverage
|
|
34
|
+
if: matrix.python-version == '3.12'
|
|
35
|
+
uses: actions/upload-artifact@v4
|
|
36
|
+
with:
|
|
37
|
+
name: coverage-report
|
|
38
|
+
path: coverage.xml
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
id-token: write
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
test:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Set up Python
|
|
17
|
+
uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
|
|
21
|
+
- name: Install dependencies
|
|
22
|
+
run: pip install -e ".[test]"
|
|
23
|
+
|
|
24
|
+
- name: Run tests
|
|
25
|
+
run: pytest --tb=short -q
|
|
26
|
+
|
|
27
|
+
publish:
|
|
28
|
+
needs: test
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
environment: pypi
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@v4
|
|
33
|
+
|
|
34
|
+
- name: Set up Python
|
|
35
|
+
uses: actions/setup-python@v5
|
|
36
|
+
with:
|
|
37
|
+
python-version: "3.12"
|
|
38
|
+
|
|
39
|
+
- name: Install build tools
|
|
40
|
+
run: pip install build
|
|
41
|
+
|
|
42
|
+
- name: Build package
|
|
43
|
+
run: python -m build
|
|
44
|
+
|
|
45
|
+
- name: Publish to PyPI
|
|
46
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
.aider*
|
|
2
|
+
# Python
|
|
3
|
+
__pycache__/
|
|
4
|
+
*.pyc
|
|
5
|
+
*.pyo
|
|
6
|
+
*.pyd
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Build artifacts
|
|
10
|
+
build/
|
|
11
|
+
dist/
|
|
12
|
+
*.egg-info/
|
|
13
|
+
*.egg
|
|
14
|
+
*.whl
|
|
15
|
+
|
|
16
|
+
# Virtual environments
|
|
17
|
+
.venv/
|
|
18
|
+
venv/
|
|
19
|
+
ENV/
|
|
20
|
+
env/
|
|
21
|
+
|
|
22
|
+
# IDE / Editor specific
|
|
23
|
+
.vscode/
|
|
24
|
+
.idea/
|
|
25
|
+
*.project
|
|
26
|
+
*.pydevproject
|
|
27
|
+
*.sublime-workspace
|
|
28
|
+
*.sublime-project
|
|
29
|
+
|
|
30
|
+
# OS specific
|
|
31
|
+
.DS_Store
|
|
32
|
+
Thumbs.db
|
|
33
|
+
|
|
34
|
+
# Configuration files (if any local, non-committed ones are used)
|
|
35
|
+
# .env
|
|
36
|
+
|
|
37
|
+
# Test artifacts
|
|
38
|
+
.pytest_cache/
|
|
39
|
+
.coverage
|
|
40
|
+
htmlcov/
|
|
41
|
+
nosetests.xml
|
|
42
|
+
coverage.xml
|
|
43
|
+
*.cover
|
|
44
|
+
*.log
|
|
45
|
+
|
|
46
|
+
# Hatchling specific (build backend)
|
|
47
|
+
.hatch/
|
|
48
|
+
|
|
49
|
+
# Projectile marker file
|
|
50
|
+
.projectile
|
|
51
|
+
/local/
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
Servonaut is a Terminal User Interface (TUI) for managing servers. Built with Python and Textual, it provides SSH connections, SCP file transfer, remote file browsing, command execution, and keyword-based server scanning across all AWS regions.
|
|
8
|
+
|
|
9
|
+
## Development Commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Run directly without installing (primary dev workflow)
|
|
13
|
+
PYTHONPATH=src python3 -m servonaut.main
|
|
14
|
+
|
|
15
|
+
# Or run the script directly
|
|
16
|
+
python src/servonaut/main.py
|
|
17
|
+
|
|
18
|
+
# Run with debug logging (prints to stderr + log file)
|
|
19
|
+
PYTHONPATH=src python3 -m servonaut.main --debug
|
|
20
|
+
|
|
21
|
+
# Install via pipx (production)
|
|
22
|
+
pipx install .
|
|
23
|
+
|
|
24
|
+
# Update existing pipx installation after changes
|
|
25
|
+
pipx install . --force
|
|
26
|
+
|
|
27
|
+
# Install editable for development
|
|
28
|
+
pip install -e .
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Tests use pytest. Run with `pip install -e ".[test]" && pytest`. CI runs on push/PR to master via GitHub Actions.
|
|
32
|
+
|
|
33
|
+
## Architecture
|
|
34
|
+
|
|
35
|
+
Modular TUI built on Textual, organized into five packages under `src/servonaut/`:
|
|
36
|
+
|
|
37
|
+
- **`config/`** — Configuration management: `AppConfig` dataclass hierarchy (`schema.py`), JSON load/save/validate (`manager.py`), v1→v2 migration (`migration.py`)
|
|
38
|
+
- **`services/`** — Business logic with abstract interfaces (`interfaces.py`). Each service implements its interface. Key services: `AWSService` (boto3 EC2 API), `CacheService` (stale-while-revalidate), `SSHService` (key management, command building), `ConnectionService` (bastion/ProxyJump resolution), `ScanService` + `KeywordStore` (keyword scanning), `TerminalService` (terminal detection/launch), `SCPService` (file transfer)
|
|
39
|
+
- **`screens/`** — Textual `Screen` subclasses for each view (main menu, instance list, server actions, file browser, command overlay, SCP transfer, scan results, settings, key management, search, help)
|
|
40
|
+
- **`widgets/`** — Reusable Textual widgets: `InstanceTable` (DataTable), `RemoteTree` (Tree for remote fs), `StatusBar`, `ProgressIndicator`, `CommandOutput` (RichLog)
|
|
41
|
+
- **`utils/`** — Helpers: `formatting.py`, `platform_utils.py`, `ssh_utils.py`, `match_utils.py` (instance matching with conditions like `name_contains`, `region`, `name_regex`)
|
|
42
|
+
|
|
43
|
+
### Service Initialization and Access
|
|
44
|
+
|
|
45
|
+
All services are created in `ServonautApp._init_services()` (in `app.py`) during `on_mount`. Services are stored as attributes on the app instance. Screens access them via `self.app.<service>` (e.g., `self.app.ssh_service`, `self.app.connection_service`).
|
|
46
|
+
|
|
47
|
+
Service dependency chain:
|
|
48
|
+
```
|
|
49
|
+
ConfigManager → config
|
|
50
|
+
├── CacheService(ttl_seconds=config.cache_ttl_seconds)
|
|
51
|
+
│ └── AWSService(cache_service)
|
|
52
|
+
├── SSHService(config_manager)
|
|
53
|
+
├── ConnectionService(config_manager)
|
|
54
|
+
├── ScanService(config_manager)
|
|
55
|
+
├── KeywordStore(config.keyword_store_path)
|
|
56
|
+
├── TerminalService(preferred=config.terminal_emulator)
|
|
57
|
+
├── SCPService()
|
|
58
|
+
└── CommandHistoryService(config.command_history_path)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Screen Navigation
|
|
62
|
+
|
|
63
|
+
Screens use `self.app.push_screen()` / `self.app.pop_screen()`. Shared instance data lives in `self.app.instances` (list of dicts with keys: `id`, `name`, `type`, `state`, `public_ip`, `private_ip`, `region`, `key_name`).
|
|
64
|
+
|
|
65
|
+
### Async Pattern
|
|
66
|
+
|
|
67
|
+
Long-running operations (AWS API, SSH) are async and run via `self.run_worker()` to avoid blocking the TUI. Workers notify the UI via `self.notify()`.
|
|
68
|
+
|
|
69
|
+
### Styling
|
|
70
|
+
|
|
71
|
+
All CSS is in a single `app.css` file using Textual's CSS-like syntax with design tokens (`$surface`, `$primary`, `$accent`, etc.). Screen-specific styles are organized into labeled sections within this file.
|
|
72
|
+
|
|
73
|
+
## Key Design Decisions
|
|
74
|
+
|
|
75
|
+
**SSH Connection Strategy:**
|
|
76
|
+
- ProxyJump (`-J`) when no separate bastion key; ProxyCommand when `bastion_key` is set (allows different key for bastion vs target)
|
|
77
|
+
- `IdentitiesOnly=yes` only added when `-i` flag is present
|
|
78
|
+
- Key auto-discovery searches `~/.ssh/` with multiple patterns (exact match, `.pem`, fuzzy)
|
|
79
|
+
- External SSH sessions launch in new terminal window via wrapper script that keeps terminal open on failure
|
|
80
|
+
|
|
81
|
+
**Instance Caching (stale-while-revalidate):**
|
|
82
|
+
- Cache at `~/.servonaut/cache.json` with configurable TTL (default 3600s)
|
|
83
|
+
- Startup: show stale data immediately, refresh in background if expired
|
|
84
|
+
- `CacheService.load()` respects TTL; `load_any()` ignores TTL; `is_fresh()` checks TTL
|
|
85
|
+
- Force refresh via `R` key in instance list
|
|
86
|
+
|
|
87
|
+
**Configuration:**
|
|
88
|
+
- JSON at `~/.servonaut/config.json`, dataclass-based schema (`AppConfig`, `ScanRule`, `ConnectionProfile`, `ConnectionRule`)
|
|
89
|
+
- Schema versioning (`CONFIG_VERSION = 2`) with automatic v1→v2 migration
|
|
90
|
+
- Connection rules evaluated in order — first match wins
|
|
91
|
+
|
|
92
|
+
**Instance Matching (`match_utils.py`):**
|
|
93
|
+
- Used by both scan rules and connection rules
|
|
94
|
+
- Supports: `name_contains`, `name_regex`, `region`, `id`, `type_contains`, `has_public_ip`
|
|
95
|
+
- All conditions are AND-ed together
|
|
96
|
+
|
|
97
|
+
## Runtime Files
|
|
98
|
+
|
|
99
|
+
All runtime files are under `~/.servonaut/`:
|
|
100
|
+
|
|
101
|
+
- `~/.servonaut/config.json` — Main configuration
|
|
102
|
+
- `~/.servonaut/cache.json` — Cached instance list
|
|
103
|
+
- `~/.servonaut/keywords.json` — Scan results store
|
|
104
|
+
- `~/.servonaut/command_history.json` — Saved commands and command history
|
|
105
|
+
- `~/.servonaut/logs/servonaut.log` — Application log
|
|
106
|
+
- `~/.servonaut/logs/servonaut_*.sh` — Temporary SSH wrapper scripts
|
|
107
|
+
|
|
108
|
+
## Dependencies
|
|
109
|
+
|
|
110
|
+
- `boto3` — AWS EC2 API
|
|
111
|
+
- `tabulate` — Table formatting (legacy)
|
|
112
|
+
- `textual>=0.40.0` — TUI framework
|
|
113
|
+
- Python 3.8+ required
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Contributing to Servonaut
|
|
2
|
+
|
|
3
|
+
First off, thank you for considering contributing to Servonaut! Your help is appreciated.
|
|
4
|
+
|
|
5
|
+
This document provides guidelines for contributing to this project.
|
|
6
|
+
|
|
7
|
+
## How Can I Contribute?
|
|
8
|
+
|
|
9
|
+
### Reporting Bugs
|
|
10
|
+
* Ensure the bug was not already reported by searching on GitHub under [Issues](https://github.com/zb-ss/ec2-ssh/issues).
|
|
11
|
+
* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/zb-ss/ec2-ssh/issues/new). Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample or an executable test case** demonstrating the expected behavior that is not occurring.
|
|
12
|
+
|
|
13
|
+
### Suggesting Enhancements
|
|
14
|
+
* Open a new issue to discuss your enhancement. Clearly describe the proposed enhancement and its potential benefits.
|
|
15
|
+
* Provide a step-by-step description of the suggested enhancement in as many details as possible.
|
|
16
|
+
|
|
17
|
+
### Pull Requests
|
|
18
|
+
1. **Fork the repository**: Click the "Fork" button at the top right of the repository page.
|
|
19
|
+
2. **Clone your fork**: `git clone https://github.com/zb-ss/ec2-ssh.git`.
|
|
20
|
+
3. **Create a new branch**: `git checkout -b name-of-your-new-feature-or-fix`
|
|
21
|
+
4. **Make your changes**: Make your changes in your local repository.
|
|
22
|
+
5. **Follow coding style**:
|
|
23
|
+
* Ensure your code adheres to the existing style.
|
|
24
|
+
* If you are adding new features, try to include tests if applicable.
|
|
25
|
+
* Update documentation (e.g., `README.md`) if your changes affect usage or add new features.
|
|
26
|
+
6. **Commit your changes**: Use clear and descriptive commit messages.
|
|
27
|
+
```bash
|
|
28
|
+
git add .
|
|
29
|
+
git commit -m "feat: Add new feature X"
|
|
30
|
+
# or "fix: Resolve bug Y"
|
|
31
|
+
# or "docs: Update README for feature Z"
|
|
32
|
+
```
|
|
33
|
+
7. **Push to your fork**: `git push origin name-of-your-new-feature-or-fix`
|
|
34
|
+
8. **Open a Pull Request**: Go to the original repository on GitHub and click the "New pull request" button. Fill out the pull request template.
|
|
35
|
+
|
|
36
|
+
## Development Setup
|
|
37
|
+
Please refer to the `README.md` for instructions on setting up your development environment and installing dependencies.
|
|
38
|
+
|
|
39
|
+
## Code of Conduct
|
|
40
|
+
Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms. For now, please be respectful and constructive in all interactions.
|
|
41
|
+
|
|
42
|
+
## License
|
|
43
|
+
By contributing to Servonaut, you agree that your contributions will be licensed under its MIT License.
|
|
44
|
+
|
|
45
|
+
Thank you for your contribution!
|
servonaut-2.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 zb-ss
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
servonaut-2.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: servonaut
|
|
3
|
+
Version: 2.1.0
|
|
4
|
+
Summary: Interactive TUI for managing servers — SSH, SCP, scanning & more
|
|
5
|
+
Project-URL: Homepage, https://github.com/zb-ss/ec2-ssh
|
|
6
|
+
Project-URL: Repository, https://github.com/zb-ss/ec2-ssh
|
|
7
|
+
Project-URL: Issues, https://github.com/zb-ss/ec2-ssh/issues
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Intended Audience :: System Administrators
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: MacOS
|
|
16
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Topic :: System :: Systems Administration
|
|
25
|
+
Requires-Python: >=3.8
|
|
26
|
+
Requires-Dist: boto3
|
|
27
|
+
Requires-Dist: tabulate
|
|
28
|
+
Requires-Dist: textual>=0.40.0
|
|
29
|
+
Provides-Extra: test
|
|
30
|
+
Requires-Dist: pytest-cov>=4.0; extra == 'test'
|
|
31
|
+
Requires-Dist: pytest>=7.0; extra == 'test'
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
# Servonaut
|
|
35
|
+
|
|
36
|
+
A modern Terminal User Interface (TUI) for managing servers — SSH, SCP, scanning & more.
|
|
37
|
+
|
|
38
|
+
## Quick Install
|
|
39
|
+
|
|
40
|
+
**Linux / macOS:**
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
curl -sSL https://raw.githubusercontent.com/zb-ss/ec2-ssh/master/install.sh | bash
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Windows (PowerShell):**
|
|
47
|
+
|
|
48
|
+
```powershell
|
|
49
|
+
irm https://raw.githubusercontent.com/zb-ss/ec2-ssh/master/install.ps1 | iex
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Or install directly via pipx / pip:**
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pipx install servonaut
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Manual install from source:**
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
git clone https://github.com/zb-ss/ec2-ssh.git
|
|
62
|
+
cd ec2-ssh
|
|
63
|
+
pipx install .
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Features
|
|
67
|
+
|
|
68
|
+
- **Interactive TUI** with mouse and keyboard support powered by [Textual](https://textual.textualize.io/)
|
|
69
|
+
- **List and search** EC2 instances across all AWS regions
|
|
70
|
+
- **SSH into instances** — launches in new terminal window with auto-detected emulator
|
|
71
|
+
- **Run remote commands** via overlay panel with real-time streaming output, persistent history, and saved command favorites
|
|
72
|
+
- **Browse remote file systems** — interactive file tree navigation
|
|
73
|
+
- **SCP file transfer** — upload/download files and directories
|
|
74
|
+
- **Keyword-based server scanning** — search file contents across instances
|
|
75
|
+
- **Bastion host / jump server support** via ProxyJump or ProxyCommand
|
|
76
|
+
- **SSH key management** with auto-discovery and per-instance configuration
|
|
77
|
+
- **Instance caching** with stale-while-revalidate for fast startup
|
|
78
|
+
- **Fully configurable** — all settings in `~/.servonaut/config.json`
|
|
79
|
+
|
|
80
|
+
## Prerequisites
|
|
81
|
+
|
|
82
|
+
- Python 3.8+
|
|
83
|
+
- AWS CLI configured (`~/.aws/credentials` and `~/.aws/config`)
|
|
84
|
+
- SSH client (standard on Linux/macOS, OpenSSH on Windows)
|
|
85
|
+
- `pipx` for isolated installation (recommended)
|
|
86
|
+
|
|
87
|
+
Your AWS credentials need `ec2:DescribeInstances` and `ec2:DescribeRegions` permissions.
|
|
88
|
+
|
|
89
|
+
## Usage
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
servonaut # Launch the TUI
|
|
93
|
+
servonaut --debug # Launch with debug logging to stderr
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Keyboard Shortcuts
|
|
97
|
+
|
|
98
|
+
| Context | Key | Action |
|
|
99
|
+
|---------|-----|--------|
|
|
100
|
+
| Global | `Q` | Quit |
|
|
101
|
+
| Global | `?` | Help screen |
|
|
102
|
+
| Global | `Escape` | Go back / close |
|
|
103
|
+
| Instance List | `/` | Focus search |
|
|
104
|
+
| Instance List | `R` | Force-refresh from AWS |
|
|
105
|
+
| Instance List | `S` | SSH to selected instance |
|
|
106
|
+
| Instance List | `B` | Browse remote files |
|
|
107
|
+
| Instance List | `C` | Run command overlay |
|
|
108
|
+
| Instance List | `T` | SCP transfer |
|
|
109
|
+
| Command Overlay | `Ctrl+C` | Stop running command |
|
|
110
|
+
| Command Overlay | `Ctrl+R` | Command picker (saved + recent) |
|
|
111
|
+
| Command Overlay | `Ctrl+S` | Save command to favorites |
|
|
112
|
+
| Command Overlay | `Up/Down` | Command history |
|
|
113
|
+
|
|
114
|
+
### What You Can Do
|
|
115
|
+
|
|
116
|
+
1. **List Instances** — View all EC2 instances with search/filter
|
|
117
|
+
2. **Search** — Filter instances by name, type, region, or state; search scan results
|
|
118
|
+
3. **Manage SSH Keys** — Configure default and per-instance SSH keys
|
|
119
|
+
4. **Scan Servers** — Run keyword scans across running instances
|
|
120
|
+
5. **Settings** — Configure connection profiles, scan rules, preferences
|
|
121
|
+
|
|
122
|
+
When you select a server: browse files, run commands, SSH connect, SCP transfer, or view scan results. Command history persists across sessions — use `Ctrl+R` to search history and saved commands, `Ctrl+S` to save favorites.
|
|
123
|
+
|
|
124
|
+
### Instance Caching
|
|
125
|
+
|
|
126
|
+
| Scenario | Behavior |
|
|
127
|
+
|----------|----------|
|
|
128
|
+
| First launch (no cache) | Fetches from AWS with progress indicator |
|
|
129
|
+
| Restart within TTL (default 1h) | Instant load from cache |
|
|
130
|
+
| Restart after TTL | Shows stale data immediately, refreshes in background |
|
|
131
|
+
| Press `R` | Force-refresh from AWS |
|
|
132
|
+
|
|
133
|
+
### Configuration
|
|
134
|
+
|
|
135
|
+
All configuration lives in `~/.servonaut/config.json`, created automatically on first run.
|
|
136
|
+
|
|
137
|
+
See [Configuration Guide](docs/configuration.md) for the full reference including connection profiles, scan rules, and match conditions.
|
|
138
|
+
|
|
139
|
+
## Development
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Run directly (primary dev workflow)
|
|
143
|
+
PYTHONPATH=src python3 -m servonaut.main
|
|
144
|
+
|
|
145
|
+
# Run with debug logging
|
|
146
|
+
PYTHONPATH=src python3 -m servonaut.main --debug
|
|
147
|
+
|
|
148
|
+
# Install editable
|
|
149
|
+
pip install -e .
|
|
150
|
+
|
|
151
|
+
# Update pipx installation after changes
|
|
152
|
+
pipx install . --force
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# Run tests
|
|
157
|
+
pip install -e ".[test]"
|
|
158
|
+
pytest
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
See [Architecture](docs/architecture.md) for codebase structure and design patterns.
|
|
162
|
+
|
|
163
|
+
## Troubleshooting
|
|
164
|
+
|
|
165
|
+
See [Troubleshooting Guide](docs/troubleshooting.md) for help with SSH connections, bastion hosts, key management, and AWS credentials.
|
|
166
|
+
|
|
167
|
+
## Logging
|
|
168
|
+
|
|
169
|
+
Logs are always written to `~/.servonaut/logs/servonaut.log`. Use `--debug` for verbose stderr output.
|
|
170
|
+
|
|
171
|
+
When SSH fails, the terminal window stays open showing the error and exit code.
|
|
172
|
+
|
|
173
|
+
## License
|
|
174
|
+
|
|
175
|
+
This project is licensed under the MIT License — see the [LICENSE](LICENSE) file for details.
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Servonaut
|
|
2
|
+
|
|
3
|
+
A modern Terminal User Interface (TUI) for managing servers — SSH, SCP, scanning & more.
|
|
4
|
+
|
|
5
|
+
## Quick Install
|
|
6
|
+
|
|
7
|
+
**Linux / macOS:**
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
curl -sSL https://raw.githubusercontent.com/zb-ss/ec2-ssh/master/install.sh | bash
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
**Windows (PowerShell):**
|
|
14
|
+
|
|
15
|
+
```powershell
|
|
16
|
+
irm https://raw.githubusercontent.com/zb-ss/ec2-ssh/master/install.ps1 | iex
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Or install directly via pipx / pip:**
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pipx install servonaut
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Manual install from source:**
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
git clone https://github.com/zb-ss/ec2-ssh.git
|
|
29
|
+
cd ec2-ssh
|
|
30
|
+
pipx install .
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Features
|
|
34
|
+
|
|
35
|
+
- **Interactive TUI** with mouse and keyboard support powered by [Textual](https://textual.textualize.io/)
|
|
36
|
+
- **List and search** EC2 instances across all AWS regions
|
|
37
|
+
- **SSH into instances** — launches in new terminal window with auto-detected emulator
|
|
38
|
+
- **Run remote commands** via overlay panel with real-time streaming output, persistent history, and saved command favorites
|
|
39
|
+
- **Browse remote file systems** — interactive file tree navigation
|
|
40
|
+
- **SCP file transfer** — upload/download files and directories
|
|
41
|
+
- **Keyword-based server scanning** — search file contents across instances
|
|
42
|
+
- **Bastion host / jump server support** via ProxyJump or ProxyCommand
|
|
43
|
+
- **SSH key management** with auto-discovery and per-instance configuration
|
|
44
|
+
- **Instance caching** with stale-while-revalidate for fast startup
|
|
45
|
+
- **Fully configurable** — all settings in `~/.servonaut/config.json`
|
|
46
|
+
|
|
47
|
+
## Prerequisites
|
|
48
|
+
|
|
49
|
+
- Python 3.8+
|
|
50
|
+
- AWS CLI configured (`~/.aws/credentials` and `~/.aws/config`)
|
|
51
|
+
- SSH client (standard on Linux/macOS, OpenSSH on Windows)
|
|
52
|
+
- `pipx` for isolated installation (recommended)
|
|
53
|
+
|
|
54
|
+
Your AWS credentials need `ec2:DescribeInstances` and `ec2:DescribeRegions` permissions.
|
|
55
|
+
|
|
56
|
+
## Usage
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
servonaut # Launch the TUI
|
|
60
|
+
servonaut --debug # Launch with debug logging to stderr
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Keyboard Shortcuts
|
|
64
|
+
|
|
65
|
+
| Context | Key | Action |
|
|
66
|
+
|---------|-----|--------|
|
|
67
|
+
| Global | `Q` | Quit |
|
|
68
|
+
| Global | `?` | Help screen |
|
|
69
|
+
| Global | `Escape` | Go back / close |
|
|
70
|
+
| Instance List | `/` | Focus search |
|
|
71
|
+
| Instance List | `R` | Force-refresh from AWS |
|
|
72
|
+
| Instance List | `S` | SSH to selected instance |
|
|
73
|
+
| Instance List | `B` | Browse remote files |
|
|
74
|
+
| Instance List | `C` | Run command overlay |
|
|
75
|
+
| Instance List | `T` | SCP transfer |
|
|
76
|
+
| Command Overlay | `Ctrl+C` | Stop running command |
|
|
77
|
+
| Command Overlay | `Ctrl+R` | Command picker (saved + recent) |
|
|
78
|
+
| Command Overlay | `Ctrl+S` | Save command to favorites |
|
|
79
|
+
| Command Overlay | `Up/Down` | Command history |
|
|
80
|
+
|
|
81
|
+
### What You Can Do
|
|
82
|
+
|
|
83
|
+
1. **List Instances** — View all EC2 instances with search/filter
|
|
84
|
+
2. **Search** — Filter instances by name, type, region, or state; search scan results
|
|
85
|
+
3. **Manage SSH Keys** — Configure default and per-instance SSH keys
|
|
86
|
+
4. **Scan Servers** — Run keyword scans across running instances
|
|
87
|
+
5. **Settings** — Configure connection profiles, scan rules, preferences
|
|
88
|
+
|
|
89
|
+
When you select a server: browse files, run commands, SSH connect, SCP transfer, or view scan results. Command history persists across sessions — use `Ctrl+R` to search history and saved commands, `Ctrl+S` to save favorites.
|
|
90
|
+
|
|
91
|
+
### Instance Caching
|
|
92
|
+
|
|
93
|
+
| Scenario | Behavior |
|
|
94
|
+
|----------|----------|
|
|
95
|
+
| First launch (no cache) | Fetches from AWS with progress indicator |
|
|
96
|
+
| Restart within TTL (default 1h) | Instant load from cache |
|
|
97
|
+
| Restart after TTL | Shows stale data immediately, refreshes in background |
|
|
98
|
+
| Press `R` | Force-refresh from AWS |
|
|
99
|
+
|
|
100
|
+
### Configuration
|
|
101
|
+
|
|
102
|
+
All configuration lives in `~/.servonaut/config.json`, created automatically on first run.
|
|
103
|
+
|
|
104
|
+
See [Configuration Guide](docs/configuration.md) for the full reference including connection profiles, scan rules, and match conditions.
|
|
105
|
+
|
|
106
|
+
## Development
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Run directly (primary dev workflow)
|
|
110
|
+
PYTHONPATH=src python3 -m servonaut.main
|
|
111
|
+
|
|
112
|
+
# Run with debug logging
|
|
113
|
+
PYTHONPATH=src python3 -m servonaut.main --debug
|
|
114
|
+
|
|
115
|
+
# Install editable
|
|
116
|
+
pip install -e .
|
|
117
|
+
|
|
118
|
+
# Update pipx installation after changes
|
|
119
|
+
pipx install . --force
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Run tests
|
|
124
|
+
pip install -e ".[test]"
|
|
125
|
+
pytest
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
See [Architecture](docs/architecture.md) for codebase structure and design patterns.
|
|
129
|
+
|
|
130
|
+
## Troubleshooting
|
|
131
|
+
|
|
132
|
+
See [Troubleshooting Guide](docs/troubleshooting.md) for help with SSH connections, bastion hosts, key management, and AWS credentials.
|
|
133
|
+
|
|
134
|
+
## Logging
|
|
135
|
+
|
|
136
|
+
Logs are always written to `~/.servonaut/logs/servonaut.log`. Use `--debug` for verbose stderr output.
|
|
137
|
+
|
|
138
|
+
When SSH fails, the terminal window stays open showing the error and exit code.
|
|
139
|
+
|
|
140
|
+
## License
|
|
141
|
+
|
|
142
|
+
This project is licensed under the MIT License — see the [LICENSE](LICENSE) file for details.
|