def test_update_workflow_invalid_new_workflow(self): from walkoff.executiondb.schemas import WorkflowSchema from walkoff.executiondb import ExecutionDatabase playbook = execution_db_help.standard_load() workflow = playbook.workflows[0] expected_json = WorkflowSchema().dump(workflow) expected_json['name'] = self.change_workflow_name expected_json['actions'][0]['action_name'] = 'invalid' expected_json.pop('is_valid') response = self.put_with_status_check('/api/workflows', data=json.dumps(expected_json), headers=self.headers, content_type='application/json') response.pop('is_valid') errors = response['actions'][0].pop('errors') self.assertEqual(len(errors), 1) self.assertDictEqual(response, expected_json) self.assertIsNotNone( ExecutionDatabase.instance.session.query(Workflow).filter_by( id=workflow.id).first()) self.assertIsNone( ExecutionDatabase.instance.session.query(Workflow).join( Workflow.playbook).filter( Workflow.name == self.add_workflow_name).first())
def test_copy_workflow(self): playbook = execution_db_help.standard_load() for workflow in playbook.workflows: workflow_id = workflow.id response = self.post_with_status_check('/api/workflows?source={0}'.format(workflow_id), headers=self.headers, status_code=OBJECT_CREATED, data=json.dumps( {'name': self.add_workflow_name, 'playbook_id': str(playbook.id)}), content_type="application/json") self.assertEqual(len(playbook.workflows), 2) for workflow in playbook.workflows: self.assertIn(workflow.name, ['helloWorldWorkflow', self.add_workflow_name]) if workflow.name == 'helloWorldWorkflow': workflow_original = workflow elif workflow.name == self.add_workflow_name: workflow_copy = workflow copy_workflow_json = WorkflowSchema().dump(workflow_copy) original_workflow_json = WorkflowSchema().dump(workflow_original) copy_workflow_json.pop('name', None) original_workflow_json.pop('name', None) self.assertNotEqual(original_workflow_json['start'], copy_workflow_json['start']) copy_workflow_json.pop('start') original_workflow_json.pop('start') self.assertEqual(len(workflow_original.actions), len(workflow_copy.actions))
def test_create_playbook_bad_id_in_workflow(self): workflow = Workflow('wf1', uuid4()) self.app.running_context.execution_db.session.add(workflow) self.app.running_context.execution_db.session.flush() workflow_json = WorkflowSchema().dump(workflow) workflow_json.pop('is_valid', None) workflow_json['id'] = 'garbage' data = {'name': self.add_playbook_name, 'workflows': [workflow_json]} self.post_with_status_check('/api/playbooks', data=json.dumps(data), headers=self.headers, status_code=BAD_REQUEST, content_type="application/json")
def test_read_workflow(self): playbook = execution_db_help.standard_load() target_workflow = playbook.workflows[0] response = self.get_with_status_check('/api/workflows/{}'.format( target_workflow.id), headers=self.headers) self.assertDictEqual( self.strip_ids(response), self.strip_ids(WorkflowSchema().dump(target_workflow).data))
def test_update_workflow(self): from walkoff.executiondb.schemas import WorkflowSchema playbook = execution_db_help.standard_load() workflow = playbook.workflows[0] expected_json = WorkflowSchema().dump(workflow) expected_json['name'] = self.change_workflow_name expected_json.pop('is_valid') response = self.put_with_status_check('/api/workflows', data=json.dumps(expected_json), headers=self.headers, content_type='application/json') response.pop('is_valid') self.assertDictEqual(response, expected_json) self.assertIsNotNone( self.app.running_context.execution_db.session.query(Workflow).filter_by(id=workflow.id).first()) self.assertIsNone( self.app.running_context.execution_db.session.query(Workflow).join(Workflow.playbook).filter( Workflow.name == self.add_workflow_name).first())
def test_update_workflow(self): from walkoff.executiondb.schemas import WorkflowSchema playbook = execution_db_help.standard_load() workflow = playbook.workflows[0] expected_json = WorkflowSchema().dump(workflow) expected_json['name'] = self.change_workflow_name expected_json.pop('is_valid') response = self.put_with_status_check('/api/workflows', data=json.dumps(expected_json), headers=self.headers, content_type='application/json') response.pop('is_valid') self.assertDictEqual(response, expected_json) self.assertIsNotNone( self.app.running_context.execution_db.session.query( Workflow).filter_by(id=workflow.id).first()) self.assertIsNone( self.app.running_context.execution_db.session.query(Workflow).join( Workflow.playbook).filter( Workflow.name == self.add_workflow_name).first())
def test_update_workflow_invalid_new_workflow(self): from walkoff.executiondb.schemas import WorkflowSchema from walkoff.executiondb import ExecutionDatabase playbook = execution_db_help.standard_load() workflow = playbook.workflows[0] expected_json = WorkflowSchema().dump(workflow) expected_json['name'] = self.change_workflow_name expected_json['actions'][0]['action_name'] = 'invalid' expected_json.pop('is_valid') response = self.put_with_status_check('/api/workflows', data=json.dumps(expected_json), headers=self.headers, content_type='application/json') response.pop('is_valid') errors = response['actions'][0].pop('errors') self.assertEqual(len(errors), 1) self.assertDictEqual(response, expected_json) self.assertIsNotNone( ExecutionDatabase.instance.session.query(Workflow).filter_by(id=workflow.id).first()) self.assertIsNone( ExecutionDatabase.instance.session.query(Workflow).join(Workflow.playbook).filter( Workflow.name == self.add_workflow_name).first())
def test_read_playbook(self): playbook = execution_db_help.standard_load() response = self.get_with_status_check('/api/playbooks/{}'.format( playbook.id), headers=self.headers) expected_workflows = [ self.strip_ids(WorkflowSchema().dump(workflow).data) for workflow in playbook.workflows ] self.assertEqual(response['name'], 'test') self.assertEqual(len(response['workflows']), len(expected_workflows)) self.assertListEqual( [self.strip_ids(workflow) for workflow in response['workflows']], expected_workflows)
def test_read_playbook_workflows_from_query(self): playbook = execution_db_help.standard_load() response = self.get_with_status_check( '/api/workflows?playbook={}'.format(playbook.id), headers=self.headers) expected_workflows = [ self.strip_ids(WorkflowSchema().dump(workflow)) for workflow in playbook.workflows ] self.assertEqual(len(response), len(expected_workflows)) self.assertListEqual( [self.strip_ids(workflow) for workflow in response], expected_workflows)
def load_workflow(resource, workflow_name): """Loads a workflow from a file. Args: resource (str): Path to the workflow. workflow_name (str): Name of the workflow to load. Returns: True on success, False otherwise. """ try: playbook_file = open(resource, 'r') except (IOError, OSError) as e: logger.error( 'Could not load workflow from {0}. Reason: {1}'.format( resource, format_exception_message(e))) return None else: with playbook_file: workflow_loaded = playbook_file.read() try: playbook_json = json.loads(workflow_loaded) playbook_name = playbook_json['name'] workflow_json = next( (workflow for workflow in playbook_json['workflows'] if workflow['name'] == workflow_name), None) if workflow_json is None: logger.warning( 'Workflow {0} not found in playbook {0}. ' 'Cannot load.'.format(workflow_name, playbook_name)) return None workflow = WorkflowSchema().load(workflow_json) return playbook_name, workflow except ValueError as e: logger.exception('Cannot parse {0}. Reason: {1}'.format( resource, format_exception_message(e))) except (InvalidArgument, UnknownApp, UnknownAppAction, UnknownTransform, UnknownCondition) as e: logger.error( 'Error constructing workflow {0}. Reason: {1}'.format( workflow_name, format_exception_message(e))) return None except KeyError as e: logger.error( 'Invalid Playbook JSON format. Details: {}'.format(e)) return None
def test_copy_workflow(self): playbook = execution_db_help.standard_load() for workflow in playbook.workflows: workflow_id = workflow.id response = self.post_with_status_check( '/api/workflows?source={0}'.format(workflow_id), headers=self.headers, status_code=OBJECT_CREATED, data=json.dumps({ 'name': self.add_workflow_name, 'playbook_id': str(playbook.id) }), content_type="application/json") self.assertEqual(len(playbook.workflows), 2) for workflow in playbook.workflows: self.assertIn(workflow.name, ['helloWorldWorkflow', self.add_workflow_name]) if workflow.name == 'helloWorldWorkflow': workflow_original = workflow elif workflow.name == self.add_workflow_name: workflow_copy = workflow copy_workflow_json = WorkflowSchema().dump(workflow_copy).data original_workflow_json = WorkflowSchema().dump(workflow_original).data copy_workflow_json.pop('name', None) original_workflow_json.pop('name', None) self.assertNotEqual(original_workflow_json['start'], copy_workflow_json['start']) copy_workflow_json.pop('start') original_workflow_json.pop('start') self.assertEqual(len(workflow_original.actions), len(workflow_copy.actions))
from sqlalchemy import exists, and_ from sqlalchemy.exc import IntegrityError, StatementError from walkoff.appgateway.apiutil import UnknownApp, UnknownFunction, InvalidArgument from walkoff.executiondb.playbook import Playbook from walkoff.executiondb.schemas import PlaybookSchema, WorkflowSchema from walkoff.executiondb.workflow import Workflow from walkoff.helpers import regenerate_workflow_ids from walkoff.helpers import strip_device_ids, strip_argument_ids from walkoff.security import permissions_accepted_for_resources, ResourcePermissions from walkoff.server.decorators import with_resource_factory, validate_resource_exists_factory, is_valid_uid from walkoff.server.problem import Problem from walkoff.server.returncodes import * playbook_schema = PlaybookSchema() workflow_schema = WorkflowSchema() invalid_execution_element_exceptions = (InvalidArgument, UnknownApp, UnknownFunction) def does_workflow_exist(playbook_id, workflow_id): return current_app.running_context.execution_db.session.query( exists().where( and_(Workflow.id == workflow_id, Workflow.playbook_id == playbook_id))).scalar() def playbook_getter(playbook_id): playbook = current_app.running_context.execution_db.session.query( Playbook).filter_by(id=playbook_id).first()