def __init__(self, executor=MultiprocessedExecutor): """Initializes a Controller object. Args: executor (cls, optional): The executor to use in the controller. Defaults to MultiprocessedExecutor """ self.uid = 'controller' self.playbook_store = PlaybookStore() self.scheduler = Scheduler() self.executor = executor()
def setUp(self): self.store = PlaybookStore() self.loader = MockPlaybookLoader()
class TestPlaybookStore(TestCase): def setUp(self): self.store = PlaybookStore() self.loader = MockPlaybookLoader() def assertStoreKeysEqual(self, keys): self.assertSetEqual(set(self.store.playbooks.keys()), set(keys)) def assertPlaybookHasWorkflowName(self, playbook_name, workflow_name): self.assertTrue(self.store.playbooks[playbook_name].has_workflow_name(workflow_name)) def assertPlaybookWorkflowNamesEqual(self, playbook_name, workflows): self.assertSetEqual(set(self.store.playbooks[playbook_name].get_all_workflow_names()), set(workflows)) def test_init(self): self.assertDictEqual(self.store.playbooks, {}) def test_load_workflow_not_found(self): self.assertIsNone(self.store.load_workflow('test1', 'invalid', loader=self.loader)) def test_load_workflow_playbook_not_in_store_empty_store(self): self.store.load_workflow('play1', 'work1', loader=self.loader) self.assertIn('play1', self.store.playbooks) self.assertPlaybookWorkflowNamesEqual('play1', {'work1'}) def test_load_workflow_playbook_not_in_store(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.load_workflow('play2', 'work3', loader=self.loader) self.assertIn('play2', self.store.playbooks) self.assertPlaybookWorkflowNamesEqual('play2', {'work3'}) def test_load_workflow_playbook_in_storage_new_workflows(self): copied_playbook = deepcopy(self.loader.playbook1) copied_playbook.remove_workflow_by_name('work1') self.store.playbooks['play1'] = copied_playbook self.store.load_workflow('play1', 'work1', loader=self.loader) self.assertIn('play1', self.store.playbooks) self.assertPlaybookWorkflowNamesEqual('play1', {'work1', 'work2'}) def test_load_workflow_playbook_in_storage_workflow_in_storage(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.load_workflow('play1', 'work1', loader=self.loader) self.assertIn('play1', self.store.playbooks) self.assertPlaybookWorkflowNamesEqual('play1', {'work1', 'work2'}) def test_load_playbook_not_found_none_in_store(self): self.store.load_playbook('invalid', loader=self.loader) self.assertDictEqual(self.store.playbooks, {}) def test_load_playbook_not_found_some_in_store(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.load_playbook('invalid', loader=self.loader) self.assertStoreKeysEqual({'play1'}) def test_load_playbook_not_in_store(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.load_playbook('play2', loader=self.loader) self.assertStoreKeysEqual({'play1', 'play2'}) def test_load_playbook_already_in_store(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.load_playbook('play1', loader=self.loader) self.assertStoreKeysEqual({'play1'}) self.assertPlaybookWorkflowNamesEqual('play1', {'work1', 'work2'}) def test_add_playbook_no_playbooks(self): self.store.add_playbook(self.loader.playbook1) self.assertStoreKeysEqual({'play1'}) self.assertEqual(self.store.playbooks['play1'], self.loader.playbook1) def test_add_playbook_some_playbooks(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.add_playbook(self.loader.playbook2) self.assertStoreKeysEqual({'play1', 'play2'}) self.assertEqual(self.store.playbooks['play2'], self.loader.playbook2) def test_add_playbook_same_playbook(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.add_playbook(self.loader.playbook1) self.assertStoreKeysEqual({'play1'}) self.assertEqual(self.store.playbooks['play1'], self.loader.playbook1) def test_add_workflow_no_playbooks(self): workflow = Workflow('work1') self.store.add_workflow('play1', workflow) self.assertStoreKeysEqual({'play1'}) self.assertListEqual(list(self.store.playbooks['play1'].workflows.values()), [workflow]) def test_add_workflow_playbook_in_store(self): self.store.playbooks['play1'] = self.loader.playbook1 workflow = Workflow('work3') self.store.add_workflow('play1', workflow) self.assertStoreKeysEqual({'play1'}) self.assertPlaybookHasWorkflowName('play1', 'work3') def test_add_workflow_playbook_not_in_store(self): self.store.playbooks['play1'] = self.loader.playbook1 workflow = Workflow('work3') self.store.add_workflow('play2', workflow) self.assertSetEqual(set(self.store.playbooks.keys()), {'play1', 'play2'}) self.assertListEqual(list(self.store.playbooks['play2'].workflows.values()), [workflow]) def test_load_playbooks(self): self.store.load_playbooks('resource', loader=self.loader) self.assertStoreKeysEqual({'play1', 'play2'}) def test_create_workflow(self): self.store.create_workflow('play1', 'work1') self.assertStoreKeysEqual({'play1'}) self.assertPlaybookHasWorkflowName('play1', 'work1') def test_create_workflow_playbook_exists(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.create_workflow('play1', 'work3') self.assertStoreKeysEqual({'play1'}) self.assertPlaybookWorkflowNamesEqual('play1', {'work1', 'work2', 'work3'}) def test_create_workflow_playbook_workflow_exist(self): self.store.playbooks['play1'] = self.loader.playbook1 original_uid = self.store.playbooks['play1'].get_workflow_by_name('work1').uid self.store.create_workflow('play1', 'work1') self.assertNotEqual(self.store.playbooks['play1'].get_workflow_by_name('work1').uid, original_uid) def test_create_playbook_empty_store_no_workflows(self): self.store.create_playbook('play1') self.assertStoreKeysEqual({'play1'}) self.assertListEqual(list(self.store.playbooks['play1'].workflows.values()), []) def test_create_playbook_empty_store_with_workflows(self): workflow = Workflow('work1') self.store.create_playbook('play1', [workflow]) self.assertStoreKeysEqual({'play1'}) self.assertListEqual(list(self.store.playbooks['play1'].workflows.values()), [workflow]) def test_create_playbook_nonempty_store_no_workflows(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.create_playbook('play2') self.assertStoreKeysEqual({'play1', 'play2'}) self.assertListEqual(list(self.store.playbooks['play2'].workflows.values()), []) def test_create_playbook_nonempty_store_with_workflows(self): self.store.playbooks['play1'] = self.loader.playbook1 workflow = Workflow('work1') self.store.create_playbook('play2', [workflow]) self.assertStoreKeysEqual({'play1', 'play2'}) self.assertListEqual(list(self.store.playbooks['play2'].workflows.values()), [workflow]) def test_create_playbook_playbook_already_exists(self): self.store.playbooks['play1'] = self.loader.playbook1 workflow = Workflow('work3') self.store.create_playbook('play1', workflows=[workflow]) self.assertStoreKeysEqual({'play1'}) self.assertPlaybookWorkflowNamesEqual('play1', {'work3'}) def test_remove_workflow(self): self.store.playbooks['play1'] = self.loader.playbook1 self.assertTrue(self.store.remove_workflow('play1', 'work1')) self.assertStoreKeysEqual({'play1'}) self.assertPlaybookWorkflowNamesEqual('play1', {'work2'}) def test_remove_workflow_workflow_not_found(self): self.store.playbooks['play1'] = self.loader.playbook1 self.assertFalse(self.store.remove_workflow('play1', 'invalid')) self.assertStoreKeysEqual({'play1'}) self.assertPlaybookWorkflowNamesEqual('play1', {'work1', 'work2'}) def test_remove_workflow_playbook_not_found(self): self.store.playbooks['play1'] = self.loader.playbook1 self.assertFalse(self.store.remove_workflow('invalid', 'work1')) self.assertStoreKeysEqual({'play1'}) self.assertPlaybookWorkflowNamesEqual('play1', {'work1', 'work2'}) def test_remove_workflow_empty_store(self): self.assertFalse(self.store.remove_workflow('play1', 'work1')) self.assertStoreKeysEqual(set()) def test_remove_playbook_empty_store(self): self.assertFalse(self.store.remove_playbook('play1')) self.assertStoreKeysEqual(set()) def test_remove_playbook_playbook_not_found(self): self.store.playbooks['play1'] = self.loader.playbook1 self.assertFalse(self.store.remove_playbook('invalid')) self.assertStoreKeysEqual({'play1'}) def test_remove_playbook(self): self.store.playbooks['play1'] = self.loader.playbook1 self.assertTrue(self.store.remove_playbook('play1')) self.assertStoreKeysEqual(set()) def test_get_all_workflows_with_representations_empty_store(self): self.assertListEqual(self.store.get_all_workflows(full_representations=True), []) def test_get_all_workflows_with_limited_representations_empty_store(self): self.assertListEqual(self.store.get_all_workflows(), []) def test_get_all_workflows_with_representations(self): self.store.playbooks['play1'] = self.loader.playbook1 self.assertListEqual(self.store.get_all_workflows(full_representations=True), [self.loader.playbook1.read()]) def test_get_all_workflows_with_limited_representations(self): self.store.playbooks['play1'] = self.loader.playbook1 expected = [{'name': 'play1', 'workflows': [{'name': workflow.name, 'uid': workflow.uid} for workflow in self.loader.playbook1.workflows.values()]}] self.assertListEqual(self.store.get_all_workflows(), expected) def test_get_all_workflows_with_representation_custom_reader(self): self.store.playbooks['play1'] = self.loader.playbook1 self.assertListEqual(self.store.get_all_workflows(full_representations=True, reader=MockElementReader), [id(self.loader.playbook1)]) def test_get_all_playbooks_empty_store(self): self.assertListEqual(self.store.get_all_playbooks(), []) def test_get_all_playbooks(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.playbooks['play2'] = self.loader.playbook2 self.assertSetEqual(set(self.store.get_all_playbooks()), {'play1', 'play2'}) def test_is_workflow_registered(self): self.store.playbooks['play1'] = self.loader.playbook1 self.assertTrue(self.store.is_workflow_registered('play1', 'work1')) def test_is_workflow_registered_empty_store(self): self.assertFalse(self.store.is_workflow_registered('play1', 'work1')) def test_is_workflow_registered_invalid_playbook(self): self.store.playbooks['play1'] = self.loader.playbook1 self.assertFalse(self.store.is_workflow_registered('invalid', 'work1')) def test_is_workflow_registered_invalid_workflow(self): self.store.playbooks['play1'] = self.loader.playbook1 self.assertFalse(self.store.is_workflow_registered('play1', 'invalid')) def test_is_playbook_registered_empty_store(self): self.assertFalse(self.store.is_playbook_registered('play1')) def test_is_playbook_registered(self): self.store.playbooks['play1'] = self.loader.playbook1 self.assertTrue(self.store.is_playbook_registered('play1')) def test_is_playbook_registered_invalid_playbook(self): self.store.playbooks['play1'] = self.loader.playbook1 self.assertFalse(self.store.is_playbook_registered('invalid')) def test_update_workflow_name_empty_store(self): self.store.update_workflow_name('old_playbook', 'old_workflow', 'new_playbook', 'new_workflow') self.assertStoreKeysEqual(set()) def test_update_workflow_name_invalid_playbook(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.update_workflow_name('invalid', 'work1', 'new_playbook', 'new_workflow') self.assertStoreKeysEqual({'play1'}) self.assertPlaybookWorkflowNamesEqual('play1', {'work1', 'work2'}) def test_update_workflow_name_invalid_workflow(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.update_workflow_name('play1', 'invalid', 'new_playbook', 'new_workflow') self.assertStoreKeysEqual({'play1'}) self.assertPlaybookWorkflowNamesEqual('play1', {'work1', 'work2'}) def test_update_workflow_name_same_playbook_same_workflow(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.update_workflow_name('play1', 'work1', 'play1', 'work1') self.assertStoreKeysEqual({'play1'}) self.assertPlaybookWorkflowNamesEqual('play1', {'work1', 'work2'}) def test_update_workflow_name_same_playbook(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.update_workflow_name('play1', 'work1', 'play1', 'renamed') self.assertStoreKeysEqual({'play1'}) self.assertPlaybookWorkflowNamesEqual('play1', {'renamed', 'work2'}) def test_update_workflow_name_new_playbook(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.update_workflow_name('play1', 'work1', 'play2', 'renamed') self.assertStoreKeysEqual({'play1', 'play2'}) self.assertPlaybookWorkflowNamesEqual('play1', {'work2'}) self.assertPlaybookWorkflowNamesEqual('play2', {'renamed'}) def test_update_playbook_name_empty_store(self): self.store.update_playbook_name('old_playbook', 'new_playbook') self.assertStoreKeysEqual(set()) def test_update_playbook_name_invalid_playbook(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.update_playbook_name('invalid', 'renamed') self.assertStoreKeysEqual({'play1'}) def test_update_playbook_name(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.update_playbook_name('play1', 'renamed') self.assertStoreKeysEqual({'renamed'}) self.assertEqual(self.store.playbooks['renamed'], self.loader.playbook1) def test_get_workflow_empty_store(self): self.assertIsNone(self.store.get_workflow('play1', 'work1')) def test_get_workflow_invalid_playbook(self): self.store.playbooks['play1'] = self.loader.playbook1 self.assertIsNone(self.store.get_workflow('invalid', 'work1')) def test_get_workflow_invalid_workflow(self): self.store.playbooks['play1'] = self.loader.playbook1 self.assertIsNone(self.store.get_workflow('play1', 'invalid')) def test_get_workflow(self): self.store.playbooks['play1'] = self.loader.playbook1 workflow = self.loader.playbook1.get_workflow_by_name('work1') self.assertEqual(self.store.get_workflow('play1', 'work1'), workflow) def test_get_playbook_empty_store(self): self.assertIsNone(self.store.get_playbook('play1')) def test_get_playbook_invalid_playbook(self): self.store.playbooks['play1'] = self.loader.playbook1 self.assertIsNone(self.store.get_playbook('invalid')) def test_get_playbook(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.playbooks['play2'] = self.loader.playbook2 self.assertEqual(self.store.get_playbook('play1'), self.loader.playbook1) def test_get_all_workflows_by_playbook_empty_store(self): self.assertListEqual(self.store.get_all_workflows_by_playbook('play1'), []) def test_get_all_workflows_by_playbook_invalid_playbook(self): self.store.playbooks['play1'] = self.loader.playbook1 self.assertListEqual(self.store.get_all_workflows_by_playbook('invalid'), []) def test_get_all_workflows_by_playbook(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.playbooks['play2'] = self.loader.playbook2 self.assertSetEqual(set(self.store.get_all_workflows_by_playbook('play2')), {'work1', 'work3'}) def test_playbook_representation_empty_store(self): self.assertIsNone(self.store.get_playbook_representation('play1')) def test_playbook_representation_invalid_playbook(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.playbooks['play2'] = self.loader.playbook2 self.assertIsNone(self.store.get_playbook_representation('invalid')) def test_playbook_representation(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.playbooks['play2'] = self.loader.playbook2 self.assertDictEqual(self.store.get_playbook_representation('play1'), self.loader.playbook1.read()) def test_playbook_representation_custom_reader(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.playbooks['play2'] = self.loader.playbook2 self.assertEqual(id(self.loader.playbook1), self.loader.playbook1.read(reader=MockElementReader)) def test_copy_workflow_empty_store(self): self.store.copy_workflow('old_playbook', 'new_playbook', 'old_workflow', 'new_workflow') self.assertStoreKeysEqual(set()) def test_copy_workflow_invalid_playbook(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.playbooks['play2'] = self.loader.playbook2 self.store.copy_workflow('invalid', 'play1', 'old_workflow', 'new_workflow') self.assertStoreKeysEqual({'play1', 'play2'}) self.assertPlaybookWorkflowNamesEqual('play1', {'work1', 'work2'}) def test_copy_workflow_invalid_workflow(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.playbooks['play2'] = self.loader.playbook2 self.store.copy_workflow('play1', 'play3', 'invalid', 'new_workflow') self.assertStoreKeysEqual({'play1', 'play2'}) self.assertPlaybookWorkflowNamesEqual('play1', {'work1', 'work2'}) def test_copy_workflow_same_playbook_same_workflow(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.playbooks['play2'] = self.loader.playbook2 self.store.copy_workflow('play1', 'play1', 'work1', 'work1') self.assertStoreKeysEqual({'play1', 'play2'}) self.assertPlaybookWorkflowNamesEqual('play1', {'work1', 'work2'}) def test_copy_workflow_same_playbook(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.playbooks['play2'] = self.loader.playbook2 self.store.copy_workflow('play1', 'play1', 'work1', 'new_work') self.assertStoreKeysEqual({'play1', 'play2'}) self.assertPlaybookWorkflowNamesEqual('play1', {'work1', 'work2', 'new_work'}) def test_copy_workflow_new_playbook_new_playbook_does_not_exist(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.playbooks['play2'] = self.loader.playbook2 self.store.copy_workflow('play1', 'play3', 'work1', 'new_work') self.assertStoreKeysEqual({'play1', 'play2', 'play3'}) self.assertPlaybookWorkflowNamesEqual('play1', {'work1', 'work2'}) self.assertPlaybookWorkflowNamesEqual('play3', {'new_work'}) def test_copy_workflow_new_playbook_new_playbook_already_exists(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.playbooks['play2'] = self.loader.playbook2 self.store.copy_workflow('play1', 'play2', 'work1', 'new_work') self.assertStoreKeysEqual({'play1', 'play2'}) self.assertPlaybookWorkflowNamesEqual('play1', {'work1', 'work2'}) self.assertPlaybookWorkflowNamesEqual('play2', {'work1', 'work3', 'new_work'}) def test_copy_playbook_empty_store(self): self.store.copy_playbook('old_playbook', 'new_playbook') self.assertStoreKeysEqual(set()) def test_copy_playbook_invalid_playbook(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.playbooks['play2'] = self.loader.playbook2 self.store.copy_playbook('invalid', 'new_playbook') self.assertStoreKeysEqual({'play1', 'play2'}) def test_copy_playbook(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.playbooks['play2'] = self.loader.playbook2 original_uid = self.loader.playbook1.uid self.store.copy_playbook('play1', 'play3') self.assertStoreKeysEqual({'play1', 'play2', 'play3'}) self.assertPlaybookWorkflowNamesEqual('play3', {'work1', 'work2'}) self.assertNotEqual(self.store.playbooks['play3'].uid, original_uid) def test_copy_playbook_new_playbook_already_exists(self): self.store.playbooks['play1'] = self.loader.playbook1 self.store.playbooks['play2'] = self.loader.playbook2 original_uid = self.loader.playbook1.uid self.store.copy_playbook('play1', 'play2') self.assertStoreKeysEqual({'play1', 'play2'}) self.assertPlaybookWorkflowNamesEqual('play2', {'work1', 'work2'}) self.assertNotEqual(self.store.playbooks['play2'].uid, original_uid)
class Controller(object): def __init__(self, executor=MultiprocessedExecutor): """Initializes a Controller object. Args: executor (cls, optional): The executor to use in the controller. Defaults to MultiprocessedExecutor """ self.uid = 'controller' self.playbook_store = PlaybookStore() self.scheduler = Scheduler() self.executor = executor() def initialize_threading(self, worker_environment_setup=None): """Initializes threading in the executor """ self.executor.initialize_threading( worker_environment_setup=worker_environment_setup) def shutdown_pool(self, num_workflows=0): """Shuts down the executor Args: num_workflows (int, optional): Number of workflows to wait to complete before shutting down. Defaults to 0, meaning that it will immediately shutdown the pool upon receiving this command. """ self.executor.shutdown_pool(num_workflows=num_workflows) def pause_workflow(self, execution_uid): """Pauses a workflow. Args: execution_uid (str): The execution UID of the workflow to pause """ self.executor.pause_workflow(execution_uid) def resume_workflow(self, workflow_execution_uid): """Resumes a workflow that has been paused. Args: workflow_execution_uid (str): The randomly-generated hexadecimal key that was returned from pause_workflow(). This is needed to resume a workflow for security purposes. Returns: (bool) True if successful, False otherwise. """ return self.executor.resume_workflow(workflow_execution_uid) def load_workflow(self, 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. """ return self.playbook_store.load_workflow(resource, workflow_name) def load_playbook(self, resource): """Loads playbook from a file. Args: resource (str): Path to the workflow. """ return self.playbook_store.load_playbook(resource) def load_playbooks(self, resource_collection=None): """Loads all playbooks from a directory. Args: resource_collection (str, optional): Path to the directory to load from. Defaults to the configuration workflows_path. """ return self.playbook_store.load_playbooks(resource_collection) def schedule_workflows(self, task_id, workflow_uids, trigger): """Schedules workflows to be run by the scheduler Args: task_id (str|int): Id of the task to run workflow_uids (list[str]): UIDs of the workflows to schedule trigger: The type of scheduler trigger to use """ playbook_workflows = self.playbook_store.get_workflows_by_uid( workflow_uids) schedule_workflows = [] for playbook_name, workflows in playbook_workflows.items(): for workflow in workflows: schedule_workflows.append( (playbook_name, workflow.name, workflow.uid)) self.scheduler.schedule_workflows(task_id, self.execute_workflow, schedule_workflows, trigger) def create_workflow(self, playbook_name, workflow_name): """Creates a workflow from a workflow template. Args: playbook_name (str): The name of the new playbook. workflow_name (str): The name of the new workflow. Returns: True on success, False if otherwise. """ return self.playbook_store.create_workflow(playbook_name, workflow_name) def create_playbook(self, playbook_name, workflows=None): """Creates a playbook from a playbook template. Args: playbook_name (str): The name of the new playbook. workflows (list[Workflow], optional): An optional list of Workflows to be associated with this Playbook. Defaults to None. """ return self.playbook_store.create_playbook(playbook_name, workflows) def remove_workflow(self, playbook_name, workflow_name): """Removes a workflow. Args: playbook_name (str): Playbook name under which the workflow is located. workflow_name (str): The name of the workflow to remove. Returns: True on success, False otherwise. """ self.playbook_store.remove_workflow(playbook_name, workflow_name) def remove_playbook(self, playbook_name): """Removes a playbook and all workflows within it. Args: playbook_name (str): The name of the playbook to remove. Returns: True on success, False otherwise. """ self.playbook_store.remove_playbook(playbook_name) def get_all_workflows(self, full_representation=False, reader=None): """Gets all of the currently loaded workflows. Args: full_representation (bool, optional): A boolean specifying whether or not to include the JSON representation of all the workflows, or just their names. Defaults to False. reader (cls): The reader to specify how to display the Workflows. Defaults to None, which will show basic JSON representation of the Workflows. Returns: A dict with key being the playbook, mapping to a list of workflow names for each playbook. """ return self.playbook_store.get_all_workflows(full_representation, reader=reader) def get_all_playbooks(self): """Gets a list of all playbooks. Returns: A list containing all currently loaded playbook names. """ return self.playbook_store.get_all_playbooks() def is_workflow_registered(self, playbook_name, workflow_name): """Checks whether or not a workflow is currently registered in the system. Args: playbook_name (str): Playbook name under which the workflow is located. workflow_name (str): The name of the workflow. Returns: True if the workflow is registered, false otherwise. """ return self.playbook_store.is_workflow_registered( playbook_name, workflow_name) def is_playbook_registered(self, playbook_name): """Checks whether or not a playbook is currently registered in the system. Args: playbook_name (str): The name of the playbook. Returns: True if the playbook is registered, false otherwise. """ return self.playbook_store.is_playbook_registered(playbook_name) def update_workflow_name(self, old_playbook, old_workflow, new_playbook, new_workflow): """Update the name of a workflow. Args: old_playbook (str): Name of the current playbook. old_workflow (str): Name of the current workflow. new_playbook (str): The new name of the playbook. new_workflow (str): The new name of the workflow. """ self.playbook_store.update_workflow_name(old_playbook, old_workflow, new_playbook, new_workflow) def update_playbook_name(self, old_playbook, new_playbook): """Update the name of a playbook. Args: old_playbook (str): Name of the current playbook. new_playbook (str): The new name of the playbook. """ self.playbook_store.update_playbook_name(old_playbook, new_playbook) def execute_workflow(self, playbook_name, workflow_name, start=None, start_input=None): """Executes a workflow. Args: playbook_name (str): Playbook name under which the workflow is located. workflow_name (str): Workflow to execute. start (str, optional): The name of the first, or starting step. Defaults to None. start_input (dict, optional): The input to the starting step of the workflow. Defaults to None. Returns: The execution UID if successful, None otherwise. """ if self.playbook_store.is_workflow_registered(playbook_name, workflow_name): workflow = self.playbook_store.get_workflow( playbook_name, workflow_name) return self.executor.execute_workflow(workflow, start, start_input) else: logger.error( 'Attempted to execute playbook which does not exist in controller' ) return None, 'Attempted to execute playbook which does not exist in controller' def get_waiting_workflows(self): return self.executor.get_waiting_workflows() def get_workflow(self, playbook_name, workflow_name): """Get a workflow object. Args: playbook_name (str): Playbook name under which the workflow is located. workflow_name (str): The name of the workflow. Returns: The workflow object if found, else None. """ return self.playbook_store.get_workflow(playbook_name, workflow_name) def get_all_workflows_by_playbook(self, playbook_name): """Get a list of all workflow objects in a playbook. Args: playbook_name: The name of the playbook. Returns: A list of all workflow objects in a playbook. """ return self.playbook_store.get_all_workflows_by_playbook(playbook_name) def get_playbook_representation(self, playbook_name, reader=None): """Returns the JSON representation of a playbook. Args: playbook_name: The name of the playbook. reader (cls, optional): An optional different way to represent the Playbook. Defaults to None, meaning that it will show basic JSON representation. Returns: The JSON representation of the playbook if the playbook has any workflows under it, else None. """ return self.playbook_store.get_playbook_representation(playbook_name, reader=reader) def copy_workflow(self, old_playbook_name, new_playbook_name, old_workflow_name, new_workflow_name): """Duplicates a workflow into its current playbook, or a different playbook. Args: old_playbook_name (str): Playbook name under which the workflow is located. new_playbook_name (str): The new playbook name for the duplicated workflow. old_workflow_name (str): The name of the workflow to be copied. new_workflow_name (str): The new name of the duplicated workflow. """ self.playbook_store.copy_workflow(old_playbook_name, new_playbook_name, old_workflow_name, new_workflow_name) def copy_playbook(self, old_playbook_name, new_playbook_name): """Copies a playbook. Args: old_playbook_name (str): The name of the playbook to be copied. new_playbook_name (str): The new name of the duplicated playbook. """ self.playbook_store.copy_playbook(old_playbook_name, new_playbook_name) def send_data_to_trigger(self, data_in, workflow_uids, inputs=None): """Tries to match the data in against the conditionals of all the triggers registered in the database. Args: data_in (dict): Data to be used to match against the triggers for a Step awaiting data. workflow_uids (list[str]): A list of workflow execution UIDs to send this data to. inputs (dict, optional): An optional dict of inputs to update for a Step awaiting data for a trigger. Defaults to {}. Returns: Dictionary of {"status": <status string>} """ inputs = inputs if inputs is not None else {} if workflow_uids is not None: self.executor.send_data_to_trigger(data_in, workflow_uids, inputs) def get_workflow_status(self, execution_uid): """Gets the status of an executing workflow Args: execution_uid (str): Execution UID of the executing workflow Returns: (int) Status code of the executing workflow """ return self.executor.get_workflow_status(execution_uid)