From 0e98497a994c332a2c8ba63b6525e32169267785 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Tue, 17 Feb 2015 14:52:51 +0100 Subject: [PATCH] Add an endpoint for exporting the initial config file --- gns3server/handlers/iou_handler.py | 19 +++++++++++++++++++ gns3server/modules/iou/iou_vm.py | 15 +++++++++++++++ gns3server/schemas/iou.py | 20 ++++++++++++++++++++ tests/api/test_iou.py | 30 ++++++++++++++++++++++++++---- 4 files changed, 80 insertions(+), 4 deletions(-) diff --git a/gns3server/handlers/iou_handler.py b/gns3server/handlers/iou_handler.py index 356b72ce..dc272d04 100644 --- a/gns3server/handlers/iou_handler.py +++ b/gns3server/handlers/iou_handler.py @@ -25,6 +25,7 @@ from ..schemas.iou import IOU_UPDATE_SCHEMA from ..schemas.iou import IOU_OBJECT_SCHEMA from ..schemas.iou import IOU_NIO_SCHEMA from ..schemas.iou import IOU_CAPTURE_SCHEMA +from ..schemas.iou import IOU_INITIAL_CONFIG_SCHEMA from ..modules.iou import IOU @@ -293,3 +294,21 @@ class IOUHandler: port_number = int(request.match_info["port_number"]) yield from vm.stop_capture(adapter_number, port_number) response.set_status(204) + + @Route.get( + r"/projects/{project_id}/iou/vms/{vm_id}/initial_config", + status_codes={ + 200: "Initial config retrieved", + 400: "Invalid request", + 404: "Instance doesn't exist" + }, + output=IOU_INITIAL_CONFIG_SCHEMA, + description="Retrieve the initial config content") + def show_initial_config(request, response): + + iou_manager = IOU.instance() + vm = iou_manager.get_vm(request.match_info["vm_id"], + project_id=request.match_info["project_id"]) + response.set_status(200) + response.json({"content": vm.initial_config, + "path": vm.relative_initial_config_file}) diff --git a/gns3server/modules/iou/iou_vm.py b/gns3server/modules/iou/iou_vm.py index a67a0e13..46e62804 100644 --- a/gns3server/modules/iou/iou_vm.py +++ b/gns3server/modules/iou/iou_vm.py @@ -889,6 +889,21 @@ class IOUVM(BaseVM): else: return None + @property + def relative_initial_config_file(self): + """ + Returns the initial config file relative to the project directory. + It's compatible with pre 1.3 topologies. + + :returns: path to config file. None if the file doesn't exist + """ + + path = os.path.join(self.working_dir, 'initial-config.cfg') + if os.path.exists(path): + return path.replace(self.project.path, "")[1:] + else: + return None + @asyncio.coroutine def start_capture(self, adapter_number, port_number, output_file, data_link_type="DLT_EN10MB"): """ diff --git a/gns3server/schemas/iou.py b/gns3server/schemas/iou.py index 3e7234d2..60ee9a4f 100644 --- a/gns3server/schemas/iou.py +++ b/gns3server/schemas/iou.py @@ -281,3 +281,23 @@ IOU_CAPTURE_SCHEMA = { "additionalProperties": False, "required": ["capture_file_name", "data_link_type"] } + +IOU_INITIAL_CONFIG_SCHEMA = { + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Request validation to get the initial configuration file", + "type": "object", + "properties": { + "content": { + "description": "Content of the initial configuration file", + "type": ["string", "null"], + "minLength": 1, + }, + "path": { + "description": "Relative path on the server of the initial configuration file", + "type": ["string", "null"], + "minLength": 1, + }, + }, + "additionalProperties": False, + "required": ["content", "path"] +} diff --git a/tests/api/test_iou.py b/tests/api/test_iou.py index 1c913592..2fb15060 100644 --- a/tests/api/test_iou.py +++ b/tests/api/test_iou.py @@ -47,7 +47,9 @@ def vm(server, project, base_params): def initial_config_file(project, vm): - return os.path.join(project.path, "project-files", "iou", vm["vm_id"], "initial-config.cfg") + directory = os.path.join(project.path, "project-files", "iou", vm["vm_id"]) + os.makedirs(directory, exist_ok=True) + return os.path.join(directory, "initial-config.cfg") def test_iou_create(server, project, base_params): @@ -208,18 +210,38 @@ def test_iou_start_capture(server, vm, tmpdir): with asyncio_patch("gns3server.modules.iou.iou_vm.IOUVM.start_capture", return_value=True) as mock: params = {"capture_file_name": "test.pcap", "data_link_type": "DLT_EN10MB"} - response = server.post("/projects/{project_id}/iou/vms/{vm_id}/adapters/0/ports/0/start_capture".format(project_id=vm["project_id"], vm_id=vm["vm_id"]), body=params) + response = server.post("/projects/{project_id}/iou/vms/{vm_id}/adapters/0/ports/0/start_capture".format(project_id=vm["project_id"], vm_id=vm["vm_id"]), body=params, example=True) assert mock.called assert response.status == 200 assert "test.pcap" in response.json["pcap_file_path"] -def test_iou_stop_capture(server, vm, tmpdir): +def test_iou_stop_capture(server, vm): with asyncio_patch("gns3server.modules.iou.iou_vm.IOUVM.stop_capture", return_value=True) as mock: - response = server.post("/projects/{project_id}/iou/vms/{vm_id}/adapters/0/ports/0/stop_capture".format(project_id=vm["project_id"], vm_id=vm["vm_id"])) + response = server.post("/projects/{project_id}/iou/vms/{vm_id}/adapters/0/ports/0/stop_capture".format(project_id=vm["project_id"], vm_id=vm["vm_id"]), example=True) assert mock.called assert response.status == 204 + + +def test_get_initial_config_without_config_file(server, vm): + + response = server.get("/projects/{project_id}/iou/vms/{vm_id}/initial_config".format(project_id=vm["project_id"], vm_id=vm["vm_id"]), example=True) + assert response.status == 200 + assert response.json["content"] == None + assert response.json["path"] == None + + +def test_get_initial_config_with_config_file(server, project, vm): + + path = initial_config_file(project, vm) + with open(path, "w+") as f: + f.write("TEST") + + response = server.get("/projects/{project_id}/iou/vms/{vm_id}/initial_config".format(project_id=vm["project_id"], vm_id=vm["vm_id"]), example=True) + assert response.status == 200 + assert response.json["content"] == "TEST" + assert response.json["path"] == "project-files/iou/{vm_id}/initial-config.cfg".format(vm_id=vm["vm_id"])