diff --git a/app/Controller/WorkflowsController.php b/app/Controller/WorkflowsController.php index 6c657fa9d..bd964ae39 100644 --- a/app/Controller/WorkflowsController.php +++ b/app/Controller/WorkflowsController.php @@ -181,31 +181,54 @@ class WorkflowsController extends AppController $this->set('menuData', ['menuList' => 'workflows', 'menuItem' => 'view_module']); } - public function import() + public function toggleModule($module_id, $enabled) { - if ($this->request->is('post') || $this->request->is('put')) { - $data = $this->request->data['Workflow']; - $text = FileAccessTool::getTempUploadedFile($data['submittedjson'], $data['json']); - $workflow = JsonTool::decode($text); - if ($workflow === null) { - throw new MethodNotAllowedException(__('Error while decoding JSON')); - } - $workflow['Workflow']['enabled'] = false; - $workflow['Workflow']['data'] = JsonTool::encode($workflow['Workflow']['data']); - $this->request->data = $workflow; - $this->add(); + $this->request->allowMethod(['post', 'put']); + $saved = $this->Workflow->toggleModule($module_id, $enabled); + if ($saved) { + return $this->__getSuccessResponseBasedOnContext( + __('%s module %s', ($enabled ? 'Enabled' : 'Disabled'), $module_id), + null, + 'toggle_module', + $module_id, + ['action' => 'moduleIndex'] + ); + } else { + return $this->__getFailResponseBasedOnContext( + __('Could not %s module %s', ($enabled ? 'Enabled' : 'Disabled'), $module_id), + null, + 'toggle_module', + $module_id, + ['action' => 'moduleIndex'] + ); } } - public function export($id) - { - $workflow = $this->Workflow->fetchWorkflow($id); - $content = JsonTool::encode($workflow, JSON_PRETTY_PRINT); - $this->response->body($content); - $this->response->type('json'); - $this->response->download(sprintf('workflow_%s_%s.json', $workflow['Workflow']['name'], time())); - return $this->response; - } + // public function import() + // { + // if ($this->request->is('post') || $this->request->is('put')) { + // $data = $this->request->data['Workflow']; + // $text = FileAccessTool::getTempUploadedFile($data['submittedjson'], $data['json']); + // $workflow = JsonTool::decode($text); + // if ($workflow === null) { + // throw new MethodNotAllowedException(__('Error while decoding JSON')); + // } + // $workflow['Workflow']['enabled'] = false; + // $workflow['Workflow']['data'] = JsonTool::encode($workflow['Workflow']['data']); + // $this->request->data = $workflow; + // $this->add(); + // } + // } + + // public function export($id) + // { + // $workflow = $this->Workflow->fetchWorkflow($id); + // $content = JsonTool::encode($workflow, JSON_PRETTY_PRINT); + // $this->response->body($content); + // $this->response->type('json'); + // $this->response->download(sprintf('workflow_%s_%s.json', $workflow['Workflow']['name'], time())); + // return $this->response; + // } private function __getSuccessResponseBasedOnContext($message, $data = null, $action = '', $id = false, $redirect = array()) { diff --git a/app/Model/Server.php b/app/Model/Server.php index 182af9077..d5346869b 100644 --- a/app/Model/Server.php +++ b/app/Model/Server.php @@ -7045,6 +7045,13 @@ class Server extends AppModel 'test' => 'testForPortNumber', 'type' => 'numeric' ), + 'WorkflowTriggers_publish' => array( + 'level' => 1, + 'description' => __('Enable/disable the `publish` trigger'), + 'value' => false, + 'test' => 'testBool', + 'type' => 'boolean' + ), 'Cortex_services_url' => array( 'level' => 1, 'description' => __('The url used to access Cortex. By default, it is accessible at http://cortex-url'), diff --git a/app/Model/Workflow.php b/app/Model/Workflow.php index bd1a0bd20..2190ae359 100644 --- a/app/Model/Workflow.php +++ b/app/Model/Workflow.php @@ -61,6 +61,7 @@ class Workflow extends AppModel const REDIS_KEY_WORKFLOW_NAMESPACE = 'workflow'; const REDIS_KEY_WORKFLOW_PER_TRIGGER = 'workflow:workflow_list:%s'; const REDIS_KEY_TRIGGER_PER_WORKFLOW = 'workflow:trigger_list:%s'; + const REDIS_KEY_MODULES_ENABLED = 'workflow:modules_enabled'; const BLOCKING_PATH = 'blocking'; const NON_BLOCKING_PATH = 'non-blocking'; @@ -136,8 +137,34 @@ class Workflow extends AppModel { $filename = sprintf('Module_%s.php', preg_replace('/[^a-zA-Z0-9_]/', '_', Inflector::underscore($trigger_id))); $module_config = $this->__getClassFromModuleFiles('trigger', [$filename])['classConfigs']; - // FIXME: Merge global configuration! - return empty($module_config['disabled']); + $module_disabled = empty(Configure::read(sprintf('Plugin.WorkflowTriggers_%s', $trigger_id))); + return empty($module_config['disabled']) && !$module_disabled; + } + + protected function getEnabledModules(): array + { + try { + $redis = $this->setupRedisWithException(); + } catch (Exception $e) { + return false; + } + $list = $redis->sMembers(Workflow::REDIS_KEY_MODULES_ENABLED); + return !empty($list) ? $list : []; + } + + public function toggleModule($module_id, $enable): bool + { + try { + $redis = $this->setupRedisWithException(); + } catch (Exception $e) { + return false; + } + if ($enable) { + $list = $redis->sAdd(Workflow::REDIS_KEY_MODULES_ENABLED, $module_id); + } else { + $list = $redis->sRem(Workflow::REDIS_KEY_MODULES_ENABLED, $module_id); + } + return true; } protected function checkTriggerListenedTo($trigger_id) @@ -465,6 +492,17 @@ class Workflow extends AppModel 'warning' => [], 'info' => [], ]; + if ($module['disabled']) { + $modules[$moduleType][$i]['notifications']['error'][] = [ + 'text' => __('Module disabled'), + 'description' => __('This module is disabled and thus will not be executed.'), + 'details' => [ + __('Disabled modules that are blocking will also block the remaining of the execution') + ], + '__show_in_sidebar' => false, + '__show_in_node' => true, + ]; + } } } return $modules; @@ -500,24 +538,36 @@ class Workflow extends AppModel private function __mergeGlobalConfigIntoLoadedModules() { /* FIXME: Delete `disabled` entry. This is for testing while we wait for module settings */ - array_walk($this->loaded_modules['trigger'], function (&$trigger) { - $module_enabled = !in_array($trigger['id'], ['publish', 'new-attribute']); - $trigger['html_template'] = !empty($trigger['html_template']) ? $trigger['html_template'] : 'trigger'; - $trigger['disabled'] = $module_enabled; - $this->loaded_classes['trigger'][$trigger['id']]->disabled = $module_enabled; - $this->loaded_classes['trigger'][$trigger['id']]->html_template = !empty($trigger['html_template']) ? $trigger['html_template'] : 'trigger'; - }); - array_walk($this->loaded_modules['logic'], function (&$logic) { - $module_enabled = true; - $logic['disabled'] = !$module_enabled; - $this->loaded_classes['logic'][$logic['id']]->disabled = $module_enabled; - }); - array_walk($this->loaded_modules['action'], function (&$action) { - $module_enabled = !in_array($action['id'], ['push-zmq', 'slack-message', 'mattermost-message', 'add-tag', 'writeactions', 'enrich-event', 'testaction', 'stop-execution', ]); - $action['disabled'] = $module_enabled; - $this->loaded_classes['action'][$action['id']]->disabled = $module_enabled; - }); + // array_walk($this->loaded_modules['logic'], function (&$logic) { + // $module_enabled = true; + // $logic['disabled'] = !$module_enabled; + // $this->loaded_classes['logic'][$logic['id']]->disabled = $module_enabled; + // }); + // array_walk($this->loaded_modules['action'], function (&$action) { + // $module_enabled = !in_array($action['id'], ['push-zmq', 'slack-message', 'mattermost-message', 'add-tag', 'writeactions', 'enrich-event', 'testaction', 'stop-execution', ]); + // $action['disabled'] = $module_enabled; + // $this->loaded_classes['action'][$action['id']]->disabled = $module_enabled; + // }); /* FIXME: end */ + foreach ($this->loaded_modules['trigger'] as &$trigger) { + $module_disabled = empty(Configure::read(sprintf('Plugin.WorkflowTriggers_%s', $trigger['id']))); + $trigger['html_template'] = !empty($trigger['html_template']) ? $trigger['html_template'] : 'trigger'; + $trigger['disabled'] = $module_disabled; + $this->loaded_classes['trigger'][$trigger['id']]->disabled = $module_disabled; + $this->loaded_classes['trigger'][$trigger['id']]->html_template = !empty($trigger['html_template']) ? $trigger['html_template'] : 'trigger'; + } + $enabledModules = $this->getEnabledModules(); + array_walk($this->loaded_modules['logic'], function (&$logic) use ($enabledModules) { + $module_disabled = !in_array($logic['id'], $enabledModules); + $logic['disabled'] = $module_disabled; + $this->loaded_classes['logic'][$logic['id']]->disabled = $module_disabled; + }); + array_walk($this->loaded_modules['action'], function (&$action) use ($enabledModules) { + $module_disabled = !in_array($action['id'], $enabledModules); + $action['disabled'] = $module_disabled; + $this->loaded_classes['action'][$action['id']]->disabled = $module_disabled; + }); + } private function __getEnabledModulesFromModuleService() diff --git a/app/Model/WorkflowModules/logic/Module_parallel_task.php b/app/Model/WorkflowModules/logic/Module_parallel_task.php index 1cd1b138a..4b0b00fb3 100644 --- a/app/Model/WorkflowModules/logic/Module_parallel_task.php +++ b/app/Model/WorkflowModules/logic/Module_parallel_task.php @@ -13,6 +13,9 @@ class Module_parallel_task extends WorkflowBaseModule public $html_template = 'parallel'; public $params = []; + private $Workflow; + private $Job; + public function __construct() { parent::__construct(); diff --git a/app/View/Elements/Workflows/sidebar-block.ctp b/app/View/Elements/Workflows/sidebar-block.ctp index 70e37f4a5..df07d49e1 100644 --- a/app/View/Elements/Workflows/sidebar-block.ctp +++ b/app/View/Elements/Workflows/sidebar-block.ctp @@ -5,7 +5,7 @@ $classFromSeverity = [ 'error' => 'danger', ]; ?> -