diff --git a/CHANGELOG b/CHANGELOG index 35645177..2268d8f3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,35 @@ # Change Log +## 2.1.1 22/12/2017 + +* Protect variable replacement for Qemu options. Escape double quotes. +* Add proper exception when cannot find tunnel on QEMU, Fixes: #1241 +* Increase timeout for creation of image, Ref. #2239 +* Protect variable replacement for Qemu options. +* Do not overwrites persistent Docker volumes. Fixes #2358. +* Allow users to see an error when the server cannot stream a PCAP file. +* Fix issue with Qemu + SPICE when IPv4 is not enabled. +* Warn users if the GNS3 VM and local server are not in the same subnet. Fixes #1231. +* Add missing appliance files. +* Update appliance files. +* Fix auto idle-pc from preferences. +* Keep consistance of aiohttp.web.HTTPForbidden() execution +* Make sure connected links are removed when a node is deleted. +* Validate idle-pc values for auto idle-pc feature. +* Fix error when updating packet filter on stopped Docker link. Fixes #1229. +* Remotely close telnet console. Ref #2330 +* EthernetSwitch closing connections, Ref: gui/#2330 +* Export files from remote server, Fixes: gui/#2271 +* New option: require KVM. If false, Qemu VMs will not be prevented to run without KVM. +* Implement variable replacement for Qemu VM options. +* Avoid duplicate "-nographic" option. +* Show qemu-img stdout in case of an error. +* Use the correct NVRAM amount when pushing private config to IOU. +* Check and fix corrupt Qemu disk images. Fixes #2301. +* Update warning messages when connecting to non custom adapter for VMware VMs. +* Fix "Can't use VirtualBox VM when an interface is managed by VirtualBox". Fixes #2335. +* Add low disk space warning when creating a new project. + ## 2.1.0 09/11/2017 * Fix typo in vcpus on VirtualBoxVM, fixes: #1213 diff --git a/gns3server/crash_report.py b/gns3server/crash_report.py index a364a184..6598a359 100644 --- a/gns3server/crash_report.py +++ b/gns3server/crash_report.py @@ -57,7 +57,7 @@ class CrashReport: Report crash to a third party service """ - DSN = "sync+https://6ea2fd77178749dea96d725eb4b1b4d1:307d5441e2d7405fa0bd668042392b02@sentry.io/38482" + DSN = "sync+https://ad494b2c01ee40a5b0250d950c815bd2:547cc717c79e4893b5950f6bd835af98@sentry.io/38482" if hasattr(sys, "frozen"): cacert = get_resource("cacert.pem") if cacert is not None and os.path.isfile(cacert): diff --git a/gns3server/handlers/api/controller/drawing_handler.py b/gns3server/handlers/api/controller/drawing_handler.py index 48af0c53..719b2694 100644 --- a/gns3server/handlers/api/controller/drawing_handler.py +++ b/gns3server/handlers/api/controller/drawing_handler.py @@ -61,6 +61,26 @@ class DrawingHandler: response.set_status(201) response.json(drawing) + @Route.get( + r"/projects/{project_id}/drawings/{drawing_id}", + parameters={ + "project_id": "Project UUID", + "drawing_id": "Drawing UUID" + }, + status_codes={ + 200: "Drawing found", + 400: "Invalid request", + 404: "Drawing doesn't exist" + }, + description="Get a drawing instance", + output=DRAWING_OBJECT_SCHEMA) + def get_drawing(request, response): + + project = yield from Controller.instance().get_loaded_project(request.match_info["project_id"]) + drawing = project.get_drawing(request.match_info["drawing_id"]) + response.set_status(200) + response.json(drawing) + @Route.put( r"/projects/{project_id}/drawings/{drawing_id}", parameters={ @@ -71,7 +91,7 @@ class DrawingHandler: 201: "Drawing updated", 400: "Invalid request" }, - description="Create a new drawing instance", + description="Update a drawing instance", input=DRAWING_OBJECT_SCHEMA, output=DRAWING_OBJECT_SCHEMA) def update(request, response): diff --git a/gns3server/handlers/api/controller/link_handler.py b/gns3server/handlers/api/controller/link_handler.py index 96d89cfc..48e394cb 100644 --- a/gns3server/handlers/api/controller/link_handler.py +++ b/gns3server/handlers/api/controller/link_handler.py @@ -97,6 +97,26 @@ class LinkHandler: response.set_status(200) response.json(link.available_filters()) + @Route.get( + r"/projects/{project_id}/links/{link_id}", + parameters={ + "project_id": "Project UUID", + "link_id": "Link UUID" + }, + status_codes={ + 200: "Link found", + 400: "Invalid request", + 404: "Link doesn't exist" + }, + description="Get a link instance", + output=LINK_OBJECT_SCHEMA) + def get_link(request, response): + + project = yield from Controller.instance().get_loaded_project(request.match_info["project_id"]) + link = project.get_link(request.match_info["link_id"]) + response.set_status(200) + response.json(link) + @Route.put( r"/projects/{project_id}/links/{link_id}", parameters={ diff --git a/gns3server/version.py b/gns3server/version.py index f0a58d23..84bef943 100644 --- a/gns3server/version.py +++ b/gns3server/version.py @@ -23,8 +23,8 @@ # or negative for a release candidate or beta (after the base version # number has been incremented) -__version__ = "2.1.1dev2" -__version_info__ = (2, 1, 0, 0) +__version__ = "2.1.2dev1" +__version_info__ = (2, 1, 1, 0) # If it's a git checkout try to add the commit if "dev" in __version__: diff --git a/tests/handlers/api/controller/test_drawing.py b/tests/handlers/api/controller/test_drawing.py index ca5f899b..07070c11 100644 --- a/tests/handlers/api/controller/test_drawing.py +++ b/tests/handlers/api/controller/test_drawing.py @@ -50,6 +50,19 @@ def test_create_drawing(http_controller, tmpdir, project, async_run): assert response.json["drawing_id"] is not None +def test_get_drawing(http_controller, tmpdir, project, async_run): + + response = http_controller.post("/projects/{}/drawings".format(project.id), { + "svg": '', + "x": 10, + "y": 20, + "z": 0 + },) + response = http_controller.get("/projects/{}/drawings/{}".format(project.id, response.json["drawing_id"]), example=True) + assert response.status == 200 + assert response.json["x"] == 10 + + def test_update_drawing(http_controller, tmpdir, project, async_run): response = http_controller.post("/projects/{}/drawings".format(project.id), { diff --git a/tests/handlers/api/controller/test_link.py b/tests/handlers/api/controller/test_link.py index 319e3dc3..7a938d4f 100644 --- a/tests/handlers/api/controller/test_link.py +++ b/tests/handlers/api/controller/test_link.py @@ -128,6 +128,43 @@ def test_create_link_failure(http_controller, tmpdir, project, compute, async_ru assert len(project.links) == 0 +def test_get_link(http_controller, tmpdir, project, compute, async_run): + response = MagicMock() + response.json = {"console": 2048} + compute.post = AsyncioMagicMock(return_value=response) + + node1 = async_run(project.add_node(compute, "node1", None, node_type="qemu")) + node1._ports = [EthernetPort("E0", 0, 0, 3)] + node2 = async_run(project.add_node(compute, "node2", None, node_type="qemu")) + node2._ports = [EthernetPort("E0", 0, 2, 4)] + + with asyncio_patch("gns3server.controller.udp_link.UDPLink.create"): + response = http_controller.post("/projects/{}/links".format(project.id), { + "nodes": [ + { + "node_id": node1.id, + "adapter_number": 0, + "port_number": 3, + "label": { + "text": "Text", + "x": 42, + "y": 0 + } + }, + { + "node_id": node2.id, + "adapter_number": 2, + "port_number": 4 + } + ] + }) + link_id = response.json["link_id"] + assert response.json["nodes"][0]["label"]["x"] == 42 + response = http_controller.get("/projects/{}/links/{}".format(project.id, link_id), example=True) + assert response.status == 200 + assert response.json["nodes"][0]["label"]["x"] == 42 + + def test_update_link_suspend(http_controller, tmpdir, project, compute, async_run): response = MagicMock() response.json = {"console": 2048} @@ -242,7 +279,7 @@ def test_update_link(http_controller, tmpdir, project, compute, async_run): } ], "filters": filters - }) + }, example=True) assert response.status == 201 assert response.json["nodes"][0]["label"]["x"] == 64 assert list(project.links.values())[0].filters == filters