blob: fe86871d3213f091bd9e64bbbcee2a25d76adc76 [file] [log] [blame]
smbakere36a7de2013-10-29 17:25:25 -07001import os
2import json
3import socket
4import sys
5import time
6import traceback
7import xmlrpclib
Scott Baker9cc9bf32013-12-13 17:26:07 -08008
smbakere36a7de2013-10-29 17:25:25 -07009from core.models import Slice, Sliver, ServiceClass, Reservation, Tag, Network, User, Node, Image, Deployment, Site, NetworkTemplate, NetworkSlice
10
11from django.http import HttpResponse
12from django.views.decorators.csrf import csrf_exempt
13
smbakere36a7de2013-10-29 17:25:25 -070014def ps_id_to_pl_id(x):
Scott Baker670848a2015-02-18 16:02:46 -080015 # Since we don't want the XOS object IDs to conflict with existing
16 # PlanetLab object IDs in the CMI, just add 100000 to the XOS object
smbakere36a7de2013-10-29 17:25:25 -070017 # IDs.
18 return 100000 + x
19
20def pl_id_to_ps_id(x):
21 return x - 100000
22
Scott Baker9cc9bf32013-12-13 17:26:07 -080023# slice_remap is a dict of ps_slice_name -> (pl_slice_name, pl_slice_id)
24
25def pl_slice_id(slice, slice_remap={}):
26 if slice.name in slice_remap:
27 return int(slice_remap[slice.name][1])
smbakere36a7de2013-10-29 17:25:25 -070028 else:
29 return ps_id_to_pl_id(slice.id)
30
Scott Baker9cc9bf32013-12-13 17:26:07 -080031def pl_slicename(slice, slice_remap={}):
32 if slice.name in slice_remap:
33 return slice_remap[slice.name][0]
34 else:
35 return slice.name
smbakere36a7de2013-10-29 17:25:25 -070036
37def filter_fields(src, fields):
38 dest = {}
39 for (key,value) in src.items():
40 if (not fields) or (key in fields):
41 dest[key] = value
42 return dest
43
Scott Baker9cc9bf32013-12-13 17:26:07 -080044def GetSlices(filter={}, slice_remap={}):
45 #ps_slices = Slice.objects.filter(**filter)
46 ps_slices = Slice.objects.all()
smbakere36a7de2013-10-29 17:25:25 -070047 slices = []
48 for ps_slice in ps_slices:
Scott Baker9cc9bf32013-12-13 17:26:07 -080049 if (filter) and ("name" in filter):
50 remapped_name = slice_remap.get(ps_slice.name, (ps_slice.name,))[0]
51 if (remapped_name != filter["name"]):
52 continue
53
smbakere36a7de2013-10-29 17:25:25 -070054 node_ids=[]
55 for ps_sliver in ps_slice.slivers.all():
56 node_ids.append(ps_id_to_pl_id(ps_sliver.node.id))
57
58 slice = {"instantiation": "plc-instantiated",
Scott Baker670848a2015-02-18 16:02:46 -080059 "description": "XOS slice",
Scott Baker9cc9bf32013-12-13 17:26:07 -080060 "slice_id": pl_slice_id(ps_slice, slice_remap),
smbakere36a7de2013-10-29 17:25:25 -070061 "node_ids": node_ids,
Scott Baker670848a2015-02-18 16:02:46 -080062 "url": "xos",
smbakere36a7de2013-10-29 17:25:25 -070063 "max_nodes": 1000,
64 "peer_slice_id": None,
65 "slice_tag_ids": [],
66 "peer_id": None,
67 "site_id": ps_id_to_pl_id(ps_slice.site_id),
Scott Baker9cc9bf32013-12-13 17:26:07 -080068 "name": pl_slicename(ps_slice, slice_remap),
Scott Baker670848a2015-02-18 16:02:46 -080069 "planetstack_name": ps_slice.name} # keeping planetstack_name for now, to match the modified config.py
smbakere36a7de2013-10-29 17:25:25 -070070
71 # creator_person_id, person_ids, expires, created
72
73 slices.append(slice)
74 return slices
75
Scott Baker9cc9bf32013-12-13 17:26:07 -080076def GetNodes(node_ids=None, fields=None, slice_remap={}):
smbakere36a7de2013-10-29 17:25:25 -070077 if node_ids:
78 ps_nodes = Node.objects.filter(id__in=[pl_id_to_ps_id(nid) for nid in node_ids])
79 else:
80 ps_nodes = Node.objects.all()
81 nodes = []
82 for ps_node in ps_nodes:
83 slice_ids=[]
84 for ps_sliver in ps_node.slivers.all():
Scott Baker9cc9bf32013-12-13 17:26:07 -080085 slice_ids.append(pl_slice_id(ps_sliver.slice, slice_remap))
smbakere36a7de2013-10-29 17:25:25 -070086
87 node = {"node_id": ps_id_to_pl_id(ps_node.id),
88 "site_id": ps_id_to_pl_id(ps_node.site_id),
89 "node_type": "regular",
90 "peer_node_id": None,
Scott Bakercb236252014-10-09 11:10:05 -070091 "hostname": ps_node.name.lower(),
smbakere36a7de2013-10-29 17:25:25 -070092 "conf_file_ids": [],
93 "slice_ids": slice_ids,
Scott Baker670848a2015-02-18 16:02:46 -080094 "model": "xos",
smbakere36a7de2013-10-29 17:25:25 -070095 "peer_id": None,
96 "node_tag_ids": []}
97
98 # last_updated, key, boot_state, pcu_ids, node_type, session, last_boot,
99 # interface_ids, slice_ids_whitelist, run_level, ssh_rsa_key, last_pcu_reboot,
100 # nodegroup_ids, verified, last_contact, boot_nonce, version,
101 # last_pcu_configuration, last_download, date_created, ports
102
103 nodes.append(node)
104
105 nodes = [filter_fields(node, fields) for node in nodes]
106
107 return nodes
108
109def GetTags(slicename,node_id):
110 return {}
111
Scott Baker9cc9bf32013-12-13 17:26:07 -0800112def GetSites(slice_remap={}):
smbakere36a7de2013-10-29 17:25:25 -0700113 ps_sites = Site.objects.all()
114 sites = []
115 for ps_site in ps_sites:
116 slice_ids=[]
117 for ps_slice in ps_site.slices.all():
Scott Baker9cc9bf32013-12-13 17:26:07 -0800118 slice_ids.append(pl_slice_id(ps_slice, slice_remap))
smbakere36a7de2013-10-29 17:25:25 -0700119
120 node_ids=[]
121 for ps_node in ps_site.nodes.all():
122 node_ids.append(ps_id_to_pl_id(ps_node.id))
123
smbakere36a7de2013-10-29 17:25:25 -0700124 site = {"site_id": ps_id_to_pl_id(ps_site.id),
125 "node_ids": node_ids,
126 "pcu_ids": [],
127 "max_slices": 100,
128 "max_slivers": 1000,
129 "is_public": False,
130 "peer_site_id": None,
131 "abbrebiated_name": ps_site.abbreviated_name,
132 "address_ids": [],
133 "name": ps_site.name,
134 "url": None,
135 "site_tag_ids": [],
136 "enabled": True,
137 "longitude": float(ps_site.location.longitude),
138 "latitude": float(ps_site.location.latitude),
139 "slice_ids": slice_ids,
140 "login_base": ps_site.login_base,
141 "peer_id": None}
142
143 # last_updated, ext_consortium_id, person_ids, date_created
144
145 sites.append(site)
146
147 return sites
148
Scott Baker4f276852015-04-13 15:45:47 -0700149def GetInterfaces(slicename, node_ids, return_nat=False, return_private=False):
smbakere36a7de2013-10-29 17:25:25 -0700150 interfaces = []
151 ps_slices = Slice.objects.filter(name=slicename)
152 for ps_slice in ps_slices:
153 for ps_sliver in ps_slice.slivers.all():
154 node_id = ps_id_to_pl_id(ps_sliver.node_id)
155 if node_id in node_ids:
156 ps_node = ps_sliver.node
Scott Baker2b9f5202014-09-09 14:54:48 -0700157
Scott Bakere4a33932015-02-25 23:11:53 -0800158 ip = socket.gethostbyname(ps_node.name.strip())
Scott Baker2b9f5202014-09-09 14:54:48 -0700159
Scott Bakerd4dc1182015-06-04 17:11:21 -0700160 # If the slice has a network that's labeled for hpc_client, then
161 # return that network.
162 found_labeled_network = False
Scott Bakereb70ceb2015-08-27 18:39:16 -0700163 for port in ps_sliver.ports.all():
164 if (not port.ip):
Scott Baker2b9f5202014-09-09 14:54:48 -0700165 continue
Scott Bakereb70ceb2015-08-27 18:39:16 -0700166 if (port.network.owner != ps_slice):
Scott Bakerd4dc1182015-06-04 17:11:21 -0700167 continue
Scott Bakereb70ceb2015-08-27 18:39:16 -0700168 if port.network.labels and ("hpc_client" in port.network.labels):
169 ip=port.ip
Scott Bakerd4dc1182015-06-04 17:11:21 -0700170 found_labeled_network = True
171
172 if not found_labeled_network:
173 # search for a dedicated public IP address
Scott Bakereb70ceb2015-08-27 18:39:16 -0700174 for port in ps_sliver.ports.all():
175 if (not port.ip):
Scott Bakerd4dc1182015-06-04 17:11:21 -0700176 continue
Scott Bakereb70ceb2015-08-27 18:39:16 -0700177 template = port.network.template
Scott Bakerd4dc1182015-06-04 17:11:21 -0700178 if (template.visibility=="public") and (template.translation=="none"):
Scott Bakereb70ceb2015-08-27 18:39:16 -0700179 ip=port.ip
Scott Baker2b9f5202014-09-09 14:54:48 -0700180
Scott Baker4f276852015-04-13 15:45:47 -0700181 if return_nat:
182 ip = None
Scott Bakereb70ceb2015-08-27 18:39:16 -0700183 for port in ps_sliver.ports.all():
184 if (not port.ip):
Scott Baker4f276852015-04-13 15:45:47 -0700185 continue
Scott Bakereb70ceb2015-08-27 18:39:16 -0700186 template = port.network.template
Scott Baker4f276852015-04-13 15:45:47 -0700187 if (template.visibility=="private") and (template.translation=="NAT"):
Scott Bakereb70ceb2015-08-27 18:39:16 -0700188 ip=port.ip
Scott Baker4f276852015-04-13 15:45:47 -0700189 if not ip:
190 continue
191
192 if return_private:
193 ip = None
Scott Bakereb70ceb2015-08-27 18:39:16 -0700194 for port in ps_sliver.ports.all():
195 if (not port.ip):
Scott Baker4f276852015-04-13 15:45:47 -0700196 continue
Scott Bakereb70ceb2015-08-27 18:39:16 -0700197 template = port.network.template
Scott Baker4f276852015-04-13 15:45:47 -0700198 if (template.visibility=="private") and (template.translation=="none"):
Scott Bakereb70ceb2015-08-27 18:39:16 -0700199 ip=port.ip
Scott Baker4f276852015-04-13 15:45:47 -0700200 if not ip:
201 continue
202
smbakere36a7de2013-10-29 17:25:25 -0700203 interface = {"node_id": node_id,
Scott Baker2b9f5202014-09-09 14:54:48 -0700204 "ip": ip,
smbakere36a7de2013-10-29 17:25:25 -0700205 "broadcast": None,
206 "mac": "11:22:33:44:55:66",
207 "bwlimit": None,
208 "network": None,
209 "is_primary": True,
210 "dns1": None,
211 "hostname": None,
212 "netmask": None,
213 "interface_tag_ids": [],
214 "interface_id": node_id, # assume each node has only one interface
215 "gateway": None,
216 "dns2": None,
217 "type": "ipv4",
218 "method": "dhcp"}
219 interfaces.append(interface)
220 return interfaces
221
Scott Baker9cc9bf32013-12-13 17:26:07 -0800222def GetConfiguration(name, slice_remap={}):
smbakere36a7de2013-10-29 17:25:25 -0700223 slicename = name["name"]
224 if "node_id" in name:
225 node_id = name["node_id"]
226 else:
227 node_id = 0
228
smbakere36a7de2013-10-29 17:25:25 -0700229 node_sliver_tags = GetTags(slicename, node_id)
230
Scott Baker9cc9bf32013-12-13 17:26:07 -0800231 slices = GetSlices({"name": slicename}, slice_remap=slice_remap)
smbakere36a7de2013-10-29 17:25:25 -0700232 perhost = {}
233 allinterfaces = {}
Scott Bakerd4dc1182015-06-04 17:11:21 -0700234 hostprivmap = {}
smbakere36a7de2013-10-29 17:25:25 -0700235 hostipmap = {}
Scott Baker4f276852015-04-13 15:45:47 -0700236 hostnatmap = {}
smbakere36a7de2013-10-29 17:25:25 -0700237 nodes = []
238 if len(slices)==1:
239 slice = slices[0]
240 node_ids = slice['node_ids']
Scott Baker9cc9bf32013-12-13 17:26:07 -0800241 nodes = GetNodes(node_ids, ['hostname', 'node_id', 'site_id'], slice_remap=slice_remap)
smbakere36a7de2013-10-29 17:25:25 -0700242 nodemap = {}
243 for node in nodes:
244 nodemap[node['node_id']]=node['hostname']
245
Scott Baker9cc9bf32013-12-13 17:26:07 -0800246 interfaces = GetInterfaces(slice["planetstack_name"], node_ids)
smbakere36a7de2013-10-29 17:25:25 -0700247 hostipmap = {}
248 for interface in interfaces:
249 if nodemap[interface['node_id']] not in allinterfaces:
250 allinterfaces[nodemap[interface['node_id']]] = []
251 interface['interface_tags'] = []
252 allinterfaces[nodemap[interface['node_id']]].append(interface)
253 if interface['is_primary']:
254 hostipmap[nodemap[interface['node_id']]] = interface['ip']
255
Scott Baker4f276852015-04-13 15:45:47 -0700256 hostnatmap = {}
257 interfaces = GetInterfaces(slice["planetstack_name"], node_ids, return_nat=True)
258 for interface in interfaces:
259 interface['interface_tags'] = []
260 hostnatmap[nodemap[interface['node_id']]] = interface['ip']
261
262 hostprivmap = {}
263 interfaces = GetInterfaces(slice["planetstack_name"], node_ids, return_private=True)
264 for interface in interfaces:
265 interface['interface_tags'] = []
266 hostprivmap[nodemap[interface['node_id']]] = interface['ip']
267
smbakere36a7de2013-10-29 17:25:25 -0700268 for nid in node_ids:
269 sliver_tags = GetTags(slicename,nid)
270 perhost[nodemap[nid]] = sliver_tags
271
Scott Baker9cc9bf32013-12-13 17:26:07 -0800272 slivers = GetSlices(slice_remap=slice_remap)
smbakere36a7de2013-10-29 17:25:25 -0700273 if node_id != 0:
274 slivers = [slice for slice in slivers if (node_id in slice.node_ids)]
275
Scott Baker9cc9bf32013-12-13 17:26:07 -0800276 sites = GetSites(slice_remap=slice_remap)
smbakere36a7de2013-10-29 17:25:25 -0700277 for site in sites:
278 site["site_tags"] = []
279
280 timestamp = int(time.time())
281 return {'version': 3,
282 'timestamp': timestamp,
283 'configuration': node_sliver_tags,
284 'allconfigurations':perhost,
285 'hostipmap':hostipmap,
Scott Baker4f276852015-04-13 15:45:47 -0700286 'hostnatmap':hostnatmap,
287 'hostprivmap':hostprivmap,
smbakere36a7de2013-10-29 17:25:25 -0700288 'slivers': slivers,
289 'interfaces': allinterfaces,
290 'sites': sites,
291 'nodes': nodes}
292
Scott Baker9cc9bf32013-12-13 17:26:07 -0800293DEFAULT_REMAP = {"princeton_vcoblitz2": ["princeton_vcoblitz", 70]}
294
295def HandleGetConfiguration1():
smbakere36a7de2013-10-29 17:25:25 -0700296 configs={}
297 for slicename in ["princeton_vcoblitz"]:
Scott Baker9cc9bf32013-12-13 17:26:07 -0800298 configs[slicename] = GetConfiguration({"name": slicename}, DEFAULT_REMAP)
smbakerf33829c2013-10-29 17:46:32 -0700299 return configs
smbakere36a7de2013-10-29 17:25:25 -0700300
Scott Baker9cc9bf32013-12-13 17:26:07 -0800301def HandleGetNodes1():
302 return GetNodes(slice_remap=DEFAULT_REMAP)
smbakere36a7de2013-10-29 17:25:25 -0700303
Scott Baker9cc9bf32013-12-13 17:26:07 -0800304def HandleGetSlices1():
305 return GetSlices(slice_remap=DEFAULT_REMAP)
smbakerf33829c2013-10-29 17:46:32 -0700306
Scott Baker9cc9bf32013-12-13 17:26:07 -0800307def HandleGetConfiguration2(name, slice_remap):
308 return GetConfiguration(name, slice_remap=slice_remap)
smbakerf33829c2013-10-29 17:46:32 -0700309
Scott Baker9cc9bf32013-12-13 17:26:07 -0800310def HandleGetNodes2(slice_remap):
311 return GetNodes(slice_remap=slice_remap)
312
313def HandleGetSlices2(slice_remap):
314 return GetSlices(slice_remap=slice_remap)
315
316FUNCS = {"GetConfiguration": HandleGetConfiguration1,
317 "GetNodes": HandleGetNodes1,
318 "GetSlices": HandleGetSlices1,
319 "GetConfiguration2": HandleGetConfiguration2,
320 "GetNodes2": HandleGetNodes2,
321 "GetSlices2": HandleGetSlices2}
smbakere36a7de2013-10-29 17:25:25 -0700322
323@csrf_exempt
324def LegacyXMLRPC(request):
325 if request.method == "POST":
326 try:
327 (args, method) = xmlrpclib.loads(request.body)
328 result = None
smbakerf33829c2013-10-29 17:46:32 -0700329 if method in FUNCS:
Scott Baker9cc9bf32013-12-13 17:26:07 -0800330 result = FUNCS[method](*args)
smbakere36a7de2013-10-29 17:25:25 -0700331 return HttpResponse(xmlrpclib.dumps((result,), methodresponse=True, allow_none=1))
332 except:
333 traceback.print_exc()
334 return HttpResponseServerError()
335 else:
336 return HttpResponse("Not Implemented")
337
338if __name__ == '__main__':
Scott Baker9cc9bf32013-12-13 17:26:07 -0800339 slices = GetSlices(slice_remap = DEFAULT_REMAP)
340 nodes = GetNodes(slice_remap = DEFAULT_REMAP)
smbakere36a7de2013-10-29 17:25:25 -0700341
Scott Baker670848a2015-02-18 16:02:46 -0800342 config = GetConfiguration({"name": "princeton_vcoblitz"}, slice_remap = DEFAULT_REMAP)
343 print config
344 print slices
345 print nodes
smbakere36a7de2013-10-29 17:25:25 -0700346