From e97df86d962a4f4fcfab8ce1c7c0f0a4caa07ac0 Mon Sep 17 00:00:00 2001 From: YueGuobin Date: Sun, 2 Aug 2026 22:32:04 +0800 Subject: [PATCH] marker: fix PUT marker with an enabled-only body (bpf no longer required) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit update_marker reused MarkerCreate, whose bpf is required, so a partial PUT like {"enabled": false} was rejected with 422 "bpf field required". Add a MarkerUpdate schema with every field optional (bpf included; capture_node_id and name are create-only/path-driven and omitted) and use it for the PUT route — partial updates now validate cleanly. --- gns3server/api/routes/controller/links.py | 2 +- gns3server/schemas/__init__.py | 2 +- gns3server/schemas/controller/links.py | 23 +++++++++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/gns3server/api/routes/controller/links.py b/gns3server/api/routes/controller/links.py index 1bddff2d1..522f692cc 100644 --- a/gns3server/api/routes/controller/links.py +++ b/gns3server/api/routes/controller/links.py @@ -497,7 +497,7 @@ async def delete_marker( ) async def update_marker( marker_name: str, - marker_data: schemas.MarkerCreate, + marker_data: schemas.MarkerUpdate, link: Link = Depends(dep_link) ) -> dict: """ diff --git a/gns3server/schemas/__init__.py b/gns3server/schemas/__init__.py index 7c8b9cab2..fc18b73af 100644 --- a/gns3server/schemas/__init__.py +++ b/gns3server/schemas/__init__.py @@ -20,7 +20,7 @@ from .common import ErrorMessage from .version import Version # Controller schemas -from .controller.links import LinkCreate, LinkUpdate, Link, UDPPortInfo, EthernetPortInfo, LinkCapture, MarkerCreate, MarkerDefinitionCreate +from .controller.links import LinkCreate, LinkUpdate, Link, UDPPortInfo, EthernetPortInfo, LinkCapture, MarkerCreate, MarkerUpdate, MarkerDefinitionCreate from .controller.computes import ComputeCreate, ComputeUpdate, ComputeVirtualBoxVM, ComputeVMwareVM, ComputeDockerImage, AutoIdlePC, Compute from .controller.templates import TemplateCreate, TemplateUpdate, TemplateUsage, Template from .controller.images import Image, ImageType diff --git a/gns3server/schemas/controller/links.py b/gns3server/schemas/controller/links.py index 3ec06c5d5..31bdc607a 100644 --- a/gns3server/schemas/controller/links.py +++ b/gns3server/schemas/controller/links.py @@ -191,6 +191,29 @@ class MarkerCreate(BaseModel): ) +class MarkerUpdate(BaseModel): + """ + Body for updating a marker — partial update, every field optional. + + ``bpf`` is optional here (it is required on create). ``capture_node_id`` and + ``name`` are create-only / path-driven and intentionally absent; an explicit + ``direction: null`` clears the direction back to both (omitting keeps it). + """ + + bpf: Optional[str] = None + tag: Optional[int] = None + direction: Optional[str] = Field( + None, + pattern=r"^(tx|rx)$", + description="Direction filter; an explicit null clears it to both. Omit to keep.", + ) + color: Optional[str] = Field(None, description="Hex color render hint, e.g. '#ff5722'") + highlight_duration: Optional[int] = Field( + None, ge=1, description="UI highlight duration in ms; null = UI default" + ) + enabled: Optional[bool] = Field(None, description="Toggle the marker on/off (instant).") + + class MarkerDefinitionCreate(BaseModel): """ Body for creating / updating a project-level marker definition.