157 Commits

Author SHA1 Message Date
Jeremy Grossmann
0a78a2bf12
Merge pull request #2961 from markparonyan/api-issue-13-bfbm9z
feat(api): add Notification schema and document notification streams
2026-10-08 04:11:14 +02:00
Mark Paronyan
11a310dd9b
feat(api): type link filters and available_filters response 2026-10-07 15:48:52 +03:00
Mark Paronyan
86a279330d
feat(api): add Notification schema and document notification streams 2026-10-07 15:14:50 +03:00
Jeremy Grossmann
f184883aa7
Merge branch '3.1' into images-nested-folders-support 2026-10-06 16:50:40 +02:00
Jeremy Grossmann
e2161fb66c
Merge branch '3.1' into fix-api 2026-10-06 16:12:18 +02:00
Mark Paronyan
d9678ce98c
refactor: derive update schemas with PartialUpdateModel 2026-10-06 16:46:22 +03:00
Mark Paronyan
b8e552ee9d
refactor: ruff fixes 2026-10-05 21:05:24 +03:00
Cristi
207db770c6 feat(image-manager): Add support for nested image folders and appliance compatibility checks 2026-10-05 18:49:21 +03:00
Mark Paronyan
be52a0d0d4
refactor: discriminate appliance settings by template_type 2026-10-05 15:00:35 +03:00
Mark Paronyan
306d8fbde4
refactor: remove unused imports 2026-10-03 19:43:58 +03:00
Mark Paronyan
b78672a8ca style: sort imports in the new image management modules 2026-10-02 12:43:26 +03:00
Mark Paronyan
3b993b464f style: sort imports in schemas 2026-10-02 12:43:26 +03:00
Jeremy Grossmann
a2cdc14a25
Merge branch '3.1' into image-manager-out-of-sync 2026-10-01 14:44:24 +02:00
Jeremy Grossmann
e90be1ebac
Merge pull request #2930 from markparonyan/mypy-db-templates-images
fix(typing): resolve the remaining mypy errors (18 modules)
2026-09-29 21:37:14 +02:00
Mark Paronyan
0954723ebd
fix(typing): resolve mypy errors in schemas.controller.computes 2026-09-29 22:02:22 +03:00
Mark Paronyan
a3cb73da3d
fix(typing): resolve mypy errors in api.routes.controller.dependencies.authentication 2026-09-29 21:48:33 +03:00
Jeremy Grossmann
1838ad7f05
Merge branch '3.1' into mypy-schemas-plus 2026-09-29 13:41:11 +02:00
Jeremy Grossmann
eace280c5f
Merge branch '3.1' into mypy-schemas 2026-09-29 13:40:00 +02:00
Mark Paronyan
79862d900a
fix(typing): resolve mypy errors in schemas.controller.templates.vmware_templates 2026-09-29 09:23:14 +03:00
Mark Paronyan
3abed40707
fix(typing): resolve mypy errors in schemas.controller.templates.docker_templates 2026-09-29 09:23:13 +03:00
Mark Paronyan
edaf9a4377
fix(typing): resolve mypy errors in schemas.controller.templates.virtualbox_templates 2026-09-29 09:23:13 +03:00
Mark Paronyan
94a0f462bf
fix(typing): resolve mypy errors in schemas.controller.templates.iou_templates 2026-09-29 09:23:13 +03:00
Mark Paronyan
07dc9b4d7d
fix(typing): resolve mypy errors in schemas.controller.settings 2026-09-29 09:23:12 +03:00
Mark Paronyan
01dd09495c
fix(typing): resolve mypy errors in schemas.controller.projects 2026-09-29 09:23:12 +03:00
Mark Paronyan
a68e57dd2e
fix(typing): resolve mypy errors in schemas.controller.nodes 2026-09-29 09:23:12 +03:00
Mark Paronyan
7439e91f5a
fix(typing): resolve mypy errors in schemas.controller.appliances 2026-09-29 09:23:12 +03:00
Mark Paronyan
68d96193ec
fix(typing): resolve mypy errors in api.routes.controller.groups 2026-09-29 09:23:07 +03:00
Cristi
42d30651da Merge origin/3.1 into image-manager-out-of-sync
Preserve image reconciliation, locking, and regression coverage while integrating upstream release, dependency, typing, and formatting updates. Align feature code with the new Ruff checks.
2026-09-28 23:16:24 +03:00
Mark Paronyan
6f3e5cfc2b
fix(typing): resolve mypy errors in schemas.controller.templates.dynamips_templates 2026-09-28 21:47:56 +03:00
Cristi
046dff4d08 fix(images): reconcile the image inventory with filesystem changes 2026-09-28 16:01:36 +03:00
Mark Paronyan
a0450b6bce
refactor: ruff autofixes 2026-09-27 15:55:10 +03:00
Cristi
59a367b88d Allow projects containing missing images to open in a degraded state instead of failing to load 2026-09-18 15:06:17 +03:00
YueGuobin
b7dbf45a90
docs: add field descriptions to the settings schemas
Document all 70 configuration fields with pydantic Field
descriptions, ported from the config sample comments and verified
against the actual consumers (allow_remote_console and local had
no documentation anywhere). The descriptions flow into the
OpenAPI schema of GET /v3/settings, giving the Web UI tooltips,
defaults and validation bounds from a single source. Response
models re-declare six path fields as plain strings, which drops
the inherited description — restore them explicitly.

Sync the config sample: document local and allow_remote_console,
drop hardware_virtualization_check which no longer exists in the
schema.
2026-08-24 00:35:26 +08:00
YueGuobin
e0962a59ed
feat: add GET/PUT /v3/settings server settings API
GET returns all settings sections except the deprecated
VirtualBox/VMware ones (Server.Audit privilege); secrets are
masked and Controller.jwt_secret_key is excluded entirely.
PUT applies a partial update (Server.Modify privilege): masked
or empty secrets mean unchanged, null removes the option, the
response carries the new values plus restart_required, and a
settings.updated notification is emitted. New
Server.Audit/Server.Modify privileges are seeded into the
Administrator role at table creation.
2026-08-23 18:54:31 +08:00
YueGuobin
7e8c515a3c
api: expose installed netmiko device types for the web UI
New GET /v3/netmiko/device_types endpoint returns the device types
supported by the netmiko library installed on the server, including
the gns3-copilot custom drivers, so the web UI can populate the
netmiko_device_type dropdown on templates and nodes.

The list is read at runtime from netmiko's ssh_dispatcher.CLASS_MAPPER
registry (the same table ConnectHandler dispatches on), filtered to
drop the '_ssh' aliases and the 'autodetect' pseudo type, and cached
for the process lifetime. Returns 501 when netmiko is not installed
(ai-features extra).
2026-08-21 21:41:42 +08:00
YueGuobin
92d4e3d378
nodes: per-node default credentials seeded from the template
Add default_username/default_password as controller-only node properties
(the netmiko_device_type pattern): they are not sent to the compute,
persist with the project topology and can be updated or cleared per
node. Creating a node from a template seeds them from the template
appliance metadata, and the metadata itself is dropped there so it
never leaks into the node properties.
2026-08-21 21:41:42 +08:00
YueGuobin
300c53e6fb
templates: persist appliance metadata on install
Appliance fields that describe the appliance (vendor information, default
credentials, installation instructions...) were dropped when installing a
template. Keep them in a new appliance_metadata JSON column on the
templates table, filled by the appliance-to-template conversion for both
registry v1-6 and v8 (version level values override the appliance level
ones). The nested schema allows extra fields so future registry fields
persist without a migration.
2026-08-21 21:41:42 +08:00
YueGuobin
1c68a52856
fix: address appliance v8 install review findings
- install: resolve the image directory from the version's settings type and
  skip image handling for docker appliances; guard appliance.images
- appliance schema: validate template_properties against template_type,
  align cpu_throttling with the qemu template, add kvm and version idlepc
- conversion: map IOU image to path, kvm disable to accel=tcg, inherit only
  same-type default settings, symbol fallback from the effective category,
  template_properties cannot override structural fields
- allow clearing netmiko_device_type with an empty string
- download the template symbol regardless of the level it is defined at and
  give qemu guests a default symbol
2026-08-21 21:41:42 +08:00
YueGuobin
f524e9a713
appliance: seed netmiko_device_type from the appliance file
Both the v1-6 and v8 appliance models accept an optional top-level
netmiko_device_type, and ApplianceToTemplate copies it into the created
template so installed appliances carry the automation hint end to end.
2026-08-21 21:41:35 +08:00
YueGuobin
d64f47afa4
nodes: per-node netmiko_device_type (controller-only)
netmiko_device_type follows the CONTROLLER_ONLY_PROPERTIES pattern
(like console_auto_start): a node created from a template inherits the
template value, PUT /nodes can override it inside a topology, updates
never round-trip to the compute, and the value persists in the project
topology file.
2026-08-21 21:41:35 +08:00
YueGuobin
9260108f53
templates: add netmiko_device_type for automation tools
Common template field (schema + templates table column + Alembic
migration) holding the Netmiko device type (e.g. 'cisco_xr', 'nokia_srl')
so Netmiko/Nornir based tooling can look up how to reach a node's CLI
without hard-coded vendor mappings. Free-form lowercase string on
purpose: Netmiko's platform list evolves independently of GNS3.
2026-08-21 21:41:35 +08:00
YueGuobin
254721dbda
appliance: close the v8 gaps for Docker vendor appliances
DockerPropertiesV8 now accepts custom_adapters (already available to
v1-6 top-level appliances and to Qemu v8 properties), so port-named
Docker appliances (XRd, SR Linux) can move to the v8 format without
losing their interface naming.

Appliance.type resolves the node type from the v8 settings template_type
(default set first) instead of misclassifying every v8 appliance as
qemu, and _get_default_symbol applies the docker guest symbol to v8
Docker guest appliances.
2026-08-21 21:41:35 +08:00
YueGuobin
08e37a4509
docker: inject config files into containers via extra_configs
Add an `extra_configs` field (list of {target, content}) to the docker
node/template/appliance schemas. For each entry GNS3 writes `content` to a
file in the node working directory and bind-mounts it read-only at `target`
inside the container.

This lets a NOS appliance seed its startup config without rebuilding the
image: XRd points XR_FIRST_BOOT_CONFIG at an injected /firstboot.cfg, FRR at
/etc/frr/frr.conf, etc. The bind is a single-file mount applied at create
time, so it works for both the generic init.sh path and vendor nodes that
skip init.sh (console_type=docker_exec). Entries are only injected when
present, so ordinary nodes are unaffected.

The content can't go through `environment` (it is line-delimited, one var per
line), hence a dedicated field -- the same plumbing shape as extra_volumes.
2026-08-13 23:33:34 +08:00
YueGuobin
9e830f7883
appliance: expose custom_adapters on the v1-6 appliance model
The top-level ApplianceV1_6 model declared first_port_name /
port_name_format / port_segment_size but not custom_adapters, so the
GET /appliances endpoint (response_model=schemas.Appliance) stripped
custom_adapters from the response — the frontend never saw per-adapter
port names even though the appliance file and the server-side template
conversion (appliance_to_template reads it from the raw dict) handled it.

Add custom_adapters: Optional[List[CustomAdapterItem]] to ApplianceV1_6
so the field round-trips through the API. (ApplianceV8 already models it
inside its TemplateSetting.)
2026-08-13 02:05:17 +08:00
YueGuobin
141b3d8701
appliance: accept docker_exec console type in Docker appliances
The Docker appliance Pydantic model (DockerConsoleType) rejected
console_type='docker_exec', so an appliance file using the vendor NOS
docker_exec console could not be loaded (validation error at import).
Add docker_exec to the enum — it is already a valid ConsoleType
(schemas/common.py) and is handled by VendorDockerVM.
2026-08-13 02:05:17 +08:00
YueGuobin
3322233658
marker: serial-link (WAN) support via data_link_type -> uBridge linktype
Markers now work on serial links (Cisco HDLC / PPP / Frame Relay / ATM), not just Ethernet. A marker carries a data_link_type (default DLT_EN10MB); at the uBridge boundary it becomes the 'mark ... linktype <dlt>' keyword so the BPF compiles and the pcap is written with the matching link-layer.

- MarkerCreate / MarkerDefinitionCreate gain data_link_type (default DLT_EN10MB). Per-link it is create-only; definitions are updatable (a change re-fans-out).
- base_node._marker_linktype() normalizes the GNS3 DLT name (strip DLT_, uppercase, None for EN10MB). Single source is SerialPort.data_link_types, so Cisco PPP -> PPP_SERIAL (50), matching the capture path -- no second mapping table.
- _ubridge_add_marker_filter (generic) and the IOU marker loop append 'linktype <dlt>'.
- Definition fan-out branches on link_type in inherit_marker: Ethernet is always EN10MB; a serial link uses the definition's WAN encapsulation, or is SKIPPED when none was chosen (an EN10MB pcap on serial is undecodable). One definition covers a mixed topology.
- MCP marker_definition exposes data_link_type (None = not forwarded).
- No uBridge rebuild on a data_link_type change -- only that one marker's filter is swapped (delete + re-add), mirroring a BPF change; reset_packet_filters preserves sibling mark filters.

Requires the uBridge build with 'mark ... linktype' support.
2026-08-07 01:53:33 +08:00
YueGuobin
f7b19dae99
marker: tighten marker name max length from 128 to 32
128 characters was far beyond any realistic marker label (icmp, arp, tcp-syn)
and would have collided with the pcap filename budget once a tag prefix is
added later. Cap the user-facing name at 32 in both MarkerCreate and
MarkerDefinitionCreate; the compute-side name guard now also rejects names
longer than 48, which covers the `global-{def_name}` inherited form (≤ 39).
2026-08-05 00:49:37 +08:00
YueGuobin
9323ea4cec
schema: accept direction='both' in marker schemas, normalize to None 2026-08-03 00:31:45 +08:00
YueGuobin
e97df86d96
marker: fix PUT marker with an enabled-only body (bpf no longer required)
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.
2026-08-02 22:32:04 +08:00
YueGuobin
71fa778d50
marker: let callers pin the capture node via capture_node_id
A marker is single-sided — only the chosen capture node's uBridge installs the
mark filter — and dir=tx|rx is interpreted from that node's perspective. Until
now the observer was always auto-picked (_choose_marker_side), so dir=tx meant
"the auto-chosen endpoint is sending", which is unpredictable and makes the
direction filter hard to render meaningfully in the Web UI.

Add an optional create-only capture_node_id to MarkerCreate: when set, the
marker is pinned to that endpoint's uBridge (validated as a link endpoint and a
marker-capable type); when omitted, behavior is unchanged (auto-pick). The
chosen id is already echoed back as capture_node_id and in MARK signals, so the
UI can always render the observer regardless of who picked it.

capture_node_id is create-only (changing it would silently flip the meaning of
stored direction; recreate instead) and is not accepted on project-level
definitions — they are link-agnostic and have no endpoints, so inherited
markers keep auto-picking per link.

Plumbed through REST create_marker, the MCP link_marker tool, and base
Link.start_marker. update_marker does not forward it.
2026-08-01 22:24:47 +08:00