Пример #1
0
    def test_convert_config_to_v6_json(self):
        """Tests calling convert_config_to_v6_json()"""

        # Try configuration with nothing set
        config = RecipeConfiguration()
        json = convert_config_to_v6_json(config)
        RecipeConfigurationV6(config=json.get_dict(),
                              do_validate=True)  # Revalidate

        # Try configuration with a variety of values
        config = RecipeConfiguration()
        config.add_mount(HostMountConfig('mount_1', '/the/host/path'))
        config.add_mount(
            VolumeMountConfig('mount_2', 'driver', {
                'opt_1': 'foo',
                'opt_2': 'bar'
            }))
        config.default_output_workspace = 'workspace_1'
        config.add_output_workspace('output_2', 'workspace_2')
        config.priority = 999
        config.add_setting('setting_1', 'Hello')
        config.add_setting('setting_2', 'Scale!')
        json = convert_config_to_v6_json(config)
        RecipeConfigurationV6(config=json.get_dict(),
                              do_validate=True)  # Revalidate
        self.assertSetEqual(set(json.get_dict()['mounts'].keys()),
                            {'mount_1', 'mount_2'})
        self.assertEqual(json.get_dict()['priority'], 999)
        self.assertSetEqual(set(json.get_dict()['settings'].keys()),
                            {'setting_1', 'setting_2'})
Пример #2
0
    def _create_new_recipes(self):
        """Creates the recipe models for a new recipe run
        """
        rt = RecipeType.objects.get(name=self.recipe_type_name)
        if not rt.is_active:
            raise InactiveRecipeType("Recipe Type %s is inactive" % rt.name)

        recipe_type_rev = RecipeTypeRevision.objects.get_revision(
            self.recipe_type_name, self.recipe_type_rev_num)

        config = None
        if self.configuration:
            config = RecipeConfigurationV6(self.configuration)

        with transaction.atomic():
            recipe_input_data = DataV6(self.recipe_input_data).get_data()
            recipe = Recipe.objects.create_recipe_v6(
                recipe_type_rev=recipe_type_rev,
                event_id=self.event_id,
                ingest_id=self.ingest_event_id,
                input_data=recipe_input_data,
                batch_id=self.batch_id,
                recipe_config=config)
            recipe.save()
            self.new_recipes.append(recipe.id)

        recipes = []
        if recipe:
            recipes.append(recipe)

        return recipes
Пример #3
0
    def post(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
        """
        if request.version != 'v6':
            raise Http404

        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))
Пример #4
0
    def merge_recipe_config(self, recipe_config):
        """Merges a recipe configuration object values into this job configuration, overriding any common fields

        :param recipe_config: The recipe config dictionary
        :type recipe_config: dict

        :raises :class:`recipe.configuration.exceptions.InvalidRecipeConfiguration`: If the recipe_config is invalid
        """

        config_to_merge = RecipeConfigurationV6(
            recipe_config).get_configuration()

        if config_to_merge.default_output_workspace:
            self.default_output_workspace = config_to_merge.default_output_workspace

        self.output_workspaces.update(config_to_merge.output_workspaces)

        if config_to_merge.priority:
            self.priority = config_to_merge.priority

        self.mounts.update(config_to_merge.mounts)

        self.settings.update(config_to_merge.settings)
Пример #5
0
    def test_init_validation(self):
        """Tests the validation done in __init__"""

        # Try minimal acceptable configuration
        RecipeConfigurationV6(do_validate=True)

        # Invalid version
        config_dict = {'version': 'BAD'}
        with self.assertRaises(InvalidRecipeConfiguration) as context:
            RecipeConfigurationV6(config_dict, do_validate=True)
            self.assertEqual(context.exception.error.name, 'INVALID_VERSION')

        # Valid v6 configuration
        config_dict = {
            'version': '6',
            'mounts': {
                'mount_1': {
                    'type': 'host',
                    'host_path': '/the/host/path'
                },
                'mount_2': {
                    'type': 'volume',
                    'driver': 'driver',
                    'driver_opts': {
                        'opt_1': 'foo',
                        'opt_2': 'bar'
                    }
                }
            },
            'output_workspaces': {
                'default': 'workspace_1',
                'outputs': {
                    'output': 'workspace_2'
                }
            },
            'priority': 999,
            'settings': {
                'setting_1': '1234',
                'setting_2': '5678'
            }
        }
        existing = RecipeConfigurationV6(config=config_dict, do_validate=True)
        jc = existing.get_configuration()
        vol1 = jc.get_mount_volume('mount_1', 'test1', '/test/path', 'ro')
        self.assertEqual(vol1.name, 'test1')
        self.assertEqual(vol1.container_path, '/test/path')
        self.assertEqual(vol1.mode, 'ro')
        self.assertEqual(vol1.is_host, True)
        self.assertEqual(vol1.host_path, '/the/host/path')
        vol2 = jc.get_mount_volume('mount_2', 'test2', '/test/path', 'ro')
        self.assertEqual(vol2.name, 'test2')
        self.assertEqual(vol2.container_path, '/test/path')
        self.assertEqual(vol2.mode, 'ro')
        self.assertEqual(vol2.is_host, False)
        self.assertEqual(vol2.host_path, None)
        self.assertEqual(vol2.driver, 'driver')
        self.assertDictEqual(vol2.driver_opts, {
            'opt_1': 'foo',
            'opt_2': 'bar'
        })
        self.assertEqual(jc.get_output_workspace('test'), 'workspace_1')
        self.assertEqual(jc.get_output_workspace('output'), 'workspace_2')
        self.assertEqual(jc.priority, 999)
        self.assertEqual(jc.get_setting_value('setting_1'), '1234')
        self.assertEqual(jc.get_setting_value('setting_2'), '5678')

        # Overriding some settings from an existing config
        config_dict = {
            'version': '6',
            'priority': 888,
            'settings': {
                'setting_1': '123',
                'setting_2': '678'
            }
        }
        jc = RecipeConfigurationV6(config=config_dict,
                                   existing=existing,
                                   do_validate=True).get_configuration()
        vol1 = jc.get_mount_volume('mount_1', 'test1', '/test/path', 'ro')
        self.assertEqual(vol1.name, 'test1')
        self.assertEqual(vol1.container_path, '/test/path')
        self.assertEqual(vol1.mode, 'ro')
        self.assertEqual(vol1.is_host, True)
        self.assertEqual(vol1.host_path, '/the/host/path')
        vol2 = jc.get_mount_volume('mount_2', 'test2', '/test/path', 'ro')
        self.assertEqual(vol2.name, 'test2')
        self.assertEqual(vol2.container_path, '/test/path')
        self.assertEqual(vol2.mode, 'ro')
        self.assertEqual(vol2.is_host, False)
        self.assertEqual(vol2.host_path, None)
        self.assertEqual(vol2.driver, 'driver')
        self.assertDictEqual(vol2.driver_opts, {
            'opt_1': 'foo',
            'opt_2': 'bar'
        })
        self.assertEqual(jc.get_output_workspace('test'), 'workspace_1')
        self.assertEqual(jc.get_output_workspace('output'), 'workspace_2')
        self.assertEqual(jc.priority, 888)
        self.assertEqual(jc.get_setting_value('setting_1'), '123')
        self.assertEqual(jc.get_setting_value('setting_2'), '678')