change bug of dict
[nepi.git] / src / nepi / resources / omf / node.py
1 """
2     NEPI, a framework to manage network experiments
3     Copyright (C) 2013 INRIA
4
5     This program is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 3 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18 """
19
20 from nepi.execution.resource import ResourceManager, clsinit
21 from nepi.execution.attribute import Attribute, Flags 
22
23 from nepi.resources.omf.omf_api import OMFAPIFactory
24
25 import time
26
27 @clsinit
28 class OMFNode(ResourceManager):
29     """
30     .. class:: Class Args :
31       
32         :param ec: The Experiment controller
33         :type ec: ExperimentController
34         :param guid: guid of the RM
35         :type guid: int
36         :param creds: Credentials to communicate with the rm (XmppClient for OMF)
37         :type creds: dict
38
39     .. note::
40
41        This class is used only by the Experiment Controller through the Resource Factory
42
43     """
44     _rtype = "OMFNode"
45     _authorized_connections = ["OMFApplication" , "OMFWifiInterface"]
46     _waiters = []
47
48     @classmethod
49     def _register_attributes(cls):
50         """Register the attributes of an OMF Node
51
52         """
53         hostname = Attribute("hostname", "Hostname of the machine")
54         cpu = Attribute("cpu", "CPU of the node")
55         ram = Attribute("ram", "RAM of the node")
56         xmppSlice = Attribute("xmppSlice","Name of the slice",
57                 flags = Flags.Credential)
58         xmppHost = Attribute("xmppHost", "Xmpp Server",
59                 flags = Flags.Credential)
60         xmppPort = Attribute("xmppPort", "Xmpp Port",
61                 flags = Flags.Credential)
62         xmppPassword = Attribute("xmppPassword", "Xmpp Port",
63                 flags = Flags.Credential)
64
65         host = Attribute("host", "Hostname of the machine",
66                 flags = Flags.Filter)
67         gateway = Attribute("gateway", "Gateway",
68                 flags = Flags.Filter)
69         granularity = Attribute("granularity", "Granularity of the reservation time",
70                 flags = Flags.Filter)
71         hardware_type = Attribute("hardware_type", "Hardware type of the machine",
72                 flags = Flags.Filter)
73
74         cls._register_attribute(hostname)
75         cls._register_attribute(ram)
76         cls._register_attribute(cpu)
77         cls._register_attribute(xmppSlice)
78         cls._register_attribute(xmppHost)
79         cls._register_attribute(xmppPort)
80         cls._register_attribute(xmppPassword)
81
82         cls._register_attribute(host)
83         cls._register_attribute(gateway)
84         cls._register_attribute(granularity)
85         cls._register_attribute(hardware_type)
86
87     # XXX: We don't necessary need to have the credentials at the 
88     # moment we create the RM
89     def __init__(self, ec, guid):
90         """
91         :param ec: The Experiment controller
92         :type ec: ExperimentController
93         :param guid: guid of the RM
94         :type guid: int
95         :param creds: Credentials to communicate with the rm (XmppClient for OMF)
96         :type creds: dict
97
98         """
99         super(OMFNode, self).__init__(ec, guid)
100
101         self._omf_api = None 
102
103         # XXX: TO DISCUSS
104
105     def _validate_connection(self, guid):
106         """Check if the connection is available.
107
108         :param guid: Guid of the current RM
109         :type guid: int
110         :rtype:  Boolean
111
112         """
113         rm = self.ec.get_resource(guid)
114         if rm.rtype() in self._authorized_connections:
115             msg = "Connection between %s %s and %s %s accepted" % (self.rtype(), self._guid, rm.rtype(), guid)
116             self.debug(msg)
117             return True
118         msg = "Connection between %s %s and %s %s refused" % (self.rtype(), self._guid, rm.rtype(), guid)
119         self.debug(msg)
120         return False
121
122     def deploy(self):
123         """Deploy the RM
124
125         """ 
126         self._omf_api = OMFAPIFactory.get_api(self.get('xmppSlice'), 
127             self.get('xmppHost'), self.get('xmppPort'), self.get('xmppPassword'))
128         self._omf_api.enroll_host(self.get('hostname'))
129
130         super(OMFNode, self).deploy()
131
132     def discover(self):
133         """ Discover the availables nodes
134
135         """
136         pass
137      
138     def provision(self):
139         """ Provision some availables nodes
140
141         """
142         pass
143
144     def start(self):
145         """Send Xmpp Message Using OMF protocol to enroll the node into the experiment
146
147         """
148         super(OMFNode, self).start()
149
150
151     def stop(self):
152         """Send Xmpp Message Using OMF protocol to disconnect the node
153
154         """
155         super(OMFNode, self).stop()
156
157     def release(self):
158         """Clean the RM at the end of the experiment
159
160         """
161         self._omf_api.release(self.get('hostname'))
162         OMFAPIFactory.release_api(self.get('xmppSlice'), 
163             self.get('xmppHost'), self.get('xmppPort'), self.get('xmppPassword'))
164
165
166     def configure(self):
167         #routes = self.tc._add_route.get(self.guid, [])
168         #iface_guids = self.tc.get_connected(self.guid, "devs", "node")
169        
170         for route in routes:
171             (destination, netprefix, nexthop, metric, device) = route
172             netmask = ipaddr2.ipv4_mask2dot(netprefix)
173
174             # Validate that the interface is associated to the node
175             for iface_guid in iface_guids:
176                 iface = self.tc.elements.get(iface_guid)
177                 if iface.devname == device:
178                     self._omf_api.execute(self.get('hostname'), 
179                         "Id#%s" % str(random.getrandbits(128)), 
180                         "add -net %s netmask %s dev %s" % (destination, netmask, iface.devname), 
181                         "/sbin/route", # path
182                         None, # env
183                      )
184                     break