diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Monit/Api/SettingsController.php b/src/opnsense/mvc/app/controllers/OPNsense/Monit/Api/SettingsController.php index 236171b0f..6829a57e0 100644 --- a/src/opnsense/mvc/app/controllers/OPNsense/Monit/Api/SettingsController.php +++ b/src/opnsense/mvc/app/controllers/OPNsense/Monit/Api/SettingsController.php @@ -1,7 +1,7 @@ [ + 'process' => ['Existence', 'Process Resource', 'Process Disk I/O', 'UID', 'GID', 'PID', 'PPID', 'Uptime', 'Connection', 'Custom'], + 'file' => ['Existence', 'File Checksum', 'Timestamp', 'File Size', 'File Content', 'Permisssion', 'UID', 'GID', 'Custom'], + 'fifo' => ['Existence', 'Timestamp', 'Permisssion', 'UID', 'GID', 'Custom'], + 'filesystem' => ['Existence', 'Filesystem Mount Flags', 'Space Usage', 'Inode Usage', 'Disk I/O', 'Permisssion', 'Custom'], + 'directory' => ['Existence', 'Timestamp', 'Permisssion', 'UID', 'GID', 'Custom'], + 'host' => ['Network Ping', 'Connection', 'Custom'], + 'system' => ['System Resource', 'Uptime', 'Custom'], + 'custom' => ['Program Status', 'Custom'], + 'network' => ['Network Interface', 'Custom'] + ], + 'operators' => ['greater', 'less', 'equal', 'notequal'], + 'units' => [ + 'timeUnits' => ['seconds', 'minutes', 'hours', 'days'], + 'amountUnits' => ['byte', 'kilobyte', 'megabyte', 'gigabyte'], + 'spaceAmountUnits' => ['byte', 'kilobyte', 'megabyte', 'gigabyte', 'percent'], + 'diskAmountUnits' => ['byte', 'kilobyte', 'megabyte', 'gigabyte', 'operations'], + 'netAmountUnits' => ['byte', 'kilobyte', 'megabyte', 'gigabyte', 'packets'], + ], + 'testConditionMapping' => [ + 'Existence' => [ + 'exist', + 'not exist' + ], + 'System Resource' => [ + 'loadavg (1min)' => ['_OPERATOR' => ['_VALUE' => null]], + 'loadavg (5min)' => ['_OPERATOR' => ['_VALUE' => null]], + 'loadavg (15min)' => ['_OPERATOR' => ['_VALUE' => null]], + 'cpu usage' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'percent']], + 'cpu user usage' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'percent']], + 'cpu system usage' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'percent']], + 'cpu wait usage' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'percent']], + 'memory usage' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'percent']], + 'swap usage' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'percent']] + ], + 'Process Resource' => [ + 'cpu' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'percent']], + 'total cpu' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'percent']], + 'threads' => ['_OPERATOR' => ['_VALUE' => null]], + 'children' => ['_OPERATOR' => ['_VALUE' => null]], + 'memory usage' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'amountUnits']], + 'total memory usage' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'percent']] + ], + 'Process Disk I/O' => [ + 'disk read rate' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'operations', '_RATE' => '/s']], + 'disk write rate' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'operations', '_RATE' => '/s']] + ], + 'File Checksum' => [ + 'failed md5 checksum', + 'changed md5 checksum', + 'failed checksum expect' => ['_VALUE' => null] + ], + 'Timestamp' => [ + 'access time' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'timeUnits']], + 'modification time' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'timeUnits']], + 'change time' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'timeUnits']], + 'timestamp' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'timeUnits']], + 'changed access time', + 'changed modification time', + 'changed change time', + 'changed timestamp' + ], + 'File Size' => [ + 'size' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'amountUnits']], + 'changed size' + ], + 'File Content' => [ + 'content =' => ['_VALUE' => null], + 'content !=' => ['_VALUE' => null] + ], + 'Filesystem Mount Flags' => [ + 'changed fsflags' + ], + 'Space Usage' => [ + 'space' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'spaceAmountUnits']], + 'space free' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'spaceAmountUnits']] + ], + 'Inode Usage' => [ + 'inodes' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'amountUnits']], + 'inodes free' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'amountUnits']] + ], + 'Disk I/O' => [ + 'read rate' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'diskAmountUnits', '_RATE' => '/s']], + 'write rate' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'diskAmountUnits', '_RATE' => '/s']], + 'service time' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'millisecond']] + ], + 'Permisssion' => [ + 'failed permission' => ['_VALUE' => null], + 'changed permission' + ], + 'UID' => [ + 'failed uid' => ['_VALUE' => null] + ], + 'GID' => [ + 'failed uid' => ['_VALUE' => null] + ], + 'PID' => [ + 'changed pid' + ], + 'PPID' => [ + 'changed ppid' + ], + 'Uptime' => [ + 'uptime' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'timeUnits']] + ], + 'Program Status' => [ + 'status' => ['_OPERATOR' => ['_VALUE' => null]], + 'changed status' + ], + 'Network Interface' => [ + 'failed link', + 'changed link capacity', + 'saturation' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'percent']], + 'upload' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'netAmountUnits', '_RATE' => '/s']], + 'download' => ['_OPERATOR' => ['_VALUE' => null, '_UNIT' => 'netAmountUnits', '_RATE' => '/s']], + ], + 'Network Ping' => [ + 'failed ping4', + 'failed ping6' + ], + 'Custom' => null + ] + ]; + /** * initialize object properties */ @@ -75,12 +203,18 @@ class SettingsController extends ApiControllerBase * query monit settings * @param $nodeType * @param $uuid + * @param $syntax * @return array result * @throws \Exception */ - public function getAction($nodeType = null, $uuid = null) + public function getAction($nodeType = null, $uuid = null, $syntax = null) { $result = array("result" => "failed"); + if ($syntax != null) { + $result['syntax'] = $this->testSyntax; + $result['result'] = 'ok'; + return $result; + } if ($this->request->isGet() && $nodeType != null) { $this->validateNodeType($nodeType); if ($nodeType == 'general') { @@ -126,6 +260,17 @@ class SettingsController extends ApiControllerBase // perform plugin specific validations if ($nodeType == 'service') { + $tests = explode(',', $monitInfo[$nodeType]['tests']); + foreach ($tests as $testUUID) { + $test = $this->mdlMonit->getNodeByReference('test.' . $testUUID); + if ($test != null) { + $testName = $test->name->__toString(); + $testType = $test->type->getNodeData()[$test->type->__toString()]['value']; + if (array_search($testType, $this->testSyntax['serviceTestMapping'][$monitInfo[$nodeType]['type']]) === false) { + $result["validations"]['monit.service.tests'] = "Test " . $testName . ' with type ' . $testType . ' not allowed for service type ' . $monitInfo[$nodeType]['type']; + } + } + } switch ($monitInfo[$nodeType]['type']) { case 'process': if (empty($monitInfo[$nodeType]['pidfile']) && empty($monitInfo[$nodeType]['match'])) { @@ -263,7 +408,7 @@ class SettingsController extends ApiControllerBase $fields = array("enabled", "name", "type"); break; case 'test': - $fields = array("name", "condition", "action"); + $fields = array("name", "type", "condition", "action"); break; } return $grid->fetchBindRequest($this->request, $fields); diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Monit/forms/tests.xml b/src/opnsense/mvc/app/controllers/OPNsense/Monit/forms/tests.xml index 5d96a0a21..a328a99d6 100644 --- a/src/opnsense/mvc/app/controllers/OPNsense/Monit/forms/tests.xml +++ b/src/opnsense/mvc/app/controllers/OPNsense/Monit/forms/tests.xml @@ -5,6 +5,12 @@ text + + monit.test.type + + dropdown + + monit.test.condition diff --git a/src/opnsense/mvc/app/models/OPNsense/Monit/Migrations/M1_0_8.php b/src/opnsense/mvc/app/models/OPNsense/Monit/Migrations/M1_0_8.php new file mode 100644 index 000000000..ea84ef767 --- /dev/null +++ b/src/opnsense/mvc/app/models/OPNsense/Monit/Migrations/M1_0_8.php @@ -0,0 +1,44 @@ +getNodeByReference('test')->__items as $test) { + $test->type = 'Custom'; + } + } +} + diff --git a/src/opnsense/mvc/app/models/OPNsense/Monit/Monit.xml b/src/opnsense/mvc/app/models/OPNsense/Monit/Monit.xml index 5603268b5..6c912c387 100644 --- a/src/opnsense/mvc/app/models/OPNsense/Monit/Monit.xml +++ b/src/opnsense/mvc/app/models/OPNsense/Monit/Monit.xml @@ -1,6 +1,6 @@ //OPNsense/monit - 1.0.7 + 1.0.8 Monit settings @@ -275,6 +275,33 @@ /^([0-9a-zA-Z\._\- ]){1,255}$/u Should be a string between 1 and 255 characters. Allowed characters are letters and numbers as well as underscore, minus, dot and space. + + Y + + Existence + System Resource + Process Resource + Process Disk I/O + File Checksum + Timestamp + File Size + File Content + Filesystem Mount Flags + Space Usage + Inode Usage + Disk I/O + Permission + UID + GID + PID + PPID + Uptime + Program Status + Network Interface + Network Ping + Custom + + Y /^.{1,255}$/u diff --git a/src/opnsense/mvc/app/views/OPNsense/Monit/index.volt b/src/opnsense/mvc/app/views/OPNsense/Monit/index.volt index c7febc420..a02bd957b 100644 --- a/src/opnsense/mvc/app/views/OPNsense/Monit/index.volt +++ b/src/opnsense/mvc/app/views/OPNsense/Monit/index.volt @@ -1,6 +1,6 @@ {# -Copyright © 2017-2018 by EURO-LOG AG +Copyright © 2017-2019 by EURO-LOG AG All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -28,6 +28,7 @@ POSSIBILITY OF SUCH DAMAGE. @@ -389,6 +687,7 @@ POSSIBILITY OF SUCH DAMAGE. {{ lang._('Name') }} + {{ lang._('Type') }} {{ lang._('Condition') }} {{ lang._('Action') }} {{ lang._('ID') }} diff --git a/src/opnsense/mvc/tests/app/compound/OPNsense/Monit/MonitTest.php b/src/opnsense/mvc/tests/app/compound/OPNsense/Monit/MonitTest.php index 3772ec55f..175c5b829 100644 --- a/src/opnsense/mvc/tests/app/compound/OPNsense/Monit/MonitTest.php +++ b/src/opnsense/mvc/tests/app/compound/OPNsense/Monit/MonitTest.php @@ -1,7 +1,7 @@ ['test' => [ 'name' => 'CPUUsage', + 'type' => 'SystemResource', 'condition' => 'cpu usage is greater than 75%', - 'action' => 'alert' + 'action' => 'alert' ] ]); $response = self::$setMonit->setAction('test'); @@ -211,6 +212,7 @@ class MonitTest extends \PHPUnit\Framework\TestCase $_POST = array('monit' => ['test' => [ 'name' => 'Ping', + 'type' => 'NetworkPing', 'condition' => 'failed ping', 'action' => 'alert' ] @@ -239,10 +241,24 @@ class MonitTest extends \PHPUnit\Framework\TestCase $_POST = array('monit' => ['service' => [ 'enabled' => 1, 'name' => 'Localhost', - 'type' => 'host', + 'type' => 'system', 'tests' => $testConfig['test']['Ping'] ] ]); + $response = self::$setMonit->setAction('service'); + $this->assertCount(1, $response['validations']); + $this->assertEquals($response['result'], 'failed'); + $this->assertNotEmpty($response['validations']['monit.service.tests']); + $this->cleanupNodes('service'); + + $_POST = array('monit' => ['service' => [ + 'enabled' => 1, + 'name' => 'Localhost', + 'type' => 'host', + 'tests' => $testConfig['test']['Ping'] + ] + ]); + $response = self::$setMonit->setAction('service'); $this->assertCount(1, $response['validations']); $this->assertEquals($response['result'], 'failed');