190 lines
5.8 KiB
Python
190 lines
5.8 KiB
Python
|
|
"""Nexus — Pydantic Request/Response Models
|
||
|
|
Shared schemas for API validation, replacing raw `dict` parameters.
|
||
|
|
"""
|
||
|
|
|
||
|
|
from typing import Optional, List
|
||
|
|
from pydantic import BaseModel, Field
|
||
|
|
|
||
|
|
|
||
|
|
# ── Server ──
|
||
|
|
|
||
|
|
class ServerCreate(BaseModel):
|
||
|
|
name: str = Field(..., min_length=1, max_length=100)
|
||
|
|
domain: str = Field(..., min_length=1, max_length=255)
|
||
|
|
port: int = Field(22, ge=1, le=65535)
|
||
|
|
username: str = Field("root", max_length=100)
|
||
|
|
auth_method: str = Field("key", pattern="^(key|password)$")
|
||
|
|
password: Optional[str] = None
|
||
|
|
ssh_key_path: Optional[str] = None
|
||
|
|
ssh_key_private: Optional[str] = None
|
||
|
|
ssh_key_public: Optional[str] = None
|
||
|
|
agent_port: int = Field(8601, ge=1, le=65535)
|
||
|
|
agent_api_key: Optional[str] = None
|
||
|
|
description: Optional[str] = None
|
||
|
|
target_path: Optional[str] = None
|
||
|
|
category: Optional[str] = None
|
||
|
|
platform_id: Optional[int] = None
|
||
|
|
node_id: Optional[int] = None
|
||
|
|
protocols: Optional[list] = None
|
||
|
|
extra_attrs: Optional[dict] = None
|
||
|
|
|
||
|
|
|
||
|
|
class ServerUpdate(BaseModel):
|
||
|
|
name: Optional[str] = Field(None, min_length=1, max_length=100)
|
||
|
|
domain: Optional[str] = Field(None, min_length=1, max_length=255)
|
||
|
|
port: Optional[int] = Field(None, ge=1, le=65535)
|
||
|
|
username: Optional[str] = None
|
||
|
|
auth_method: Optional[str] = Field(None, pattern="^(key|password)$")
|
||
|
|
password: Optional[str] = None
|
||
|
|
ssh_key_path: Optional[str] = None
|
||
|
|
ssh_key_private: Optional[str] = None
|
||
|
|
ssh_key_public: Optional[str] = None
|
||
|
|
agent_port: Optional[int] = Field(None, ge=1, le=65535)
|
||
|
|
agent_api_key: Optional[str] = None
|
||
|
|
description: Optional[str] = None
|
||
|
|
target_path: Optional[str] = None
|
||
|
|
category: Optional[str] = None
|
||
|
|
platform_id: Optional[int] = None
|
||
|
|
node_id: Optional[int] = None
|
||
|
|
protocols: Optional[list] = None
|
||
|
|
extra_attrs: Optional[dict] = None
|
||
|
|
connectivity: Optional[str] = None
|
||
|
|
|
||
|
|
|
||
|
|
class ServerPush(BaseModel):
|
||
|
|
server_ids: List[int] = Field(..., min_length=1)
|
||
|
|
source_path: str = Field(..., min_length=1)
|
||
|
|
sync_mode: str = Field("incremental", pattern="^(incremental|full|overwrite|checksum)$")
|
||
|
|
operator: str = "admin"
|
||
|
|
batch_size: int = Field(50, ge=1, le=200)
|
||
|
|
concurrency: int = Field(10, ge=1, le=50)
|
||
|
|
|
||
|
|
|
||
|
|
class ServerCheck(BaseModel):
|
||
|
|
server_ids: List[int] = Field(..., min_length=1)
|
||
|
|
|
||
|
|
|
||
|
|
# ── Sync ──
|
||
|
|
|
||
|
|
class SyncFiles(BaseModel):
|
||
|
|
server_ids: List[int] = Field(..., min_length=1)
|
||
|
|
source_path: str = Field(..., min_length=1)
|
||
|
|
target_path: Optional[str] = None
|
||
|
|
sync_mode: str = Field("incremental", pattern="^(incremental|full|overwrite|checksum)$")
|
||
|
|
batch_size: int = Field(50, ge=1, le=200)
|
||
|
|
concurrency: int = Field(10, ge=1, le=50)
|
||
|
|
|
||
|
|
|
||
|
|
class SyncCommands(BaseModel):
|
||
|
|
server_ids: List[int] = Field(..., min_length=1)
|
||
|
|
commands: List[str] = Field(..., min_length=1)
|
||
|
|
timeout: int = Field(60, ge=1, le=600)
|
||
|
|
concurrency: int = Field(10, ge=1, le=50)
|
||
|
|
|
||
|
|
|
||
|
|
class SyncConfig(BaseModel):
|
||
|
|
server_ids: List[int] = Field(..., min_length=1)
|
||
|
|
config: dict = Field(..., min_length=1)
|
||
|
|
concurrency: int = Field(10, ge=1, le=50)
|
||
|
|
|
||
|
|
|
||
|
|
class SyncSftp(BaseModel):
|
||
|
|
server_id: int
|
||
|
|
operation: str = Field("put", pattern="^(put|get)$")
|
||
|
|
local_path: str = Field(..., min_length=1)
|
||
|
|
remote_path: str = Field(..., min_length=1)
|
||
|
|
|
||
|
|
|
||
|
|
class SyncBrowse(BaseModel):
|
||
|
|
server_id: int
|
||
|
|
path: str = Field("/", min_length=1)
|
||
|
|
|
||
|
|
|
||
|
|
# ── Script ──
|
||
|
|
|
||
|
|
class ScriptCreate(BaseModel):
|
||
|
|
name: str = Field(..., min_length=1, max_length=100)
|
||
|
|
category: str = Field("ops", pattern="^(ops|deploy|check|cleanup)$")
|
||
|
|
content: str = Field(..., min_length=1)
|
||
|
|
description: Optional[str] = None
|
||
|
|
created_by: Optional[str] = None
|
||
|
|
|
||
|
|
|
||
|
|
class ScriptUpdate(BaseModel):
|
||
|
|
name: Optional[str] = Field(None, min_length=1, max_length=100)
|
||
|
|
category: Optional[str] = Field(None, pattern="^(ops|deploy|check|cleanup)$")
|
||
|
|
content: Optional[str] = None
|
||
|
|
description: Optional[str] = None
|
||
|
|
|
||
|
|
|
||
|
|
class ScriptExecute(BaseModel):
|
||
|
|
script_id: Optional[int] = None
|
||
|
|
command: str = Field(..., min_length=1)
|
||
|
|
server_ids: List[int] = Field(..., min_length=1)
|
||
|
|
timeout: int = Field(60, ge=1, le=600)
|
||
|
|
|
||
|
|
|
||
|
|
# ── Schedule ──
|
||
|
|
|
||
|
|
class ScheduleCreate(BaseModel):
|
||
|
|
name: str = Field(..., min_length=1, max_length=100)
|
||
|
|
source_path: str = Field(..., min_length=1)
|
||
|
|
server_ids: str = Field(..., min_length=3) # JSON array string
|
||
|
|
cron_expr: str = Field(..., min_length=9, max_length=100)
|
||
|
|
enabled: bool = True
|
||
|
|
|
||
|
|
|
||
|
|
class ScheduleUpdate(BaseModel):
|
||
|
|
name: Optional[str] = Field(None, min_length=1, max_length=100)
|
||
|
|
source_path: Optional[str] = None
|
||
|
|
server_ids: Optional[str] = None
|
||
|
|
cron_expr: Optional[str] = None
|
||
|
|
enabled: Optional[bool] = None
|
||
|
|
|
||
|
|
|
||
|
|
# ── Preset ──
|
||
|
|
|
||
|
|
class PresetCreate(BaseModel):
|
||
|
|
name: str = Field(..., min_length=1, max_length=100)
|
||
|
|
encrypted_pw: str = Field(..., min_length=1)
|
||
|
|
|
||
|
|
|
||
|
|
# ── Platform / Node ──
|
||
|
|
|
||
|
|
class PlatformCreate(BaseModel):
|
||
|
|
name: str = Field(..., min_length=1, max_length=100)
|
||
|
|
category: str = Field(..., min_length=1, max_length=50)
|
||
|
|
type: str = Field(..., min_length=1, max_length=50)
|
||
|
|
default_protocols: Optional[list] = None
|
||
|
|
charset: str = "utf-8"
|
||
|
|
|
||
|
|
|
||
|
|
class PlatformUpdate(BaseModel):
|
||
|
|
name: Optional[str] = Field(None, min_length=1, max_length=100)
|
||
|
|
category: Optional[str] = None
|
||
|
|
type: Optional[str] = None
|
||
|
|
default_protocols: Optional[list] = None
|
||
|
|
charset: Optional[str] = None
|
||
|
|
|
||
|
|
|
||
|
|
class NodeCreate(BaseModel):
|
||
|
|
name: str = Field(..., min_length=1, max_length=100)
|
||
|
|
parent_id: Optional[int] = None
|
||
|
|
sort_order: int = 0
|
||
|
|
|
||
|
|
|
||
|
|
class NodeUpdate(BaseModel):
|
||
|
|
name: Optional[str] = Field(None, min_length=1, max_length=100)
|
||
|
|
parent_id: Optional[int] = None
|
||
|
|
sort_order: Optional[int] = None
|
||
|
|
|
||
|
|
|
||
|
|
# ── Pagination ──
|
||
|
|
|
||
|
|
class PaginatedResponse(BaseModel):
|
||
|
|
items: list
|
||
|
|
total: int
|
||
|
|
page: int
|
||
|
|
per_page: int
|
||
|
|
pages: int
|