raijin-server 0.2.36__py3-none-any.whl → 0.2.38__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.

Potentially problematic release.


This version of raijin-server might be problematic. Click here for more details.

raijin_server/__init__.py CHANGED
@@ -1,5 +1,5 @@
1
1
  """Pacote principal do CLI Raijin Server."""
2
2
 
3
- __version__ = "0.2.36"
3
+ __version__ = "0.2.38"
4
4
 
5
5
  __all__ = ["__version__"]
@@ -8,6 +8,11 @@ import typer
8
8
 
9
9
  from raijin_server.utils import ExecutionContext, helm_upgrade_install, require_root, run_cmd
10
10
 
11
+ LOCAL_PATH_PROVISIONER_URL = (
12
+ "https://raw.githubusercontent.com/rancher/local-path-provisioner/"
13
+ "v0.0.30/deploy/local-path-storage.yaml"
14
+ )
15
+
11
16
 
12
17
  def _detect_node_name(ctx: ExecutionContext) -> str:
13
18
  """Detecta nome do node para nodeSelector."""
@@ -26,6 +31,137 @@ def _generate_secret(length: int = 32) -> str:
26
31
  return secrets.token_urlsafe(length)[:length]
27
32
 
28
33
 
34
+ def _get_default_storage_class(ctx: ExecutionContext) -> str:
35
+ """Retorna o nome da StorageClass default do cluster, se existir."""
36
+ result = run_cmd(
37
+ [
38
+ "kubectl", "get", "storageclass",
39
+ "-o", "jsonpath={.items[?(@.metadata.annotations.storageclass\\.kubernetes\\.io/is-default-class=='true')].metadata.name}",
40
+ ],
41
+ ctx,
42
+ check=False,
43
+ )
44
+ if result.returncode == 0 and (result.stdout or "").strip():
45
+ return (result.stdout or "").strip()
46
+ return ""
47
+
48
+
49
+ def _list_storage_classes(ctx: ExecutionContext) -> list:
50
+ """Lista todas as StorageClasses disponiveis."""
51
+ result = run_cmd(
52
+ ["kubectl", "get", "storageclass", "-o", "jsonpath={.items[*].metadata.name}"],
53
+ ctx,
54
+ check=False,
55
+ )
56
+ if result.returncode == 0 and (result.stdout or "").strip():
57
+ return (result.stdout or "").strip().split()
58
+ return []
59
+
60
+
61
+ def _install_local_path_provisioner(ctx: ExecutionContext) -> bool:
62
+ """Instala local-path-provisioner para usar storage local (NVMe/SSD)."""
63
+ typer.echo("Instalando local-path-provisioner para storage local...")
64
+
65
+ result = run_cmd(
66
+ ["kubectl", "apply", "-f", LOCAL_PATH_PROVISIONER_URL],
67
+ ctx,
68
+ check=False,
69
+ )
70
+ if result.returncode != 0:
71
+ typer.secho(" Falha ao instalar local-path-provisioner.", fg=typer.colors.RED)
72
+ return False
73
+
74
+ # Aguarda deployment ficar pronto
75
+ typer.echo(" Aguardando local-path-provisioner ficar Ready...")
76
+ run_cmd(
77
+ [
78
+ "kubectl", "-n", "local-path-storage", "rollout", "status",
79
+ "deployment/local-path-provisioner", "--timeout=60s",
80
+ ],
81
+ ctx,
82
+ check=False,
83
+ )
84
+
85
+ typer.secho(" ✓ local-path-provisioner instalado.", fg=typer.colors.GREEN)
86
+ return True
87
+
88
+
89
+ def _set_default_storage_class(ctx: ExecutionContext, name: str) -> None:
90
+ """Define uma StorageClass como default."""
91
+ # Remove default de outras classes primeiro
92
+ existing = _list_storage_classes(ctx)
93
+ for sc in existing:
94
+ if sc != name:
95
+ run_cmd(
96
+ [
97
+ "kubectl", "annotate", "storageclass", sc,
98
+ "storageclass.kubernetes.io/is-default-class-",
99
+ "--overwrite",
100
+ ],
101
+ ctx,
102
+ check=False,
103
+ )
104
+
105
+ # Define a nova como default
106
+ run_cmd(
107
+ [
108
+ "kubectl", "annotate", "storageclass", name,
109
+ "storageclass.kubernetes.io/is-default-class=true",
110
+ "--overwrite",
111
+ ],
112
+ ctx,
113
+ check=True,
114
+ )
115
+ typer.secho(f" ✓ StorageClass '{name}' definida como default.", fg=typer.colors.GREEN)
116
+
117
+
118
+ def _ensure_storage_class(ctx: ExecutionContext) -> str:
119
+ """Garante que existe uma StorageClass disponivel, instalando local-path se necessario."""
120
+ # Verifica se ja tem default
121
+ default_sc = _get_default_storage_class(ctx)
122
+ if default_sc:
123
+ typer.echo(f"StorageClass default detectada: {default_sc}")
124
+ return default_sc
125
+
126
+ # Lista classes disponiveis
127
+ available = _list_storage_classes(ctx)
128
+ if available:
129
+ typer.echo(f"StorageClasses disponiveis (sem default): {', '.join(available)}")
130
+ # Se local-path existe, define como default
131
+ if "local-path" in available:
132
+ _set_default_storage_class(ctx, "local-path")
133
+ return "local-path"
134
+ # Pergunta qual usar
135
+ choice = typer.prompt(
136
+ f"Qual StorageClass usar? ({'/'.join(available)})",
137
+ default=available[0],
138
+ )
139
+ return choice
140
+
141
+ # Sem StorageClass - instala local-path-provisioner
142
+ typer.secho(
143
+ "Nenhuma StorageClass encontrada no cluster.",
144
+ fg=typer.colors.YELLOW,
145
+ )
146
+ install = typer.confirm(
147
+ "Instalar local-path-provisioner para usar armazenamento local (NVMe/SSD)?",
148
+ default=True,
149
+ )
150
+ if not install:
151
+ typer.secho(
152
+ "Abortando: MinIO requer uma StorageClass para PVCs.",
153
+ fg=typer.colors.RED,
154
+ )
155
+ raise typer.Exit(1)
156
+
157
+ if not _install_local_path_provisioner(ctx):
158
+ raise typer.Exit(1)
159
+
160
+ # Define como default
161
+ _set_default_storage_class(ctx, "local-path")
162
+ return "local-path"
163
+
164
+
29
165
  def _check_existing_minio(ctx: ExecutionContext) -> bool:
30
166
  """Verifica se existe instalacao do MinIO."""
31
167
  result = run_cmd(
@@ -119,6 +255,9 @@ def run(ctx: ExecutionContext) -> None:
119
255
  if cleanup:
120
256
  _uninstall_minio(ctx)
121
257
 
258
+ # Garante que existe StorageClass (instala local-path-provisioner se necessario)
259
+ storage_class = _ensure_storage_class(ctx)
260
+
122
261
  # Configuracoes interativas
123
262
  mode = typer.prompt(
124
263
  "Modo de operacao (standalone/distributed)",
@@ -165,6 +304,15 @@ def run(ctx: ExecutionContext) -> None:
165
304
  typer.secho(f" Password gerado: {root_password}", fg=typer.colors.CYAN)
166
305
 
167
306
  persistence_size = typer.prompt("Tamanho do storage (ex: 10Gi, 50Gi)", default="10Gi")
307
+
308
+ # Permite override da StorageClass detectada
309
+ storage_class_override = typer.prompt(
310
+ f"StorageClass para os PVCs (detectada: {storage_class})",
311
+ default=storage_class,
312
+ ).strip()
313
+ if storage_class_override:
314
+ storage_class = storage_class_override
315
+
168
316
  enable_console = typer.confirm("Habilitar Console Web?", default=True)
169
317
 
170
318
  node_name = _detect_node_name(ctx)
@@ -176,6 +324,7 @@ def run(ctx: ExecutionContext) -> None:
176
324
  # Persistence
177
325
  "persistence.enabled=true",
178
326
  f"persistence.size={persistence_size}",
327
+ f"persistence.storageClass={storage_class}",
179
328
  # Resources
180
329
  f"resources.requests.memory={resources_req_mem}",
181
330
  f"resources.requests.cpu={resources_req_cpu}",
@@ -190,6 +339,14 @@ def run(ctx: ExecutionContext) -> None:
190
339
  "tolerations[1].effect=NoSchedule",
191
340
  # NodeSelector
192
341
  f"nodeSelector.kubernetes\\.io/hostname={node_name}",
342
+ # Post-job (fixtures/config) para honrar tolerations/nodeSelector e nao travar em taint
343
+ "postJob.tolerations[0].key=node-role.kubernetes.io/control-plane",
344
+ "postJob.tolerations[0].operator=Exists",
345
+ "postJob.tolerations[0].effect=NoSchedule",
346
+ "postJob.tolerations[1].key=node-role.kubernetes.io/master",
347
+ "postJob.tolerations[1].operator=Exists",
348
+ "postJob.tolerations[1].effect=NoSchedule",
349
+ f"postJob.nodeSelector.kubernetes\\.io/hostname={node_name}",
193
350
  ]
194
351
 
195
352
  if is_distributed:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: raijin-server
3
- Version: 0.2.36
3
+ Version: 0.2.38
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
@@ -1,4 +1,4 @@
1
- raijin_server/__init__.py,sha256=IgQeuxBgUcwnDqgEg_rS_3yr1tMra-K9Hnp686HgkXM,95
1
+ raijin_server/__init__.py,sha256=4mORVRvOEyarK3iUTZjD7Ez47EzyOjaWwkvvKi-JYVI,95
2
2
  raijin_server/cli.py,sha256=2m7q1znMLbBdnUwN6oOUrCZXEqC2e7SfbjYkymbP4lQ,37884
3
3
  raijin_server/config.py,sha256=QNiEVvrbW56XgvNn5-h3bkJm46Xc8mjNqPbvixXD8N0,4829
4
4
  raijin_server/healthchecks.py,sha256=lzXdFw6S0hOYbUKbqksh4phb04lXgXdTspP1Dsz4dx8,15401
@@ -22,7 +22,7 @@ raijin_server/modules/kong.py,sha256=eDSagvEP9_BCs9pZ-pCVs1BDdlYOoJfY5PnUSiTvvgc
22
22
  raijin_server/modules/kubernetes.py,sha256=9E6zV0zGQWZW92NVpxwYctpi-4JDmi6YzF3tKRI4HlU,13343
23
23
  raijin_server/modules/loki.py,sha256=aNiUpnOFppZMXoQwYhn7IoPMzwUz4aHi6pbiqj1PRjc,5022
24
24
  raijin_server/modules/metallb.py,sha256=uUuklc_RsQ-W2qDVRMQAxQm9HKGEqso444b1IwBpM6w,8554
25
- raijin_server/modules/minio.py,sha256=rHiyNs1wK2gxAMDUhxhN5zeh8nuyADlmueHiYhEyjL0,7213
25
+ raijin_server/modules/minio.py,sha256=W49LyaRXoaeLIebFO6kwqIT9usZ1IP648UK10dInHJ4,12683
26
26
  raijin_server/modules/network.py,sha256=QRlYdcryCCPAWG3QQ_W7ld9gJgETI7H8gwntOU7UqFE,4818
27
27
  raijin_server/modules/observability_dashboards.py,sha256=fVz0WEOQrUTF5rJ__Nu_onyBuwL_exFmysWMmg8AE9w,7319
28
28
  raijin_server/modules/observability_ingress.py,sha256=Fh1rlFWueBNHnOkHuoHYyhILmpO-iQXINybSUYbYsHQ,5738
@@ -38,9 +38,9 @@ raijin_server/scripts/checklist.sh,sha256=j6E0Kmk1EfjLvKK1VpCqzXJAXI_7Bm67LK4ndy
38
38
  raijin_server/scripts/install.sh,sha256=Y1ickbQ4siQ0NIPs6UgrqUr8WWy7U0LHmaTQbEgavoI,3949
39
39
  raijin_server/scripts/log_size_metric.sh,sha256=Iv4SsX8AuCYRou-klYn32mX41xB6j0xJGLBO6riw4rU,1208
40
40
  raijin_server/scripts/pre-deploy-check.sh,sha256=XqMo7IMIpwUHF17YEmU0-cVmTDMoCGMBFnmS39FidI4,4912
41
- raijin_server-0.2.36.dist-info/licenses/LICENSE,sha256=kJsMCjOiRZE0AQNtxWqBa32z9kMAaF4EUxyHj3hKaJo,1105
42
- raijin_server-0.2.36.dist-info/METADATA,sha256=tlpS6iDjkI54ZwHLoLe4UzUigdQZiGH5sCDtAucNYj8,22770
43
- raijin_server-0.2.36.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
44
- raijin_server-0.2.36.dist-info/entry_points.txt,sha256=3ZvxDX4pvcjkIRsXAJ69wIfVmKa78LKo-C3QhqN2KVM,56
45
- raijin_server-0.2.36.dist-info/top_level.txt,sha256=Yz1xneCRtsZOzbPIcTAcrSxd-1p80pohMXYAZ74dpok,14
46
- raijin_server-0.2.36.dist-info/RECORD,,
41
+ raijin_server-0.2.38.dist-info/licenses/LICENSE,sha256=kJsMCjOiRZE0AQNtxWqBa32z9kMAaF4EUxyHj3hKaJo,1105
42
+ raijin_server-0.2.38.dist-info/METADATA,sha256=kfDAsH4WoVhFS1RxNnTWqNLFo4vF0obMCQu2JHCZU2I,22770
43
+ raijin_server-0.2.38.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
44
+ raijin_server-0.2.38.dist-info/entry_points.txt,sha256=3ZvxDX4pvcjkIRsXAJ69wIfVmKa78LKo-C3QhqN2KVM,56
45
+ raijin_server-0.2.38.dist-info/top_level.txt,sha256=Yz1xneCRtsZOzbPIcTAcrSxd-1p80pohMXYAZ74dpok,14
46
+ raijin_server-0.2.38.dist-info/RECORD,,