diff --git a/gns3server/controller/project.py b/gns3server/controller/project.py index 34ace5ff..0c0093ab 100644 --- a/gns3server/controller/project.py +++ b/gns3server/controller/project.py @@ -567,6 +567,8 @@ class Project: @open_required async def delete_node(self, node_id): node = self.get_node(node_id) + if node.locked: + raise aiohttp.web.HTTPConflict(text="Node {} cannot be deleted because it is locked".format(node.name)) await self.__delete_node_links(node) self.remove_allocated_node_name(node.name) del self._nodes[node.id] diff --git a/gns3server/handlers/api/controller/node_handler.py b/gns3server/handlers/api/controller/node_handler.py index fbd4a41c..db3ae4a6 100644 --- a/gns3server/handlers/api/controller/node_handler.py +++ b/gns3server/handlers/api/controller/node_handler.py @@ -189,7 +189,8 @@ class NodeHandler: status_codes={ 204: "Instance deleted", 400: "Invalid request", - 404: "Instance doesn't exist" + 404: "Instance doesn't exist", + 409: "Cannot delete locked node" }, description="Delete a node instance") async def delete(request, response): diff --git a/tests/controller/test_project.py b/tests/controller/test_project.py index ac4f7256..5fcee71e 100644 --- a/tests/controller/test_project.py +++ b/tests/controller/test_project.py @@ -257,6 +257,25 @@ def test_delete_node(async_run, controller): project.emit_notification.assert_any_call("node.deleted", node.__json__()) +def test_delete_locked_node(async_run, controller): + """ + For a local server we send the project path + """ + compute = MagicMock() + project = Project(controller=controller, name="Test") + project.emit_notification = MagicMock() + + response = MagicMock() + response.json = {"console": 2048} + compute.post = AsyncioMagicMock(return_value=response) + + node = async_run(project.add_node(compute, "test", None, node_type="vpcs", properties={"startup_config": "test.cfg"})) + assert node.id in project._nodes + node.locked = True + with pytest.raises(aiohttp.web_exceptions.HTTPConflict): + async_run(project.delete_node(node.id)) + + def test_delete_node_delete_link(async_run, controller): """ Delete a node delete all the node connected