metadata added for netns testbed
authorAlina Quereilhac <alina.quereilhac@inria.fr>
Wed, 9 Feb 2011 17:26:23 +0000 (18:26 +0100)
committerAlina Quereilhac <alina.quereilhac@inria.fr>
Wed, 9 Feb 2011 17:26:23 +0000 (18:26 +0100)
examples/design1.py
src/nepi/core/description.py
src/nepi/core/experiment.py
src/nepi/testbeds/netns/__init__.py
src/nepi/util/validation.py

index 7a9cca3..261a64c 100644 (file)
@@ -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")
index 8b73667..88913e9 100644 (file)
@@ -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):
index 3b8ca93..76b8143 100644 (file)
@@ -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
 
index e69de29..af5eead 100644 (file)
@@ -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)
+
+
index fc8a8ec..954aa05 100644 (file)
@@ -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
+