6 from geni.util.misc import *
7 from geni.util.rspec import *
8 from geni.util.specdict import *
9 from geni.util.excep import *
10 from geni.util.storage import *
11 from geni.util.debug import log
12 from geni.util.rspec import *
13 from geni.util.specdict import *
14 from geni.aggregate import Aggregates
15 from geni.util.policy import Policy
17 class Nodes(SimpleStorage):
19 def __init__(self, api, ttl = 1):
23 self.nodes_file = os.sep.join([self.api.server_basedir, self.api.interface +'.'+ self.api.hrn + '.nodes'])
24 SimpleStorage.__init__(self, self.nodes_file)
25 self.policy = Policy(api)
31 Update the cached list of nodes
34 # Reload components list
35 now = datetime.datetime.now()
36 if not self.has_key('threshold') or not self.has_key('timestamp') or \
37 now > datetime.datetime.fromtimestamp(time.mktime(time.strptime(self['threshold'], self.api.time_format))):
38 if self.api.interface in ['aggregate']:
39 self.refresh_nodes_aggregate()
40 elif self.api.interface in ['slicemgr']:
41 self.refresh_nodes_smgr()
44 def refresh_nodes_aggregate(self):
46 rspec.parseString(self.get_rspec())
48 # filter nodes according to policy
49 blist = self.policy['node_blacklist']
50 wlist = self.policy['node_whitelist']
51 rspec.filter('NodeSpec', 'name', blacklist=blist, whitelist=wlist)
53 # extract ifspecs from rspec to get ips'
55 ifspecs = rspec.getDictsByTagName('IfSpec')
56 for ifspec in ifspecs:
57 if ifspec.has_key('addr') and ifspec['addr']:
58 ips.append(ifspec['addr'])
60 # extract nodespecs from rspec to get dns names
62 nodespecs = rspec.getDictsByTagName('NodeSpec')
63 for nodespec in nodespecs:
64 if nodespec.has_key('name') and nodespec['name']:
65 hostnames.append(nodespec['name'])
67 # update timestamp and threshold
68 timestamp = datetime.datetime.now()
69 hr_timestamp = timestamp.strftime(self.api.time_format)
70 delta = datetime.timedelta(hours=self.ttl)
71 threshold = timestamp + delta
72 hr_threshold = threshold.strftime(self.api.time_format)
75 node_details['rspec'] = rspec.toxml()
76 node_details['ip'] = ips
77 node_details['dns'] = hostnames
78 node_details['timestamp'] = hr_timestamp
79 node_details['threshold'] = hr_threshold
81 self.update(node_details)
84 def refresh_nodes_smgr(self):
85 # convert and threshold to ints
86 if self.has_key('timestamp') and self['timestamp']:
87 hr_timestamp = self['timestamp']
88 timestamp = datetime.datetime.fromtimestamp(time.mktime(time.strptime(hr_timestamp, self.api.time_format)))
89 hr_threshold = self['threshold']
90 threshold = datetime.datetime.fromtimestamp(time.mktime(time.strptime(hr_threshold, self.api.time_format)))
92 timestamp = datetime.datetime.now()
93 hr_timestamp = timestamp.strftime(self.api.time_format)
94 delta = datetime.timedelta(hours=self.ttl)
95 threshold = timestamp + delta
96 hr_threshold = threshold.strftime(self.api.time_format)
98 start_time = int(timestamp.strftime("%s"))
99 end_time = int(threshold.strftime("%s"))
100 duration = end_time - start_time
102 aggregates = Aggregates(self.api)
106 credential = self.api.getCredential()
107 for aggregate in aggregates:
109 # get the rspec from the aggregate
110 agg_rspec = aggregates[aggregate].get_resources(credential)
111 # extract the netspec from each aggregates rspec
112 rspec.parseString(agg_rspec)
113 networks.extend([{'NetSpec': rspec.getDictsByTagName('NetSpec')}])
116 # XX print out to some error log
117 print >> log, "Error calling list nodes at aggregate %s" % aggregate
118 # create the rspec dict
119 resources = {'networks': networks, 'start_time': start_time, 'duration': duration}
120 resourceDict = {'Rspec': resources}
121 # convert rspec dict to xml
122 rspec.parseDict(resourceDict)
124 # filter according to policy
125 blist = self.policy['node_blacklist']
126 wlist = self.policy['node_whitelist']
127 rspec.filter('NodeSpec', 'name', blacklist=blist, whitelist=wlist)
129 # update timestamp and threshold
130 timestamp = datetime.datetime.now()
131 hr_timestamp = timestamp.strftime(self.api.time_format)
132 delta = datetime.timedelta(hours=self.ttl)
133 threshold = timestamp + delta
134 hr_threshold = threshold.strftime(self.api.time_format)
136 nodedict = {'rspec': rspec.toxml(),
137 'timestamp': hr_timestamp,
138 'threshold': hr_threshold}
140 self.update(nodedict)
144 def get_rspec(self, hrn = None):
146 Get resource information from PLC
149 # Get the required nodes
151 nodes = self.api.plshell.GetNodes(self.api.plauth)
152 try: linkspecs = self.api.plshell.GetLinkSpecs() # if call is supported
153 except: linkspecs = []
155 slicename = hrn_to_pl_slicename(hrn)
156 slices = self.api.plshell.GetSlices(self.api.plauth, [slicename])
161 node_ids = slice['node_ids']
162 nodes = self.api.plshell.GetNodes(self.api.plauth, node_ids)
164 # Filter out whitelisted nodes
165 public_nodes = lambda n: n.has_key('slice_ids_whitelist') and not n['slice_ids_whitelist']
166 nodes = filter(public_nodes, nodes)
168 # Get all network interfaces
171 interface_ids.extend(node['nodenetwork_ids'])
172 interfaces = self.api.plshell.GetNodeNetworks(self.api.plauth, interface_ids)
174 for interface in interfaces:
175 interface_dict[interface['nodenetwork_id']] = interface
177 # join nodes with thier interfaces
179 node['interfaces'] = []
180 for nodenetwork_id in node['nodenetwork_ids']:
181 node['interfaces'].append(interface_dict[nodenetwork_id])
183 # convert and threshold to ints
184 if self.has_key('timestamp') and self['timestamp']:
185 timestamp = datetime.datetime.fromtimestamp(time.mktime(time.strptime(self['timestamp'], self.api.time_format)))
186 threshold = datetime.datetime.fromtimestamp(time.mktime(time.strptime(self['threshold'], self.api.time_format)))
188 timestamp = datetime.datetime.now()
189 delta = datetime.timedelta(hours=self.ttl)
190 threshold = timestamp + delta
192 start_time = int(timestamp.strftime("%s"))
193 end_time = int(threshold.strftime("%s"))
194 duration = end_time - start_time
196 # create the plc dict
197 networks = [{'nodes': nodes,
198 'name': self.api.hrn,
199 'start_time': start_time,
200 'duration': duration}]
202 networks[0]['links'] = linkspecs
203 resources = {'networks': networks, 'start_time': start_time, 'duration': duration}
205 # convert the plc dict to an rspec dict
206 resourceDict = RspecDict(resources)
207 # convert the rspec dict to xml
209 rspec.parseDict(resourceDict)