From 1ef1872f8e9a09bfc7700916bb19639dfc2ccc96 Mon Sep 17 00:00:00 2001 From: grossmj Date: Wed, 20 Feb 2019 16:38:43 +0700 Subject: [PATCH] Reset MAC addresses when duplicating a project. Fixes #1522 --- gns3server/controller/export_project.py | 11 ++++++++--- gns3server/controller/project.py | 2 +- gns3server/schemas/dynamips_vm.py | 6 +++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/gns3server/controller/export_project.py b/gns3server/controller/export_project.py index 4e376e50..96212ce2 100644 --- a/gns3server/controller/export_project.py +++ b/gns3server/controller/export_project.py @@ -31,7 +31,7 @@ log = logging.getLogger(__name__) @asyncio.coroutine -def export_project(project, temporary_dir, include_images=False, keep_compute_id=False, allow_all_nodes=False): +def export_project(project, temporary_dir, include_images=False, keep_compute_id=False, allow_all_nodes=False, reset_mac_addresses=False): """ Export a project to a zip file. @@ -42,6 +42,7 @@ def export_project(project, temporary_dir, include_images=False, keep_compute_id :param include images: save OS images to the zip file :param keep_compute_id: If false replace all compute id by local (standard behavior for .gns3project to make it portable) :param allow_all_nodes: Allow all nodes type to be include in the zip even if not portable + :param reset_mac_addresses: Reset MAC addresses for every nodes. :returns: ZipStream object """ @@ -61,7 +62,7 @@ def export_project(project, temporary_dir, include_images=False, keep_compute_id # First we process the .gns3 in order to be sure we don't have an error for file in os.listdir(project._path): if file.endswith(".gns3"): - yield from _patch_project_file(project, os.path.join(project._path, file), zstream, include_images, keep_compute_id, allow_all_nodes, temporary_dir) + yield from _patch_project_file(project, os.path.join(project._path, file), zstream, include_images, keep_compute_id, allow_all_nodes, temporary_dir, reset_mac_addresses) # Export the local files for root, dirs, files in os.walk(project._path, topdown=True, followlinks=False): @@ -160,7 +161,7 @@ def _is_exportable(path): @asyncio.coroutine -def _patch_project_file(project, path, zstream, include_images, keep_compute_id, allow_all_nodes, temporary_dir): +def _patch_project_file(project, path, zstream, include_images, keep_compute_id, allow_all_nodes, temporary_dir, reset_mac_addresses): """ Patch a project file (.gns3) to export a project. The .gns3 file is renamed to project.gns3 @@ -193,6 +194,10 @@ def _patch_project_file(project, path, zstream, include_images, keep_compute_id, if "properties" in node and node["node_type"] != "docker": for prop, value in node["properties"].items(): + # reset the MAC address + if reset_mac_addresses and prop in ("mac_addr", "mac_address"): + node["properties"][prop] = None + if node["node_type"] == "iou": if not prop == "path": continue diff --git a/gns3server/controller/project.py b/gns3server/controller/project.py index 8c711e7d..de2b516f 100644 --- a/gns3server/controller/project.py +++ b/gns3server/controller/project.py @@ -929,7 +929,7 @@ class Project: self.dump() try: with tempfile.TemporaryDirectory() as tmpdir: - zipstream = yield from export_project(self, tmpdir, keep_compute_id=True, allow_all_nodes=True) + zipstream = yield from export_project(self, tmpdir, keep_compute_id=True, allow_all_nodes=True, reset_mac_addresses=True) project_path = os.path.join(tmpdir, "project.gns3p") yield from wait_run_in_executor(self._create_duplicate_project_file, project_path, zipstream) with open(project_path, "rb") as f: diff --git a/gns3server/schemas/dynamips_vm.py b/gns3server/schemas/dynamips_vm.py index 43b7da4f..98441f1d 100644 --- a/gns3server/schemas/dynamips_vm.py +++ b/gns3server/schemas/dynamips_vm.py @@ -137,7 +137,7 @@ VM_CREATE_SCHEMA = { }, "mac_addr": { "description": "Base MAC address", - "type": "string", + "type": ["null", "string"], "minLength": 1, "pattern": "^([0-9a-fA-F]{4}\\.){2}[0-9a-fA-F]{4}$" }, @@ -355,7 +355,7 @@ VM_UPDATE_SCHEMA = { }, "mac_addr": { "description": "Base MAC address", - "type": "string", + "type": ["null", "string"], "minLength": 1, "pattern": "^([0-9a-fA-F]{4}\\.){2}[0-9a-fA-F]{4}$" }, @@ -595,7 +595,7 @@ VM_OBJECT_SCHEMA = { }, "mac_addr": { "description": "Base MAC address", - "type": "string", + "type": ["null", "string"] #"minLength": 1, #"pattern": "^([0-9a-fA-F]{4}\\.){2}[0-9a-fA-F]{4}$" },