mirror of
https://github.com/GNS3/gns3-server
synced 2024-11-30 20:28:08 +00:00
Update project API
This commit is contained in:
parent
431bd789cb
commit
3ca4edef93
@ -126,6 +126,14 @@ Drawing has been deleted.
|
|||||||
.. literalinclude:: api/notifications/drawing.deleted.json
|
.. literalinclude:: api/notifications/drawing.deleted.json
|
||||||
|
|
||||||
|
|
||||||
|
project.updated
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Project has been updated.
|
||||||
|
|
||||||
|
.. literalinclude:: api/notifications/project.updated.json
|
||||||
|
|
||||||
|
|
||||||
project.closed
|
project.closed
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
@ -278,16 +278,6 @@ class BaseManager:
|
|||||||
if node.id in self._nodes:
|
if node.id in self._nodes:
|
||||||
del self._nodes[node.id]
|
del self._nodes[node.id]
|
||||||
|
|
||||||
@asyncio.coroutine
|
|
||||||
def project_moved(self, project):
|
|
||||||
"""
|
|
||||||
Called when a project is moved
|
|
||||||
|
|
||||||
:param project: project instance
|
|
||||||
"""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def delete_node(self, node_id):
|
def delete_node(self, node_id):
|
||||||
"""
|
"""
|
||||||
|
@ -223,22 +223,6 @@ class Dynamips(BaseManager):
|
|||||||
if project.id in self._dynamips_ids:
|
if project.id in self._dynamips_ids:
|
||||||
del self._dynamips_ids[project.id]
|
del self._dynamips_ids[project.id]
|
||||||
|
|
||||||
@asyncio.coroutine
|
|
||||||
def project_moved(self, project):
|
|
||||||
"""
|
|
||||||
Called when a project is moved.
|
|
||||||
|
|
||||||
:param project: Project instance
|
|
||||||
"""
|
|
||||||
|
|
||||||
for node in self._nodes.values():
|
|
||||||
if node.project.id == project.id:
|
|
||||||
yield from node.hypervisor.set_working_dir(project.module_working_directory(self.module_name.lower()))
|
|
||||||
|
|
||||||
for device in self._devices.values():
|
|
||||||
if device.project.id == project.id:
|
|
||||||
yield from device.hypervisor.set_working_dir(project.module_working_directory(self.module_name.lower()))
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dynamips_path(self):
|
def dynamips_path(self):
|
||||||
"""
|
"""
|
||||||
|
@ -98,6 +98,24 @@ class Project:
|
|||||||
if not os.path.exists(self._topology_file()):
|
if not os.path.exists(self._topology_file()):
|
||||||
self.dump()
|
self.dump()
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def update(self, **kwargs):
|
||||||
|
"""
|
||||||
|
Update the node on the compute server
|
||||||
|
|
||||||
|
:param kwargs: Node properties
|
||||||
|
"""
|
||||||
|
|
||||||
|
old_json = self.__json__()
|
||||||
|
|
||||||
|
for prop in kwargs:
|
||||||
|
setattr(self, prop, kwargs[prop])
|
||||||
|
|
||||||
|
# We send notif only if object has changed
|
||||||
|
if old_json != self.__json__():
|
||||||
|
self.controller.notification.emit("project.updated", self.__json__())
|
||||||
|
self.dump()
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
"""
|
"""
|
||||||
Called when open/close a project. Cleanup internal stuff
|
Called when open/close a project. Cleanup internal stuff
|
||||||
@ -131,6 +149,10 @@ class Project:
|
|||||||
def name(self):
|
def name(self):
|
||||||
return self._name
|
return self._name
|
||||||
|
|
||||||
|
@name.setter
|
||||||
|
def name(self, val):
|
||||||
|
self._name = val
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def id(self):
|
def id(self):
|
||||||
return self._id
|
return self._id
|
||||||
@ -446,7 +468,7 @@ class Project:
|
|||||||
self._cleanPictures()
|
self._cleanPictures()
|
||||||
self._status = "closed"
|
self._status = "closed"
|
||||||
if not ignore_notification:
|
if not ignore_notification:
|
||||||
self.controller.notification.emit("project.closed", self.__json__())
|
self.controller.notification.emit("project.closed", self.__json__())
|
||||||
|
|
||||||
def _cleanPictures(self):
|
def _cleanPictures(self):
|
||||||
"""
|
"""
|
||||||
|
@ -95,32 +95,6 @@ class ProjectHandler:
|
|||||||
project = pm.get_project(request.match_info["project_id"])
|
project = pm.get_project(request.match_info["project_id"])
|
||||||
response.json(project)
|
response.json(project)
|
||||||
|
|
||||||
@Route.put(
|
|
||||||
r"/projects/{project_id}",
|
|
||||||
description="Update a project",
|
|
||||||
parameters={
|
|
||||||
"project_id": "Project UUID",
|
|
||||||
},
|
|
||||||
status_codes={
|
|
||||||
200: "Project updated",
|
|
||||||
403: "Forbidden to update this project",
|
|
||||||
404: "The project doesn't exist"
|
|
||||||
},
|
|
||||||
output=PROJECT_OBJECT_SCHEMA,
|
|
||||||
input=PROJECT_UPDATE_SCHEMA)
|
|
||||||
def update(request, response):
|
|
||||||
|
|
||||||
pm = ProjectManager.instance()
|
|
||||||
project = pm.get_project(request.match_info["project_id"])
|
|
||||||
project.name = request.json.get("name", project.name)
|
|
||||||
project_path = request.json.get("path", project.path)
|
|
||||||
if project_path != project.path:
|
|
||||||
old_path = project.path
|
|
||||||
project.path = project_path
|
|
||||||
for module in MODULES:
|
|
||||||
yield from module.instance().project_moved(project)
|
|
||||||
response.json(project)
|
|
||||||
|
|
||||||
@Route.post(
|
@Route.post(
|
||||||
r"/projects/{project_id}/close",
|
r"/projects/{project_id}/close",
|
||||||
description="Close a project",
|
description="Close a project",
|
||||||
|
@ -30,6 +30,7 @@ from gns3server.config import Config
|
|||||||
|
|
||||||
from gns3server.schemas.project import (
|
from gns3server.schemas.project import (
|
||||||
PROJECT_OBJECT_SCHEMA,
|
PROJECT_OBJECT_SCHEMA,
|
||||||
|
PROJECT_UPDATE_SCHEMA,
|
||||||
PROJECT_LOAD_SCHEMA,
|
PROJECT_LOAD_SCHEMA,
|
||||||
PROJECT_CREATE_SCHEMA
|
PROJECT_CREATE_SCHEMA
|
||||||
)
|
)
|
||||||
@ -83,6 +84,26 @@ class ProjectHandler:
|
|||||||
project = controller.get_project(request.match_info["project_id"])
|
project = controller.get_project(request.match_info["project_id"])
|
||||||
response.json(project)
|
response.json(project)
|
||||||
|
|
||||||
|
@Route.put(
|
||||||
|
r"/projects/{project_id}",
|
||||||
|
status_codes={
|
||||||
|
200: "Node updated",
|
||||||
|
400: "Invalid request",
|
||||||
|
404: "Instance doesn't exist"
|
||||||
|
},
|
||||||
|
description="Update a project instance",
|
||||||
|
input=PROJECT_UPDATE_SCHEMA,
|
||||||
|
output=PROJECT_OBJECT_SCHEMA)
|
||||||
|
def update(request, response):
|
||||||
|
project = Controller.instance().get_project(request.match_info["project_id"])
|
||||||
|
|
||||||
|
# Ignore these because we only use them when creating a project
|
||||||
|
request.json.pop("project_id", None)
|
||||||
|
|
||||||
|
yield from project.update(**request.json)
|
||||||
|
response.set_status(200)
|
||||||
|
response.json(project)
|
||||||
|
|
||||||
@Route.post(
|
@Route.post(
|
||||||
r"/projects/{project_id}/close",
|
r"/projects/{project_id}/close",
|
||||||
description="Close a project",
|
description="Close a project",
|
||||||
|
@ -62,6 +62,16 @@ def test_json(tmpdir):
|
|||||||
assert p.__json__() == {"name": "Test", "project_id": p.id, "path": p.path, "status": "opened", "filename": "Test.gns3"}
|
assert p.__json__() == {"name": "Test", "project_id": p.id, "path": p.path, "status": "opened", "filename": "Test.gns3"}
|
||||||
|
|
||||||
|
|
||||||
|
def test_update(controller, async_run):
|
||||||
|
project = Project(controller=controller, name="Hello")
|
||||||
|
controller._notification = MagicMock()
|
||||||
|
|
||||||
|
assert project.name == "Hello"
|
||||||
|
async_run(project.update(name="World"))
|
||||||
|
assert project.name == "World"
|
||||||
|
controller.notification.emit.assert_any_call("project.updated", project.__json__())
|
||||||
|
|
||||||
|
|
||||||
def test_path(tmpdir):
|
def test_path(tmpdir):
|
||||||
|
|
||||||
directory = Config.instance().get_section_config("Server").get("projects_path")
|
directory = Config.instance().get_section_config("Server").get("projects_path")
|
||||||
|
@ -97,7 +97,6 @@ def test_restore(project, controller, async_run):
|
|||||||
# project.closed notification should not be send when restoring snapshots
|
# project.closed notification should not be send when restoring snapshots
|
||||||
assert "project.closed" not in [c[0][0] for c in controller.notification.emit.call_args_list]
|
assert "project.closed" not in [c[0][0] for c in controller.notification.emit.call_args_list]
|
||||||
|
|
||||||
|
|
||||||
project = controller.get_project(project.id)
|
project = controller.get_project(project.id)
|
||||||
assert not os.path.exists(test_file)
|
assert not os.path.exists(test_file)
|
||||||
assert len(project.nodes) == 1
|
assert len(project.nodes) == 1
|
||||||
|
@ -67,6 +67,18 @@ def test_create_project_with_uuid(http_controller):
|
|||||||
assert response.json["name"] == "test"
|
assert response.json["name"] == "test"
|
||||||
|
|
||||||
|
|
||||||
|
def test_update_project(http_controller):
|
||||||
|
query = {"name": "test", "project_id": "10010203-0405-0607-0809-0a0b0c0d0e0f"}
|
||||||
|
response = http_controller.post("/projects", query)
|
||||||
|
assert response.status == 201
|
||||||
|
assert response.json["project_id"] == "10010203-0405-0607-0809-0a0b0c0d0e0f"
|
||||||
|
assert response.json["name"] == "test"
|
||||||
|
query = {"name": "test2"}
|
||||||
|
response = http_controller.put("/projects/10010203-0405-0607-0809-0a0b0c0d0e0f", query, example=True)
|
||||||
|
assert response.status == 200
|
||||||
|
assert response.json["name"] == "test2"
|
||||||
|
|
||||||
|
|
||||||
def test_list_projects(http_controller, tmpdir):
|
def test_list_projects(http_controller, tmpdir):
|
||||||
http_controller.post("/projects", {"name": "test", "path": str(tmpdir), "project_id": "00010203-0405-0607-0809-0a0b0c0d0e0f"})
|
http_controller.post("/projects", {"name": "test", "path": str(tmpdir), "project_id": "00010203-0405-0607-0809-0a0b0c0d0e0f"})
|
||||||
response = http_controller.get("/projects", example=True)
|
response = http_controller.get("/projects", example=True)
|
||||||
|
Loading…
Reference in New Issue
Block a user