5 from time import mktime
9 from django.shortcuts import render_to_response
10 from django.http import HttpResponse,QueryDict
12 from sfa.trust.certificate import Keypair, Certificate
13 from sfa.client.sfaserverproxy import SfaServerProxy
14 from manifold.gateways.sfa.proxy import SFAProxy
15 from sfa.client.return_value import ReturnValue
16 from sfa.util.xrn import Xrn, get_leaf, get_authority, hrn_to_urn, urn_to_hrn
18 from manifold.core.query import Query
20 from manifoldapi.manifoldapi import execute_admin_query
22 from unfold.loginrequired import LoginRequiredView
24 from myslice.settings import logger, config
26 from repoze.lru import lru_cache
27 from rest.json_encoder import MyEncoder
29 def dispatch(request, method):
37 # Have to be hashable for lru_cache
38 options = frozenset() # dict()
39 platforms = frozenset() # list()
44 if request.method == 'POST':
45 req_items = request.POST
46 elif request.method == 'GET':
47 req_items = request.GET
49 logger.debug("URL = %s" % request.build_absolute_uri())
51 for el in req_items.items():
52 if el[0].startswith('rspec'):
54 elif el[0].startswith('platform'):
55 platforms = frozenset(req_items.getlist('platform[]'))
56 elif el[0].startswith('options'):
57 options_url = el[1] #req_items.getlist('options')
58 options = QueryDict(options_url)
59 elif el[0].startswith('output_format'):
60 output_format = el[1] #req_items.getlist('options')
61 elif el[0].startswith('hrn'):
63 elif el[0].startswith('urn'):
65 elif el[0].startswith('type'):
67 elif el[0].startswith('recursive'):
72 elif el[0].startswith('display'):
75 start_time = time.time()
76 results = sfa_client(request, method, hrn, urn, object_type, rspec, recursive, options, platforms, output_format, False)
77 logger.debug("EXEC TIME - sfa_client() - %s sec." % (time.time() - start_time))
78 if display == 'table':
79 return render_to_response('table-default.html', {'data' : data, 'fields' : columns, 'id' : '@component_id', 'options' : None})
81 return HttpResponse(json.dumps(results, cls=MyEncoder), content_type="application/json")
83 def get_user_account(request, user_email, platform_name):
85 Returns the user configuration for a given platform.
86 This function does not resolve references.
88 user_query = Query().get('local:user').filter_by('email', '==', user_email).select('user_id')
89 user_details = execute_admin_query(request, user_query)
90 platform_query = Query().get('local:platform').filter_by('platform', '==', platform_name).select('platform_id')
91 platform_details = execute_admin_query(request, platform_query)
93 account_query = Query().get('local:account').filter_by('platform_id','==',platform_details[0]['platform_id']).filter_by('user_id', '==', user_details[0]['user_id']).select('user_id','platform_id','auth_type','config')
94 accounts = execute_admin_query(request, account_query)
97 raise Exception, "this account does not exist"
99 if accounts[0]['auth_type'] == 'reference':
100 pf = json.loads(accounts[0]['config'])['reference_platform']
101 return get_user_account(request, user_email, pf)
106 def sfa_client(request, method, hrn=None, urn=None, object_type=None, rspec=None, recursive=False, options=None, platforms=None, output_format=None, admin=False):
108 Config = ConfigParser.ConfigParser()
109 monitor_file = os.path.abspath(os.path.dirname(__file__) + '/../myslice/monitor.ini')
110 Config.read(monitor_file)
113 user_email, admin_password = config.manifold_admin_user_password()
115 #logger.debug(request.session['user']['email'])
116 user_email = request.session['user']['email']
124 if object_type is None:
128 if recursive is None:
132 if platforms is None:
135 if method not in ['GetVersion','ListResources']:
138 hrn = urn_to_hrn(urn)
140 urn = hrn_to_urn(hrn, object_type)
143 raise Exception, "Provide urn OR hrn + type as parameters of method %s" % method
145 if len(platforms)==0:
146 platforms = get_platforms(request)
147 #platforms.append('myslice')
148 #results = {'method':method,'platforms':platforms,'rspec':rspec,'options':options}
155 api_options['list_leases'] = 'all'
158 platform = get_platform_config(request, pf)
159 logger.debug("platform={}".format(platform))
160 if 'sm' in platform and len(platform['sm']) > 0:
163 server_url = platform['sm']
164 if 'rm' in platform and len(platform['rm']) > 0:
167 server_url = platform['rm']
168 if 'registry' in platform and len(platform['registry']) > 0:
169 logger.debug('registry')
171 server_url = platform['registry']
173 if not Config.has_option('monitor', 'cert') :
174 #return HttpResponse(json.dumps({'error' : '-1'}), content_type="application/json")
175 return {'error' : '-1', 'msg': 'monitor.ini has no cert configured'}
177 cert = os.path.abspath(Config.get('monitor', 'cert'))
178 if not os.path.isfile(cert) :
179 #return HttpResponse(json.dumps({'error' : '-1'}), content_type="application/json")
180 return {'error' : '-1', 'msg': 'check cert file at %s'%cert}
182 if not Config.has_option('monitor', 'pkey') :
183 #return HttpResponse(json.dumps({'error' : '-2'}), content_type="application/json")
184 return {'error' : '-2'}
186 pkey = os.path.abspath(Config.get('monitor', 'pkey'))
187 if not os.path.isfile(pkey) :
188 #return HttpResponse(json.dumps({'error' : '-2'}), content_type="application/json")
189 return {'error' : '-2'}
191 server = SfaServerProxy(server_url, pkey, cert)
192 #server = SFAProxy(server_url, pkey, cert)
193 if 'geni_rspec_version' in options:
194 # GetVersion to know if the AM supports the requested version
195 # if not ask for the default GENI v3
196 start_time = time.time()
197 result = server.GetVersion()
198 logger.debug("EXEC TIME - GetVersion() - %s sec." % (time.time() - start_time))
200 logger.debug(result['value'])
201 if 'geni_ad_rspec_versions' in result['value']:
202 for v in result['value']['geni_ad_rspec_versions']:
203 if v['type'] == options['geni_rspec_version']:
204 api_options['geni_rspec_version'] = {'type': options['geni_rspec_version']}
207 api_options['geni_rspec_version'] = {'type': 'GENI', 'version': '3'}
209 api_options['geni_rspec_version'] = {'type': 'GENI', 'version': '3'}
212 # Get user config from Manifold
213 user_config = get_user_config(request, user_email, pf)
214 if 'delegated_user_credential' in user_config:
215 logger.debug('delegated_user_credential')
216 user_cred = user_config['delegated_user_credential']
217 elif 'user_credential' in user_config:
218 logger.debug('user_credential')
219 user_cred = user_config['user_credential']
221 logger.error("no user credentials for user = ", user_email)
225 if 'delegated_%s_credentials'%object_type in user_config:
226 logger.debug('delegated_%s_credentials'%object_type)
227 for obj_name, cred in user_config['delegated_%s_credentials'%object_type].items():
230 elif '%s_credentials'%object_type in user_config:
231 logger.debug('%s_credentials'%object_type)
232 for obj_name, cred in user_config['%s_credentials'%object_type].items():
236 logger.error("no credentials for object")
237 logger.error(object_type)
238 logger.error(object_name)
242 if method == "GetVersion":
243 start_time = time.time()
244 result = server.GetVersion()
245 logger.debug("EXEC TIME - GetVersion() - %s sec." % (time.time() - start_time))
249 if method == "ListResources":
250 logger.debug(api_options)
251 #logger.debug(user_cred)
252 start_time = time.time()
253 result = server.ListResources([user_cred], api_options)
254 logger.debug("EXEC TIME - ListResources() - %s sec." % (time.time() - start_time))
255 #logger.debug(result)
256 dict_result = xmltodict.parse(result['value'])
257 result['parsed'] = dict_result
258 if isinstance(dict_result['rspec']['node'], list):
259 columns.extend(dict_result['rspec']['node'][0].keys())
261 columns.extend(dict_result['rspec']['node'].keys())
263 elif method == "Describe":
264 start_time = time.time()
265 version = server.GetVersion()
266 logger.debug("EXEC TIME - GetVersion() - %s sec." % (time.time() - start_time))
267 logger.debug(version['geni_api'])
269 if version['geni_api'] == 2:
270 # ListResources(slice_hrn)
271 api_options['geni_slice_urn'] = urn
272 result = server.ListResources([object_cred], api_options)
273 dict_result = xmltodict.parse(result['value'])
274 # else GetVersion = v3
276 result = server.Describe([urn] ,[object_cred], api_options)
277 if isinstance(result, dict):
278 if result['value'] != 0:
279 dict_result = xmltodict.parse(result['value']['geni_rspec'])
281 result['parsed'] = dict_result
282 if 'rspec' in dict_result and 'node' in dict_result['rspec']:
283 if isinstance(dict_result['rspec']['node'], list):
284 columns.extend(dict_result['rspec']['node'][0].keys())
286 columns.extend(dict_result['rspec']['node'].keys())
288 elif method == 'Renew':
289 # Renew till 1 month from now
290 d = datetime.datetime.utcnow() + datetime.timedelta(365/12)
291 date = d.isoformat("T") + "Z"
292 result = server.Renew([urn] ,[object_cred], date, api_options)
293 elif method == 'Delete':
294 result = server.Delete([urn] ,[object_cred], api_options)
295 elif method == 'Allocate':
296 api_options['call_id'] = unique_call_id()
297 # List of users comes from the Registry
298 api_options['sfa_users'] = sfa_users
299 api_options['geni_users'] = geni_users
301 version = server.GetVersion()
302 if version['geni_api'] == 2:
303 result = server.CreateSliver([urn] ,[object_cred], rspec, api_options)
304 # else GetVersion = v3
306 result = server.Allocate([urn] ,[object_cred], rspec, api_options)
307 elif method == 'Provision':
309 # Nothing it is not supported by v2 AMs
310 version = server.GetVersion()
311 if version['geni_api'] == 3:
312 api_options['call_id'] = unique_call_id()
313 # List of users comes from the Registry
314 api_options['sfa_users'] = sfa_users
315 api_options['geni_users'] = geni_users
316 result = server.Provision([urn] ,[object_cred], api_options)
317 elif method == 'Status':
318 result = server.Status([urn] ,[object_cred], api_options)
319 elif method == 'PerformOperationalAction':
321 # Nothing it is not supported by v2 AMs
322 version = server.GetVersion()
323 if version['geni_api'] == 3:
324 result = server.PerformOperationalAction([urn] ,[object_cred], action, api_options)
325 elif method == 'Shutdown':
326 result = server.Shutdown(urn ,[object_cred], api_options)
328 #return HttpResponse(json.dumps({'error' : '-3','msg':'method not supported by AM'}), content_type="application/json")
329 logger.debug('method %s not handled by AM' % method)
334 record_dict = {'urn': urn, 'hrn': hrn, 'type': object_type}
337 api_options['recursive'] = recursive
338 result = server.List(hrn, user_cred, api_options)
340 result = filter_records(object_type, result)
341 elif method == "Resolve":
343 # details can be True or False
344 api_options['details']=True
345 result = server.Resolve(hrn, user_cred, api_options)
347 result = filter_records(object_type, result)
348 elif method == "Register":
349 # record_dict must be crafted
350 # auth_cred must be selected in the list of auth_creds from user's account
351 result = server.Register(record_dict, auth_cred)
352 elif method == "Update":
353 # record_dict must be crafted
354 # object_cred must be selected in the list of creds for the object type
355 # from user's account
356 result = server.Update(record_dict, object_cred)
357 elif method == "Remove":
359 # auth_cred must be selected in the list of auth_creds from user's account
360 # object_type is required
361 result = server.Remove(hrn, auth_cred, object_type)
363 #return HttpResponse(json.dumps({'error' : '-3','msg':'method not supported by Registry'}), content_type="application/json")
364 logger.debug('method %s not handled by Registry' % method)
366 if output_format is not None:
367 if 'value' in result:
368 # TODO Python Caching
369 # to avoid translating the same RSpec in the same format several times
370 start_time = time.time()
371 result = translate(result['value'],output_format)
372 logger.debug("EXEC TIME - translate() - %s sec." % (time.time() - start_time))
376 if 'rspec' in dict_result and 'node' in dict_result['rspec']:
377 if isinstance(dict_result['rspec']['node'], list):
378 data = data + dict_result['rspec']['node']
380 data.append(dict_result['rspec']['node'])
383 logger.error(traceback.format_exc())
385 results[pf] = {'error':'-3', 'result':result,'error_msg': str(e)}
387 results['columns'] = columns
391 def translate(rspec, output_format):
395 values = {'content' : rspec}
396 url = 'https://demo.fiteagle.org/omnweb/convert/to/' + output_format
397 data = urllib.urlencode(values)
398 req = urllib2.Request(url, data)
399 response = urllib2.urlopen(req)
400 return response.read()
402 def get_user_config(request, user_email, platform_name):
403 account = get_user_account(request, user_email, platform_name)
404 return json.loads(account['config']) if account['config'] else {}
406 def get_platforms(request):
408 platform_query = Query().get('local:platform').filter_by('gateway_type', '==', 'sfa').filter_by('disabled','==',0).select('platform')
409 platforms = execute_admin_query(request, platform_query)
412 ret.append(p['platform'])
415 def get_platform_config(request, platform_name):
416 platform_query = Query().get('local:platform').filter_by('platform', '==', platform_name).select('platform', 'config')
417 platforms = execute_admin_query(request, platform_query)
419 return json.loads(platforms[0]['config']) if platforms[0]['config'] else {}
421 def filter_records(type, records):
422 filtered_records = []
423 for record in records:
424 if (record['type'] == type) or (type == "all"):
425 filtered_records.append(record)
426 return filtered_records