Start of support for topologies before 2.X

Missing part:
* GNS3 VM
* Cloud
* Image

Ref #564

Early support of conversion from 1.5
pull/638/head
Julien Duponchelle 8 years ago
parent fd0e8f89db
commit ee533943c8
No known key found for this signature in database
GPG Key ID: CE8B29639E07F5E8

@ -44,11 +44,12 @@ class Project:
:param status: Status of the project (opened / closed)
"""
def __init__(self, name=None, project_id=None, path=None, controller=None, status="opened", filename=None):
def __init__(self, name=None, project_id=None, path=None, controller=None, status="opened", filename=None, auto_start=False):
self._controller = controller
assert name is not None
self._name = name
self._auto_start = False
self._status = status
if project_id is None:
self._id = str(uuid4())
@ -81,6 +82,10 @@ class Project:
# Create the project on demand on the compute node
self._project_created_on_compute = set()
@property
def auto_start(self):
return self._auto_start
@property
def controller(self):
return self._controller

@ -17,6 +17,8 @@
import json
import jsonschema
import uuid
import shutil
import aiohttp
from ..version import __version__
@ -47,6 +49,7 @@ def project_to_topology(project):
data = {
"project_id": project.id,
"name": project.name,
"auto_start": project.auto_start,
"topology": {
"nodes": [],
"links": [],
@ -77,12 +80,294 @@ def load_topology(path):
"""
Open a topology file, patch it for last GNS3 release and return it
"""
log.debug("Read topology %s", path)
try:
with open(path) as f:
topo = json.load(f)
except OSError as e:
raise aiohttp.web.HTTPConflict(text="Could not load topology {}: {}".format(path, str(e)))
if topo["revision"] < GNS3_FILE_FORMAT_REVISION:
raise aiohttp.web.HTTPConflict(text="Old GNS3 project are not yet supported")
if "revision" not in topo or topo["revision"] < GNS3_FILE_FORMAT_REVISION:
# If it's an old GNS3 file we need to convert it
# first we backup the file
shutil.copy(path, path + ".backup")
topo = _convert_1_3_later(topo)
with open(path, "w+") as f:
json.dump(topo, f)
elif topo["revision"] > GNS3_FILE_FORMAT_REVISION:
raise aiohttp.web.HTTPConflict(text="This project is designed for a more recent version of GNS3 please update GNS3 to version {} or later".format(topo["version"]))
_check_topology_schema(topo)
return topo
def _convert_1_3_later(topo):
"""
Convert topologies to the new file format
Look in tests/topologies/README.rst for instructions to test changes here
"""
new_topo = {
"type": "topology",
"revision": GNS3_FILE_FORMAT_REVISION,
"version": __version__,
"auto_start": topo.get("auto_start", False),
"name": topo["name"],
"project_id": topo["project_id"],
"topology": {
"links": [],
"drawings": [],
"computes": [],
"nodes": []
}
}
if new_topo["project_id"] is None:
new_topo["project_id"] = str(uuid.uuid4()) # Could arrive for topologues with drawing only
if "topology" not in topo:
return new_topo
topo = topo["topology"]
# Create computes
server_id_to_compute_id = {}
for server in topo.get("servers", []):
compute = {
"host": server.get("host", "localhost"),
"port": server.get("port", 3080),
"protocol": server.get("protocol", "http")
}
if server["local"]:
compute["compute_id"] = "local"
compute["name"] = "Local"
elif server.get("vm", False):
compute["compute_id"] = "vm"
compute["name"] = "GNS3 VM"
else:
compute["name"] = "Remote {}".format(server["id"])
compute["compute_id"] = str(uuid.uuid4())
server_id_to_compute_id[server["id"]] = compute["compute_id"]
new_topo["topology"]["computes"].append(compute)
# Create nodes
ports = {}
node_id_to_node_uuid = {}
for old_node in topo.get("nodes", []):
node = {}
node["console"] = old_node["properties"].get("console", None)
node["compute_id"] = server_id_to_compute_id[old_node["server_id"]]
node["console_type"] = old_node["properties"].get("console_type", "telnet")
node["name"] = old_node["label"]["text"]
node["label"] = _convert_label(old_node["label"])
node["node_id"] = old_node.get("vm_id", str(uuid.uuid4()))
node["symbol"] = old_node.get("symbol", None)
node["x"] = int(old_node["x"])
node["y"] = int(old_node["y"])
node["z"] = int(old_node.get("z", 1))
node["properties"] = {}
if old_node["type"] == "VPCSDevice":
node["node_type"] = "vpcs"
elif old_node["type"] == "QemuVM":
node["node_type"] = "qemu"
if node["symbol"] is None:
node["symbol"] = ":/symbols/qemu_guest.svg"
elif old_node["type"] == "DockerVM":
node["node_type"] = "docker"
if node["symbol"] is None:
node["symbol"] = ":/symbols/docker_guest.svg"
elif old_node["type"] == "ATMSwitch":
node["node_type"] = "atm_switch"
node["symbol"] = ":/symbols/atm_switch.svg"
node["console_type"] = None
elif old_node["type"] == "EthernetHub":
node["node_type"] = "ethernet_hub"
node["symbol"] = ":/symbols/hub.svg"
node["console_type"] = None
node["properties"]["ports"] = []
for port in old_node["ports"]:
node["properties"]["ports"].append({
"name": "Ethernet{}".format(port["port_number"]),
"port_number": port["port_number"]
})
elif old_node["type"] == "EthernetSwitch":
node["node_type"] = "ethernet_switch"
node["symbol"] = ":/symbols/ethernet_switch.svg"
node["properties"]["ports"] = []
node["console_type"] = None
for port in old_node["ports"]:
node["properties"]["ports"].append({
"name": "Ethernet{}".format(port["port_number"]),
"port_number": port["port_number"],
"type": port["type"],
"vlan": port["vlan"]
})
elif old_node["type"] == "FrameRelaySwitch":
node["node_type"] = "frame_relay_switch"
node["symbol"] = ":/symbols/frame_relay_switch.svg"
node["console_type"] = None
elif old_node["type"] in ["C1700", "C2600", "C2691", "C3600", "C3725", "C3745", "C7200", "EtherSwitchRouter"]:
if node["symbol"] is None:
node["symbol"] = ":/symbols/router.svg"
node["node_type"] = "dynamips"
node["properties"]["dynamips_id"] = old_node["dynamips_id"]
elif old_node["type"] == "VMwareVM":
node["node_type"] = "vmware"
if node["symbol"] is None:
node["symbol"] = ":/symbols/vmware_guest.svg"
elif old_node["type"] == "VirtualBoxVM":
node["node_type"] = "virtualbox"
if node["symbol"] is None:
node["symbol"] = ":/symbols/vbox_guest.svg"
else:
raise NotImplementedError("Conversion of {} is not supported".format(old_node["type"]))
for prop in old_node["properties"]:
if prop not in ["console", "name", "console_type", "use_ubridge"]:
node["properties"][prop] = old_node["properties"][prop]
node_id_to_node_uuid[old_node["id"]] = node["node_id"]
for port in old_node.get("ports", []):
ports[port["id"]] = port
new_topo["topology"]["nodes"].append(node)
# Create links
for old_link in topo.get("links", []):
nodes = []
source_node = {
"adapter_number": ports[old_link["source_port_id"]].get("adapter_number", 0),
"port_number": ports[old_link["source_port_id"]]["port_number"],
"node_id": node_id_to_node_uuid[old_link["source_node_id"]]
}
nodes.append(source_node)
destination_node = {
"adapter_number": ports[old_link["destination_port_id"]].get("adapter_number", 0),
"port_number": ports[old_link["destination_port_id"]]["port_number"],
"node_id": node_id_to_node_uuid[old_link["destination_node_id"]]
}
nodes.append(destination_node)
link = {
"link_id": str(uuid.uuid4()),
"nodes": nodes
}
new_topo["topology"]["links"].append(link)
# Ellipse
for ellipse in topo.get("ellipses", []):
svg = '<svg height="{height}" width="{width}"><ellipse cx="{cx}" cy="{cy}" fill="{fill}" fill-opacity="1.0" rx="{rx}" ry="{ry}" {border_style} /></svg>'.format(
height=int(ellipse["height"]),
width=int(ellipse["width"]),
cx=int(ellipse["width"] / 2),
cy=int(ellipse["height"] / 2),
rx=int(ellipse["width"] / 2),
ry=int(ellipse["height"] / 2),
fill=ellipse.get("color", "#ffffff"),
border_style=_convert_border_style(ellipse)
)
new_ellipse = {
"drawing_id": str(uuid.uuid4()),
"x": int(ellipse["x"]),
"y": int(ellipse["y"]),
"z": int(ellipse.get("z", 0)),
"rotation": int(ellipse.get("rotation", 0)),
"svg": svg
}
new_topo["topology"]["drawings"].append(new_ellipse)
# Notes
for note in topo.get("notes", []):
font_info = note["font"].split(",")
if font_info[4] == "75":
weight = "bold"
else:
weight = "normal"
if font_info[5] == "1":
style = "italic"
else:
style = "normal"
svg = '<svg height="{height}" width="{width}"><text fill="{fill}" fill-opacity="{opacity}" font-family="{family}" font-size="{size}" font-weight="{weight}" font-style="{style}">{text}</text></svg>'.format(
height=int(font_info[1]) * 2,
width=int(font_info[1]) * len(note["text"]),
fill="#" + note["color"][-6:],
opacity=round(1.0 / 255 * int(note["color"][:3][-2:], base=16), 2), # Extract the alpha channel from the hexa version
family=font_info[0],
size=int(font_info[1]),
weight=weight,
style=style,
text=note["text"]
)
new_note = {
"drawing_id": str(uuid.uuid4()),
"x": int(note["x"]),
"y": int(note["y"]),
"z": int(note.get("z", 0)),
"rotation": int(ellipse.get("rotation", 0)),
"svg": svg
}
new_topo["topology"]["drawings"].append(new_note)
# Rectangles
for rectangle in topo.get("rectangles", []):
svg = '<svg height="{height}" width="{width}"><rect fill="{fill}" fill-opacity="1.0" height="{height}" width="{width}" {border_style} /></svg>'.format(
height=int(rectangle["height"]),
width=int(rectangle["width"]),
fill=rectangle.get("color", "#ffffff"),
border_style=_convert_border_style(rectangle)
)
new_rectangle = {
"drawing_id": str(uuid.uuid4()),
"x": int(rectangle["x"]),
"y": int(rectangle["y"]),
"z": int(rectangle.get("z", 0)),
"rotation": int(ellipse.get("rotation", 0)),
"svg": svg
}
new_topo["topology"]["drawings"].append(new_rectangle)
return new_topo
def _convert_border_style(element):
QT_DASH_TO_SVG = {
2: "25, 25",
3: "5, 25",
4: "5, 25, 25",
5: "25, 25, 5, 25, 5"
}
border_style = int(element.get("border_style", 0))
style = ""
if border_style == 1: # No border
return ""
elif border_style == 0:
pass # Solid line
else:
style += 'stroke-dasharray="{}" '.format(QT_DASH_TO_SVG[border_style])
style += 'stroke="{stroke}" stroke-width="{stroke_width}"'.format(
stroke=element.get("border_color", "#000000"),
stroke_width=element.get("border_width", 2)
)
return style
def _convert_label(label):
"""
Convert a label from 1.X to the new format
"""
font_info = label["font"].split(",")
style = "font-family: {};font-size: {};".format(font_info[0], font_info[1])
if font_info[4] == "75":
style += "font-weight: bold;"
if font_info[5] == "1":
style += "font-style: italic;"
color = label["color"]
style += "fill: #" + color[-6:] + ";"
style += "fill-opacity: {};".format(round(1.0 / 255 * int(color[:3][-2:], base=16), 2))
return {
"text": label["text"],
"rotation": 0,
"style": style,
"x": int(label["x"]),
"y": int(label["y"])
}

@ -41,6 +41,10 @@ TOPOLOGY_SCHEMA = {
"description": "Type of file. It's always topology",
"enum": ["topology"]
},
"auto_start": {
"description": "Start the topology when opened",
"type": "boolean"
},
"revision": {
"description": "Version of the .gns3 specification.",
"type": "integer"

@ -34,6 +34,7 @@ def test_project_to_topology_empty(tmpdir):
assert topo == {
"project_id": project.id,
"name": "Test",
"auto_start": False,
"revision": 5,
"topology": {
"nodes": [],
@ -106,11 +107,15 @@ def test_load_topology_file_error_schema_error(tmpdir):
topo = load_topology(path)
def test_load_old_topology(tmpdir):
def test_load_newer_topology(tmpdir):
"""
If a topology is design for a more recent GNS3 version
we disallow the loading.
"""
data = {
"project_id": "69f26504-7aa3-48aa-9f29-798d44841211",
"name": "Test",
"revision": 4,
"revision": 42,
"topology": {
},
"type": "topology",

@ -0,0 +1,111 @@
#!/usr/bin/env python
#
# Copyright (C) 2016 GNS3 Technologies Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# This will test the conversion from old topology format to the new
#
# Read tests/topologies/README.rst for documentation
import os
import json
import pytest
import shutil
from gns3server.controller.topology import load_topology, GNS3_FILE_FORMAT_REVISION
topologies_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), "topologies")
def topologies():
dirs = []
for directory in os.listdir(topologies_directory):
if os.path.isdir(os.path.join(topologies_directory, directory)):
dirs.append(directory)
return dirs
@pytest.mark.parametrize("directory", topologies())
def test_convert(directory, tmpdir):
before_directory = os.path.join(topologies_directory, directory, "before")
after_directory = os.path.join(topologies_directory, directory, "after")
assert os.path.exists(before_directory), "No before directory found file for {}".format(directory)
assert os.path.exists(after_directory), "No after directory found file for {}".format(directory)
gns3_file = None
for file in os.listdir(before_directory):
if file.endswith(".gns3"):
gns3_file = file
assert gns3_file, "No .gns3 found file for {}".format(before_directory)
with open(os.path.join(before_directory, gns3_file)) as f:
before_topology = json.load(f)
with open(os.path.join(after_directory, gns3_file)) as f:
after_topology = json.load(f)
# We use a temporary directory for conversion operation to not corrupt our files
work_directory = str(tmpdir / "work")
shutil.copytree(before_directory, work_directory)
work_topology = load_topology(os.path.join(work_directory, gns3_file))
assert work_topology
if "revision" not in before_topology or before_topology["revision"] < GNS3_FILE_FORMAT_REVISION:
assert os.path.exists(os.path.join(work_directory, gns3_file + ".backup"))
# We should have the same file in after directory and the work directory
for root, dirs, files in os.walk(after_directory):
for file in files:
directory = os.path.relpath(root, after_directory)
file_path = os.path.join(work_directory, directory, file)
assert os.path.exists(file_path), "{} is missing".format(os.path.join(directory, file))
# For non .gns3 file we check if the file are the same
if not file_path.endswith(".gns3"):
assert os.stat(file_path).st_size == os.stat(os.path.join(os.path.join(root, file))).st_size, "File {} is different".format(os.path.join(directory, file))
compare_dict("/", work_topology, after_topology)
def compare_dict(path, source, reference):
"""
Compare two dictionnary of a topology
"""
assert isinstance(source, dict), "Source is not a dict in {}".format(path)
for key in source:
assert key in reference, "Unexcepted {} in {} it should be {}".format(key, source, reference)
for key in sorted(reference.keys()):
val = reference[key]
assert key in source, "{} is missing in {}".format(key, source)
if isinstance(val, str) or isinstance(val, float) or isinstance(val, int) or isinstance(val, bool) or val is None:
if val == "ANYSTR":
pass
elif val == "ANYUUID" and len(source[key]) == 36:
pass
else:
assert val == source[key], "Wrong value for {}: \n{}\nit should be\n{}".format(key, source[key], val)
elif isinstance(val, dict):
compare_dict(path + key + "/", source[key], val)
elif isinstance(val, list):
assert len(val) == len(source[key]), "Not enough value in {} ({}/{}) it shoud be {} not {}".format(key, len(val), len(source[key]), val, source[key])
for idx, element in enumerate(source[key]):
compare_dict(path + key + "/", element, val[idx])
else:
assert False, "Value type for {} is not supported".format(key)

@ -0,0 +1,197 @@
{
"name": "builtins",
"project_id": "644e3892-4a50-4457-9601-2234d4842169",
"revision": 5,
"auto_start": false,
"topology": {
"computes": [
{
"compute_id": "local",
"host": "127.0.0.1",
"name": "Local",
"port": 3080,
"protocol": "http"
}
],
"drawings": [],
"links": [],
"nodes": [
{
"compute_id": "local",
"console": null,
"console_type": null,
"label": {
"rotation": 0,
"style": "font-family: TypeWriter;font-size: 10;font-weight: bold;fill: #000000;fill-opacity: 1.0;",
"text": "ATM1",
"x": 6,
"y": -25
},
"name": "ATM1",
"node_id": "ANYUUID",
"node_type": "atm_switch",
"properties": {
"mappings": {
"1:0:100": "10:0:200"
}
},
"symbol": ":/symbols/atm_switch.svg",
"x": -398,
"y": -219,
"z": 1
},
{
"compute_id": "local",
"console": null,
"console_type": null,
"label": {
"rotation": 0,
"style": "font-family: TypeWriter;font-size: 10;font-weight: bold;fill: #000000;fill-opacity: 1.0;",
"text": "HUB1",
"x": 17,
"y": -25
},
"name": "HUB1",
"node_id": "ANYUUID",
"node_type": "ethernet_hub",
"properties": {
"ports": [
{
"name": "Ethernet1",
"port_number": 1
},
{
"name": "Ethernet2",
"port_number": 2
},
{
"name": "Ethernet3",
"port_number": 3
},
{
"name": "Ethernet4",
"port_number": 4
},
{
"name": "Ethernet5",
"port_number": 5
},
{
"name": "Ethernet6",
"port_number": 6
},
{
"name": "Ethernet7",
"port_number": 7
},
{
"name": "Ethernet8",
"port_number": 8
}
]
},
"symbol": ":/symbols/hub.svg",
"x": -176,
"y": -209,
"z": 1
},
{
"compute_id": "local",
"console": null,
"console_type": null,
"label": {
"rotation": 0,
"style": "font-family: TypeWriter;font-size: 10;font-weight: bold;fill: #000000;fill-opacity: 1.0;",
"text": "SW1",
"x": 20,
"y": -25
},
"name": "SW1",
"node_id": "ANYUUID",
"node_type": "ethernet_switch",
"properties": {
"ports": [
{
"name": "Ethernet1",
"port_number": 1,
"type": "access",
"vlan": 1
},
{
"name": "Ethernet2",
"port_number": 2,
"type": "access",
"vlan": 1
},
{
"name": "Ethernet3",
"port_number": 3,
"type": "access",
"vlan": 1
},
{
"name": "Ethernet4",
"port_number": 4,
"type": "access",
"vlan": 1
},
{
"name": "Ethernet5",
"port_number": 5,
"type": "access",
"vlan": 1
},
{
"name": "Ethernet6",
"port_number": 6,
"type": "access",
"vlan": 1
},
{
"name": "Ethernet7",
"port_number": 7,
"type": "access",
"vlan": 1
},
{
"name": "Ethernet8",
"port_number": 8,
"type": "access",
"vlan": 1
}
]
},
"symbol": ":/symbols/ethernet_switch.svg",
"x": 5,
"y": -206,
"z": 1
},
{
"compute_id": "local",
"console": null,
"console_type": null,
"label": {
"rotation": 0,
"style": "font-family: TypeWriter;font-size: 10;font-weight: bold;fill: #000000;fill-opacity: 1.0;",
"text": "FR1",
"x": 11,
"y": -25
},
"name": "FR1",
"node_id": "ANYUUID",
"node_type": "frame_relay_switch",
"properties": {
"mappings": {
"1:101": "10:202"
}
},
"symbol": ":/symbols/frame_relay_switch.svg",
"x": 294,
"y": -209,
"z": 1
}
]
},
"type": "topology",
"version": "2.0.0dev1"
}

@ -0,0 +1,204 @@
{
"auto_start": false,
"name": "builtins",
"project_id": "644e3892-4a50-4457-9601-2234d4842169",
"revision": 4,
"topology": {
"nodes": [
{
"description": "ATM switch",
"device_id": "4fed7243-cd30-4e37-bdd4-d21ed9e65c03",
"id": 1,
"label": {
"color": "#ff000000",
"font": "TypeWriter,10,-1,5,75,0,0,0,0,0",
"text": "ATM1",
"x": 6.546875,
"y": -25.0
},
"properties": {
"name": "ATM1",
"mappings": {
"1:0:100": "10:0:200"
}
},
"server_id": 3,
"type": "ATMSwitch",
"x": -398.5,
"y": -219.5
},
{
"description": "Ethernet hub",
"device_id": "40199896-fabd-42d8-9bca-4651a73159dd",
"id": 2,
"label": {
"color": "#ff000000",
"font": "TypeWriter,10,-1,5,75,0,0,0,0,0",
"text": "HUB1",
"x": 17.9765625,
"y": -25.0
},
"ports": [
{
"id": 1,
"name": "1",
"port_number": 1
},
{
"id": 2,
"name": "2",
"port_number": 2
},
{
"id": 3,
"name": "3",
"port_number": 3
},
{
"id": 4,
"name": "4",
"port_number": 4
},
{
"id": 5,
"name": "5",
"port_number": 5
},
{
"id": 6,
"name": "6",
"port_number": 6
},
{
"id": 7,
"name": "7",
"port_number": 7
},
{
"id": 8,
"name": "8",
"port_number": 8
}
],
"properties": {
"name": "HUB1"
},
"server_id": 3,
"type": "EthernetHub",
"x": -176.0,
"y": -209.0
},
{
"description": "Ethernet switch",
"device_id": "96d18119-cc78-4129-9543-932f8b202d52",
"id": 3,
"label": {
"color": "#ff000000",
"font": "TypeWriter,10,-1,5,75,0,0,0,0,0",
"text": "SW1",
"x": 20.8359375,
"y": -25.0
},
"ports": [
{
"id": 9,
"name": "1",
"port_number": 1,
"type": "access",
"vlan": 1
},
{
"id": 10,
"name": "2",
"port_number": 2,
"type": "access",
"vlan": 1
},
{
"id": 11,
"name": "3",
"port_number": 3,
"type": "access",
"vlan": 1
},
{
"id": 12,
"name": "4",
"port_number": 4,
"type": "access",
"vlan": 1
},
{
"id": 13,
"name": "5",
"port_number": 5,
"type": "access",
"vlan": 1
},
{
"id": 14,
"name": "6",
"port_number": 6,
"type": "access",
"vlan": 1
},
{
"id": 15,
"name": "7",
"port_number": 7,
"type": "access",
"vlan": 1
},
{
"id": 16,
"name": "8",
"port_number": 8,
"type": "access",
"vlan": 1
}
],
"properties": {
"name": "SW1"
},
"server_id": 3,
"type": "EthernetSwitch",
"x": 5.5,
"y": -206.0
},
{
"description": "Frame Relay switch",
"device_id": "3bb18be3-0692-47be-a98e-213fa5f1ba73",
"id": 5,
"label": {
"color": "#ff000000",
"font": "TypeWriter,10,-1,5,75,0,0,0,0,0",
"text": "FR1",
"x": 11.890625,
"y": -25.0
},
"properties": {
"name": "FR1",
"mappings": {
"1:101": "10:202"
}
},
"server_id": 3,
"type": "FrameRelaySwitch",
"x": 294.5,
"y": -209.5
}
],
"servers": [
{
"host": "127.0.0.1",
"id": 3,
"local": true,
"port": 3080,
"protocol": "http",
"vm": false
}
]
},
"type": "topology",
"version": "1.5.1dev1"
}

@ -0,0 +1,50 @@
{
"name": "1_5_docker_remote",
"project_id": "8182b710-c6bf-4e51-8e2e-213cce952797",
"revision": 5,
"auto_start": false,
"topology": {
"computes": [
{
"compute_id": "ANYUUID",
"host": "127.0.0.1",
"name": "Remote 2",
"port": 8001,
"protocol": "http"
}
],
"drawings": [],
"links": [],
"nodes": [
{
"compute_id": "ANYUUID",
"console": 6001,
"console_type": "telnet",
"label": {
"rotation": 0,
"style": "font-family: TypeWriter;font-size: 10;font-weight: bold;fill: #000000;fill-opacity: 1.0;",
"text": "remote_busybox-1",
"x": -20,
"y": -25
},
"name": "remote_busybox-1",
"node_id": "d397ef5a-84f1-4b6b-9d44-671937ec7781",
"node_type": "docker",
"properties": {
"adapters": 1,
"aux": 6002,
"console_http_path": "/",
"console_http_port": 80,
"console_resolution": "1024x768",
"image": "busybox:latest"
},
"symbol": ":/symbols/docker_guest.svg",
"x": -53,
"y": -69,
"z": 1
}
]
},
"type": "topology",
"version": "2.0.0dev1"
}

@ -1,7 +1,7 @@
{
"auto_start": false,
"name": "untitled",
"project_id": "926e5c9e-887c-41b2-9214-fbd5fb628fe8",
"name": "1_5_docker_remote",
"project_id": "8182b710-c6bf-4e51-8e2e-213cce952797",
"revision": 4,
"topology": {
"nodes": [
@ -55,4 +55,4 @@
},
"type": "topology",
"version": "1.5.1dev1"
}
}

@ -0,0 +1,40 @@
{
"auto_start": false,
"name": "1_5_drawing",
"project_id": "ANYUUID",
"revision": 5,
"topology": {
"computes": [
],
"drawings": [
{
"drawing_id": "ANYUUID",
"rotation": 0,
"svg": "<svg height=\"200\" width=\"200\"><ellipse cx=\"100\" cy=\"100\" fill=\"#ffffff\" fill-opacity=\"1.0\" rx=\"100\" ry=\"100\" stroke-dasharray=\"25, 25\" stroke=\"#000000\" stroke-width=\"2\" /></svg>",
"x": 179,
"y": -44,
"z": 0
},
{
"drawing_id": "ANYUUID",
"rotation": 0,
"svg": "<svg height=\"20\" width=\"40\"><text fill=\"#000000\" fill-opacity=\"1.0\" font-family=\"TypeWriter\" font-size=\"10\" font-weight=\"bold\" font-style=\"italic\">Test</text></svg>",
"x": -151,
"y": 93,
"z": 0
},
{
"drawing_id": "ANYUUID",
"rotation": 0,
"svg": "<svg height=\"100\" width=\"200\"><rect fill=\"#18ffff\" fill-opacity=\"1.0\" height=\"100\" width=\"200\" stroke=\"#c80000\" stroke-width=\"2\" /></svg>",
"x": -210,
"y": -108,
"z": 0
}
],
"links": [],
"nodes": []
},
"type": "topology",
"version": "2.0.0dev1"
}

@ -0,0 +1,38 @@
{
"auto_start": false,
"name": "1_5_drawing",
"project_id": null,
"revision": 4,
"topology": {
"ellipses": [
{
"border_style": 2,
"height": 200.0,
"width": 200.0,
"x": 179.0,
"y": -44.0
}
],
"notes": [
{
"color": "#ff000000",
"font": "TypeWriter,10,-1,5,75,1,0,0,0,0",
"text": "Test",
"x": -151.0,
"y": 93.0
}
],
"rectangles": [
{
"border_color": "#c80000",
"color": "#18ffff",
"height": 100.0,
"width": 200.0,
"x": -210.0,
"y": -108.0
}
]
},
"type": "topology",
"version": "1.5.1dev1"
}

@ -0,0 +1,109 @@
{
"auto_start": false,
"name": "1_5_dynamips",
"project_id": "62f389c0-f26d-43b7-ab29-e4d306b29c07",
"revision": 5,
"topology": {
"computes": [
{
"compute_id": "local",
"host": "127.0.0.1",
"name": "Local",
"port": 3080,
"protocol": "http"
}
],
"drawings": [],
"links": [],
"nodes": [
{
"compute_id": "local",
"console": 5000,
"console_type": "telnet",
"label": {
"rotation": 0,
"style": "font-family: TypeWriter;font-size: 10;font-weight: bold;fill: #000000;fill-opacity: 1.0;",
"text": "R1",
"x": 22,
"y": -25
},
"name": "R1",
"node_id": "11845dea-f175-495b-9fc5-bf20a2262016",
"node_type": "dynamips",
"properties": {
"auto_delete_disks": true,
"clock_divisor": 8,
"disk0": 0,
"disk1": 0,
"dynamips_id": 1,
"exec_area": 64,
"idlemax": 500,
"idlepc": "0x60aa1da0",
"idlesleep": 30,
"image": "c3745-adventerprisek9-mz.124-25d.image",
"image_md5sum": "ddbaf74274822b50fa9670e10c75b08f",
"iomem": 5,
"mac_addr": "c401.6b0f.0000",
"mmap": true,
"nvram": 256,
"platform": "c3745",
"ram": 256,
"slot0": "GT96100-FE",
"sparsemem": true,
"startup_config": "configs/i1_startup-config.cfg",
"system_id": "FTX0945W0MY"
},
"symbol": ":/symbols/router.svg",
"x": -112,
"y": -46,
"z": 1
},
{
"compute_id": "local",
"console": 5001,
"console_type": "telnet",
"label": {
"rotation": 0,
"style": "font-family: TypeWriter;font-size: 10;font-weight: bold;fill: #000000;fill-opacity: 1.0;",
"text": "ESW1",
"x": 7,
"y": -25
},
"name": "ESW1",
"node_id": "4478a968-72a1-4722-9039-db7561c717c4",
"node_type": "dynamips",
"properties": {
"auto_delete_disks": false,
"chassis": "3660",
"clock_divisor": 4,
"disk0": 1,
"disk1": 0,
"dynamips_id": 2,
"exec_area": 64,
"idlemax": 500,
"idlepc": "0x6076e0b4",
"idlesleep": 30,
"image": "c3660-a3jk9s-mz.124-15.T14.image",
"image_md5sum": "daed99f508fd42dbaacf711e560643ed",
"iomem": 5,
"mac_addr": "cc02.6b5c.0000",
"mmap": true,
"nvram": 256,
"platform": "c3600",
"ram": 192,
"slot0": "Leopard-2FE",
"slot1": "NM-16ESW",
"sparsemem": true,
"startup_config": "configs/i2_startup-config.cfg",
"system_id": "FTX0945W0MY"
},
"symbol": ":/symbols/multilayer_switch.svg",
"x": 55,
"y": -76,
"z": 1
}
]
},
"type": "topology",
"version": "2.0.0dev1"
}

@ -0,0 +1,231 @@
{
"auto_start": false,
"name": "1_5_dynamips",
"project_id": "62f389c0-f26d-43b7-ab29-e4d306b29c07",
"revision": 4,
"topology": {
"nodes": [
{
"description": "Router c3745",
"dynamips_id": 1,
"id": 1,
"label": {
"color": "#ff000000",
"font": "TypeWriter,10,-1,5,75,0,0,0,0,0",
"text": "R1",
"x": 22.2578125,
"y": -25.0
},
"ports": [
{
"adapter_number": 0,
"id": 1,
"name": "FastEthernet0/0",
"port_number": 0
},
{
"adapter_number": 0,
"id": 2,
"name": "FastEthernet0/1",
"port_number": 1
}
],
"properties": {
"auto_delete_disks": true,
"clock_divisor": 8,
"console": 5000,
"disk0": 0,
"disk1": 0,
"exec_area": 64,
"idlemax": 500,
"idlepc": "0x60aa1da0",
"idlesleep": 30,
"image": "c3745-adventerprisek9-mz.124-25d.image",
"image_md5sum": "ddbaf74274822b50fa9670e10c75b08f",
"iomem": 5,
"mac_addr": "c401.6b0f.0000",
"mmap": true,
"name": "R1",
"nvram": 256,
"platform": "c3745",
"ram": 256,
"slot0": "GT96100-FE",
"sparsemem": true,
"startup_config": "configs/i1_startup-config.cfg",
"system_id": "FTX0945W0MY"
},
"server_id": 3,
"type": "C3745",
"vm_id": "11845dea-f175-495b-9fc5-bf20a2262016",
"x": -112.19595949289331,
"y": -46.04163056034261
},
{
"description": "Router c3600",
"dynamips_id": 2,
"id": 2,
"label": {
"color": "#ff000000",
"font": "TypeWriter,10,-1,5,75,0,0,0,0,0",
"text": "ESW1",
"x": 7.8359375,
"y": -25.0
},
"ports": [
{
"adapter_number": 0,
"id": 3,
"name": "FastEthernet0/0",
"port_number": 0
},
{
"adapter_number": 0,
"id": 4,
"name": "FastEthernet0/1",
"port_number": 1
},
{
"adapter_number": 1,
"id": 5,
"name": "FastEthernet1/0",
"port_number": 0
},
{
"adapter_number": 1,
"id": 6,
"name": "FastEthernet1/1",
"port_number": 1
},
{
"adapter_number": 1,
"id": 7,
"name": "FastEthernet1/2",
"port_number": 2
},
{
"adapter_number": 1,
"id": 8,
"name": "FastEthernet1/3",
"port_number": 3
},
{
"adapter_number": 1,
"id": 9,
"name": "FastEthernet1/4",
"port_number": 4
},
{
"adapter_number": 1,
"id": 10,
"name": "FastEthernet1/5",
"port_number": 5
},
{
"adapter_number": 1,
"id": 11,
"name": "FastEthernet1/6",
"port_number": 6
},
{
"adapter_number": 1,
"id": 12,
"name": "FastEthernet1/7",
"port_number": 7
},
{
"adapter_number": 1,
"id": 13,
"name": "FastEthernet1/8",
"port_number": 8
},
{
"adapter_number": 1,
"id": 14,
"name": "FastEthernet1/9",
"port_number": 9
},
{
"adapter_number": 1,
"id": 15,
"name": "FastEthernet1/10",
"port_number": 10
},
{
"adapter_number": 1,
"id": 16,
"name": "FastEthernet1/11",
"port_number": 11
},
{
"adapter_number": 1,
"id": 17,
"name": "FastEthernet1/12",
"port_number": 12
},
{
"adapter_number": 1,
"id": 18,
"name": "FastEthernet1/13",
"port_number": 13
},
{
"adapter_number": 1,
"id": 19,
"name": "FastEthernet1/14",
"port_number": 14
},
{
"adapter_number": 1,
"id": 20,
"name": "FastEthernet1/15",
"port_number": 15
}
],
"properties": {
"auto_delete_disks": false,
"chassis": "3660",
"clock_divisor": 4,
"console": 5001,
"disk0": 1,
"disk1": 0,
"exec_area": 64,
"idlemax": 500,
"idlepc": "0x6076e0b4",
"idlesleep": 30,
"image": "c3660-a3jk9s-mz.124-15.T14.image",
"image_md5sum": "daed99f508fd42dbaacf711e560643ed",
"iomem": 5,
"mac_addr": "cc02.6b5c.0000",
"mmap": true,
"name": "ESW1",
"nvram": 256,
"platform": "c3600",
"ram": 192,
"slot0": "Leopard-2FE",
"slot1": "NM-16ESW",
"sparsemem": true,
"startup_config": "configs/i2_startup-config.cfg",
"system_id": "FTX0945W0MY"
},
"server_id": 3,
"symbol": ":/symbols/multilayer_switch.svg",
"type": "C3600",
"vm_id": "4478a968-72a1-4722-9039-db7561c717c4",
"x": 55,
"y": -76
}
],
"servers": [
{
"host": "127.0.0.1",
"id": 3,
"local": true,
"port": 3080,
"protocol": "http",
"vm": false
}
]
},
"type": "topology",
"version": "1.5.1dev1"
}

@ -0,0 +1,63 @@
{
"name": "testqemu",
"project_id": "a3ca8a82-6b11-4c8e-b20d-c9e94286054c",
"revision": 5,
"auto_start": false,
"topology": {
"computes": [
{
"compute_id": "local",
"host": "127.0.0.1",
"name": "Local",
"port": 3080,
"protocol": "http"
}
],
"drawings": [],
"links": [],
"nodes": [
{
"compute_id": "local",
"console": 5000,
"console_type": "telnet",
"label": {
"rotation": 0,
"style": "font-family: TypeWriter;font-size: 10;font-weight: bold;fill: #000000;fill-opacity: 1.0;",
"text": "MicroCore-1",
"x": -4,
"y": -25
},
"name": "MicroCore-1",
"node_id": "426face4-7f73-436b-88fa-050e3ee101e9",
"node_type": "qemu",
"properties": {
"acpi_shutdown": false,
"adapter_type": "e1000",
"adapters": 1,
"boot_priority": "c",
"cpu_throttling": 0,
"cpus": 1,
"hda_disk_image": "core-linux-6.4-internet-0.1.img",
"hda_disk_image_md5sum": "8ebc5a6ec53a1c05b7aa101b5ceefe31",
"hda_disk_interface": "ide",
"hdb_disk_interface": "ide",
"hdc_disk_interface": "ide",
"hdd_disk_interface": "ide",
"legacy_networking": false,
"mac_address": "00:05:4c:01:e9:00",
"options": "-nographic",
"platform": "x86_64",
"process_priority": "normal",
"qemu_path": "/usr/local/bin/qemu-system-x86_64",
"ram": 256
},
"symbol": ":/symbols/qemu_guest.svg",
"x": -88,
"y": -102,
"z": 1
}
]
},
"type": "topology",
"version": "2.0.0dev1"
}

@ -0,0 +1,72 @@
{
"auto_start": false,
"name": "testqemu",
"project_id": "a3ca8a82-6b11-4c8e-b20d-c9e94286054c",
"revision": 4,
"topology": {
"nodes": [
{
"description": "QEMU VM",
"id": 1,
"label": {
"color": "#ff000000",
"font": "TypeWriter,10,-1,5,75,0,0,0,0,0",
"text": "MicroCore-1",
"x": -4.1875,
"y": -25.0
},
"linked_clone": true,
"port_name_format": "Ethernet{0}",
"ports": [
{
"adapter_number": 0,
"id": 1,
"name": "Ethernet0",
"port_number": 0
}
],
"properties": {
"acpi_shutdown": false,
"adapter_type": "e1000",
"adapters": 1,
"boot_priority": "c",
"console": 5000,
"console_type": "telnet",
"cpu_throttling": 0,
"cpus": 1,
"hda_disk_image": "core-linux-6.4-internet-0.1.img",
"hda_disk_image_md5sum": "8ebc5a6ec53a1c05b7aa101b5ceefe31",
"hda_disk_interface": "ide",
"hdb_disk_interface": "ide",
"hdc_disk_interface": "ide",
"hdd_disk_interface": "ide",
"legacy_networking": false,
"mac_address": "00:05:4c:01:e9:00",
"name": "MicroCore-1",
"options": "-nographic",
"platform": "x86_64",
"process_priority": "normal",
"qemu_path": "/usr/local/bin/qemu-system-x86_64",
"ram": 256
},
"server_id": 3,
"type": "QemuVM",
"vm_id": "426face4-7f73-436b-88fa-050e3ee101e9",
"x": -88.5,
"y": -102.5
}
],
"servers": [
{
"host": "127.0.0.1",
"id": 3,
"local": true,
"port": 3080,
"protocol": "http",
"vm": false
}
]
},
"type": "topology",
"version": "1.5.1dev1"
}

@ -0,0 +1,52 @@
{
"auto_start": false,
"name": "1_5_virtualbox",
"project_id": "bf00c459-05a5-45c0-950c-3f6150a20703",
"revision": 5,
"topology": {
"computes": [
{
"compute_id": "local",
"host": "127.0.0.1",
"name": "Local",
"port": 3080,
"protocol": "http"
}
],
"drawings": [],
"links": [],
"nodes": [
{
"compute_id": "local",
"console": 5000,
"console_type": "telnet",
"label": {
"rotation": 0,
"style": "font-family: TypeWriter;font-size: 10;font-weight: bold;fill: #000000;fill-opacity: 1.0;",
"text": "debian",
"x": 11,
"y": -25
},
"name": "debian",
"node_id": "af5fa728-85da-44f1-b17a-e99a65a7037e",
"node_type": "virtualbox",
"properties": {
"acpi_shutdown": false,
"adapter_type": "Intel PRO/1000 MT Desktop (82540EM)",
"adapters": 1,
"enable_remote_console": false,
"headless": false,
"ram": 512,
"use_any_adapter": false,
"vmname": "debian"
},
"symbol": ":/symbols/vbox_guest.svg",
"x": -48,
"y": -43,
"z": 1
}
]
},
"type": "topology",
"version": "2.0.0dev1"
}

@ -0,0 +1,60 @@
{
"auto_start": false,
"name": "1_5_virtualbox",
"project_id": "bf00c459-05a5-45c0-950c-3f6150a20703",
"revision": 4,
"topology": {
"nodes": [
{
"description": "VirtualBox VM",
"id": 1,
"label": {
"color": "#ff000000",
"font": "TypeWriter,10,-1,5,75,0,0,0,0,0",
"text": "debian",
"x": 11.1015625,
"y": -25.0
},
"linked_clone": false,
"port_name_format": "Ethernet{0}",
"ports": [
{
"adapter_number": 0,
"id": 1,
"name": "Ethernet0",
"port_number": 0
}
],
"properties": {
"acpi_shutdown": false,
"adapter_type": "Intel PRO/1000 MT Desktop (82540EM)",
"adapters": 1,
"console": 5000,
"enable_remote_console": false,
"headless": false,
"name": "debian",
"ram": 512,
"use_any_adapter": false,
"vmname": "debian"
},
"server_id": 3,
"type": "VirtualBoxVM",
"vm_id": "af5fa728-85da-44f1-b17a-e99a65a7037e",
"x": -48.5,
"y": -43.5
}
],
"servers": [
{
"host": "127.0.0.1",
"id": 3,
"local": true,
"port": 3080,
"protocol": "http",
"vm": false
}
]
},
"type": "topology",
"version": "1.5.1dev1"
}

@ -0,0 +1,51 @@
{
"name": "1_5_vmware",
"project_id": "4be1f3e5-76e5-4223-93b7-f37f4091549e",
"revision": 5,
"auto_start": false,
"topology": {
"computes": [
{
"compute_id": "local",
"host": "127.0.0.1",
"name": "Local",
"port": 3080,
"protocol": "http"
}
],
"drawings": [],
"links": [],
"nodes": [
{
"compute_id": "local",
"console": 2000,
"console_type": "telnet",
"label": {
"rotation": 0,
"style": "font-family: TypeWriter;font-size: 10;font-weight: bold;fill: #000000;fill-opacity: 1.0;",
"text": "GNS3 VM",
"x": 5,
"y": -25
},
"name": "GNS3 VM",
"node_id": "9e06d0ce-e8df-4f38-bdfa-7c83e19a91c1",
"node_type": "vmware",
"properties": {
"acpi_shutdown": false,
"adapter_type": "e1000",
"adapters": 1,
"enable_remote_console": false,
"headless": false,
"use_any_adapter": false,
"vmx_path": "/Users/bob/Documents/Virtual Machines.localized/GNS3 VM.vmwarevm/GNS3 VM.vmx"
},
"symbol": ":/symbols/vmware_guest.svg",
"x": 7,
"y": 8,
"z": 1
}
]
},
"type": "topology",
"version": "2.0.0dev1"
}

@ -0,0 +1,60 @@
{
"auto_start": false,
"name": "1_5_vmware",
"project_id": "4be1f3e5-76e5-4223-93b7-f37f4091549e",
"revision": 4,
"topology": {
"nodes": [
{
"description": "VMware VM",
"id": 1,
"label": {
"color": "#ff000000",
"font": "TypeWriter,10,-1,5,75,0,0,0,0,0",
"text": "GNS3 VM",
"x": 5.125,
"y": -25.0
},
"linked_clone": false,
"port_name_format": "Ethernet{0}",
"ports": [
{
"adapter_number": 0,
"id": 1,
"name": "Ethernet0",
"port_number": 0
}
],
"properties": {
"acpi_shutdown": false,
"adapter_type": "e1000",
"adapters": 1,
"console": 2000,
"enable_remote_console": false,
"headless": false,
"name": "GNS3 VM",
"use_any_adapter": false,
"use_ubridge": true,
"vmx_path": "/Users/bob/Documents/Virtual Machines.localized/GNS3 VM.vmwarevm/GNS3 VM.vmx"
},
"server_id": 3,
"type": "VMwareVM",
"vm_id": "9e06d0ce-e8df-4f38-bdfa-7c83e19a91c1",
"x": 7,
"y": 8
}
],
"servers": [
{
"host": "127.0.0.1",
"id": 3,
"local": true,
"port": 3080,
"protocol": "http",
"vm": false
}
]
},
"type": "topology",
"version": "1.5.1dev1"
}

@ -0,0 +1,83 @@
{
"auto_start": false,
"name": "1_5_vpcs",
"project_id": "62fc7a04-ae65-4003-a9e6-a046b1996f0e",
"revision": 5,
"topology": {
"computes": [
{
"compute_id": "local",
"host": "127.0.0.1",
"name": "Local",
"port": 3080,
"protocol": "http"
}
],
"drawings": [],
"links": [
{
"link_id": "ANYUUID",
"nodes": [
{
"adapter_number": 0,
"node_id": "b570a150-c09f-47d9-8d32-9ca5b03234d6",
"port_number": 0
},
{
"adapter_number": 0,
"node_id": "0fd3dd4d-dc93-4a04-a9b9-7396a9e22e8b",
"port_number": 0
}
]
}
],
"nodes": [
{
"compute_id": "local",
"console": 5000,
"console_type": "telnet",
"label": {
"rotation": 0,
"style": "font-family: TypeWriter;font-size: 10;font-weight: bold;fill: #000000;fill-opacity: 1.0;",
"text": "PC1",
"x": 18,
"y": -25
},
"name": "PC1",
"node_id": "0fd3dd4d-dc93-4a04-a9b9-7396a9e22e8b",
"node_type": "vpcs",
"properties": {
"startup_script_path": "startup.vpc"
},
"symbol": ":/symbols/vpcs_guest.svg",
"x": -87,
"y": -65,
"z": 1
},
{
"compute_id": "local",
"console": 5001,
"console_type": "telnet",
"label": {
"rotation": 0,
"style": "font-family: TypeWriter;font-size: 10;font-weight: bold;fill: #000000;fill-opacity: 1.0;",
"text": "PC2",
"x": 18,
"y": -25
},
"name": "PC2",
"node_id": "b570a150-c09f-47d9-8d32-9ca5b03234d6",
"node_type": "vpcs",
"properties": {
"startup_script_path": "startup.vpc"
},
"symbol": ":/symbols/vpcs_guest.svg",
"x": 123,
"y": -65,
"z": 1
}
]
},
"type": "topology",
"version": "ANYSTR"
}

@ -0,0 +1,98 @@
{
"auto_start": false,
"name": "1_5_vpcs",
"project_id": "62fc7a04-ae65-4003-a9e6-a046b1996f0e",
"revision": 4,
"topology": {
"links": [
{
"description": "Link from PC2 port Ethernet0 to PC1 port Ethernet0",
"destination_node_id": 1,
"destination_port_id": 1,
"id": 1,
"source_node_id": 2,
"source_port_id": 2
}
],
"nodes": [
{
"description": "VPCS device",
"id": 1,
"label": {
"color": "#ff000000",
"font": "TypeWriter,10,-1,5,75,0,0,0,0,0",
"text": "PC1",
"x": 18.5859375,
"y": -25.0
},
"ports": [
{
"adapter_number": 0,
"description": "connected to PC2 on port Ethernet0",
"id": 1,
"link_id": 1,
"name": "Ethernet0",
"nio": "NIO_UDP",
"port_number": 0
}
],
"properties": {
"console": 5000,
"name": "PC1",
"startup_script_path": "startup.vpc"
},
"server_id": 3,
"symbol": ":/symbols/vpcs_guest.svg",
"type": "VPCSDevice",
"vm_id": "0fd3dd4d-dc93-4a04-a9b9-7396a9e22e8b",
"x": -87.5,
"y": -65.5
},
{
"description": "VPCS device",
"id": 2,
"label": {
"color": "#ff000000",
"font": "TypeWriter,10,-1,5,75,0,0,0,0,0",
"text": "PC2",
"x": 18.5859375,
"y": -25.0
},
"ports": [
{
"adapter_number": 0,
"description": "connected to PC1 on port Ethernet0",
"id": 2,
"link_id": 1,
"name": "Ethernet0",
"nio": "NIO_UDP",
"port_number": 0
}
],
"properties": {
"console": 5001,
"name": "PC2",
"startup_script_path": "startup.vpc"
},
"server_id": 3,
"symbol": ":/symbols/vpcs_guest.svg",
"type": "VPCSDevice",
"vm_id": "b570a150-c09f-47d9-8d32-9ca5b03234d6",
"x": 123.5,
"y": -65.5
}
],
"servers": [
{
"host": "127.0.0.1",
"id": 3,
"local": true,
"port": 3080,
"protocol": "http",
"vm": false
}
]
},
"type": "topology",
"version": "1.5.1dev1"
}

@ -0,0 +1,30 @@
This directories contain topologies made for previous version of GNS3
Each directory is a GNS3 project. You have two directory inside:
* before
* after
Before is the state of the project before conversion and after
is the reference for checking if conversion is a success.
To check if file are the same we check the file size except
for .gns3
.gns3 check
###########
The .gns3 json is loaded and compare to the reference project.
You have some special value in the after project:
* "ANYSTR" allow for any string to match
* "ANYUUID" allow for any uuid to match
Run the tests
###############
You can run the tests with:
.. code:: bash
py.test -vv -x tests/test_topologies.py
Loading…
Cancel
Save