diff --git a/gns3server/compute/base_node.py b/gns3server/compute/base_node.py index fe771b2b..c5f60cfd 100644 --- a/gns3server/compute/base_node.py +++ b/gns3server/compute/base_node.py @@ -247,6 +247,13 @@ class BaseNode: raise NotImplementedError + def suspend(self): + """ + Suspends the node process. + """ + + raise NotImplementedError + @asyncio.coroutine def close(self): """ diff --git a/gns3server/handlers/api/controller/node_handler.py b/gns3server/handlers/api/controller/node_handler.py index da438204..9f1cdbf9 100644 --- a/gns3server/handlers/api/controller/node_handler.py +++ b/gns3server/handlers/api/controller/node_handler.py @@ -88,6 +88,84 @@ class NodeHandler: response.set_status(200) response.json(node) + @Route.post( + r"/projects/{project_id}/nodes/start", + parameters={ + "project_id": "Project UUID" + }, + status_codes={ + 204: "All nodes successfully started", + 400: "Invalid request", + 404: "Instance doesn't exist" + }, + description="Start all nodes belonging to the project", + output=NODE_OBJECT_SCHEMA) + def start_all(request, response): + + project = Controller.instance().get_project(request.match_info["project_id"]) + for node in project.nodes.values(): + yield from node.start() + response.set_status(204) + + @Route.post( + r"/projects/{project_id}/nodes/stop", + parameters={ + "project_id": "Project UUID" + }, + status_codes={ + 204: "All nodes successfully stopped", + 400: "Invalid request", + 404: "Instance doesn't exist" + }, + description="Stop all nodes belonging to the project", + output=NODE_OBJECT_SCHEMA) + def stop_all(request, response): + + project = Controller.instance().get_project(request.match_info["project_id"]) + for node in project.nodes.values(): + yield from node.stop() + response.set_status(204) + + @Route.post( + r"/projects/{project_id}/nodes/suspend", + parameters={ + "project_id": "Project UUID" + }, + status_codes={ + 204: "All nodes successfully suspended", + 400: "Invalid request", + 404: "Instance doesn't exist" + }, + description="Suspend all nodes belonging to the project", + output=NODE_OBJECT_SCHEMA) + def suspend_all(request, response): + + project = Controller.instance().get_project(request.match_info["project_id"]) + for node in project.nodes.values(): + yield from node.suspend() + response.set_status(204) + + @Route.post( + r"/projects/{project_id}/nodes/reload", + parameters={ + "project_id": "Project UUID" + }, + status_codes={ + 204: "All nodes successfully reloaded", + 400: "Invalid request", + 404: "Instance doesn't exist" + }, + description="Reload all nodes belonging to the project", + output=NODE_OBJECT_SCHEMA) + def reload_all(request, response): + + project = Controller.instance().get_project(request.match_info["project_id"]) + for node in project.nodes.values(): + yield from node.stop() + for node in project.nodes.values(): + yield from node.start() + response.set_status(204) + @Route.post( r"/projects/{project_id}/nodes/{node_id}/start", parameters={ diff --git a/tests/handlers/api/controller/test_node.py b/tests/handlers/api/controller/test_node.py index 12f941af..1f0e7b87 100644 --- a/tests/handlers/api/controller/test_node.py +++ b/tests/handlers/api/controller/test_node.py @@ -107,6 +107,33 @@ def test_update_node(http_controller, tmpdir, project, compute, node): assert response.json["name"] == "test" assert "name" not in response.json["properties"] +def test_start_all_nodes(http_controller, tmpdir, project, compute): + response = MagicMock() + compute.post = AsyncioMagicMock() + + response = http_controller.post("/projects/{}/nodes/start".format(project.id), example=True) + assert response.status == 204 + +def test_stop_all_nodes(http_controller, tmpdir, project, compute): + response = MagicMock() + compute.post = AsyncioMagicMock() + + response = http_controller.post("/projects/{}/nodes/stop".format(project.id), example=True) + assert response.status == 204 + +def test_suspend_all_nodes(http_controller, tmpdir, project, compute): + response = MagicMock() + compute.post = AsyncioMagicMock() + + response = http_controller.post("/projects/{}/nodes/suspend".format(project.id), example=True) + assert response.status == 204 + +def test_reload_all_nodes(http_controller, tmpdir, project, compute): + response = MagicMock() + compute.post = AsyncioMagicMock() + + response = http_controller.post("/projects/{}/nodes/reload".format(project.id), example=True) + assert response.status == 204 def test_start_node(http_controller, tmpdir, project, compute, node): response = MagicMock()