Skip to content

Commit

Permalink
Move the generation of the list of ports to the server
Browse files Browse the repository at this point in the history
Ref #676
  • Loading branch information
julien-duponchelle committed Sep 14, 2016
1 parent f06c00f commit 2f0e226
Show file tree
Hide file tree
Showing 50 changed files with 1,347 additions and 240 deletions.
1 change: 1 addition & 0 deletions docs/index.rst
Expand Up @@ -30,4 +30,5 @@ GNS3 developements
.. toctree::
development
file_format
port_name_format

38 changes: 38 additions & 0 deletions docs/port_name_format.rst
@@ -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.
16 changes: 8 additions & 8 deletions gns3server/compute/builtin/nodes/cloud.py
Expand Up @@ -45,9 +45,9 @@ def __init__(self, name, node_id, project, manager, ports=None):

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):

Expand All @@ -60,29 +60,29 @@ def __json__(self):
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):
Expand Down
2 changes: 1 addition & 1 deletion gns3server/compute/builtin/nodes/nat.py
Expand Up @@ -53,5 +53,5 @@ def __json__(self):
"node_id": self.id,
"project_id": self.project.id,
"status": "started",
"ports": self.ports
"ports_mapping": self.ports
}
2 changes: 1 addition & 1 deletion gns3server/compute/dynamips/nodes/ethernet_hub.py
Expand Up @@ -60,7 +60,7 @@ def __json__(self):
return {"name": self.name,
"node_id": self.id,
"project_id": self.project.id,
"ports": self._ports,
"ports_mapping": self._ports,
"status": "started"}

@property
Expand Down
11 changes: 1 addition & 10 deletions gns3server/compute/dynamips/nodes/ethernet_switch.py
Expand Up @@ -65,17 +65,8 @@ def __json__(self):
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
Expand Down
27 changes: 0 additions & 27 deletions gns3server/compute/qemu/qemu_vm.py
Expand Up @@ -114,9 +114,6 @@ def __init__(self, name, node_id, project, manager, linked_clone=True, qemu_path
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
Expand Down Expand Up @@ -756,30 +753,6 @@ def kernel_command_line(self, kernel_command_line):
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):
"""
Expand Down
32 changes: 1 addition & 31 deletions gns3server/compute/virtualbox/virtualbox_vm.py
Expand Up @@ -71,9 +71,6 @@ def __init__(self, name, node_id, project, manager, vmname, linked_clone, consol
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):

Expand All @@ -90,10 +87,7 @@ def __json__(self):
"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:
Expand Down Expand Up @@ -684,30 +678,6 @@ def adapter_type(self, adapter_type):
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):
"""
Expand Down
32 changes: 1 addition & 31 deletions gns3server/compute/vmware/vmware_vm.py
Expand Up @@ -70,9 +70,6 @@ def __init__(self, name, node_id, project, manager, vmx_path, linked_clone, cons
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))
Expand All @@ -92,10 +89,7 @@ def __json__(self):
"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
Expand Down Expand Up @@ -738,30 +732,6 @@ def use_any_adapter(self, use_any_adapter):
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):
"""
Expand Down
72 changes: 67 additions & 5 deletions gns3server/controller/node.py
Expand Up @@ -23,6 +23,7 @@


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

Expand All @@ -33,7 +34,8 @@

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):
"""
Expand Down Expand Up @@ -69,12 +71,20 @@ def __init__(self, project, compute, name, node_id=None, node_type=None, **kwarg
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:
Expand Down Expand Up @@ -220,6 +230,30 @@ def label(self, val):
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):
"""
Expand Down Expand Up @@ -423,6 +457,27 @@ def dynamips_idlepc_proposals(self):
"""
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)

Expand Down Expand Up @@ -450,7 +505,10 @@ def __json__(self, topology_dump=False):
"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),
Expand All @@ -471,5 +529,9 @@ def __json__(self, topology_dump=False):
"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()]
}
Empty file.

0 comments on commit 2f0e226

Please sign in to comment.