diff --git a/gns3server/compute/builtin/nodes/cloud.py b/gns3server/compute/builtin/nodes/cloud.py index 603f63f1..dc963efc 100644 --- a/gns3server/compute/builtin/nodes/cloud.py +++ b/gns3server/compute/builtin/nodes/cloud.py @@ -23,7 +23,7 @@ from ...error import NodeError from ...base_node import BaseNode from ...nios.nio_udp import NIOUDP -from gns3server.utils.interfaces import interfaces +import gns3server.utils.interfaces import gns3server.utils.asyncio import logging @@ -41,18 +41,29 @@ class Cloud(BaseNode): :param manager: Parent VM Manager """ - def __init__(self, name, node_id, project, manager, ports=None): + def __init__(self, name, node_id, project, manager, ports=[]): super().__init__(name, node_id, project, manager) self._nios = {} - self._ports_mapping = [] - if ports: + # If the cloud is not configured we fill it with host interfaces + if not ports or len(ports) == 0: + self._ports_mapping = [] + network_interfaces = gns3server.utils.interfaces.interfaces() + for interface in network_interfaces: + if not interface["special"]: + self._ports_mapping.append({ + "interface": interface["name"], + "type": interface["type"], + "port_number": len(self._ports_mapping), + "name": interface["name"] + }) + else: self._ports_mapping = ports def __json__(self): host_interfaces = [] - network_interfaces = interfaces() + network_interfaces = gns3server.utils.interfaces.interfaces() for interface in network_interfaces: host_interfaces.append({"name": interface["name"], "type": interface["type"], diff --git a/gns3server/compute/builtin/nodes/nat.py b/gns3server/compute/builtin/nodes/nat.py index 324e977c..7e1a1582 100644 --- a/gns3server/compute/builtin/nodes/nat.py +++ b/gns3server/compute/builtin/nodes/nat.py @@ -29,19 +29,27 @@ class Nat(Cloud): """ def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - if "virbr0" not in [interface["name"] for interface in gns3server.utils.interfaces.interfaces()]: raise NodeError("virbr0 is missing. You need to install libvirt") - self.ports_mapping = [ + ports = [ { - "name": "virbr0", + "name": "nat0", "type": "ethernet", "interface": "virbr0", "port_number": 0 } ] + super().__init__(*args, ports=ports) + + @property + def ports_mapping(self): + return self._ports_mapping + + @ports_mapping.setter + def ports_mapping(self, ports): + # It's not allowed to change it + pass @classmethod def is_supported(self): diff --git a/gns3server/utils/interfaces.py b/gns3server/utils/interfaces.py index 877670c9..4dfe102c 100644 --- a/gns3server/utils/interfaces.py +++ b/gns3server/utils/interfaces.py @@ -208,7 +208,7 @@ def interfaces(): # This interface have special behavior for result in results: result["special"] = False - for special_interface in ("lo", "vmnet", "vboxnet", "docker", "lxcbr", "virbr", "ovs-system", "veth", "fw", "p2p"): + for special_interface in ("lo", "vmnet", "vboxnet", "docker", "lxcbr", "virbr", "ovs-system", "veth", "fw", "p2p", "bridge"): if result["name"].lower().startswith(special_interface): result["special"] = True diff --git a/tests/compute/builtin/nodes/test_cloud.py b/tests/compute/builtin/nodes/test_cloud.py new file mode 100644 index 00000000..361b694a --- /dev/null +++ b/tests/compute/builtin/nodes/test_cloud.py @@ -0,0 +1,85 @@ +#!/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 . + +import uuid +import pytest +from unittest.mock import MagicMock + +from gns3server.compute.builtin.nodes.cloud import Cloud + + +def test_json_with_ports(on_gns3vm, project): + ports = [ + { + "interface": "virbr0", + "name": "virbr0", + "port_number": 0, + "type": "ethernet" + } + ] + cloud = Cloud("cloud1", str(uuid.uuid4()), project, MagicMock(), ports=ports) + assert cloud.__json__() == { + "name": "cloud1", + "node_id": cloud.id, + "project_id": project.id, + "status": "started", + "ports_mapping": [ + { + "interface": "virbr0", + "name": "virbr0", + "port_number": 0, + "type": "ethernet" + } + ], + "interfaces": [ + {'name': 'eth0', 'special': False, 'type': 'ethernet'}, + {'name': 'eth1', 'special': False, 'type': 'ethernet'}, + {'name': 'virbr0', 'special': True, 'type': 'ethernet'} + ] + } + + +def test_json_without_ports(on_gns3vm, project): + """ + If no interface is provide the cloud is prefill with non special interfaces + """ + cloud = Cloud("cloud1", str(uuid.uuid4()), project, MagicMock(), ports=None) + assert cloud.__json__() == { + "name": "cloud1", + "node_id": cloud.id, + "project_id": project.id, + "status": "started", + "ports_mapping": [ + { + "interface": "eth0", + "name": "eth0", + "port_number": 0, + "type": "ethernet" + }, + { + "interface": "eth1", + "name": "eth1", + "port_number": 1, + "type": "ethernet" + } + ], + "interfaces": [ + {'name': 'eth0', 'special': False, 'type': 'ethernet'}, + {'name': 'eth1', 'special': False, 'type': 'ethernet'}, + {'name': 'virbr0', 'special': True, 'type': 'ethernet'} + ] + } diff --git a/tests/compute/builtin/nodes/test_nat.py b/tests/compute/builtin/nodes/test_nat.py index 2c90127b..8f1d9967 100644 --- a/tests/compute/builtin/nodes/test_nat.py +++ b/tests/compute/builtin/nodes/test_nat.py @@ -32,7 +32,7 @@ def test_json(on_gns3vm, project): "ports_mapping": [ { "interface": "virbr0", - "name": "virbr0", + "name": "nat0", "port_number": 0, "type": "ethernet" } diff --git a/tests/conftest.py b/tests/conftest.py index 9c4672d0..74a84217 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -318,6 +318,9 @@ def on_gns3vm(linux_platform): """ Mock the hostname to emulate the GNS3 VM """ - with patch("gns3server.utils.interfaces.interfaces", return_value=[{"name": "eth0"}, {"name": "eth1", "name": "virbr0"}]): + with patch("gns3server.utils.interfaces.interfaces", return_value=[ + {"name": "eth0", "special": False, "type": "ethernet"}, + {"name": "eth1", "special": False, "type": "ethernet"}, + {"name": "virbr0", "special": True, "type": "ethernet"}]): with patch("socket.gethostname", return_value="gns3vm"): yield