raijin-server 0.2.4__py3-none-any.whl → 0.2.5__py3-none-any.whl

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.
@@ -437,6 +437,7 @@ def _install_cert_manager_helm(ctx: ExecutionContext) -> bool:
437
437
  typer.secho("\n📦 Instalando cert-manager via Helm...", fg=typer.colors.CYAN, bold=True)
438
438
 
439
439
  try:
440
+ # O helm_upgrade_install agora limpa releases pendentes automaticamente
440
441
  helm_upgrade_install(
441
442
  release="cert-manager",
442
443
  chart=CHART_NAME,
raijin_server/utils.py CHANGED
@@ -299,6 +299,62 @@ def helm_repo_update(ctx: ExecutionContext) -> None:
299
299
  run_cmd(["helm", "repo", "update"], ctx)
300
300
 
301
301
 
302
+ def _get_helm_release_status(release: str, namespace: str) -> str:
303
+ """Retorna status do release Helm (lowercased) ou string vazia se nao existir."""
304
+ try:
305
+ import json
306
+ result = subprocess.run(
307
+ ["helm", "status", release, "-n", namespace, "-o", "json"],
308
+ capture_output=True,
309
+ text=True,
310
+ timeout=30,
311
+ )
312
+ if result.returncode != 0 or not result.stdout:
313
+ return ""
314
+ data = json.loads(result.stdout)
315
+ return str(data.get("info", {}).get("status", "")).lower()
316
+ except Exception:
317
+ return ""
318
+
319
+
320
+ def _cleanup_pending_helm_release(release: str, namespace: str, ctx: ExecutionContext) -> None:
321
+ """Remove release Helm em estado pendente que bloqueia novas operacoes."""
322
+ if ctx.dry_run:
323
+ return
324
+
325
+ status = _get_helm_release_status(release, namespace)
326
+ if not status:
327
+ return
328
+
329
+ # Estados que bloqueiam: pending-install, pending-upgrade, pending-rollback
330
+ if status.startswith("pending"):
331
+ typer.secho(
332
+ f"⚠ Release '{release}' em estado '{status}'. Limpando antes de prosseguir...",
333
+ fg=typer.colors.YELLOW,
334
+ )
335
+ # Tenta rollback primeiro (funciona para pending-upgrade)
336
+ subprocess.run(
337
+ ["helm", "rollback", release, "-n", namespace, "--wait", "--timeout", "2m"],
338
+ capture_output=True,
339
+ timeout=150,
340
+ )
341
+ # Verifica se resolveu
342
+ new_status = _get_helm_release_status(release, namespace)
343
+ if new_status.startswith("pending"):
344
+ # Se ainda pendente, desinstala
345
+ typer.secho(
346
+ f" Rollback nao resolveu. Desinstalando release '{release}'...",
347
+ fg=typer.colors.YELLOW,
348
+ )
349
+ subprocess.run(
350
+ ["helm", "uninstall", release, "-n", namespace, "--wait", "--timeout", "3m"],
351
+ capture_output=True,
352
+ timeout=200,
353
+ )
354
+ time.sleep(5)
355
+ typer.secho(f"✓ Release '{release}' limpo.", fg=typer.colors.GREEN)
356
+
357
+
302
358
  def helm_upgrade_install(
303
359
  release: str,
304
360
  chart: str,
@@ -311,9 +367,16 @@ def helm_upgrade_install(
311
367
  create_namespace: bool = True,
312
368
  extra_args: list[str] | None = None,
313
369
  ) -> None:
314
- """Executa helm upgrade --install com opcoes comuns."""
370
+ """Executa helm upgrade --install com opcoes comuns.
371
+
372
+ Automaticamente detecta e limpa releases em estado pendente antes de instalar.
373
+ """
315
374
 
316
375
  ensure_tool("helm", ctx, install_hint="Instale helm ou habilite dry-run para so visualizar.")
376
+
377
+ # Limpa releases pendentes antes de tentar instalar
378
+ _cleanup_pending_helm_release(release, namespace, ctx)
379
+
317
380
  if repo and repo_url:
318
381
  helm_repo_add(repo, repo_url, ctx)
319
382
  helm_repo_update(ctx)
@@ -328,7 +391,21 @@ def helm_upgrade_install(
328
391
  cmd.extend(["--set", value])
329
392
  if extra_args:
330
393
  cmd.extend(extra_args)
331
- run_cmd(cmd, ctx)
394
+
395
+ try:
396
+ run_cmd(cmd, ctx)
397
+ except Exception as e:
398
+ err_text = str(e).lower()
399
+ # Se falhou por operacao em progresso, tenta limpar e reinstalar uma vez
400
+ if "another operation" in err_text and "in progress" in err_text:
401
+ typer.secho(
402
+ f"⚠ Helm detectou operacao pendente em '{release}'. Limpando e tentando novamente...",
403
+ fg=typer.colors.YELLOW,
404
+ )
405
+ _cleanup_pending_helm_release(release, namespace, ctx)
406
+ run_cmd(cmd, ctx)
407
+ else:
408
+ raise
332
409
 
333
410
 
334
411
  def kubectl_apply(target: str, ctx: ExecutionContext) -> None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: raijin-server
3
- Version: 0.2.4
3
+ Version: 0.2.5
4
4
  Summary: CLI para automacao de setup e hardening de servidores Ubuntu Server.
5
5
  Home-page: https://example.com/raijin-server
6
6
  Author: Equipe Raijin
@@ -37,6 +37,14 @@ CLI em Python (Typer) para automatizar setup e hardening de servidores Ubuntu Se
37
37
 
38
38
  **✨ Versão Auditada e Resiliente para Produção**
39
39
 
40
+ ## Links úteis
41
+
42
+ - Repositório: https://github.com/rafaelluisdacostacoelho/raijin-server
43
+ - Documentação completa: [docs/INFRASTRUCTURE_GUIDE.md](docs/INFRASTRUCTURE_GUIDE.md)
44
+ - Arquitetura: [ARCHITECTURE.md](ARCHITECTURE.md)
45
+ - Auditoria: [AUDIT.md](AUDIT.md)
46
+ - Segurança: [SECURITY.md](SECURITY.md)
47
+
40
48
  ## Destaques
41
49
 
42
50
  - ✅ **Validações de Pré-requisitos**: OS, espaço em disco, memória, conectividade, ambiente Python (venv)
@@ -405,6 +413,32 @@ pytest
405
413
  ruff check src tests
406
414
  ```
407
415
 
416
+ ## Publicar no PyPI (Twine)
417
+
418
+ O Twine é a ferramenta oficial para enviar pacotes Python ao PyPI com upload seguro (HTTPS e checagem de hash). Use sempre um token de API.
419
+
420
+ Passo a passo:
421
+ ```bash
422
+ # 1) Gere artefatos
423
+ python -m build --sdist --wheel --outdir dist/
424
+
425
+ # 2) Configure o token (crie em https://pypi.org/manage/account/token/)
426
+ export TWINE_USERNAME=__token__
427
+ export TWINE_PASSWORD="<seu-token>"
428
+
429
+ # 3) Envie para o PyPI
430
+ python -m twine upload dist/*
431
+
432
+ # 4) Verifique instalação
433
+ python -m pip install -U raijin-server
434
+ raijin-server --version
435
+ ```
436
+
437
+ Boas práticas:
438
+ - Use venv dedicado para publicar (`python -m venv ~/.venvs/publish && source ~/.venvs/publish/bin/activate`).
439
+ - Nunca commite ou exponha o token; mantenha em variável de ambiente/secret manager.
440
+ - Sempre suba primeiro para TestPyPI se quiser validar (`--repository testpypi`).
441
+
408
442
  ## Acesso remoto seguro (VPN + SSH)
409
443
 
410
444
  Execute `raijin-server ssh-hardening` para aplicar as politicas abaixo automaticamente e `raijin-server vpn` para subir o servidor WireGuard com um cliente inicial. Use `--dry-run` se quiser apenas revisar os comandos.
@@ -2,13 +2,13 @@ raijin_server/__init__.py,sha256=7-69Vj-HYrv98hWrKmwDqDQ-ehtTqJebx1JeP4St6Q4,94
2
2
  raijin_server/cli.py,sha256=PfuIXc-pw1yZtJzCrxDVSWSsPAVBt9wqZBF-dWh6mwo,19274
3
3
  raijin_server/config.py,sha256=Dta2CS1d6RgNiQ84P6dTXk98boFrjzuvhs_fCdlm0I4,4810
4
4
  raijin_server/healthchecks.py,sha256=BJyWyUDtEswEblvGwWMejtMnsUb8kJcULVdS9iycrcc,14565
5
- raijin_server/utils.py,sha256=oQM-NGL_kmlNZejFvxXk85MI_WkcxNfwaw5LeAsKUFU,11476
5
+ raijin_server/utils.py,sha256=MNIevCttKq5fVS-I4ZwlY7f7JZtEiwwY_kj69WV4AsQ,14330
6
6
  raijin_server/validators.py,sha256=qOZMHgwjHogVf17UPlxfUCpQd9qAGQW7tycd8mUvnEs,9404
7
7
  raijin_server/modules/__init__.py,sha256=e_IbkhLGPcF8to9QUmIESP6fpcTOYcIhaXLKIvqRJMY,920
8
8
  raijin_server/modules/apokolips_demo.py,sha256=8ltsXRbVDwlDwLMIvh02NG-FeAfBWw_v6lh7IGOyNqs,13725
9
9
  raijin_server/modules/bootstrap.py,sha256=oVIGNRW_JbgY8zXNHGAIP0vGbbHNHyQexthxo5zhbcw,9762
10
10
  raijin_server/modules/calico.py,sha256=a8N7YYv7NoaspPKdhRtwHy3V2mM4cP5xA1H8BwslB18,4139
11
- raijin_server/modules/cert_manager.py,sha256=3aXK2ivh0eCFLMllpWjUWS36UA3sWplP40daQRfWv14,34393
11
+ raijin_server/modules/cert_manager.py,sha256=dse7AIUVOM2h7d2i3DWsvHLsA9NtcazebTPgOEUWB-8,34473
12
12
  raijin_server/modules/essentials.py,sha256=2xUXCyCQtFGd2DnCKV81N1R6bEJqH8zaet8mLovtQ1I,689
13
13
  raijin_server/modules/firewall.py,sha256=h6AISqiZeTinVT7BjmQIS872qRAFZJLg7meqlth3cfw,757
14
14
  raijin_server/modules/full_install.py,sha256=aR3yOuD7y0KLI20eMrxuFBNrWWn7JMpI4HFKNizEF3o,7464
@@ -36,9 +36,9 @@ raijin_server/scripts/checklist.sh,sha256=j6E0Kmk1EfjLvKK1VpCqzXJAXI_7Bm67LK4ndy
36
36
  raijin_server/scripts/install.sh,sha256=IZOTujOSGmKpznwgL59picsQNVzYkai6FtfFS3Klf34,3908
37
37
  raijin_server/scripts/log_size_metric.sh,sha256=rC2Ck4xnYVJV4Qymu24-indC8bkzfZs4FBqqxGPRl1I,1143
38
38
  raijin_server/scripts/pre-deploy-check.sh,sha256=naPUgKjnKgsh-eGDH2623C7zcr9VjDEw1H0lfYaXW8c,4853
39
- raijin_server-0.2.4.dist-info/licenses/LICENSE,sha256=kJsMCjOiRZE0AQNtxWqBa32z9kMAaF4EUxyHj3hKaJo,1105
40
- raijin_server-0.2.4.dist-info/METADATA,sha256=4X4baNp5EyOCEl916XlHFbXtd25KWwhtwPky5nzT0lU,17772
41
- raijin_server-0.2.4.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
42
- raijin_server-0.2.4.dist-info/entry_points.txt,sha256=3ZvxDX4pvcjkIRsXAJ69wIfVmKa78LKo-C3QhqN2KVM,56
43
- raijin_server-0.2.4.dist-info/top_level.txt,sha256=Yz1xneCRtsZOzbPIcTAcrSxd-1p80pohMXYAZ74dpok,14
44
- raijin_server-0.2.4.dist-info/RECORD,,
39
+ raijin_server-0.2.5.dist-info/licenses/LICENSE,sha256=kJsMCjOiRZE0AQNtxWqBa32z9kMAaF4EUxyHj3hKaJo,1105
40
+ raijin_server-0.2.5.dist-info/METADATA,sha256=TVzTE_0qlyVoyy3lsoWfFn97hJylE_oKyXDFv32BMkg,18925
41
+ raijin_server-0.2.5.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
42
+ raijin_server-0.2.5.dist-info/entry_points.txt,sha256=3ZvxDX4pvcjkIRsXAJ69wIfVmKa78LKo-C3QhqN2KVM,56
43
+ raijin_server-0.2.5.dist-info/top_level.txt,sha256=Yz1xneCRtsZOzbPIcTAcrSxd-1p80pohMXYAZ74dpok,14
44
+ raijin_server-0.2.5.dist-info/RECORD,,