"""Server-level file-management elevation policy (stored in ``servers.extra_attrs``).""" from __future__ import annotations from enum import StrEnum from server.domain.models import Server FILES_ELEVATION_ATTR = "files_elevation" VALID_FILES_ELEVATIONS = frozenset({"off", "auto_sudo", "always_sudo"}) DEFAULT_FILES_ELEVATION = "auto_sudo" SUDOERS_DOC_PATH = "docs/deploy/nexus-files-sudoers.example" class FilesElevation(StrEnum): OFF = "off" AUTO = "auto_sudo" ALWAYS = "always_sudo" def normalize_files_elevation(value: object | None) -> FilesElevation: """Return elevation mode; unknown values fall back to AUTO.""" if value is None or value == "": return FilesElevation.AUTO raw = str(value).strip().lower() if raw in VALID_FILES_ELEVATIONS: return FilesElevation(raw) return FilesElevation.AUTO def get_files_elevation(server: Server) -> FilesElevation: attrs = server.extra_attrs if isinstance(server.extra_attrs, dict) else {} return normalize_files_elevation(attrs.get(FILES_ELEVATION_ATTR)) def merge_files_elevation_into_extra_attrs( extra_attrs: dict | None, files_elevation: str | None, ) -> dict | None: if files_elevation is None: return extra_attrs out = dict(extra_attrs or {}) mode = normalize_files_elevation(files_elevation) out[FILES_ELEVATION_ATTR] = mode.value return out def apply_files_elevation_payload(data: dict) -> None: """Pop ``files_elevation`` from API payload and merge into ``extra_attrs``.""" fe = data.pop("files_elevation", None) if fe is not None: data["extra_attrs"] = merge_files_elevation_into_extra_attrs( data.get("extra_attrs"), fe, )