Deleting a template with prune_images, deleting an image, or pruning
orphan images only checked template references — a project node still
pointing at the image (e.g. via hda_disk_image_backing_file) was left
with a dangling reference and the project could no longer be opened.
- Add controller helpers scanning every known project (opened projects
via in-memory nodes, closed projects via their .gns3 file) for
template and image usage; unreadable topologies are skipped
- Guard DELETE /templates/{id}, DELETE /templates/{id}?prune_images,
DELETE /images/{path} and /images/prune with a 409 listing the
project names
- Run all template-delete checks before any mutation so a refused
deletion cannot leave the template gone while its images survive
- Use `default=str` in `json.dumps` to handle non-serializable objects
- Return proper HTTP 304 response with ETag header instead of raising exception
- Ensure consistent ETag generation for template caching
- Add optional `tags` query parameter to `/nodes` and `/templates` endpoints
- Support filtering by tags in format "key:value" with multiple tags ANDed together
- Example: `?tags=vendor:cisco&tags=model:7200` filters nodes/templates with both tags
- Maintain backward compatibility for existing API usage without tags parameter