mirror of
https://github.com/GNS3/gns3-server.git
synced 2024-12-30 09:38:53 +00:00
Create link when loading topology on controller
This commit is contained in:
parent
742243e9df
commit
0569480953
@ -200,14 +200,7 @@ class Controller:
|
|||||||
topo_data.pop("type")
|
topo_data.pop("type")
|
||||||
|
|
||||||
project = yield from self.add_project(path=os.path.dirname(path), **topo_data)
|
project = yield from self.add_project(path=os.path.dirname(path), **topo_data)
|
||||||
|
yield from project.load()
|
||||||
for compute in topology["computes"]:
|
|
||||||
yield from self.add_compute(**compute)
|
|
||||||
for node in topology["nodes"]:
|
|
||||||
compute = self.get_compute(node.pop("compute_id"))
|
|
||||||
name = node.pop("name")
|
|
||||||
node_id = node.pop("node_id")
|
|
||||||
yield from project.add_node(compute, name, node_id, **node)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def projects(self):
|
def projects(self):
|
||||||
|
@ -30,8 +30,11 @@ class Link:
|
|||||||
Base class for links.
|
Base class for links.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, project):
|
def __init__(self, project, link_id=None):
|
||||||
|
|
||||||
|
if link_id:
|
||||||
|
self._id = link_id
|
||||||
|
else:
|
||||||
self._id = str(uuid.uuid4())
|
self._id = str(uuid.uuid4())
|
||||||
self._nodes = []
|
self._nodes = []
|
||||||
self._project = project
|
self._project = project
|
||||||
@ -134,6 +137,10 @@ class Link:
|
|||||||
def id(self):
|
def id(self):
|
||||||
return self._id
|
return self._id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def nodes(self):
|
||||||
|
return self._nodes
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def capturing(self):
|
def capturing(self):
|
||||||
return self._capturing
|
return self._capturing
|
||||||
|
@ -24,11 +24,12 @@ import shutil
|
|||||||
from uuid import UUID, uuid4
|
from uuid import UUID, uuid4
|
||||||
|
|
||||||
from .node import Node
|
from .node import Node
|
||||||
from .topology import project_to_topology
|
from .topology import project_to_topology, load_topology
|
||||||
from .udp_link import UDPLink
|
from .udp_link import UDPLink
|
||||||
from ..config import Config
|
from ..config import Config
|
||||||
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__)
|
||||||
|
|
||||||
@ -245,11 +246,13 @@ class Project:
|
|||||||
return self._nodes
|
return self._nodes
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def add_link(self):
|
def add_link(self, link_id=None):
|
||||||
"""
|
"""
|
||||||
Create a link. By default the link is empty
|
Create a link. By default the link is empty
|
||||||
"""
|
"""
|
||||||
link = UDPLink(self)
|
if link_id and link_id in self._links:
|
||||||
|
return self._links[link.id]
|
||||||
|
link = UDPLink(self, link_id=link_id)
|
||||||
self._links[link.id] = link
|
self._links[link.id] = link
|
||||||
self.dump()
|
self.dump()
|
||||||
return link
|
return link
|
||||||
@ -307,18 +310,42 @@ class Project:
|
|||||||
raise aiohttp.web.HTTPInternalServerError(text="Could not create project directory: {}".format(e))
|
raise aiohttp.web.HTTPInternalServerError(text="Could not create project directory: {}".format(e))
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
def _topology_file(self):
|
||||||
|
if self.name is None:
|
||||||
|
filename = "untitled.gns3"
|
||||||
|
else:
|
||||||
|
filename = self.name + ".gns3"
|
||||||
|
return os.path.join(self.path, filename)
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def load(self):
|
||||||
|
"""
|
||||||
|
Load topology elements
|
||||||
|
"""
|
||||||
|
path = self._topology_file()
|
||||||
|
topology = load_topology(path)["topology"]
|
||||||
|
for compute in topology["computes"]:
|
||||||
|
yield from self.controller.add_compute(**compute)
|
||||||
|
for node in topology["nodes"]:
|
||||||
|
compute = self.controller.get_compute(node.pop("compute_id"))
|
||||||
|
name = node.pop("name")
|
||||||
|
node_id = node.pop("node_id")
|
||||||
|
yield from self.add_node(compute, name, node_id, **node)
|
||||||
|
for link_data in topology["links"]:
|
||||||
|
link = yield from self.add_link(link_id=link_data["link_id"])
|
||||||
|
for node_link in link_data["nodes"]:
|
||||||
|
node = self.get_node(node_link["node_id"])
|
||||||
|
yield from link.add_node(node, node_link["adapter_number"], node_link["port_number"])
|
||||||
|
|
||||||
def dump(self):
|
def dump(self):
|
||||||
"""
|
"""
|
||||||
Dump topology to disk
|
Dump topology to disk
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
if self.name is None:
|
|
||||||
filename = "untitled.gns3"
|
|
||||||
else:
|
|
||||||
filename = self.name + ".gns3"
|
|
||||||
topo = project_to_topology(self)
|
topo = project_to_topology(self)
|
||||||
log.debug("Write %s", filename)
|
path = self._topology_file()
|
||||||
with open(os.path.join(self.path, filename), "w+") as f:
|
log.debug("Write %s", path)
|
||||||
|
with open(path, "w+") as f:
|
||||||
json.dump(topo, f, indent=4, sort_keys=True)
|
json.dump(topo, f, indent=4, sort_keys=True)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
raise aiohttp.web.HTTPInternalServerError(text="Could not write topology: {}".format(e))
|
raise aiohttp.web.HTTPInternalServerError(text="Could not write topology: {}".format(e))
|
||||||
|
@ -22,6 +22,7 @@ from ..version import __version__
|
|||||||
|
|
||||||
GNS3_FILE_FORMAT_REVISION = 5
|
GNS3_FILE_FORMAT_REVISION = 5
|
||||||
|
|
||||||
|
|
||||||
def project_to_topology(project):
|
def project_to_topology(project):
|
||||||
"""
|
"""
|
||||||
:return: A dictionnary with the topology ready to dump to a .gns3
|
:return: A dictionnary with the topology ready to dump to a .gns3
|
||||||
|
@ -24,8 +24,8 @@ from .link import Link
|
|||||||
|
|
||||||
class UDPLink(Link):
|
class UDPLink(Link):
|
||||||
|
|
||||||
def __init__(self, project):
|
def __init__(self, project, link_id=None):
|
||||||
super().__init__(project)
|
super().__init__(project, link_id=link_id)
|
||||||
self._capture_node = None
|
self._capture_node = None
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
|
@ -21,7 +21,7 @@ import json
|
|||||||
import pytest
|
import pytest
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock
|
||||||
from tests.utils import AsyncioMagicMock
|
from tests.utils import AsyncioMagicMock, asyncio_patch
|
||||||
|
|
||||||
from gns3server.controller import Controller
|
from gns3server.controller import Controller
|
||||||
from gns3server.controller.compute import Compute
|
from gns3server.controller.compute import Compute
|
||||||
@ -205,7 +205,6 @@ def test_load_project(controller, async_run, tmpdir):
|
|||||||
],
|
],
|
||||||
"links": [
|
"links": [
|
||||||
{
|
{
|
||||||
"capturing": True,
|
|
||||||
"link_id": "c44331d2-2da4-490d-9aad-7f5c126ae271",
|
"link_id": "c44331d2-2da4-490d-9aad-7f5c126ae271",
|
||||||
"nodes": [
|
"nodes": [
|
||||||
{"node_id": "c067b922-7f77-4680-ac00-0226c6583598", "adapter_number": 0, "port_number": 0},
|
{"node_id": "c067b922-7f77-4680-ac00-0226c6583598", "adapter_number": 0, "port_number": 0},
|
||||||
@ -240,15 +239,17 @@ def test_load_project(controller, async_run, tmpdir):
|
|||||||
with open(str(tmpdir / "test.gns3"), "w+") as f:
|
with open(str(tmpdir / "test.gns3"), "w+") as f:
|
||||||
json.dump(data, f)
|
json.dump(data, f)
|
||||||
controller.add_compute = AsyncioMagicMock()
|
controller.add_compute = AsyncioMagicMock()
|
||||||
mock_project = MagicMock()
|
|
||||||
controller.add_project = AsyncioMagicMock(return_value=mock_project)
|
|
||||||
controller._computes["my_remote"] = MagicMock()
|
controller._computes["my_remote"] = MagicMock()
|
||||||
|
|
||||||
|
with asyncio_patch("gns3server.controller.node.Node.create") as mock_node_create:
|
||||||
async_run(controller.load_project(str(tmpdir / "test.gns3")))
|
async_run(controller.load_project(str(tmpdir / "test.gns3")))
|
||||||
|
|
||||||
controller.add_compute.assert_called_with(compute_id='my_remote', host='127.0.0.1', name='My remote', port=3080, protocol='http')
|
controller.add_compute.assert_called_with(compute_id='my_remote', host='127.0.0.1', name='My remote', port=3080, protocol='http')
|
||||||
controller.add_project.assert_called_with(name='Test', project_id='c8d07a5a-134f-4c3f-8599-e35eac85eb17', path=str(tmpdir))
|
project = controller.get_project('c8d07a5a-134f-4c3f-8599-e35eac85eb17')
|
||||||
|
assert project.name == "Test"
|
||||||
mock_project.add_node.assert_any_call(controller._computes["my_remote"], 'PC1', '50d66d7b-0dd7-4e9f-b720-6eb621ae6543', node_type='vpcs', properties={'startup_script': 'set pcname PC1\n', 'startup_script_path': 'startup.vpc'})
|
assert project.path == str(tmpdir)
|
||||||
mock_project.add_node.assert_any_call(controller._computes["my_remote"], 'PC2', 'c067b922-7f77-4680-ac00-0226c6583598', node_type='vpcs', properties={'startup_script': 'set pcname PC2\n', 'startup_script_path': 'startup.vpc'})
|
link = project.get_link("c44331d2-2da4-490d-9aad-7f5c126ae271")
|
||||||
|
assert len(link.nodes) == 2
|
||||||
|
|
||||||
|
node1 = project.get_node("50d66d7b-0dd7-4e9f-b720-6eb621ae6543")
|
||||||
|
assert node1.name == "PC1"
|
||||||
|
@ -64,7 +64,6 @@ def test_basic_topology(tmpdir, async_run, controller):
|
|||||||
assert topo["topology"]["computes"][0] == compute.__json__()
|
assert topo["topology"]["computes"][0] == compute.__json__()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_load_topology(tmpdir):
|
def test_load_topology(tmpdir):
|
||||||
data = {
|
data = {
|
||||||
"project_id": "69f26504-7aa3-48aa-9f29-798d44841211",
|
"project_id": "69f26504-7aa3-48aa-9f29-798d44841211",
|
||||||
@ -84,6 +83,7 @@ def test_load_topology(tmpdir):
|
|||||||
topo = load_topology(path)
|
topo = load_topology(path)
|
||||||
assert topo == data
|
assert topo == data
|
||||||
|
|
||||||
|
|
||||||
def test_load_topology_file_error(tmpdir):
|
def test_load_topology_file_error(tmpdir):
|
||||||
path = str(tmpdir / "test.gns3")
|
path = str(tmpdir / "test.gns3")
|
||||||
with pytest.raises(aiohttp.web.HTTPConflict):
|
with pytest.raises(aiohttp.web.HTTPConflict):
|
||||||
|
Loading…
Reference in New Issue
Block a user