From: Alina Quereilhac Date: Wed, 9 Feb 2011 17:26:23 +0000 (+0100) Subject: metadata added for netns testbed X-Git-Tag: nepi_v2~209 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=91e213ecadc54ee715d32fc5b8bab1e13bf63dfc;p=nepi.git metadata added for netns testbed --- diff --git a/examples/design1.py b/examples/design1.py index 7a9cca39..261a64c3 100644 --- a/examples/design1.py +++ b/examples/design1.py @@ -4,7 +4,7 @@ from nepi.core.experiment import ExperimentDescription testbed_id = "netns" -testbed_version = "0.1" +testbed_version = "v0.1" experiment = ExperimentDescription() netns = experiment.add_testbed_description(testbed_id, testbed_version) node1 = netns.create("Node") diff --git a/src/nepi/core/description.py b/src/nepi/core/description.py index 8b736679..88913e9a 100644 --- a/src/nepi/core/description.py +++ b/src/nepi/core/description.py @@ -34,7 +34,9 @@ class ConnectorType(object): self._name = name self._max = max self._min = min - self._allowed_connections = list() + # list of connector_type_ids with which this connector_type is allowed + # to connect + self._allowed_connector_type_ids = list() @property def connector_type_id(self): @@ -56,11 +58,11 @@ class ConnectorType(object): def min(self): return self._min - def add_allowed_connection(self, connector_type_id): - self._allowed_connections.append(connector_type_id) + def add_allowed_connector_type_id(self, connector_type_id): + self._allowed_connector_type_ids.append(connector_type_id) def can_connect(self, connector_type_id): - return connector_type_id in self._allowed_connections + return connector_type_id in self._allowed_connector_type_ids class Connector(object): """A Connector sepcifies the connection points in an Object""" @@ -327,11 +329,12 @@ class RoutingTableElement(Element): self._route = None class ElementFactory(AttributesMap): - def __init__(self, factory_id, help = None, category = None): + def __init__(self, factory_id, display_name, help = None, category = None): super(ElementFactory, self).__init__() self._factory_id = factory_id self._help = help self._category = category + self._display_name = display_name self._connector_types = set() self._traces = list() self._element_attributes = list() @@ -348,6 +351,10 @@ class ElementFactory(AttributesMap): def category(self): return self._category + @property + def display_name(self): + return self._display_name + @property def connector_types(self): return self._connector_types @@ -360,8 +367,11 @@ class ElementFactory(AttributesMap): def element_attributes(self): return self._element_attributes - def add_connector_type(self, connector_id, help, name, max = -1, min = 0): - connector_type = ConnectorType(connector_id, help, name, max, min) + def add_connector_type(self, connector_type_id, help, name, max = -1, + min = 0, allowed_connector_type_ids = []): + connector_type = ConnectorType(connector_type_id, help, name, max, min) + for connector_type_id in allowed_connector_type_ids: + connector_type.add_allowed_connector_type_id(connector_type_id) self._connector_types.add(connector_type) def add_trace(self, name, help, enabled = False): @@ -382,21 +392,24 @@ class ElementFactory(AttributesMap): self._connector_types = None class AddressableElementFactory(ElementFactory): - def __init__(self, factory_id, family, max_addresses = 1, help = None, category = None): - super(AddressableElementFactory, self).__init__(factory_id, help, category) + def __init__(self, factory_id, display_name, family, max_addresses = 1, + help = None, category = None): + super(AddressableElementFactory, self).__init__(factory_id, + display_name, help, category) self._family = family self._max_addresses = 1 def create(self, guid, testbed_description): - return AddressableElement(guid, self, self._family, self._max_addresses) + return AddressableElement(guid, self, self._family, + self._max_addresses) class RoutingTableElementFactory(ElementFactory): def create(self, guid, testbed_description): return RoutingTableElement(guid, self) -class Provider(object): +class FactoriesProvider(object): def __init__(self): - super(Provider, self).__init__() + super(FactoriesProvider, self).__init__() self._factories = dict() def factory(self, factory_id): diff --git a/src/nepi/core/experiment.py b/src/nepi/core/experiment.py index 3b8ca93b..76b8143a 100644 --- a/src/nepi/core/experiment.py +++ b/src/nepi/core/experiment.py @@ -19,8 +19,7 @@ class ExperimentDescription(object): testbed_module = self._testbed_module(testbed_id) testbed_provider = self._testbed_provider(testbed_id, testbed_version) testbed_description = testbed_module.create_description_instance( - self._guid_generator, tesbed_id, testbed_version, - testbed_provider) + self._guid_generator, testbed_version, testbed_provider) guid = testbed_description.guid self._testbed_descriptions[guid] = testbed_description diff --git a/src/nepi/testbeds/netns/__init__.py b/src/nepi/testbeds/netns/__init__.py index e69de29b..af5eeadd 100644 --- a/src/nepi/testbeds/netns/__init__.py +++ b/src/nepi/testbeds/netns/__init__.py @@ -0,0 +1,259 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from nepi.core import description +from nepi.core.attributes import Attribute +from nepi.util import validation + +TESTBED_ID = "netns" + +factories_metadata = dict({ + "v0.1" : metadata_v01 + }) + +def metadata_v01(): + return = dict({ + "node": dict({ #TODO: RoutingTable + "display_name": "Node", + "help": "Node element", + "category": "topology", + "connector_types": [ + ("netns_node_apps", + "Connector from node to applications", + "apps", -1, 0, + ["netns_application_node"]), + ("netns_node_devs", + "Connector from node to network interfaces", + "devs", -1, 0, + [ + "netns_nodeiface_node", + "netns_tapiface_node", + "netns_p2piface_node" + ]) + ], + "element_attributes": [ + ("forward_X11", + "Forward x11 from main namespace to the node", + Attribute.BOOL, + False, None, None, False, + validation.is_bool) + ] + }), + "p2piface": dict({ #TODO: Addresses! + "display_name": "P2PInterface", + "help": "Point to point network interface", + "category": "devices", + "connector_types": [ + ("netns_p2piface_node", + "Connector from P2PInterface to Node", + "node", 1, 1, + ["netns_node_devs"]), + ("netns_p2pinterface_p2p", + "Connector to another P2PInterface", + "p2p", 1, 0, + ["netns_p2piface_p2p"]) + ], + "element_attributes": [ + ("lladdr", "Mac address", Attribute.STRING, + None, None, None, False, + validation.is_mac_address), + ("up", "Link up", Attribute.BOOL, + False, None, None, False, + validation.is_bool), + ("name", "Device name", Attribute.STRING, + None, None, None, False, + validation.is_string), + ("mtu", "Maximmum transmition unit for device", + Attribute.INTEGER, + None, None, None, False, + validation.is_integer), + ("broadcast", "Broadcast address", + Attribute.STRING, + None, None, None, False, + validation.is_string), + ("multicast", "Is multicast enabled", + Attribute.BOOL, + False, None, None, False, + validation.is_bool), + ("arp", "Is ARP enabled", Attribute.BOOL, + True, None, None, False, + validation.is_bool), + ] + }), + "tapiface": dict({ #TODO: Addresses! + "display_name": "TapNodeInterface", + "help": "Tap device network interface", + "category": "devices", + "connector_types": [ + ("netns_tapiface_node", + "Connector to a Node", + "node", 1, 1, + ["netns_node_devs"]), + ("netns_tapiface_fd", + "Connector to a network interface that can receive a file descriptor", + "fd", 1, 0, + # TODO: Doesn't exist yet! + ["ns3_fdnetdev_fd"]) + ], + "element_attributes": [ + ("lladdr", "Mac address", Attribute.STRING, + None, None, None, False, + validation.is_mac_address), + ("up", "Link up", Attribute.BOOL, + False, None, None, False, + validation.is_bool), + ("name", "Device name", Attribute.STRING, + None, None, None, False, + validation.is_string), + ("mtu", "Maximmum transmition unit for device", + Attribute.INTEGER, + None, None, None, False, + validation.is_integer), + ("broadcast", "Broadcast address", + Attribute.STRING, + None, None, None, False, + validation.is_string), + ("multicast", "Is multicast enabled", + Attribute.BOOL, + False, None, None, False, + validation.is_bool), + ("arp", "Is ARP enabled", Attribute.BOOL, + True, None, None, False, + validation.is_bool), + ] + }), + "nodeiface": dict({ #TODO: Addresses! + "display_name": "NodeInterface", + "help": "Node network interface", + "category": "devices", + "connector_types": [ + ("netns_nodeiface_node", "Connector to a node", + "node", 1, 1, + ["netns_node_devs"]), + ("netns_nodeiface_switch", "Connector to a switch", + "switch", 1, 0, + ["netns_switch_devs"]) + ], + "element_attributes": [ + ("lladdr", "Mac address", Attribute.STRING, + None, None, None, False, + validation.is_mac_address), + ("up", "Link up", Attribute.BOOL, + False, None, None, False, + validation.is_bool), + ("name", "Device name", Attribute.STRING, + None, None, None, False, + validation.is_string), + ("mtu", "Maximmum transmition unit for device", + Attribute.INTEGER, + None, None, None, False, + validation.is_integer), + ("broadcast", "Broadcast address", + Attribute.STRING, + None, None, None, False, + validation.is_string), + ("multicast", "Is multicast enabled", + Attribute.BOOL, + False, None, None, False, + validation.is_bool), + ("arp", "Is ARP enabled", Attribute.BOOL, + True, None, None, False, + validation.is_bool), + ] + }), + "switch": dict({ + "display_name": "Switch", + "help": "Switch interface", + "category": "devices", + "connector_types": [ + ("netns_switch_devs", "Connector to network interfaces", + "devs", -1, 0, + ["netns_nodeiface_switch"]) + ], + "element_attributes": [ + ("Up", "Link up", Attribute.BOOL, + False, None, None, False, + validation.is_bool), + ("Name", "Device name", Attribute.STRING, + None, None, None, False, + validation,is_string), + ("Mtu", "Maximmum transmition unit for device", + Attribute.INTEGER, + None, None, None, False, + validation.is_integer), + ("Multicast", "Is multicast enabled", + Attribute.BOOL, + None, None, None, False, + validation.is_bool), + #TODO:("Stp", help, type, value, range, allowed, readonly, validation_function), + #TODO:("ForwarddDelay", help, type, value, range, allowed, readonly, validation_function), + #TODO:("HelloTime", help, type, value, range, allowed, readonly, validation_function), + #TODO:("AgeingTime", help, type, value, range, allowed, readonly, validation_function), + #TODO:("MaxAge", help, type, value, range, allowed, readonly, validation_function) + ] + }), + "application": dict({ + "display_name": "Application", + "help": "Generic executable command line application", + "category": "applications", + "connector_types": [ + ("netns_application_node", "Connector to a node", + "node", 1, 1, + ["netns_node_apps"]) + ], + "traces": [ + ("StdoutTrace", "Standard output"), + ("StderrTrace", "Standard error") + ], + "element_attributes": [ + ("Command", "Command line", + Attribute.STRING, + None, None, None, False, + validation.is_string) + ("User", "System user", + Attribute.STRING, + None, None, None, False, + validation.is_string) + ("Stdin", "Standard input", + Attribute.STRING, + None, None, None, False, + validation.is_string) + ] + }), + + }) + +def create_factories(version): + factories = list() + metadata = factories_metadata[version]() + + for factory_id, info in metadata.iteritems(): + help = info["help"] + category = info["category"] + display_name = info["display_name"] + factory = Factory(factory_id, display_name, help, category) + + for (connector_type_id, help, name, max, min, + allowed_connector_type_ids) in info["connector_types"]: + factory.add_connector_type(connector_type_id, help, name, max, + min, allowed_connector_type_ids) + for : + factory.add_trace(name, help) + for : + factory.add_attribute(name, help, type, value, range, allowed, + readonly, validation_function) + for : + factory.add_element_attribute(name, help, type, value, range, + allowed, readonly, validation_function) + factories.append(factory) + return factories + +def create_provider(version): + provider = description.FactoriesProvider() + for factory in create_factories(version): + provider.add_factory(factory) + return provider + +def create_description_instance(guid_generator, version, provider): + return description.TestbedDescription(guid_generator, TESTBED_ID, version, provider) + + diff --git a/src/nepi/util/validation.py b/src/nepi/util/validation.py index fc8a8ecb..954aa055 100644 --- a/src/nepi/util/validation.py +++ b/src/nepi/util/validation.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- import ipaddr +import re def is_bool(value): return isinstance(value, bool) @@ -26,3 +27,10 @@ def is_ip6_address(value): return False return True +def is_mac_address(value): + regex = r'^([0-9a-zA-Z]{0,2}:)*[0-9a-zA-Z]{0,2}' + found = re.search(regex, value) + if not found or value.count(':') != 5: + return False + return True +