mirror of
https://github.com/GNS3/gns3-server.git
synced 2025-01-18 07:23:47 +02:00
Create/update project on compute when variables changes
This commit is contained in:
parent
83445214be
commit
7b3d5ae5e3
@ -25,13 +25,13 @@ import zipfile
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
from uuid import UUID, uuid4
|
from uuid import UUID, uuid4
|
||||||
|
|
||||||
from .port_manager import PortManager
|
from .port_manager import PortManager
|
||||||
from .notification_manager import NotificationManager
|
from .notification_manager import NotificationManager
|
||||||
from ..config import Config
|
from ..config import Config
|
||||||
from ..utils.asyncio import wait_run_in_executor
|
from ..utils.asyncio import wait_run_in_executor
|
||||||
from ..utils.path import check_path_allowed, get_default_project_directory
|
from ..utils.path import check_path_allowed, get_default_project_directory
|
||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -297,6 +297,17 @@ class Project:
|
|||||||
yield from node.delete()
|
yield from node.delete()
|
||||||
self._nodes.remove(node)
|
self._nodes.remove(node)
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def update(self, variables=None, **kwargs):
|
||||||
|
original_variables = self.variables
|
||||||
|
self.variables = variables
|
||||||
|
|
||||||
|
# we need to update docker nodes when variables changes
|
||||||
|
if original_variables != variables:
|
||||||
|
for node in self.nodes:
|
||||||
|
if hasattr(node, 'update'):
|
||||||
|
yield from node.update()
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def close(self):
|
def close(self):
|
||||||
"""
|
"""
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
import asyncio
|
||||||
import psutil
|
import psutil
|
||||||
import platform
|
import platform
|
||||||
from .project import Project
|
from .project import Project
|
||||||
@ -95,16 +96,16 @@ class ProjectManager:
|
|||||||
log.warning(message)
|
log.warning(message)
|
||||||
project.emit("log.warning", {"message": message})
|
project.emit("log.warning", {"message": message})
|
||||||
|
|
||||||
def create_project(self, name=None, project_id=None, path=None):
|
def create_project(self, name=None, project_id=None, path=None, variables=None):
|
||||||
"""
|
"""
|
||||||
Create a project and keep a references to it in project manager.
|
Create a project and keep a references to it in project manager.
|
||||||
|
|
||||||
See documentation of Project for arguments
|
See documentation of Project for arguments
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if project_id is not None and project_id in self._projects:
|
if project_id is not None and project_id in self._projects:
|
||||||
return self._projects[project_id]
|
return self._projects[project_id]
|
||||||
project = Project(name=name, project_id=project_id, path=path)
|
project = Project(name=name, project_id=project_id,
|
||||||
|
path=path, variables=variables)
|
||||||
self._check_available_disk_space(project)
|
self._check_available_disk_space(project)
|
||||||
self._projects[project.id] = project
|
self._projects[project.id] = project
|
||||||
return project
|
return project
|
||||||
|
@ -460,11 +460,12 @@ class Compute:
|
|||||||
msg = json.loads(response.data)
|
msg = json.loads(response.data)
|
||||||
action = msg.pop("action")
|
action = msg.pop("action")
|
||||||
event = msg.pop("event")
|
event = msg.pop("event")
|
||||||
|
|
||||||
if action == "ping":
|
if action == "ping":
|
||||||
self._cpu_usage_percent = event["cpu_usage_percent"]
|
self._cpu_usage_percent = event["cpu_usage_percent"]
|
||||||
self._memory_usage_percent = event["memory_usage_percent"]
|
self._memory_usage_percent = event["memory_usage_percent"]
|
||||||
self._controller.notification.emit("compute.updated", self.__json__())
|
self._controller.notification.emit("compute.updated", self.__json__())
|
||||||
|
elif action == 'project.updated':
|
||||||
|
print(event)
|
||||||
else:
|
else:
|
||||||
yield from self._controller.notification.dispatch(action, event, compute_id=self.id)
|
yield from self._controller.notification.dispatch(action, event, compute_id=self.id)
|
||||||
if self._ws:
|
if self._ws:
|
||||||
|
@ -136,6 +136,15 @@ class Project:
|
|||||||
self.controller.notification.emit("project.updated", self.__json__())
|
self.controller.notification.emit("project.updated", self.__json__())
|
||||||
self.dump()
|
self.dump()
|
||||||
|
|
||||||
|
# update on computes
|
||||||
|
for compute in list(self._project_created_on_compute):
|
||||||
|
yield from compute.put(
|
||||||
|
"/projects/{}".format(self._id), {
|
||||||
|
"variables": self.variables
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
"""
|
"""
|
||||||
Called when open/close a project. Cleanup internal stuff
|
Called when open/close a project. Cleanup internal stuff
|
||||||
@ -493,12 +502,14 @@ class Project:
|
|||||||
yield from compute.post("/projects", data={
|
yield from compute.post("/projects", data={
|
||||||
"name": self._name,
|
"name": self._name,
|
||||||
"project_id": self._id,
|
"project_id": self._id,
|
||||||
"path": self._path
|
"path": self._path,
|
||||||
|
"variables": self._variables
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
yield from compute.post("/projects", data={
|
yield from compute.post("/projects", data={
|
||||||
"name": self._name,
|
"name": self._name,
|
||||||
"project_id": self._id,
|
"project_id": self._id,
|
||||||
|
"variables": self._variables
|
||||||
})
|
})
|
||||||
|
|
||||||
self._project_created_on_compute.add(compute)
|
self._project_created_on_compute.add(compute)
|
||||||
|
@ -73,11 +73,31 @@ class ProjectHandler:
|
|||||||
p = pm.create_project(
|
p = pm.create_project(
|
||||||
name=request.json.get("name"),
|
name=request.json.get("name"),
|
||||||
path=request.json.get("path"),
|
path=request.json.get("path"),
|
||||||
project_id=request.json.get("project_id")
|
project_id=request.json.get("project_id"),
|
||||||
|
variables=request.json.get("variables", None)
|
||||||
)
|
)
|
||||||
response.set_status(201)
|
response.set_status(201)
|
||||||
response.json(p)
|
response.json(p)
|
||||||
|
|
||||||
|
@Route.put(
|
||||||
|
r"/projects/{project_id}",
|
||||||
|
description="Update the project on the server",
|
||||||
|
status_codes={
|
||||||
|
201: "Project updated",
|
||||||
|
403: "Forbidden to update a project"
|
||||||
|
},
|
||||||
|
output=PROJECT_OBJECT_SCHEMA,
|
||||||
|
input=PROJECT_UPDATE_SCHEMA)
|
||||||
|
def update_project(request, response):
|
||||||
|
|
||||||
|
pm = ProjectManager.instance()
|
||||||
|
project = pm.get_project(request.match_info["project_id"])
|
||||||
|
yield from project.update(
|
||||||
|
variables=request.json.get("variables", None)
|
||||||
|
)
|
||||||
|
response.set_status(200)
|
||||||
|
response.json(project)
|
||||||
|
|
||||||
@Route.get(
|
@Route.get(
|
||||||
r"/projects/{project_id}",
|
r"/projects/{project_id}",
|
||||||
description="Get project information",
|
description="Get project information",
|
||||||
|
@ -205,3 +205,10 @@ def test_emit(async_run):
|
|||||||
(action, event, context) = async_run(queue.get(0.5))
|
(action, event, context) = async_run(queue.get(0.5))
|
||||||
assert action == "test"
|
assert action == "test"
|
||||||
assert context["project_id"] == project.id
|
assert context["project_id"] == project.id
|
||||||
|
|
||||||
|
|
||||||
|
def test_update_project(loop):
|
||||||
|
variables = [{"name": "TEST", "value": "VAL"}]
|
||||||
|
project = Project(project_id=str(uuid.uuid4()))
|
||||||
|
loop.run_until_complete(asyncio.async(project.update(variables=variables)))
|
||||||
|
assert project.variables == variables
|
||||||
|
@ -85,13 +85,27 @@ def test_json(tmpdir):
|
|||||||
def test_update(controller, async_run):
|
def test_update(controller, async_run):
|
||||||
project = Project(controller=controller, name="Hello")
|
project = Project(controller=controller, name="Hello")
|
||||||
controller._notification = MagicMock()
|
controller._notification = MagicMock()
|
||||||
|
|
||||||
assert project.name == "Hello"
|
assert project.name == "Hello"
|
||||||
async_run(project.update(name="World"))
|
async_run(project.update(name="World"))
|
||||||
assert project.name == "World"
|
assert project.name == "World"
|
||||||
controller.notification.emit.assert_any_call("project.updated", project.__json__())
|
controller.notification.emit.assert_any_call("project.updated", project.__json__())
|
||||||
|
|
||||||
|
|
||||||
|
def test_update_on_compute(controller, async_run):
|
||||||
|
variables = [{"name": "TEST", "value": "VAL1"}]
|
||||||
|
compute = MagicMock()
|
||||||
|
compute.id = "local"
|
||||||
|
project = Project(controller=controller, name="Test")
|
||||||
|
project._project_created_on_compute = [compute]
|
||||||
|
controller._notification = MagicMock()
|
||||||
|
|
||||||
|
async_run(project.update(variables=variables))
|
||||||
|
|
||||||
|
compute.put.assert_any_call('/projects/{}'.format(project.id), {
|
||||||
|
"variables": variables
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
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")
|
||||||
@ -150,7 +164,8 @@ def test_add_node_local(async_run, controller):
|
|||||||
compute.post.assert_any_call('/projects', data={
|
compute.post.assert_any_call('/projects', data={
|
||||||
"name": project._name,
|
"name": project._name,
|
||||||
"project_id": project._id,
|
"project_id": project._id,
|
||||||
"path": project._path
|
"path": project._path,
|
||||||
|
"variables": None
|
||||||
})
|
})
|
||||||
compute.post.assert_any_call('/projects/{}/vpcs/nodes'.format(project.id),
|
compute.post.assert_any_call('/projects/{}/vpcs/nodes'.format(project.id),
|
||||||
data={'node_id': node.id,
|
data={'node_id': node.id,
|
||||||
@ -178,7 +193,8 @@ def test_add_node_non_local(async_run, controller):
|
|||||||
|
|
||||||
compute.post.assert_any_call('/projects', data={
|
compute.post.assert_any_call('/projects', data={
|
||||||
"name": project._name,
|
"name": project._name,
|
||||||
"project_id": project._id
|
"project_id": project._id,
|
||||||
|
"variables": None
|
||||||
})
|
})
|
||||||
compute.post.assert_any_call('/projects/{}/vpcs/nodes'.format(project.id),
|
compute.post.assert_any_call('/projects/{}/vpcs/nodes'.format(project.id),
|
||||||
data={'node_id': node.id,
|
data={'node_id': node.id,
|
||||||
@ -218,7 +234,8 @@ def test_add_node_from_appliance(async_run, controller):
|
|||||||
compute.post.assert_any_call('/projects', data={
|
compute.post.assert_any_call('/projects', data={
|
||||||
"name": project._name,
|
"name": project._name,
|
||||||
"project_id": project._id,
|
"project_id": project._id,
|
||||||
"path": project._path
|
"path": project._path,
|
||||||
|
"variables": None
|
||||||
})
|
})
|
||||||
compute.post.assert_any_call('/projects/{}/vpcs/nodes'.format(project.id),
|
compute.post.assert_any_call('/projects/{}/vpcs/nodes'.format(project.id),
|
||||||
data={'node_id': node.id,
|
data={'node_id': node.id,
|
||||||
|
@ -53,6 +53,8 @@ def test_project_to_topology_empty(tmpdir):
|
|||||||
"drawings": []
|
"drawings": []
|
||||||
},
|
},
|
||||||
"type": "topology",
|
"type": "topology",
|
||||||
|
"supplier": None,
|
||||||
|
"variables": None,
|
||||||
"version": __version__
|
"version": __version__
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +91,23 @@ def test_delete_project(http_compute, project):
|
|||||||
assert mock.called
|
assert mock.called
|
||||||
|
|
||||||
|
|
||||||
|
def test_update_project(http_compute):
|
||||||
|
query = {"name": "test", "project_id": "51010203-0405-0607-0809-0a0b0c0d0e0f"}
|
||||||
|
response = http_compute.post("/projects", query)
|
||||||
|
assert response.status == 201
|
||||||
|
|
||||||
|
query = {
|
||||||
|
"variables": [{"name": "TEST1", "value": "VAL1"}]
|
||||||
|
}
|
||||||
|
response = http_compute.put(
|
||||||
|
"/projects/{project_id}".format(project_id="51010203-0405-0607-0809-0a0b0c0d0e0f"),
|
||||||
|
query,
|
||||||
|
example=True
|
||||||
|
)
|
||||||
|
assert response.status == 200
|
||||||
|
assert response.json["variables"] == [{"name": "TEST1", "value": "VAL1"}]
|
||||||
|
|
||||||
|
|
||||||
def test_delete_project_invalid_uuid(http_compute):
|
def test_delete_project_invalid_uuid(http_compute):
|
||||||
response = http_compute.delete("/projects/{project_id}".format(project_id=uuid.uuid4()))
|
response = http_compute.delete("/projects/{project_id}".format(project_id=uuid.uuid4()))
|
||||||
assert response.status == 404
|
assert response.status == 404
|
||||||
|
Loading…
Reference in New Issue
Block a user