def create(self, request): """Creates a new Workspace and returns it in JSON form :param request: the HTTP POST request :type request: :class:`rest_framework.request.Request` :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ name = rest_util.parse_string(request, 'name') title = rest_util.parse_string(request, 'title', required=False) description = rest_util.parse_string(request, 'description', required=False) json_config = rest_util.parse_dict(request, 'json_config') base_url = rest_util.parse_string(request, 'base_url', required=False) is_active = rest_util.parse_bool(request, 'is_active', default_value=True, required=False) try: workspace = Workspace.objects.create_workspace(name, title, description, json_config, base_url, is_active) except InvalidWorkspaceConfiguration as ex: logger.exception('Unable to create new workspace: %s', name) raise BadParameter(unicode(ex)) # Fetch the full workspace with details try: workspace = Workspace.objects.get_details(workspace.id) except Workspace.DoesNotExist: raise Http404 serializer = WorkspaceDetailsSerializer(workspace) workspace_url = urlresolvers.reverse('workspace_details_view', args=[workspace.id]) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=dict(location=workspace_url))
def create(self, request): """Creates a new Strike process and returns a link to the detail URL :param request: the HTTP POST request :type request: :class:`rest_framework.request.Request` :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ name = rest_util.parse_string(request, 'name') title = rest_util.parse_string(request, 'title', required=False) description = rest_util.parse_string(request, 'description', required=False) configuration = rest_util.parse_dict(request, 'configuration') try: strike = Strike.objects.create_strike(name, title, description, configuration) except InvalidStrikeConfiguration as ex: raise BadParameter('Strike configuration invalid: %s' % unicode(ex)) # Fetch the full strike process with details try: strike = Strike.objects.get_details(strike.id) except Strike.DoesNotExist: raise Http404 serializer = StrikeDetailsSerializer(strike) strike_url = reverse('strike_details_view', args=[strike.id], request=request) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=dict(location=strike_url))
def post(self, request): """Validates a new Strike process and returns any warnings discovered :param request: the HTTP POST request :type request: :class:`rest_framework.request.Request` :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ name = rest_util.parse_string(request, 'name') configuration = rest_util.parse_dict(request, 'configuration') rest_util.parse_string(request, 'title', required=False) rest_util.parse_string(request, 'description', required=False) # Validate the Strike configuration try: config = StrikeConfiguration(configuration) warnings = config.validate() except InvalidStrikeConfiguration as ex: logger.exception('Unable to validate new Strike process: %s', name) raise BadParameter(unicode(ex)) results = [{'id': w.key, 'details': w.details} for w in warnings] return Response({'warnings': results})
def patch(self, request, scan_id): """Edits an existing Scan process and returns the updated details :param request: the HTTP GET request :type request: :class:`rest_framework.request.Request` :param scan_id: The ID of the Scan process :type scan_id: int encoded as a str :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ title = rest_util.parse_string(request, 'title', required=False) description = rest_util.parse_string(request, 'description', required=False) configuration = rest_util.parse_dict(request, 'configuration', required=False) try: Scan.objects.edit_scan(scan_id, title, description, configuration) scan = Scan.objects.get_details(scan_id) except Scan.DoesNotExist: raise Http404 except InvalidScanConfiguration as ex: logger.exception('Unable to edit Scan process: %s', scan_id) raise BadParameter(unicode(ex)) serializer = self.get_serializer(scan) return Response(serializer.data)
def create(self, request): """Creates a new Scan process and returns a link to the detail URL :param request: the HTTP POST request :type request: :class:`rest_framework.request.Request` :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ name = rest_util.parse_string(request, 'name') title = rest_util.parse_string(request, 'title', required=False) description = rest_util.parse_string(request, 'description', required=False) configuration = rest_util.parse_dict(request, 'configuration') try: scan = Scan.objects.create_scan(name, title, description, configuration) except InvalidScanConfiguration as ex: raise BadParameter('Scan configuration invalid: %s' % unicode(ex)) serializer = ScanDetailsSerializer(scan) scan_url = reverse('scans_details_view', args=[scan.id], request=request) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=dict(location=scan_url))
def patch_impl_v6(self, request, strike_id): """Edits an existing Strike process and returns the updated details :param request: the HTTP GET request :type request: :class:`rest_framework.request.Request` :param strike_id: The ID of the Strike process :type strike_id: int encoded as a str :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ title = rest_util.parse_string(request, 'title', required=False) description = rest_util.parse_string(request, 'description', required=False) configuration = rest_util.parse_dict(request, 'configuration', required=False) try: Strike.objects.edit_strike_v6(strike_id, title, description, configuration) except Strike.DoesNotExist: raise Http404 except InvalidStrikeConfiguration as ex: logger.exception('Unable to edit Strike process: %s', strike_id) raise BadParameter(unicode(ex)) return Response(status=status.HTTP_204_NO_CONTENT)
def post(self, request): """Validates a new workspace and returns any warnings discovered :param request: the HTTP POST request :type request: :class:`rest_framework.request.Request` :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ name = rest_util.parse_string(request, 'name') json_config = rest_util.parse_dict(request, 'json_config') rest_util.parse_string(request, 'title', required=False) rest_util.parse_string(request, 'description', required=False) rest_util.parse_string(request, 'base_url', required=False) rest_util.parse_string(request, 'is_active', required=False) # Validate the workspace configuration try: warnings = Workspace.objects.validate_workspace(name, json_config) except InvalidWorkspaceConfiguration as ex: logger.exception('Unable to validate new workspace: %s', name) raise BadParameter(unicode(ex)) results = [{'id': w.key, 'details': w.details} for w in warnings] return Response({'warnings': results})
def patch(self, request, workspace_id): """Edits an existing workspace and returns the updated details :param request: the HTTP GET request :type request: :class:`rest_framework.request.Request` :param workspace_id: The ID for the workspace. :type workspace_id: int encoded as a str :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ title = rest_util.parse_string(request, 'title', required=False) description = rest_util.parse_string(request, 'description', required=False) json_config = rest_util.parse_dict(request, 'json_config', required=False) base_url = rest_util.parse_string(request, 'base_url', required=False) is_active = rest_util.parse_string(request, 'is_active', required=False) try: Workspace.objects.edit_workspace(workspace_id, title, description, json_config, base_url, is_active) workspace = Workspace.objects.get_details(workspace_id) except Workspace.DoesNotExist: raise Http404 except InvalidWorkspaceConfiguration as ex: logger.exception('Unable to edit workspace: %s', workspace_id) raise BadParameter(unicode(ex)) serializer = self.get_serializer(workspace) return Response(serializer.data)
def post(self, request, recipe_id): """Schedules a recipe for reprocessing and returns it in JSON form :param request: the HTTP GET request :type request: :class:`rest_framework.request.Request` :param recipe_id: The id of the recipe :type recipe_id: int encoded as a str :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ job_names = rest_util.parse_string_list(request, 'job_names', required=False) all_jobs = rest_util.parse_bool(request, 'all_jobs', required=False) try: handler = Recipe.objects.reprocess_recipe(recipe_id, job_names, all_jobs) except Recipe.DoesNotExist: raise Http404 except ReprocessError as err: raise BadParameter(unicode(err)) try: new_recipe = Recipe.objects.get_details(handler.recipe.id) except Recipe.DoesNotExist: raise Http404 url = urlresolvers.reverse('recipe_details_view', args=[new_recipe.id]) serializer = self.get_serializer(new_recipe) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=dict(location=url))
def post(self, request): """Creates a new error and returns a link to the info URL :param request: the HTTP POST request :type request: :class:`rest_framework.request.Request` :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ name = rest_util.parse_string(request, 'name') title = rest_util.parse_string(request, 'title') description = rest_util.parse_string(request, 'description') category = rest_util.parse_string( request, 'category', accepted_values=[c for c, _ in Error.CATEGORIES]) # Do not allow the creation of SYSTEM level errors if category == 'SYSTEM': raise BadParameter('System level errors cannot be created.') error = Error.objects.create_error(name, title, description, category) serializer = ErrorDetailsSerializer(error) error_url = urlresolvers.reverse('error_details_view', args=[error.id]) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=dict(location=error_url))
def patch_impl_v6(self, request, strike_id): """Edits an existing Strike process and returns the updated details :param request: the HTTP GET request :type request: :class:`rest_framework.request.Request` :param strike_id: The ID of the Strike process :type strike_id: int encoded as a str :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ title = rest_util.parse_string(request, 'title', required=False) description = rest_util.parse_string(request, 'description', required=False) configuration = rest_util.parse_dict(request, 'configuration', required=False) config = None try: if configuration: config = StrikeConfigurationV6(configuration, do_validate=True).get_configuration() except InvalidStrikeConfiguration as ex: raise BadParameter('Strike configuration invalid: %s' % unicode(ex)) try: # must collect old config before editing strike if config: new_config = config.get_dict() old_config = Strike.objects.get_details(strike_id) Strike.objects.edit_strike(strike_id, title, description, config) # if workspace has changed strike job must be restarted for changes to take effect if config and old_config.configuration["workspace"] != new_config["workspace"]: strike_job = old_config.job Job.objects.update_jobs_to_canceled([strike_job], timezone.now()) requeue_jobs = [] requeue_jobs.append(QueuedJob(strike_job.id, strike_job.num_exes)) msg = create_requeue_jobs_messages(requeue_jobs) CommandMessageManager().send_messages(msg) except Strike.DoesNotExist: raise Http404 except InvalidStrikeConfiguration as ex: logger.exception('Unable to edit Strike process: %s', strike_id) raise BadParameter(unicode(ex)) return Response(status=status.HTTP_204_NO_CONTENT)
def patch_v6(self, request, name): """Edits an existing recipe type and returns the updated details :param request: the HTTP GET request :type request: :class:`rest_framework.request.Request` :param name: The name of the recipe type :type name: string :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ title = rest_util.parse_string(request, 'title', required=False) description = rest_util.parse_string(request, 'description', required=False) definition_dict = rest_util.parse_dict(request, 'definition', required=False) auto_update = rest_util.parse_bool(request, 'auto_update', required=False, default_value=True) is_active = rest_util.parse_bool(request, 'is_active', required=False) # Fetch the current recipe type model try: recipe_type = RecipeType.objects.filter(name=name).first() except RecipeType.DoesNotExist: raise Http404 try: with transaction.atomic(): # Validate the recipe definition recipe_def = None if definition_dict: recipe_def = RecipeDefinitionV6( definition=definition_dict, do_validate=True).get_definition() # Edit the recipe type validation = RecipeType.objects.edit_recipe_type_v6( recipe_type_id=recipe_type.id, title=title, description=description, definition=recipe_def, auto_update=auto_update, is_active=is_active) except InvalidDefinition as ex: logger.exception('Unable to update recipe type: %s', name) raise BadParameter(unicode(ex)) resp_dict = { 'is_valid': validation.is_valid, 'errors': [e.to_dict() for e in validation.errors], 'warnings': [w.to_dict() for w in validation.warnings], 'diff': validation.diff } return Response(resp_dict)
def create_v6(self, request): """Creates or edits a dataset and returns a link to the detail URL :param request: the HTTP POST request :type request: :class:`rest_framework.request.Request` :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ title = rest_util.parse_string(request, 'title', required=False) description = rest_util.parse_string(request, 'description', required=False) definition = rest_util.parse_dict(request, 'definition', required=True) # validate the definition try: dataset_def = DataSetDefinitionV6( definition=definition, do_validate=True).get_definition() except InvalidDataSetDefinition as ex: message = 'DataSet definition is invalid' logger.exception(message) raise BadParameter('%s: %s' % (message, unicode(ex))) try: dataset = DataSet.objects.create_dataset_v6( dataset_def, title=title, description=description) except Exception as ex: message = 'Unable to create new dataset' logger.exception(message) raise BadParameter('%s: %s' % (message, unicode(ex))) try: dataset = DataSet.objects.get_details_v6(dataset.id) except DataSet.DoesNotExist: raise Http404 url = reverse('dataset_details_view', args=[dataset.id], request=request) serializer = DataSetDetailsSerializerV6(dataset) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=dict(location=url))
def _create_v6(self, request): """Creates a new recipe type and returns a link to the detail URL :param request: the HTTP POST request :type request: :class:`rest_framework.request.Request` :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ title = rest_util.parse_string(request, 'title', required=True) description = rest_util.parse_string(request, 'description', required=False) definition_dict = rest_util.parse_dict(request, 'definition', required=True) basename = title_to_basename(title) if basename == 'validation': logger.exception('Unable to create recipe type named "validation"') raise BadParameter(unicode('Unable to create recipe type named "validation"')) existing_recipes = RecipeType.objects.filter(name=basename) if existing_recipes.count() > 0: logger.exception('Existing recipe types found for %s - will not re-create.', basename) raise BadParameter(unicode('Existing recipe types found for %s - will not re-create. Please change the title or patch the existing recipe type.' % basename)) name = title_to_name(self.queryset, title) try: with transaction.atomic(): # Validate the recipe definition recipe_def = RecipeDefinitionV6(definition=definition_dict, do_validate=True).get_definition() # Create the recipe type recipe_type = RecipeType.objects.create_recipe_type_v6(name, title, description, recipe_def) except InvalidDefinition as ex: logger.exception('Unable to create new recipe type: %s', name) raise BadParameter(unicode(ex)) # Fetch the full recipe type with details try: recipe_type = RecipeType.objects.get_details_v6(recipe_type.name) except RecipeType.DoesNotExist: raise Http404 url = reverse('recipe_type_details_view', args=[recipe_type.name], request=request) serializer = RecipeTypeDetailsSerializerV6(recipe_type) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=dict(location=url))
def _post_v6(self, request): """Queue a recipe and returns the new job information in JSON form :param request: the HTTP POST request :type request: :class:`rest_framework.request.Request` :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ recipe_type_id = rest_util.parse_int(request, 'recipe_type_id') recipe_data = rest_util.parse_dict(request, 'input', {}) configuration_dict = rest_util.parse_dict(request, 'configuration', required=False) configuration = None try: recipeData = DataV6(recipe_data, do_validate=True) except InvalidData as ex: logger.exception('Unable to queue new recipe. Invalid input: %s', recipe_data) raise BadParameter(unicode(ex)) try: recipe_type = RecipeType.objects.get(pk=recipe_type_id) except RecipeType.DoesNotExist: raise Http404 if configuration_dict: try: configuration = RecipeConfigurationV6(configuration_dict, do_validate=True).get_configuration() except InvalidRecipeConfiguration as ex: message = 'Recipe configuration invalid' logger.exception(message) raise BadParameter('%s: %s' % (message, unicode(ex))) try: recipe = Queue.objects.queue_new_recipe_for_user_v6(recipe_type, recipeData.get_data(), recipe_config=configuration) except (InvalidData, InvalidRecipeData) as err: return Response('Invalid recipe data: ' + unicode(err), status=status.HTTP_400_BAD_REQUEST) except InactiveRecipeType as err: return Response('Inactive recipe type: ' + unicode(err), status=status.HTTP_400_BAD_REQUEST) serializer = RecipeSerializerV6(recipe) recipe_url = reverse('recipe_details_view', args=[recipe.id], request=request) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=dict(location=recipe_url))
def post(self, request): """Submit command message to re-queue jobs that fit the given filter criteria :param request: the HTTP GET request :type request: :class:`rest_framework.request.Request` :returns: the HTTP response to send back to the user """ started = rest_util.parse_timestamp(request, 'started', required=False) ended = rest_util.parse_timestamp(request, 'ended', required=False) rest_util.check_time_range(started, ended) error_categories = rest_util.parse_string_list(request, 'error_categories', required=False) error_ids = rest_util.parse_int_list(request, 'error_ids', required=False) job_ids = rest_util.parse_int_list(request, 'job_ids', required=False) job_status = rest_util.parse_string(request, 'status', required=False) job_type_ids = rest_util.parse_int_list(request, 'job_type_ids', required=False) priority = rest_util.parse_int(request, 'priority', required=False) job_type_names = rest_util.parse_string_list(request, 'job_type_names', required=False) batch_ids = rest_util.parse_int_list(request, 'batch_ids', required=False) recipe_ids = rest_util.parse_int_list(request, 'recipe_ids', required=False) is_superseded = rest_util.parse_bool(request, 'is_superseded', required=False) job_types = rest_util.parse_dict_list(request, 'job_types', required=False) for jt in job_types: if 'name' not in jt or 'version' not in jt: raise BadParameter('Job types argument invalid: %s' % job_types) existing_job_type = JobType.objects.filter(name=jt['name'], version=jt['version']).first() if not existing_job_type: raise BadParameter( 'Job Type with name: %s and version: %s does not exist' % (jt['name'], jt['version'])) job_type_ids.append(existing_job_type.id) # Create and send message msg = create_requeue_jobs_bulk_message(started=started, ended=ended, error_categories=error_categories, error_ids=error_ids, job_ids=job_ids, job_type_ids=job_type_ids, priority=priority, status=job_status, job_type_names=job_type_names, batch_ids=batch_ids, recipe_ids=recipe_ids, is_superseded=is_superseded) CommandMessageManager().send_messages([msg]) return Response(status=status.HTTP_202_ACCEPTED)
def _patch_v6(self, request, workspace_id): """Edits an existing workspace and returns the updated details :param request: the HTTP GET request :type request: :class:`rest_framework.request.Request` :param workspace_id: The ID for the workspace. :type workspace_id: int encoded as a str :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ title = rest_util.parse_string(request, 'title', required=False) description = rest_util.parse_string(request, 'description', required=False) json = rest_util.parse_dict(request, 'configuration', required=False) base_url = rest_util.parse_string(request, 'base_url', required=False) is_active = rest_util.parse_string(request, 'is_active', required=False) configuration = None if json: try: configuration = WorkspaceConfigurationV6( json, do_validate=True).get_configuration() except InvalidWorkspaceConfiguration as ex: message = 'Workspace configuration invalid' logger.exception(message) raise BadParameter('%s: %s' % (message, unicode(ex))) try: Workspace.objects.edit_workspace(workspace_id, title, description, configuration, base_url, is_active) except Workspace.DoesNotExist: raise Http404 except InvalidWorkspaceConfiguration as ex: logger.exception('Unable to edit workspace: %s', workspace_id) raise BadParameter(unicode(ex)) return HttpResponse(status=204)
def create(self, request): """Creates a new batch and returns a link to the detail URL :param request: the HTTP POST request :type request: :class:`rest_framework.request.Request` :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ recipe_type_id = rest_util.parse_int(request, 'recipe_type_id') title = rest_util.parse_string(request, 'title', required=False) description = rest_util.parse_string(request, 'description', required=False) # Make sure the recipe type exists try: recipe_type = RecipeType.objects.get(pk=recipe_type_id) except RecipeType.DoesNotExist: raise BadParameter('Unknown recipe type: %i' % recipe_type_id) # Validate the batch definition definition_dict = rest_util.parse_dict(request, 'definition') definition = None try: if definition_dict: definition = BatchDefinition(definition_dict) definition.validate(recipe_type) except InvalidDefinition as ex: raise BadParameter('Batch definition invalid: %s' % unicode(ex)) # Create the batch batch = Batch.objects.create_batch(recipe_type, definition, title=title, description=description) # Fetch the full batch with details try: batch = Batch.objects.get_details(batch.id) except Batch.DoesNotExist: raise Http404 url = reverse('batch_details_view', args=[batch.id], request=request) serializer = BatchDetailsSerializer(batch) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=dict(location=url))
def _patch_v5(self, request, error_id): """Edits an existing error and returns the updated model :param request: the HTTP PATCH request :type request: :class:`rest_framework.request.Request` :param error_id: The id of the error :type error_id: int encoded as a str :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ try: error = Error.objects.get(pk=error_id) except Error.DoesNotExist: raise Http404 # Do not allow editing of SYSTEM level errors if error.category == 'SYSTEM': raise BadParameter('System level errors cannot be edited.') title = rest_util.parse_string(request, 'title', required=False) description = rest_util.parse_string(request, 'description', required=False) category = rest_util.parse_string( request, 'category', required=False, accepted_values=[c for c, _ in Error.CATEGORIES]) # Do not allow editing of SYSTEM level errors if category == 'SYSTEM': raise BadParameter('Errors cannot be changed to system level.') error.title = title or error.title error.description = description or error.description error.category = category or error.category error.save() serializer = self.get_serializer(error) return Response(serializer.data)
def patch_impl(self, request, strike_id): """Edits an existing Strike process and returns the updated details :param request: the HTTP GET request :type request: :class:`rest_framework.request.Request` :param strike_id: The ID of the Strike process :type strike_id: int encoded as a str :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ title = rest_util.parse_string(request, 'title', required=False) description = rest_util.parse_string(request, 'description', required=False) configuration = rest_util.parse_dict(request, 'configuration', required=False) config = None try: if configuration: config = StrikeConfigurationV2( configuration, do_validate=True).get_configuration() except InvalidStrikeConfiguration as ex: raise BadParameter('Strike configuration invalid: %s' % unicode(ex)) try: Strike.objects.edit_strike(strike_id, title, description, config) strike = Strike.objects.get_details(strike_id) except Strike.DoesNotExist: raise Http404 except InvalidStrikeConfiguration as ex: logger.exception('Unable to edit Strike process: %s', strike_id) raise BadParameter(unicode(ex)) serializer = self.get_serializer(strike) return Response(serializer.data)
def _create_v6(self, request): """Creates a new Workspace and returns it in JSON form :param request: the HTTP POST request :type request: :class:`rest_framework.request.Request` :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ title = rest_util.parse_string(request, 'title', required=True) name = title_to_name(self.queryset, title) description = rest_util.parse_string(request, 'description', required=False) json = rest_util.parse_dict(request, 'configuration') base_url = rest_util.parse_string(request, 'base_url', required=False) is_active = rest_util.parse_bool(request, 'is_active', default_value=True, required=False) configuration = None if json: try: configuration = WorkspaceConfigurationV6(json, do_validate=True).get_configuration() except InvalidWorkspaceConfiguration as ex: message = 'Workspace configuration invalid' logger.exception(message) raise BadParameter('%s: %s' % (message, unicode(ex))) try: workspace = Workspace.objects.create_workspace(name, title, description, configuration, base_url, is_active) except InvalidWorkspaceConfiguration as ex: logger.exception('Unable to create new workspace: %s', name) raise BadParameter(unicode(ex)) # Fetch the full workspace with details try: workspace = Workspace.objects.get_details(workspace.id) except Workspace.DoesNotExist: raise Http404 serializer = WorkspaceDetailsSerializerV6(workspace) workspace_url = reverse('workspace_details_view', args=[workspace.id], request=request) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=dict(location=workspace_url))
def _post_v5(self, request): """The v5 version for validating a new batch :param request: the HTTP POST request :type request: :class:`rest_framework.request.Request` :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ recipe_type_id = rest_util.parse_int(request, 'recipe_type_id') # Make sure the recipe type exists try: recipe_type = RecipeType.objects.get(pk=recipe_type_id) except RecipeType.DoesNotExist: raise BadParameter('Unknown recipe type: %i' % recipe_type_id) # Validate the batch definition definition_dict = rest_util.parse_dict(request, 'definition') definition = None warnings = [] try: if definition_dict: definition = OldBatchDefinition(definition_dict) warnings = definition.validate(recipe_type) except InvalidDefinition as ex: raise BadParameter('Batch definition invalid: %s' % unicode(ex)) # Get a rough estimate of how many recipes/files will be affected old_recipes = Batch.objects.get_matched_recipes( recipe_type, definition) old_files = Batch.objects.get_matched_files(recipe_type, definition) return Response({ 'recipe_count': old_recipes.count(), 'file_count': old_files.count(), 'warnings': warnings, })
def _patch_v6(self, request, scan_id): """Edits an existing Scan process and returns the updated details :param request: the HTTP GET request :type request: :class:`rest_framework.request.Request` :param scan_id: The ID of the Scan process :type scan_id: int encoded as a str :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ title = rest_util.parse_string(request, 'title', required=False) description = rest_util.parse_string(request, 'description', required=False) configuration = rest_util.parse_dict(request, 'configuration', required=False) config = None try: if configuration: config = ScanConfigurationV6( configuration, do_validate=True).get_configuration() except InvalidScanConfiguration as ex: raise BadParameter('Scan configuration invalid: %s' % unicode(ex)) try: Scan.objects.edit_scan(scan_id, title, description, config) except Scan.DoesNotExist: raise Http404 except InvalidScanConfiguration as ex: logger.exception('Unable to edit Scan process: %s', scan_id) raise BadParameter(unicode(ex)) return Response(status=status.HTTP_204_NO_CONTENT)
def post(self, request, *args, **kwargs): if request.version != 'v5': raise Http404() file_name = None file_content = None # Check whether AJAX or a standard encoded form was used if request.is_ajax(): # File name must be provided by an HTTP header if 'HTTP_X_FILE_NAME' not in request.META: return Response('Missing HTTP header for file name.', status=status.HTTP_400_BAD_REQUEST) file_name = request.META['HTTP_X_FILE_NAME'] file_content = request else: # File content must be already processed by the request if len(request.data) != 1: return Response('Missing embedded file content.', status=status.HTTP_400_BAD_REQUEST) file_handle = request.data.values()[0] file_name = file_handle.name file_content = file_handle # Make sure the file type is supported if not file_name or not file_content: return Response('Missing file attachment.', status=status.HTTP_400_BAD_REQUEST) if os.path.splitext(file_name)[1] not in ['.json']: return Response('Unsupported file type.', status=status.HTTP_400_BAD_REQUEST) # Attempt to parse the file content # TODO: Add buffer overflow protection import_dict = json.loads(file_content.read()) # Attempt to apply the configuration try: warnings = importer.import_config(import_dict) except InvalidConfiguration as ex: logger.exception('Unable to import configuration.') raise BadParameter(unicode(ex)) results = [{'id': w.key, 'details': w.details} for w in warnings] return Response({'warnings': results})
def post(self, request): """Imports job and recipe configuration and updates the corresponding models. :param request: the HTTP POST request :type request: :class:`rest_framework.request.Request` :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ import_dict = rest_util.parse_dict(request, 'import') try: warnings = importer.import_config(import_dict) except InvalidConfiguration as ex: logger.exception('Unable to import configuration.') raise BadParameter(unicode(ex)) results = [{'id': w.key, 'details': w.details} for w in warnings] return Response({'warnings': results})
def post(self, request): """Creates and queues the specified number of Scale Roulette jobs :param request: the HTTP POST request :type request: :class:`rest_framework.request.Request` :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ num = rest_util.parse_int(request, 'num') if num < 1: raise BadParameter('num must be at least 1') # TODO: in the future, send command message to do this asynchronously job_type = JobType.objects.get(name='scale-roulette', version='1.0') for _ in xrange(num): Queue.objects.queue_new_job_for_user(job_type, {}) return Response(status=status.HTTP_202_ACCEPTED)
def _post_v5(self, request): """Validates a new Scan process and returns any warnings discovered :param request: the HTTP POST request :type request: :class:`rest_framework.request.Request` :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ configuration = rest_util.parse_dict(request, 'configuration') # Validate the Scan configuration try: config = ScanConfigurationV1(configuration).get_configuration() warnings = config.validate() except InvalidScanConfiguration as ex: logger.exception('Unable to validate Scan configuration.') raise BadParameter(unicode(ex)) results = [{'id': w.key, 'details': w.details} for w in warnings] return Response({'warnings': results})
def _update_v6(self, request, batch_id): """The v6 version for updating a batch :param request: the HTTP PATCH request :type request: :class:`rest_framework.request.Request` :param batch_id: the batch id :type batch_id: int :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ title = rest_util.parse_string(request, 'title', required=False) description = rest_util.parse_string(request, 'description', required=False) configuration_dict = rest_util.parse_dict(request, 'configuration', required=False) try: batch = Batch.objects.get(id=batch_id) except Batch.DoesNotExist: raise Http404() # Validate and create the batch try: configuration = None if configuration_dict: configuration_json = BatchConfigurationV6( configuration=configuration_dict, do_validate=True) configuration = configuration_json.get_configuration() Batch.objects.edit_batch_v6(batch, title=title, description=description, configuration=configuration) except InvalidConfiguration as ex: raise BadParameter('Batch configuration invalid: %s' % unicode(ex)) return Response(status=status.HTTP_204_NO_CONTENT)
def post(self, request): '''Creates a new Strike process and returns its ID in JSON form :param request: the HTTP POST request :type request: :class:`rest_framework.request.Request` :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user ''' name = rest_util.parse_string(request, 'name') title = rest_util.parse_string(request, 'title', required=False) description = rest_util.parse_string(request, 'description', required=False) configuration = rest_util.parse_dict(request, 'configuration') try: strike = Strike.objects.create_strike_process( name, title, description, configuration) except InvalidStrikeConfiguration: raise BadParameter('Configuration failed to validate.') return Response({'strike_id': strike.id})
def queue_casino_recipes(self, request): """Creates and queues the specified number of Scale Casino recipes :param request: the HTTP POST request :type request: :class:`rest_framework.request.Request` :rtype: :class:`rest_framework.response.Response` :returns: the HTTP response to send back to the user """ num = rest_util.parse_int(request, 'num') if num < 1: raise BadParameter('num must be at least 1') # TODO: in the future, send command message to do this asynchronously recipe_type = RecipeType.objects.get(name='scale-casino', version='1.0') for _ in xrange(num): Queue.objects.queue_new_recipe_for_user(recipe_type, LegacyRecipeData()) return Response(status=status.HTTP_202_ACCEPTED)