raijin-server 0.2.5__py3-none-any.whl → 0.2.6__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.
@@ -432,39 +432,347 @@ def _wait_for_webhook_ready(ctx: ExecutionContext, timeout: int = WEBHOOK_READY_
432
432
  # Instalação e Configuração
433
433
  # =============================================================================
434
434
 
435
- def _install_cert_manager_helm(ctx: ExecutionContext) -> bool:
436
- """Instala cert-manager via Helm."""
437
- typer.secho("\n📦 Instalando cert-manager via Helm...", fg=typer.colors.CYAN, bold=True)
435
+ def _test_helm_repo_connectivity(ctx: ExecutionContext) -> bool:
436
+ """Testa conectividade com o repositório Helm antes de instalar."""
437
+ if ctx.dry_run:
438
+ return True
439
+
440
+ logger.info("Testando conectividade com charts.jetstack.io")
441
+ typer.echo(" [1/5] Testando conectividade com charts.jetstack.io...")
438
442
 
439
443
  try:
440
- # O helm_upgrade_install agora limpa releases pendentes automaticamente
441
- helm_upgrade_install(
442
- release="cert-manager",
443
- chart=CHART_NAME,
444
- namespace=NAMESPACE,
445
- ctx=ctx,
446
- repo="jetstack",
447
- repo_url=CHART_REPO,
448
- create_namespace=True,
449
- extra_args=[
450
- "--set", "installCRDs=true",
451
- "--set", "webhook.timeoutSeconds=30",
452
- "--set", "startupapicheck.timeout=5m",
453
- "--set", "startupapicheck.enabled=true",
454
- # Aumenta recursos para ambientes mais lentos
455
- "--set", "webhook.replicaCount=1",
456
- "--set", "cainjector.replicaCount=1",
457
- "--wait", # Espera o Helm considerar o release deployed
458
- "--timeout", "10m",
459
- ],
444
+ start = time.time()
445
+ result = subprocess.run(
446
+ ["curl", "-sI", "--connect-timeout", "15", f"{CHART_REPO}/index.yaml"],
447
+ capture_output=True,
448
+ text=True,
449
+ timeout=20,
460
450
  )
451
+ elapsed = time.time() - start
452
+
453
+ if result.returncode == 0 and "200" in result.stdout:
454
+ logger.info(f"Repositório Helm acessível em {elapsed:.2f}s")
455
+ typer.secho(f" ✓ Repositório Helm acessível ({elapsed:.2f}s)", fg=typer.colors.GREEN)
456
+ return True
457
+ else:
458
+ logger.error(f"Repositório retornou erro: {result.stdout[:200]}")
459
+ typer.secho(f" ✗ Repositório retornou erro: {result.stdout[:100]}", fg=typer.colors.RED)
460
+ return False
461
+ except subprocess.TimeoutExpired:
462
+ logger.error("Timeout ao conectar com charts.jetstack.io")
463
+ typer.secho(" ✗ Timeout ao conectar com charts.jetstack.io (>15s)", fg=typer.colors.RED)
464
+ return False
465
+ except Exception as e:
466
+ logger.error(f"Erro de conectividade: {e}")
467
+ typer.secho(f" ✗ Erro de conectividade: {e}", fg=typer.colors.RED)
468
+ return False
469
+
470
+
471
+ def _test_image_registry_connectivity(ctx: ExecutionContext) -> bool:
472
+ """Testa conectividade com o registry de imagens."""
473
+ if ctx.dry_run:
461
474
  return True
475
+
476
+ logger.info("Testando conectividade com quay.io (registry de imagens)")
477
+ typer.echo(" [2/5] Testando conectividade com quay.io (registry de imagens)...")
478
+
479
+ try:
480
+ start = time.time()
481
+ result = subprocess.run(
482
+ ["curl", "-sI", "--connect-timeout", "15", "https://quay.io/v2/"],
483
+ capture_output=True,
484
+ text=True,
485
+ timeout=20,
486
+ )
487
+ elapsed = time.time() - start
488
+
489
+ # quay.io retorna 401 para /v2/ sem auth, mas isso significa que está acessível
490
+ if result.returncode == 0 and ("200" in result.stdout or "401" in result.stdout):
491
+ logger.info(f"Registry quay.io acessível em {elapsed:.2f}s")
492
+ typer.secho(f" ✓ Registry quay.io acessível ({elapsed:.2f}s)", fg=typer.colors.GREEN)
493
+ return True
494
+ else:
495
+ logger.warning(f"Registry pode estar inacessível: {result.stdout[:100]}")
496
+ typer.secho(f" ⚠ Registry pode estar inacessível", fg=typer.colors.YELLOW)
497
+ return True # Não bloqueia, apenas avisa
462
498
  except Exception as e:
463
- typer.secho(f" Erro na instalação do Helm: {e}", fg=typer.colors.RED)
464
- ctx.errors.append(f"cert-manager: falha na instalação Helm - {e}")
499
+ logger.warning(f"Não foi possível testar registry: {e}")
500
+ typer.secho(f" Não foi possível testar registry: {e}", fg=typer.colors.YELLOW)
501
+ return True # Não bloqueia
502
+
503
+
504
+ def _add_helm_repo(ctx: ExecutionContext) -> bool:
505
+ """Adiciona e atualiza o repositório Helm."""
506
+ if ctx.dry_run:
507
+ typer.echo(" [3/5] [dry-run] Adicionando repositório Helm jetstack...")
508
+ return True
509
+
510
+ logger.info("Adicionando repositório Helm jetstack")
511
+ typer.echo(" [3/5] Adicionando repositório Helm jetstack...")
512
+
513
+ try:
514
+ start = time.time()
515
+
516
+ # Adiciona repo
517
+ result = subprocess.run(
518
+ ["helm", "repo", "add", "jetstack", CHART_REPO, "--force-update"],
519
+ capture_output=True,
520
+ text=True,
521
+ timeout=60,
522
+ )
523
+
524
+ if result.returncode != 0:
525
+ logger.error(f"Falha ao adicionar repo: {result.stderr}")
526
+ typer.secho(f" ✗ Falha ao adicionar repo: {result.stderr[:100]}", fg=typer.colors.RED)
527
+ return False
528
+
529
+ elapsed_add = time.time() - start
530
+ logger.info(f"Repo adicionado em {elapsed_add:.2f}s")
531
+ typer.echo(f" Repo adicionado ({elapsed_add:.2f}s)")
532
+
533
+ # Atualiza repo
534
+ typer.echo(" Atualizando índice do repositório...")
535
+ start = time.time()
536
+
537
+ result = subprocess.run(
538
+ ["helm", "repo", "update", "jetstack"],
539
+ capture_output=True,
540
+ text=True,
541
+ timeout=120,
542
+ )
543
+
544
+ elapsed_update = time.time() - start
545
+
546
+ if result.returncode != 0:
547
+ logger.error(f"Falha ao atualizar repo: {result.stderr}")
548
+ typer.secho(f" ✗ Falha ao atualizar repo: {result.stderr[:100]}", fg=typer.colors.RED)
549
+ return False
550
+
551
+ logger.info(f"Repo atualizado em {elapsed_update:.2f}s")
552
+ typer.secho(f" ✓ Repositório configurado ({elapsed_add + elapsed_update:.2f}s total)", fg=typer.colors.GREEN)
553
+ return True
554
+
555
+ except subprocess.TimeoutExpired:
556
+ logger.error("Timeout ao configurar repositório Helm")
557
+ typer.secho(" ✗ Timeout ao configurar repositório (>60s)", fg=typer.colors.RED)
558
+ return False
559
+ except Exception as e:
560
+ logger.error(f"Erro ao configurar repo: {e}")
561
+ typer.secho(f" ✗ Erro: {e}", fg=typer.colors.RED)
465
562
  return False
466
563
 
467
564
 
565
+ def _run_helm_install(ctx: ExecutionContext) -> bool:
566
+ """Executa o helm upgrade --install."""
567
+ if ctx.dry_run:
568
+ typer.echo(" [4/5] [dry-run] Executando helm upgrade --install...")
569
+ return True
570
+
571
+ logger.info("Executando helm upgrade --install cert-manager")
572
+ typer.echo(" [4/5] Executando helm upgrade --install cert-manager...")
573
+ typer.echo(" (isso pode levar vários minutos)")
574
+
575
+ cmd = [
576
+ "helm", "upgrade", "--install", "cert-manager", "jetstack/cert-manager",
577
+ "-n", NAMESPACE,
578
+ "--create-namespace",
579
+ "--set", "installCRDs=true",
580
+ "--set", "webhook.timeoutSeconds=30",
581
+ "--set", "startupapicheck.timeout=5m",
582
+ "--set", "startupapicheck.enabled=true",
583
+ "--set", "webhook.replicaCount=1",
584
+ "--set", "cainjector.replicaCount=1",
585
+ "--wait",
586
+ "--timeout", "15m",
587
+ "--debug", # Mais logs
588
+ ]
589
+
590
+ logger.info(f"Comando: {' '.join(cmd)}")
591
+
592
+ try:
593
+ start = time.time()
594
+
595
+ # Executa com output em tempo real para ver progresso
596
+ process = subprocess.Popen(
597
+ cmd,
598
+ stdout=subprocess.PIPE,
599
+ stderr=subprocess.STDOUT,
600
+ text=True,
601
+ )
602
+
603
+ output_lines = []
604
+ last_log_time = time.time()
605
+
606
+ while True:
607
+ line = process.stdout.readline()
608
+ if not line and process.poll() is not None:
609
+ break
610
+ if line:
611
+ output_lines.append(line)
612
+ logger.debug(line.strip())
613
+
614
+ # Mostra progresso a cada 30s
615
+ if time.time() - last_log_time > 30:
616
+ elapsed = int(time.time() - start)
617
+ typer.echo(f" ... ainda instalando ({elapsed}s)")
618
+ last_log_time = time.time()
619
+
620
+ elapsed = time.time() - start
621
+ return_code = process.poll()
622
+
623
+ if return_code == 0:
624
+ logger.info(f"Helm install concluído em {elapsed:.2f}s")
625
+ typer.secho(f" ✓ Helm install concluído ({elapsed:.2f}s)", fg=typer.colors.GREEN)
626
+ return True
627
+ else:
628
+ output = "".join(output_lines[-20:]) # Últimas 20 linhas
629
+ logger.error(f"Helm install falhou (código {return_code}): {output}")
630
+ typer.secho(f" ✗ Helm install falhou (código {return_code})", fg=typer.colors.RED)
631
+
632
+ # Mostra as últimas linhas do erro
633
+ typer.echo("\n Últimas linhas do log:")
634
+ for line in output_lines[-10:]:
635
+ typer.echo(f" {line.strip()}")
636
+
637
+ return False
638
+
639
+ except Exception as e:
640
+ logger.error(f"Erro durante helm install: {e}")
641
+ typer.secho(f" ✗ Erro: {e}", fg=typer.colors.RED)
642
+ return False
643
+
644
+
645
+ def _verify_installation(ctx: ExecutionContext) -> bool:
646
+ """Verifica se os pods estão rodando."""
647
+ if ctx.dry_run:
648
+ typer.echo(" [5/5] [dry-run] Verificando instalação...")
649
+ return True
650
+
651
+ logger.info("Verificando pods do cert-manager")
652
+ typer.echo(" [5/5] Verificando pods do cert-manager...")
653
+
654
+ try:
655
+ result = subprocess.run(
656
+ ["kubectl", "get", "pods", "-n", NAMESPACE, "-o", "wide"],
657
+ capture_output=True,
658
+ text=True,
659
+ timeout=30,
660
+ )
661
+
662
+ if result.returncode == 0:
663
+ typer.echo(f"\n{result.stdout}")
664
+
665
+ # Verifica se todos estão Running
666
+ if "Running" in result.stdout and "0/1" not in result.stdout:
667
+ logger.info("Todos os pods estão Running")
668
+ typer.secho(" ✓ Todos os pods estão Running", fg=typer.colors.GREEN)
669
+ return True
670
+ else:
671
+ logger.warning("Alguns pods podem não estar prontos")
672
+ typer.secho(" ⚠ Alguns pods podem não estar prontos", fg=typer.colors.YELLOW)
673
+ return True # Não falha, o wait_for_webhook vai verificar
674
+ else:
675
+ logger.error(f"Erro ao verificar pods: {result.stderr}")
676
+ return False
677
+
678
+ except Exception as e:
679
+ logger.error(f"Erro ao verificar pods: {e}")
680
+ return False
681
+
682
+
683
+ def _install_cert_manager_helm(ctx: ExecutionContext) -> bool:
684
+ """Instala cert-manager via Helm com logs detalhados."""
685
+ typer.secho("\n📦 Instalando cert-manager via Helm...", fg=typer.colors.CYAN, bold=True)
686
+ logger.info("Iniciando instalação do cert-manager")
687
+
688
+ start_total = time.time()
689
+
690
+ # Etapa 1: Testa conectividade com repo Helm
691
+ if not _test_helm_repo_connectivity(ctx):
692
+ typer.secho(
693
+ "\n⚠ Problema de conectividade com o repositório Helm.",
694
+ fg=typer.colors.YELLOW,
695
+ )
696
+ typer.echo(" Teste manual: curl -sI https://charts.jetstack.io/index.yaml")
697
+ if not typer.confirm("Tentar instalar mesmo assim?", default=False):
698
+ return False
699
+
700
+ # Etapa 2: Testa conectividade com registry de imagens
701
+ _test_image_registry_connectivity(ctx)
702
+
703
+ # Etapa 3: Adiciona e atualiza repo Helm
704
+ if not _add_helm_repo(ctx):
705
+ return False
706
+
707
+ # Etapa 4: Executa helm install
708
+ if not _run_helm_install(ctx):
709
+ _show_diagnostic_info(ctx)
710
+ return False
711
+
712
+ # Etapa 5: Verifica instalação
713
+ _verify_installation(ctx)
714
+
715
+ elapsed_total = time.time() - start_total
716
+ logger.info(f"Instalação do cert-manager concluída em {elapsed_total:.2f}s")
717
+ typer.secho(f"\n✓ Instalação concluída em {elapsed_total:.2f}s", fg=typer.colors.GREEN)
718
+
719
+ return True
720
+
721
+
722
+ def _show_diagnostic_info(ctx: ExecutionContext) -> None:
723
+ """Mostra informações de diagnóstico quando falha."""
724
+ if ctx.dry_run:
725
+ return
726
+
727
+ typer.secho("\n🔍 Informações de diagnóstico:", fg=typer.colors.YELLOW, bold=True)
728
+
729
+ # Pods
730
+ typer.echo("\n Pods:")
731
+ try:
732
+ result = subprocess.run(
733
+ ["kubectl", "get", "pods", "-n", NAMESPACE, "-o", "wide"],
734
+ capture_output=True,
735
+ text=True,
736
+ timeout=15,
737
+ )
738
+ if result.stdout:
739
+ for line in result.stdout.strip().split("\n"):
740
+ typer.echo(f" {line}")
741
+ except Exception:
742
+ typer.echo(" (não foi possível obter pods)")
743
+
744
+ # Eventos recentes
745
+ typer.echo("\n Eventos recentes:")
746
+ try:
747
+ result = subprocess.run(
748
+ ["kubectl", "get", "events", "-n", NAMESPACE, "--sort-by=.lastTimestamp"],
749
+ capture_output=True,
750
+ text=True,
751
+ timeout=15,
752
+ )
753
+ if result.stdout:
754
+ lines = result.stdout.strip().split("\n")
755
+ for line in lines[-10:]: # Últimos 10 eventos
756
+ typer.echo(f" {line[:120]}")
757
+ except Exception:
758
+ typer.echo(" (não foi possível obter eventos)")
759
+
760
+ # Helm status
761
+ typer.echo("\n Helm release status:")
762
+ try:
763
+ result = subprocess.run(
764
+ ["helm", "status", "cert-manager", "-n", NAMESPACE],
765
+ capture_output=True,
766
+ text=True,
767
+ timeout=15,
768
+ )
769
+ if result.stdout:
770
+ for line in result.stdout.strip().split("\n")[:15]:
771
+ typer.echo(f" {line}")
772
+ except Exception:
773
+ typer.echo(" (não foi possível obter status do Helm)")
774
+
775
+
468
776
  def _apply_manifest_with_retry(
469
777
  manifest: str,
470
778
  ctx: ExecutionContext,
File without changes
File without changes
File without changes
raijin_server/utils.py CHANGED
@@ -317,6 +317,125 @@ def _get_helm_release_status(release: str, namespace: str) -> str:
317
317
  return ""
318
318
 
319
319
 
320
+ def _get_helm_release_history(release: str, namespace: str) -> list:
321
+ """Retorna histórico do release Helm."""
322
+ try:
323
+ import json
324
+ result = subprocess.run(
325
+ ["helm", "history", release, "-n", namespace, "-o", "json"],
326
+ capture_output=True,
327
+ text=True,
328
+ timeout=30,
329
+ )
330
+ if result.returncode != 0 or not result.stdout:
331
+ return []
332
+ return json.loads(result.stdout)
333
+ except Exception:
334
+ return []
335
+
336
+
337
+ def _diagnose_helm_release(release: str, namespace: str) -> None:
338
+ """Mostra diagnóstico detalhado de um release Helm."""
339
+ typer.secho(f"\n🔍 Diagnóstico do release '{release}':", fg=typer.colors.YELLOW)
340
+
341
+ # Status atual
342
+ status = _get_helm_release_status(release, namespace)
343
+ typer.echo(f" Status atual: {status or '(não encontrado)'}")
344
+
345
+ # Histórico
346
+ history = _get_helm_release_history(release, namespace)
347
+ if history:
348
+ typer.echo(f" Histórico ({len(history)} revisões):")
349
+ for rev in history[-5:]: # Últimas 5 revisões
350
+ typer.echo(f" Rev {rev.get('revision')}: {rev.get('status')} - {rev.get('description', '')[:50]}")
351
+
352
+ # Secrets do Helm (onde guarda estado)
353
+ try:
354
+ result = subprocess.run(
355
+ ["kubectl", "get", "secrets", "-n", namespace, "-l", f"name={release},owner=helm", "-o", "name"],
356
+ capture_output=True,
357
+ text=True,
358
+ timeout=15,
359
+ )
360
+ if result.stdout.strip():
361
+ secrets = result.stdout.strip().split("\n")
362
+ typer.echo(f" Secrets do Helm: {len(secrets)}")
363
+ for s in secrets[-5:]:
364
+ typer.echo(f" {s}")
365
+ except Exception:
366
+ pass
367
+
368
+ # Pods relacionados
369
+ try:
370
+ result = subprocess.run(
371
+ ["kubectl", "get", "pods", "-n", namespace, "-o", "wide", "--no-headers"],
372
+ capture_output=True,
373
+ text=True,
374
+ timeout=15,
375
+ )
376
+ if result.stdout.strip():
377
+ typer.echo(" Pods:")
378
+ for line in result.stdout.strip().split("\n")[:5]:
379
+ typer.echo(f" {line}")
380
+ except Exception:
381
+ pass
382
+
383
+
384
+ def _force_cleanup_helm_release(release: str, namespace: str) -> bool:
385
+ """Limpeza forçada de release Helm travado - remove secrets diretamente."""
386
+ typer.secho(f" Limpeza forçada do release '{release}'...", fg=typer.colors.YELLOW)
387
+ logger.warning(f"Executando limpeza forçada do release {release} em {namespace}")
388
+
389
+ try:
390
+ # 1. Primeiro tenta uninstall normal com --no-hooks (pula hooks que podem estar travando)
391
+ result = subprocess.run(
392
+ ["helm", "uninstall", release, "-n", namespace, "--no-hooks", "--wait", "--timeout", "2m"],
393
+ capture_output=True,
394
+ text=True,
395
+ timeout=150,
396
+ )
397
+
398
+ if result.returncode == 0:
399
+ typer.secho(f" ✓ Release removido via helm uninstall", fg=typer.colors.GREEN)
400
+ time.sleep(3)
401
+ return True
402
+
403
+ # 2. Se falhou, remove os secrets do Helm diretamente
404
+ typer.echo(" Helm uninstall falhou, removendo secrets diretamente...")
405
+ logger.warning("Removendo secrets do Helm diretamente")
406
+
407
+ # Lista secrets do Helm para este release
408
+ result = subprocess.run(
409
+ ["kubectl", "get", "secrets", "-n", namespace, "-l", f"name={release},owner=helm", "-o", "name"],
410
+ capture_output=True,
411
+ text=True,
412
+ timeout=15,
413
+ )
414
+
415
+ if result.stdout.strip():
416
+ secrets = result.stdout.strip().split("\n")
417
+ for secret in secrets:
418
+ secret_name = secret.replace("secret/", "")
419
+ subprocess.run(
420
+ ["kubectl", "delete", "secret", secret_name, "-n", namespace],
421
+ capture_output=True,
422
+ timeout=30,
423
+ )
424
+ typer.echo(f" Removido: {secret_name}")
425
+
426
+ time.sleep(3)
427
+ typer.secho(f" ✓ Secrets do Helm removidos", fg=typer.colors.GREEN)
428
+ return True
429
+ else:
430
+ typer.echo(" Nenhum secret do Helm encontrado")
431
+ return True
432
+
433
+ except Exception as e:
434
+ logger.error(f"Erro na limpeza forçada: {e}")
435
+ typer.secho(f" ✗ Erro na limpeza: {e}", fg=typer.colors.RED)
436
+ return False
437
+
438
+
320
439
  def _cleanup_pending_helm_release(release: str, namespace: str, ctx: ExecutionContext) -> None:
321
440
  """Remove release Helm em estado pendente que bloqueia novas operacoes."""
322
441
  if ctx.dry_run:
@@ -327,32 +446,61 @@ def _cleanup_pending_helm_release(release: str, namespace: str, ctx: ExecutionCo
327
446
  return
328
447
 
329
448
  # 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(
449
+ if not status.startswith("pending"):
450
+ return
451
+
452
+ typer.secho(
453
+ f"\n⚠ Release '{release}' em estado '{status}' - bloqueando novas operações",
454
+ fg=typer.colors.YELLOW,
455
+ )
456
+
457
+ # Mostra diagnóstico
458
+ _diagnose_helm_release(release, namespace)
459
+
460
+ typer.echo("\n Tentando recuperar...")
461
+
462
+ # 1. Tenta rollback primeiro (funciona para pending-upgrade)
463
+ if status == "pending-upgrade":
464
+ typer.echo(" Tentando rollback para versão anterior...")
465
+ result = subprocess.run(
337
466
  ["helm", "rollback", release, "-n", namespace, "--wait", "--timeout", "2m"],
338
467
  capture_output=True,
468
+ text=True,
339
469
  timeout=150,
340
470
  )
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)
471
+
472
+ if result.returncode == 0:
473
+ new_status = _get_helm_release_status(release, namespace)
474
+ if not new_status.startswith("pending"):
475
+ typer.secho(f" ✓ Rollback bem-sucedido (status: {new_status})", fg=typer.colors.GREEN)
476
+ return
477
+
478
+ typer.echo(" Rollback não resolveu...")
479
+
480
+ # 2. Tenta uninstall normal
481
+ typer.echo(" Tentando helm uninstall...")
482
+ result = subprocess.run(
483
+ ["helm", "uninstall", release, "-n", namespace, "--wait", "--timeout", "3m"],
484
+ capture_output=True,
485
+ text=True,
486
+ timeout=200,
487
+ )
488
+
489
+ if result.returncode == 0:
490
+ typer.secho(f" ✓ Release removido com sucesso", fg=typer.colors.GREEN)
491
+ time.sleep(3)
492
+ return
493
+
494
+ # 3. Se ainda falhou, força limpeza
495
+ typer.echo(" Uninstall normal falhou, tentando limpeza forçada...")
496
+ _force_cleanup_helm_release(release, namespace)
497
+
498
+ # Verifica resultado final
499
+ final_status = _get_helm_release_status(release, namespace)
500
+ if final_status:
501
+ typer.secho(f" ⚠ Release ainda existe com status: {final_status}", fg=typer.colors.YELLOW)
502
+ else:
503
+ typer.secho(f" ✓ Release '{release}' limpo com sucesso", fg=typer.colors.GREEN)
356
504
 
357
505
 
358
506
  def helm_upgrade_install(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: raijin-server
3
- Version: 0.2.5
3
+ Version: 0.2.6
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
@@ -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=MNIevCttKq5fVS-I4ZwlY7f7JZtEiwwY_kj69WV4AsQ,14330
5
+ raijin_server/utils.py,sha256=Gs182mcLVM3ClCADFIK9Qi1fQA7BfunaTu0ie-8pAvo,19692
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=dse7AIUVOM2h7d2i3DWsvHLsA9NtcazebTPgOEUWB-8,34473
11
+ raijin_server/modules/cert_manager.py,sha256=Kb8N60j3BDjkNS8t8aTsdsKy5syRWobccP3PBpv-Q8E,45887
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.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,,
39
+ raijin_server-0.2.6.dist-info/licenses/LICENSE,sha256=kJsMCjOiRZE0AQNtxWqBa32z9kMAaF4EUxyHj3hKaJo,1105
40
+ raijin_server-0.2.6.dist-info/METADATA,sha256=KXv3RV6GSO2qQJ85n_SFJP6h10rbph0WbTJ611fG-M4,18925
41
+ raijin_server-0.2.6.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
42
+ raijin_server-0.2.6.dist-info/entry_points.txt,sha256=3ZvxDX4pvcjkIRsXAJ69wIfVmKa78LKo-C3QhqN2KVM,56
43
+ raijin_server-0.2.6.dist-info/top_level.txt,sha256=Yz1xneCRtsZOzbPIcTAcrSxd-1p80pohMXYAZ74dpok,14
44
+ raijin_server-0.2.6.dist-info/RECORD,,