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): """ 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)