예제 #1
0
def validate_operational_options(workflow_type, parsed_options):
    """Validate and return  workflow operational options.

    :param workflow_type: A supported workflow specification type.
    :param parsed_options: A dict with the parsed operational parameters.
    :returns: A dictionary which represents the valid workflow specification.
    """
    if not isinstance(parsed_options, dict):
        raise REANAValidationError(
            "==> ERROR: Operational options must be a dictionary."
        )
    elif not parsed_options:
        return parsed_options

    validated_options = copy.deepcopy(parsed_options)
    for option in parsed_options.keys():
        if option not in available_options:
            raise REANAValidationError(
                '==> ERROR: Operational option "{0}" not supported.'.format(option)
            )
        translation = available_options[option].get(workflow_type)
        if not translation:
            raise REANAValidationError(
                '==> ERROR: Operational option "{0}" not supported for'
                " {1} workflows.".format(option, workflow_type)
            )
        # Override engine specific options
        if translation not in available_options:
            validated_options[translation] = validated_options[option]
            del validated_options[option]

    return validated_options
예제 #2
0
def snakemake_validate(workflow_file: str, configfiles: List[str]):
    """Validate Snakemake workflow specification.

    :param workflow_file: A specification file compliant with
        `snakemake` workflow specification.
    :type workflow_file: string
    :param configfiles: List of config files paths.
    :type configfiles: List
    """
    valid = snakemake(
        snakefile=workflow_file,
        configfiles=configfiles,
        dryrun=True,
        quiet=True,
    )
    if not valid:
        raise REANAValidationError("Snakemake specification is invalid.")
예제 #3
0
def validate_workspace(
    workspace_option: str,
    available_paths: List[str] = list(WORKSPACE_PATHS.values())
) -> str:
    """Validate and return workspace.

    :param workspace_option: A string of the workspace to validate.
    :type workspace_option: string
    :param available_paths: A list of the available workspaces.
    :type available_paths: list
    :returns: A string of the validated workspace.
    """
    if workspace_option:
        available = any(
            os.path.join(os.path.abspath(workspace_option), "").startswith(
                os.path.join(os.path.abspath(path), ""))
            for path in available_paths)
        if not available:
            raise REANAValidationError(
                f'Desired workspace "{workspace_option}" not valid.\n'
                "Please run `reana-client info` to see the list of allowed prefix values."
            )
    return workspace_option
예제 #4
0
    def validate_parameters(self):
        """Validate input parameters for CWL workflows."""
        def _check_dangerous_operations(workflow):
            """Check for "baseCommand" and "arguments" in workflow.

            If these keys are found, validate if they have dangerous operations.
            """
            cmd_keys = ["baseCommand", "arguments"]
            for cmd_key in cmd_keys:
                if cmd_key in workflow:
                    commands = (workflow[cmd_key] if isinstance(
                        workflow[cmd_key], list) else [workflow[cmd_key]])
                    self._validate_dangerous_operations(
                        commands, step=workflow.get("id"))

        from reana_commons.utils import run_command

        cwl_main_spec_path = self.reana_yaml["workflow"].get("file")
        if os.path.exists(cwl_main_spec_path):
            run_command(
                "cwltool --validate --strict {}".format(cwl_main_spec_path),
                display=False,
                return_output=True,
                stderr_output=True,
            )
        else:
            raise REANAValidationError(
                "Workflow path {} is not valid.".format(cwl_main_spec_path))

        workflow = self.specification.get("$graph", self.specification)

        if isinstance(workflow, dict):
            _check_dangerous_operations(workflow)
        elif isinstance(workflow, list):
            for wf in workflow:
                _check_dangerous_operations(wf)
예제 #5
0
 def raise_error(self, compute_backend: str, step_name: str) -> None:
     """Raise validation error."""
     raise REANAValidationError(
         f'Compute backend "{compute_backend}" found in step "{step_name}" is not supported. '
         f'List of supported compute backends: "{", ".join(self.supported_backends)}"'
     )