vordr 0.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.
- vordr-0.1.0/.github/workflows/ci.yml +29 -0
- vordr-0.1.0/.github/workflows/publish.yml +43 -0
- vordr-0.1.0/.gitignore +32 -0
- vordr-0.1.0/LICENSE +21 -0
- vordr-0.1.0/PKG-INFO +207 -0
- vordr-0.1.0/README.md +180 -0
- vordr-0.1.0/config.example.toml +47 -0
- vordr-0.1.0/pyproject.toml +59 -0
- vordr-0.1.0/tests/test_cli.py +312 -0
- vordr-0.1.0/tests/test_config.py +114 -0
- vordr-0.1.0/tests/test_format.py +64 -0
- vordr-0.1.0/tests/test_hetzner.py +45 -0
- vordr-0.1.0/tests/test_probe.py +87 -0
- vordr-0.1.0/tests/test_rdap.py +86 -0
- vordr-0.1.0/tests/test_secrets.py +42 -0
- vordr-0.1.0/tests/test_vultr.py +48 -0
- vordr-0.1.0/vordr/__init__.py +8 -0
- vordr-0.1.0/vordr/__main__.py +6 -0
- vordr-0.1.0/vordr/cli.py +749 -0
- vordr-0.1.0/vordr/config.py +188 -0
- vordr-0.1.0/vordr/format.py +99 -0
- vordr-0.1.0/vordr/hetzner.py +69 -0
- vordr-0.1.0/vordr/probe.py +225 -0
- vordr-0.1.0/vordr/providers.py +44 -0
- vordr-0.1.0/vordr/rdap.py +121 -0
- vordr-0.1.0/vordr/secrets.py +89 -0
- vordr-0.1.0/vordr/ssh.py +104 -0
- vordr-0.1.0/vordr/vultr.py +78 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
python-version: ["3.11", "3.12"]
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
18
|
+
uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: ${{ matrix.python-version }}
|
|
21
|
+
|
|
22
|
+
- name: Install
|
|
23
|
+
run: pip install -e ".[dev]"
|
|
24
|
+
|
|
25
|
+
- name: Lint (ruff)
|
|
26
|
+
run: ruff check .
|
|
27
|
+
|
|
28
|
+
- name: Test (pytest)
|
|
29
|
+
run: pytest
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
|
|
13
|
+
- name: Set up Python
|
|
14
|
+
uses: actions/setup-python@v5
|
|
15
|
+
with:
|
|
16
|
+
python-version: "3.12"
|
|
17
|
+
|
|
18
|
+
- name: Build
|
|
19
|
+
run: |
|
|
20
|
+
python -m pip install --upgrade build
|
|
21
|
+
python -m build
|
|
22
|
+
|
|
23
|
+
- name: Upload artifacts
|
|
24
|
+
uses: actions/upload-artifact@v4
|
|
25
|
+
with:
|
|
26
|
+
name: dist
|
|
27
|
+
path: dist/
|
|
28
|
+
|
|
29
|
+
publish:
|
|
30
|
+
needs: build
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
environment: pypi
|
|
33
|
+
permissions:
|
|
34
|
+
id-token: write # exigido pelo Trusted Publishing (OIDC)
|
|
35
|
+
steps:
|
|
36
|
+
- name: Download artifacts
|
|
37
|
+
uses: actions/download-artifact@v4
|
|
38
|
+
with:
|
|
39
|
+
name: dist
|
|
40
|
+
path: dist/
|
|
41
|
+
|
|
42
|
+
- name: Publish to PyPI
|
|
43
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
vordr-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Configuração real do usuário — NUNCA versionar (pode conter datas/custos privados)
|
|
2
|
+
config.toml
|
|
3
|
+
/config.toml
|
|
4
|
+
.config/
|
|
5
|
+
|
|
6
|
+
# Segredos (tokens de API) — NUNCA versionar
|
|
7
|
+
secrets.toml
|
|
8
|
+
/secrets.toml
|
|
9
|
+
|
|
10
|
+
# Python
|
|
11
|
+
__pycache__/
|
|
12
|
+
*.py[cod]
|
|
13
|
+
*.egg-info/
|
|
14
|
+
.eggs/
|
|
15
|
+
build/
|
|
16
|
+
dist/
|
|
17
|
+
.venv/
|
|
18
|
+
venv/
|
|
19
|
+
env/
|
|
20
|
+
|
|
21
|
+
# Ferramentas
|
|
22
|
+
.pytest_cache/
|
|
23
|
+
.ruff_cache/
|
|
24
|
+
.mypy_cache/
|
|
25
|
+
.coverage
|
|
26
|
+
htmlcov/
|
|
27
|
+
|
|
28
|
+
# Editores / SO
|
|
29
|
+
.vscode/
|
|
30
|
+
.idea/
|
|
31
|
+
*.swp
|
|
32
|
+
.DS_Store
|
vordr-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Gustavo Almeida
|
|
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.
|
vordr-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: vordr
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Guardião dos servidores — monitoramento de status, recursos, custo/expiração e segurança de hosts Linux via SSH.
|
|
5
|
+
Project-URL: Homepage, https://github.com/gusta-ve/vordr
|
|
6
|
+
Project-URL: Repository, https://github.com/gusta-ve/vordr
|
|
7
|
+
Project-URL: Issues, https://github.com/gusta-ve/vordr/issues
|
|
8
|
+
Author: Gustavo Almeida
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: billing,cli,devops,monitoring,security,servers,ssh,uptime
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: System Administrators
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: System :: Monitoring
|
|
19
|
+
Classifier: Topic :: System :: Systems Administration
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Requires-Dist: rich>=13.7
|
|
22
|
+
Requires-Dist: typer>=0.12
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
25
|
+
Requires-Dist: ruff>=0.5; extra == 'dev'
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# Vordr 🐺
|
|
29
|
+
|
|
30
|
+
> _Na mitologia nórdica, **Vörðr** é o espírito-guardião que acompanha cada pessoa do
|
|
31
|
+
> nascimento à morte, vigiando-a sem descanso. Aqui, Vordr monta guarda diante dos
|
|
32
|
+
> seus servidores._
|
|
33
|
+
|
|
34
|
+
**Vordr** é uma CLI que vigia seus hosts Linux por SSH e responde, num só lugar, às
|
|
35
|
+
perguntas que importam no dia a dia:
|
|
36
|
+
|
|
37
|
+
- **Estão de pé?** — estado, uptime, carga, RAM, disco e containers de todos os hosts.
|
|
38
|
+
- **Vou ser cobrado?** — há quanto tempo você hospeda cada host, quando o
|
|
39
|
+
**servidor** renova e quando o **domínio** expira, e quanto você gasta por mês.
|
|
40
|
+
_O recurso que evita a cobrança surpresa._
|
|
41
|
+
- **Estão seguros?** — falhas de login, portas em escuta, fail2ban, atualizações
|
|
42
|
+
pendentes e necessidade de reboot.
|
|
43
|
+
|
|
44
|
+
Sem agentes instalados nos servidores, sem banco de dados, sem segredos no código:
|
|
45
|
+
Vordr só precisa do seu `~/.ssh/config`.
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
┌──────────────────────────────────────────────────────────────────────┐
|
|
49
|
+
│ Vordr · status dos servidores │
|
|
50
|
+
├───────────┬──────────┬─────────┬──────┬─────┬───────┬────────┬─────────┤
|
|
51
|
+
│ host │ estado │ uptime │ load │ ram │ disco │ docker │ expira │
|
|
52
|
+
├───────────┼──────────┼─────────┼──────┼─────┼───────┼────────┼─────────┤
|
|
53
|
+
│ web │ ● online │ 2sem 5d │ 0.28 │ 32% │ 22% │ 5/6 │ 53d │
|
|
54
|
+
│ db │ ● online │ 4sem 4d │ 0.04 │ 18% │ 62% │ 6/6 │ 6d ⚠ │
|
|
55
|
+
└───────────┴──────────┴─────────┴──────┴─────┴───────┴────────┴─────────┘
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Por que existe
|
|
59
|
+
|
|
60
|
+
Quem mantém alguns servidores acaba acumulando comandos soltos e logins repetidos
|
|
61
|
+
para responder perguntas simples. Vordr junta isso numa camada única que:
|
|
62
|
+
|
|
63
|
+
1. olha **todos os hosts de uma vez**, com métricas comparáveis e coloridas por
|
|
64
|
+
limiar (load por CPU, % de disco/RAM);
|
|
65
|
+
2. avisa **antes** de uma renovação cobrar de novo;
|
|
66
|
+
3. dá uma **auditoria rápida de segurança** sem precisar logar em cada máquina.
|
|
67
|
+
|
|
68
|
+
Vordr coleta métricas via pequenos scripts `sh` que emitem `CHAVE=valor` (estável e
|
|
69
|
+
testável) em vez de parsear saída colorida e frágil — mas ainda oferece um modo
|
|
70
|
+
`--raw` que reproduz a saída nativa de um `status_command` seu, quando você define um.
|
|
71
|
+
|
|
72
|
+
## Instalação
|
|
73
|
+
|
|
74
|
+
Requer Python 3.11+ e o cliente `ssh` configurado com os hosts que você quer monitorar.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pipx install vordr # recomendado (ferramenta isolada no PATH)
|
|
78
|
+
# ou, para desenvolvimento:
|
|
79
|
+
pip install -e ".[dev]"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Configuração
|
|
83
|
+
|
|
84
|
+
Os hosts são **aliases do seu `~/.ssh/config`** — nenhum IP, usuário ou chave fica
|
|
85
|
+
guardado pelo Vordr. As datas de cobrança são informadas por você (o servidor não tem
|
|
86
|
+
como saber quando o provedor ou o registrar vão cobrar de novo).
|
|
87
|
+
|
|
88
|
+
Cada host tem dois blocos opcionais de ciclo de vida: `[hosts.X.server]` (a
|
|
89
|
+
hospedagem) e `[hosts.X.domain]` (o domínio). Ambos com `expires`/`cost`, somados no
|
|
90
|
+
custo mensal.
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
vordr init # cria ~/.config/vordr/config.toml comentado
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
```toml
|
|
97
|
+
[thresholds]
|
|
98
|
+
warn_days = 14
|
|
99
|
+
critical_days = 7
|
|
100
|
+
|
|
101
|
+
[hosts.web]
|
|
102
|
+
ssh = "web" # alias no ~/.ssh/config
|
|
103
|
+
label = "Web"
|
|
104
|
+
# status_command = "meu-status" # opcional: seu script para `vordr status --raw`
|
|
105
|
+
|
|
106
|
+
[hosts.web.server] # a hospedagem
|
|
107
|
+
provider = "Hetzner"
|
|
108
|
+
since = "2024-03-01" # desde quando você hospeda (tempo de hospedagem)
|
|
109
|
+
expires = "2026-08-15" # AAAA-MM-DD — próxima renovação do servidor
|
|
110
|
+
cost = 6.99
|
|
111
|
+
currency = "USD"
|
|
112
|
+
cycle = "monthly" # monthly | yearly
|
|
113
|
+
|
|
114
|
+
[hosts.web.domain] # o domínio (opcional)
|
|
115
|
+
name = "web.exemplo.com"
|
|
116
|
+
registrar = "Cloudflare"
|
|
117
|
+
expires = "2027-03-01"
|
|
118
|
+
cost = 12.00
|
|
119
|
+
currency = "USD"
|
|
120
|
+
cycle = "yearly"
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Vordr não embute nenhum host: `vordr init` cria um `config.toml` comentado para você
|
|
124
|
+
preencher com seus aliases. Sem hosts configurados, os comandos apenas orientam a
|
|
125
|
+
rodar `vordr init`.
|
|
126
|
+
|
|
127
|
+
## Uso
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
vordr status # painel de todos os hosts
|
|
131
|
+
vordr status web # só um host
|
|
132
|
+
vordr status --watch 5 # atualiza a cada 5s (tela cheia)
|
|
133
|
+
vordr status --raw # saída nativa do status_command do host
|
|
134
|
+
|
|
135
|
+
vordr resources # CPU/load, memória e disco em detalhe
|
|
136
|
+
vordr security # auditoria: logins, falhas, portas, fail2ban, updates
|
|
137
|
+
vordr cost # tabela: hospedagem, renovação de servidor/domínio, custo/mês
|
|
138
|
+
vordr cost web # painel detalhado do ciclo de vida de um host
|
|
139
|
+
vordr cost --offline # sem rede: usa só o que está no config
|
|
140
|
+
vordr hosts # lista o que está configurado
|
|
141
|
+
|
|
142
|
+
vordr secret set hetzner # guarda o token da API (chmod 600, fora do repo)
|
|
143
|
+
vordr secret status # mostra quais provedores têm token (mascarado)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Todas as cores seguem limiares: verde (ok), amarelo (atenção), vermelho (crítico) —
|
|
147
|
+
para disco/RAM, load por CPU e dias até a cobrança.
|
|
148
|
+
|
|
149
|
+
## Automação do `cost` (sem digitar datas)
|
|
150
|
+
|
|
151
|
+
O `cost` preenche sozinho o que você não informou — **e o valor do config sempre
|
|
152
|
+
vence** (útil para preços promocionais/legados):
|
|
153
|
+
|
|
154
|
+
- **Domínio:** informe só `name` no `[hosts.X.domain]` e a expiração vem do **RDAP**
|
|
155
|
+
(público, sem credencial), cacheada em `~/.cache/vordr/rdap.json`.
|
|
156
|
+
- **Servidor:** com `provider = "Hetzner"` ou `"Vultr"` e um token configurado, o
|
|
157
|
+
`since` (data de criação) e o **custo mensal** vêm da **API do provedor**.
|
|
158
|
+
|
|
159
|
+
Provedores suportados: **Hetzner** (`HCLOUD_TOKEN`) e **Vultr** (`VULTR_API_KEY`).
|
|
160
|
+
Tokens nunca ficam no repositório: são lidos de variável de ambiente ou de
|
|
161
|
+
`~/.config/vordr/secrets.toml` (chmod 600, no `.gitignore`), com o env tendo
|
|
162
|
+
prioridade. Configure com `vordr secret set <provedor>`. Valores vindos da rede
|
|
163
|
+
aparecem marcados com `(API)` / `(RDAP)`.
|
|
164
|
+
|
|
165
|
+
> ⚠️ O preço da API é o **de lista** do tipo/plano — se a sua conta tem valor
|
|
166
|
+
> promocional/travado, informe `cost` no config (ele vence). A API da **Vultr** usa
|
|
167
|
+
> allowlist de IP e o token é *full-access* (não há read-only): cuide bem dele.
|
|
168
|
+
|
|
169
|
+
## Como funciona
|
|
170
|
+
|
|
171
|
+
| Camada | Arquivo | Responsabilidade |
|
|
172
|
+
|-------------------|--------------------|----------------------------------------------------|
|
|
173
|
+
| Transporte SSH | `vordr/ssh.py` | Executa comandos remotos (`BatchMode`, timeout). |
|
|
174
|
+
| Coleta de métrica | `vordr/probe.py` | Scripts `sh` → `CHAVE=valor` → dataclasses. |
|
|
175
|
+
| Configuração | `vordr/config.py` | Lê o TOML; cálculo de dias/custo. |
|
|
176
|
+
| Expiração domínio | `vordr/rdap.py` | RDAP público + cache em disco (sem credencial). |
|
|
177
|
+
| API de provedor | `vordr/hetzner.py` | Cliente read-only da Hetzner (since + preço). |
|
|
178
|
+
| Segredos | `vordr/secrets.py` | Tokens fora do repo (env > arquivo chmod 600). |
|
|
179
|
+
| Formatação | `vordr/format.py` | Funções puras (uptime, bytes, limiares de cor). |
|
|
180
|
+
| CLI | `vordr/cli.py` | Typer + Rich; orquestra tudo em paralelo. |
|
|
181
|
+
|
|
182
|
+
Os hosts são consultados **em paralelo** (`ThreadPoolExecutor`), então monitorar 2 ou
|
|
183
|
+
10 servidores leva praticamente o mesmo tempo.
|
|
184
|
+
|
|
185
|
+
### Segurança por design
|
|
186
|
+
|
|
187
|
+
- **Read-only:** Vordr só roda comandos de leitura (`/proc`, `df`, `ss`, `last`, …).
|
|
188
|
+
- **Sem segredos no repositório:** hosts são aliases SSH; o `config.toml` real fica
|
|
189
|
+
fora do versionamento (veja `.gitignore`).
|
|
190
|
+
- **Sem `sudo` interativo:** checagens privilegiadas usam `sudo -n` (não-interativo) e
|
|
191
|
+
degradam graciosamente quando não há permissão — nunca travam o terminal.
|
|
192
|
+
- **`BatchMode`:** se a chave não estiver disponível, falha rápido em vez de pedir senha.
|
|
193
|
+
|
|
194
|
+
## Desenvolvimento
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
pip install -e ".[dev]"
|
|
198
|
+
ruff check .
|
|
199
|
+
pytest
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Os testes não tocam a rede: a camada SSH é injetada (`monkeypatch`) e a lógica de
|
|
203
|
+
parsing/formatação é testada com amostras reais de saída dos servidores.
|
|
204
|
+
|
|
205
|
+
## Licença
|
|
206
|
+
|
|
207
|
+
MIT — veja [LICENSE](LICENSE).
|
vordr-0.1.0/README.md
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Vordr 🐺
|
|
2
|
+
|
|
3
|
+
> _Na mitologia nórdica, **Vörðr** é o espírito-guardião que acompanha cada pessoa do
|
|
4
|
+
> nascimento à morte, vigiando-a sem descanso. Aqui, Vordr monta guarda diante dos
|
|
5
|
+
> seus servidores._
|
|
6
|
+
|
|
7
|
+
**Vordr** é uma CLI que vigia seus hosts Linux por SSH e responde, num só lugar, às
|
|
8
|
+
perguntas que importam no dia a dia:
|
|
9
|
+
|
|
10
|
+
- **Estão de pé?** — estado, uptime, carga, RAM, disco e containers de todos os hosts.
|
|
11
|
+
- **Vou ser cobrado?** — há quanto tempo você hospeda cada host, quando o
|
|
12
|
+
**servidor** renova e quando o **domínio** expira, e quanto você gasta por mês.
|
|
13
|
+
_O recurso que evita a cobrança surpresa._
|
|
14
|
+
- **Estão seguros?** — falhas de login, portas em escuta, fail2ban, atualizações
|
|
15
|
+
pendentes e necessidade de reboot.
|
|
16
|
+
|
|
17
|
+
Sem agentes instalados nos servidores, sem banco de dados, sem segredos no código:
|
|
18
|
+
Vordr só precisa do seu `~/.ssh/config`.
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
┌──────────────────────────────────────────────────────────────────────┐
|
|
22
|
+
│ Vordr · status dos servidores │
|
|
23
|
+
├───────────┬──────────┬─────────┬──────┬─────┬───────┬────────┬─────────┤
|
|
24
|
+
│ host │ estado │ uptime │ load │ ram │ disco │ docker │ expira │
|
|
25
|
+
├───────────┼──────────┼─────────┼──────┼─────┼───────┼────────┼─────────┤
|
|
26
|
+
│ web │ ● online │ 2sem 5d │ 0.28 │ 32% │ 22% │ 5/6 │ 53d │
|
|
27
|
+
│ db │ ● online │ 4sem 4d │ 0.04 │ 18% │ 62% │ 6/6 │ 6d ⚠ │
|
|
28
|
+
└───────────┴──────────┴─────────┴──────┴─────┴───────┴────────┴─────────┘
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Por que existe
|
|
32
|
+
|
|
33
|
+
Quem mantém alguns servidores acaba acumulando comandos soltos e logins repetidos
|
|
34
|
+
para responder perguntas simples. Vordr junta isso numa camada única que:
|
|
35
|
+
|
|
36
|
+
1. olha **todos os hosts de uma vez**, com métricas comparáveis e coloridas por
|
|
37
|
+
limiar (load por CPU, % de disco/RAM);
|
|
38
|
+
2. avisa **antes** de uma renovação cobrar de novo;
|
|
39
|
+
3. dá uma **auditoria rápida de segurança** sem precisar logar em cada máquina.
|
|
40
|
+
|
|
41
|
+
Vordr coleta métricas via pequenos scripts `sh` que emitem `CHAVE=valor` (estável e
|
|
42
|
+
testável) em vez de parsear saída colorida e frágil — mas ainda oferece um modo
|
|
43
|
+
`--raw` que reproduz a saída nativa de um `status_command` seu, quando você define um.
|
|
44
|
+
|
|
45
|
+
## Instalação
|
|
46
|
+
|
|
47
|
+
Requer Python 3.11+ e o cliente `ssh` configurado com os hosts que você quer monitorar.
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pipx install vordr # recomendado (ferramenta isolada no PATH)
|
|
51
|
+
# ou, para desenvolvimento:
|
|
52
|
+
pip install -e ".[dev]"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Configuração
|
|
56
|
+
|
|
57
|
+
Os hosts são **aliases do seu `~/.ssh/config`** — nenhum IP, usuário ou chave fica
|
|
58
|
+
guardado pelo Vordr. As datas de cobrança são informadas por você (o servidor não tem
|
|
59
|
+
como saber quando o provedor ou o registrar vão cobrar de novo).
|
|
60
|
+
|
|
61
|
+
Cada host tem dois blocos opcionais de ciclo de vida: `[hosts.X.server]` (a
|
|
62
|
+
hospedagem) e `[hosts.X.domain]` (o domínio). Ambos com `expires`/`cost`, somados no
|
|
63
|
+
custo mensal.
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
vordr init # cria ~/.config/vordr/config.toml comentado
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
```toml
|
|
70
|
+
[thresholds]
|
|
71
|
+
warn_days = 14
|
|
72
|
+
critical_days = 7
|
|
73
|
+
|
|
74
|
+
[hosts.web]
|
|
75
|
+
ssh = "web" # alias no ~/.ssh/config
|
|
76
|
+
label = "Web"
|
|
77
|
+
# status_command = "meu-status" # opcional: seu script para `vordr status --raw`
|
|
78
|
+
|
|
79
|
+
[hosts.web.server] # a hospedagem
|
|
80
|
+
provider = "Hetzner"
|
|
81
|
+
since = "2024-03-01" # desde quando você hospeda (tempo de hospedagem)
|
|
82
|
+
expires = "2026-08-15" # AAAA-MM-DD — próxima renovação do servidor
|
|
83
|
+
cost = 6.99
|
|
84
|
+
currency = "USD"
|
|
85
|
+
cycle = "monthly" # monthly | yearly
|
|
86
|
+
|
|
87
|
+
[hosts.web.domain] # o domínio (opcional)
|
|
88
|
+
name = "web.exemplo.com"
|
|
89
|
+
registrar = "Cloudflare"
|
|
90
|
+
expires = "2027-03-01"
|
|
91
|
+
cost = 12.00
|
|
92
|
+
currency = "USD"
|
|
93
|
+
cycle = "yearly"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Vordr não embute nenhum host: `vordr init` cria um `config.toml` comentado para você
|
|
97
|
+
preencher com seus aliases. Sem hosts configurados, os comandos apenas orientam a
|
|
98
|
+
rodar `vordr init`.
|
|
99
|
+
|
|
100
|
+
## Uso
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
vordr status # painel de todos os hosts
|
|
104
|
+
vordr status web # só um host
|
|
105
|
+
vordr status --watch 5 # atualiza a cada 5s (tela cheia)
|
|
106
|
+
vordr status --raw # saída nativa do status_command do host
|
|
107
|
+
|
|
108
|
+
vordr resources # CPU/load, memória e disco em detalhe
|
|
109
|
+
vordr security # auditoria: logins, falhas, portas, fail2ban, updates
|
|
110
|
+
vordr cost # tabela: hospedagem, renovação de servidor/domínio, custo/mês
|
|
111
|
+
vordr cost web # painel detalhado do ciclo de vida de um host
|
|
112
|
+
vordr cost --offline # sem rede: usa só o que está no config
|
|
113
|
+
vordr hosts # lista o que está configurado
|
|
114
|
+
|
|
115
|
+
vordr secret set hetzner # guarda o token da API (chmod 600, fora do repo)
|
|
116
|
+
vordr secret status # mostra quais provedores têm token (mascarado)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Todas as cores seguem limiares: verde (ok), amarelo (atenção), vermelho (crítico) —
|
|
120
|
+
para disco/RAM, load por CPU e dias até a cobrança.
|
|
121
|
+
|
|
122
|
+
## Automação do `cost` (sem digitar datas)
|
|
123
|
+
|
|
124
|
+
O `cost` preenche sozinho o que você não informou — **e o valor do config sempre
|
|
125
|
+
vence** (útil para preços promocionais/legados):
|
|
126
|
+
|
|
127
|
+
- **Domínio:** informe só `name` no `[hosts.X.domain]` e a expiração vem do **RDAP**
|
|
128
|
+
(público, sem credencial), cacheada em `~/.cache/vordr/rdap.json`.
|
|
129
|
+
- **Servidor:** com `provider = "Hetzner"` ou `"Vultr"` e um token configurado, o
|
|
130
|
+
`since` (data de criação) e o **custo mensal** vêm da **API do provedor**.
|
|
131
|
+
|
|
132
|
+
Provedores suportados: **Hetzner** (`HCLOUD_TOKEN`) e **Vultr** (`VULTR_API_KEY`).
|
|
133
|
+
Tokens nunca ficam no repositório: são lidos de variável de ambiente ou de
|
|
134
|
+
`~/.config/vordr/secrets.toml` (chmod 600, no `.gitignore`), com o env tendo
|
|
135
|
+
prioridade. Configure com `vordr secret set <provedor>`. Valores vindos da rede
|
|
136
|
+
aparecem marcados com `(API)` / `(RDAP)`.
|
|
137
|
+
|
|
138
|
+
> ⚠️ O preço da API é o **de lista** do tipo/plano — se a sua conta tem valor
|
|
139
|
+
> promocional/travado, informe `cost` no config (ele vence). A API da **Vultr** usa
|
|
140
|
+
> allowlist de IP e o token é *full-access* (não há read-only): cuide bem dele.
|
|
141
|
+
|
|
142
|
+
## Como funciona
|
|
143
|
+
|
|
144
|
+
| Camada | Arquivo | Responsabilidade |
|
|
145
|
+
|-------------------|--------------------|----------------------------------------------------|
|
|
146
|
+
| Transporte SSH | `vordr/ssh.py` | Executa comandos remotos (`BatchMode`, timeout). |
|
|
147
|
+
| Coleta de métrica | `vordr/probe.py` | Scripts `sh` → `CHAVE=valor` → dataclasses. |
|
|
148
|
+
| Configuração | `vordr/config.py` | Lê o TOML; cálculo de dias/custo. |
|
|
149
|
+
| Expiração domínio | `vordr/rdap.py` | RDAP público + cache em disco (sem credencial). |
|
|
150
|
+
| API de provedor | `vordr/hetzner.py` | Cliente read-only da Hetzner (since + preço). |
|
|
151
|
+
| Segredos | `vordr/secrets.py` | Tokens fora do repo (env > arquivo chmod 600). |
|
|
152
|
+
| Formatação | `vordr/format.py` | Funções puras (uptime, bytes, limiares de cor). |
|
|
153
|
+
| CLI | `vordr/cli.py` | Typer + Rich; orquestra tudo em paralelo. |
|
|
154
|
+
|
|
155
|
+
Os hosts são consultados **em paralelo** (`ThreadPoolExecutor`), então monitorar 2 ou
|
|
156
|
+
10 servidores leva praticamente o mesmo tempo.
|
|
157
|
+
|
|
158
|
+
### Segurança por design
|
|
159
|
+
|
|
160
|
+
- **Read-only:** Vordr só roda comandos de leitura (`/proc`, `df`, `ss`, `last`, …).
|
|
161
|
+
- **Sem segredos no repositório:** hosts são aliases SSH; o `config.toml` real fica
|
|
162
|
+
fora do versionamento (veja `.gitignore`).
|
|
163
|
+
- **Sem `sudo` interativo:** checagens privilegiadas usam `sudo -n` (não-interativo) e
|
|
164
|
+
degradam graciosamente quando não há permissão — nunca travam o terminal.
|
|
165
|
+
- **`BatchMode`:** se a chave não estiver disponível, falha rápido em vez de pedir senha.
|
|
166
|
+
|
|
167
|
+
## Desenvolvimento
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
pip install -e ".[dev]"
|
|
171
|
+
ruff check .
|
|
172
|
+
pytest
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Os testes não tocam a rede: a camada SSH é injetada (`monkeypatch`) e a lógica de
|
|
176
|
+
parsing/formatação é testada com amostras reais de saída dos servidores.
|
|
177
|
+
|
|
178
|
+
## Licença
|
|
179
|
+
|
|
180
|
+
MIT — veja [LICENSE](LICENSE).
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Exemplo de configuração do Vordr.
|
|
2
|
+
# Copie para ~/.config/vordr/config.toml (ou rode `vordr init`) e ajuste.
|
|
3
|
+
#
|
|
4
|
+
# IMPORTANTE: os hosts são apenas ALIASES do seu ~/.ssh/config.
|
|
5
|
+
# Nenhum IP, usuário ou segredo deve ficar aqui — quem resolve isso é o SSH.
|
|
6
|
+
#
|
|
7
|
+
# Cada host tem dois blocos opcionais de ciclo de vida:
|
|
8
|
+
# [hosts.X.server] — a hospedagem (provedor, desde quando, renovação, custo)
|
|
9
|
+
# [hosts.X.domain] — o domínio (registrar, expiração, custo)
|
|
10
|
+
|
|
11
|
+
[thresholds]
|
|
12
|
+
warn_days = 14 # amarelo quando faltarem <= 14 dias para expirar
|
|
13
|
+
critical_days = 7 # vermelho quando faltarem <= 7 dias
|
|
14
|
+
|
|
15
|
+
[hosts.web]
|
|
16
|
+
ssh = "web" # alias no ~/.ssh/config
|
|
17
|
+
label = "Web"
|
|
18
|
+
# status_command = "meu-status" # opcional: seu script p/ `vordr status --raw`
|
|
19
|
+
|
|
20
|
+
[hosts.web.server]
|
|
21
|
+
provider = "Hetzner" # com token (vordr secret set hetzner), since e custo
|
|
22
|
+
# provider_server = "web-01" # nome do servidor na API, se != do alias
|
|
23
|
+
since = "2024-03-01" # vêm da API; o que você puser aqui sempre vence.
|
|
24
|
+
expires = "2026-08-15" # AAAA-MM-DD — próxima renovação do servidor
|
|
25
|
+
cost = 6.99
|
|
26
|
+
currency = "USD"
|
|
27
|
+
cycle = "monthly" # monthly | yearly
|
|
28
|
+
|
|
29
|
+
[hosts.web.domain]
|
|
30
|
+
name = "web.exemplo.com"
|
|
31
|
+
registrar = "Cloudflare"
|
|
32
|
+
expires = "2027-03-01" # quando o domínio expira
|
|
33
|
+
cost = 12.00
|
|
34
|
+
currency = "USD"
|
|
35
|
+
cycle = "yearly"
|
|
36
|
+
|
|
37
|
+
[hosts.db]
|
|
38
|
+
ssh = "db"
|
|
39
|
+
label = "DB"
|
|
40
|
+
|
|
41
|
+
[hosts.db.server]
|
|
42
|
+
provider = "DigitalOcean"
|
|
43
|
+
since = "2025-01-10"
|
|
44
|
+
expires = "2026-07-30"
|
|
45
|
+
cost = 12.00
|
|
46
|
+
currency = "USD"
|
|
47
|
+
cycle = "monthly"
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "vordr"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Guardião dos servidores — monitoramento de status, recursos, custo/expiração e segurança de hosts Linux via SSH."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
requires-python = ">=3.11"
|
|
12
|
+
authors = [{ name = "Gustavo Almeida" }]
|
|
13
|
+
keywords = ["monitoring", "ssh", "devops", "security", "cli", "servers", "uptime", "billing"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Environment :: Console",
|
|
17
|
+
"Intended Audience :: System Administrators",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Topic :: System :: Monitoring",
|
|
22
|
+
"Topic :: System :: Systems Administration",
|
|
23
|
+
]
|
|
24
|
+
dependencies = [
|
|
25
|
+
"typer>=0.12",
|
|
26
|
+
"rich>=13.7",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
dev = ["pytest>=8.0", "ruff>=0.5"]
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Homepage = "https://github.com/gusta-ve/vordr"
|
|
34
|
+
Repository = "https://github.com/gusta-ve/vordr"
|
|
35
|
+
Issues = "https://github.com/gusta-ve/vordr/issues"
|
|
36
|
+
|
|
37
|
+
[project.scripts]
|
|
38
|
+
vordr = "vordr.cli:app"
|
|
39
|
+
|
|
40
|
+
[tool.hatch.version]
|
|
41
|
+
path = "vordr/__init__.py"
|
|
42
|
+
|
|
43
|
+
[tool.hatch.build.targets.wheel]
|
|
44
|
+
packages = ["vordr"]
|
|
45
|
+
|
|
46
|
+
[tool.ruff]
|
|
47
|
+
line-length = 100
|
|
48
|
+
target-version = "py311"
|
|
49
|
+
|
|
50
|
+
[tool.ruff.lint]
|
|
51
|
+
select = ["E", "F", "I", "UP", "B", "W"]
|
|
52
|
+
|
|
53
|
+
[tool.ruff.lint.per-file-ignores]
|
|
54
|
+
# probe.py embute scripts shell (awk one-liners) que não cabem em 100 colunas.
|
|
55
|
+
"vordr/probe.py" = ["E501"]
|
|
56
|
+
|
|
57
|
+
[tool.pytest.ini_options]
|
|
58
|
+
testpaths = ["tests"]
|
|
59
|
+
addopts = "-q"
|