mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-06 15:21:13 +02:00
feat: add response models for endpoints returning untyped objects
This commit is contained in:
24 files changed
+1192
-53
No files matched your search
@@ -26,10 +26,20 @@ from .controller.computes import (
|
||||
ComputeUpdate,
|
||||
ComputeVirtualBoxVM,
|
||||
ComputeVMwareVM,
|
||||
IdlePC,
|
||||
)
|
||||
from .controller.drawings import Drawing
|
||||
from .controller.gns3vm import GNS3VM
|
||||
from .controller.images import Image, ImageSyncJob, ImageSyncRequest, ImageType, ImageUpload
|
||||
from .controller.gns3vm import GNS3VM, GNS3VMEngineInfo, GNS3VMInfo
|
||||
from .controller.images import (
|
||||
Image,
|
||||
ImageInstallCreated,
|
||||
ImageInstallResult,
|
||||
ImageInstallSkipped,
|
||||
ImageSyncJob,
|
||||
ImageSyncRequest,
|
||||
ImageType,
|
||||
ImageUpload,
|
||||
)
|
||||
|
||||
# Controller schemas
|
||||
from .controller.links import (
|
||||
@@ -37,10 +47,17 @@ from .controller.links import (
|
||||
Link,
|
||||
LinkCapture,
|
||||
LinkCreate,
|
||||
LinkFilterInfo,
|
||||
LinkFilterParameter,
|
||||
LinkUpdate,
|
||||
LinkWiresharkRestart,
|
||||
Marker,
|
||||
MarkerCreate,
|
||||
MarkerDefinition,
|
||||
MarkerDefinitionCreate,
|
||||
MarkerDefinitionWithLinks,
|
||||
MarkerUpdate,
|
||||
ProjectMarker,
|
||||
UDPPortInfo,
|
||||
)
|
||||
from .controller.nodes import Node, NodeCapture, NodeCreate, NodeDuplicate, NodeUpdate
|
||||
@@ -51,6 +68,7 @@ from .controller.projects import (
|
||||
ProjectCreate,
|
||||
ProjectDuplicate,
|
||||
ProjectFile,
|
||||
ProjectStats,
|
||||
ProjectUpdate,
|
||||
)
|
||||
from .controller.templates import Template, TemplateCreate, TemplateUpdate, TemplateUsage
|
||||
@@ -108,11 +126,31 @@ from .compute.vmware_nodes import VMware, VMwareCreate, VMwareUpdate
|
||||
from .compute.vpcs_nodes import VPCS, VPCSCreate, VPCSUpdate
|
||||
from .controller.capabilities import Capabilities
|
||||
from .controller.iou_license import IOULicense
|
||||
from .controller.marker_replay import (
|
||||
ReplayFrame,
|
||||
ReplayFrameDetail,
|
||||
ReplayFrames,
|
||||
ReplayFrameSource,
|
||||
ReplaySource,
|
||||
ReplayTimeline,
|
||||
ReplayTreeNode,
|
||||
)
|
||||
from .controller.netmiko import NetmikoDeviceType, NetmikoDeviceTypeList
|
||||
from .controller.pools import Resource, ResourceCreate, ResourcePool, ResourcePoolCreate, ResourcePoolUpdate
|
||||
from .controller.rbac import ACE, ACECreate, ACEUpdate, Privilege, Role, RoleCreate, RoleUpdate
|
||||
from .controller.rbac import ACE, ACECreate, ACEEndpoint, ACEUpdate, Privilege, Role, RoleCreate, RoleUpdate
|
||||
from .controller.settings import SettingsResponse, SettingsUpdate, SettingsUpdateResponse
|
||||
from .controller.snapshots import Snapshot, SnapshotCreate
|
||||
from .controller.statistics import (
|
||||
ComputeStatistics,
|
||||
ComputeStatisticsEntry,
|
||||
LinkStatistics,
|
||||
NodeStatistics,
|
||||
ProjectCountStatistics,
|
||||
ServerStatistics,
|
||||
WebWiresharkContainer,
|
||||
WebWiresharkStatistics,
|
||||
)
|
||||
from .controller.symbols import SymbolDimensions, SymbolInfo
|
||||
from .controller.templates.cloud_templates import CloudTemplate, CloudTemplateUpdate
|
||||
from .controller.templates.docker_templates import DockerTemplate, DockerTemplateUpdate
|
||||
from .controller.templates.dynamips_templates import (
|
||||
@@ -141,7 +179,7 @@ from .controller.templates.vmware_templates import VMwareTemplate, VMwareTemplat
|
||||
|
||||
# Controller template schemas
|
||||
from .controller.templates.vpcs_templates import VPCSTemplate, VPCSTemplateUpdate
|
||||
from .controller.tokens import ApiKeyCreate, RefreshTokenRequest, Token
|
||||
from .controller.tokens import ApiKey, ApiKeyCreate, ApiKeyCreated, ApiKeyMessage, RefreshTokenRequest, Token
|
||||
|
||||
# Schemas for both controller and compute
|
||||
from .qemu_disk_image import QemuDiskImageCreate, QemuDiskImageFormat, QemuDiskImageUpdate
|
||||
@@ -155,11 +193,15 @@ __all__ = [
|
||||
"UDPNIO",
|
||||
"VPCS",
|
||||
"ACECreate",
|
||||
"ACEEndpoint",
|
||||
"ACEUpdate",
|
||||
"ATMSwitch",
|
||||
"ATMSwitchCreate",
|
||||
"ATMSwitchUpdate",
|
||||
"ApiKey",
|
||||
"ApiKeyCreate",
|
||||
"ApiKeyCreated",
|
||||
"ApiKeyMessage",
|
||||
"Appliance",
|
||||
"ApplianceVersion",
|
||||
"ApplianceVersionV8",
|
||||
@@ -192,6 +234,8 @@ __all__ = [
|
||||
"Compute",
|
||||
"ComputeCreate",
|
||||
"ComputeDockerImage",
|
||||
"ComputeStatistics",
|
||||
"ComputeStatisticsEntry",
|
||||
"ComputeUpdate",
|
||||
"ComputeVMwareVM",
|
||||
"ComputeVirtualBoxVM",
|
||||
@@ -223,13 +267,19 @@ __all__ = [
|
||||
"FrameRelaySwitch",
|
||||
"FrameRelaySwitchCreate",
|
||||
"FrameRelaySwitchUpdate",
|
||||
"GNS3VMEngineInfo",
|
||||
"GNS3VMInfo",
|
||||
"IOUCreate",
|
||||
"IOULicense",
|
||||
"IOUStart",
|
||||
"IOUTemplate",
|
||||
"IOUTemplateUpdate",
|
||||
"IOUUpdate",
|
||||
"IdlePC",
|
||||
"Image",
|
||||
"ImageInstallCreated",
|
||||
"ImageInstallResult",
|
||||
"ImageInstallSkipped",
|
||||
"ImageSyncJob",
|
||||
"ImageSyncRequest",
|
||||
"ImageType",
|
||||
@@ -244,10 +294,17 @@ __all__ = [
|
||||
"Link",
|
||||
"LinkCapture",
|
||||
"LinkCreate",
|
||||
"LinkFilterInfo",
|
||||
"LinkFilterParameter",
|
||||
"LinkStatistics",
|
||||
"LinkUpdate",
|
||||
"LinkWiresharkRestart",
|
||||
"LoggedInUserUpdate",
|
||||
"Marker",
|
||||
"MarkerCreate",
|
||||
"MarkerDefinition",
|
||||
"MarkerDefinitionCreate",
|
||||
"MarkerDefinitionWithLinks",
|
||||
"MarkerRebuild",
|
||||
"MarkerToggle",
|
||||
"MarkerUpdate",
|
||||
@@ -260,15 +317,19 @@ __all__ = [
|
||||
"NodeCreate",
|
||||
"NodeDuplicate",
|
||||
"NodeFile",
|
||||
"NodeStatistics",
|
||||
"NodeUpdate",
|
||||
"OpenAIMessage",
|
||||
"OpenAIToolCall",
|
||||
"Privilege",
|
||||
"Project",
|
||||
"ProjectCompression",
|
||||
"ProjectCountStatistics",
|
||||
"ProjectCreate",
|
||||
"ProjectDuplicate",
|
||||
"ProjectFile",
|
||||
"ProjectMarker",
|
||||
"ProjectStats",
|
||||
"ProjectUpdate",
|
||||
"Qemu",
|
||||
"QemuCreate",
|
||||
@@ -280,6 +341,13 @@ __all__ = [
|
||||
"QemuUpdate",
|
||||
"RefreshTokenRequest",
|
||||
"RenameSession",
|
||||
"ReplayFrame",
|
||||
"ReplayFrameDetail",
|
||||
"ReplayFrameSource",
|
||||
"ReplayFrames",
|
||||
"ReplaySource",
|
||||
"ReplayTimeline",
|
||||
"ReplayTreeNode",
|
||||
"Resource",
|
||||
"ResourceCreate",
|
||||
"ResourcePool",
|
||||
@@ -289,11 +357,14 @@ __all__ = [
|
||||
"RoleCreate",
|
||||
"RoleUpdate",
|
||||
"ServerConfig",
|
||||
"ServerStatistics",
|
||||
"SettingsResponse",
|
||||
"SettingsUpdate",
|
||||
"SettingsUpdateResponse",
|
||||
"Snapshot",
|
||||
"SnapshotCreate",
|
||||
"SymbolDimensions",
|
||||
"SymbolInfo",
|
||||
"Template",
|
||||
"TemplateCreate",
|
||||
"TemplateUpdate",
|
||||
@@ -321,4 +392,6 @@ __all__ = [
|
||||
"VirtualBoxTemplate",
|
||||
"VirtualBoxTemplateUpdate",
|
||||
"VirtualBoxUpdate",
|
||||
"WebWiresharkContainer",
|
||||
"WebWiresharkStatistics",
|
||||
]
|
||||
@@ -161,3 +161,11 @@ class AutoIdlePC(BaseModel):
|
||||
model_config = ConfigDict(
|
||||
json_schema_extra={"example": {"platform": "c7200", "image": "/path/to/c7200_image.bin", "ram": 256}}
|
||||
)
|
||||
|
||||
|
||||
class IdlePC(BaseModel):
|
||||
"""
|
||||
Result of an Idle-PC computation.
|
||||
"""
|
||||
|
||||
idlepc: Optional[str] = Field(None, description="Idle-PC value, null when none was found")
|
||||
@@ -55,3 +55,24 @@ class GNS3VM(BaseModel):
|
||||
vcpus: Optional[int] = Field(None, description="Number of CPUs to allocate for the GNS3 VM")
|
||||
ram: Optional[int] = Field(None, description="Amount of memory to allocate for the GNS3 VM")
|
||||
port: Optional[int] = Field(None, gt=0, le=65535)
|
||||
|
||||
|
||||
class GNS3VMEngineInfo(BaseModel):
|
||||
"""
|
||||
A virtualization engine supported by the GNS3 VM.
|
||||
"""
|
||||
|
||||
engine_id: str = Field(..., description="Engine identifier")
|
||||
name: str = Field(..., description="Engine display name")
|
||||
description: str = Field(..., description="Engine description (may contain HTML)")
|
||||
support_when_exit: bool = Field(..., description="The engine supports the 'when exit' action")
|
||||
support_headless: bool = Field(..., description="The engine supports headless mode")
|
||||
support_ram: bool = Field(..., description="The engine supports RAM and vCPUs allocation")
|
||||
|
||||
|
||||
class GNS3VMInfo(BaseModel):
|
||||
"""
|
||||
A virtual machine available on a virtualization engine.
|
||||
"""
|
||||
|
||||
vmname: str = Field(..., description="Virtual machine name")
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
from typing import Annotated, Literal, Optional
|
||||
from typing import Annotated, List, Literal, Optional
|
||||
from uuid import UUID
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
@@ -100,3 +101,32 @@ class ImageCompatibility(BaseModel):
|
||||
class ImageCompatibilityCatalog(BaseModel):
|
||||
image_sizes: list[int]
|
||||
has_unknown_sizes: bool
|
||||
|
||||
|
||||
class ImageInstallCreated(BaseModel):
|
||||
"""
|
||||
A template created from an image by the automatic installation.
|
||||
"""
|
||||
|
||||
template_id: UUID
|
||||
name: Optional[str] = None
|
||||
version: Optional[str] = None
|
||||
template_type: Optional[str] = None
|
||||
|
||||
|
||||
class ImageInstallSkipped(BaseModel):
|
||||
"""
|
||||
An image or template that the automatic installation skipped.
|
||||
"""
|
||||
|
||||
name: Optional[str] = None
|
||||
reason: str
|
||||
|
||||
|
||||
class ImageInstallResult(BaseModel):
|
||||
"""
|
||||
Result of the automatic template installation from images.
|
||||
"""
|
||||
|
||||
created: List[ImageInstallCreated]
|
||||
skipped: List[ImageInstallSkipped]
|
||||
@@ -274,3 +274,81 @@ class MarkerDefinitionCreate(BaseModel):
|
||||
@classmethod
|
||||
def _both_to_none(cls, v):
|
||||
return None if v == "both" else v
|
||||
|
||||
|
||||
class Marker(BaseModel):
|
||||
"""
|
||||
A traffic-insight marker attached to a link.
|
||||
"""
|
||||
|
||||
bpf: str = Field(..., description="libpcap BPF expression")
|
||||
tag: Optional[int] = Field(None, description="Correlation id shared by markers replayed together")
|
||||
enabled: bool = Field(True, description="Whether the marker is capturing")
|
||||
color: Optional[str] = Field(None, description="Hex color used by the Web UI")
|
||||
highlight_duration: Optional[int] = Field(None, description="Web UI highlight duration in milliseconds")
|
||||
capture_node_id: Optional[str] = Field(None, description="Node whose uBridge hosts the marker")
|
||||
direction: Optional[str] = Field(None, description="'tx' or 'rx', null for both directions")
|
||||
data_link_type: Optional[str] = Field(None, description="pcap link-layer type of the capture file")
|
||||
inherited_from: Optional[str] = Field(None, description="Project marker definition this marker was copied from")
|
||||
|
||||
|
||||
class ProjectMarker(Marker):
|
||||
"""
|
||||
A marker in the project-wide aggregation, with the link and node it belongs to.
|
||||
"""
|
||||
|
||||
link_id: str
|
||||
node_id: Optional[str] = None
|
||||
|
||||
|
||||
class MarkerDefinition(BaseModel):
|
||||
"""
|
||||
A project-level marker definition inherited by every link.
|
||||
"""
|
||||
|
||||
bpf: str = Field(..., description="libpcap BPF expression")
|
||||
tag: Optional[int] = Field(None, description="Correlation id shared by markers replayed together")
|
||||
direction: Optional[str] = Field(None, description="'tx' or 'rx', null for both directions")
|
||||
color: Optional[str] = Field(None, description="Hex color used by the Web UI")
|
||||
highlight_duration: Optional[int] = Field(None, description="Web UI highlight duration in milliseconds")
|
||||
data_link_type: Optional[str] = Field(None, description="pcap link-layer type of inherited markers")
|
||||
paused: bool = Field(False, description="Whether the inherited markers are paused")
|
||||
|
||||
|
||||
class MarkerDefinitionWithLinks(MarkerDefinition):
|
||||
"""
|
||||
A project-level marker definition with the links currently carrying a copy of it.
|
||||
"""
|
||||
|
||||
link_ids: List[str] = Field(..., description="Links carrying an inherited copy of the definition")
|
||||
|
||||
|
||||
class LinkWiresharkRestart(BaseModel):
|
||||
"""
|
||||
Result of restarting the Wireshark window of a link capture.
|
||||
"""
|
||||
|
||||
status: str
|
||||
|
||||
|
||||
class LinkFilterParameter(BaseModel):
|
||||
"""
|
||||
A parameter of a packet filter.
|
||||
"""
|
||||
|
||||
name: str
|
||||
type: str
|
||||
minimum: Optional[int] = None
|
||||
maximum: Optional[int] = None
|
||||
unit: Optional[str] = None
|
||||
|
||||
|
||||
class LinkFilterInfo(BaseModel):
|
||||
"""
|
||||
A packet filter that can be applied to a link.
|
||||
"""
|
||||
|
||||
type: str = Field(..., description="Filter identifier used as key in the link 'filters' property")
|
||||
name: str
|
||||
description: str
|
||||
parameters: List[LinkFilterParameter]
|
||||
@@ -0,0 +1,114 @@
|
||||
#
|
||||
# Copyright (C) 2026 GNS3 Technologies Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import List, Optional
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
|
||||
class ReplaySource(BaseModel):
|
||||
"""
|
||||
A capture source (one marker pcap) of a replay tag.
|
||||
"""
|
||||
|
||||
node_id: str
|
||||
link_id: str
|
||||
marker: str
|
||||
data_link_type: str
|
||||
count: int = Field(..., description="Total frames in the capture, unaffected by filters")
|
||||
|
||||
|
||||
class ReplayFrame(BaseModel):
|
||||
"""
|
||||
One frame of the merged replay timeline.
|
||||
"""
|
||||
|
||||
ts: str = Field(..., description="Timestamp string to send back unchanged")
|
||||
len: int = Field(..., description="Captured length in bytes")
|
||||
node_id: str
|
||||
link_id: str
|
||||
marker: str
|
||||
frame_number: int = Field(..., description="1-based frame number in the source pcap")
|
||||
src: Optional[str] = None
|
||||
dst: Optional[str] = None
|
||||
proto: Optional[str] = None
|
||||
info: Optional[str] = None
|
||||
bg: Optional[str] = Field(None, description="Wireshark coloring rule background")
|
||||
fg: Optional[str] = Field(None, description="Wireshark coloring rule foreground")
|
||||
|
||||
|
||||
class ReplayTimeline(BaseModel):
|
||||
"""
|
||||
Replay timeline of a tag.
|
||||
"""
|
||||
|
||||
tag: int
|
||||
start: Optional[str] = Field(None, description="Timestamp of the first matching frame")
|
||||
end: Optional[str] = Field(None, description="Timestamp of the last matching frame")
|
||||
frame_count: int
|
||||
sources: List[ReplaySource]
|
||||
frames: List[ReplayFrame]
|
||||
|
||||
|
||||
class ReplayFrames(BaseModel):
|
||||
"""
|
||||
Frames of a replay time window.
|
||||
"""
|
||||
|
||||
frames: List[ReplayFrame]
|
||||
|
||||
|
||||
class ReplayFrameSource(BaseModel):
|
||||
"""
|
||||
The source pcap and frame a decoded frame comes from.
|
||||
"""
|
||||
|
||||
node_id: str
|
||||
link_id: str
|
||||
marker: str
|
||||
frame_number: int
|
||||
|
||||
|
||||
class ReplayTreeNode(BaseModel):
|
||||
"""
|
||||
A node of the decoded protocol tree.
|
||||
|
||||
Keys sharkd adds in the future are passed through unchanged.
|
||||
"""
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
element: Optional[str] = Field(None, description="Node type")
|
||||
label: Optional[str] = Field(None, description="Display text")
|
||||
name: Optional[str] = Field(None, description="Field name, e.g. 'ip.ttl'")
|
||||
filter_expr: Optional[str] = Field(None, description="Display filter with the value baked in")
|
||||
pos: Optional[int] = Field(None, description="Byte offset for hex highlighting")
|
||||
size: Optional[int] = Field(None, description="Byte length for hex highlighting")
|
||||
expert: Optional[str] = Field(None, description="Expert severity")
|
||||
generated: Optional[bool] = Field(None, description="Generated by Wireshark")
|
||||
children: Optional[List["ReplayTreeNode"]] = Field(None, description="Nested fields")
|
||||
|
||||
|
||||
class ReplayFrameDetail(BaseModel):
|
||||
"""
|
||||
One decoded frame.
|
||||
"""
|
||||
|
||||
ts: str
|
||||
source: ReplayFrameSource
|
||||
field_count: int
|
||||
hex: str = Field(..., description="Raw frame bytes as hex")
|
||||
tree: List[ReplayTreeNode]
|
||||
@@ -126,3 +126,15 @@ class ProjectCompression(str, Enum):
|
||||
bzip2 = "bzip2"
|
||||
lzma = "lzma"
|
||||
zstd = "zstd"
|
||||
|
||||
|
||||
class ProjectStats(BaseModel):
|
||||
"""
|
||||
Project object counts.
|
||||
"""
|
||||
|
||||
nodes: int
|
||||
links: int
|
||||
drawings: int
|
||||
snapshots: int
|
||||
markers: int
|
||||
@@ -109,3 +109,13 @@ class Role(DateTimeModelMixin, RoleBase):
|
||||
is_builtin: bool
|
||||
privileges: List[Privilege]
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class ACEEndpoint(BaseModel):
|
||||
"""
|
||||
An endpoint that can be used in an ACL entry.
|
||||
"""
|
||||
|
||||
endpoint: str = Field(..., description="Endpoint path to use as the ACE path")
|
||||
name: str = Field(..., description="Human readable name of the endpoint")
|
||||
endpoint_type: str = Field(..., description="Kind of resource the endpoint refers to")
|
||||
@@ -0,0 +1,131 @@
|
||||
#
|
||||
# Copyright (C) 2026 GNS3 Technologies Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Dict, List, Optional, Union
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class ComputeStatistics(BaseModel):
|
||||
"""
|
||||
Resource usage reported by a compute.
|
||||
|
||||
Fields come from the compute itself, so a compute running another build
|
||||
may omit some of them.
|
||||
"""
|
||||
|
||||
memory_total: Optional[int] = None
|
||||
memory_free: Optional[int] = None
|
||||
memory_used: Optional[int] = None
|
||||
swap_total: Optional[int] = None
|
||||
swap_free: Optional[int] = None
|
||||
swap_used: Optional[int] = None
|
||||
cpu_usage_percent: Optional[int] = None
|
||||
cpu_count: Optional[int] = None
|
||||
cpu_count_physical: Optional[int] = None
|
||||
cpu_model: Optional[str] = None
|
||||
memory_usage_percent: Optional[int] = None
|
||||
swap_usage_percent: Optional[int] = None
|
||||
disk_usage_percent: Optional[int] = None
|
||||
disk_total: Optional[int] = None
|
||||
disk_used: Optional[int] = None
|
||||
disk_free: Optional[int] = None
|
||||
load_average: Optional[List[float]] = None
|
||||
load_average_percent: Optional[List[float]] = None
|
||||
|
||||
|
||||
class ComputeStatisticsEntry(BaseModel):
|
||||
"""
|
||||
Statistics of one compute.
|
||||
"""
|
||||
|
||||
compute_id: str
|
||||
compute_name: str
|
||||
statistics: ComputeStatistics
|
||||
|
||||
|
||||
class ProjectCountStatistics(BaseModel):
|
||||
"""
|
||||
Project counts by status.
|
||||
"""
|
||||
|
||||
total: int
|
||||
opened: int
|
||||
closed: int
|
||||
|
||||
|
||||
class NodeStatistics(BaseModel):
|
||||
"""
|
||||
Node counts across all projects.
|
||||
"""
|
||||
|
||||
total: int
|
||||
open_project_nodes: int
|
||||
closed_project_nodes: int
|
||||
by_type: Dict[str, int] = Field(..., description="Node count by node type")
|
||||
by_status: Dict[str, int] = Field(..., description="Node count by status, open projects only")
|
||||
|
||||
|
||||
class LinkStatistics(BaseModel):
|
||||
"""
|
||||
Link counts across all projects.
|
||||
"""
|
||||
|
||||
total: int
|
||||
capturing: int
|
||||
|
||||
|
||||
class WebWiresharkContainer(BaseModel):
|
||||
"""
|
||||
A Web Wireshark container.
|
||||
"""
|
||||
|
||||
project_id: str
|
||||
project_name: str
|
||||
container_id: str
|
||||
status: str
|
||||
running: bool
|
||||
active_sessions: Optional[int] = None
|
||||
memory_limit: Optional[str] = None
|
||||
cpu_limit: Optional[str] = None
|
||||
pids_limit: Optional[Union[int, str]] = Field(None, description="Process limit, or 'unlimited'")
|
||||
memory: Optional[str] = Field(None, description="Current memory usage")
|
||||
cpu: Optional[str] = Field(None, description="Current CPU usage")
|
||||
pids: Optional[int] = Field(None, description="Current process count")
|
||||
|
||||
|
||||
class WebWiresharkStatistics(BaseModel):
|
||||
"""
|
||||
Web Wireshark container statistics across all opened projects.
|
||||
"""
|
||||
|
||||
total_containers: int
|
||||
running_containers: int
|
||||
active_sessions: int
|
||||
containers: List[WebWiresharkContainer]
|
||||
|
||||
|
||||
class ServerStatistics(BaseModel):
|
||||
"""
|
||||
Server statistics.
|
||||
"""
|
||||
|
||||
uptime_seconds: int
|
||||
computes: List[ComputeStatisticsEntry]
|
||||
projects: ProjectCountStatistics
|
||||
nodes: NodeStatistics
|
||||
links: LinkStatistics
|
||||
webwireshark: WebWiresharkStatistics
|
||||
@@ -0,0 +1,37 @@
|
||||
#
|
||||
# Copyright (C) 2026 GNS3 Technologies Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class SymbolInfo(BaseModel):
|
||||
"""
|
||||
A symbol available on the controller.
|
||||
"""
|
||||
|
||||
symbol_id: str
|
||||
filename: str
|
||||
theme: str
|
||||
builtin: bool
|
||||
|
||||
|
||||
class SymbolDimensions(BaseModel):
|
||||
"""
|
||||
Symbol dimensions in pixels.
|
||||
"""
|
||||
|
||||
width: int
|
||||
height: int
|
||||
@@ -15,6 +15,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Optional
|
||||
from uuid import UUID
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
@@ -41,3 +42,30 @@ class ApiKeyCreate(BaseModel):
|
||||
"""Schema for creating a new API key."""
|
||||
|
||||
name: str
|
||||
|
||||
|
||||
class ApiKey(BaseModel):
|
||||
"""API key metadata. The secret is never returned after creation."""
|
||||
|
||||
api_key_id: UUID
|
||||
name: str
|
||||
key_prefix: str
|
||||
created_at: Optional[str] = None
|
||||
last_used_at: Optional[str] = None
|
||||
revoked: bool
|
||||
|
||||
|
||||
class ApiKeyCreated(BaseModel):
|
||||
"""A newly created API key. The full key is returned only once."""
|
||||
|
||||
api_key_id: UUID
|
||||
api_key: str
|
||||
name: str
|
||||
key_prefix: str
|
||||
created_at: Optional[str] = None
|
||||
|
||||
|
||||
class ApiKeyMessage(BaseModel):
|
||||
"""Confirmation message returned when an API key is revoked or restored."""
|
||||
|
||||
message: str
|
||||
Reference in new issue
Block a user