1
0
mirror of https://github.com/GNS3/gns3-server synced 2024-11-24 09:18:08 +00:00

Move the generation of the list of ports to the server

Ref #676
This commit is contained in:
Julien Duponchelle 2016-09-13 09:47:22 +02:00
parent f06c00fdb8
commit 2f0e2260ab
No known key found for this signature in database
GPG Key ID: CE8B29639E07F5E8
50 changed files with 1347 additions and 240 deletions

View File

@ -30,4 +30,5 @@ GNS3 developements
.. toctree::
development
file_format
port_name_format

38
docs/port_name_format.rst Normal file
View File

@ -0,0 +1,38 @@
Port name formatting
####################
Some node like qemu allow you to personnalize the name of ports in order to match the name of the interfaces inside the emulator.
Simple syntax
==============
The first {} will be replace by the interface number
For example: "eth{}" will give:
* eth0
* eth1
* eth2
Or more verbose "eth{port0}" and "eth{0}" will do the same.
Use segments
============
Segment allow you to split your interface in multiple ports
For example "Ethernet{segment0}/{port0}" with a segment size of 3:
* Ethernet0/0
* Ethernet0/1
* Ethernet0/2
* Ethernet1/0
* Ethernet1/1
You can also change the start number.
For example "Ethernet{segment1}/{port1}" with a segment size of 3:
* Ethernet1/1
* Ethernet1/2
* Ethernet1/3
* Ethernet2/1
* Ethernet2/2
This work from port0 to port9 if you need a bigger range ask us.

View File

@ -45,9 +45,9 @@ class Cloud(BaseNode):
super().__init__(name, node_id, project, manager)
self._nios = {}
self._ports = []
self._ports_mapping = []
if ports:
self._ports = ports
self._ports_mapping = ports
def __json__(self):
@ -60,29 +60,29 @@ class Cloud(BaseNode):
return {"name": self.name,
"node_id": self.id,
"project_id": self.project.id,
"ports": self._ports,
"ports_mapping": self._ports_mapping,
"interfaces": host_interfaces,
"status": "started"}
@property
def ports(self):
def ports_mapping(self):
"""
Ports on this cloud.
:returns: ports info
"""
return self._ports
return self._ports_mapping
@ports.setter
def ports(self, ports):
@ports_mapping.setter
def ports_mapping(self, ports):
"""
Set the ports on this cloud.
:param ports: ports info
"""
self._ports = ports
self._ports_mapping = ports
@asyncio.coroutine
def create(self):

View File

@ -53,5 +53,5 @@ class Nat(Cloud):
"node_id": self.id,
"project_id": self.project.id,
"status": "started",
"ports": self.ports
"ports_mapping": self.ports
}

View File

@ -60,7 +60,7 @@ class EthernetHub(Bridge):
return {"name": self.name,
"node_id": self.id,
"project_id": self.project.id,
"ports": self._ports,
"ports_mapping": self._ports,
"status": "started"}
@property

View File

@ -65,17 +65,8 @@ class EthernetSwitch(Device):
ethernet_switch_info = {"name": self.name,
"node_id": self.id,
"project_id": self.project.id,
"ports": self._ports,
"ports_mapping": self._ports,
"status": "started"}
# ports = []
# for port_number, settings in self._mappings.items():
# ports.append({"port": port_number,
# "type": settings[0],
# "vlan": settings[1],
# "ethertype": settings[2] if len(settings) > 2 else ""})
#
# ethernet_switch_info["ports"] = ports
return ethernet_switch_info
@property

View File

@ -114,9 +114,6 @@ class QemuVM(BaseNode):
self._acpi_shutdown = False
self._cpu_throttling = 0 # means no CPU throttling
self._process_priority = "low"
self._first_port_name = ""
self._port_segment_size = 0
self._port_name_format = "Ethernet{0}"
self.mac_address = "" # this will generate a MAC address
self.adapters = 1 # creates 1 adapter by default
@ -756,30 +753,6 @@ class QemuVM(BaseNode):
kernel_command_line=kernel_command_line))
self._kernel_command_line = kernel_command_line
@property
def port_name_format(self):
return self._port_name_format
@port_name_format.setter
def port_name_format(self, val):
self._port_name_format = val
@property
def port_segment_size(self):
return self._port_segment_size
@port_segment_size.setter
def port_segment_size(self, val):
self._port_segment_size = val
@property
def first_port_name(self):
return self._first_port_name
@first_port_name.setter
def first_port_name(self, val):
self._first_port_name = val
@asyncio.coroutine
def _set_process_priority(self):
"""

View File

@ -71,9 +71,6 @@ class VirtualBoxVM(BaseNode):
self._use_any_adapter = False
self._ram = 0
self._adapter_type = "Intel PRO/1000 MT Desktop (82540EM)"
self._port_name_format = "Ethernet{0}"
self._port_segment_size = 0
self._first_port_name = None
def __json__(self):
@ -90,10 +87,7 @@ class VirtualBoxVM(BaseNode):
"ram": self.ram,
"status": self.status,
"use_any_adapter": self.use_any_adapter,
"linked_clone": self._linked_clone,
"port_name_format": self._port_name_format,
"port_segment_size": self._port_segment_size,
"first_port_name": self._first_port_name}
"linked_clone": self._linked_clone}
if self._linked_clone:
json["node_directory"] = self.working_dir
else:
@ -684,30 +678,6 @@ class VirtualBoxVM(BaseNode):
id=self.id,
adapter_type=adapter_type))
@property
def port_name_format(self):
return self._port_name_format
@port_name_format.setter
def port_name_format(self, val):
self._port_name_format = val
@property
def port_segment_size(self):
return self._port_segment_size
@port_segment_size.setter
def port_segment_size(self, val):
self._port_segment_size = val
@property
def first_port_name(self):
return self._first_port_name
@first_port_name.setter
def first_port_name(self, val):
self._first_port_name = val
@asyncio.coroutine
def _get_vm_info(self):
"""

View File

@ -70,9 +70,6 @@ class VMwareVM(BaseNode):
self._ethernet_adapters = {}
self._adapter_type = "e1000"
self._use_any_adapter = False
self._port_name_format = "Ethernet{0}"
self._port_segment_size = 0
self._first_port_name = None
if not os.path.exists(vmx_path):
raise VMwareError('VMware VM "{name}" [{id}]: could not find VMX file "{vmx_path}"'.format(name=name, id=node_id, vmx_path=vmx_path))
@ -92,10 +89,7 @@ class VMwareVM(BaseNode):
"use_any_adapter": self.use_any_adapter,
"status": self.status,
"node_directory": self.working_dir,
"linked_clone": self._linked_clone,
"port_name_format": self._port_name_format,
"port_segment_size": self._port_segment_size,
"first_port_name": self._first_port_name}
"linked_clone": self._linked_clone}
return json
@property
@ -738,30 +732,6 @@ class VMwareVM(BaseNode):
log.info("VMware VM '{name}' [{id}] is not allowed to use any adapter".format(name=self.name, id=self.id))
self._use_any_adapter = use_any_adapter
@property
def port_name_format(self):
return self._port_name_format
@port_name_format.setter
def port_name_format(self, val):
self._port_name_format = val
@property
def port_segment_size(self):
return self._port_segment_size
@port_segment_size.setter
def port_segment_size(self, val):
self._port_segment_size = val
@property
def first_port_name(self):
return self._first_port_name
@first_port_name.setter
def first_port_name(self, val):
self._first_port_name = val
@asyncio.coroutine
def adapter_add_nio_binding(self, adapter_number, nio):
"""

View File

@ -23,6 +23,7 @@ import os
from .compute import ComputeConflict
from .ports.port_factory import PortFactory, StandardPortFactory, DynamipsPortFactory
from ..utils.images import images_directories
from ..utils.qt import qt_font_to_style
@ -33,7 +34,8 @@ log = logging.getLogger(__name__)
class Node:
# This properties are used only on controller and are not forwarded to the compute
CONTROLLER_ONLY_PROPERTIES = ["x", "y", "z", "width", "height", "symbol", "label", "console_host"]
CONTROLLER_ONLY_PROPERTIES = ["x", "y", "z", "width", "height", "symbol", "label", "console_host",
"port_name_format", "first_port_name", "port_segment_size", "ports"]
def __init__(self, project, compute, name, node_id=None, node_type=None, **kwargs):
"""
@ -69,12 +71,20 @@ class Node:
self._y = 0
self._z = 0
self._symbol = None
# Update node properties with additional elements
if node_type == "iou":
self._port_name_format = "Ethernet{segment0}/{port0}"
self._port_by_adapter = 4
self.port_segment_size = 4
else:
self._port_name_format = "Ethernet{0}"
self._port_by_adapter = 1
self._port_segment_size = 0
self._first_port_name = None
# This properties will be recompute
ignore_properties = ("width", "height")
# Update node properties with additional elements
for prop in kwargs:
if prop not in ignore_properties:
try:
@ -220,6 +230,30 @@ class Node:
val["text"] = self._name
self._label = val
@property
def port_name_format(self):
return self._port_name_format
@port_name_format.setter
def port_name_format(self, val):
self._port_name_format = val
@property
def port_segment_size(self):
return self._port_segment_size
@port_segment_size.setter
def port_segment_size(self, val):
self._port_segment_size = val
@property
def first_port_name(self):
return self._first_port_name
@first_port_name.setter
def first_port_name(self, val):
self._first_port_name = val
@asyncio.coroutine
def create(self):
"""
@ -423,6 +457,27 @@ class Node:
"""
return (yield from self._compute.get("/projects/{}/{}/nodes/{}/idlepc_proposals".format(self._project.id, self._node_type, self._id), timeout=240)).json
def _list_ports(self):
"""
Generate the list of port display in the client
if the compute has sent a list we return it (use by
node where you can not personnalize the port naming).
"""
ports = []
# Some special cases
if self._node_type == "atm_switch":
for adapter_number in range(0, len(self.properties["mappings"])):
ports.append(PortFactory("ATM{}".format(adapter_number), adapter_number, adapter_number, 0, "atm"))
return ports
elif self._node_type == "frame_relay_switch":
for adapter_number in range(0, len(self.properties["mappings"])):
ports.append(PortFactory("FrameRelay{}".format(adapter_number), adapter_number, adapter_number, 0, "frame_relay"))
return ports
elif self._node_type == "dynamips":
return DynamipsPortFactory(self.properties)
else:
return StandardPortFactory(self.properties, self._port_by_adapter, self._first_port_name, self._port_name_format, self._port_segment_size)
def __repr__(self):
return "<gns3server.controller.Node {} {}>".format(self._node_type, self._name)
@ -450,7 +505,10 @@ class Node:
"z": self._z,
"width": self._width,
"height": self._height,
"symbol": self._symbol
"symbol": self._symbol,
"port_name_format": self._port_name_format,
"port_segment_size": self._port_segment_size,
"first_port_name": self._first_port_name
}
return {
"compute_id": str(self._compute.id),
@ -471,5 +529,9 @@ class Node:
"z": self._z,
"width": self._width,
"height": self._height,
"symbol": self._symbol
"symbol": self._symbol,
"port_name_format": self._port_name_format,
"port_segment_size": self._port_segment_size,
"first_port_name": self._first_port_name,
"ports": [port.__json__() for port in self._list_ports()]
}

View File

View File

@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2014 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/>.
"""
ATM port for ATM link end points.
"""
from .port import Port
class ATMPort(Port):
@staticmethod
def longNameType():
"""
Returns the long name type for this port.
:returns: string
"""
return "ATM"
@staticmethod
def shortNameType():
"""
Returns the short name type for this port.
:returns: string
"""
return "a"
@staticmethod
def linkType():
"""
Returns the link type to be used to connect this port.
:returns: string
"""
return "Serial"
@staticmethod
def dataLinkTypes():
"""
Returns the supported PCAP DLTs.
:return: dictionary
"""
return {"ATM": "DLT_ATM_RFC1483"}

View File

@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2014 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/>.
"""
Ethernet port for Ethernet link end points.
"""
from .port import Port
class EthernetPort(Port):
"""
Ethernet port.
"""
@staticmethod
def longNameType():
"""
Returns the long name type for this port.
:returns: string
"""
return "Ethernet"
@staticmethod
def shortNameType():
"""
Returns the short name type for this port.
:returns: string
"""
return "e"

View File

@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2014 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/>.
"""
FastEthernet port for Ethernet link end points.
"""
from .port import Port
class FastEthernetPort(Port):
@staticmethod
def longNameType():
"""
Returns the long name type for this port.
:returns: string
"""
return "FastEthernet"
@staticmethod
def shortNameType():
"""
Returns the short name type for this port.
:returns: string
"""
return "f"

View File

@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2014 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/>.
"""
Frame relay port for serial link end points.
"""
from .serial_port import SerialPort
class FrameRelayPort(SerialPort):
@staticmethod
def longNameType():
"""
Returns the long name type for this port.
:returns: string
"""
return "FrameRelay"
@staticmethod
def dataLinkTypes():
"""
Returns the supported PCAP DLTs.
:return: dictionary
"""
return {"Frame Relay": "DLT_FRELAY"}

View File

@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2014 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/>.
"""
GigabitEthernet port for Ethernet link end points.
"""
from .port import Port
class GigabitEthernetPort(Port):
@staticmethod
def longNameType():
"""
Returns the long name type for this port.
:returns: string
"""
return "GigabitEthernet"
@staticmethod
def shortNameType():
"""
Returns the short name type for this port.
:returns: string
"""
return "g"

View File

@ -0,0 +1,51 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2014 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/>.
class Port:
"""
Base class for port objects.
"""
def __init__(self, name, interface_number, adapter_number, port_number):
self._interface_number = interface_number
self._adapter_number = adapter_number
self._port_number = port_number
self._name = name
@staticmethod
def dataLinkTypes():
"""
Returns the supported PCAP DLTs.
:return: dictionary
"""
return {"Ethernet": "DLT_EN10MB"}
@staticmethod
def linkType():
return "Ethernet"
def __json__(self):
return {
"name": self._name,
"short_name": self.shortNameType() + "{}/{}".format(self._interface_number, self._port_number),
"data_link_types": self.dataLinkTypes(),
"port_number": self._port_number,
"adapter_number": self._adapter_number,
"link_type": self.linkType().lower()
}

View File

@ -0,0 +1,189 @@
#!/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/>.
from .atm_port import ATMPort
from .frame_relay_port import FrameRelayPort
from .gigabitethernet_port import GigabitEthernetPort
from .fastethernet_port import FastEthernetPort
from .ethernet_port import EthernetPort
from .serial_port import SerialPort
from .pos_port import POSPort
import logging
log = logging.getLogger(__name__)
PORTS = {
'atm': ATMPort,
'frame_relay': FrameRelayPort,
'fastethernet': FastEthernetPort,
'gigabitethernet': GigabitEthernetPort,
'ethernet': EthernetPort,
'serial': SerialPort
}
class PortFactory:
"""
Factory to create an Port object based on the type
"""
def __new__(cls, name, interface_number, adapter_number, port_number, port_type, **kwargs):
return PORTS[port_type](name, interface_number, adapter_number, port_number, **kwargs)
class StandardPortFactory:
"""
Create ports for standard device
"""
def __new__(cls, properties, port_by_adapter, first_port_name, port_name_format, port_segment_size):
ports = []
interface_number = segment_number = 0
if "serial_adapters" in properties:
for adapter_number in range(0, properties["serial_adapters"]):
for port_number in range(0, port_by_adapter):
ports.append(PortFactory("Serial{}/{}".format(adapter_number, port_number), adapter_number, adapter_number, port_number, "serial"))
if "ethernet_adapters" in properties:
ethernet_adapters = properties["ethernet_adapters"]
else:
ethernet_adapters = properties.get("adapters", 1)
for adapter_number in range(0, ethernet_adapters):
for port_number in range(0, port_by_adapter):
if first_port_name and adapter_number == 0:
port_name = first_port_name
else:
port_name = port_name_format.format(
interface_number,
segment_number,
adapter=adapter_number,
**cls._generate_replacement(interface_number, segment_number))
interface_number += 1
if port_segment_size and interface_number % port_segment_size == 0:
segment_number += 1
interface_number = 0
ports.append(PortFactory(port_name, adapter_number, adapter_number, port_number, "ethernet"))
return ports
@staticmethod
def _generate_replacement(interface_number, segment_number):
"""
This will generate replacement string for
{port0} => {port9}
{segment0} => {segment9}
"""
replacements = {}
for i in range(0, 9):
replacements["port" + str(i)] = interface_number + i
replacements["segment" + str(i)] = segment_number + i
return replacements
class DynamipsPortFactory:
"""
Create port for dynamips devices
"""
ADAPTER_MATRIX = {
"C1700-MB-1FE": {"nb_ports": 1,
"port": FastEthernetPort},
"C1700-MB-WIC1": {"nb_ports": 0,
"port": None},
"C2600-MB-1E": {"nb_ports": 1,
"port": EthernetPort},
"C2600-MB-1FE": {"nb_ports": 1,
"port": FastEthernetPort},
"C2600-MB-2E": {"nb_ports": 2,
"port": EthernetPort},
"C2600-MB-2FE": {"nb_ports": 2,
"port": FastEthernetPort},
"C7200-IO-2FE": {"nb_ports": 2,
"port": FastEthernetPort},
"C7200-IO-FE": {"nb_ports": 1,
"port": FastEthernetPort},
"C7200-IO-GE-E": {"nb_ports": 1,
"port": GigabitEthernetPort},
"GT96100-FE": {"nb_ports": 2,
"port": FastEthernetPort},
"Leopard-2FE": {"nb_ports": 2,
"port": FastEthernetPort},
"NM-16ESW": {"nb_ports": 16,
"port": FastEthernetPort},
"NM-1E": {"nb_ports": 1,
"port": EthernetPort},
"NM-1FE-TX": {"nb_ports": 1,
"port": FastEthernetPort},
"NM-4E": {"nb_ports": 4,
"port": EthernetPort},
"NM-4T": {"nb_ports": 4,
"port": SerialPort},
"PA-2FE-TX": {"nb_ports": 2,
"port": FastEthernetPort},
"PA-4E": {"nb_ports": 4,
"port": EthernetPort},
"PA-4T+": {"nb_ports": 4,
"port": SerialPort},
"PA-8E": {"nb_ports": 8,
"port": EthernetPort},
"PA-8T": {"nb_ports": 8,
"port": SerialPort},
"PA-A1": {"nb_ports": 1,
"port": ATMPort},
"PA-FE-TX": {"nb_ports": 1,
"port": FastEthernetPort},
"PA-GE": {"nb_ports": 1,
"port": GigabitEthernetPort},
"PA-POS-OC3": {"nb_ports": 1,
"port": POSPort},
}
WIC_MATRIX = {"WIC-1ENET": {"nb_ports": 1,
"port": EthernetPort},
"WIC-1T": {"nb_ports": 1,
"port": SerialPort},
"WIC-2T": {"nb_ports": 2,
"port": SerialPort}
}
def __new__(cls, properties):
ports = []
interface_numbers = {}
adapter_number = 0
wic_port_number = 16
for name in sorted(properties.keys()):
if name.startswith("slot") and properties[name]:
port_class = cls.ADAPTER_MATRIX[properties[name]]["port"]
if port_class:
interface_numbers.setdefault(port_class, 0)
interface_number = interface_numbers[port_class]
for port_number in range(0, cls.ADAPTER_MATRIX[properties[name]]["nb_ports"]):
name = "{}{}/{}".format(port_class.longNameType(), interface_number, port_number)
ports.append(port_class(name, interface_number, adapter_number, port_number))
interface_numbers[port_class] += 1
adapter_number += 1
elif name.startswith("wic") and properties[name]:
port_class = cls.WIC_MATRIX[properties[name]]["port"]
if port_class:
for port_number in range(0, cls.WIC_MATRIX[properties[name]]["nb_ports"]):
name = "{}{}/{}".format(port_class.longNameType(), 0, wic_port_number)
ports.append(port_class(name, 0, 0, wic_port_number))
wic_port_number += 1
return ports

View File

@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2014 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/>.
"""
POS port for Packet over SONET link end points.
"""
from .port import Port
class POSPort(Port):
@staticmethod
def longNameType():
"""
Returns the long name type for this port.
:returns: string
"""
return "POS"
@staticmethod
def shortNameType():
"""
Returns the short name type for this port.
:returns: string
"""
return "p"
@staticmethod
def linkType():
"""
Returns the link type to be used to connect this port.
:returns: string
"""
return "Serial"
@staticmethod
def dataLinkTypes():
"""
Returns the supported PCAP DLTs.
:return: dictionary
"""
# Packet capture on PoS is not supported
return {}

View File

@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2014 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/>.
"""
Serial port for serial link end points.
"""
from .port import Port
class SerialPort(Port):
@staticmethod
def longNameType():
"""
Returns the long name type for this port.
:returns: string
"""
return "Serial"
@staticmethod
def shortNameType():
"""
Returns the short name type for this port.
:returns: string
"""
return "s"
@staticmethod
def linkType():
"""
Returns the link type to be used to connect this port.
:returns: string
"""
return "Serial"
@staticmethod
def dataLinkTypes():
"""
Returns the supported PCAP DLTs.
:return: dictionary
"""
return {"Frame Relay": "DLT_FRELAY",
"Cisco HDLC": "DLT_C_HDLC",
"Cisco PPP": "DLT_PPP_SERIAL"}

View File

@ -179,6 +179,9 @@ def _convert_1_3_later(topo, topo_path):
node["x"] = int(old_node["x"])
node["y"] = int(old_node["y"])
node["z"] = int(old_node.get("z", 1))
node["port_name_format"] = old_node.get("port_name_format", "Ethernet{0}")
node["port_segment_size"] = int(old_node.get("port_segment_size", "0"))
node["first_port_name"] = old_node.get("first_port_name")
node["properties"] = {}
@ -196,21 +199,21 @@ def _convert_1_3_later(topo, topo_path):
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"] = []
node["symbol"] = ":/symbols/hub.svg"
node["properties"]["ports_mapping"] = []
for port in old_node["ports"]:
node["properties"]["ports"].append({
node["properties"]["ports_mapping"].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
node["properties"]["ports_mapping"] = []
for port in old_node["ports"]:
node["properties"]["ports"].append({
node["properties"]["ports_mapping"].append({
"name": "Ethernet{}".format(port["port_number"]),
"port_number": port["port_number"],
"type": port["type"],
@ -439,7 +442,7 @@ def _create_cloud(node, old_node, icon):
}
ports.append(port)
node["properties"]["ports"] = ports
node["properties"]["ports_mapping"] = ports
node["properties"]["interfaces"] = []

View File

@ -55,7 +55,7 @@ class CloudHandler:
request.match_info["project_id"],
request.json.get("node_id"),
node_type="cloud",
ports=request.json.get("ports"))
ports=request.json.get("ports_mapping"))
response.set_status(201)
response.json(node)

View File

@ -57,7 +57,7 @@ class EthernetHubHandler:
request.match_info["project_id"],
request.json.get("node_id"),
device_type="ethernet_hub",
ports=request.json.get("ports"))
ports=request.json.get("ports_mapping"))
# On Linux, use the generic hub
# builtin_manager = Builtin.instance()
@ -112,8 +112,8 @@ class EthernetHubHandler:
node = dynamips_manager.get_device(request.match_info["node_id"], project_id=request.match_info["project_id"])
if "name" in request.json and node.name != request.json["name"]:
yield from node.set_name(request.json["name"])
if "ports" in request.json:
node.ports = request.json["ports"]
if "ports_mapping" in request.json:
node.ports_mapping = request.json["ports_mapping"]
# builtin_manager = Builtin.instance()
# node = builtin_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])

View File

@ -57,7 +57,7 @@ class EthernetSwitchHandler:
request.match_info["project_id"],
request.json.get("node_id"),
device_type="ethernet_switch",
ports=request.json.get("ports"))
ports=request.json.get("ports_mapping"))
# On Linux, use the generic switch
# builtin_manager = Builtin.instance()
@ -112,8 +112,8 @@ class EthernetSwitchHandler:
node = dynamips_manager.get_device(request.match_info["node_id"], project_id=request.match_info["project_id"])
if "name" in request.json and node.name != request.json["name"]:
yield from node.set_name(request.json["name"])
if "ports" in request.json:
node.ports = request.json["ports"]
if "ports_mapping" in request.json:
node.ports_mapping = request.json["ports_mapping"]
# builtin_manager = Builtin.instance()
# node = builtin_manager.get_node(request.match_info["node_id"], project_id=request.match_info["project_id"])

View File

@ -55,7 +55,7 @@ class NatHandler:
request.match_info["project_id"],
request.json.get("node_id"),
node_type="nat",
ports=request.json.get("ports"))
ports=request.json.get("ports_mapping"))
response.set_status(201)
response.json(node)

View File

@ -56,7 +56,7 @@ CLOUD_CREATE_SCHEMA = {
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"}
]
},
"ports": {
"ports_mapping": {
"type": "array",
"items": [
PORT_OBJECT_SCHEMA
@ -103,7 +103,7 @@ CLOUD_OBJECT_SCHEMA = {
"maxLength": 36,
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
},
"ports": {
"ports_mapping": {
"type": "array",
"items": [
PORT_OBJECT_SCHEMA
@ -124,7 +124,7 @@ CLOUD_OBJECT_SCHEMA = {
},
},
"additionalProperties": False,
"required": ["name", "node_id", "project_id", "ports"]
"required": ["name", "node_id", "project_id", "ports_mapping"]
}
CLOUD_UPDATE_SCHEMA = CLOUD_OBJECT_SCHEMA

View File

@ -54,7 +54,7 @@ ETHERNET_HUB_CREATE_SCHEMA = {
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"}
]
},
"ports": {
"ports_mapping": {
"type": "array",
"items": [
{"type": "object",
@ -111,7 +111,7 @@ ETHERNET_HUB_OBJECT_SCHEMA = {
"maxLength": 36,
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
},
"ports": {
"ports_mapping": {
"type": "array",
"items": [
{"type": "object",
@ -126,7 +126,7 @@ ETHERNET_HUB_OBJECT_SCHEMA = {
},
},
"additionalProperties": False,
"required": ["name", "node_id", "project_id", "ports"]
"required": ["name", "node_id", "project_id", "ports_mapping"]
}
ETHERNET_HUB_UPDATE_SCHEMA = ETHERNET_HUB_OBJECT_SCHEMA

View File

@ -66,7 +66,7 @@ ETHERNET_SWITCH_CREATE_SCHEMA = {
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"}
]
},
"ports": {
"ports_mapping": {
"type": "array",
"items": [
{"type": "object",
@ -135,7 +135,7 @@ ETHERNET_SWITCH_OBJECT_SCHEMA = {
"maxLength": 36,
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
},
"ports": {
"ports_mapping": {
"type": "array",
"items": [
{"type": "object",

View File

@ -46,7 +46,7 @@ NAT_OBJECT_SCHEMA = {
"description": "Node status",
"enum": ["started", "stopped", "suspended"]
},
"ports": {
"ports_mapping": {
"type": "array",
"items": [
PORT_OBJECT_SCHEMA

View File

@ -168,6 +168,55 @@ NODE_OBJECT_SCHEMA = {
"z": {
"description": "Z position of the node",
"type": "integer"
},
"port_name_format": {
"description": "Formating for port name {0} will be replace by port number",
"type": "string"
},
"port_segment_size": {
"description": "Size of the port segment",
"type": "integer",
"minimum": 0
},
"first_port_name": {
"description": "Name of the first port",
"type": ["string", "null"],
},
"ports": {
"description": "List of node ports READ only",
"type": "array",
"items": {
"type": "object",
"description": "A node port",
"properties": {
"name": {
"type": "string",
"description": "Port name",
},
"short_name": {
"type": "string",
"description": "Short version of port name",
},
"adapter_number": {
"type": "integer",
"description": "Adapter slot"
},
"port_number": {
"type": "integer",
"description": "Port slot"
},
"link_type": {
"description": "Type of link",
"enum": ["ethernet", "serial"]
},
"data_link_types": {
"type": "object",
"description": "Available PCAP type for capture",
"properties": {}
},
},
"additionalProperties": False
}
}
},
"additionalProperties": False,

View File

@ -199,19 +199,6 @@ QEMU_CREATE_SCHEMA = {
"options": {
"description": "Additional QEMU options",
"type": ["string", "null"],
},
"port_name_format": {
"description": "Formating for port name {0} will be replace by port number",
"type": "string"
},
"port_segment_size": {
"description": "Size of the port segment",
"type": "integer",
"minimum": 0
},
"first_port_name": {
"description": "Name of the first port",
"type": ["string", "null"],
}
},
"additionalProperties": False,
@ -389,19 +376,6 @@ QEMU_UPDATE_SCHEMA = {
"options": {
"description": "Additional QEMU options",
"type": ["string", "null"],
},
"port_name_format": {
"description": "Formating for port name {0} will be replace by port number",
"type": "string"
},
"port_segment_size": {
"description": "Size of the port segment",
"type": "integer",
"minimum": 0
},
"first_port_name": {
"description": "Name of the first port",
"type": ["string", "null"],
}
},
"additionalProperties": False,
@ -595,19 +569,6 @@ QEMU_OBJECT_SCHEMA = {
"command_line": {
"description": "Last command line used by GNS3 to start QEMU",
"type": "string"
},
"port_name_format": {
"description": "Formating for port name {0} will be replace by port number",
"type": "string"
},
"port_segment_size": {
"description": "Size of the port segment",
"type": "integer",
"minimum": 0
},
"first_port_name": {
"description": "Name of the first port",
"type": "string",
}
},
"additionalProperties": False,
@ -651,10 +612,7 @@ QEMU_OBJECT_SCHEMA = {
"options",
"node_directory",
"command_line",
"status",
"port_name_format",
"first_port_name",
"port_segment_size"]
"status"]
}
QEMU_BINARY_FILTER_SCHEMA = {

View File

@ -103,10 +103,12 @@ TOPOLOGY_SCHEMA = {
def main():
import jsonschema
import json
import sys
with open(sys.argv[1]) as f:
jsonschema.validate(f.read(), TOPOLOGY_SCHEMA)
data = json.load(f)
jsonschema.validate(data, TOPOLOGY_SCHEMA)
if __name__ == '__main__':

View File

@ -83,19 +83,6 @@ VBOX_CREATE_SCHEMA = {
"acpi_shutdown": {
"description": "ACPI shutdown",
"type": "boolean"
},
"port_name_format": {
"description": "Formating for port name {0} will be replace by port number",
"type": "string"
},
"port_segment_size": {
"description": "Size of the port segment",
"type": "integer",
"minimum": 0
},
"first_port_name": {
"description": "Name of the first port",
"type": ["string", "null"]
}
},
"additionalProperties": False,
@ -182,19 +169,6 @@ VBOX_OBJECT_SCHEMA = {
"linked_clone": {
"description": "Whether the VM is a linked clone or not",
"type": "boolean"
},
"port_name_format": {
"description": "Formating for port name {0} will be replace by port number",
"type": "string"
},
"port_segment_size": {
"description": "Size of the port segment",
"type": "integer",
"minimum": 0
},
"first_port_name": {
"description": "Name of the first port",
"type": ["string", "null"]
}
},
"additionalProperties": False,

View File

@ -74,19 +74,6 @@ VMWARE_CREATE_SCHEMA = {
"use_any_adapter": {
"description": "Allow GNS3 to use any VMware adapter",
"type": "boolean",
},
"port_name_format": {
"description": "Formating for port name {0} will be replace by port number",
"type": "string"
},
"port_segment_size": {
"description": "Size of the port segment",
"type": "integer",
"minimum": 0
},
"first_port_name": {
"description": "Name of the first port",
"type": ["string", "null"]
}
},
"additionalProperties": False,
@ -167,19 +154,6 @@ VMWARE_OBJECT_SCHEMA = {
"linked_clone": {
"description": "Whether the VM is a linked clone or not",
"type": "boolean"
},
"port_name_format": {
"description": "Formating for port name {0} will be replace by port number",
"type": "string"
},
"port_segment_size": {
"description": "Size of the port segment",
"type": "integer",
"minimum": 0
},
"first_port_name": {
"description": "Name of the first port",
"type": ["string", "null"]
}
},
"additionalProperties": False

View File

@ -29,7 +29,7 @@ def test_json(on_gns3vm, project):
"node_id": nat.id,
"project_id": project.id,
"status": "started",
"ports": [
"ports_mapping": [
{
"interface": "virbr0",
"name": "virbr0",

View File

@ -101,7 +101,20 @@ def test_json(node, compute):
"width": node.width,
"height": node.height,
"symbol": node.symbol,
"label": node.label
"label": node.label,
"port_name_format": "Ethernet{0}",
"port_segment_size": 0,
"first_port_name": None,
"ports": [
{
"adapter_number": 0,
"data_link_types": {"Ethernet": "DLT_EN10MB"},
"link_type": "ethernet",
"name": "Ethernet0",
"port_number": 0,
"short_name": "e0/0"
}
]
}
assert node.__json__(topology_dump=True) == {
"compute_id": str(compute.id),
@ -117,7 +130,10 @@ def test_json(node, compute):
"width": node.width,
"height": node.height,
"symbol": node.symbol,
"label": node.label
"label": node.label,
"port_name_format": "Ethernet{0}",
"port_segment_size": 0,
"first_port_name": None
}

View File

@ -0,0 +1,446 @@
#!/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/>.
import pytest
import uuid
from tests.utils import AsyncioMagicMock
from gns3server.controller.node import Node
from gns3server.controller.project import Project
@pytest.fixture
def compute():
s = AsyncioMagicMock()
s.id = "http://test.com:42"
return s
@pytest.fixture
def project(controller):
return Project(str(uuid.uuid4()), controller=controller)
@pytest.fixture
def node(compute, project):
node = Node(project, compute, "demo",
node_id=str(uuid.uuid4()),
node_type="vpcs",
console_type="vnc",
properties={"startup_script": "echo test"})
return node
def test_list_ports(node):
"""
List port by default
"""
assert node.__json__()["ports"] == [
{
"name": "Ethernet0",
"short_name": "e0/0",
"data_link_types": {"Ethernet": "DLT_EN10MB"},
"port_number": 0,
"adapter_number": 0,
"link_type": "ethernet"
}
]
def test_list_ports_port_name_format(node):
"""
Support port name format
"""
node._first_port_name = None
node._port_name_format = "eth{}"
assert node.__json__()["ports"][0]["name"] == "eth0"
node._port_name_format = "eth{port0}"
assert node.__json__()["ports"][0]["name"] == "eth0"
node._port_name_format = "eth{port1}"
assert node.__json__()["ports"][0]["name"] == "eth1"
node._first_port_name = ""
node._port_segment_size = 2
node._port_name_format = "eth{segment0}/{port0}"
node.properties["adapters"] = 8
assert node.__json__()["ports"][6]["name"] == "eth3/0"
assert node.__json__()["ports"][7]["name"] == "eth3/1"
node._first_port_name = "mgnt0"
assert node.__json__()["ports"][0]["name"] == "mgnt0"
assert node.__json__()["ports"][1]["name"] == "eth0/0"
def test_list_ports_adapters(node):
"""
List port using adapters properties
"""
node.properties["adapters"] = 2
assert node.__json__()["ports"] == [
{
"name": "Ethernet0",
"short_name": "e0/0",
"data_link_types": {"Ethernet": "DLT_EN10MB"},
"port_number": 0,
"adapter_number": 0,
"link_type": "ethernet"
},
{
"name": "Ethernet1",
"short_name": "e1/0",
"data_link_types": {"Ethernet": "DLT_EN10MB"},
"port_number": 0,
"adapter_number": 1,
"link_type": "ethernet"
}
]
def test_list_ports_atm_switch(project, compute):
"""
List port for atm switch
"""
node = Node(project, compute, "demo",
node_id=str(uuid.uuid4()),
node_type="atm_switch")
node.properties["mappings"] = {
"1:0:100": "10:0:200"
}
assert node.__json__()["ports"] == [
{
"name": "ATM0",
"short_name": "a0/0",
"data_link_types": {"ATM": "DLT_ATM_RFC1483"},
"port_number": 0,
"adapter_number": 0,
"link_type": "serial"
}
]
def test_list_ports_frame_relay_switch(project, compute):
"""
List port for frame relay switch
"""
node = Node(project, compute, "demo",
node_id=str(uuid.uuid4()),
node_type="frame_relay_switch")
node.properties["mappings"] = {
"1:0:100": "10:0:200"
}
assert node.__json__()["ports"] == [
{
"name": "FrameRelay0",
"short_name": "s0/0",
"data_link_types": {"Frame Relay": "DLT_FRELAY"},
"port_number": 0,
"adapter_number": 0,
"link_type": "serial"
}
]
def test_list_ports_iou(compute, project):
"""
IOU has a special behavior 4 port by adapters
"""
node = Node(project, compute, "demo",
node_id=str(uuid.uuid4()),
node_type="iou")
node.properties["serial_adapters"] = 2
node.properties["ethernet_adapters"] = 3
assert node.__json__()["ports"] == [
{
"name": "Serial0/0",
"short_name": "s0/0",
"data_link_types": {
"Frame Relay": "DLT_FRELAY",
"Cisco HDLC": "DLT_C_HDLC",
"Cisco PPP": "DLT_PPP_SERIAL"
},
"port_number": 0,
"adapter_number": 0,
"link_type": "serial"
},
{
"name": "Serial0/1",
"short_name": "s0/1",
"data_link_types": {
"Frame Relay": "DLT_FRELAY",
"Cisco HDLC": "DLT_C_HDLC",
"Cisco PPP": "DLT_PPP_SERIAL"
},
"port_number": 1,
"adapter_number": 0,
"link_type": "serial"
},
{
"name": "Serial0/2",
"short_name": "s0/2",
"data_link_types": {
"Frame Relay": "DLT_FRELAY",
"Cisco HDLC": "DLT_C_HDLC",
"Cisco PPP": "DLT_PPP_SERIAL"
},
"port_number": 2,
"adapter_number": 0,
"link_type": "serial"
},
{
"name": "Serial0/3",
"short_name": "s0/3",
"data_link_types": {
"Frame Relay": "DLT_FRELAY",
"Cisco HDLC": "DLT_C_HDLC",
"Cisco PPP": "DLT_PPP_SERIAL"
},
"port_number": 3,
"adapter_number": 0,
"link_type": "serial"
},
{
"name": "Serial1/0",
"short_name": "s1/0",
"data_link_types": {
"Frame Relay": "DLT_FRELAY",
"Cisco HDLC": "DLT_C_HDLC",
"Cisco PPP": "DLT_PPP_SERIAL"
},
"port_number": 0,
"adapter_number": 1,
"link_type": "serial"
},
{
"name": "Serial1/1",
"short_name": "s1/1",
"data_link_types": {
"Frame Relay": "DLT_FRELAY",
"Cisco HDLC": "DLT_C_HDLC",
"Cisco PPP": "DLT_PPP_SERIAL"
},
"port_number": 1,
"adapter_number": 1,
"link_type": "serial"
},
{
"name": "Serial1/2",
"short_name": "s1/2",
"data_link_types": {
"Frame Relay": "DLT_FRELAY",
"Cisco HDLC": "DLT_C_HDLC",
"Cisco PPP": "DLT_PPP_SERIAL"
},
"port_number": 2,
"adapter_number": 1,
"link_type": "serial"
},
{
"name": "Serial1/3",
"short_name": "s1/3",
"data_link_types": {
"Frame Relay": "DLT_FRELAY",
"Cisco HDLC": "DLT_C_HDLC",
"Cisco PPP": "DLT_PPP_SERIAL"
},
"port_number": 3,
"adapter_number": 1,
"link_type": "serial"
},
{
"name": "Ethernet0/0",
"short_name": "e0/0",
"data_link_types": {"Ethernet": "DLT_EN10MB"},
"port_number": 0,
"adapter_number": 0,
"link_type": "ethernet"
},
{
"name": "Ethernet0/1",
"short_name": "e0/1",
"data_link_types": {"Ethernet": "DLT_EN10MB"},
"port_number": 1,
"adapter_number": 0,
"link_type": "ethernet"
},
{
"name": "Ethernet0/2",
"short_name": "e0/2",
"data_link_types": {"Ethernet": "DLT_EN10MB"},
"port_number": 2,
"adapter_number": 0,
"link_type": "ethernet"
},
{
"name": "Ethernet0/3",
"short_name": "e0/3",
"data_link_types": {"Ethernet": "DLT_EN10MB"},
"port_number": 3,
"adapter_number": 0,
"link_type": "ethernet"
},
{
"name": "Ethernet1/0",
"short_name": "e1/0",
"data_link_types": {"Ethernet": "DLT_EN10MB"},
"port_number": 0,
"adapter_number": 1,
"link_type": "ethernet"
},
{
"name": "Ethernet1/1",
"short_name": "e1/1",
"data_link_types": {"Ethernet": "DLT_EN10MB"},
"port_number": 1,
"adapter_number": 1,
"link_type": "ethernet"
},
{
"name": "Ethernet1/2",
"short_name": "e1/2",
"data_link_types": {"Ethernet": "DLT_EN10MB"},
"port_number": 2,
"adapter_number": 1,
"link_type": "ethernet"
},
{
"name": "Ethernet1/3",
"short_name": "e1/3",
"data_link_types": {"Ethernet": "DLT_EN10MB"},
"port_number": 3,
"adapter_number": 1,
"link_type": "ethernet"
},
{
"name": "Ethernet2/0",
"short_name": "e2/0",
"data_link_types": {"Ethernet": "DLT_EN10MB"},
"port_number": 0,
"adapter_number": 2,
"link_type": "ethernet"
},
{
"name": "Ethernet2/1",
"short_name": "e2/1",
"data_link_types": {"Ethernet": "DLT_EN10MB"},
"port_number": 1,
"adapter_number": 2,
"link_type": "ethernet"
},
{
"name": "Ethernet2/2",
"short_name": "e2/2",
"data_link_types": {"Ethernet": "DLT_EN10MB"},
"port_number": 2,
"adapter_number": 2,
"link_type": "ethernet"
},
{
"name": "Ethernet2/3",
"short_name": "e2/3",
"data_link_types": {"Ethernet": "DLT_EN10MB"},
"port_number": 3,
"adapter_number": 2,
"link_type": "ethernet"
}
]
def test_list_ports_dynamips(project, compute):
"""
List port for dynamips
"""
node = Node(project, compute, "demo",
node_id=str(uuid.uuid4()),
node_type="dynamips")
node.properties["slot0"] = "C7200-IO-FE"
node.properties["slot1"] = "GT96100-FE"
node.properties["wic0"] = "WIC-2T"
node.properties["wic1"] = "WIC-2T"
assert node.__json__()["ports"] == [
{
"name": "FastEthernet0/0",
"short_name": "f0/0",
"data_link_types": {"Ethernet": "DLT_EN10MB"},
"port_number": 0,
"adapter_number": 0,
"link_type": "ethernet"
},
{
"name": "FastEthernet1/0",
"short_name": "f1/0",
"data_link_types": {"Ethernet": "DLT_EN10MB"},
"port_number": 0,
"adapter_number": 1,
"link_type": "ethernet"
},
{
"name": "FastEthernet1/1",
"short_name": "f1/1",
"data_link_types": {"Ethernet": "DLT_EN10MB"},
"port_number": 1,
"adapter_number": 1,
"link_type": "ethernet"
},
{
"name": "Serial0/16",
"short_name": "s0/16",
"data_link_types": {
"Cisco HDLC": "DLT_C_HDLC",
"Cisco PPP": "DLT_PPP_SERIAL",
"Frame Relay": "DLT_FRELAY"},
"port_number": 16,
"adapter_number": 0,
"link_type": "serial"
},
{
"name": "Serial0/17",
"short_name": "s0/17",
"data_link_types": {
"Cisco HDLC": "DLT_C_HDLC",
"Cisco PPP": "DLT_PPP_SERIAL",
"Frame Relay": "DLT_FRELAY"},
"port_number": 17,
"adapter_number": 0,
"link_type": "serial"
},
{
"name": "Serial0/18",
"short_name": "s0/18",
"data_link_types": {
"Cisco HDLC": "DLT_C_HDLC",
"Cisco PPP": "DLT_PPP_SERIAL",
"Frame Relay": "DLT_FRELAY"},
"port_number": 18,
"adapter_number": 0,
"link_type": "serial"
},
{
"name": "Serial0/19",
"short_name": "s0/19",
"data_link_types": {
"Cisco HDLC": "DLT_C_HDLC",
"Cisco PPP": "DLT_PPP_SERIAL",
"Frame Relay": "DLT_FRELAY"},
"port_number": 19,
"adapter_number": 0,
"link_type": "serial"
}
]

View File

@ -31,6 +31,9 @@
"name": "R1",
"node_id": "0bce6ad5-c688-4d4d-a425-f21aaf3927e2",
"node_type": "dynamips",
"port_name_format": "Ethernet{0}",
"port_segment_size": 0,
"first_port_name": null,
"properties": {
"dynamips_id": 1,
"auto_delete_disks": true,

View File

@ -30,6 +30,9 @@
"name": "ATM1",
"node_id": "ANYUUID",
"node_type": "atm_switch",
"port_name_format": "Ethernet{0}",
"port_segment_size": 0,
"first_port_name": null,
"properties": {
"mappings": {
"1:0:100": "10:0:200"
@ -54,8 +57,11 @@
"name": "HUB1",
"node_id": "ANYUUID",
"node_type": "ethernet_hub",
"port_name_format": "Ethernet{0}",
"port_segment_size": 0,
"first_port_name": null,
"properties": {
"ports": [
"ports_mapping": [
{
"name": "Ethernet1",
"port_number": 1
@ -109,8 +115,11 @@
"name": "SW1",
"node_id": "ANYUUID",
"node_type": "ethernet_switch",
"port_name_format": "Ethernet{0}",
"port_segment_size": 0,
"first_port_name": null,
"properties": {
"ports": [
"ports_mapping": [
{
"name": "Ethernet1",
"port_number": 1,
@ -180,6 +189,9 @@
"name": "FR1",
"node_id": "ANYUUID",
"node_type": "frame_relay_switch",
"port_name_format": "Ethernet{0}",
"port_segment_size": 0,
"first_port_name": null,
"properties": {
"mappings": {
"1:101": "10:202"

View File

@ -30,10 +30,13 @@
"name": "Cloud 1",
"node_id": "ANYUUID",
"node_type": "cloud",
"port_name_format": "Ethernet{0}",
"port_segment_size": 0,
"first_port_name": null,
"properties": {
"interfaces": [
],
"ports": [
"ports_mapping": [
{
"interface": "bridge0",
"name": "bridge0",

View File

@ -30,6 +30,9 @@
"name": "remote_busybox-1",
"node_id": "d397ef5a-84f1-4b6b-9d44-671937ec7781",
"node_type": "docker",
"port_name_format": "Ethernet{0}",
"port_segment_size": 0,
"first_port_name": null,
"properties": {
"adapters": 1,
"aux": 6002,

View File

@ -30,6 +30,9 @@
"name": "R1",
"node_id": "11845dea-f175-495b-9fc5-bf20a2262016",
"node_type": "dynamips",
"port_name_format": "Ethernet{0}",
"port_segment_size": 0,
"first_port_name": null,
"properties": {
"auto_delete_disks": true,
"clock_divisor": 8,
@ -72,6 +75,9 @@
"name": "ESW1",
"node_id": "4478a968-72a1-4722-9039-db7561c717c4",
"node_type": "dynamips",
"port_name_format": "Ethernet{0}",
"port_segment_size": 0,
"first_port_name": null,
"properties": {
"auto_delete_disks": false,
"chassis": "3660",

View File

@ -30,10 +30,13 @@
"name": "Host 1",
"node_id": "ANYUUID",
"node_type": "cloud",
"port_name_format": "Ethernet{0}",
"port_segment_size": 0,
"first_port_name": null,
"properties": {
"interfaces": [
],
"ports": [
"ports_mapping": [
{"interface": "bridge0", "port_number": 1, "type": "ethernet", "name": "bridge0"},
{"interface": "en0", "port_number": 2, "type": "ethernet", "name": "en0"},
{"interface": "en1", "port_number": 3, "type": "ethernet", "name": "en1"},

View File

@ -40,6 +40,9 @@
"name": "Internet 0.1-1",
"node_id": "b8bef484-89d2-42a7-b151-6ead2eda965e",
"node_type": "nat",
"port_name_format": "Ethernet{0}",
"port_segment_size": 0,
"first_port_name": null,
"properties": {
"ports": [
{
@ -69,6 +72,9 @@
"name": "PC1",
"node_id": "761c5e9e-eded-45b5-b6db-ca367b1855e2",
"node_type": "vpcs",
"port_name_format": "Ethernet{0}",
"port_segment_size": 0,
"first_port_name": null,
"properties": {
"startup_script_path": "startup.vpc"
},

View File

@ -30,6 +30,9 @@
"name": "IOU1",
"node_id": "aaeb2288-a7d8-42a9-b9d8-c42ab464a390",
"node_type": "iou",
"port_name_format": "Ethernet{0}",
"port_segment_size": 0,
"first_port_name": null,
"properties": {
"ethernet_adapters": 2,
"l1_keepalives": false,

View File

@ -30,6 +30,9 @@
"name": "MicroCore-1",
"node_id": "426face4-7f73-436b-88fa-050e3ee101e9",
"node_type": "qemu",
"port_name_format": "Ethernet{0}",
"port_segment_size": 0,
"first_port_name": null,
"properties": {
"acpi_shutdown": false,
"adapter_type": "e1000",

View File

@ -14,6 +14,9 @@
"name" : "PC1",
"symbol" : ":/symbols/vpcs_guest.svg",
"console_type" : "telnet",
"port_name_format": "Ethernet{0}",
"port_segment_size": 0,
"first_port_name": null,
"properties" : {
"startup_script_path" : "startup.vpc"
},

View File

@ -30,6 +30,9 @@
"name": "debian",
"node_id": "af5fa728-85da-44f1-b17a-e99a65a7037e",
"node_type": "virtualbox",
"port_name_format": "Ethernet{0}",
"port_segment_size": 0,
"first_port_name": null,
"properties": {
"acpi_shutdown": false,
"adapter_type": "Intel PRO/1000 MT Desktop (82540EM)",

View File

@ -30,6 +30,9 @@
"name": "GNS3 VM",
"node_id": "9e06d0ce-e8df-4f38-bdfa-7c83e19a91c1",
"node_type": "vmware",
"port_name_format": "Ethernet{0}",
"port_segment_size": 0,
"first_port_name": null,
"properties": {
"acpi_shutdown": false,
"adapter_type": "e1000",

View File

@ -46,6 +46,9 @@
"name": "PC1",
"node_id": "0fd3dd4d-dc93-4a04-a9b9-7396a9e22e8b",
"node_type": "vpcs",
"port_name_format": "Ethernet{0}",
"port_segment_size": 0,
"first_port_name": null,
"properties": {
"startup_script_path": "startup.vpc"
},
@ -68,6 +71,9 @@
"name": "PC2",
"node_id": "b570a150-c09f-47d9-8d32-9ca5b03234d6",
"node_type": "vpcs",
"port_name_format": "Ethernet{0}",
"port_segment_size": 0,
"first_port_name": null,
"properties": {
"startup_script_path": "startup.vpc"
},