diff --git a/gns3server/controller/compute.py b/gns3server/controller/compute.py index e727c0e4..05154fd3 100644 --- a/gns3server/controller/compute.py +++ b/gns3server/controller/compute.py @@ -477,6 +477,10 @@ class Compute: host = "127.0.0.1" return "{}://{}:{}/v2/compute{}".format(self._protocol, host, self._port, path) + def get_url(self, path): + """ Returns URL for specific path at Compute""" + return self._getUrl(path) + @asyncio.coroutine def _run_http_query(self, method, path, data=None, timeout=20, raw=False): with Timeout(timeout): diff --git a/gns3server/handlers/api/controller/compute_handler.py b/gns3server/handlers/api/controller/compute_handler.py index 2091cc63..46c50689 100644 --- a/gns3server/handlers/api/controller/compute_handler.py +++ b/gns3server/handlers/api/controller/compute_handler.py @@ -21,7 +21,8 @@ from gns3server.controller import Controller from gns3server.schemas.compute import ( COMPUTE_CREATE_SCHEMA, COMPUTE_OBJECT_SCHEMA, - COMPUTE_UPDATE_SCHEMA + COMPUTE_UPDATE_SCHEMA, + COMPUTE_ENDPOINT_OUTPUT_OBJECT_SCHEMA ) import logging @@ -93,6 +94,33 @@ class ComputeHandler: res = yield from compute.images(request.match_info["emulator"]) response.json(res) + @Route.get( + r"/computes/endpoint/{compute_id}/{emulator}/{action:.+}", + parameters={ + "compute_id": "Compute UUID" + }, + status_codes={ + 200: "OK", + 404: "Instance doesn't exist" + }, + raw=True, + output=COMPUTE_ENDPOINT_OUTPUT_OBJECT_SCHEMA, + description="Returns the endpoint for particular `compute` to specific action.") + def endpoint(request, response): + controller = Controller.instance() + compute = controller.get_compute(request.match_info["compute_id"]) + + path = '/{emulator}/{action}'.format( + emulator=request.match_info['emulator'], + action=request.match_info['action']) + + endpoint = compute.get_url(path) + + response.set_status(200) + response.json(dict( + endpoint=endpoint + )) + @Route.get( r"/computes/{compute_id}/{emulator}/{action:.+}", parameters={ diff --git a/gns3server/schemas/compute.py b/gns3server/schemas/compute.py index 8e44de50..2e8d08bc 100644 --- a/gns3server/schemas/compute.py +++ b/gns3server/schemas/compute.py @@ -109,3 +109,17 @@ COMPUTE_OBJECT_SCHEMA = { "additionalProperties": False, "required": ["compute_id", "protocol", "host", "port", "name"] } + +COMPUTE_ENDPOINT_OUTPUT_OBJECT_SCHEMA = { + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Output schema for obtaining endpoint on compute", + "type": "object", + "properties": { + "endpoint": { + "description": "URL to endpoint on specific compute and to particular action", + "type": "string" + }, + }, + "additionalProperties": False, +} + diff --git a/tests/controller/test_compute.py b/tests/controller/test_compute.py index 8d5f16ab..b39ff9ad 100644 --- a/tests/controller/test_compute.py +++ b/tests/controller/test_compute.py @@ -55,6 +55,13 @@ def test_getUrl(controller): assert compute._getUrl("/test") == "https://[::1]:84/v2/compute/test" +def test_get_url(controller): + compute = Compute("my_compute_id", protocol="https", host="localhost", port=84, controller=controller) + with patch('gns3server.controller.compute.Compute._getUrl', return_value="returned") as getURL: + assert compute.get_url("/test") == 'returned' + getURL.assert_called_once_with('/test') + + def test_host_ip(controller): compute = Compute("my_compute_id", protocol="https", host="localhost", port=84, controller=controller) assert compute.host_ip == "127.0.0.1" diff --git a/tests/handlers/api/controller/test_compute.py b/tests/handlers/api/controller/test_compute.py index 275d6102..04427627 100644 --- a/tests/handlers/api/controller/test_compute.py +++ b/tests/handlers/api/controller/test_compute.py @@ -240,4 +240,19 @@ def test_compute_autoidlepc(http_controller, controller): assert response.status == 200 +def test_compute_endpoint(http_controller, controller): + params = { + "compute_id": "my_compute", + "protocol": "http", + "host": "localhost", + "port": 84, + "user": "julien", + "password": "secure" + } + response = http_controller.post("/computes", params) + assert response.status == 201 + + response = http_controller.get("/computes/endpoint/my_compute/virtualbox/images") + assert response.status == 200 + assert response.json['endpoint'] == 'http://localhost:84/v2/compute/virtualbox/images'