Release / verify (push) Canceled after 0s
CI / checks (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CI / backend (push) Canceled after 0s
Release / test (push) Canceled after 0s
Release / publish (backend) (push) Canceled after 0s
Release / publish (frontend) (push) Canceled after 0s
Release / publish (proxy) (push) Canceled after 0s
Release / publish (updater) (push) Canceled after 0s
- **Übernehmen: mit vorhandenem zentralem Objekt verknüpfen:** Dieselbe von Hand angelegte Regel, derselbe Alias oder dieselbe NAT-Regel auf mehreren Firewalls (z. B. beide HA-Knoten) wird nicht mehr als zweites Objekt übernommen. Im Dialog „Von Firewall übernehmen“ erscheint bei exakter Übereinstimmung (nach Einsetzen der Host-Variablen, bei Aliasen inkl. Verweisen) die Aktion **Verknüpfen**: die Firewall wird weiteres Ziel des vorhandenen Objekts, die Vorschau zeigt „keine Änderung“, und der nächste Rollout aktualisiert alle Firewalls an einem Objekt. Auf der Firewall wird dabei nichts geändert. Unterscheidet sich ein gleichnamiges Objekt, zeigt der Dialog die abweichenden Felder; verknüpft wird dann nie. „Alle übernehmbaren“ fragt vorher nach („3 verknüpfen, 2 neu übernehmen, 1 nicht übernehmbar“). Aliase, die bisher wegen „Name existiert“ abgelehnt wurden, lassen sich so übernehmen. Wartet das vorhandene Objekt gerade auf eine Bestätigung, wird nicht verknüpft; „Alle übernehmbaren“ lässt den Eintrag dann aus. Verknüpfen macht ein gerade geöffnetes Bearbeiten-Formular des Objekts ungültig, damit die neue Firewall nicht versehentlich wieder aus den Zielen fällt. - **Tooltips überarbeitet:** Der deaktivierte Button „Oberfläche öffnen“ nennt jetzt den Grund im Klartext samt nächstem Schritt (statt nur einer Variablen wie `GUI_GATEWAY_TOKEN`); dasselbe gilt für ausgeschaltete Funktion, deaktivierte Firewall, Nicht-HTTPS-Adresse und ausgeschaltete Zertifikatsprüfung. Texte durchgehend in Du-Form, kürzere VPN-Einleitungen, verständlichere Hinweise bei gesperrten Buttons (Zertifikate, Benutzer, Dienste). Icon-Buttons (Bearbeiten, Löschen, Schließen, Reihenfolge) zeigen beim Darüberfahren ihren Namen.
109 lines
3.5 KiB
Python
109 lines
3.5 KiB
Python
import uuid
|
|
from datetime import datetime
|
|
from typing import Literal
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
|
|
from app.schemas.adopt import LinkTarget
|
|
|
|
|
|
class RuleCreate(BaseModel):
|
|
description: str = Field(min_length=1, max_length=255)
|
|
interface: str = Field(min_length=1, max_length=64)
|
|
direction: Literal["in", "out"] = "in"
|
|
ipprotocol: Literal["inet", "inet6"] = "inet"
|
|
protocol: str = Field(default="any", min_length=1, max_length=16)
|
|
action: Literal["pass", "block", "reject"] = "pass"
|
|
source_net: str = Field(default="any", min_length=1, max_length=128)
|
|
source_port: str | None = Field(default=None, max_length=32)
|
|
destination_net: str = Field(default="any", min_length=1, max_length=128)
|
|
destination_port: str | None = Field(default=None, max_length=32)
|
|
enabled: bool = True
|
|
log: bool = False
|
|
target_host_ids: list[uuid.UUID] = Field(default_factory=list)
|
|
target_group_ids: list[uuid.UUID] = Field(default_factory=list)
|
|
|
|
|
|
@field_validator("description", "interface", "protocol", "source_net", "destination_net")
|
|
@classmethod
|
|
def nonblank(cls, value):
|
|
if not value.strip():
|
|
raise ValueError("Feld darf nicht nur Leerzeichen enthalten")
|
|
return value.strip()
|
|
|
|
|
|
class DeploymentResult(BaseModel):
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
host_id: uuid.UUID
|
|
host_name: str
|
|
status: Literal["success", "error", "pending", "reverted", "revert_failed"]
|
|
message: str | None = None
|
|
# Only set while status == "pending" — the client counts down to this
|
|
# and shows the Confirm button until it passes.
|
|
revert_deadline: datetime | None = None
|
|
|
|
|
|
class RuleRead(BaseModel):
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: uuid.UUID
|
|
description: str
|
|
interface: str
|
|
direction: str
|
|
ipprotocol: str
|
|
protocol: str
|
|
action: str
|
|
source_net: str
|
|
source_port: str | None
|
|
destination_net: str
|
|
destination_port: str | None
|
|
enabled: bool
|
|
log: bool = False
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
target_host_ids: list[uuid.UUID]
|
|
target_group_ids: list[uuid.UUID] = Field(default_factory=list)
|
|
effective_host_ids: list[uuid.UUID] = Field(default_factory=list)
|
|
workflow_state: Literal["attention", "pending", "cleanup", "unassigned", "disabled", "draft", "synced"]
|
|
workflow_counts: dict[str, int]
|
|
deployments: list[DeploymentResult]
|
|
|
|
|
|
class RuleEdit(RuleCreate):
|
|
expected_updated_at: datetime
|
|
|
|
|
|
class DeployApproval(BaseModel):
|
|
preview_token: str = Field(min_length=64, max_length=64)
|
|
|
|
|
|
class AdoptRequest(BaseModel):
|
|
host_id: uuid.UUID
|
|
# Link to this existing central rule instead of creating a new one (services/adopt_link_service.py).
|
|
link_to: uuid.UUID | None = None
|
|
rule_uuid: str = Field(min_length=1, max_length=64)
|
|
|
|
|
|
class UnmanagedRule(BaseModel):
|
|
uuid: str
|
|
description: str
|
|
interface: str
|
|
interface_label: str
|
|
direction: str
|
|
action: str
|
|
protocol: str
|
|
source_net: str
|
|
source_port: str
|
|
destination_net: str
|
|
destination_port: str
|
|
enabled: bool
|
|
log: bool
|
|
adoptable: bool
|
|
# Codes such as "negated_source" or "not_quick"; the UI turns them into text.
|
|
reasons: list[str]
|
|
# Central rules equal to this one (resolved for the host), same-description rules that differ, link possible.
|
|
matches: list[LinkTarget] = Field(default_factory=list)
|
|
similar: list[LinkTarget] = Field(default_factory=list)
|
|
linkable: bool = False
|