From 06b54d82dcda02f2e4943875d84f3ce3fbce7f80 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Mon, 6 Jun 2016 15:45:32 +0200 Subject: [PATCH] Support forwarding POST request to compute nodes --- gns3server/controller/compute.py | 4 ++-- .../api/controller/compute_handler.py | 20 ++++++++++++++-- tests/controller/test_compute.py | 12 ++++++++-- tests/handlers/api/controller/test_compute.py | 23 +++++++++++++++++-- 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/gns3server/controller/compute.py b/gns3server/controller/compute.py index 744876069..61830a408 100644 --- a/gns3server/controller/compute.py +++ b/gns3server/controller/compute.py @@ -324,9 +324,9 @@ class Compute: return (yield from self.http_query("DELETE", path, **kwargs)) @asyncio.coroutine - def forward(self, type, path): + def forward(self, method, type, path, data=None): """ Forward a call to the emulator on compute """ - res = yield from self.get("/{}/{}".format(type, path)) + res = yield from self.http_query(method, "/{}/{}".format(type, path), data=data) return res.json diff --git a/gns3server/handlers/api/controller/compute_handler.py b/gns3server/handlers/api/controller/compute_handler.py index 83a6197e4..3745612d0 100644 --- a/gns3server/handlers/api/controller/compute_handler.py +++ b/gns3server/handlers/api/controller/compute_handler.py @@ -87,10 +87,26 @@ class ComputeHandler: 404: "Instance doesn't exist" }, description="Forward call specific to compute node. Read the full compute API for available actions") - def forward(request, response): + def get_forward(request, response): controller = Controller.instance() compute = controller.get_compute(request.match_info["compute_id"]) - images = yield from compute.forward(request.match_info["emulator"], request.match_info["action"]) + images = yield from compute.forward("GET", request.match_info["emulator"], request.match_info["action"]) + response.json(images) + + @Route.post( + r"/computes/{compute_id}/{emulator}/{action}", + parameters={ + "compute_id": "Compute UUID" + }, + status_codes={ + 200: "OK", + 404: "Instance doesn't exist" + }, + description="Forward call specific to compute node. Read the full compute API for available actions") + def post_forward(request, response): + controller = Controller.instance() + compute = controller.get_compute(request.match_info["compute_id"]) + images = yield from compute.forward("POST", request.match_info["emulator"], request.match_info["action"], data=dict(request.json)) response.json(images) @Route.get( diff --git a/tests/controller/test_compute.py b/tests/controller/test_compute.py index efef050be..da055281f 100644 --- a/tests/controller/test_compute.py +++ b/tests/controller/test_compute.py @@ -223,9 +223,17 @@ def test_update(compute, controller, async_run): assert compute.connected is False -def test_forward(compute, async_run): +def test_forward_get(compute, async_run): response = MagicMock() response.status = 200 with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock: - async_run(compute.forward("qemu", "images")) + async_run(compute.forward("GET", "qemu", "images")) mock.assert_called_with("GET", "https://example.com:84/v2/compute/qemu/images", auth=None, data=None, headers={'content-type': 'application/json'}) + + +def test_forward_post(compute, async_run): + response = MagicMock() + response.status = 200 + with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock: + async_run(compute.forward("POST", "qemu", "img", data={"id": 42})) + mock.assert_called_with("POST", "https://example.com:84/v2/compute/qemu/img", auth=None, data='{"id": 42}', headers={'content-type': 'application/json'}) diff --git a/tests/handlers/api/controller/test_compute.py b/tests/handlers/api/controller/test_compute.py index 882051237..37d9c8f2f 100644 --- a/tests/handlers/api/controller/test_compute.py +++ b/tests/handlers/api/controller/test_compute.py @@ -171,7 +171,7 @@ def test_compute_list_images(http_controller, controller): with asyncio_patch("gns3server.controller.compute.Compute.forward", return_value=[]) as mock: response = http_controller.get("/computes/my_compute/qemu/images") assert response.json == [] - mock.assert_called_with("qemu", "images") + mock.assert_called_with("GET", "qemu", "images") def test_compute_list_vms(http_controller, controller): @@ -190,4 +190,23 @@ def test_compute_list_vms(http_controller, controller): with asyncio_patch("gns3server.controller.compute.Compute.forward", return_value=[]) as mock: response = http_controller.get("/computes/my_compute/virtualbox/vms") assert response.json == [] - mock.assert_called_with("virtualbox", "vms") + mock.assert_called_with("GET", "virtualbox", "vms") + + +def test_compute_create_img(http_controller, controller): + + params = { + "compute_id": "my_compute", + "protocol": "http", + "host": "example.com", + "port": 84, + "user": "julien", + "password": "secure" + } + response = http_controller.post("/computes", params) + assert response.status == 201 + + params = {"path": "/test"} + with asyncio_patch("gns3server.controller.compute.Compute.forward", return_value=[]) as mock: + response = http_controller.post("/computes/my_compute/qemu/img", params) + mock.assert_called_with("POST", "qemu", "img", data={"path": "/test"})