def create_volume_from_image(identity_uuid, image_id, size_id, name, description, metadata): """ Create a new volume from an image """ try: identity = Identity.objects.get(uuid=identity_uuid) user = identity.created_by driver = get_cached_driver(identity=identity) image = driver._connection.ex_get_image(image_id) size = driver._connection.ex_get_size(size_id) if not image: raise Exception("No image found for id=%s." % image_id) if not size: raise Exception("No size found for id=%s." % size_id) success, esh_volume = driver._connection.create_volume( size.id, name, description=description, metadata=metadata, image=image) if not success: raise Exception("Could not create volume from image") # Save the new volume to the database convert_esh_volume( esh_volume, identity.provider.uuid, identity_uuid, user) except SoftTimeLimitExceeded as e: create_volume_from_image.retry(exc=e) except Identity.DoesNotExist: logger.info("An Identity for uuid=%s does not exist.", identity_uuid) raise
def create_volume_from_snapshot(identity_uuid, snapshot_id, size_id, name, description, metadata): """ Create a new volume for the snapshot NOTE: The size must be at least the same size as the original volume. """ try: identity = Identity.objects.get(uuid=identity_uuid) driver = get_cached_driver(identity=identity) snapshot = driver._connection.ex_get_snapshot(snapshot_id) size = driver._connection.ex_get_size(size_id) if not snapshot: raise Exception("No snapshot found for id=%s." % snapshot_id) if not size: raise Exception("No size found for id=%s." % size_id) success, esh_volume = driver._connection.create_volume( snapshot.size, name, description=description, metadata=metadata, snapshot=snapshot) if not success: raise Exception("Could not create volume from snapshot") # Save the new volume to the database convert_esh_volume( esh_volume, identity.provider.uuid, identity_uuid, identity.created_by) except SoftTimeLimitExceeded as e: create_volume_from_snapshot.retry(exc=e) except Identity.DoesNotExist: logger.info("An Identity for uuid=%s does not exist.", identity_uuid) raise
def monitor_volumes_for(provider_id, print_logs=False): """ Run the set of tasks related to monitoring sizes for a provider. Optionally, provide a list of usernames to monitor While debugging, print_logs=True can be very helpful. start_date and end_date allow you to search a 'non-standard' window of time. """ from service.driver import get_account_driver from core.models import Identity if print_logs: console_handler = _init_stdout_logging() provider = Provider.objects.get(id=provider_id) account_driver = get_account_driver(provider) # Non-End dated volumes on this provider db_volumes = Volume.objects.filter(only_current_source(), instance_source__provider=provider) all_volumes = account_driver.admin_driver.list_all_volumes(timeout=30) seen_volumes = [] for cloud_volume in all_volumes: try: core_volume = convert_esh_volume(cloud_volume, provider_uuid=provider.uuid) seen_volumes.append(core_volume) except ObjectDoesNotExist: tenant_id = cloud_volume.extra['object']['os-vol-tenant-attr:tenant_id'] tenant = account_driver.get_project_by_id(tenant_id) tenant_name = tenant.name if tenant else tenant_id try: if not tenant: celery_logger.warn("Warning: tenant_id %s found on volume %s, but did not exist from the account driver perspective.", tenant_id, cloud_volume) raise ObjectDoesNotExist() identity = Identity.objects.filter( contains_credential('ex_project_name', tenant_name), provider=provider ).first() if not identity: raise ObjectDoesNotExist() core_volume = convert_esh_volume( cloud_volume, provider.uuid, identity.uuid, identity.created_by) except ObjectDoesNotExist: celery_logger.info("Skipping Volume %s - No Identity for: Provider:%s + Project Name:%s" % (cloud_volume.id, provider, tenant_name)) pass now_time = timezone.now() needs_end_date = [volume for volume in db_volumes if volume not in seen_volumes] for volume in needs_end_date: celery_logger.debug("End dating inactive volume: %s" % volume) volume.end_date = now_time volume.save() if print_logs: _exit_stdout_logging(console_handler) for vol in seen_volumes: vol.esh = None return [vol.instance_source.identifier for vol in seen_volumes]
def get(self, request, provider_uuid, identity_uuid): """ Retrieves list of volumes and updates the DB """ user = request.user esh_driver = prepare_driver(request, provider_uuid, identity_uuid) 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 MalformedResponseError: return malformed_response(provider_id, identity_id) except InvalidCredsError: return invalid_creds(provider_id, identity_id) 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 esh_driver = prepare_driver(request, provider_uuid, identity_uuid) 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 InvalidCredsError: 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 esh_driver = prepare_driver(request, provider_uuid, identity_uuid) 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 MalformedResponseError: return malformed_response(provider_uuid, identity_uuid) except InvalidCredsError: 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 esh_driver = prepare_driver(request, provider_uuid, identity_uuid) 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 InvalidCredsError: 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 convert_instance_source( esh_driver, esh_instance, esh_source, provider_uuid, identity_uuid, user ): """ Given the instance source, create the appropriate core REPR and return """ from rtwo.models.volume import BaseVolume from rtwo.models.machine import BaseMachine # TODO: Future Release.. new_source = None if isinstance(esh_source, BaseVolume): core_source = convert_esh_volume( esh_source, provider_uuid, identity_uuid, user ) elif isinstance(esh_source, BaseMachine): if isinstance(esh_source, MockMachine): # MockMachine includes only the Alias/ID information # so a lookup on the machine is required to get accurate # information. new_source = esh_driver.get_machine(esh_source.id) if not new_source: core_source = get_or_create_provider_machine( esh_source.id, "Inactive Machine for Instance %s" % esh_instance.id, provider_uuid ) else: core_source = convert_esh_machine( esh_driver, new_source, provider_uuid, user ) elif not isinstance(esh_source, BaseMachine): raise Exception("Encountered unknown source %s" % esh_source) return core_source
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, provider_id, identity_id) if not esh_driver: return invalid_creds(provider_id, identity_id) esh_volume = esh_driver.get_volume(volume_id) if not esh_volume: return volume_not_found(volume_id) core_volume = convert_esh_volume(esh_volume, provider_id, identity_id, user) serializer = VolumeSerializer(core_volume, data=data, context={'request': request}) if serializer.is_valid(): serializer.save() response = Response(serializer.data) return response else: failure_response( status.HTTP_400_BAD_REQUEST, serializer.errors)
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, provider_id, identity_id) if not esh_driver: return invalid_creds(provider_id, identity_id) esh_volume = esh_driver.get_volume(volume_id) if not esh_volume: return volume_not_found(volume_id) 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, context={'user':request.user}, ).data response = Response(serialized_data) return response
def post(self, request, provider_uuid, identity_uuid): """ Creates a new volume and adds it to the DB """ user = request.user driver = prepare_driver(request, provider_uuid, identity_uuid) 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_volume(driver, identity_uuid, name, size, description, snapshot=snapshot, image=image) except OverQuotaError as oqe: return over_quota(oqe) except ConnectionFailure: return connection_failure(provider_uuid, identity_uuid) except MalformedResponseError: return malformed_response(provider_uuid, identity_uuid) except InvalidCredsError: 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 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, volume_id): """ """ user = request.user esh_driver = prepare_driver(request, provider_id, identity_id) if not esh_driver: return invalid_creds(provider_id, identity_id) esh_volume = esh_driver.get_volume(volume_id) if not esh_volume: return volume_not_found(volume_id) 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 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_id, identity_id): """ Retrieves list of volumes and updates the DB """ user = request.user esh_driver = prepare_driver(request, identity_id) volume_list_method = esh_driver.list_volumes if AccountProvider.objects.filter(identity__id=identity_id): # Instance list method changes when using the OPENSTACK provider volume_list_method = esh_driver.list_all_volumes esh_volume_list = volume_list_method() core_volume_list = [convert_esh_volume(volume, provider_id, identity_id, user) for volume in esh_volume_list] serializer = VolumeSerializer(core_volume_list, many=True) response = Response(serializer.data) return response
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 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) try: esh_volume = esh_driver.get_volume(volume_id) except ConnectionFailure: return connection_failure(provider_uuid, identity_uuid) except InvalidCredsError: 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): """ 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 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_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 InvalidCredsError: 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 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, provider_id, identity_id) if not esh_driver: return invalid_creds(provider_id, identity_id) esh_volume = esh_driver.get_volume(volume_id) if not esh_volume: return volume_not_found(volume_id) 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 convert_instance_source(esh_driver, esh_source, provider_uuid, identity_uuid, user): """ Given the instance source, create the appropriate core REPR and return """ from rtwo.volume import BaseVolume from rtwo.machine import BaseMachine #TODO: Future Release.. #if isinstance(esh_source, BaseSnapShot): # core_source = convert_esh_snapshot(esh_source, provider_uuid, identity_uuid, user) if isinstance(esh_source, BaseVolume): core_source = convert_esh_volume(esh_source, provider_uuid, identity_uuid, user) elif isinstance(esh_source, BaseMachine): if type(esh_source) == MockMachine: #MockMachine includes only the Alias/ID information #so a lookup on the machine is required to get accurate #information. esh_source = esh_driver.get_machine(esh_source.id) core_source = convert_esh_machine(esh_driver, esh_source, provider_uuid, user) elif not isinstance(esh_source, BaseMachine): raise Exception ("Encountered unknown source %s" % esh_source) return core_source
def get(self, request, provider_id, identity_id): """ Retrieves list of volumes and updates the DB """ user = request.user esh_driver = prepare_driver(request, provider_id, identity_id) if not esh_driver: return invalid_creds(provider_id, identity_id) volume_list_method = esh_driver.list_volumes if AccountProvider.objects.filter(identity__id=identity_id): # Instance list method changes when using the OPENSTACK provider volume_list_method = esh_driver.list_all_volumes esh_volume_list = volume_list_method() core_volume_list = [convert_esh_volume(volume, provider_id, identity_id, user) for volume in esh_volume_list] serializer = VolumeSerializer(core_volume_list, many=True) response = Response(serializer.data) return response
def patch(self, request, provider_uuid, identity_uuid, volume_id): """ Updates DB values for volume """ user = request.user data = request.data # Ensure volume exists esh_driver = prepare_driver(request, provider_uuid, identity_uuid) 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 InvalidCredsError: 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}, partial=True) if serializer.is_valid(): serializer.save() _update_volume_metadata( esh_driver, esh_volume, data) response = Response(serializer.data) return response else: return failure_response( status.HTTP_400_BAD_REQUEST, serializer.errors)
def convert_instance_source( esh_driver, esh_instance, esh_source, provider_uuid, identity_uuid, user): """ Given the instance source, create the appropriate core REPR and return """ from rtwo.models.volume import BaseVolume from rtwo.models.machine import BaseMachine # TODO: Future Release.. new_source = None if isinstance(esh_source, BaseVolume): core_source = convert_esh_volume( esh_source, provider_uuid, identity_uuid, user) elif isinstance(esh_source, BaseMachine): if isinstance(esh_source, MockMachine): # MockMachine includes only the Alias/ID information # so a lookup on the machine is required to get accurate # information. new_source = esh_driver.get_machine(esh_source.id) if not new_source: core_source = get_or_create_provider_machine( esh_source.id, "Inactive Machine for Instance %s" % esh_instance.id, provider_uuid) else: core_source = convert_esh_machine(esh_driver, new_source, provider_uuid, user) elif not isinstance(esh_source, BaseMachine): raise Exception("Encountered unknown source %s" % esh_source) return core_source
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, provider_id, identity_id) if not esh_driver: return invalid_creds(provider_id, identity_id) esh_volume = esh_driver.get_volume(volume_id) if not esh_volume: return volume_not_found(volume_id) 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: failure_response( status.HTTP_400_BAD_REQUEST, serializer.errors)
def get(self, request, provider_id, identity_id, volume_id): """ """ user = request.user esh_driver = prepare_driver(request, provider_id, identity_id) if not esh_driver: return invalid_creds(provider_id, identity_id) esh_volume = esh_driver.get_volume(volume_id) if not esh_volume: try: core_volume = CoreVolume.objects.get( alias=volume_id, provider__id=provider_id) core_volume.end_date = datetime.now() core_volume.save() except CoreVolume.DoesNotExist: pass return volume_not_found(volume_id) core_volume = convert_esh_volume(esh_volume, provider_id, identity_id, user) serialized_data = VolumeSerializer(core_volume, context={'request': request}).data response = Response(serialized_data) return response
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 esh_driver = prepare_driver(request, provider_uuid, identity_uuid) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) try: esh_instance = esh_driver.get_instance(instance_id) except ConnectionFailure: return connection_failure(provider_uuid, identity_uuid) except InvalidCredsError: 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_instance: return failure_response( status.HTTP_400_BAD_REQUEST, 'Instance %s no longer exists' % (instance_id,)) action = action_params['action'] try: if 'volume' in action: volume_id = action_params.get('volume_id') mount_location = action_params.get('mount_location', None) device = action_params.get('device', None) if 'attach_volume' == action: if mount_location == 'null' or mount_location == 'None': mount_location = None if device == 'null' or device == 'None': device = None future_mount_location =\ task.attach_volume_task(esh_driver, esh_instance.alias, volume_id, device, mount_location) elif 'mount_volume' == action: future_mount_location =\ task.mount_volume_task(esh_driver, esh_instance.alias, volume_id, device, mount_location) elif 'unmount_volume' == action: (result, error_msg) =\ task.unmount_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 return failure_response( status.HTTP_400_BAD_REQUEST, error_msg) # 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_uuid, identity_uuid, user) result_obj =\ VolumeSerializer(core_volume, context={"request": request}).data elif 'resize' == action: size_alias = action_params.get('size', '') if type(size_alias) == int: size_alias = str(size_alias) resize_instance(esh_driver, esh_instance, size_alias, provider_uuid, identity_uuid, user) elif 'confirm_resize' == action: confirm_resize(esh_driver, esh_instance, provider_uuid, identity_uuid, user) elif 'revert_resize' == action: esh_driver.revert_resize_instance(esh_instance) elif 'redeploy' == action: redeploy_init(esh_driver, esh_instance, countdown=None) elif 'resume' == action: result_obj = resume_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) elif 'suspend' == action: result_obj = suspend_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) elif 'shelve' == action: result_obj = shelve_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) elif 'unshelve' == action: result_obj = unshelve_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) elif 'shelve_offload' == action: result_obj = offload_instance(esh_driver, esh_instance) elif 'start' == action: start_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) elif 'stop' == action: stop_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) elif 'reset_network' == action: esh_driver.reset_network(esh_instance) elif 'console' == action: result_obj = esh_driver._connection\ .ex_vnc_console(esh_instance) elif 'reboot' == action: reboot_type = action_params.get('reboot_type', 'SOFT') reboot_instance(esh_driver, esh_instance, identity_uuid, user, reboot_type) 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: return failure_response( status.HTTP_400_BAD_REQUEST, 'Unable to to perform action %s.' % (action)) 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 HypervisorCapacityError, hce: return over_capacity(hce)
def post(self, request, provider_id, identity_id, 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 esh_driver = prepare_driver(request, provider_id, identity_id) if not esh_driver: return invalid_creds(provider_id, 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 ConnectionFailure: return connection_failure(provider_id, identity_id) except InvalidCredsError: return invalid_creds(provider_id, identity_id) esh_instance = esh_driver.get_instance(instance_id) if not esh_instance: return failure_response( status.HTTP_400_BAD_REQUEST, 'Instance %s no longer exists' % (instance_id,)) 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 return failure_response( status.HTTP_400_BAD_REQUEST, error_msg) #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, context={"request":request} ).data elif 'resize' == action: size_alias = action_params.get('size', '') if type(size_alias) == int: size_alias = str(size_alias) resize_instance(esh_driver, esh_instance, size_alias, provider_id, identity_id, user) elif 'confirm_resize' == action: confirm_resize(esh_driver, esh_instance, provider_id, identity_id, user) elif 'revert_resize' == action: esh_driver.revert_resize_instance(esh_instance) elif 'redeploy' == action: redeploy_init(esh_driver, esh_instance, countdown=None) 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 'console' == action: result_obj = esh_driver._connection.ex_vnc_console(esh_instance) elif 'reboot' == action: reboot_type = action_params.get('reboot_type', 'SOFT') reboot_instance(esh_driver, esh_instance, reboot_type) 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: return failure_response( status.HTTP_400_BAD_REQUEST, 'Unable to to perform action %s.' % (action)) #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 HypervisorCapacityError, hce: return over_capacity(hce)
description, snapshot=snapshot, image=image) except OverQuotaError, oqe: return over_quota(oqe) except ConnectionFailure: return connection_failure(provider_uuid, identity_uuid) except MalformedResponseError: return malformed_response(provider_uuid, identity_uuid) except InvalidCredsError: 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) class Volume(APIView): """Details of specific volume on Identity.""" permission_classes = (ApiAuthRequired, ) def get(self, request, provider_uuid, identity_uuid, volume_id): """ """ user = request.user
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 esh_driver = prepare_driver(request, provider_uuid, identity_uuid) 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 InvalidCredsError: 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_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, oqe: return over_quota(oqe)
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 esh_driver = prepare_driver(request, provider_uuid, identity_uuid) 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 InvalidCredsError: 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_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 InvalidCredsError: return invalid_creds(provider_uuid, identity_uuid)
def monitor_volumes_for(provider_id, print_logs=False): """ Run the set of tasks related to monitoring sizes for a provider. Optionally, provide a list of usernames to monitor While debugging, print_logs=True can be very helpful. start_date and end_date allow you to search a 'non-standard' window of time. """ from service.driver import get_account_driver from core.models import Identity if print_logs: console_handler = _init_stdout_logging() provider = Provider.objects.get(id=provider_id) account_driver = get_account_driver(provider) # Non-End dated volumes on this provider db_volumes = Volume.objects.filter( only_current_source(), instance_source__provider=provider ) all_volumes = account_driver.admin_driver.list_all_volumes(timeout=30) seen_volumes = [] for cloud_volume in all_volumes: try: core_volume = convert_esh_volume( cloud_volume, provider_uuid=provider.uuid ) seen_volumes.append(core_volume) except ObjectDoesNotExist: tenant_id = cloud_volume.extra['object'][ 'os-vol-tenant-attr:tenant_id'] tenant = account_driver.get_project_by_id(tenant_id) tenant_name = tenant.name if tenant else tenant_id try: if not tenant: celery_logger.warn( "Warning: tenant_id %s found on volume %s, " "but did not exist from the account driver " "perspective.", tenant_id, cloud_volume ) raise ObjectDoesNotExist() identity = Identity.objects.filter( contains_credential('ex_project_name', tenant_name), provider=provider ).first() if not identity: raise ObjectDoesNotExist() core_volume = convert_esh_volume( cloud_volume, provider.uuid, identity.uuid, identity.created_by ) except ObjectDoesNotExist: celery_logger.info( "Skipping Volume %s - No Identity for: Provider:%s + Project Name:%s" % (cloud_volume.id, provider, tenant_name) ) pass now_time = timezone.now() needs_end_date = [ volume for volume in db_volumes if volume not in seen_volumes ] for volume in needs_end_date: celery_logger.debug("End dating inactive volume: %s" % volume) volume.end_date = now_time volume.save() if print_logs: _exit_stdout_logging(console_handler) for vol in seen_volumes: vol.esh = None return [vol.instance_source.identifier for vol in seen_volumes]
def post(self, request, provider_id, identity_id, 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 esh_driver = prepare_driver(request, provider_id, identity_id) if not esh_driver: return invalid_creds(provider_id, 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: return failure_response( status.HTTP_400_BAD_REQUEST, 'Instance %s no longer exists' % (instance_id, )) 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 return failure_response(status.HTTP_400_BAD_REQUEST, error_msg) #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, context={ 'user': request.user }).data elif 'resize' == action: size_alias = action_params.get('size', '') if type(size_alias) == int: size_alias = str(size_alias) resize_instance(esh_driver, esh_instance, size_alias, provider_id, identity_id, user) elif 'confirm_resize' == action: confirm_resize(esh_driver, esh_instance, provider_id, identity_id, user) elif 'revert_resize' == action: esh_driver.revert_resize_instance(esh_instance) elif 'redeploy' == action: redeploy_init(esh_driver, esh_instance, countdown=None) 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 'console' == action: result_obj = esh_driver._connection.ex_vnc_console( esh_instance) elif 'reboot' == action: reboot_type = action_params.get('reboot_type', 'SOFT') reboot_instance(esh_driver, esh_instance, reboot_type) 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: return failure_response( status.HTTP_400_BAD_REQUEST, 'Unable to to perform action %s.' % (action)) #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 HypervisorCapacityError, hce: return over_capacity(hce)
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 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 esh_driver = prepare_driver(request, provider_uuid, identity_uuid) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) try: esh_instance = esh_driver.get_instance(instance_id) except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except InvalidCredsError: 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_instance: return failure_response( status.HTTP_400_BAD_REQUEST, 'Instance %s no longer exists' % (instance_id,)) action = action_params['action'] try: if 'volume' in action: volume_id = action_params.get('volume_id') mount_location = action_params.get('mount_location', None) device = action_params.get('device', None) if 'attach_volume' == action: if mount_location == 'null' or mount_location == 'None': mount_location = None if device == 'null' or device == 'None': device = None task.attach_volume_task(esh_driver, esh_instance.alias, volume_id, device, mount_location) elif 'mount_volume' == action: task.mount_volume_task(esh_driver, esh_instance.alias, volume_id, device, mount_location) elif 'unmount_volume' == action: (result, error_msg) =\ task.unmount_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 return failure_response( status.HTTP_400_BAD_REQUEST, error_msg) # 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_uuid, identity_uuid, user) result_obj =\ VolumeSerializer(core_volume, context={"request": request}).data elif 'resize' == action: size_alias = action_params.get('size', '') if isinstance(size_alias, int): size_alias = str(size_alias) resize_instance(esh_driver, esh_instance, size_alias, provider_uuid, identity_uuid, user) elif 'confirm_resize' == action: confirm_resize(esh_driver, esh_instance, provider_uuid, identity_uuid, user) elif 'revert_resize' == action: esh_driver.revert_resize_instance(esh_instance) elif 'redeploy' == action: redeploy_init(esh_driver, esh_instance) elif 'resume' == action: result_obj = resume_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) elif 'suspend' == action: result_obj = suspend_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) elif 'shelve' == action: result_obj = shelve_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) elif 'unshelve' == action: result_obj = unshelve_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) elif 'shelve_offload' == action: result_obj = offload_instance(esh_driver, esh_instance) elif 'start' == action: start_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) elif 'stop' == action: stop_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) elif 'reset_network' == action: esh_driver.reset_network(esh_instance) elif 'console' == action: result_obj = esh_driver._connection\ .ex_vnc_console(esh_instance) elif 'reboot' == action: reboot_type = action_params.get('reboot_type', 'SOFT') reboot_instance(esh_driver, esh_instance, identity_uuid, user, reboot_type) 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: return failure_response( status.HTTP_400_BAD_REQUEST, 'Unable to to perform action %s.' % (action)) 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 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_availabe(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_404_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 esh_driver = prepare_driver(request, provider_uuid, identity_uuid) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) try: esh_instance = esh_driver.get_instance(instance_id) except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except InvalidCredsError: 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_instance: return failure_response( status.HTTP_400_BAD_REQUEST, 'Instance %s no longer exists' % (instance_id,)) action = action_params['action'] try: if 'volume' in action: volume_id = action_params.get('volume_id') mount_location = action_params.get('mount_location', None) device = action_params.get('device', None) if 'attach_volume' == action: if mount_location == 'null' or mount_location == 'None': mount_location = None if device == 'null' or device == 'None': device = None future_mount_location =\ task.attach_volume_task(esh_driver, esh_instance.alias, volume_id, device, mount_location) elif 'mount_volume' == action: future_mount_location =\ task.mount_volume_task(esh_driver, esh_instance.alias, volume_id, device, mount_location) elif 'unmount_volume' == action: (result, error_msg) =\ task.unmount_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 return failure_response( status.HTTP_400_BAD_REQUEST, error_msg) # 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_uuid, identity_uuid, user) result_obj =\ VolumeSerializer(core_volume, context={"request": request}).data elif 'resize' == action: size_alias = action_params.get('size', '') if type(size_alias) == int: size_alias = str(size_alias) resize_instance(esh_driver, esh_instance, size_alias, provider_uuid, identity_uuid, user) elif 'confirm_resize' == action: confirm_resize(esh_driver, esh_instance, provider_uuid, identity_uuid, user) elif 'revert_resize' == action: esh_driver.revert_resize_instance(esh_instance) elif 'redeploy' == action: redeploy_init(esh_driver, esh_instance, countdown=None) elif 'resume' == action: result_obj = resume_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) elif 'suspend' == action: result_obj = suspend_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) elif 'shelve' == action: result_obj = shelve_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) elif 'unshelve' == action: result_obj = unshelve_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) elif 'shelve_offload' == action: result_obj = offload_instance(esh_driver, esh_instance) elif 'start' == action: start_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) elif 'stop' == action: stop_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) elif 'reset_network' == action: esh_driver.reset_network(esh_instance) elif 'console' == action: result_obj = esh_driver._connection\ .ex_vnc_console(esh_instance) elif 'reboot' == action: reboot_type = action_params.get('reboot_type', 'SOFT') reboot_instance(esh_driver, esh_instance, identity_uuid, user, reboot_type) 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: return failure_response( status.HTTP_400_BAD_REQUEST, 'Unable to to perform action %s.' % (action)) 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 HypervisorCapacityError, hce: return over_capacity(hce)
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)
name, size, description, snapshot=snapshot, image=image) except OverQuotaError, oqe: return over_quota(oqe) except ConnectionFailure: return connection_failure(provider_uuid, identity_uuid) except MalformedResponseError: return malformed_response(provider_uuid, identity_uuid) except InvalidCredsError: 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) class Volume(APIView): """Details of specific volume on Identity.""" permission_classes = (ApiAuthRequired,) def get(self, request, provider_uuid, identity_uuid, volume_id): """ """ user = request.user esh_driver = prepare_driver(request, provider_uuid, identity_uuid) if not esh_driver: