From c4d619ce3c0b7c948d4685347e6a064da62c3a1e Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Wed, 15 Jun 2016 16:43:03 +0200 Subject: [PATCH] API for loading a project from a .gns3 --- .../api/controller/project_handler.py | 32 +++++++++++++++++-- gns3server/schemas/project.py | 15 +++++++++ tests/handlers/api/controller/test_project.py | 11 ++++++- 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/gns3server/handlers/api/controller/project_handler.py b/gns3server/handlers/api/controller/project_handler.py index 31626ae7..5e69b4f3 100644 --- a/gns3server/handlers/api/controller/project_handler.py +++ b/gns3server/handlers/api/controller/project_handler.py @@ -21,9 +21,12 @@ import asyncio from gns3server.web.route import Route from gns3server.controller import Controller +from gns3server.config import Config + from gns3server.schemas.project import ( PROJECT_OBJECT_SCHEMA, + PROJECT_LOAD_SCHEMA, PROJECT_CREATE_SCHEMA ) @@ -85,7 +88,8 @@ class ProjectHandler: status_codes={ 204: "The project has been closed", 404: "The project doesn't exist" - }) + }, + output=PROJECT_OBJECT_SCHEMA) def close(request, response): controller = Controller.instance() @@ -103,7 +107,8 @@ class ProjectHandler: status_codes={ 201: "The project has been opened", 404: "The project doesn't exist" - }) + }, + output=PROJECT_OBJECT_SCHEMA) def open(request, response): controller = Controller.instance() @@ -112,6 +117,29 @@ class ProjectHandler: response.set_status(201) response.json(project) + @Route.post( + r"/projects/load", + description="Open a project (only local server)", + parameters={ + "path": ".gns3 path", + }, + status_codes={ + 201: "The project has been opened", + 403: "The server is not the local server" + }, + input=PROJECT_LOAD_SCHEMA, + output=PROJECT_OBJECT_SCHEMA) + def load(request, response): + + controller = Controller.instance() + config = Config.instance() + if config.get_section_config("Server").getboolean("local", False) is False: + response.set_status(403) + return + project = yield from controller.load_project(request.json.get("path"),) + response.set_status(201) + response.json(project) + @Route.delete( r"/projects/{project_id}", description="Delete a project from disk", diff --git a/gns3server/schemas/project.py b/gns3server/schemas/project.py index 9988d453..7e80ff41 100644 --- a/gns3server/schemas/project.py +++ b/gns3server/schemas/project.py @@ -91,6 +91,21 @@ PROJECT_OBJECT_SCHEMA = { "required": ["project_id"] } +PROJECT_LOAD_SCHEMA = { + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Load a project", + "type": "object", + "properties": { + "path": { + "description": ".gns3 path", + "type": "string", + "minLength": 1 + } + }, + "additionalProperties": False, + "required": ["path"] +} + PROJECT_LIST_SCHEMA = { "$schema": "http://json-schema.org/draft-04/schema#", "description": "List of projects", diff --git a/tests/handlers/api/controller/test_project.py b/tests/handlers/api/controller/test_project.py index 1d431f5c..b1e17aa0 100644 --- a/tests/handlers/api/controller/test_project.py +++ b/tests/handlers/api/controller/test_project.py @@ -100,13 +100,22 @@ def test_close_project(http_controller, project): assert mock.called -def test_close_project(http_controller, project): +def test_open_project(http_controller, project): with asyncio_patch("gns3server.controller.project.Project.open", return_value=True) as mock: response = http_controller.post("/projects/{project_id}/open".format(project_id=project.id), example=True) assert response.status == 201 assert mock.called +def test_load_project(http_controller, project, config): + config.set("Server", "local", "true") + with asyncio_patch("gns3server.controller.Controller.load_project", return_value=project) as mock: + response = http_controller.post("/projects/load".format(project_id=project.id), {"path": "/tmp/test.gns3"}, example=True) + assert response.status == 201 + mock.assert_called_with("/tmp/test.gns3") + assert response.json["project_id"] == project.id + + def test_notification(http_controller, project, controller, loop): @asyncio.coroutine def go(future):