def create(self, request): user = request.user data = request.data try: self.validate_input(user, data) except Exception as exc: return failure_response(status.HTTP_400_BAD_REQUEST, exc.message) # Create a mutable dict and start modifying. data = data.copy() name = data.get('name') identity_uuid = data.get('identity') source_alias = data.get('source_alias') size_alias = data.get('size_alias') allocation_source_id = data.get('allocation_source_id') boot_scripts = data.pop("scripts", []) deploy = data.get('deploy') extra = data.get('extra') try: identity = Identity.objects.get(uuid=identity_uuid) allocation_source = AllocationSource.objects.get( source_id=allocation_source_id) core_instance = launch_instance(user, identity_uuid, size_alias, source_alias, name, deploy, **extra) # Faking a 'partial update of nothing' to allow call to 'is_valid' serialized_instance = InstanceSerializer( core_instance, context={'request': self.request}, data={}, partial=True) if not serialized_instance.is_valid(): return Response(serialized_instance.errors, status=status.HTTP_400_BAD_REQUEST) instance = serialized_instance.save() if boot_scripts: _save_scripts_to_instance(instance, boot_scripts) instance.change_allocation_source(allocation_source) return Response(serialized_instance.data, status=status.HTTP_201_CREATED) except UnderThresholdError as ute: return under_threshold(ute) except (OverQuotaError, OverAllocationError) as oqe: return over_quota(oqe) except ProviderNotActive as pna: return inactive_provider(pna) except SizeNotAvailable as snae: return size_not_available(snae) except HypervisorCapacityError as hce: return over_capacity(hce) except SecurityGroupNotCreated: return connection_failure(identity) except (socket_error, ConnectionFailure): return connection_failure(identity) except LibcloudInvalidCredsError: return invalid_creds(identity) except Exception as exc: logger.exception("Encountered a generic exception. " "Returning 409-CONFLICT") return failure_response(status.HTTP_409_CONFLICT, str(exc.message))
def get(self, request, provider_uuid, identity_uuid): """ Using provider and identity, getlist of machines TODO: Cache this request """ try: request_user = request.user logger.debug("filtered_machine_list") filtered_machine_list = provider_filtered_machines( request, provider_uuid, identity_uuid, request_user ) except ProviderNotActive as pna: return inactive_provider(pna) except LibcloudInvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) except LibcloudBadResponseError: return malformed_response(provider_uuid, identity_uuid) except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except ObjectDoesNotExist: return invalid_provider_identity(provider_uuid, identity_uuid) except Exception as e: logger.exception("Unexpected exception for user:%s" % request_user) return failure_response(status.HTTP_409_CONFLICT, e.message) serialized_data = ProviderMachineSerializer( filtered_machine_list, request_user=request.user, many=True ).data response = Response(serialized_data) return response
def perform_create(self, serializer): data = serializer.validated_data name = data.get('name') size = data.get('size') image_id = data.get('image') snapshot_id = data.get('snapshot') instance_source = data.get("instance_source") identity = instance_source.get("created_by_identity") provider = instance_source.get('provider') try: esh_volume = create_volume_or_fail(name, size, self.request.user, provider, identity, image_id=image_id, snapshot_id=snapshot_id) created_on = esh_volume.extra.get("createTime", timezone.now()) serializer.save(identifier=esh_volume.id, name=esh_volume.name, created_on=pytz.utc.localize(created_on), user=self.request.user) except InvalidCredsError as e: raise exceptions.PermissionDenied(detail=e.message) except ProviderNotActive as pna: return inactive_provider(pna) except VOLUME_EXCEPTIONS as e: raise exceptions.ParseError(detail=e.message)
def get(self, request, provider_uuid, identity_uuid, action=None): """ """ if not action: return failure_response(status.HTTP_400_BAD_REQUEST, 'Action is not supported.') try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response(status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) 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_uuid, identity_uuid)) return failure_response(status.HTTP_401_UNAUTHORIZED, 'Identity/Provider Authentication Failed') except NotImplemented as ne: logger.exception(ne) return failure_response( status.HTTP_404_NOT_FOUND, 'The requested resource %s is not available on this provider' % action)
def get(self, request, provider_uuid, identity_uuid, volume_id): """ """ user = request.user try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response(status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) try: esh_volume = esh_driver.get_volume(volume_id) except ConnectionFailure: return connection_failure(provider_uuid, identity_uuid) except LibcloudInvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) except Exception as exc: logger.exception("Encountered a generic exception. " "Returning 409-CONFLICT") return failure_response(status.HTTP_409_CONFLICT, str(exc.message)) if not esh_volume: try: source = InstanceSource.objects.get(identifier=volume_id, provider__uuid=provider_uuid) source.end_date = datetime.now() source.save() except (InstanceSource.DoesNotExist, CoreVolume.DoesNotExist): pass return volume_not_found(volume_id) core_volume = convert_esh_volume(esh_volume, provider_uuid, identity_uuid, user) serialized_data = VolumeSerializer(core_volume, context={"request": request}).data response = Response(serialized_data) return response
def get(self, request, provider_uuid, identity_uuid, machine_id): """ Details view for specific machine (Lookup using the given provider/identity) """ user = request.user try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response( status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) # TODO: Need to determine that identity_uuid is ALLOWED to # see machine_id. if not covered by calling as the users driver.. esh_machine = esh_driver.get_machine(machine_id) core_machine = convert_esh_machine(esh_driver, esh_machine, provider_uuid, user) serialized_data = ProviderMachineSerializer( core_machine, request_user=request.user).data response = Response(serialized_data) return response
def get(self, request, provider_uuid, identity_uuid, machine_id): user = request.user try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response( status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) # TODO: Need to determine that identity_uuid is ALLOWED to # see machine_id. # if not covered by calling as the users driver.. esh_machine = esh_driver.get_machine(machine_id) core_machine = convert_esh_machine(esh_driver, esh_machine, provider_uuid, user) if not core_machine: return failure_response( status.HTTP_400_BAD_REQUEST, "Could not retrieve machine with ID = %s" % machine_id) if not core_machine.application_version.application.icon: return None app_icon = core_machine.application_version.application.icon image_name, image_ext = os.path.splitext(app_icon.name) return Response(app_icon.file)
def perform_create(self, serializer): data = serializer.validated_data name = data.get('name') size = data.get('size') image_id = data.get('image_id') snapshot_id = data.get('snapshot_id') description = data.get('description') instance_source = data.get("instance_source") identity = instance_source.get("created_by_identity") provider = identity.provider try: esh_volume = create_volume_or_fail(name, size, self.request.user, provider, identity, description=description, image_id=image_id, snapshot_id=snapshot_id) created_on = esh_volume.extra.get("createTime", timezone.now()) serializer.save(identifier=esh_volume.id, name=esh_volume.name, created_on=pytz.utc.localize(created_on), user=self.request.user) except InvalidCredsError as e: raise exceptions.PermissionDenied(detail=e.message) except ProviderNotActive as pna: return inactive_provider(pna) except VOLUME_EXCEPTIONS as e: raise exceptions.ParseError(detail=e.message) except Exception as exc: logger.exception("Error occurred creating a v2 volume -- User:%s" % self.request.user) return Response(exc.message, status=status.HTTP_409_CONFLICT)
def post_instance_action(self, request, pk=None): user = request.user instance_id = pk instance = find_instance(instance_id) identity = instance.created_by_identity action_params = dict(request.data) action = action_params.pop('action') if type(action) == list: action = action[0] try: result_obj = run_instance_action(user, identity, instance_id, action, action_params) api_response = { 'result': 'success', 'message': 'The requested action <%s> was run successfully' % (action,), 'object': result_obj, } response = Response(api_response, status=status.HTTP_200_OK) return response except (socket_error, ConnectionFailure): return connection_failure(identity) except InstanceDoesNotExist as dne: return failure_response( status.HTTP_404_NOT_FOUND, 'Instance %s no longer exists' % (dne.message,)) except LibcloudInvalidCredsError: return invalid_creds(identity) except HypervisorCapacityError as hce: return over_capacity(hce) except ProviderNotActive as pna: return inactive_provider(pna) except (OverQuotaError, OverAllocationError) as oqe: return over_quota(oqe) except SizeNotAvailable as snae: return size_not_available(snae) except (socket_error, ConnectionFailure): return connection_failure(identity) except VolumeMountConflict as vmc: return mount_failed(vmc) except NotImplemented: return failure_response( status.HTTP_409_CONFLICT, "The requested action %s is not available on this provider." % action) except ActionNotAllowed: return failure_response( status.HTTP_409_CONFLICT, "The requested action %s has been explicitly " "disabled on this provider." % action) except Exception as exc: logger.exception("Exception occurred processing InstanceAction") message = exc.message if message.startswith('409 Conflict'): return failure_response( status.HTTP_409_CONFLICT, message) return failure_response( status.HTTP_403_FORBIDDEN, "The requested action %s encountered " "an irrecoverable exception: %s" % (action, message))
def get(self, request, provider_uuid, identity_uuid): """ """ try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response( status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) try: esh_snapshots = esh_driver._connection.ex_list_snapshots() except LibcloudBadResponseError: return malformed_response(provider_uuid, identity_uuid) except LibcloudInvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) snapshot_data = [] for ss in esh_snapshots: snapshot_data.append({ 'id': ss.id, 'name': ss.extra['name'], 'size': ss.size, 'description': ss.extra['description'], 'created': ss.extra['created'], 'status': ss.extra['status'], 'volume_id': ss.extra['volume_id'], }) response = Response(snapshot_data) return response
def get(self, request, provider_uuid, identity_uuid, machine_id): user = request.user try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response(status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) # TODO: Need to determine that identity_uuid is ALLOWED to # see machine_id. # if not covered by calling as the users driver.. esh_machine = esh_driver.get_machine(machine_id) core_machine = convert_esh_machine( esh_driver, esh_machine, provider_uuid, user ) if not core_machine: return failure_response( status.HTTP_400_BAD_REQUEST, "Could not retrieve machine with ID = %s" % machine_id ) if not core_machine.application_version.application.icon: return None app_icon = core_machine.application_version.application.icon return Response(app_icon.file)
def get(self, request, provider_uuid, identity_uuid, action=None): """ """ if not action: return failure_response( status.HTTP_400_BAD_REQUEST, 'Action is not supported.' ) try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response( status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) 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 LibcloudInvalidCredsError: logger.warn('Authentication Failed. Provider-id:%s Identity-id:%s' % (provider_uuid, identity_uuid)) return failure_response( status.HTTP_401_UNAUTHORIZED, 'Identity/Provider Authentication Failed') except NotImplemented as ne: logger.exception(ne) return failure_response( status.HTTP_404_NOT_FOUND, 'The requested resource %s is not available on this provider' % action)
def get(self, request, provider_uuid, identity_uuid): """ Using provider and identity, getlist of machines TODO: Cache this request """ # TODO: Decide how we should pass this in (I.E. GET query string?) active = False user = request.user try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response( status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) try: esh_size_list = esh_driver.list_sizes() except LibcloudBadResponseError: return malformed_response(provider_uuid, identity_uuid) except LibcloudInvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) all_size_list = [convert_esh_size(size, provider_uuid) for size in esh_size_list] if active: all_size_list = [s for s in all_size_list if s.active()] serialized_data = ProviderSizeSerializer(all_size_list, many=True).data response = Response(serialized_data) return response
def get(self, request, provider_uuid, identity_uuid, size_alias): """ Lookup the size information (Lookup using the given provider/identity) Update on server DB (If applicable) """ user = request.user try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response( status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) esh_size = esh_driver.get_size(size_alias) if not esh_size: return failure_response( status.HTTP_404_NOT_FOUND, 'Size %s not found' % (size_alias,)) core_size = convert_esh_size(esh_size, provider_uuid) serialized_data = ProviderSizeSerializer(core_size).data response = Response(serialized_data) return response
def get(self, request, provider_uuid, identity_uuid, instance_id): """ Authentication Required, get instance details. """ user = request.user # NOTE: This 'Scheme' should be used across # the ENTIRE API v1 (Machines, Volumes, Sizes) # NOTE: Especially the part below, where you end date # all the things that are 'inactive' try: provider = Provider.objects.get(uuid=provider_uuid) if not provider.is_current(): raise ProviderNotActive(provider) except Provider.DoesNotExist: return invalid_creds(provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) # Cleared provider testing -- ready for driver prep. try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) logger.info("InstanceQuery Looking for %s" % instance_id) esh_instance = esh_driver.get_instance(instance_id) logger.info("InstanceQuery Found instance %s" % esh_instance) except (socket_error, ConnectionFailure): logger.exception("Connection failure prevented InstanceQuery") return connection_failure(provider_uuid, identity_uuid) except LibcloudInvalidCredsError: logger.exception("Invalid credentialsprevented InstanceQuery") return invalid_creds(provider_uuid, identity_uuid) except Exception as exc: logger.exception("Encountered a generic exception. " "Returning 409-CONFLICT") return failure_response(status.HTTP_409_CONFLICT, str(exc.message)) # NOTE: Especially THIS part below, where you end date all the # things that are 'inactive' if not esh_instance: try: core_inst = CoreInstance.objects.get( provider_alias=instance_id, source__provider__uuid=provider_uuid, created_by_identity__uuid=identity_uuid) core_inst.end_date_all() except CoreInstance.DoesNotExist: pass return instance_not_found(instance_id) core_instance = convert_esh_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) serialized_data = InstanceSerializer( core_instance, context={"request": request}).data response = Response(serialized_data) response['Cache-Control'] = 'no-cache' return response
def get(self, request, provider_uuid, identity_uuid, instance_id): """ Authentication Required, get instance details. """ user = request.user # NOTE: This 'Scheme' should be used across # the ENTIRE API v1 (Machines, Volumes, Sizes) # NOTE: Especially the part below, where you end date # all the things that are 'inactive' try: provider = Provider.objects.get(uuid=provider_uuid) if not provider.is_active(): raise ProviderNotActive(provider) except Provider.DoesNotExist: return invalid_creds(provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) # Cleared provider testing -- ready for driver prep. try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) logger.info("InstanceQuery Looking for %s" % instance_id) esh_instance = esh_driver.get_instance(instance_id) logger.info("InstanceQuery Found instance %s" % esh_instance) except (socket_error, ConnectionFailure): logger.exception("Connection failure prevented InstanceQuery") return connection_failure(provider_uuid, identity_uuid) except LibcloudInvalidCredsError: logger.exception("Invalid credentialsprevented InstanceQuery") return invalid_creds(provider_uuid, identity_uuid) except Exception as exc: logger.exception("Encountered a generic exception. " "Returning 409-CONFLICT") return failure_response(status.HTTP_409_CONFLICT, str(exc.message)) # NOTE: Especially THIS part below, where you end date all the # things that are 'inactive' if not esh_instance: try: core_inst = CoreInstance.objects.get( provider_alias=instance_id, source__provider__uuid=provider_uuid, created_by_identity__uuid=identity_uuid) core_inst.end_date_all() except CoreInstance.DoesNotExist: pass return instance_not_found(instance_id) core_instance = convert_esh_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) serialized_data = InstanceSerializer(core_instance, context={ "request": request }).data response = Response(serialized_data) response['Cache-Control'] = 'no-cache' return response
def post_instance_action(self, request, pk=None): user = request.user instance_id = pk instance = find_instance(instance_id) identity = instance.created_by_identity action_params = request.data action = action_params.pop('action') try: result_obj = run_instance_action(user, identity, instance_id, action, action_params) api_response = { 'result': 'success', 'message': 'The requested action <%s> was run successfully' % (action,), 'object': result_obj, } response = Response(api_response, status=status.HTTP_200_OK) return response except (socket_error, ConnectionFailure): return connection_failure(identity) except InstanceDoesNotExist as dne: return failure_response( status.HTTP_404_NOT_FOUND, 'Instance %s no longer exists' % (dne.message,)) except InvalidCredsError: return invalid_creds(identity) except HypervisorCapacityError as hce: return over_capacity(hce) except ProviderNotActive as pna: return inactive_provider(pna) except (OverQuotaError, OverAllocationError) as oqe: return over_quota(oqe) except SizeNotAvailable as snae: return size_not_available(snae) except (socket_error, ConnectionFailure): return connection_failure(identity) except InvalidCredsError: return invalid_creds(identity) except VolumeMountConflict as vmc: return mount_failed(vmc) except NotImplemented: return failure_response( status.HTTP_409_CONFLICT, "The requested action %s is not available on this provider." % action_params['action']) except ActionNotAllowed: return failure_response( status.HTTP_409_CONFLICT, "The requested action %s has been explicitly " "disabled on this provider." % action_params['action']) except Exception as exc: logger.exception("Exception occurred processing InstanceAction") message = exc.message if message.startswith('409 Conflict'): return failure_response( status.HTTP_409_CONFLICT, message) return failure_response( status.HTTP_403_FORBIDDEN, "The requested action %s encountered " "an irrecoverable exception: %s" % (action_params['action'], message))
def get(self, request, provider_uuid, identity_uuid, machine_id): """ Details view for specific machine (Lookup using the given provider/identity) """ user = request.user try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response(status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) # TODO: Need to determine that identity_uuid is ALLOWED to # see machine_id. if not covered by calling as the users driver.. esh_machine = esh_driver.get_machine(machine_id) core_machine = convert_esh_machine( esh_driver, esh_machine, provider_uuid, user ) serialized_data = ProviderMachineSerializer( core_machine, request_user=request.user ).data response = Response(serialized_data) return response
def delete(self, request, provider_uuid, identity_uuid, snapshot_id): """ Destroys the volume and updates the DB """ user = request.user # Ensure volume exists try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response( status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) if not can_use_snapshot(user, snapshot_id, leader_required=True): return member_action_forbidden(user.username, "Snapshot", snapshot_id) snapshot = esh_driver._connection.get_snapshot(snapshot_id) if not snapshot: return snapshot_not_found(snapshot_id) delete_success = esh_driver._connection.ex_delete_snapshot(snapshot) # NOTE: Always false until icehouse... # return failure_response( # status.HTTP_400_BAD_REQUEST, # % snapshot_id) return Response(status=status.HTTP_204_NO_CONTENT)
def delete(self, request, provider_uuid, identity_uuid, volume_id): """ Destroys the volume and updates the DB """ user = request.user # Ensure volume exists try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response(status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) try: esh_volume = esh_driver.get_volume(volume_id) except ConnectionFailure: return connection_failure(provider_uuid, identity_uuid) except LibcloudInvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) except Exception as exc: logger.exception("Encountered a generic exception. " "Returning 409-CONFLICT") return failure_response(status.HTTP_409_CONFLICT, str(exc.message)) if not esh_volume: return volume_not_found(volume_id) core_volume = convert_esh_volume(esh_volume, provider_uuid, identity_uuid, user) # Delete the object, update the DB esh_driver.destroy_volume(esh_volume) core_volume.end_date = now() core_volume.save() # Return the object serialized_data = VolumeSerializer(core_volume, context={"request": request}).data response = Response(serialized_data) return response
def get(self, request, provider_uuid, identity_uuid): """ Using provider and identity, getlist of machines TODO: Cache this request """ try: request_user = request.user logger.debug("filtered_machine_list") filtered_machine_list = provider_filtered_machines(request, provider_uuid, identity_uuid, request_user) except ProviderNotActive as pna: return inactive_provider(pna) except LibcloudInvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) except LibcloudBadResponseError: return malformed_response(provider_uuid, identity_uuid) except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except ObjectDoesNotExist: return invalid_provider_identity(provider_uuid, identity_uuid) except Exception as e: logger.exception("Unexpected exception for user:%s" % request_user) return failure_response(status.HTTP_409_CONFLICT, e.message) serialized_data = ProviderMachineSerializer(filtered_machine_list, request_user=request.user, many=True).data response = Response(serialized_data) return response
def create(self, request): user = request.user data = request.data try: self.validate_input(user, data) except Exception as exc: return failure_response( status.HTTP_400_BAD_REQUEST, exc.message) # Create a mutable dict and start modifying. data = data.copy() name = data.get('name') identity_uuid = data.get('identity') source_alias = data.get('source_alias') size_alias = data.get('size_alias') boot_scripts = data.pop("scripts", []) deploy = data.get('deploy') extra = data.get('extra') try: identity = Identity.objects.get(uuid=identity_uuid) core_instance = launch_instance( user, identity_uuid, size_alias, source_alias, name, deploy, **extra) # Faking a 'partial update of nothing' to allow call to 'is_valid' serialized_instance = InstanceSerializer( core_instance, context={'request': self.request}, data={}, partial=True) if not serialized_instance.is_valid(): return Response(serialized_instance.errors, status=status.HTTP_400_BAD_REQUEST) instance = serialized_instance.save() if boot_scripts: _save_scripts_to_instance(instance, boot_scripts) return Response( serialized_instance.data, status=status.HTTP_201_CREATED) except UnderThresholdError as ute: return under_threshold(ute) except (OverQuotaError, OverAllocationError) as oqe: return over_quota(oqe) except ProviderNotActive as pna: return inactive_provider(pna) except SizeNotAvailable as snae: return size_not_available(snae) except HypervisorCapacityError as hce: return over_capacity(hce) except SecurityGroupNotCreated: return connection_failure(identity) except (socket_error, ConnectionFailure): return connection_failure(identity) except InvalidCredsError: return invalid_creds(identity) except Exception as exc: logger.exception("Encountered a generic exception. " "Returning 409-CONFLICT") return failure_response(status.HTTP_409_CONFLICT, str(exc.message))
def perform_destroy(self, instance): try: destroy_volume_or_fail(instance, self.request.user) instance.end_date = timezone.now() instance.save() except InvalidCredsError as e: raise exceptions.PermissionDenied(detail=e.message) except ProviderNotActive as pna: return inactive_provider(pna) except VOLUME_EXCEPTIONS as e: raise exceptions.ParseError(detail=e.message)
def create(self, request): """ Override 'create' at a higher level than 'perform_create' so that we can swap Serializers behind-the-scenes. """ serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) #NOTE: This work normally happens in 'perform_create()' data = serializer.validated_data name = data.get('name') size = data.get('size') image_id = data.get('image_id') snapshot_id = data.get('snapshot_id') description = data.get('description') project = data.get('projects') identity = data.get("created_by_identity") provider = identity.provider try: core_volume = create_volume_or_fail(name, size, self.request.user, provider, identity, description=description, project=project, image_id=image_id, snapshot_id=snapshot_id) #NOTE: This is normally where 'perform_create()' would end # but we swap out the VolumeSerializer Class at this point. serialized_volume = VolumeSerializer( core_volume, context={'request': self.request}, data={}, partial=True) if not serialized_volume.is_valid(): return Response(serialized_volume.errors, status=status.HTTP_400_BAD_REQUEST) serialized_volume.save() headers = self.get_success_headers(serialized_volume.data) return Response(serialized_volume.data, status=status.HTTP_201_CREATED, headers=headers) except LibcloudInvalidCredsError as e: raise exceptions.PermissionDenied(detail=e.message) except ProviderNotActive as pna: return inactive_provider(pna) except VOLUME_EXCEPTIONS as e: raise exceptions.ParseError(detail=e.message) except Exception as exc: logger.exception("Error occurred creating a v2 volume -- User:%s" % self.request.user) return Response(exc.message, status=status.HTTP_409_CONFLICT)
def _update_machine( self, request, provider_uuid, identity_uuid, machine_id ): # TODO: Determine who is allowed to edit machines besides # core_machine.owner user = request.user data = request.data try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response(status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) esh_machine = esh_driver.get_machine(machine_id) core_machine = convert_esh_machine( esh_driver, esh_machine, provider_uuid, user ) if not user.is_staff and user is not core_machine.application_version.application.created_by: logger.warn( '%s is Non-staff/non-owner trying to update a machine' % (user.username) ) return failure_response( status.HTTP_401_UNAUTHORIZED, "Only Staff and the machine Owner " "are allowed to change machine info." ) partial_update = True if request.method == 'PATCH' else False serializer = ProviderMachineSerializer( core_machine, request_user=request.user, data=data, partial=partial_update ) if serializer.is_valid(): logger.info('metadata = %s' % data) update_machine_metadata(esh_driver, esh_machine, data) machine = serializer.save() if 'created_by_identity' in request.data: identity = machine.created_by_identity update_application_owner( core_machine.application_version.application, identity ) logger.info(serializer.data) return Response(serializer.data) return failure_response(status.HTTP_400_BAD_REQUEST, serializer.errors)
def get(self, request, provider_uuid, identity_uuid): """ Returns all available URLs based on the user profile. """ try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response(status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) data = add_user_urls(request, provider_uuid, identity_uuid) return Response(data)
def perform_destroy(self, instance): try: destroy_volume_or_fail(instance, self.request.user) instance.end_date = timezone.now() instance.save() except InvalidCredsError as e: raise exceptions.PermissionDenied(detail=e.message) except ProviderNotActive as pna: return inactive_provider(pna) except VOLUME_EXCEPTIONS as e: raise exceptions.ParseError(detail=e.message) except Exception as exc: logger.exception("Error occurred deleting a v2 volume -- User:%s" % self.request.user) return Response(exc.message, status=status.HTTP_409_CONFLICT)
def perform_destroy(self, instance): try: destroy_volume_or_fail(instance, self.request.user) instance.end_date = timezone.now() instance.save() except LibcloudInvalidCredsError as e: raise exceptions.PermissionDenied(detail=e.message) except ProviderNotActive as pna: return inactive_provider(pna) except VOLUME_EXCEPTIONS as e: raise exceptions.ParseError(detail=e.message) except Exception as exc: logger.exception("Error occurred deleting a v2 volume -- User:%s" % self.request.user) return Response(exc.message, status=status.HTTP_409_CONFLICT)
def put(self, request, provider_uuid, identity_uuid, volume_id): """ Updates DB values for volume """ user = request.user data = request.data # Ensure volume exists try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response( status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) if not can_use_volume(user, volume_id, leader_required=True): return member_action_forbidden(user.username, "Volume", volume_id) try: esh_volume = esh_driver.get_volume(volume_id) except ConnectionFailure: return connection_failure(provider_uuid, identity_uuid) except LibcloudInvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) except Exception as exc: logger.exception("Encountered a generic exception. " "Returning 409-CONFLICT") return failure_response(status.HTTP_409_CONFLICT, str(exc.message)) if not esh_volume: return volume_not_found(volume_id) core_volume = convert_esh_volume(esh_volume, provider_uuid, identity_uuid, user) serializer = VolumeSerializer(core_volume, data=data, context={'request': request}) if serializer.is_valid(): serializer.save() _update_volume_metadata( esh_driver, esh_volume, data) response = Response(serializer.data) return response else: failure_response( status.HTTP_400_BAD_REQUEST, serializer.errors)
def get(self, request, provider_uuid, identity_uuid, snapshot_id): """ """ try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response(status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) snapshot = esh_driver._connection.get_snapshot(snapshot_id) if not snapshot: return snapshot_not_found(snapshot_id) response = Response(snapshot) return response
def create(self, request): """ Override 'create' at a higher level than 'perform_create' so that we can swap Serializers behind-the-scenes. """ serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) #NOTE: This work normally happens in 'perform_create()' data = serializer.validated_data name = data.get('name') size = data.get('size') image_id = data.get('image_id') snapshot_id = data.get('snapshot_id') description = data.get('description') project = data.get('projects') identity = data.get("created_by_identity") provider = identity.provider try: core_volume = create_volume_or_fail( name, size, self.request.user, provider, identity, description=description, project=project, image_id=image_id, snapshot_id=snapshot_id) #NOTE: This is normally where 'perform_create()' would end # but we swap out the VolumeSerializer Class at this point. serialized_volume = VolumeSerializer( core_volume, context={'request': self.request}, data={}, partial=True) if not serialized_volume.is_valid(): return Response(serialized_volume.errors, status=status.HTTP_400_BAD_REQUEST) serialized_volume.save() headers = self.get_success_headers(serialized_volume.data) return Response( serialized_volume.data, status=status.HTTP_201_CREATED, headers=headers) except InvalidCredsError as e: raise exceptions.PermissionDenied(detail=e.message) except ProviderNotActive as pna: return inactive_provider(pna) except VOLUME_EXCEPTIONS as e: raise exceptions.ParseError(detail=e.message) except Exception as exc: logger.exception("Error occurred creating a v2 volume -- User:%s" % self.request.user) return Response(exc.message, status=status.HTTP_409_CONFLICT)
def get(self, request, provider_uuid, identity_uuid): """ Retrieves list of volumes and updates the DB """ user = request.user try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response(status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) volume_list_method = esh_driver.list_volumes if AccountProvider.objects.filter(identity__uuid=identity_uuid): # Instance list method changes when using the OPENSTACK provider volume_list_method = esh_driver.list_all_volumes try: esh_volume_list = volume_list_method() except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except LibcloudBadResponseError: return malformed_response(provider_uuid, identity_uuid) except LibcloudInvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) except Exception: logger.exception("Uncaught Exception in Volume list method") return failure_response( status.HTTP_500_INTERNAL_SERVER_ERROR, 'Volume list method failed. Contact support' ) core_volume_list = [ convert_esh_volume(volume, provider_uuid, identity_uuid, user) for volume in esh_volume_list ] serializer = VolumeSerializer( core_volume_list, context={'request': request}, many=True ) response = Response(serializer.data) return response
def get(self, request, provider_uuid, identity_uuid, volume_id): """ """ user = request.user try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response( status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) try: esh_volume = esh_driver.get_volume(volume_id) except ConnectionFailure: return connection_failure(provider_uuid, identity_uuid) except LibcloudInvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) except Exception as exc: logger.exception("Encountered a generic exception. " "Returning 409-CONFLICT") return failure_response(status.HTTP_409_CONFLICT, str(exc.message)) if not esh_volume: try: source = InstanceSource.objects.get( identifier=volume_id, provider__uuid=provider_uuid) source.end_date = datetime.now() source.save() except (InstanceSource.DoesNotExist, CoreVolume.DoesNotExist): pass return volume_not_found(volume_id) core_volume = convert_esh_volume(esh_volume, provider_uuid, identity_uuid, user) serialized_data = VolumeSerializer(core_volume, context={'request': request}).data response = Response(serialized_data) return response
def get(self, request, provider_uuid, identity_uuid): """ Retrieves list of volumes and updates the DB """ user = request.user try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response( status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) volume_list_method = esh_driver.list_volumes if AccountProvider.objects.filter(identity__uuid=identity_uuid): # Instance list method changes when using the OPENSTACK provider volume_list_method = esh_driver.list_all_volumes try: esh_volume_list = volume_list_method() except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except LibcloudBadResponseError: return malformed_response(provider_uuid, identity_uuid) except LibcloudInvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) except Exception: logger.exception("Uncaught Exception in Volume list method") return failure_response( status.HTTP_500_INTERNAL_SERVER_ERROR, 'Volume list method failed. Contact support') core_volume_list = [convert_esh_volume(volume, provider_uuid, identity_uuid, user) for volume in esh_volume_list] serializer = VolumeSerializer(core_volume_list, context={'request': request}, many=True) response = Response(serializer.data) return response
def delete(self, request, provider_uuid, identity_uuid, volume_id): """ Destroys the volume and updates the DB """ user = request.user # Ensure volume exists try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response( status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) try: esh_volume = esh_driver.get_volume(volume_id) except ConnectionFailure: return connection_failure(provider_uuid, identity_uuid) except LibcloudInvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) except Exception as exc: logger.exception("Encountered a generic exception. " "Returning 409-CONFLICT") return failure_response(status.HTTP_409_CONFLICT, str(exc.message)) if not esh_volume: return volume_not_found(volume_id) core_volume = convert_esh_volume(esh_volume, provider_uuid, identity_uuid, user) # Delete the object, update the DB esh_driver.destroy_volume(esh_volume) core_volume.end_date = now() core_volume.save() # Return the object serialized_data = VolumeSerializer(core_volume, context={'request': request}).data response = Response(serialized_data) return response
def get(self, request, provider_uuid, identity_uuid): """ Returns a list of all instances """ user = request.user try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response( status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) identity = Identity.objects.get(uuid=identity_uuid) # Probably redundant if not user.can_use_identity(identity.id): return invalid_creds(provider_uuid, identity_uuid) try: esh_instance_list = get_cached_instances(identity=identity) except MalformedResponseError: return malformed_response(provider_uuid, identity_uuid) except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except InvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) core_instance_list = [convert_esh_instance(esh_driver, inst, provider_uuid, identity_uuid, user) for inst in esh_instance_list] # TODO: Core/Auth checks for shared instances serialized_data = InstanceSerializer(core_instance_list, context={"request": request}, many=True).data response = Response(serialized_data) response['Cache-Control'] = 'no-cache' return response
def get(self, request, provider_uuid, identity_uuid): """ Returns a list of all instances """ user = request.user try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response(status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) identity = Identity.objects.get(uuid=identity_uuid) # Probably redundant if not user.can_use_identity(identity.id): return invalid_creds(provider_uuid, identity_uuid) try: esh_instance_list = get_cached_instances(identity=identity) except LibcloudBadResponseError: return malformed_response(provider_uuid, identity_uuid) except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except LibcloudInvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) core_instance_list = [ convert_esh_instance(esh_driver, inst, provider_uuid, identity_uuid, user) for inst in esh_instance_list ] # TODO: Core/Auth checks for shared instances serialized_data = InstanceSerializer(core_instance_list, context={ "request": request }, many=True).data response = Response(serialized_data) response['Cache-Control'] = 'no-cache' return response
def get(self, request, provider_uuid, identity_uuid, instance_id, tag_slug, *args, **kwargs): """ Return the credential information for this tag """ try: core_instance = get_core_instance(request, provider_uuid, identity_uuid, instance_id) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response(status.HTTP_409_CONFLICT, e.message) if not core_instance: instance_not_found(instance_id) try: tag = core_instance.tags.get(name__iexact=tag_slug) except CoreTag.DoesNotExist: return Response(['Tag does not exist'], status=status.HTTP_404_NOT_FOUND) serializer = TagSerializer(tag) return Response(serializer.data)
def get(self, request, provider_uuid, identity_uuid, instance_id, tag_slug, *args, **kwargs): """ Return the credential information for this tag """ try: core_instance = get_core_instance(request, provider_uuid, identity_uuid, instance_id) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response( status.HTTP_409_CONFLICT, e.message) if not core_instance: instance_not_found(instance_id) try: tag = core_instance.tags.get(name__iexact=tag_slug) except CoreTag.DoesNotExist: return Response(['Tag does not exist'], status=status.HTTP_404_NOT_FOUND) serializer = TagSerializer(tag) return Response(serializer.data)
def post(self, request, provider_uuid, identity_uuid): """ Updates DB values for volume """ user = request.user data = request.data missing_keys = valid_snapshot_post_data(data) if missing_keys: return keys_not_found(missing_keys) # Required size = data.get('size') volume_id = data.get('volume_id') display_name = data.get('display_name') # Optional description = data.get('description') metadata = data.get('metadata') snapshot_id = data.get('snapshot_id') # STEP 0 - Existence tests try: esh_driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response( status.HTTP_409_CONFLICT, e.message) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) try: esh_volume = esh_driver.get_volume(volume_id) except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except LibcloudInvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) except Exception as exc: logger.exception("Encountered a generic exception. " "Returning 409-CONFLICT") return failure_response(status.HTTP_409_CONFLICT, str(exc.message)) # TODO: Put quota tests at the TOP so we dont over-create resources! # STEP 1 - Reuse/Create snapshot if snapshot_id: snapshot = esh_driver._connection.get_snapshot(snapshot_id) if not snapshot: return failure_response( status.HTTP_400_BAD_REQUEST, "Snapshot %s not found. Process aborted." % snapshot_id) else: # Normal flow, create a snapshot from the volume if not esh_volume: return volume_not_found(volume_id) if esh_volume.extra['status'].lower() != 'available': return failure_response( status.HTTP_400_BAD_REQUEST, "Volume status must be 'available'. " "Did you detach the volume?") snapshot = esh_driver._connection.ex_create_snapshot( esh_volume, display_name, description) if not snapshot: return failure_response( status.HTTP_400_BAD_REQUEST, "Snapshot not created. Process aborted.") # STEP 2 - Create volume from snapshot try: success, esh_volume = create_esh_volume(esh_driver, identity_uuid, display_name, size, description, metadata, snapshot=snapshot) if not success: return failure_response( status.HTTP_500_INTERNAL_SERVER_ERROR, 'Volume creation failed. Contact support') # Volume creation succeeded core_volume = convert_esh_volume(esh_volume, provider_uuid, identity_uuid, user) serialized_data = VolumeSerializer( core_volume, context={'request': request}).data return Response(serialized_data, status=status.HTTP_201_CREATED) except OverQuotaError as oqe: return over_quota(oqe) except ConnectionFailure: return connection_failure(provider_uuid, identity_uuid) except LibcloudInvalidCredsError: return invalid_creds(provider_uuid, identity_uuid)
def post(self, request, provider_uuid, identity_uuid): """ Creates a new volume and adds it to the DB """ user = request.user try: membership = IdentityMembership.objects.get( identity__uuid=identity_uuid, member__name=user.username) except: return failure_response( status.HTTP_409_CONFLICT, "Identity %s is invalid -OR- User %s does not have the appropriate IdentityMembership." % (identity_uuid, user)) try: driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response( status.HTTP_409_CONFLICT, e.message) if not driver: return invalid_creds(provider_uuid, identity_uuid) data = request.data missing_keys = valid_volume_post_data(data) if missing_keys: return keys_not_found(missing_keys) # Pass arguments name = data.get('name') size = data.get('size') # Optional fields description = data.get('description') image_id = data.get('image') if image_id: image = driver.get_machine(image_id) image_size = image._connection.get_size(image._image) if int(size) > image_size + 4: return failure_response( status.HTTP_400_BAD_REQUEST, "Volumes created from images cannot exceed " "more than 4GB greater than the size of " "the image: %s GB" % image_size) else: image = None snapshot_id = data.get('snapshot') if snapshot_id: snapshot = driver._connection.ex_get_snapshot(image_id) else: snapshot = None try: success, esh_volume = create_esh_volume(driver, user.username, identity_uuid, name, size, description, snapshot=snapshot, image=image) except BaseHTTPError as http_error: if 'Requested volume or snapshot exceed' in http_error.message: return over_quota(http_error) return failure_response(status.HTTP_400_BAD_REQUEST, http_error.message) except OverQuotaError as oqe: return over_quota(oqe) except ConnectionFailure: return connection_failure(provider_uuid, identity_uuid) except LibcloudBadResponseError: return malformed_response(provider_uuid, identity_uuid) except LibcloudInvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) if not success: return failure_response( status.HTTP_500_INTERNAL_SERVER_ERROR, 'Volume creation failed. Contact support') # Volume creation succeeded core_volume = convert_esh_volume(esh_volume, provider_uuid, identity_uuid, user) serialized_data = VolumeSerializer(core_volume, context={'request': request}).data return Response(serialized_data, status=status.HTTP_201_CREATED)
def post(self, request, provider_uuid, identity_uuid, instance_id): """Authentication Required, Attempt a specific instance action, including necessary parameters. """ # Service-specific call to action action_params = request.data if not action_params.get('action', None): return failure_response( status.HTTP_400_BAD_REQUEST, 'POST request to /action require a BODY with \'action\'.') result_obj = None user = request.user identity = Identity.objects.get(uuid=identity_uuid) action = action_params['action'] try: result_obj = run_instance_action(user, identity, instance_id, action, action_params) result_obj = _further_process_result(request, action, result_obj) 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 except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except InstanceDoesNotExist as dne: return failure_response( status.HTTP_404_NOT_FOUND, 'Instance %s no longer exists' % (dne.message,)) except InvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) except HypervisorCapacityError as hce: return over_capacity(hce) except OverQuotaError as oqe: return over_quota(oqe) except OverAllocationError as oae: return over_quota(oae) except SizeNotAvailable as snae: return size_not_available(snae) except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except InvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) except VolumeMountConflict as vmc: return mount_failed(vmc) except NotImplemented: return failure_response( status.HTTP_409_CONFLICT, "The requested action %s is not available on this provider." % action_params['action']) except ActionNotAllowed: return failure_response( status.HTTP_409_CONFLICT, "The requested action %s has been explicitly " "disabled on this provider." % action_params['action']) except Exception as exc: logger.exception("Exception occurred processing InstanceAction") message = exc.message if message.startswith('409 Conflict'): return failure_response( status.HTTP_409_CONFLICT, message) return failure_response( status.HTTP_403_FORBIDDEN, "The requested action %s encountered " "an irrecoverable exception: %s" % (action_params['action'], message))
def post(self, request, provider_uuid, identity_uuid): """ Creates a new volume and adds it to the DB """ user = request.user try: membership = IdentityMembership.objects.get( identity__uuid=identity_uuid, member__memberships__user=user) except: return failure_response( status.HTTP_409_CONFLICT, "Identity %s is invalid -OR- User %s does not have the appropriate IdentityMembership." % (identity_uuid, user)) try: driver = prepare_driver(request, provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except Exception as e: return failure_response( status.HTTP_409_CONFLICT, e.message) if not driver: return invalid_creds(provider_uuid, identity_uuid) data = request.data missing_keys = valid_volume_post_data(data) if missing_keys: return keys_not_found(missing_keys) # Pass arguments name = data.get('name') size = data.get('size') # Optional fields description = data.get('description') image_id = data.get('image') if image_id: image = driver.get_machine(image_id) image_size = image._connection.get_size(image._image) if int(size) > image_size + 4: return failure_response( status.HTTP_400_BAD_REQUEST, "Volumes created from images cannot exceed " "more than 4GB greater than the size of " "the image: %s GB" % image_size) else: image = None snapshot_id = data.get('snapshot') if snapshot_id: snapshot = driver._connection.ex_get_snapshot(image_id) else: snapshot = None try: success, esh_volume = create_esh_volume(driver, user.username, identity_uuid, name, size, description, snapshot=snapshot, image=image) except BaseHTTPError as http_error: if 'Requested volume or snapshot exceed' in http_error.message: return over_quota(http_error) return failure_response(status.HTTP_400_BAD_REQUEST, http_error.message) except OverQuotaError as oqe: return over_quota(oqe) except ConnectionFailure: return connection_failure(provider_uuid, identity_uuid) except LibcloudBadResponseError: return malformed_response(provider_uuid, identity_uuid) except LibcloudInvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) if not success: return failure_response( status.HTTP_500_INTERNAL_SERVER_ERROR, 'Volume creation failed. Contact support') # Volume creation succeeded core_volume = convert_esh_volume(esh_volume, provider_uuid, identity_uuid, user) serialized_data = VolumeSerializer(core_volume, context={'request': request}).data return Response(serialized_data, status=status.HTTP_201_CREATED)
def post(self, request, provider_uuid, identity_uuid, instance_id): """Authentication Required, Attempt a specific instance action, including necessary parameters. """ # Service-specific call to action action_params = request.data if not action_params.get('action', None): return failure_response( status.HTTP_400_BAD_REQUEST, 'POST request to /action require a BODY with \'action\'.') result_obj = None user = request.user identity = Identity.objects.get(uuid=identity_uuid) action = action_params['action'] try: result_obj = run_instance_action(user, identity, instance_id, action, action_params) result_obj = _further_process_result(request, action, result_obj) 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 except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except ProviderNotActive as pna: return inactive_provider(pna) except InstanceDoesNotExist as dne: return failure_response( status.HTTP_404_NOT_FOUND, 'Instance %s no longer exists' % (dne.message, )) except LibcloudInvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) except HypervisorCapacityError as hce: return over_capacity(hce) except OverQuotaError as oqe: return over_quota(oqe) except OverAllocationError as oae: return over_quota(oae) except SizeNotAvailable as snae: return size_not_available(snae) except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except LibcloudInvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) except VolumeMountConflict as vmc: return mount_failed(vmc) except NotImplemented: return failure_response( status.HTTP_409_CONFLICT, "The requested action %s is not available on this provider." % action_params['action']) except ActionNotAllowed: return failure_response( status.HTTP_409_CONFLICT, "The requested action %s has been explicitly " "disabled on this provider." % action_params['action']) except Exception as exc: logger.exception("Exception occurred processing InstanceAction") message = exc.message if message.startswith('409 Conflict'): return failure_response(status.HTTP_409_CONFLICT, message) return failure_response( status.HTTP_403_FORBIDDEN, "The requested action %s encountered " "an irrecoverable exception: %s" % (action_params['action'], message))