raijin-server 0.2.3__tar.gz → 0.2.5__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.
Files changed (52) hide show
  1. {raijin_server-0.2.3/src/raijin_server.egg-info → raijin_server-0.2.5}/PKG-INFO +65 -1
  2. {raijin_server-0.2.3 → raijin_server-0.2.5}/README.md +64 -0
  3. {raijin_server-0.2.3 → raijin_server-0.2.5}/setup.cfg +1 -1
  4. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/__init__.py +1 -1
  5. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/cli.py +77 -0
  6. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/healthchecks.py +61 -2
  7. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/apokolips_demo.py +40 -4
  8. raijin_server-0.2.5/src/raijin_server/modules/cert_manager.py +1035 -0
  9. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/full_install.py +44 -1
  10. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/utils.py +79 -2
  11. {raijin_server-0.2.3 → raijin_server-0.2.5/src/raijin_server.egg-info}/PKG-INFO +65 -1
  12. raijin_server-0.2.3/src/raijin_server/modules/cert_manager.py +0 -156
  13. {raijin_server-0.2.3 → raijin_server-0.2.5}/LICENSE +0 -0
  14. {raijin_server-0.2.3 → raijin_server-0.2.5}/pyproject.toml +0 -0
  15. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/config.py +0 -0
  16. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/__init__.py +0 -0
  17. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/bootstrap.py +0 -0
  18. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/calico.py +0 -0
  19. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/essentials.py +0 -0
  20. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/firewall.py +0 -0
  21. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/grafana.py +0 -0
  22. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/hardening.py +0 -0
  23. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/harness.py +0 -0
  24. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/istio.py +0 -0
  25. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/kafka.py +0 -0
  26. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/kong.py +0 -0
  27. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/kubernetes.py +0 -0
  28. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/loki.py +0 -0
  29. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/minio.py +0 -0
  30. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/network.py +0 -0
  31. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/observability_dashboards.py +0 -0
  32. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/observability_ingress.py +0 -0
  33. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/prometheus.py +0 -0
  34. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/sanitize.py +0 -0
  35. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/secrets.py +0 -0
  36. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/ssh_hardening.py +0 -0
  37. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/traefik.py +0 -0
  38. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/velero.py +0 -0
  39. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/modules/vpn.py +0 -0
  40. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/scripts/__init__.py +0 -0
  41. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/scripts/checklist.sh +0 -0
  42. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/scripts/install.sh +0 -0
  43. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/scripts/log_size_metric.sh +0 -0
  44. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/scripts/pre-deploy-check.sh +0 -0
  45. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server/validators.py +0 -0
  46. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server.egg-info/SOURCES.txt +0 -0
  47. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server.egg-info/dependency_links.txt +0 -0
  48. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server.egg-info/entry_points.txt +0 -0
  49. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server.egg-info/requires.txt +0 -0
  50. {raijin_server-0.2.3 → raijin_server-0.2.5}/src/raijin_server.egg-info/top_level.txt +0 -0
  51. {raijin_server-0.2.3 → raijin_server-0.2.5}/tests/test_full_install_sequence.py +0 -0
  52. {raijin_server-0.2.3 → raijin_server-0.2.5}/tests/test_registry.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: raijin-server
3
- Version: 0.2.3
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)
@@ -81,6 +89,36 @@ source .venv/bin/activate
81
89
  python -m pip install -e .
82
90
  ```
83
91
 
92
+ ### Instalação em Produção (Recomendado)
93
+
94
+ Para servidores em produção, use um venv isolado e execute com sudo preservando o ambiente:
95
+
96
+ ```bash
97
+ # 1. Sair do venv atual (se estiver ativo)
98
+ deactivate
99
+
100
+ # 2. (Opcional) Remover venv antigo
101
+ rm -rf ~/.venvs/raijin
102
+
103
+ # 3. Criar venv novo
104
+ python3 -m venv ~/.venvs/raijin
105
+ source ~/.venvs/raijin/bin/activate
106
+ pip install -U pip setuptools
107
+
108
+ # 4. Instalar a versão mais recente
109
+ pip install -U raijin-server
110
+
111
+ # 5. Rodar usando root preservando o venv
112
+ sudo -E ~/.venvs/raijin/bin/raijin-server --version
113
+ sudo -E ~/.venvs/raijin/bin/raijin-server validate
114
+ sudo -E ~/.venvs/raijin/bin/raijin-server full-install
115
+
116
+ # 6. Para sair do venv quando terminar
117
+ deactivate
118
+ ```
119
+
120
+ > **Nota**: O `-E` no sudo preserva as variáveis de ambiente, garantindo que o Python use o venv correto mesmo como root.
121
+
84
122
  ## Uso rapido
85
123
 
86
124
  ### Validar Sistema
@@ -375,6 +413,32 @@ pytest
375
413
  ruff check src tests
376
414
  ```
377
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
+
378
442
  ## Acesso remoto seguro (VPN + SSH)
379
443
 
380
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.
@@ -4,6 +4,14 @@ CLI em Python (Typer) para automatizar setup e hardening de servidores Ubuntu Se
4
4
 
5
5
  **✨ Versão Auditada e Resiliente para Produção**
6
6
 
7
+ ## Links úteis
8
+
9
+ - Repositório: https://github.com/rafaelluisdacostacoelho/raijin-server
10
+ - Documentação completa: [docs/INFRASTRUCTURE_GUIDE.md](docs/INFRASTRUCTURE_GUIDE.md)
11
+ - Arquitetura: [ARCHITECTURE.md](ARCHITECTURE.md)
12
+ - Auditoria: [AUDIT.md](AUDIT.md)
13
+ - Segurança: [SECURITY.md](SECURITY.md)
14
+
7
15
  ## Destaques
8
16
 
9
17
  - ✅ **Validações de Pré-requisitos**: OS, espaço em disco, memória, conectividade, ambiente Python (venv)
@@ -48,6 +56,36 @@ source .venv/bin/activate
48
56
  python -m pip install -e .
49
57
  ```
50
58
 
59
+ ### Instalação em Produção (Recomendado)
60
+
61
+ Para servidores em produção, use um venv isolado e execute com sudo preservando o ambiente:
62
+
63
+ ```bash
64
+ # 1. Sair do venv atual (se estiver ativo)
65
+ deactivate
66
+
67
+ # 2. (Opcional) Remover venv antigo
68
+ rm -rf ~/.venvs/raijin
69
+
70
+ # 3. Criar venv novo
71
+ python3 -m venv ~/.venvs/raijin
72
+ source ~/.venvs/raijin/bin/activate
73
+ pip install -U pip setuptools
74
+
75
+ # 4. Instalar a versão mais recente
76
+ pip install -U raijin-server
77
+
78
+ # 5. Rodar usando root preservando o venv
79
+ sudo -E ~/.venvs/raijin/bin/raijin-server --version
80
+ sudo -E ~/.venvs/raijin/bin/raijin-server validate
81
+ sudo -E ~/.venvs/raijin/bin/raijin-server full-install
82
+
83
+ # 6. Para sair do venv quando terminar
84
+ deactivate
85
+ ```
86
+
87
+ > **Nota**: O `-E` no sudo preserva as variáveis de ambiente, garantindo que o Python use o venv correto mesmo como root.
88
+
51
89
  ## Uso rapido
52
90
 
53
91
  ### Validar Sistema
@@ -342,6 +380,32 @@ pytest
342
380
  ruff check src tests
343
381
  ```
344
382
 
383
+ ## Publicar no PyPI (Twine)
384
+
385
+ 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.
386
+
387
+ Passo a passo:
388
+ ```bash
389
+ # 1) Gere artefatos
390
+ python -m build --sdist --wheel --outdir dist/
391
+
392
+ # 2) Configure o token (crie em https://pypi.org/manage/account/token/)
393
+ export TWINE_USERNAME=__token__
394
+ export TWINE_PASSWORD="<seu-token>"
395
+
396
+ # 3) Envie para o PyPI
397
+ python -m twine upload dist/*
398
+
399
+ # 4) Verifique instalação
400
+ python -m pip install -U raijin-server
401
+ raijin-server --version
402
+ ```
403
+
404
+ Boas práticas:
405
+ - Use venv dedicado para publicar (`python -m venv ~/.venvs/publish && source ~/.venvs/publish/bin/activate`).
406
+ - Nunca commite ou exponha o token; mantenha em variável de ambiente/secret manager.
407
+ - Sempre suba primeiro para TestPyPI se quiser validar (`--repository testpypi`).
408
+
345
409
  ## Acesso remoto seguro (VPN + SSH)
346
410
 
347
411
  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.
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = raijin-server
3
- version = 0.2.3
3
+ version = 0.2.5
4
4
  description = CLI para automacao de setup e hardening de servidores Ubuntu Server.
5
5
  long_description = file: README.md
6
6
  long_description_content_type = text/markdown
@@ -1,5 +1,5 @@
1
1
  """Pacote principal do CLI Raijin Server."""
2
2
 
3
- __version__ = "0.2.3"
3
+ __version__ = "0.2.4"
4
4
 
5
5
  __all__ = ["__version__"]
@@ -470,6 +470,83 @@ def sanitize(ctx: typer.Context) -> None:
470
470
  _run_module(ctx, "sanitize")
471
471
 
472
472
 
473
+ # ============================================================================
474
+ # Subcomandos Cert-Manager
475
+ # ============================================================================
476
+ cert_app = typer.Typer(help="Comandos para gerenciamento do cert-manager")
477
+ app.add_typer(cert_app, name="cert")
478
+
479
+
480
+ @cert_app.command(name="install")
481
+ def cert_install(ctx: typer.Context) -> None:
482
+ """Instala cert-manager e configura ClusterIssuer interativamente."""
483
+ _run_module(ctx, "cert_manager")
484
+
485
+
486
+ @cert_app.command(name="status")
487
+ def cert_status(ctx: typer.Context) -> None:
488
+ """Exibe status detalhado do cert-manager, pods, webhook e certificados."""
489
+ exec_ctx = ctx.obj or ExecutionContext()
490
+ cert_manager.status(exec_ctx)
491
+
492
+
493
+ @cert_app.command(name="diagnose")
494
+ def cert_diagnose(ctx: typer.Context) -> None:
495
+ """Executa diagnóstico completo para troubleshooting do cert-manager."""
496
+ exec_ctx = ctx.obj or ExecutionContext()
497
+ cert_manager.diagnose(exec_ctx)
498
+
499
+
500
+ @cert_app.command(name="list-certs")
501
+ def cert_list(ctx: typer.Context) -> None:
502
+ """Lista todos os certificados no cluster."""
503
+ import subprocess
504
+
505
+ typer.secho("\n📜 Certificados no Cluster", fg=typer.colors.CYAN, bold=True)
506
+ try:
507
+ result = subprocess.run(
508
+ [
509
+ "kubectl", "get", "certificates", "-A",
510
+ "-o", "wide"
511
+ ],
512
+ capture_output=False,
513
+ timeout=15,
514
+ )
515
+ if result.returncode != 0:
516
+ typer.secho("Nenhum certificado encontrado ou erro ao listar.", fg=typer.colors.YELLOW)
517
+ except Exception as e:
518
+ typer.secho(f"Erro: {e}", fg=typer.colors.RED)
519
+
520
+
521
+ @cert_app.command(name="list-issuers")
522
+ def cert_list_issuers(ctx: typer.Context) -> None:
523
+ """Lista todos os ClusterIssuers e Issuers."""
524
+ import subprocess
525
+
526
+ typer.secho("\n🔐 ClusterIssuers", fg=typer.colors.CYAN, bold=True)
527
+ try:
528
+ subprocess.run(
529
+ ["kubectl", "get", "clusterissuers", "-o", "wide"],
530
+ timeout=15,
531
+ )
532
+ except Exception:
533
+ pass
534
+
535
+ typer.secho("\n🔐 Issuers (por namespace)", fg=typer.colors.CYAN, bold=True)
536
+ try:
537
+ subprocess.run(
538
+ ["kubectl", "get", "issuers", "-A", "-o", "wide"],
539
+ timeout=15,
540
+ )
541
+ except Exception:
542
+ pass
543
+
544
+
545
+ # ============================================================================
546
+ # Comandos Existentes
547
+ # ============================================================================
548
+
549
+
473
550
  @app.command(name="bootstrap")
474
551
  def bootstrap_cmd(ctx: typer.Context) -> None:
475
552
  """Instala todas as ferramentas necessarias: helm, kubectl, istioctl, velero, containerd."""
@@ -264,8 +264,67 @@ def verify_helm_chart(release: str, namespace: str, ctx: ExecutionContext) -> bo
264
264
 
265
265
 
266
266
  def verify_cert_manager(ctx: ExecutionContext) -> bool:
267
- """Health check para cert-manager."""
268
- return verify_helm_chart("cert-manager", CERT_NS, ctx)
267
+ """Health check completo para cert-manager."""
268
+ logger.info("Verificando health check: cert-manager")
269
+ typer.secho("\n=== Health Check: Cert-Manager ===", fg=typer.colors.CYAN)
270
+
271
+ all_ok = True
272
+
273
+ # Verifica release Helm
274
+ ok, status = check_helm_release("cert-manager", CERT_NS, ctx)
275
+ if ok:
276
+ typer.secho(f" ✓ Release cert-manager: {status}", fg=typer.colors.GREEN)
277
+ else:
278
+ typer.secho(f" ✗ Release cert-manager: {status}", fg=typer.colors.RED)
279
+ return False
280
+
281
+ # Verifica pods
282
+ if not check_k8s_pods_in_namespace(CERT_NS, ctx, timeout=180):
283
+ all_ok = False
284
+
285
+ # Verifica CRDs
286
+ if not ctx.dry_run:
287
+ try:
288
+ import subprocess
289
+ result = subprocess.run(
290
+ ["kubectl", "get", "crd", "certificates.cert-manager.io"],
291
+ capture_output=True,
292
+ timeout=10,
293
+ )
294
+ if result.returncode == 0:
295
+ typer.secho(" ✓ CRDs instalados", fg=typer.colors.GREEN)
296
+ else:
297
+ typer.secho(" ✗ CRDs não encontrados", fg=typer.colors.RED)
298
+ all_ok = False
299
+ except Exception as e:
300
+ typer.secho(f" ✗ Erro ao verificar CRDs: {e}", fg=typer.colors.RED)
301
+ all_ok = False
302
+
303
+ # Verifica webhook ready
304
+ if not ctx.dry_run:
305
+ try:
306
+ import subprocess
307
+ result = subprocess.run(
308
+ [
309
+ "kubectl", "get", "deployment", "cert-manager-webhook",
310
+ "-n", CERT_NS,
311
+ "-o", "jsonpath={.status.readyReplicas}"
312
+ ],
313
+ capture_output=True,
314
+ text=True,
315
+ timeout=10,
316
+ )
317
+ ready = result.returncode == 0 and result.stdout.strip() and int(result.stdout.strip()) >= 1
318
+ if ready:
319
+ typer.secho(" ✓ Webhook pronto", fg=typer.colors.GREEN)
320
+ else:
321
+ typer.secho(" ✗ Webhook não está pronto", fg=typer.colors.RED)
322
+ all_ok = False
323
+ except Exception as e:
324
+ typer.secho(f" ✗ Erro ao verificar webhook: {e}", fg=typer.colors.RED)
325
+ all_ok = False
326
+
327
+ return all_ok
269
328
 
270
329
 
271
330
  def verify_secrets(ctx: ExecutionContext) -> bool:
@@ -244,7 +244,15 @@ def _resolve_tls_secret() -> str | None:
244
244
  return secret.strip() or None
245
245
 
246
246
 
247
- def _build_manifest(host: str, tls_secret: str | None) -> str:
247
+ def _resolve_ip_access() -> bool:
248
+ """Pergunta se deseja acesso via IP direto (para testes)."""
249
+ env_ip = os.environ.get("APOKOLIPS_IP_ACCESS")
250
+ if env_ip:
251
+ return env_ip.strip().lower() in ("1", "true", "yes")
252
+ return typer.confirm("Habilitar acesso via IP direto? (apenas para testes)", default=True)
253
+
254
+
255
+ def _build_manifest(host: str, tls_secret: str | None, ip_access: bool = False) -> str:
248
256
  html_block = indent(HTML_TEMPLATE.strip("\n"), " " * 4)
249
257
  tls_block = ""
250
258
  if tls_secret:
@@ -254,6 +262,20 @@ def _build_manifest(host: str, tls_secret: str | None) -> str:
254
262
  f" - {host}\n"
255
263
  f" secretName: {tls_secret}\n"
256
264
  )
265
+
266
+ # Regra adicional para acesso via IP (sem host)
267
+ ip_rule = ""
268
+ if ip_access:
269
+ ip_rule = """
270
+ - http:
271
+ paths:
272
+ - path: /
273
+ pathType: Prefix
274
+ backend:
275
+ service:
276
+ name: apokolips-demo
277
+ port:
278
+ number: 80"""
257
279
 
258
280
  template = """\
259
281
  apiVersion: v1
@@ -340,12 +362,13 @@ spec:
340
362
  service:
341
363
  name: apokolips-demo
342
364
  port:
343
- number: 80
365
+ number: 80__IP_RULE__
344
366
  __TLS__
345
367
  """
346
368
 
347
369
  manifest = template.format(namespace=NAMESPACE, host=host)
348
370
  manifest = manifest.replace("__HTML__", html_block)
371
+ manifest = manifest.replace("__IP_RULE__", ip_rule)
349
372
  manifest = manifest.replace("__TLS__", tls_block.rstrip())
350
373
  return f"{manifest.strip()}\n"
351
374
 
@@ -354,7 +377,8 @@ def run(ctx: ExecutionContext) -> None:
354
377
  ensure_tool("kubectl", ctx, install_hint="Instale kubectl para aplicar o manifesto do site.")
355
378
  host = _resolve_host()
356
379
  tls_secret = _resolve_tls_secret()
357
- manifest = _build_manifest(host, tls_secret)
380
+ ip_access = _resolve_ip_access()
381
+ manifest = _build_manifest(host, tls_secret, ip_access)
358
382
 
359
383
  typer.echo("Gerando manifesto Apokolips...")
360
384
  write_file(TMP_MANIFEST, manifest, ctx)
@@ -369,10 +393,22 @@ def run(ctx: ExecutionContext) -> None:
369
393
  typer.echo(f" • Host: {host}")
370
394
  if tls_secret:
371
395
  typer.echo(f" • Secret TLS: {tls_secret}")
396
+ if ip_access:
397
+ typer.secho(" • Acesso via IP: HABILITADO (apenas para testes)", fg=typer.colors.YELLOW)
398
+
372
399
  typer.echo("\nTestes sugeridos:")
373
- typer.echo(f" curl -H 'Host: {host}' https://<IP_DO_LOAD_BALANCER>/ --insecure")
400
+ if ip_access:
401
+ typer.echo(" # Acesso direto via IP (teste):")
402
+ typer.echo(" curl http://<IP_DO_SERVIDOR>/")
403
+ typer.echo("")
404
+ typer.echo(f" # Acesso via DNS (produção):")
405
+ typer.echo(f" curl -H 'Host: {host}' http://<IP_DO_LOAD_BALANCER>/")
374
406
  typer.echo(f" kubectl -n {NAMESPACE} get ingress {NAMESPACE}")
375
407
  typer.echo(f" kubectl -n {NAMESPACE} get pods")
376
408
 
409
+ if ip_access:
410
+ typer.secho("\n⚠️ Lembre-se de desabilitar o acesso via IP após configurar o DNS!", fg=typer.colors.YELLOW)
411
+ typer.echo(" Rode novamente com APOKOLIPS_IP_ACCESS=false ou responda 'não' na pergunta.")
412
+
377
413
  typer.echo("\nPara remover:")
378
414
  typer.echo(f" kubectl delete namespace {NAMESPACE}")