mirror of
https://github.com/GNS3/gns3-server
synced 2024-11-12 19:38:57 +00:00
parent
00f80f54e8
commit
672a617102
@ -628,9 +628,11 @@ class Router(BaseNode):
|
||||
"""
|
||||
|
||||
is_running = yield from self.is_running()
|
||||
was_auto_started = False
|
||||
if not is_running:
|
||||
# router is not running
|
||||
raise DynamipsError('Router "{name}" is not running'.format(name=self._name))
|
||||
yield from self.start()
|
||||
was_auto_started = True
|
||||
yield from asyncio.sleep(20) # leave time to the router to boot
|
||||
|
||||
log.info('Router "{name}" [{id}] has started calculating Idle-PC values'.format(name=self._name, id=self._id))
|
||||
begin = time.time()
|
||||
@ -638,6 +640,8 @@ class Router(BaseNode):
|
||||
log.info('Router "{name}" [{id}] has finished calculating Idle-PC values after {time:.4f} seconds'.format(name=self._name,
|
||||
id=self._id,
|
||||
time=time.time() - begin))
|
||||
if was_auto_started:
|
||||
yield from self.stop()
|
||||
return idlepcs
|
||||
|
||||
@asyncio.coroutine
|
||||
|
@ -157,12 +157,12 @@ class Compute:
|
||||
return response.content
|
||||
|
||||
@asyncio.coroutine
|
||||
def http_query(self, method, path, data=None):
|
||||
def http_query(self, method, path, data=None, **kwargs):
|
||||
if not self._connected:
|
||||
yield from self._connect()
|
||||
if not self._connected:
|
||||
raise aiohttp.web.HTTPConflict(text="The server {} is not a GNS3 server".format(self._id))
|
||||
response = yield from self._run_http_query(method, path, data=data)
|
||||
response = yield from self._run_http_query(method, path, data=data, **kwargs)
|
||||
return response
|
||||
|
||||
@asyncio.coroutine
|
||||
@ -202,8 +202,8 @@ class Compute:
|
||||
return "{}://{}:{}/v2/compute{}".format(self._protocol, self._host, self._port, path)
|
||||
|
||||
@asyncio.coroutine
|
||||
def _run_http_query(self, method, path, data=None):
|
||||
with aiohttp.Timeout(10):
|
||||
def _run_http_query(self, method, path, data=None, timeout=10):
|
||||
with aiohttp.Timeout(timeout):
|
||||
url = self._getUrl(path)
|
||||
headers = {'content-type': 'application/json'}
|
||||
if data == {}:
|
||||
@ -243,19 +243,19 @@ class Compute:
|
||||
return response
|
||||
|
||||
@asyncio.coroutine
|
||||
def get(self, path):
|
||||
return (yield from self.http_query("GET", path))
|
||||
def get(self, path, **kwargs):
|
||||
return (yield from self.http_query("GET", path, **kwargs))
|
||||
|
||||
@asyncio.coroutine
|
||||
def post(self, path, data={}):
|
||||
response = yield from self.http_query("POST", path, data)
|
||||
def post(self, path, data={}, **kwargs):
|
||||
response = yield from self.http_query("POST", path, data, **kwargs)
|
||||
return response
|
||||
|
||||
@asyncio.coroutine
|
||||
def put(self, path, data={}):
|
||||
response = yield from self.http_query("PUT", path, data)
|
||||
def put(self, path, data={}, **kwargs):
|
||||
response = yield from self.http_query("PUT", path, data, **kwargs)
|
||||
return response
|
||||
|
||||
@asyncio.coroutine
|
||||
def delete(self, path):
|
||||
return (yield from self.http_query("DELETE", path))
|
||||
def delete(self, path, **kwargs):
|
||||
return (yield from self.http_query("DELETE", path, **kwargs))
|
||||
|
@ -147,7 +147,7 @@ class Node:
|
||||
self._console_type = value
|
||||
elif key == "name":
|
||||
self._name = value
|
||||
elif key in ["node_id", "project_id"]:
|
||||
elif key in ["node_id", "project_id", "console_host"]:
|
||||
pass
|
||||
else:
|
||||
self._properties[key] = value
|
||||
@ -166,7 +166,7 @@ class Node:
|
||||
|
||||
# None properties are not be send. Because it can mean the emulator doesn't support it
|
||||
for key in list(data.keys()):
|
||||
if data[key] is None:
|
||||
if data[key] is None or key in ["console_host"]:
|
||||
del data[key]
|
||||
return data
|
||||
|
||||
@ -236,6 +236,20 @@ class Node:
|
||||
else:
|
||||
return (yield from self._compute.delete("/projects/{}/{}/nodes/{}{}".format(self._project.id, self._node_type, self._id, path)))
|
||||
|
||||
@asyncio.coroutine
|
||||
def dynamips_auto_idlepc(self):
|
||||
"""
|
||||
Compute the idle PC for a dynamips node
|
||||
"""
|
||||
return (yield from self._compute.get("/projects/{}/{}/nodes/{}/auto_idlepc".format(self._project.id, self._node_type, self._id), timeout=240)).json
|
||||
|
||||
@asyncio.coroutine
|
||||
def dynamips_idlepc_proposals(self):
|
||||
"""
|
||||
Compute a list of potential idle PC
|
||||
"""
|
||||
return (yield from self._compute.get("/projects/{}/{}/nodes/{}/idlepc_proposals".format(self._project.id, self._node_type, self._id), timeout=240)).json
|
||||
|
||||
def __repr__(self):
|
||||
return "<gns3server.controller.Node {} {}>".format(self._node_type, self._name)
|
||||
|
||||
@ -248,6 +262,7 @@ class Node:
|
||||
"node_directory": self._node_directory,
|
||||
"name": self._name,
|
||||
"console": self._console,
|
||||
"console_host": self._compute.host,
|
||||
"console_type": self._console_type,
|
||||
"command_line": self._command_line,
|
||||
"properties": self._properties,
|
||||
|
@ -262,3 +262,43 @@ class NodeHandler:
|
||||
project = Controller.instance().get_project(request.match_info["project_id"])
|
||||
yield from project.delete_node(request.match_info["node_id"])
|
||||
response.set_status(204)
|
||||
|
||||
@Route.get(
|
||||
r"/projects/{project_id}/nodes/{node_id}/dynamips/auto_idlepc",
|
||||
parameters={
|
||||
"project_id": "Project UUID",
|
||||
"node_id": "Node UUID"
|
||||
},
|
||||
status_codes={
|
||||
204: "Instance reloaded",
|
||||
400: "Invalid request",
|
||||
404: "Instance doesn't exist"
|
||||
},
|
||||
description="Compute the IDLE PC for a Dynamips node")
|
||||
def auto_idlepc(request, response):
|
||||
|
||||
project = Controller.instance().get_project(request.match_info["project_id"])
|
||||
node = project.get_node(request.match_info["node_id"])
|
||||
idle = yield from node.dynamips_auto_idlepc()
|
||||
response.json(idle)
|
||||
response.set_status(200)
|
||||
|
||||
@Route.get(
|
||||
r"/projects/{project_id}/nodes/{node_id}/dynamips/idlepc_proposals",
|
||||
parameters={
|
||||
"project_id": "Project UUID",
|
||||
"node_id": "Node UUID"
|
||||
},
|
||||
status_codes={
|
||||
204: "Instance reloaded",
|
||||
400: "Invalid request",
|
||||
404: "Instance doesn't exist"
|
||||
},
|
||||
description="Compute a list of potential idle PC for a node")
|
||||
def idlepc_proposals(request, response):
|
||||
|
||||
project = Controller.instance().get_project(request.match_info["project_id"])
|
||||
node = project.get_node(request.match_info["node_id"])
|
||||
idle = yield from node.dynamips_idlepc_proposals()
|
||||
response.json(idle)
|
||||
response.set_status(200)
|
||||
|
@ -109,6 +109,11 @@ NODE_OBJECT_SCHEMA = {
|
||||
"maximum": 65535,
|
||||
"type": ["integer", "null"]
|
||||
},
|
||||
"console_host": {
|
||||
"description": "Console host",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
},
|
||||
"console_type": {
|
||||
"description": "Console type",
|
||||
"enum": ["serial", "vnc", "telnet", None]
|
||||
|
@ -55,6 +55,7 @@ def test_json(node, compute):
|
||||
"name": "demo",
|
||||
"console": node.console,
|
||||
"console_type": node.console_type,
|
||||
"console_host": compute.host,
|
||||
"command_line": None,
|
||||
"node_directory": None,
|
||||
"properties": node.properties,
|
||||
@ -172,3 +173,23 @@ def test_post(node, compute, async_run):
|
||||
def test_delete(node, compute, async_run):
|
||||
async_run(node.delete("/test"))
|
||||
compute.delete.assert_called_with("/projects/{}/vpcs/nodes/{}/test".format(node.project.id, node.id))
|
||||
|
||||
|
||||
def test_dynamips_idle_pc(node, async_run, compute):
|
||||
node._node_type = "dynamips"
|
||||
response = MagicMock()
|
||||
response.json = {"idlepc": "0x60606f54"}
|
||||
compute.get = AsyncioMagicMock(return_value=response)
|
||||
|
||||
async_run(node.dynamips_auto_idlepc())
|
||||
compute.get.assert_called_with("/projects/{}/dynamips/nodes/{}/auto_idlepc".format(node.project.id, node.id))
|
||||
|
||||
|
||||
def test_dynamips_idlepc_proposals(node, async_run, compute):
|
||||
node._node_type = "dynamips"
|
||||
response = MagicMock()
|
||||
response.json = ["0x60606f54", "0x30ff6f37"]
|
||||
compute.get = AsyncioMagicMock(return_value=response)
|
||||
|
||||
async_run(node.dynamips_idlepc_proposals())
|
||||
compute.get.assert_called_with("/projects/{}/dynamips/nodes/{}/idlepc_proposals".format(node.project.id, node.id))
|
||||
|
@ -38,6 +38,7 @@ from gns3server.controller.node import Node
|
||||
def compute(http_controller, async_run):
|
||||
compute = MagicMock()
|
||||
compute.id = "example.com"
|
||||
compute.host = "example.org"
|
||||
Controller.instance()._computes = {"example.com": compute}
|
||||
return compute
|
||||
|
||||
@ -107,6 +108,7 @@ 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()
|
||||
@ -114,6 +116,7 @@ def test_start_all_nodes(http_controller, tmpdir, project, compute):
|
||||
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()
|
||||
@ -121,6 +124,7 @@ def test_stop_all_nodes(http_controller, tmpdir, project, compute):
|
||||
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()
|
||||
@ -128,6 +132,7 @@ def test_suspend_all_nodes(http_controller, tmpdir, project, compute):
|
||||
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()
|
||||
@ -135,6 +140,7 @@ def test_reload_all_nodes(http_controller, tmpdir, project, compute):
|
||||
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()
|
||||
compute.post = AsyncioMagicMock()
|
||||
@ -142,6 +148,7 @@ def test_start_node(http_controller, tmpdir, project, compute, node):
|
||||
response = http_controller.post("/projects/{}/nodes/{}/start".format(project.id, node.id), example=True)
|
||||
assert response.status == 204
|
||||
|
||||
|
||||
def test_stop_node(http_controller, tmpdir, project, compute, node):
|
||||
response = MagicMock()
|
||||
compute.post = AsyncioMagicMock()
|
||||
@ -172,3 +179,23 @@ def test_delete_node(http_controller, tmpdir, project, compute, node):
|
||||
|
||||
response = http_controller.delete("/projects/{}/nodes/{}".format(project.id, node.id), example=True)
|
||||
assert response.status == 204
|
||||
|
||||
|
||||
def test_dynamips_idle_pc(http_controller, tmpdir, project, compute, node):
|
||||
response = MagicMock()
|
||||
response.json = {"idlepc": "0x60606f54"}
|
||||
compute.get = AsyncioMagicMock(return_value=response)
|
||||
|
||||
response = http_controller.get("/projects/{}/nodes/{}/dynamips/auto_idlepc".format(project.id, node.id), example=True)
|
||||
assert response.status == 200
|
||||
assert response.json["idlepc"] == "0x60606f54"
|
||||
|
||||
|
||||
def test_dynamips_idlepc_proposals(http_controller, tmpdir, project, compute, node):
|
||||
response = MagicMock()
|
||||
response.json = ["0x60606f54", "0x33805a22"]
|
||||
compute.get = AsyncioMagicMock(return_value=response)
|
||||
|
||||
response = http_controller.get("/projects/{}/nodes/{}/dynamips/idlepc_proposals".format(project.id, node.id), example=True)
|
||||
assert response.status == 200
|
||||
assert response.json == ["0x60606f54", "0x33805a22"]
|
||||
|
Loading…
Reference in New Issue
Block a user