def perform_destroy(self, instance): user = self.request.user identity_uuid = instance.created_by_identity.uuid identity = Identity.objects.get(id=identity_uuid) try: # Test that there is not an attached volume BEFORE we destroy #NOTE: Although this is a task we are calling and waiting for response.. core_instance = destroy_instance( user, identity_uuid, instance.provider_alias) serialized_instance = InstanceSerializer( core_instance, context={ 'request': self.request}, data={}, partial=True) if not serialized_instance.is_valid(): return Response(serialized_instance.data, status=status.HTTP_400_BAD_REQUEST) return Response(status=status.HTTP_204_NO_CONTENT) except VolumeAttachConflict as exc: message = exc.message return failure_response(status.HTTP_409_CONFLICT, message) 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): user = self.request.user identity_uuid = instance.created_by_identity.uuid identity = Identity.objects.get(uuid=identity_uuid) try: # Test that there is not an attached volume BEFORE we destroy #NOTE: Although this is a task we are calling and waiting for response.. core_instance = destroy_instance(user, identity_uuid, instance.provider_alias) serialized_instance = InstanceSerializer( core_instance, context={'request': self.request}, data={}, partial=True) if not serialized_instance.is_valid(): return Response(serialized_instance.data, status=status.HTTP_400_BAD_REQUEST) return Response(status=status.HTTP_204_NO_CONTENT) except VolumeAttachConflict as exc: message = exc.message return failure_response(status.HTTP_409_CONFLICT, message) 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 update(self, request, pk=None, partial=False): if not pk: return Response("Missing instance primary key", status=status.HTTP_400_BAD_REQUEST) data = request.data instance = Instance.objects.get(id=pk) if "allocation_source" in data and \ "id" in data["allocation_source"]: allocation_id = data["allocation_source"]["id"] try: user_source = UserAllocationSource.objects.get(user=request.user, allocation_source_id=allocation_id) except UserAllocationSource.DoesNotExist: return Response("Invalid allocation_source", status=status.HTTP_400_BAD_REQUEST) instance.change_allocation_source(user_source.allocation_source) serializer = InstanceSerializer( instance, data=data, partial=partial, context={'request': self.request}) if not serializer.is_valid(): return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) instance = serializer.save() return Response(serializer.data, status=status.HTTP_200_OK)
def update(self, request, pk=None, partial=False): if not pk: return Response( "Missing instance primary key", status=status.HTTP_400_BAD_REQUEST ) data = request.data instance = Instance.objects.get(id=pk) if "allocation_source" in data and \ "id" in data["allocation_source"]: allocation_id = data["allocation_source"]["id"] try: user_source = UserAllocationSource.objects.get( user=request.user, allocation_source_id=allocation_id ) except UserAllocationSource.DoesNotExist: return Response( "Invalid allocation_source", status=status.HTTP_400_BAD_REQUEST ) instance.change_allocation_source(user_source.allocation_source) serializer = InstanceSerializer( instance, data=data, partial=partial, context={'request': self.request} ) if not serializer.is_valid(): return Response( serializer.errors, status=status.HTTP_400_BAD_REQUEST ) instance = serializer.save() return Response(serializer.data, status=status.HTTP_200_OK)
def perform_destroy(self, instance): user = self.request.user identity_uuid = str(instance.created_by_identity.uuid) identity = Identity.objects.get(uuid=identity_uuid) provider_uuid = str(identity.provider.uuid) try: # Test that there is not an attached volume and destroy is ASYNC destroy_instance.delay( instance.provider_alias, user, identity_uuid) # NOTE: Task to delete has been queued, return 204 serializer = InstanceSerializer( instance, context={ 'request': self.request}, data={}, partial=True) if not serializer.is_valid(): return Response("Errors encountered during delete: %s" % serializer.errors, status=status.HTTP_400_BAD_REQUEST) return Response(status=status.HTTP_204_NO_CONTENT) except VolumeAttachConflict as exc: message = exc.message return failure_response(status.HTTP_409_CONFLICT, message) except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except LibcloudInvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) except InstanceDoesNotExist as dne: return failure_response( status.HTTP_404_NOT_FOUND, 'Instance %s no longer exists' % (dne.message,)) 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): user = self.request.user identity_uuid = str(instance.created_by_identity.uuid) identity = Identity.objects.get(uuid=identity_uuid) provider_uuid = str(identity.provider.uuid) try: # Test that there is not an attached volume and destroy is ASYNC destroy_instance.delay(instance.provider_alias, user, identity_uuid) # NOTE: Task to delete has been queued, return 204 serializer = InstanceSerializer(instance, context={'request': self.request}, data={}, partial=True) if not serializer.is_valid(): return Response("Errors encountered during delete: %s" % serializer.errors, status=status.HTTP_400_BAD_REQUEST) return Response(status=status.HTTP_204_NO_CONTENT) except VolumeAttachConflict as exc: message = exc.message return failure_response(status.HTTP_409_CONFLICT, message) except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except LibcloudInvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) except InstanceDoesNotExist as dne: return failure_response( status.HTTP_404_NOT_FOUND, 'Instance %s no longer exists' % (dne.message, )) except Exception as exc: logger.exception("Encountered a generic exception. " "Returning 409-CONFLICT") return failure_response(status.HTTP_409_CONFLICT, str(exc.message))
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 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 _multi_create( self, user, identity_uuid, size_alias, source_alias, name, deploy, allocation_source, project, boot_scripts, extra ): """ 1. Launch multiple instances 2. Serialize the launched instances 3. Return a list of serialized instances """ core_instances = launch_instance( user, identity_uuid, size_alias, source_alias, name, deploy, allocation_source=allocation_source, **extra ) serialized_data = [] # Serialize all instances launched for core_instance in core_instances: # 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(): logger.error( "multi-instance-launch, serialized instance is invalid, {}". format(serialized_instance) ) instance = serialized_instance.save() instance.project = project instance.save() if boot_scripts: _save_scripts_to_instance(instance, boot_scripts) instance.change_allocation_source(allocation_source) # append to result serialized_data.append(serialized_instance.data) # return a list of instances in the response return Response(serialized_data, status=status.HTTP_201_CREATED)
def destroy(self, request, pk=None): user = self.request.user try: instance = Instance.objects.get( Q(id=pk) if isinstance(pk, int) else Q(provider_alias=pk) ) identity_uuid = str(instance.created_by_identity.uuid) identity = Identity.objects.get(uuid=identity_uuid) provider_uuid = str(identity.provider.uuid) destroy_instance.delay(instance.provider_alias, user, identity_uuid) # We must invalidate the cache while we still depend on api.v1.instance invalidate_cached_instances(identity=identity) serializer = InstanceSerializer( instance, context={'request': self.request}, data={}, partial=True ) if not serializer.is_valid(): return Response( "Errors encountered during delete: %s" % serializer.errors, status=status.HTTP_400_BAD_REQUEST ) return Response(status=status.HTTP_204_NO_CONTENT) except VolumeAttachConflict as exc: message = exc.message return failure_response(status.HTTP_409_CONFLICT, message) except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except LibcloudInvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) except InstanceDoesNotExist as dne: return failure_response( status.HTTP_404_NOT_FOUND, 'Instance %s no longer exists' % (dne.message, ) ) except Exception as exc: logger.exception( "Encountered a generic exception. " "Returning 409-CONFLICT" ) return failure_response(status.HTTP_409_CONFLICT, str(exc.message))
def update(self, request, pk=None, partial=False): if not pk: return Response("Missing instance primary key", status=status.HTTP_400_BAD_REQUEST) data = request.data instance = Instance.objects.get(id=pk) if data.has_key("allocation_source") and \ data["allocation_source"].has_key("id"): allocation_id = data["allocation_source"]["id"] try: user_source = UserAllocationSource.objects.get( user=request.user, allocation_source_id=allocation_id) except UserAllocationSource.DoesNotExist: return Response("Invalid allocation_source", status=status.HTTP_400_BAD_REQUEST) instance.change_allocation_source(user_source.allocation_source) serialized_instance = InstanceSerializer( instance, context={'request': self.request}) return Response(serialized_instance.data, status=status.HTTP_200_OK)