diff --git a/Dockerfile b/Dockerfile index 5f20c86..3a04960 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,11 +29,9 @@ RUN groupadd -r appuser && useradd -r -g appuser appuser RUN mkdir -p /app /tmp/reports && \ chown -R appuser:appuser /app /tmp/reports -# Copiar dependências Python do stage anterior -COPY --from=builder /root/.local /home/appuser/.local - -# Definir PATH para incluir dependências locais -ENV PATH=/home/appuser/.local/bin:$PATH +# Instalar dependências Python globalmente +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt # Definir diretório de trabalho WORKDIR /app diff --git a/app/api/routes.py b/app/api/routes.py index 912b093..a6e7099 100644 --- a/app/api/routes.py +++ b/app/api/routes.py @@ -175,12 +175,13 @@ async def get_validations_by_namespace( severity: Optional[str] = None, page: int = 1, page_size: int = 20, + include_system_namespaces: bool = False, k8s_client=Depends(get_k8s_client) ): """Listar validações agrupadas por namespace com paginação""" try: - # Coletar todos os pods - pods = await k8s_client.get_all_pods() + # Coletar todos os pods com filtro de namespaces do sistema + pods = await k8s_client.get_all_pods(include_system_namespaces=include_system_namespaces) # Validar recursos e agrupar por namespace namespace_validations = {} diff --git a/app/core/config.py b/app/core/config.py index 88e5c5b..1617bfe 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -4,6 +4,7 @@ Configurações da aplicação import os from typing import List, Optional from pydantic_settings import BaseSettings +from pydantic import Field class Settings(BaseSettings): """Configurações da aplicação""" @@ -31,6 +32,24 @@ class Settings(BaseSettings): "openshift-sdn" ] + # Configurações de filtro de namespaces + include_system_namespaces: bool = Field(default=False, alias="INCLUDE_SYSTEM_NAMESPACES") + system_namespace_prefixes: List[str] = Field( + default=[ + "kube-", + "openshift-", + "default", + "kube-system", + "kube-public", + "kube-node-lease" + ], + alias="SYSTEM_NAMESPACE_PREFIXES" + ) + + class Config: + env_file = ".env" + case_sensitive = False + # Configurações de relatório report_export_path: str = "/tmp/reports" diff --git a/app/core/kubernetes_client.py b/app/core/kubernetes_client.py index c390710..2ba5bc6 100644 --- a/app/core/kubernetes_client.py +++ b/app/core/kubernetes_client.py @@ -44,7 +44,20 @@ class K8sClient: logger.error(f"Erro ao inicializar cliente Kubernetes: {e}") raise - async def get_all_pods(self) -> List[PodResource]: + def _is_system_namespace(self, namespace: str, include_system: bool = None) -> bool: + """Verificar se um namespace é do sistema""" + # Usar parâmetro se fornecido, senão usar configuração global + should_include = include_system if include_system is not None else settings.include_system_namespaces + + if should_include: + return False + + for prefix in settings.system_namespace_prefixes: + if namespace.startswith(prefix): + return True + return False + + async def get_all_pods(self, include_system_namespaces: bool = None) -> List[PodResource]: """Coletar informações de todos os pods do cluster""" if not self.initialized: raise RuntimeError("Cliente Kubernetes não inicializado") @@ -56,6 +69,9 @@ class K8sClient: pods = self.v1.list_pod_for_all_namespaces(watch=False) for pod in pods.items: + # Filtrar namespaces do sistema + if self._is_system_namespace(pod.metadata.namespace, include_system_namespaces): + continue pod_resource = PodResource( name=pod.metadata.name, namespace=pod.metadata.namespace, @@ -102,6 +118,18 @@ class K8sClient: if not self.initialized: raise RuntimeError("Cliente Kubernetes não inicializado") + # Verificar se é namespace do sistema + if self._is_system_namespace(namespace): + logger.info(f"Namespace {namespace} é do sistema, retornando vazio") + return NamespaceResources( + name=namespace, + pods=[], + total_cpu_requests="0", + total_cpu_limits="0", + total_memory_requests="0", + total_memory_limits="0" + ) + try: # Listar pods do namespace pods = self.v1.list_namespaced_pod(namespace=namespace) diff --git a/app/static/index.html b/app/static/index.html index c56c2d4..214b10d 100644 --- a/app/static/index.html +++ b/app/static/index.html @@ -488,6 +488,19 @@ border-radius: 4px; } + .checkbox-label { + display: flex !important; + flex-direction: row !important; + align-items: center; + gap: 0.5rem; + cursor: pointer; + } + + .checkbox-label input[type="checkbox"] { + margin: 0; + width: auto; + } + @media (max-width: 768px) { .container { padding: 1rem; @@ -635,6 +648,12 @@ +