4998 Commits

Author SHA1 Message Date
YueGuobin
2efcc619b1
perf: batch RBAC permission checking for GET /projects
Replace per-project check_user_has_privilege calls with a single
batch method that performs 3 fixed DB queries regardless of project
count. Reduces GET /projects response time for 10000 projects from
~12s to ~290ms (40x improvement).
2026-05-27 13:27:35 +08:00
YueGuobin
1eca8c5c94
fix: prevent duplicate projects when user projects are in resource pools
Fixed a bug where projects created by a user that are also in a resource pool
the user has access to would appear twice in the GET /projects response.

Changes:
- Add seen_project_ids set to track already added projects
- Check for duplicates before adding projects in Step 2 (user projects)
- Check for duplicates before adding projects in Step 3 (resource pool projects)

This ensures each project appears only once regardless of whether it's user-created
or shared via resource pool.
2026-05-27 10:47:36 +08:00
YueGuobin
ca5db7567c
fix: check both regular ACEs and resource pool ACEs for proper access control
This fix addresses a critical issue in the RBAC permission checking logic
introduced in PR #2750. When a project is shared through a resource pool,
both the project creator (with regular ACEs like "All endpoints") and the
shared user (with resource pool ACEs) should be able to see the project.

Changes:
- Modified `check_user_has_privilege` in `gns3server/db/repositories/rbac.py`
- Changed from if-elif (exclusive) to sequential (inclusive) checking
- Now checks regular ACEs first, then resource pool ACEs
- Both types of ACEs can grant access (OR logic instead of XOR)

This fixes the scenario where:
1. user100 has "All endpoints" ACE and creates a project
2. user100 shares the project via resource pool with user200
3. Both users should see the project (user100 via regular ACE, user200 via pool ACE)

Related to PR #2750 - RBAC user isolation implementation.
2026-05-27 00:17:52 +08:00
YueGuobin
2062136d12
feat: add alembic migration for LLMConfig privileges
Add migration to insert LLMConfig.Audit, LLMConfig.Modify, LLMConfig.Allocate
privileges into existing databases and associate LLMConfig.Audit/Modify
with the default User role.
2026-05-26 14:28:54 +08:00
YueGuobin
9fca2181a8
feat: add independent LLMConfig permissions for AI profile management
Add new privilege definitions:
- LLMConfig.Audit - View LLM model configurations
- LLMConfig.Modify - Update LLM model configurations
- LLMConfig.Allocate - Create/delete LLM model configurations

Add LLMConfig.Audit and LLMConfig.Modify to default User role so that
regular users can manage their own AI profiles without needing the
User.Manager role.

User-scoped LLM config endpoints now use LLMConfig.* permissions.
Group-scoped LLM config endpoints retain Group.* permissions.
2026-05-26 14:24:41 +08:00
YueGuobin
f7a69bd546
feat: remove resource pools from 'all endpoints' list
Remove resource pools from the ACE endpoints list to prevent accidental
access through the 'all endpoints' option. Resource pools must be
explicitly configured for team sharing to maintain clear security
boundaries and prevent unintended exposure of shared projects.

This change aligns the UI behavior with the actual permission checking
logic where 'path: /' does not grant resource pool access.
2026-05-26 13:31:04 +08:00
YueGuobin
5e4d9e057e
refactor: add efficient get_aces_for_path method for resource pool checks
Add a new repository method get_aces_for_path() that:
- Queries ACEs for a specific path at database level (more efficient)
- Preloads related user, group, and role objects to prevent 500 errors
- Keeps original get_aces() method unchanged to avoid performance impact

This improves both performance and code clarity for resource pool
deletion safety checks.
2026-05-26 12:59:37 +08:00
YueGuobin
6fcbb8e57b
feat: prevent deletion of resource pools used by ACE configurations
Add safety check to prevent deletion of resource pools that are being
used by ACE configurations. If an attempt is made to delete a resource
pool that has ACE rules referencing it, the API returns a 400 error
with detailed information showing which users/groups are using the
pool and their roles.

The error message only shows the resource pool name for a clean,
user-friendly experience without exposing internal path details.
2026-05-26 12:54:48 +08:00
YueGuobin
ee36a9aec2
feat: fix permission check logic to properly handle ACE and user isolation
Implement the correct three-step permission check logic:
- Step 1: ACE check - basic access permission (get projects user has ACE for)
- Step 2: Filter ace_projects by created_by - user's own projects (project sharing only through resource pools)
- Step 3: Resource pool projects (projects shared through resource pools)

This fixes the design flaw where:
- ACE check could bypass user isolation with broad ACE configurations
- seen_project_ids mechanism prevented proper layered checking
- Project sharing was confused with direct ACE configuration

The new logic ensures:
- User isolation works even with broad ACE (path='/', propagate=True)
- Project sharing is only available through resource pools (clear design)
- Proper layered checking without seen blocking mechanism
2026-05-26 12:33:08 +08:00
YueGuobin
265d0ff860
feat: implement layered permission checks for proper user isolation and sharing
Implement a three-layer permission system:
- Layer 1: ACE strategy check (explicitly authorized/shared projects)
- Layer 2: Ownership check (user's own projects based on created_by)
- Layer 3: Resource pools (team shared projects)

This approach:
- Resolves the conflict between ACE and user isolation
- Enables project sharing via ACE (other users can grant access)
- Maintains default user isolation via ownership
- Prevents duplicate projects in results
- Preserves resource pool functionality
2026-05-26 00:31:19 +08:00
YueGuobin
7c0b465b74
feat: implement simple user isolation based on project ownership
Users can only see projects they created (created_by field).
Super admins see all projects.
Resource pool projects continue to work as before.
2026-05-26 00:16:45 +08:00
YueGuobin
045db5bdd8
fix: clean BPF syntax error message and specify loopback interface
- Add -i lo to tshark command to avoid "(null)" interface in errors
- Strip "for interface" suffix from error message for cleaner output
2026-05-24 23:00:41 +08:00
YueGuobin
ce58e9adc8
feat: add BPF syntax validation using tshark
- Add _validate_bpf_syntax() method to validate BPF expressions
- Use tshark with 1-second timeout for syntax checking
- Check for "Invalid" in output to detect syntax errors
- Validate BPF filters before applying them to links
- Handle tshark not installed scenario gracefully
- Support both single and multiple BPF expressions
- Return detailed error messages for syntax validation failures
2026-05-24 22:49:59 +08:00
YueGuobin
e71931d096
feat: add show_filters_icon parameter to packet filter tool
- Add show_filters_icon parameter with default value False
- Pass show_filters_icon to link.update() in set and clear operations
- Update tool description to explain default behavior
- Remove "clear" action from description to simplify interface
- Hide filter icon in GNS3 Web UI by default for cleaner UI during fault injection
2026-05-24 22:46:52 +08:00
YueGuobin
8ba1f064d2
feat: add packet filter management tool for GNS3-Copilot fault injection
Add comprehensive packet filter management functionality to GNS3-Copilot,
enabling AI-powered fault injection scenarios with network simulation
capabilities like latency, packet loss, and corruption.

## Changes

### New Features
- **GNS3PacketFilterTool**: New LangChain tool for managing packet filters
  on GNS3 links with support for delay, packet loss, corruption,
  frequency_drop, and BPF filtering
  - Actions: get_available, set, get, clear
  - Integrated into troubleshooting_injection mode for fault scenarios

### API Integration
- **Link.available_filters()**: Added method to custom_gns3fy.py Link class
  - Queries available filter types for specific links
  - API v3+ only (raises ValueError for v2 connectors)
  - Returns filter definitions with parameters and constraints

### Tool Integration
- Added GNS3PacketFilterTool to TROUBLESHOOTING_INJECTION_MODE_TOOLS
- Positioned as 3rd tool in fault injection workflow
- Optimized for troubleshooting practice scenarios

## Files Modified
- gns3server/agent/gns3_copilot/agent/gns3_copilot.py
- gns3server/agent/gns3_copilot/gns3_client/custom_gns3fy.py
- gns3server/agent/gns3_copilot/tools_v2/__init__.py

## Files Added
- gns3server/agent/gns3_copilot/tools_v2/gns3_packet_filter.py

## Testing
- All validation tests passed
- Version checking verified (v3+ only)
- Tool integration confirmed in troubleshooting mode
2026-05-24 22:31:28 +08:00
YueGuobin
31d8046e30
fix: add getattr fallback to show_filters_icon property for backward compatibility 2026-05-23 17:09:50 +08:00
YueGuobin
a1f4942746
feat: add show_filters_icon property to Link for controlling Web UI filter icon display
This commit adds a new  property to the Link class, allowing users to control whether filter icons are displayed in the Web UI at the individual link level.

**Changes:**
- Added  attribute to Link class (default: True)
- Added  property getter
- Added  method for updating the property
- Updated  to include the new field with backward compatibility
- Added  field to LinkBase schema using Optional[bool] = Field(True, ...) pattern
- Updated API routes to handle the new field in create and update operations
- Added loading logic for show_filters_icon in project.open() to preserve settings when reopening projects

**Schema Definition:**
Uses the same pattern as the  field:

**API Impact:**
- POST /v3/projects/{project_id}/links - accepts  in request body
- PUT /v3/projects/{project_id}/links/{link_id} - can update
- GET /v3/projects/{project_id}/links/{link_id} - returns  field

**Future Applications:**
This feature provides granular control for future AI fault injection modules to manage link-level protocol failures while maintaining clean UI presentation.
2026-05-23 16:57:39 +08:00
YueGuobin
367c565d7c
fix: ensure show_filters_icon is always returned in API responses
Set default value for show_filters_icon in LinkBase schema to ensure the field is always included in API responses, even when response_model_exclude_unset=True is used.
2026-05-23 15:21:44 +08:00
YueGuobin
aa6845b32b
feat: add show_filters_icon property to Link for controlling Web UI filter icon display
This commit adds a new `show_filters_icon` property to the Link class, allowing users to control whether filter icons are displayed in the Web UI at the individual link level.

**Changes:**
- Added `_show_filters_icon` attribute to Link class (default: True)
- Added `show_filters_icon` property getter
- Added `update_show_filters_icon()` method for updating the property
- Updated `asdict()` to include the new field in both topology and regular dumps
- Added `show_filters_icon` field to LinkBase schema
- Updated API routes to handle the new field in create and update operations

**API Impact:**
- POST /v3/projects/{project_id}/links - accepts `show_filters_icon` in request body
- PUT /v3/projects/{project_id}/links/{link_id} - can update `show_filters_icon`
- GET /v3/projects/{project_id}/links/{link_id} - returns `show_filters_icon` field

**Future Applications:**
This feature provides granular control for future AI fault injection modules to manage link-level protocol failures while maintaining clean UI presentation.
2026-05-23 14:57:58 +08:00
Guobin Yue
11fe3a24cf
Merge branch '3.0' into fix/unclosed-client-session-websocket-proxy 2026-05-19 00:02:26 +08:00
YueGuobin
868e317d24
fix: close DockerHTTPClient session to prevent UnixConnector leak in Web Wireshark
The Web Wireshark WebSocket endpoint created a WebWiresharkManager but
never called close(), leaving the DockerHTTPClient's ClientSession with
UnixConnector unclosed when users closed the browser tab.

Also switch asyncio.wait in WebSocket proxy from ALL_COMPLETED to
FIRST_COMPLETED to avoid blocking cleanup when one direction disconnects.
2026-05-18 23:59:56 +08:00
grossmj
7cf25bc0d5
Release v3.1.0a2 2026-05-13 00:34:05 +08:00
grossmj
7bb0a2a863
Bundle web-ui v3.1.0a2 2026-05-13 00:29:25 +08:00
grossmj
748b8a1571
Sync appliances 2026-05-13 00:25:27 +08:00
YueGuobin
30a140a9e3
fix: surface tshark stderr errors to LLM, not just log them 2026-05-12 15:10:27 +08:00
YueGuobin
b79fea918d
fix: hint LLM about -c behavior when tshark returns empty with -c 2026-05-12 14:54:50 +08:00
YueGuobin
09b0fbcfea
fix: update search_fields examples to use existing field names 2026-05-12 14:48:37 +08:00
YueGuobin
73e0de7706
fix: reject multi-keyword search_fields, single keyword only 2026-05-12 14:47:00 +08:00
YueGuobin
c357d52fbf
fix: document action/query params in PacketAnalysisTool description 2026-05-12 14:36:21 +08:00
YueGuobin
2a34d0ef58
feat: add search_fields action to PacketAnalysisTool for real-time field lookup 2026-05-12 14:33:13 +08:00
YueGuobin
32c3b4cd35
feat: validate tshark -e field names before running analysis 2026-05-12 14:27:16 +08:00
YueGuobin
9c23f9037c
fix: document -c behavior caveat in PacketAnalysisTool description 2026-05-12 14:00:58 +08:00
YueGuobin
b7a0b611df
fix: demote loader-level load logs to DEBUG, info already reported by manager
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 13:52:05 +08:00
YueGuobin
89da58fe1b
fix: promote skills/prompts load logs to INFO level
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 13:46:36 +08:00
YueGuobin
c5af9ce389
fix: load packet analysis protocols during skills initialization
- Add reload_packet_analysis_protocols() call in _ensure_skills_manager()
- PACKET_ANALYSIS_REGISTRY was empty because it was never loaded
2026-05-12 13:41:52 +08:00
YueGuobin
67b3b778b8
feat: add PacketAnalysisSkillsTool
- Register packet_analysis_skills as a LangChain tool for LLM
- LLM can query protocol field definitions before calling packet_analysis
- Follows the same pattern as DeviceSkillsTool and InjectionSkillsTool
2026-05-12 13:37:59 +08:00
YueGuobin
2a38816d3d
fix: remove remaining quoted example from tool input docstring 2026-05-12 13:30:18 +08:00
YueGuobin
b991125c6c
fix: use shlex.split for tshark_args parsing
- Replace str.split() with shlex.split() to handle quoted arguments
- LLM may pass args with or without quotes, both work correctly now
2026-05-12 13:29:31 +08:00
YueGuobin
e0c2d64b7c
feat: add packet analysis workflow to tool description
- Update PacketAnalysisTool.description with step-by-step workflow
- Instruct LLM to query packet_analysis skills first, then construct tshark_args
2026-05-12 13:13:24 +08:00
YueGuobin
2c5cfdbee8
refactor: remove old PacketCaptureTool, replaced by PacketAnalysisTool
- Delete packet_capture_tools.py (analyze_packets with packet_number)
- PacketAnalysisTool is more flexible and can do everything the old tool could
- Update tool registration to use only PacketAnalysisTool
- Cleaner, more unified packet analysis interface
2026-05-12 10:19:25 +08:00
YueGuobin
84b9742045
feat: add protocol-oriented packet analysis tool
- Add PacketAnalysisTool that accepts user-provided tshark arguments
- LLM constructs tshark commands based on protocol knowledge from skills
- Add PACKET_ANALYSIS_REGISTRY for protocol definitions
- Add load_packet_analysis_protocols() to SkillsLoader
- Add get_packet_analysis_protocol() and list functions to registry
- Register PacketAnalysisTool in teaching and lab automation modes
- Update SkillsManager to reload packet analysis protocols

Related: GNS3-Skills commit 7bc45d2
2026-05-12 09:59:10 +08:00
YueGuobin
a408148073
feat: require superadmin for /reload/skills endpoint
Only administrators can reload skills from the external repository.
Non-admin users receive 403 Forbidden.
2026-05-11 22:59:28 +08:00
YueGuobin
ae1a444677
fix: remove background init timeout and allow skills reload retry
- Remove 5s thread.join() timeout so git clone/pull is not truncated
- Remove _init_complete flag, reset _init_in_progress on failure instead
- Let /reload/skills API retry initialization after network failure
- Raise GIT_HTTP_LOW_SPEED_LIMIT from 1 KB/s to 10 KB/s

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 22:51:57 +08:00
YueGuobin
e68cc17ed5
feat: add fault injection system and external skills repository
## Summary

Add a complete fault injection system for GNS3 Copilot, migrate all
skills from local Python files to an external Git repository with
hot reload support, and restructure Copilot API under /copilot/.

## Key Changes

### Fault Injection
- New troubleshooting_injection mode with InjectionSkillsTool
- 368 fault scenarios across 39 protocol categories
- Context-based filtering (LLM must pass topology protocols)

### External Skills Repository
- SkillsManager: Git clone/pull, version tracking, smart updates
- SkillsLoader: YAML skills + Markdown prompts from external repo
- Hot reload via POST /copilot/reload/skills
- Configurable via gns3_server.conf

### Architecture
- API unified under /copilot/ prefix
- SkillsManager moved from Controller to agent module
- Lazy initialization with startup background preload
- Per-command Git timeout, smart update checks
- Forbidden commands hot-reloadable from external repo
- 32 INFO logs downgraded to DEBUG
2026-05-11 01:24:55 +08:00
YueGuobin
156072118f
fix: Disable DeepSeek thinking mode to avoid reasoning_content errors
DeepSeek models (deepseek-v4-flash/pro) enable thinking mode by default,
which returns reasoning_content that must be passed back to the API in
subsequent requests. This causes 400 errors in multi-turn conversations
when the reasoning_content is not properly handled.

This commit disables thinking mode by passing extra_body={"thinking": {"type": "disabled"}}
as an explicit parameter to DeepSeek models, preventing the reasoning_content
field from being generated.

Modified:
- create_base_model(): Add extra_body parameter with thinking mode disabled
- create_title_model(): Add extra_body parameter with thinking mode disabled

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 22:31:50 +08:00
grossmj
97bf94e06e
Merge branch '2.2' into 3.0
# Conflicts:
#	CHANGELOG
#	gns3server/compute/iou/iou_vm.py
#	gns3server/crash_report.py
#	gns3server/utils/asyncio/telnet_server.py
#	gns3server/version.py
#	requirements.txt
#	setup.py
2026-05-09 18:23:00 +08:00
YueGuobin
5c7018283f
fix: Skip offline compute nodes during project import
When importing a project, the round-robin logic would attempt to distribute
nodes across all configured compute resources, including offline ones. This
caused import failures when any remote compute was unreachable.

This fix filters the compute list to only include connected computes before
round-robin distribution. If no remote computes are connected, all nodes
are assigned to the local compute.

This matches the approach used in project._get_disconnected_computes() and
prevents the issue where importing a project fails with:
"Cannot connect to compute 'X' with request POST /projects"

Fixes issue introduced in commit 90e3a8d6 (2017) which added round-robin
load balancing without considering offline compute nodes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 13:46:58 +08:00
YueGuobin
b4220d55c6
fix: Import status module in project.py
Fix F821 undefined name 'status' error by importing the status
module from fastapi. This resolves build errors when using
status.HTTP_403_FORBIDDEN and status.HTTP_404_NOT_FOUND.
2026-05-08 23:58:43 +08:00
Guobin Yue
cd732ab4b5
Merge branch '3.0' into feature/list-node-files-api 2026-05-08 23:51:56 +08:00
YueGuobin
3752b2bac8
fix: Handle connection errors when stopping node console
Add exception handling in stop_wrap_console to gracefully handle
ConnectionResetError, BrokenPipeError, and OSError when waiting
for console writer to close.

This prevents 500 errors when stopping QEMU nodes if the console
connection is reset before the writer finishes closing.

Fixes race condition where QEMU process exits and closes connections
before the console writer cleanup completes.
2026-05-08 23:30:41 +08:00