From: Alina Quereilhac Date: Thu, 10 Feb 2011 17:23:25 +0000 (+0100) Subject: netns module can build description factories X-Git-Tag: nepi_v2~208 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=a1233ac69a70a36c55d1212d5b019bbf6cf8835b;p=nepi.git netns module can build description factories --- diff --git a/examples/design1.py b/examples/design1.py index 261a64c3..2d1c4108 100644 --- a/examples/design1.py +++ b/examples/design1.py @@ -4,7 +4,7 @@ from nepi.core.experiment import ExperimentDescription testbed_id = "netns" -testbed_version = "v0.1" +testbed_version = "01" experiment = ExperimentDescription() netns = experiment.add_testbed_description(testbed_id, testbed_version) node1 = netns.create("Node") @@ -27,7 +27,7 @@ app = netns.create("Application") app.set_attribute_value("command", "ping -qc10 10.0.0.2") app.connector("node").connect(node1.connector("apps")) -print experiment.xml_description +#print experiment.xml_description description = """ diff --git a/src/nepi/core/attributes.py b/src/nepi/core/attributes.py index 7f2d6bac..02f68c38 100644 --- a/src/nepi/core/attributes.py +++ b/src/nepi/core/attributes.py @@ -39,7 +39,7 @@ class AttributesMap(object): def add_attribute(self, name, help, type, value = None, range = None, allowed = None, readonly = False, validation_function = None): if name in self._attributes: - raise AttributeError('Attribute %s already exists' % name)) + raise AttributeError("Attribute %s already exists" % name) attribute = Attribute(name, help, type, value, range, allowed, readonly, validation_function) self._attributes[name] = attribute @@ -115,7 +115,7 @@ class Attribute(object): value = property(get_value, set_value) def _is_in_range(self, value): - return not self.range or + return not self.range or \ (value >= self.range[0] and value <= self.range[1]) def _is_in_allowed_values(self, value): diff --git a/src/nepi/core/description.py b/src/nepi/core/description.py index 88913e9a..3b3b9259 100644 --- a/src/nepi/core/description.py +++ b/src/nepi/core/description.py @@ -3,6 +3,7 @@ from nepi.core.attributes import AttributesMap, Attribute from nepi.util import validation +import sys AF_INET = 0 AF_INET6 = 1 @@ -101,8 +102,8 @@ class Connector(object): connector._connections[self._key] = self def disconnect(self, connector): - if connector._key not in self._connections or - self._key not in connector._connections: + if connector._key not in self._connections or\ + self._key not in connector._connections: raise RuntimeError("Could not disconnect.") del self._connections[connector._key] del connector._connections[self._key] @@ -147,7 +148,7 @@ class Address(AttributesMap): self.add_attribute(name = "Family", help = "Address family type: AF_INET, AFT_INET6", type = Attribute.INTEGER, - value = family + value = family, readonly = True) address_validation = validation.is_ip4_address if family == AF_INET \ else validation.is_ip6_address @@ -164,7 +165,7 @@ class Address(AttributesMap): if family == AF_INET: self.add_attribute(name = "Broadcast", help = "Broadcast address", - type = Attribute.STRING + type = Attribute.STRING, validation_function = validation.is_ip4_address) class Route(AttributesMap): @@ -173,7 +174,7 @@ class Route(AttributesMap): self.add_attribute(name = "Family", help = "Address family type: AF_INET, AFT_INET6", type = Attribute.INTEGER, - value = family + value = family, readonly = True) address_validation = validation.is_ip4_address if family == AF_INET \ else validation.is_ip6_address @@ -424,7 +425,7 @@ class FactoriesProvider(object): def list_factories(self): return self._factories.keys() -class TestbedDescription(AttributeMap): +class TestbedDescription(AttributesMap): def __init__(self, guid_generator, testbed_id, testbed_version, provider): super(TestbedDescription, self).__init__() self._guid_generator = guid_generator diff --git a/src/nepi/testbeds/netns/__init__.py b/src/nepi/testbeds/netns/__init__.py index af5eeadd..e37f7e11 100644 --- a/src/nepi/testbeds/netns/__init__.py +++ b/src/nepi/testbeds/netns/__init__.py @@ -1,249 +1,66 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- + from nepi.core import description -from nepi.core.attributes import Attribute -from nepi.util import validation +import sys TESTBED_ID = "netns" -factories_metadata = dict({ - "v0.1" : metadata_v01 - }) +def add_connector_types(factory, connector_types_metadata): + for (connector_type_id, help, name, max, min, + allowed_connector_type_ids) in connector_types_metadata: + factory.add_connector_type(connector_type_id, help, name, max, + min, allowed_connector_type_ids) -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 add_traces(factory, traces_metadata): + for (name, help) in traces_metadata: + factory.add_trace(name, help) - }) +def add_attributes(factory, attributes_metadata): + for (name, help, type, value, range, allowed, readonly, + validation_function) in attributes_metadata: + factory.add_attribute(name, help, type, value, range, allowed, + readonly, validation_function) -def create_factories(version): - factories = list() - metadata = factories_metadata[version]() - - for factory_id, info in metadata.iteritems(): +def add_element_attributes(factory, element_attributes_metadata): + for (name, help, type, value, range, allowed, readonly, + validation_function) in element_attributes_metadata: + factory.add_element_attribute(name, help, type, value, range, + allowed, readonly, validation_function) + +def create_factory_from_metadata(factory_id, info): help = info["help"] category = info["category"] display_name = info["display_name"] - factory = Factory(factory_id, display_name, help, category) + factory_type = info["factory_type"] if "factory_type" in info else None + if factory_type == "addressable": + family = info["family"] + max_addresses = info["max_addresses"] + factory = description.AddressableElementFactory(factory_id, + display_name, family, max_addresses, help, category) + elif factory_type == "routing": + factory = description.RoutingTableElementFactory(factory_id, + display_name, help, category) + else: + factory = description.ElementFactory(factory_id, display_name, help, category) + if "connector_types" in info: + add_connector_types(factory, info["connector_types"]) + if "traces" in info: + add_traces(factory, info["traces"]) + if "attributes" in info: + add_attributes(factory, info["attributes"]) + if "element_attributes" in info: + add_element_attributes(factory, info["element_attributes"]) + return factory - 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) +def create_factories(version): + factories = list() + mod_name = "%s.metadata_v%s" % (__name__, version) + if not mod_name in sys.modules: + __import__(mod_name) + metadata = sys.modules[mod_name].get_metadata() + for factory_id, info in metadata.iteritems(): + factory = create_factory_from_metadata(factory_id, info) factories.append(factory) return factories @@ -254,6 +71,6 @@ def create_provider(version): return provider def create_description_instance(guid_generator, version, provider): - return description.TestbedDescription(guid_generator, TESTBED_ID, version, provider) - + return description.TestbedDescription(guid_generator, TESTBED_ID, version, + provider) diff --git a/src/nepi/testbeds/netns/metadata_v01.py b/src/nepi/testbeds/netns/metadata_v01.py new file mode 100644 index 00000000..82de1502 --- /dev/null +++ b/src/nepi/testbeds/netns/metadata_v01.py @@ -0,0 +1,227 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from nepi.core.description import AF_INET +from nepi.core.attributes import Attribute +from nepi.util import validation + +def get_metadata(): + return dict({ + "node": dict({ + "factory_type": "routing", + "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({ + "factory_type": "addressable", + "family": AF_INET, + "max_addresses": 1, + "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({ + "factory_type": "addressable", + "family": AF_INET, + "max_addresses": 1, + "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! + "factory_type": "addressable", + "family": AF_INET, + "max_addresses": 1, + "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) + ] + }), + }) diff --git a/src/nepi/util/guid_generator.py b/src/nepi/util/guid.py similarity index 100% rename from src/nepi/util/guid_generator.py rename to src/nepi/util/guid.py