3a86db05e33af7b7997944dd8fc25127154f8d58
[nepi.git] / src / nepi / testbeds / omf / metadata.py
1 # -*- coding: utf-8 -*-
2
3 from constants import TESTBED_ID, TESTBED_VERSION
4 from nepi.core import metadata
5 from nepi.core.attributes import Attribute
6 from nepi.util import tags, validation
7 from nepi.util.constants import ApplicationStatus as AS, \
8         FactoryCategories as FC, DeploymentConfiguration as DC
9
10 # Factories
11 NODE = "Node"
12 WIFIIFACE = "WifiInterface"
13 ETHIFACE = "EthInterface"
14 CHANNEL = "Channel"
15 APPLICATION = "Application"
16
17 ### Connection functions ####
18
19 ### Creation functions ###
20
21 def create_node(testbed_instance, guid):
22     parameters = testbed_instance._get_parameters(guid)
23     hostname = parameters['hostname']
24     testbed_instance._elements[guid] = hostname
25     testbed_instance._publish_and_enroll_host(hostname)
26
27 def create_wifiiface(testbed_instance, guid):
28     pass
29
30 def create_ethiface(testbed_instance, guid):
31     pass
32
33 def create_channel(testbed_instance, guid):
34     pass
35
36 def create_application(testbed_instance, guid):
37     pass
38
39 ### Start/Stop functions ###
40
41 def start_application(testbed_instance, guid):
42     # search for the node asociated with the device
43     node_guids = testbed_instance.get_connected(guid, "node", "apps")
44     if len(node_guids) == 0:
45         raise RuntimeError("Can't instantiate interface %d outside node" % guid)
46
47     # node attributes
48     node_parameters = testbed_instance._get_parameters(node_guids[0])
49     hostname = node_parameters['hostname']
50
51     # application attributes
52     parameters = testbed_instance._get_parameters(guid)
53     app_id = parameters.get("appId")
54     arguments = parameters.get("arguments")
55     path = parameters.get("path")
56     testbed_instance._publish_execute(hostname, app_id, arguments, path)
57
58 def stop_application(testbed_instance, guid):
59     pass
60
61 ### Status functions ###
62
63 def status_application(testbed_instance, guid):
64     if guid not in testbed_instance.elements.keys():
65         return AS.STATUS_NOT_STARTED
66     return AS.STATUS_RUNNING
67     # TODO!!!!
68     #return AS.STATUS_FINISHED
69
70 ### Configure functions ###
71
72 def configure_wifiiface(testbed_instance, guid):
73     # search for the node asociated with the device
74     node_guids = testbed_instance.get_connected(guid, "node", "devs")
75     if len(node_guids) == 0:
76         raise RuntimeError("Can't instantiate interface %d outside node" % guid)
77
78     # node attributes
79     node_parameters = testbed_instance._get_parameters(node_guids[0])
80     hostname = node_parameters['hostname']
81
82     # wifi iface attributes
83     parameters = testbed_instance._get_parameters(guid)
84
85     for attr in ["mode", "type", "channel", "essid"]: 
86         attribute = "net/w0/%s" % attr
87         value = parameters.get(attr)
88         if value:
89             testbed_instance._publish_configure(hostname, attribute, value)
90
91     if guid in testbed_instance._add_address: 
92         attribute = "net/w0/ip"
93         addresses = testbed_instance._add_address[guid]
94         (value, netprefix, broadcast) = addresses[0]
95         testbed_instance._publish_configure(hostname, attribute, value)
96
97 ### Factory information ###
98
99 connector_types = dict({
100     "apps": dict({
101                 "help": "Connector from node to applications", 
102                 "name": "apps",
103                 "max": -1, 
104                 "min": 0
105             }),
106     "devs": dict({
107                 "help": "Connector to network interfaces", 
108                 "name": "devs",
109                 "max": -1, 
110                 "min": 0
111             }),
112     "chan": dict({
113                 "help": "Connector from a device to a channel", 
114                 "name": "chan",
115                 "max": 1, 
116                 "min": 1
117             }),
118     "node": dict({
119                 "help": "Connector to a Node", 
120                 "name": "node",
121                 "max": 1, 
122                 "min": 1
123             }),
124    })
125
126 connections = [
127     dict({
128         "from": (TESTBED_ID, NODE, "devs"),
129         "to":   (TESTBED_ID, WIFIIFACE, "node"),
130         "can_cross": False
131     }),
132     dict({
133         "from": (TESTBED_ID, NODE, "devs"),
134         "to":   (TESTBED_ID, ETHIFACE, "node"),
135         "can_cross": False
136     }),
137     dict({
138         "from": (TESTBED_ID, WIFIIFACE, "chan"),
139         "to":   (TESTBED_ID, CHANNEL, "devs"),
140         "can_cross": False
141     }),
142     dict({
143         "from": (TESTBED_ID, NODE, "apps"),
144         "to":   (TESTBED_ID, APPLICATION, "node"),
145         "can_cross": False
146     }),
147  ]
148
149 attributes = dict({
150     "appId": dict({
151                 "name": "appId",
152                 "help": "Application id",
153                 "type": Attribute.STRING,
154                 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
155                 "validation_function": validation.is_string
156             }),
157     "arguments": dict({
158                 "name": "arguments",
159                 "help": "Application arguments",
160                 "type": Attribute.STRING,
161                 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
162                 "validation_function": validation.is_string
163             }),
164     "path": dict({
165                 "name": "path",
166                 "help": "Path to binary (e.g '/opt/vlc-1.1.13/vlc')",
167                 "type": Attribute.STRING,
168                 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
169                 "validation_function": validation.is_string
170             }),
171     "hostname": dict({
172                 "name": "hostname",
173                 "help": "Hostname for the target OMF node",
174                 "type": Attribute.STRING,
175                 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
176                 "validation_function": validation.is_string
177             }),
178     "mode": dict({
179                 "name": "mode",
180                 "help": "Corresponds to the OMF attributes net/w0/mode",
181                 "type": Attribute.STRING,
182                 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
183                 "validation_function": validation.is_string
184             }),
185     "type": dict({
186                 "name": "type",
187                 "help": "Corresponds to the OMF attributes net/w0/type",
188                 "type": Attribute.STRING,
189                 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
190                 "validation_function": validation.is_string
191             }),
192     "channel": dict({
193                 "name": "channel",
194                 "help": "Corresponds to the OMF attributes net/w0/channel",
195                 "type": Attribute.STRING,
196                 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
197                 "validation_function": validation.is_string
198             }),
199     "essid": dict({
200                 "name": "essid",
201                 "help": "Corresponds to the OMF attributes net/w0/essid",
202                 "type": Attribute.STRING,
203                 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
204                 "validation_function": validation.is_string
205             }),
206
207
208     })
209
210 traces = dict()
211
212 create_order = [ NODE, WIFIIFACE, ETHIFACE, CHANNEL, APPLICATION ]
213 configure_order = [ WIFIIFACE, ETHIFACE, NODE, CHANNEL, APPLICATION ]
214
215 factories_info = dict({
216     NODE: dict({
217             "help": "OMF Node",
218             "category": FC.CATEGORY_NODES,
219             "create_function": create_node,
220             "box_attributes": ["hostname"],
221             "connector_types": ["devs", "apps"],
222             "tags": [tags.NODE, tags.ALLOW_ROUTES],
223        }),
224     WIFIIFACE: dict({
225             "help": "Wireless network interface",
226             "category": FC.CATEGORY_DEVICES,
227             "create_function": create_wifiiface,
228             "configure_function": configure_wifiiface,
229             "box_attributes": ["mode", "type", "channel", "essid"],
230             "connector_types": ["node", "chan"],
231             "tags": [tags.INTERFACE, tags.ALLOW_ADDRESSES],
232        }),
233     ETHIFACE: dict({
234             "help": "Ethernet network interface",
235             "category": FC.CATEGORY_DEVICES,
236             "create_function": create_ethiface,
237             #"box_attributes": [""],
238             "connector_types": ["node"],
239             "tags": [tags.INTERFACE, tags.ALLOW_ADDRESSES],
240        }),
241     CHANNEL: dict({
242             "help": "Wireless channel",
243             "category": FC.CATEGORY_DEVICES,
244             "create_function": create_channel,
245             "box_attributes": ["mode", "type", "channel", "essid"],
246             "connector_types": ["devs"],
247        }),
248     APPLICATION: dict({
249             "help": "Generic executable command line application",
250             "category": FC.CATEGORY_APPLICATIONS,
251             "create_function": create_application,
252             "start_function": start_application,
253             "stop_function": stop_application,
254             "status_function": status_application,
255             "box_attributes": ["appId", "arguments", "path"],
256             "connector_types": ["node"],
257             "tags": [tags.APPLICATION],
258         }),
259 })
260
261 testbed_attributes = dict({
262     "enable_debug": dict({
263             "name": "enableDebug",
264             "help": "Enable netns debug output",
265             "type": Attribute.BOOL,
266             "value": False,
267             "validation_function": validation.is_bool
268         }),
269     "xmppSlice": dict({
270                 "name": "xmppSlice",
271                 "help": "OMF slice",
272                 "type": Attribute.STRING,
273                 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
274                 "validation_function": validation.is_string
275             }),
276     "xmppHost": dict({
277                 "name": "xmppHost",
278                 "help": "OMF XMPP server host",
279                 "type": Attribute.STRING,
280                 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
281                 "validation_function": validation.is_string
282             }),
283     "xmppPort": dict({
284                 "name": "xmppPort",
285                 "help": "OMF XMPP service port",
286                 "type": Attribute.INTEGER,
287                 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
288                 "validation_function": validation.is_integer
289             }),
290     "xmppPassword": dict({
291                 "name": "xmppPassword",
292                 "help": "OMF XMPP slice password",
293                 "type": Attribute.STRING,
294                 "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
295                 "validation_function": validation.is_string
296             }),
297     })
298
299 supported_recovery_policies = [
300         DC.POLICY_FAIL,
301     ]
302
303 class MetadataInfo(metadata.MetadataInfo):
304     @property
305     def connector_types(self):
306         return connector_types
307
308     @property
309     def connections(self):
310         return connections
311
312     @property
313     def attributes(self):
314         return attributes
315
316     @property
317     def traces(self):
318         return traces
319
320     @property
321     def create_order(self):
322         return create_order
323
324     @property
325     def configure_order(self):
326         return configure_order
327
328     @property
329     def factories_info(self):
330         return factories_info
331
332     @property
333     def testbed_attributes(self):
334         return testbed_attributes
335
336     @property
337     def testbed_id(self):
338         return TESTBED_ID
339
340     @property
341     def testbed_version(self):
342         return TESTBED_VERSION
343     
344     @property
345     def supported_recover_policies(self):
346         return supported_recovery_policies
347