def get(self, request, provider_id=None, identity_id=None, action=None): """ """ if not action: errorObj = failureJSON([{ 'code': 400, 'message': 'Action is not supported.'}]) return Response(errorObj, status=status.HTTP_400_BAD_REQUEST) esh_driver = prepare_driver(request, identity_id) esh_meta = esh_driver.meta() try: if 'test_links' in action: test_links = esh_meta.test_links() return Response(test_links, status=status.HTTP_200_OK) except InvalidCredsError: logger.warn('Authentication Failed. Provider-id:%s Identity-id:%s' % (provider_id, identity_id)) errorObj = failureJSON([{ 'code': 401, 'message': 'Identity/Provider Authentication Failed'}]) return Response(errorObj, status=status.HTTP_401_UNAUTHORIZED) except NotImplemented, ne: logger.exception(ne) errorObj = failureJSON([{ 'code': 404, 'message': 'The requested resource %s is not available on this provider' % action}]) return Response(errorObj, status=status.HTTP_404_NOT_FOUND)
def get(self, request, provider_id, identity_id): """ """ data = request.DATA user = get_first(User.objects.filter(username=request.user)) if not user: errorObj = failureJSON([{ 'code': 401, 'message': 'User not found'}]) return Response(errorObj, status=status.HTTP_401_UNAUTHORIZED) query = request.QUERY_PARAMS.get('query') if not query: errorObj = failureJSON([{ 'code': 400, 'message': 'Query not provided'}]) return Response(errorObj, status=status.HTTP_400_BAD_REQUEST) identity = get_first(Identity.objects.filter(id=identity_id)) if not identity: errorObj = failureJSON([{ 'code': 400, 'message': 'Identity not provided'}]) return Response(errorObj, status=status.HTTP_400_BAD_REQUEST) search_result = search([CoreSearchProvider], identity, query) page = request.QUERY_PARAMS.get('page') if page: paginator = Paginator(search_result, 20) try: search_page = paginator.page(page) except PageNotAnInteger: # If page is not an integer, deliver first page. search_page = paginator.page(1) except EmptyPage: # Page is out of range. # deliver last page of results. search_page = paginator.page(paginator.num_pages) serialized_data = \ PaginatedProviderMachineSerializer( search_page).data else: serialized_data = ProviderMachineSerializer( search_result).data response = Response(serialized_data) response['Cache-Control'] = 'no-cache' return response
def put(self, request, provider_id, identity_id, machine_id): """ TODO: Determine who is allowed to edit machines besides coreMachine.owner """ user = request.user data = request.DATA esh_driver = prepare_driver(request, identity_id) esh_machine = esh_driver.get_machine(machine_id) coreMachine = convert_esh_machine(esh_driver, esh_machine, provider_id) if not user.is_staff and user is not coreMachine.application.created_by: logger.warn('Non-staff/non-owner trying to update a machine') errorObj = failureJSON([{ 'code': 401, 'message': 'Only Staff and the machine Owner ' + 'are allowed to change machine info.'}]) return Response(errorObj, status=status.HTTP_401_UNAUTHORIZED) coreMachine.application.update(data) serializer = ProviderMachineSerializer(coreMachine, data=data, partial=True) if serializer.is_valid(): logger.info('metadata = %s' % data) update_machine_metadata(esh_driver, esh_machine, data) serializer.save() logger.info(serializer.data) return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def _email_instance_owner(self, request, params): """ OLD API """ instance_token = params.get("token") username = params.get("userid") vm_info = params.get("vminfo") instance_name = params.get("name") instance = CoreInstance.objects.filter(provider_alias=vm_info["instance-id"]) if not instance: error_list = [{"code": 404, "message": "The token %s did not match a core instance" % instance_token}] instance = CoreInstance.objects.filter(ip_address=request.META["REMOTE_ADDR"]) if not instance: error_list.append( { "code": 404, "message": "The IP Address %s did not match a core instance" % request.META["REMOTE_ADDR"], } ) errorObj = failureJSON(error_list) return Response(errorObj, status=status.HTTP_404_NOT_FOUND) instance = instance[0] ip_address = vm_info.get("public-ipv4", request.META.get("REMOTE_ADDR")) if ip_address: instance.ip_address = ip_address instance.save() launch_time = instance.start_date linuxusername = vm_info.get("linuxusername", instance.created_by) instance_id = vm_info.get("instance-id", instance.provider_alias) # Only send email if the provider isn't OpenStack. if instance.created_by_identity.provider.type.name != "OpenStack": send_instance_email(username, instance_id, instance_name, ip_address, launch_time, linuxusername)
def get(self, request, provider_id): try: provider = Provider.objects.get(id=provider_id) except Provider.DoesNotExist: errorObj = failureJSON([{ 'code': 404, 'message': 'The provider does not exist.'}]) return Response(errorObj, status=status.HTTP_404_NOT_FOUND) admin_driver = get_admin_driver(provider) if hasattr(admin_driver._connection, "ex_hypervisor_statistics"): return Response(admin_driver._connection.ex_hypervisor_statistics()) else: errorObj = failureJSON([{ 'code': 404, 'message': 'The provider does not exist.'}]) return Response(errorObj, status=status.HTTP_404_NOT_FOUND)
def post(self, request, provider_id, identity_id): """ Creates a new volume and adds it to the DB """ user = request.user esh_driver = prepare_driver(request, identity_id) data = request.DATA if not data.get('name') or not data.get('size'): errorObj = failureJSON([{ 'code': 400, 'message': 'Missing params: name and size required to create a volume'}]) return Response(errorObj, status=status.HTTP_400_BAD_REQUEST) name = data.get('name') size = data.get('size') quota = get_quota(identity_id) CoreQuota.objects.get(identitymembership__identity__id=identity_id) if not has_storage_quota(esh_driver, quota, size) \ or not has_storage_count_quota(esh_driver, quota, 1): errorObj = failureJSON([{ 'code': 403, 'message': 'Over quota: ' + 'You have used all of your allocated volume quota'}]) return Response(errorObj, status=status.HTTP_403_FORBIDDEN) logger.debug((name, size)) success, esh_volume = esh_driver.create_volume( name=name, size=size, description=data.get('description', '')) if not success: errorObj = failureJSON({'code': 500, 'message': 'Volume creation failed'}) return Response(errorObj, status=status.HTTP_500_INTERNAL_SERVER_ERROR) core_volume = convert_esh_volume(esh_volume, provider_id, identity_id, user) serialized_data = VolumeSerializer(core_volume).data response = Response(serialized_data, status=status.HTTP_201_CREATED) return response
def get(self, request, provider_id, identity_id, volume_id): """ """ user = request.user esh_driver = prepare_driver(request, identity_id) esh_volume = esh_driver.get_volume(volume_id) if not esh_volume: errorObj = failureJSON([{'code': 404, 'message': 'Volume does not exist'}]) return Response(errorObj, status=status.HTTP_404_NOT_FOUND) core_volume = convert_esh_volume(esh_volume, provider_id, identity_id, user) serialized_data = VolumeSerializer(core_volume).data response = Response(serialized_data) return response
def get(self, request, provider_id, identity_id): data = request.DATA user = User.objects.filter(username=request.user) if user and len(user) > 0: user = user[0] else: errorObj = failureJSON([{ 'code': 401, 'message': 'User not found'}]) return Response(errorObj, status=status.HTTP_401_UNAUTHORIZED) esh_driver = prepare_driver(request, identity_id) # Historic Machines all_machines_list = all_filtered_machines() if all_machines_list: history_machine_list =\ [m for m in all_machines_list if m.application.created_by.username == user.username] logger.warn(len(history_machine_list)) else: history_machine_list = [] page = request.QUERY_PARAMS.get('page') if page: paginator = Paginator(history_machine_list, 5) try: history_machine_page = paginator.page(page) except PageNotAnInteger: # If page is not an integer, deliver first page. history_machine_page = paginator.page(1) except EmptyPage: # Page is out of range. # deliver last page of results. history_machine_page = paginator.page(paginator.num_pages) serialized_data = \ PaginatedProviderMachineSerializer( history_machine_page).data else: serialized_data = ProviderMachineSerializer( history_machine_list).data response = Response(serialized_data) response['Cache-Control'] = 'no-cache' return response
def get(self, request, provider_id): """ return provider if accessible by request user """ username = request.user.username group = Group.objects.get(name=username) try: provider = group.providers.get(id=provider_id, active=True, end_date=None) except CoreProvider.DoesNotExist: errorObj = failureJSON([{ 'code': 404, 'message': 'The provider does not exist.'}]) return Response(errorObj, status=status.HTTP_404_NOT_FOUND) serialized_data = ProviderSerializer(provider).data return Response(serialized_data)
def get(self, request): """ List all providers accessible by request user """ username = request.user.username group = Group.objects.get(name=username) try: providers = group.providers.filter(active=True, end_date=None).order_by('id') except CoreProvider.DoesNotExist: errorObj = failureJSON([{ 'code': 404, 'message': 'The provider does not exist.'}]) return Response(errorObj, status=status.HTTP_404_NOT_FOUND) serialized_data = ProviderSerializer(providers, many=True).data return Response(serialized_data)
def put(self, request, provider_id, identity_id, volume_id): """ Updates DB values for volume """ user = request.user data = request.DATA #Ensure volume exists esh_driver = prepare_driver(request, identity_id) esh_volume = esh_driver.get_volume(volume_id) if not esh_volume: errorObj = failureJSON([{'code': 404, 'message': 'Volume does not exist'}]) return Response(errorObj, status=status.HTTP_404_NOT_FOUND) core_volume = convert_esh_volume(esh_volume, provider_id, identity_id, user) serializer = VolumeSerializer(core_volume, data=data) if serializer.is_valid(): serializer.save() response = Response(serializer.data) return response else: return Response(serializer.errors, status=400)
def delete(self, request, provider_id, identity_id, volume_id): """ Destroys the volume and updates the DB """ user = request.user #Ensure volume exists esh_driver = prepare_driver(request, identity_id) esh_volume = esh_driver.get_volume(volume_id) if not esh_volume: errorObj = failureJSON([{'code': 404, 'message': 'Volume does not exist'}]) return Response(errorObj, status=status.HTTP_404_NOT_FOUND) core_volume = convert_esh_volume(esh_volume, provider_id, identity_id, user) #Delete the object, update the DB esh_driver.destroy_volume(esh_volume) core_volume.end_date = datetime.now() core_volume.save() #Return the object serialized_data = VolumeSerializer(core_volume).data response = Response(serialized_data) return response
def get(self, request, provider_id): """ Returns occupancy data for the specific provider. """ #Get meta for provider to call occupancy try: provider = Provider.objects.get(id=provider_id) except Provider.DoesNotExist: errorObj = failureJSON([{ 'code': 404, 'message': 'The provider does not exist.'}]) return Response(errorObj, status=status.HTTP_404_NOT_FOUND) admin_driver = get_admin_driver(provider) meta_driver = admin_driver.meta(admin_driver=admin_driver) esh_size_list = meta_driver.occupancy() core_size_list = [convert_esh_size(size, provider_id) for size in esh_size_list] serialized_data = ProviderSizeSerializer(core_size_list, many=True).data return Response(serialized_data)
def instance_not_found(instance_id): errorObj = failureJSON([{ 'code': 404, 'message': 'Instance %s does not exist' % instance_id}]) return Response(errorObj, status=status.HTTP_404_NOT_FOUND)
response = Response(api_response, status=status.HTTP_200_OK) return response ### Exception handling below.. except OverQuotaError, oqe: return over_quota(oqe) except OverAllocationError, oae: return over_quota(oae) except SizeNotAvailable, snae: return size_not_availabe(snae) except InvalidCredsError: return invalid_creds(provider_id, identity_id) except NotImplemented, ne: logger.exception(ne) errorObj = failureJSON([{ 'code': 404, 'message': 'The requested action %s is not available on this provider' % action_params['action']}]) return Response(errorObj, status=status.HTTP_404_NOT_FOUND) class Instance(APIView): """ An instance is a self-contained copy of a machine built to a specific size and hosted on a specific provider """ #renderer_classes = (JSONRenderer, JSONPRenderer) @api_auth_token_required def get(self, request, provider_id, identity_id, instance_id): """
def get(self, request, provider_id=None, identity_id=None): data = request.DATA params = request.QUERY_PARAMS.copy() user = User.objects.filter(username=request.user) if user and len(user) > 0: user = user[0] else: errorObj = failureJSON([{ 'code': 401, 'message': 'User not found'}]) return Response(errorObj, status=status.HTTP_401_UNAUTHORIZED) page = params.pop('page',None) emulate_name = params.pop('username',None) try: #Support for staff users to emulate a specific user history if user.is_staff and emulate_name: emualate_name = emulate_name[0] # Querystring conversion user = User.objects.get(username=emulate_name) # List of all instances created by user history_instance_list = CoreInstance.objects.filter( created_by=user).order_by("-start_date") #Filter the list based on query strings for filter_key, value in params.items(): if 'start_date' == filter_key: history_instance_list = history_instance_list.filter( start_date__gt=value) elif 'end_date' == filter_key: history_instance_list = history_instance_list.filter( Q(end_date=None) | Q(end_date__lt=value)) elif 'ip_address' == filter_key: history_instance_list = history_instance_list.filter( ip_address__contains=value) elif 'alias' == filter_key: history_instance_list = history_instance_list.filter( provider_alias__contains=value) except Exception as e: errorObj = failureJSON([{ 'code': 400, 'message': 'Bad query string caused filter validation errors : %s' % (e,)}]) return Response(errorObj, status=status.HTTP_401_UNAUTHORIZED) if page: paginator = Paginator(history_instance_list, 5) try: history_instance_page = paginator.page(page) except PageNotAnInteger: # If page is not an integer, deliver first page. history_instance_page = paginator.page(1) except EmptyPage: # Page is out of range. # deliver last page of results. history_instance_page = paginator.page(paginator.num_pages) serialized_data = \ PaginatedInstanceHistorySerializer( history_instance_page).data else: serialized_data = InstanceHistorySerializer(history_instance_list, many=True).data response = Response(serialized_data) response['Cache-Control'] = 'no-cache' return response
def post(self, request, provider_id, identity_id, instance_id): """ """ #Service-specific call to action action_params = request.DATA if not action_params.get('action', None): errorObj = failureJSON([{ 'code': 400, 'message': 'POST request to /action require a BODY with \'action\':'}]) return Response(errorObj, status=status.HTTP_400_BAD_REQUEST) result_obj = None user = request.user esh_driver = prepare_driver(request, identity_id) instance_list_method = esh_driver.list_instances if AccountProvider.objects.filter(identity__id=identity_id): # Instance list method changes when using the OPENSTACK provider instance_list_method = esh_driver.list_all_instances try: esh_instance_list = instance_list_method() except InvalidCredsError: return invalid_creds(provider_id, identity_id) esh_instance = esh_driver.get_instance(instance_id) if not esh_instance: errorObj = failureJSON([{ 'code': 400, 'message': 'Instance %s no longer exists' % (instance_id,)}]) return Response(errorObj, status=status.HTTP_400_BAD_REQUEST) action = action_params['action'] try: if 'volume' in action: volume_id = action_params.get('volume_id') if 'attach_volume' == action: mount_location = action_params.get('mount_location',None) if mount_location == 'null' or mount_location == 'None': mount_location = None device = action_params.get('device', None) if device == 'null' or device == 'None': device = None task.attach_volume_task(esh_driver, esh_instance.alias, volume_id, device, mount_location) elif 'detach_volume' == action: (result, error_msg) = task.detach_volume_task( esh_driver, esh_instance.alias, volume_id) if not result and error_msg: #Return reason for failed detachment errorObj = failureJSON([{'code': 400, 'message': error_msg}]) return Response(errorObj, status=status.HTTP_400_BAD_REQUEST) #Task complete, convert the volume and return the object esh_volume = esh_driver.get_volume(volume_id) core_volume = convert_esh_volume(esh_volume, provider_id, identity_id, user) result_obj = VolumeSerializer(core_volume).data elif 'resize' == action: size_alias = action_params.get('size', '') if type(size_alias) == int: size_alias = str(size_alias) size = esh_driver.get_size(size_alias) esh_driver.resize_instance(esh_instance, size) elif 'confirm_resize' == action: esh_driver.confirm_resize_instance(esh_instance) elif 'revert_resize' == action: esh_driver.revert_resize_instance(esh_instance) elif 'resume' == action: resume_instance(esh_driver, esh_instance, provider_id, identity_id, user) elif 'suspend' == action: suspend_instance(esh_driver, esh_instance, provider_id, identity_id, user) elif 'start' == action: start_instance(esh_driver, esh_instance, provider_id, identity_id, user) elif 'stop' == action: stop_instance(esh_driver, esh_instance, provider_id, identity_id, user) elif 'reset_network' == action: esh_driver.reset_network(esh_instance) elif 'reboot' == action: esh_driver.reboot_instance(esh_instance) elif 'rebuild' == action: machine_alias = action_params.get('machine_alias', '') machine = esh_driver.get_machine(machine_alias) esh_driver.rebuild_instance(esh_instance, machine) else: errorObj = failureJSON([{ 'code': 400, 'message': 'Unable to to perform action %s.' % (action)}]) return Response( errorObj, status=status.HTTP_400_BAD_REQUEST) #ASSERT: The action was executed successfully api_response = { 'result': 'success', 'message': 'The requested action <%s> was run successfully' % action_params['action'], 'object': result_obj, } response = Response(api_response, status=status.HTTP_200_OK) return response ### Exception handling below.. except OverQuotaError, oqe: return over_quota(oqe)
def over_allocation(allocation_exception): errorObj = failureJSON([{ 'code': 413, 'message': allocation_exception.message}]) return Response(errorObj, status=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE)
def size_not_availabe(sna_exception): errorObj = failureJSON([{ 'code': 413, 'message': sna_exception.message}]) return Response(errorObj, status=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE)
def invalid_creds(provider_id, identity_id): logger.warn('Authentication Failed. Provider-id:%s Identity-id:%s' % (provider_id, identity_id)) errorObj = failureJSON([{'code': 401, 'message': 'Identity/Provider Authentication Failed'}]) return Response(errorObj, status=status.HTTP_400_BAD_REQUEST)
def keys_not_found(missing_keys): errorObj = failureJSON([{ 'code': 400, 'message': 'Missing required POST datavariables : %s' % missing_keys}]) return Response(errorObj, status=status.HTTP_400_BAD_REQUEST)