def call_api(request, service): """Serves as agave api for apps, files, systems, meta :param request: http request from angular service :returns: JSON response for agave call """ if request.user.is_authenticated(): try: token = request.user.agave_oauth agave = Agave(api_server=settings.AGAVE_TENANT_BASEURL, token=token.access_token, resources=AGAVE_RESOURCES) if service == 'apps': appId = request.GET.get('appId') pems = request.GET.get('pems') if request.method == 'GET': if appId: if pems: metrics.info('agave.apps.listPermissions', extra={ 'operation': 'agave.apps.listPermissions', 'user': request.user.username, 'info': { 'appId': appId } }) data = agave.apps.listPermissions(appId=appId) else: metrics.info('agave.apps.get', extra={ 'operation': 'agave.apps.get', 'user': request.user.username, 'info': { 'appId': appId } }) data = agave.apps.get(appId=appId) lic_type = _app_license_type(appId) data['license'] = {'type': lic_type} if lic_type is not None: _, license_models = get_license_info() license_model = [ x for x in license_models if x.license_type == lic_type ][0] lic = license_model.objects.filter( user=request.user).first() data['license']['enabled'] = lic is not None else: metrics.info('agave.apps.list', extra={ 'operation': 'agave.apps.list', 'user': request.user.username, 'info': {} }) data = agave.apps.list(search={ 'filter': '*', 'available': True }) elif request.method == 'POST': body = json.loads(request.body) if (appId): if pems: username = request.GET.get('username') metrics.info( 'agave.apps.updatePermissionsForUser', extra={ 'operation': 'agave.apps.updatePermissionsForUser', 'user': request.user.username, 'info': { 'username': username } }) data = agave.apps.updatePermissionsForUser( appId=appId, username=username, body=body) else: metrics.info('agave.apps.manage', extra={ 'operation': 'agave.apps.manage', 'user': request.user.username, 'info': { 'appId': appId, 'body': body } }) data = agave.apps.manage(appId=appId, body=body) else: metrics.info('agave.apps.add', extra={ 'operation': 'agave.apps.add', 'user': request.user.username, 'info': { 'body': body } }) data = agave.apps.add(body=body) elif request.method == 'DELETE': metrics.info('apps DELETE') if appId: if pems: username = request.GET.get('username') metrics.info( 'agave.apps.deletePermissionsForUser', extra={ 'operation': 'agave.apps.deletePermissionsForUser', 'user': request.user.username, 'info': { 'username': username } }) data = agave.apps.deletePermissionsForUser( appId=appId, username=username) else: metrics.info('agave.apps.delete', extra={ 'operation': 'agave.apps.delete', 'user': request.user.username, 'info': { 'appId': appId } }) data = agave.apps.delete(appId=appId) elif service == 'files': system_id = request.GET.get('system_id') path = request.GET.get('path') metrics.info('agave.files.list', extra={ 'operation': 'agave.files.list', 'user': request.user.username, 'info': { 'system_id': system_id, 'path': path } }) if (system_id and path): data = agave.files.list(systemId=system_id, filePath=path) elif service == 'systems': system_id = request.GET.get('system_id') public = request.GET.get('isPublic') type = request.GET.get('type') roles = request.GET.get('roles') user_role = request.GET.get('user_role') if request.method == 'GET': if system_id: if roles: metrics.info('agave.systems.listRoles', extra={ 'operation': 'agave.systems.listRoles', 'user': request.user.username, 'info': { 'system_id': system_id } }) data = agave.systems.listRoles(systemId=system_id) elif user_role: metrics.info('agave.systems.getRoleForUser', extra={ 'operation': 'agave.systems.getRoleForUser', 'user': request.user.username, 'info': { 'system_id': system_id } }) data = agave.systems.getRoleForUser( systemId=system_id, username=request.user.username) else: metrics.info('agave.systems.get', extra={ 'operation': 'agave.systems.get', 'user': request.user.username, 'info': { 'system_id': system_id } }) data = agave.systems.get(systemId=system_id) else: if (public): if (type): logger.debug('SHOULD BE HERE') metrics.info('agave.systems.list', extra={ 'operation': 'agave.systems.list public', 'user': request.user.username, 'info': { 'public': public, 'type': type } }) data = agave.systems.list(public=public, type=type) else: metrics.info('agave.systems.list', extra={ 'operation': 'agave.systems.list public', 'user': request.user.username, 'info': { 'public': public } }) data = agave.systems.list(public=public) else: if (type): metrics.info('agave.systems.list', extra={ 'operation': 'agave.systems.list', 'user': request.user.username, 'info': { 'type': type } }) data = agave.systems.list(type=type) else: metrics.info('agave.systems.list', extra={ 'operation': 'agave.systems.list', 'user': request.user.username, 'info': {} }) data = agave.systems.list() elif service == 'meta': uuid = request.GET.get('uuid') pems = request.GET.get('pems') query = request.GET.get('q') if request.method == 'GET': if pems: if uuid: metrics.info( 'agave.meta.listMetadataPermissions', extra={ 'user': request.user.username, 'operation': 'agave.meta.listMetadataPermissions', 'info': { 'uuid': uuid } }) data = agave.meta.listMetadataPermissions( uuid=uuid) else: if uuid: metrics.info('agave.meta.getMetadata', extra={ 'operation': 'agave.meta.getMetadata', 'user': request.user.username, 'info': { 'uuid': uuid } }) data = agave.meta.getMetadata(uuid=uuid) elif query: metrics.info('agave.meta.listMetadata', extra={ 'operation': 'agave.meta.listMetadata', 'user': request.user.username, 'info': { 'query': query } }) data = agave.meta.listMetadata(q=query, limit=0) else: metrics.info('agave.meta.listMetadata') data = agave.meta.listMetadata() elif request.method == 'POST': body = json.loads(request.body) metrics.info('meta POST body', extra={ 'operation': 'agave.meta.listMetadata', 'user': request.user.username, 'info': { 'body': body } }) if pems: username = request.GET.get('username') if username: metrics.info( 'agave.meta.updateMetadataPermissionsForUser', extra={ 'operation': 'agave.meta.listMetadata', 'user': request.user.username, 'info': { 'uuid': uuid, 'username': username } }) data = agave.meta.updateMetadataPermissionsForUser( body=body, uuid=uuid, username=username) else: metrics.info('agave.meta.updateMetadata', extra={ 'operation': 'agave.meta.listMetadata', 'user': request.user.username, 'info': { 'uuid': uuid } }) data = agave.meta.updateMetadata(body=body, uuid=uuid) index_or_update_project.apply_async(args=[uuid], queue='api') else: if uuid: metrics.info('agave.meta.updateMetadata uuid', extra={ 'operation': 'agave.meta.listMetadata', 'user': request.user.username, 'info': { 'uuid': uuid } }) data = agave.meta.updateMetadata(uuid=uuid, body=body) index_or_update_project.apply_async(args=[uuid], queue='api') else: metrics.info('agave.meta.addMetadata', extra={ 'operation': 'agave.meta.listMetadata', 'user': request.user.username, 'info': { 'body': body } }) data = agave.meta.addMetadata(body=body) elif request.method == 'DELETE': if uuid: if pems: username = request.GET.get('username') metrics.info( 'agave.meta.deleteMetadataPermissionsForUser', extra={ 'operation': 'agave.meta.listMetadata', 'user': request.user.username, 'info': { 'username': username } }) data = agave.meta.deleteMetadataPermissionsForUser( uuid=uuid, username=username) else: metrics.info('agave.meta.deleteMetadata', extra={ 'operation': 'agave.meta.listMetadata', 'user': request.user.username, 'info': { 'uuid': uuid } }) data = agave.meta.deleteMetadata(uuid=uuid) elif service == 'sync': uuid = request.GET.get('uuid') pems = request.GET.get('pems') appId = request.GET.get('appId') query = request.GET.get('q') ds_admin_client = Agave(api_server=getattr( settings, 'AGAVE_TENANT_BASEURL'), token=getattr(settings, 'AGAVE_SUPER_TOKEN')) if request.method == 'GET': if appId and pems: metrics.info( 'ds_admin_client.apps.listPermissions', extra={ 'operation': 'ds_admin_client.apps.listPermissions', 'user': '******', 'info': { 'appId': appId } }) data = ds_admin_client.apps.listPermissions( appId=appId) else: metrics.info('ds_admin_client.meta.listMetadata', extra={ 'operation': 'ds_admin_client.meta.listMetadata', 'user': '******', 'info': { 'query': query } }) data = ds_admin_client.meta.listMetadata(q=query) elif request.method == 'POST': body = json.loads(request.body) username = request.GET.get('username') if pems and username: metrics.info( 'ds_admin_client.meta.updateMetadataPermissionsForUser', extra={ 'operation': 'agave.meta.listMetadata', 'user': '******', 'info': { 'body': body, 'uuid': uuid, 'username': username } }) data = ds_admin_client.meta.updateMetadataPermissionsForUser( body=body, uuid=uuid, username=username) else: return HttpResponse('Unexpected service: %s' % service, status=400) except AgaveException as e: logger.error( 'Failed to execute {0} API call due to AgaveException={1}'. format(service, e)) return HttpResponse(json.dumps(e), content_type='application/json', status=400) except HTTPError as e: try: json_response = e.response.json() metrics.info( 'Failed to execute {0} API call due to HTTPError={1}'. format(service, json_response.get('message')), extra={ 'operation': 'agave.meta.listMetadata', 'user': request.user.username, 'info': {} }) logger.error( 'Failed to execute {0} API call due to HTTPError={1}'. format(service, json_response.get('message'))) return HttpResponse(json.dumps(json_response.get('message')), content_type='application/json', status=400) except Exception as e: return HttpResponse(json.dumps(e), content_type='application/json', status=400) except Exception as e: metrics.info( 'Failed to execute {0} API call due to Exception={1}'.format( service, e), extra={ 'operation': 'agave.meta.listMetadata', 'user': request.user.username, 'info': {} }) logger.error( 'Failed to execute {0} API call due to Exception={1}'.format( service, e), extra={'user': request.user.username}) return HttpResponse(json.dumps({ 'status': 'error', 'message': '{}'.format(e) }), content_type='application/json', status=400) return HttpResponse(json.dumps(data, cls=DjangoJSONEncoder), content_type='application/json') else: return HttpResponse(json.dumps({ 'status': 'error', 'message': 'Invalid credentials. Please login.' }), content_type='application/json', status=400)
def call_api(request, service): try: agave = request.user.agave_oauth.client if service == 'apps': app_id = request.GET.get('app_id') if app_id: data = agave.apps.get(appId=app_id) data['exec_sys'] = agave.systems.get( systemId=data['executionSystem']) lic_type = _app_license_type(app_id) data['license'] = {'type': lic_type} if lic_type is not None: _, license_models = get_license_info() license_model = [ x for x in license_models if x.license_type == lic_type ][0] lic = license_model.objects.filter( user=request.user).first() data['license']['enabled'] = lic is not None else: public_only = request.GET.get('publicOnly') if public_only == 'true': data = agave.apps.list(publicOnly='true') else: data = agave.apps.list() elif service == 'monitors': target = request.GET.get('target') ds_admin_client = Agave(api_server=getattr(settings, 'AGAVE_TENANT_BASEURL'), token=getattr(settings, 'AGAVE_SUPER_TOKEN')) data = ds_admin_client.monitors.list(target=target) elif service == 'meta': app_id = request.GET.get('app_id') if request.method == 'GET': if app_id: data = agave.meta.get(appId=app_id) lic_type = _app_license_type(app_id) data['license'] = {'type': lic_type} if lic_type is not None: _, license_models = get_license_info() license_model = [ x for x in license_models if x.license_type == lic_type ][0] lic = license_model.objects.filter( user=request.user).first() data['license']['enabled'] = lic is not None else: query = request.GET.get('q') data = agave.meta.listMetadata(q=query) elif request.method == 'POST': meta_post = json.loads(request.body) meta_uuid = meta_post.get('uuid') if meta_uuid: del meta_post['uuid'] data = agave.meta.updateMetadata(uuid=meta_uuid, body=meta_post) index_or_update_project.apply_async(args=[meta_uuid], queue='api') else: data = agave.meta.addMetadata(body=meta_post) elif request.method == 'DELETE': meta_uuid = request.GET.get('uuid') if meta_uuid: data = agave.meta.deleteMetadata(uuid=meta_uuid) # TODO: Need auth on this DELETE business elif service == 'jobs': if request.method == 'DELETE': job_id = request.GET.get('job_id') data = agave.jobs.delete(jobId=job_id) elif request.method == 'POST': job_post = json.loads(request.body) logger.debug(job_post) job_id = job_post.get('job_id') # cancel job / stop job if job_id: data = agave.jobs.manage(jobId=job_id, body='{"action":"stop"}') # submit job elif job_post: # cleaning archive path value if 'archivePath' in job_post: parsed = urlparse(job_post['archivePath']) if parsed.path.startswith('/'): # strip leading '/' archive_path = parsed.path[1:] else: archive_path = parsed.path job_post['archivePath'] = archive_path if parsed.netloc: job_post['archiveSystem'] = parsed.netloc else: job_post['archivePath'] = \ '{}/archive/jobs/{}/${{JOB_NAME}}-${{JOB_ID}}'.format( request.user.username, datetime.now().strftime('%Y-%m-%d')) # check for running licensed apps lic_type = _app_license_type(job_post['appId']) if lic_type is not None: _, license_models = get_license_info() license_model = [ x for x in license_models if x.license_type == lic_type ][0] lic = license_model.objects.filter( user=request.user).first() job_post['parameters'][ '_license'] = lic.license_as_str() # url encode inputs if job_post['inputs']: for key, value in six.iteritems(job_post['inputs']): if type(value) == list: inputs = [] for val in value: parsed = urlparse(val) if parsed.scheme: inputs.append('{}://{}{}'.format( parsed.scheme, parsed.netloc, urllib.parse.quote(parsed.path))) else: inputs.append( urllib.parse.quote(parsed.path)) job_post['inputs'][key] = inputs else: parsed = urlparse(value) if parsed.scheme: job_post['inputs'][ key] = '{}://{}{}'.format( parsed.scheme, parsed.netloc, urllib.parse.quote(parsed.path)) else: job_post['inputs'][ key] = urllib.parse.quote(parsed.path) if settings.DEBUG: wh_base_url = settings.WEBHOOK_POST_URL.strip( '/') + '/webhooks/' jobs_wh_url = settings.WEBHOOK_POST_URL + reverse( 'designsafe_api:jobs_wh_handler') else: wh_base_url = request.build_absolute_uri('/webhooks/') jobs_wh_url = request.build_absolute_uri( reverse('designsafe_api:jobs_wh_handler')) job_post['parameters']['_webhook_base_url'] = wh_base_url # Remove any params from job_post that are not in appDef for param, _ in list(job_post['parameters'].items()): if not any(p['id'] == param for p in job_post['appDefinition']['parameters']): del job_post['parameters'][param] del job_post['appDefinition'] job_post['notifications'] = [{ 'url': jobs_wh_url, 'event': e } for e in [ "PENDING", "QUEUED", "SUBMITTING", "PROCESSING_INPUTS", "STAGED", "RUNNING", "KILLED", "FAILED", "STOPPED", "FINISHED", "BLOCKED" ]] try: data = submit_job(request, request.user.username, job_post) except JobSubmitError as e: data = e.json() logger.error('Failed to submit job {0}'.format(data)) return HttpResponse(json.dumps(data), content_type='application/json', status=e.status_code) # list jobs (via POST?) else: limit = request.GET.get('limit', 10) offset = request.GET.get('offset', 0) data = agave.jobs.list(limit=limit, offset=offset) elif request.method == 'GET': job_id = request.GET.get('job_id') # get specific job info if job_id: data = agave.jobs.get(jobId=job_id) q = {"associationIds": job_id} job_meta = agave.meta.listMetadata(q=json.dumps(q)) data['_embedded'] = {"metadata": job_meta} archive_system_path = '{}/{}'.format( data['archiveSystem'], data['archivePath']) data['archiveUrl'] = reverse('designsafe_data:data_depot') data['archiveUrl'] += 'agave/{}/'.format( archive_system_path) # list jobs else: limit = request.GET.get('limit', 10) offset = request.GET.get('offset', 0) data = agave.jobs.list(limit=limit, offset=offset) else: return HttpResponse('Unexpected service: %s' % service, status=400) elif service == 'ipynb': put = json.loads(request.body) dir_path = put.get('file_path') system = put.get('system') data = WorkspaceUtils.setup_identity_file(request.user.username, agave, system, dir_path) elif service == 'description': app_id = request.GET.get('app_id') try: data = AppDescription.objects.get(appId=app_id).desc_to_dict() except ObjectDoesNotExist: return HttpResponse( 'No description found for {}'.format(app_id), status=200) else: return HttpResponse('Unexpected service: %s' % service, status=400) except HTTPError as e: logger.exception( 'Failed to execute %s API call due to HTTPError=%s\n%s', service, e, e.response.content) return HttpResponse(json.dumps(e), content_type='application/json', status=400) except AgaveException as e: logger.exception( 'Failed to execute {0} API call due to AgaveException={1}'.format( service, e)) return HttpResponse(json.dumps(e), content_type='application/json', status=400) except Exception as e: logger.exception( 'Failed to execute {0} API call due to Exception={1}'.format( service, e)) return HttpResponse(json.dumps({ 'status': 'error', 'message': '{}'.format(e) }), content_type='application/json', status=400) return HttpResponse(json.dumps(data, cls=DjangoJSONEncoder), content_type='application/json')
def call_api(request, service): try: agave = request.user.agave_oauth.client if service == 'apps': app_id = request.GET.get('app_id') if app_id: data = agave.apps.get(appId=app_id) lic_type = _app_license_type(app_id) data['license'] = {'type': lic_type} if lic_type is not None: _, license_models = get_license_info() license_model = filter( lambda x: x.license_type == lic_type, license_models)[0] lic = license_model.objects.filter( user=request.user).first() data['license']['enabled'] = lic is not None else: public_only = request.GET.get('publicOnly') if public_only == 'true': data = agave.apps.list(publicOnly='true') else: data = agave.apps.list() elif service == 'monitors': target = request.GET.get('target') ds_admin_client = Agave(api_server=getattr(settings, 'AGAVE_TENANT_BASEURL'), token=getattr(settings, 'AGAVE_SUPER_TOKEN')) data = ds_admin_client.monitors.list(target=target) elif service == 'meta': app_id = request.GET.get('app_id') if request.method == 'GET': if app_id: data = agave.meta.get(appId=app_id) lic_type = _app_license_type(app_id) data['license'] = {'type': lic_type} if lic_type is not None: _, license_models = get_license_info() license_model = filter( lambda x: x.license_type == lic_type, license_models)[0] lic = license_model.objects.filter( user=request.user).first() data['license']['enabled'] = lic is not None else: query = request.GET.get('q') data = agave.meta.listMetadata(q=query) elif request.method == 'POST': meta_post = json.loads(request.body) meta_uuid = meta_post.get('uuid') if meta_uuid: del meta_post['uuid'] data = agave.meta.updateMetadata(uuid=meta_uuid, body=meta_post) index_or_update_project.apply_async(args=[meta_uuid], queue='api') else: data = agave.meta.addMetadata(body=meta_post) elif request.method == 'DELETE': meta_uuid = request.GET.get('uuid') if meta_uuid: data = agave.meta.deleteMetadata(uuid=meta_uuid) # TODO: Need auth on this DELETE business elif service == 'jobs': if request.method == 'DELETE': job_id = request.GET.get('job_id') data = agave.jobs.delete(jobId=job_id) elif request.method == 'POST': job_post = json.loads(request.body) job_id = job_post.get('job_id') # cancel job / stop job if job_id: data = agave.jobs.manage(jobId=job_id, body='{"action":"stop"}') # submit job elif job_post: # cleaning archive path value if 'archivePath' in job_post: parsed = urlparse(job_post['archivePath']) if parsed.path.startswith('/'): # strip leading '/' archive_path = parsed.path[1:] else: archive_path = parsed.path if not archive_path.startswith(request.user.username): archive_path = '{}/{}'.format( request.user.username, archive_path) job_post['archivePath'] = archive_path if parsed.netloc: job_post['archiveSystem'] = parsed.netloc else: job_post['archivePath'] = \ '{}/archive/jobs/{}/${{JOB_NAME}}-${{JOB_ID}}'.format( request.user.username, datetime.now().strftime('%Y-%m-%d')) # check for running licensed apps lic_type = _app_license_type(job_post['appId']) if lic_type is not None: _, license_models = get_license_info() license_model = filter( lambda x: x.license_type == lic_type, license_models)[0] lic = license_model.objects.filter( user=request.user).first() job_post['parameters'][ '_license'] = lic.license_as_str() # url encode inputs if job_post['inputs']: for key, value in six.iteritems(job_post['inputs']): if type(value) == list: inputs = [] for val in value: parsed = urlparse(val) if parsed.scheme: inputs.append('{}://{}{}'.format( parsed.scheme, parsed.netloc, urllib.quote(parsed.path))) else: inputs.append(urllib.quote( parsed.path)) job_post['inputs'][key] = inputs else: parsed = urlparse(value) if parsed.scheme: job_post['inputs'][ key] = '{}://{}{}'.format( parsed.scheme, parsed.netloc, urllib.quote(parsed.path)) else: job_post['inputs'][key] = urllib.quote( parsed.path) try: data = submit_job(request, request.user.username, job_post) except JobSubmitError as e: data = e.json() logger.error('Failed to submit job {0}'.format(data)) return HttpResponse(json.dumps(data), content_type='application/json', status=e.status_code) # list jobs (via POST?) else: limit = request.GET.get('limit', 10) offset = request.GET.get('offset', 0) data = agave.jobs.list(limit=limit, offset=offset) elif request.method == 'GET': job_id = request.GET.get('job_id') # get specific job info if job_id: data = agave.jobs.get(jobId=job_id) q = {"associationIds": job_id} job_meta = agave.meta.listMetadata(q=json.dumps(q)) data['_embedded'] = {"metadata": job_meta} archive_system_path = '{}/{}'.format( data['archiveSystem'], data['archivePath']) data['archiveUrl'] = reverse('designsafe_data:data_depot') data['archiveUrl'] += 'agave/{}/'.format( archive_system_path) # list jobs else: limit = request.GET.get('limit', 10) offset = request.GET.get('offset', 0) data = agave.jobs.list(limit=limit, offset=offset) else: return HttpResponse('Unexpected service: %s' % service, status=400) elif service == 'ipynb': put = json.loads(request.body) dir_path = put.get('file_path') system = put.get('system') data = WorkspaceUtils.setup_identity_file(request.user.username, agave, system, dir_path) else: return HttpResponse('Unexpected service: %s' % service, status=400) except HTTPError as e: logger.error( 'Failed to execute {0} API call due to HTTPError={1}'.format( service, e.message)) return HttpResponse(json.dumps(e.message), content_type='application/json', status=400) except AgaveException as e: logger.error( 'Failed to execute {0} API call due to AgaveException={1}'.format( service, e.message)) return HttpResponse(json.dumps(e.message), content_type='application/json', status=400) except Exception as e: logger.error( 'Failed to execute {0} API call due to Exception={1}'.format( service, e)) return HttpResponse(json.dumps({ 'status': 'error', 'message': '{}'.format(e.message) }), content_type='application/json', status=400) return HttpResponse(json.dumps(data, cls=DjangoJSONEncoder), content_type='application/json')