def delete(self, request, provider_uuid, identity_uuid, instance_id): """Authentication Required, TERMINATE the instance. Be careful, there is no going back once you've deleted an instance. """ 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)) try: # Test that there is not an attached volume BEFORE we destroy task.destroy_instance_task(user, esh_instance, identity_uuid) invalidate_cached_instances(identity=Identity.objects.get(uuid=identity_uuid)) existing_instance = esh_driver.get_instance(instance_id) if existing_instance: # Instance will be deleted soon... esh_instance = existing_instance if esh_instance.extra and "task" not in esh_instance.extra: esh_instance.extra["task"] = "queueing delete" 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 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)) try: core_instance = convert_esh_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) if core_instance: core_instance.end_date_all() else: logger.warn("Unable to find core instance %s." % (instance_id)) serialized_data = InstanceSerializer(core_instance, context={"request": request}).data response = Response(serialized_data, status=status.HTTP_200_OK) response["Cache-Control"] = "no-cache" return response except (Identity.DoesNotExist) as exc: return failure_response(status.HTTP_400_BAD_REQUEST, "Invalid provider_uuid or identity_uuid.") except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except InvalidCredsError: return invalid_creds(provider_uuid, identity_uuid)
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 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 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): """ 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 esh_driver = prepare_driver(request, provider_uuid, identity_uuid) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) try: esh_size_list = esh_driver.list_sizes() except MalformedResponseError: return malformed_response(provider_uuid, identity_uuid) except InvalidCredsError: 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_esh_instance(request, provider_uuid, identity_uuid, instance_id): esh_driver = prepare_driver(request, provider_uuid, identity_uuid) if not esh_driver: raise LibcloudInvalidCredsError("Provider_uuid && identity_uuid " "did not produce a valid combination") esh_instance = None try: esh_instance = esh_driver.get_instance(instance_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)) if not esh_instance: # End date everything 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 esh_instance
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 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): """ 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) #logger.debug(filtered_machine_list) except InvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) except MalformedResponseError: return malformed_response(provider_uuid, identity_uuid) except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except Exception as e: logger.exception("Unexpected exception for user:%s" % request_user) return failure_response(status.HTTP_500_INTERNAL_SERVER_ERROR, e.message) #logger.debug(filtered_machine_list) serialized_data = ProviderMachineSerializer(filtered_machine_list, request_user=request.user, many=True).data response = Response(serialized_data) return response
def get(self, request, provider_uuid, identity_uuid): """ Returns a list of all instances """ user = request.user esh_driver = prepare_driver(request, provider_uuid, identity_uuid) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) identity = Identity.objects.get(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_esh_instance(request, provider_uuid, identity_uuid, instance_id): esh_driver = prepare_driver(request, provider_uuid, identity_uuid) if not esh_driver: raise InvalidCredsError( "Provider_uuid && identity_uuid " "did not produce a valid combination") esh_instance = None 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: # End date everything 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 esh_instance
def get(self, request, provider_uuid, identity_uuid, hypervisor_id): """ Lookup the Hypervisor information (Lookup using the given provider/identity) Update on server DB (If applicable) """ provider = Provider.objects.filter(uuid=provider_uuid) if not provider: return invalid_creds(provider_uuid, identity_uuid) esh_driver = get_admin_driver(provider[0]) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) hypervisor = {} if not hasattr(esh_driver._connection, 'ex_detail_hypervisor_node'): return failure_response( status.HTTP_404_NOT_FOUND, "Hypervisor Details cannot be retrieved for this provider.") try: hypervisor = esh_driver._connection\ .ex_detail_hypervisor_node(hypervisor_id) hypervisor['cpu_info'] = json.loads(hypervisor['cpu_info']) response = Response(hypervisor) return response except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except Exception as exc: return failure_response( status.HTTP_404_NOT_FOUND, "Error encountered retrieving hypervisor details:%s" % exc)
def get(self, request, provider_uuid, identity_uuid): """ Using provider and identity, getlist of machines TODO: Cache this request """ provider = Provider.objects.filter(uuid=provider_uuid) if not provider: return invalid_creds(provider_uuid, identity_uuid) esh_driver = get_admin_driver(provider[0]) esh_hypervisor_list = [] if not hasattr(esh_driver._connection, 'ex_list_hypervisor_nodes'): return failure_response( status.HTTP_404_NOT_FOUND, "The Hypervisor List cannot be retrieved for this provider.") try: esh_hypervisor_list =\ esh_driver._connection.ex_list_hypervisor_nodes() region_name = esh_driver._connection._ex_force_service_region for obj in esh_hypervisor_list: obj['service_region'] = region_name response = Response(esh_hypervisor_list) return response except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except Exception as exc: return failure_response( status.HTTP_404_NOT_FOUND, "Error encountered retrieving hypervisor list:%s" % exc)
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 provider = Provider.objects.filter(uuid=provider_uuid) if not provider: return invalid_creds(provider_uuid, identity_uuid) esh_driver = get_admin_driver(provider[0]) esh_hypervisor_list = [] if not hasattr(esh_driver._connection, 'ex_list_hypervisor_nodes'): return failure_response( status.HTTP_404_NOT_FOUND, "The Hypervisor List cannot be retrieved for this provider.") try: esh_hypervisor_list =\ esh_driver._connection.ex_list_hypervisor_nodes() region_name = esh_driver._connection._ex_force_service_region for obj in esh_hypervisor_list: obj['service_region'] = region_name response = Response(esh_hypervisor_list) return response except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except Exception as exc: return failure_response( status.HTTP_404_NOT_FOUND, "Error encountered retrieving hypervisor list:%s" % exc)
def get(self, request, provider_uuid, identity_uuid, hypervisor_id): """ Lookup the Hypervisor information (Lookup using the given provider/identity) Update on server DB (If applicable) """ user = request.user provider = Provider.objects.filter(uuid=provider_uuid) if not provider: return invalid_creds(provider_uuid, identity_uuid) esh_driver = get_admin_driver(provider[0]) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) hypervisor = {} if not hasattr(esh_driver._connection, 'ex_detail_hypervisor_node'): return failure_response( status.HTTP_404_NOT_FOUND, "Hypervisor Details cannot be retrieved for this provider.") try: hypervisor = esh_driver._connection\ .ex_detail_hypervisor_node(hypervisor_id) hypervisor['cpu_info'] = json.loads(hypervisor['cpu_info']) response = Response(hypervisor) return response except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except Exception as exc: return failure_response( status.HTTP_404_NOT_FOUND, "Error encountered retrieving hypervisor details:%s" % exc)
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) #logger.debug(filtered_machine_list) except InvalidCredsError: return invalid_creds(provider_uuid, identity_uuid) except MalformedResponseError: return malformed_response(provider_uuid, identity_uuid) except (socket_error, ConnectionFailure): return connection_failure(provider_uuid, identity_uuid) except Exception as e: logger.exception("Unexpected exception for user:%s" % request_user) return failure_response(status.HTTP_500_INTERNAL_SERVER_ERROR, e.message) #logger.debug(filtered_machine_list) serialized_data = ProviderMachineSerializer(filtered_machine_list, request_user=request.user, many=True).data response = Response(serialized_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 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 put(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}) 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): try: provider = Provider.get_active(provider_uuid) except Provider.DoesNotExist: return failure_response( status.HTTP_404_NOT_FOUND, "The provider does not exist.") admin_driver = get_admin_driver(provider) if not admin_driver: return failure_response( status.HTTP_404_NOT_FOUND, "The driver cannot be retrieved for this provider.") if not hasattr(admin_driver._connection, "ex_hypervisor_statistics"): return failure_response( status.HTTP_404_NOT_FOUND, "Occupancy statistics cannot be retrieved for this provider.") try: stats = admin_driver._connection.ex_hypervisor_statistics() return Response(stats) except (socket_error, ConnectionFailure): return connection_failure(provider_uuid) except Exception as exc: return failure_response( status.HTTP_503_SERVICE_UNAVAILABLE, "Error occurred while retrieving statistics: %s" % exc)
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 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) 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(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_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) logger.info("Looking for %s" % instance_id) esh_instance = esh_driver.get_instance(instance_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)) # 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 put(self, request, provider_uuid, identity_uuid, instance_id): """Authentication Required, update metadata about the instance""" user = request.user data = request.data # Ensure item exists on the server first 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 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_instance: return instance_not_found(instance_id) # Gather the DB related item and update core_instance = convert_esh_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) serializer = InstanceSerializer(core_instance, data=data, context={"request": request}) identity = Identity.objects.get(uuid=identity_uuid) if serializer.is_valid(): logger.info('metadata = %s' % data) #NOTE: We shouldn't allow 'full replacement' of metadata.. # We should also validate against potentional updating of 'atmo-used metadata' update_metadata.s(esh_driver.__class__, esh_driver.provider, esh_driver.identity, esh_instance.id, data, replace_metadata=False).apply() new_instance = serializer.save() boot_scripts = data.pop('boot_scripts', []) if boot_scripts: new_instance = _save_scripts_to_instance( new_instance, boot_scripts) serializer = InstanceSerializer(new_instance, context={"request": request}) invalidate_cached_instances(identity=identity) response = Response(serializer.data) logger.info('data = %s' % serializer.data) response['Cache-Control'] = 'no-cache' return response else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def patch(self, request, provider_uuid, identity_uuid, instance_id): """Authentication Required, update metadata about the instance""" user = request.user data = request.data 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 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_instance: return instance_not_found(instance_id) # Gather the DB related item and update core_instance = convert_esh_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) serializer = InstanceSerializer(core_instance, data=data, context={"request": request}, partial=True) identity = Identity.objects.get(uuid=identity_uuid) provider = identity.provider if serializer.is_valid(): logger.info('metadata = %s' % data) driver_class = esh_driver.__class__ update_metadata.s(driver_class, provider, identity, esh_instance.id, data, replace_metadata=False).apply() instance = serializer.save() boot_scripts = data.pop('boot_scripts', []) if boot_scripts: _save_scripts_to_instance(instance, boot_scripts) invalidate_cached_instances(identity=identity) response = Response(serializer.data) logger.info('data = %s' % serializer.data) response['Cache-Control'] = 'no-cache' return response else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def put(self, request, provider_uuid, identity_uuid, instance_id): """Authentication Required, update metadata about the instance""" user = request.user data = request.DATA # Ensure item exists on the server first 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 instance_not_found(instance_id) # Gather the DB related item and update core_instance = convert_esh_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) serializer = InstanceSerializer(core_instance, data=data, context={"request": request}) identity = Identity.objects.get(uuid=identity_uuid) provider = identity.provider if serializer.is_valid(): logger.info('metadata = %s' % data) #NOTE: We shouldn't allow 'full replacement' of metadata.. # We should also validate against potentional updating of 'atmo-used metadata' update_metadata.s(driver_class, provider, identity, esh_instance.id, data, replace_metadata=False).apply() new_instance = serializer.save() boot_scripts = data.pop('boot_scripts', []) if boot_scripts: new_instance = _save_scripts_to_instance(new_instance, boot_scripts) serializer = InstanceSerializer( new_instance, context={"request": request}) invalidate_cached_instances(identity=identitty) response = Response(serializer.data) logger.info('data = %s' % serializer.data) response['Cache-Control'] = 'no-cache' return response else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def patch(self, request, provider_uuid, identity_uuid, instance_id): """Authentication Required, update metadata about the instance""" user = request.user data = request.data 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 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_instance: return instance_not_found(instance_id) # Gather the DB related item and update core_instance = convert_esh_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) serializer = InstanceSerializer( core_instance, data=data, context={"request": request}, partial=True) identity = Identity.objects.get(uuid=identity_uuid) provider = identity.provider if serializer.is_valid(): logger.info('metadata = %s' % data) driver_class = esh_driver.__class__ update_metadata.s(driver_class, provider, identity, esh_instance.id, data, replace_metadata=False).apply() instance = serializer.save() boot_scripts = data.pop('boot_scripts', []) if boot_scripts: _save_scripts_to_instance(instance, boot_scripts) invalidate_cached_instances(identity=identity) response = Response(serializer.data) logger.info('data = %s' % serializer.data) response['Cache-Control'] = 'no-cache' return response else: return Response( serializer.errors, status=status.HTTP_400_BAD_REQUEST)
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 patch(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}, 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 put(self, request, provider_uuid, identity_uuid, instance_id): """Authentication Required, update metadata about the instance""" user = request.user data = request.DATA #Ensure item exists on the server first 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 instance_not_found(instance_id) #Gather the DB related item and update core_instance = convert_esh_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) serializer = InstanceSerializer(core_instance, data=data, context={"request": request}) if serializer.is_valid(): logger.info('metadata = %s' % data) update_instance_metadata(esh_driver, esh_instance, data) serializer.save() new_instance = serializer.object boot_scripts = data.pop('boot_scripts', []) if boot_scripts: new_instance = _save_scripts_to_instance( new_instance, boot_scripts) serializer = InstanceSerializer(new_instance, context={"request": request}) invalidate_cached_instances(identity=Identity.objects.get( uuid=identity_uuid)) response = Response(serializer.data) logger.info('data = %s' % serializer.data) response['Cache-Control'] = 'no-cache' return response else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, provider_uuid, identity_uuid, instance_id): """Authentication Required, TERMINATE the instance. Be careful, there is no going back once you've deleted an instance. """ 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) if not esh_instance: return instance_not_found(instance_id) #Test that there is not an attached volume BEFORE we destroy _check_volume_attachment(esh_driver, esh_instance) task.destroy_instance_task(esh_instance, identity_uuid) invalidate_cached_instances(identity=Identity.objects.get(uuid=identity_uuid)) existing_instance = esh_driver.get_instance(instance_id) if existing_instance: #Instance will be deleted soon... esh_instance = existing_instance if esh_instance.extra\ and 'task' not in esh_instance.extra: esh_instance.extra['task'] = 'queueing delete' core_instance = convert_esh_instance(esh_driver, esh_instance, provider_uuid, identity_uuid, user) if core_instance: core_instance.end_date_all() else: logger.warn("Unable to find core instance %s." % (instance_id)) serialized_data = InstanceSerializer(core_instance, context={"request":request}).data response = Response(serialized_data, status=status.HTTP_200_OK) response['Cache-Control'] = 'no-cache' return response except (Identity.DoesNotExist) as exc: return failure_response(status.HTTP_400_BAD_REQUEST, "Invalid provider_uuid or identity_uuid.") except VolumeAttachConflict as exc: message = exc.message return failure_response(status.HTTP_409_CONFLICT, message) except ConnectionFailure: return connection_failure(provider_uuid, identity_uuid) except InvalidCredsError: return invalid_creds(provider_uuid, identity_uuid)
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): """ 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 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 get(self, request, provider_uuid, identity_uuid, instance_id): """ Authentication Required, get instance details. """ 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: 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 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: 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 delete(self, request, provider_id, identity_id, instance_id): """Authentication Required, TERMINATE the instance. Be careful, there is no going back once you've deleted an instance. """ user = request.user esh_driver = prepare_driver(request, provider_id, identity_id) if not esh_driver: return invalid_creds(provider_id, identity_id) try: esh_instance = esh_driver.get_instance(instance_id) if not esh_instance: return instance_not_found(instance_id) task.destroy_instance_task(esh_instance, identity_id) existing_instance = esh_driver.get_instance(instance_id) if existing_instance: #Instance will be deleted soon... esh_instance = existing_instance if esh_instance.extra\ and 'task' not in esh_instance.extra: esh_instance.extra['task'] = 'queueing delete' core_instance = convert_esh_instance(esh_driver, esh_instance, provider_id, identity_id, user) if core_instance: core_instance.end_date_all() else: logger.warn("Unable to find core instance %s." % (instance_id)) serialized_data = InstanceSerializer(core_instance, context={"request":request}).data response = Response(serialized_data, status=status.HTTP_200_OK) response['Cache-Control'] = 'no-cache' return response except ConnectionFailure: return connection_failure(provider_id, identity_id) except InvalidCredsError: return invalid_creds(provider_id, identity_id)
def get(self, request, provider_uuid): try: provider = Provider.get_active(provider_uuid) except Provider.DoesNotExist: return failure_response( status.HTTP_404_NOT_FOUND, "The provider does not exist.") admin_driver = get_admin_driver(provider) if not admin_driver: return failure_response( status.HTTP_404_NOT_FOUND, "The driver cannot be retrieved for this provider.") if not hasattr(admin_driver._connection, "ex_hypervisor_statistics"): return failure_response( status.HTTP_404_NOT_FOUND, "Occupancy statistics cannot be retrieved for this provider.") try: stats = admin_driver._connection.ex_hypervisor_statistics() return Response(stats) except (socket_error, ConnectionFailure): return connection_failure(provider_uuid) except Exception as exc: return failure_response(status.HTTP_503_SERVICE_UNAVAILABLE, "Error occurred while retrieving statistics: %s" % exc)
def post(self, request, provider_uuid, identity_uuid, format=None): """ Instance Class: Launches an instance based on the params Returns a single instance Parameters: machine_alias, size_alias, username TODO: Create a 'reverse' using the instance-id to pass the URL for the newly created instance I.e: url = "/provider/1/instance/1/i-12345678" """ data = request.data user = request.user # Check the data is valid missing_keys = valid_post_data(data) if missing_keys: return keys_not_found(missing_keys) # Pass these as args size_alias = data.pop("size_alias") machine_alias = data.pop("machine_alias") hypervisor_name = data.pop("hypervisor", None) if hypervisor_name: # Previous method passed this with 'None' but that fails now. # This check will only add the ex_ value if it is 'truthy'. data['ex_hypervisor_name'] = hypervisor_name deploy = data.pop("deploy", True) if type(deploy) in [str, unicode] and deploy.lower() == "false": deploy = False elif not isinstance(deploy, bool): deploy = True boot_scripts = data.pop("scripts", []) try: logger.debug(data) core_instance = launch_instance( user, identity_uuid, size_alias, machine_alias, deploy=deploy, **data) except UnderThresholdError as ute: return under_threshold(ute) 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 SecurityGroupNotCreated: return connection_failure(provider_uuid, identity_uuid) 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)) serializer = InstanceSerializer(core_instance, context={"request": request}, data=data) if serializer.is_valid(): instance = serializer.save() if boot_scripts: _save_scripts_to_instance(instance, boot_scripts) return Response(serializer.data, status=status.HTTP_201_CREATED) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
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_uuid, identity_uuid, format=None): """ Instance Class: Launches an instance based on the params Returns a single instance Parameters: machine_alias, size_alias, username TODO: Create a 'reverse' using the instance-id to pass the URL for the newly created instance I.e: url = "/provider/1/instance/1/i-12345678" """ data = request.data user = request.user # Check the data is valid missing_keys = valid_post_data(data) if missing_keys: return keys_not_found(missing_keys) # Pass these as args size_alias = data.pop("size_alias") allocation_source_id = data.pop("allocation_source_id", None) machine_alias = data.pop("machine_alias") hypervisor_name = data.pop("hypervisor", None) if hypervisor_name: # Previous method passed this with 'None' but that fails now. # This check will only add the ex_ value if it is 'truthy'. data['ex_hypervisor_name'] = hypervisor_name deploy = data.pop("deploy", True) if type(deploy) in [str, unicode] and deploy.lower() == "false": deploy = False elif not isinstance(deploy, bool): deploy = True boot_scripts = data.pop("scripts", []) try: logger.debug(data) if not settings.USE_ALLOCATION_SOURCE: allocation_source = None else: allocation_source = AllocationSource.objects.get( source_id=allocation_source_id) core_instance = launch_instance(user, identity_uuid, size_alias, machine_alias, deploy=deploy, **data) except UnderThresholdError as ute: return under_threshold(ute) 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 SecurityGroupNotCreated: return connection_failure(provider_uuid, identity_uuid) 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)) serializer = InstanceSerializer(core_instance, context={"request": request}, data=data) if serializer.is_valid(): instance = serializer.save() if boot_scripts: _save_scripts_to_instance(instance, boot_scripts) instance.change_allocation_source(allocation_source) return Response(serializer.data, status=status.HTTP_201_CREATED) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class VolumeList(APIView): """List all volumes on Identity""" permission_classes = (ApiAuthRequired, ) 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 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, oqe: return over_quota(oqe) except ConnectionFailure: return connection_failure(provider_uuid, identity_uuid)
class VolumeSnapshot(APIView): """ Initialize and view volume snapshots """ permission_classes = (ApiAuthRequired, ) def get(self, request, provider_uuid, identity_uuid): """ """ esh_driver = prepare_driver(request, provider_uuid, identity_uuid) if not esh_driver: return invalid_creds(provider_uuid, identity_uuid) try: esh_snapshots = esh_driver._connection.ex_list_snapshots() except MalformedResponseError: return malformed_response(provider_uuid, identity_uuid) except InvalidCredsError: 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 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) esh_volume = esh_driver.get_volume(volume_id) #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) except ConnectionFailure: return connection_failure(provider_uuid, identity_uuid)
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))
class Instance(APIView): """ Instances are the objects created when you launch a machine. They are represented by a unique ID, randomly generated on launch, important attributes of an Instance are: Name, Status (building, active, suspended), Size, Machine""" #renderer_classes = (JSONRenderer, JSONPRenderer) permission_classes = (ApiAuthRequired, ) def get(self, request, provider_id, identity_id, instance_id): """ Authentication Required, get instance details. """ user = request.user esh_driver = prepare_driver(request, provider_id, identity_id) if not esh_driver: return invalid_creds(provider_id, identity_id) esh_instance = esh_driver.get_instance(instance_id) if not esh_instance: try: core_inst = CoreInstance.objects.get( provider_alias=instance_id, provider_machine__provider__id=provider_id, created_by_identity__id=identity_id) 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_id, identity_id, user) serialized_data = InstanceSerializer(core_instance, context={ "request": request }).data response = Response(serialized_data) response['Cache-Control'] = 'no-cache' return response def patch(self, request, provider_id, identity_id, instance_id): """Authentication Required, update metadata about the instance""" user = request.user data = request.DATA esh_driver = prepare_driver(request, provider_id, identity_id) if not esh_driver: return invalid_creds(provider_id, identity_id) esh_instance = esh_driver.get_instance(instance_id) if not esh_instance: return instance_not_found(instance_id) #Gather the DB related item and update core_instance = convert_esh_instance(esh_driver, esh_instance, provider_id, identity_id, user) serializer = InstanceSerializer(core_instance, data=data, context={"request": request}, partial=True) if serializer.is_valid(): logger.info('metadata = %s' % data) update_instance_metadata(esh_driver, esh_instance, data, replace=False) serializer.save() response = Response(serializer.data) logger.info('data = %s' % serializer.data) response['Cache-Control'] = 'no-cache' return response else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) def put(self, request, provider_id, identity_id, instance_id): """Authentication Required, update metadata about the instance""" user = request.user data = request.DATA #Ensure item exists on the server first esh_driver = prepare_driver(request, provider_id, identity_id) if not esh_driver: return invalid_creds(provider_id, identity_id) esh_instance = esh_driver.get_instance(instance_id) if not esh_instance: return instance_not_found(instance_id) #Gather the DB related item and update core_instance = convert_esh_instance(esh_driver, esh_instance, provider_id, identity_id, user) serializer = InstanceSerializer(core_instance, data=data, context={"request": request}) if serializer.is_valid(): logger.info('metadata = %s' % data) update_instance_metadata(esh_driver, esh_instance, data) serializer.save() response = Response(serializer.data) logger.info('data = %s' % serializer.data) response['Cache-Control'] = 'no-cache' return response else: return Response(serializer.errors, status=status.HTTP_400) def delete(self, request, provider_id, identity_id, instance_id): """Authentication Required, TERMINATE the instance. Be careful, there is no going back once you've deleted an instance. """ user = request.user esh_driver = prepare_driver(request, provider_id, identity_id) if not esh_driver: return invalid_creds(provider_id, identity_id) try: esh_instance = esh_driver.get_instance(instance_id) if not esh_instance: return instance_not_found(instance_id) #Test that there is not an attached volume BEFORE we destroy _check_volume_attachment(esh_driver, esh_instance) task.destroy_instance_task(esh_instance, identity_id) existing_instance = esh_driver.get_instance(instance_id) if existing_instance: #Instance will be deleted soon... esh_instance = existing_instance if esh_instance.extra\ and 'task' not in esh_instance.extra: esh_instance.extra['task'] = 'queueing delete' core_instance = convert_esh_instance(esh_driver, esh_instance, provider_id, identity_id, user) if core_instance: core_instance.end_date_all() else: logger.warn("Unable to find core instance %s." % (instance_id)) serialized_data = InstanceSerializer(core_instance, context={ "request": request }).data response = Response(serialized_data, status=status.HTTP_200_OK) response['Cache-Control'] = 'no-cache' return response except VolumeAttachConflict, exc: message = exc.message return failure_response(status.HTTP_409_CONFLICT, message) except ConnectionFailure: return connection_failure(provider_id, identity_id)
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 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)
logger.debug(data) core_instance = launch_instance( user, provider_uuid, identity_uuid, size_alias, machine_alias, ex_availability_zone=hypervisor_name, deploy=deploy, **data) except UnderThresholdError, ute: return under_threshold(ute) except OverQuotaError, oqe: return over_quota(oqe) except OverAllocationError, oae: return over_quota(oae) except SizeNotAvailable, snae: return size_not_availabe(snae) except SecurityGroupNotCreated: return connection_failure(provider_uuid, identity_uuid) 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)) serializer = InstanceSerializer(core_instance, context={"request": request}, data=data) if serializer.is_valid(): serializer.save()
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)
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, 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))
machine_alias = data.pop('machine_alias') hypervisor_name = data.pop('hypervisor',None) try: core_instance = launch_instance( user, provider_id, identity_id, size_alias, machine_alias, ex_availability_zone=hypervisor_name, **data) except OverQuotaError, oqe: return over_quota(oqe) except OverAllocationError, oae: return over_quota(oae) except SizeNotAvailable, snae: return size_not_availabe(snae) except SecurityGroupNotCreated: return connection_failure(provider_id, identity_id) except ConnectionFailure: return connection_failure(provider_id, identity_id) except InvalidCredsError: return invalid_creds(provider_id, identity_id) except Exception as exc: logger.exception("Encountered a generic exception. " "Returning 409-CONFLICT") return failure_response(status.HTTP_409_CONFLICT, str(exc.message)) serializer = InstanceSerializer(core_instance, context={"request":request}, data=data) #NEVER WRONG if serializer.is_valid():
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 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__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)