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
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.")
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
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)
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)}"' )