diff --git a/gns3server/controller/export_project.py b/gns3server/controller/export_project.py index c551cfa9..102095ec 100644 --- a/gns3server/controller/export_project.py +++ b/gns3server/controller/export_project.py @@ -123,7 +123,7 @@ def _export_project_file(project, path, z, include_images): if node["node_type"] in ["virtualbox", "vmware", "cloud"]: raise aiohttp.web.HTTPConflict(text="Topology with a {} could not be exported".format(node["node_type"])) - node["compute_id"] = "local" # To make project portable all node by default run on local + node["compute_id"] = "local" # To make project portable all node by default run on local if "properties" in node and node["node_type"] != "Docker": for prop, value in node["properties"].items(): @@ -133,12 +133,11 @@ def _export_project_file(project, path, z, include_images): images.add(value) if "topology" in topology: - topology["topology"]["computes"] = [] # Strip compute informations because could contain secret info like password + topology["topology"]["computes"] = [] # Strip compute informations because could contain secret info like password for image in images: _export_images(project, image, z) - z.writestr("project.gns3", json.dumps(topology).encode()) diff --git a/gns3server/controller/import_project.py b/gns3server/controller/import_project.py index 097b801a..354c857f 100644 --- a/gns3server/controller/import_project.py +++ b/gns3server/controller/import_project.py @@ -16,6 +16,7 @@ # along with this program. If not, see . import os +import sys import json import uuid import shutil @@ -63,6 +64,12 @@ def import_project(controller, project_id, stream): topology = load_topology(os.path.join(path, "project.gns3")) topology["name"] = project_name + # For some VM type we move them to the GNS3 VM if it's not a Linux host + if not sys.platform.startswith("linux"): + for node in topology["topology"]["nodes"]: + if node["node_type"] in ("docker", "qemu", "iou"): + node["compute_id"] = "vm" + dot_gns3_path = os.path.join(path, project_name + ".gns3") # We change the project_id to avoid erasing the project topology["project_id"] = project_id diff --git a/tests/controller/test_export_project.py b/tests/controller/test_export_project.py index c21bb178..916a79d6 100644 --- a/tests/controller/test_export_project.py +++ b/tests/controller/test_export_project.py @@ -111,7 +111,7 @@ def test_export(tmpdir, project, async_run): with myzip.open("project.gns3") as myfile: topo = json.loads(myfile.read().decode())["topology"] - assert topo["nodes"][0]["compute_id"] == "local" # All node should have compute_id local after export + assert topo["nodes"][0]["compute_id"] == "local" # All node should have compute_id local after export assert topo["computes"] == [] diff --git a/tests/controller/test_import_project.py b/tests/controller/test_import_project.py index 712db14b..440c1c9f 100644 --- a/tests/controller/test_import_project.py +++ b/tests/controller/test_import_project.py @@ -126,3 +126,94 @@ def test_import_with_images(tmpdir, async_run, controller): path = os.path.join(project._config().get("images_path"), "IOS", "test.image") assert os.path.exists(path), path + + + +def test_import_iou_non_linux(linux_platform, async_run, tmpdir, controller): + """ + On non linux host IOU should be local + """ + project_id = str(uuid.uuid4()) + + topology = { + "project_id": str(uuid.uuid4()), + "name": "test", + "type": "topology", + "topology": { + "nodes": [ + { + "compute_id": "local", + "node_type": "iou", + "properties": {} + } + ], + "links": [], + "computes": [], + "drawings": [] + }, + "revision": 5, + "version": "2.0.0" + } + + with open(str(tmpdir / "project.gns3"), 'w+') as f: + json.dump(topology, f) + + zip_path = str(tmpdir / "project.zip") + with zipfile.ZipFile(zip_path, 'w') as myzip: + myzip.write(str(tmpdir / "project.gns3"), "project.gns3") + + with open(zip_path, "rb") as f: + project = async_run(import_project(controller, project_id, f)) + + with open(os.path.join(project.path, "test.gns3")) as f: + topo = json.load(f) + assert topo["topology"]["nodes"][0]["compute_id"] == "local" + + + +def test_import_iou_non_linux(windows_platform, async_run, tmpdir, controller): + """ + On non linux host IOU should be moved to the GNS3 VM + """ + project_id = str(uuid.uuid4()) + + topology = { + "project_id": str(uuid.uuid4()), + "name": "test", + "type": "topology", + "topology": { + "nodes": [ + { + "compute_id": "local", + "node_type": "iou", + "properties": {} + }, + { + "compute_id": "local", + "node_type": "vpcs", + "properties": {} + } + ], + "links": [], + "computes": [], + "drawings": [] + }, + "revision": 5, + "version": "2.0.0" + } + + with open(str(tmpdir / "project.gns3"), 'w+') as f: + json.dump(topology, f) + + zip_path = str(tmpdir / "project.zip") + with zipfile.ZipFile(zip_path, 'w') as myzip: + myzip.write(str(tmpdir / "project.gns3"), "project.gns3") + + with open(zip_path, "rb") as f: + project = async_run(import_project(controller, project_id, f)) + + with open(os.path.join(project.path, "test.gns3")) as f: + topo = json.load(f) + assert topo["topology"]["nodes"][0]["compute_id"] == "vm" + assert topo["topology"]["nodes"][1]["compute_id"] == "local" +