diff --git a/net/relayd/Makefile b/net/relayd/Makefile index d16c606a3..c94f25e2a 100644 --- a/net/relayd/Makefile +++ b/net/relayd/Makefile @@ -1,6 +1,6 @@ PLUGIN_NAME= relayd -PLUGIN_VERSION= 2.5 -PLUGIN_REVISION= 2 +PLUGIN_VERSION= 2.6 +#PLUGIN_REVISION= 2 PLUGIN_DEPENDS= relayd PLUGIN_COMMENT= Relayd Load Balancer PLUGIN_MAINTAINER= frank.brendel@eurolog.com diff --git a/net/relayd/src/opnsense/mvc/app/controllers/OPNsense/Relayd/Api/ServiceController.php b/net/relayd/src/opnsense/mvc/app/controllers/OPNsense/Relayd/Api/ServiceController.php index d255473d4..83eda0132 100644 --- a/net/relayd/src/opnsense/mvc/app/controllers/OPNsense/Relayd/Api/ServiceController.php +++ b/net/relayd/src/opnsense/mvc/app/controllers/OPNsense/Relayd/Api/ServiceController.php @@ -2,6 +2,7 @@ /* * Copyright (C) 2018 EURO-LOG AG + * Copyright (c) 2021 Deciso B.V. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -98,10 +99,9 @@ class ServiceController extends ApiMutableServiceControllerBase $this->sessionClose(); $result['function'] = "reconfigure"; $result['status'] = 'failed'; - $mdlRelayd = new Relayd(); $backend = new Backend(); $status = $this->statusAction(); - if ($mdlRelayd->general->enabled->__toString() == 1) { + if (!empty((string)$this->getModel()->general->enabled)) { $result = $this->configtestAction(); if ($result['template'] == 'OK' && preg_match('/configuration OK$/', $result['result']) == 1) { if ($status['status'] != 'running') { @@ -118,8 +118,7 @@ class ServiceController extends ApiMutableServiceControllerBase } } $this->lock(1); - $mdlRelayd = new Relayd(); - if ($mdlRelayd->configClean()) { + if ($this->getModel()->configClean()) { $result['status'] = 'ok'; } return $result; diff --git a/net/relayd/src/opnsense/mvc/app/controllers/OPNsense/Relayd/Api/SettingsController.php b/net/relayd/src/opnsense/mvc/app/controllers/OPNsense/Relayd/Api/SettingsController.php index 67b0ff009..0f71cf62c 100644 --- a/net/relayd/src/opnsense/mvc/app/controllers/OPNsense/Relayd/Api/SettingsController.php +++ b/net/relayd/src/opnsense/mvc/app/controllers/OPNsense/Relayd/Api/SettingsController.php @@ -2,7 +2,7 @@ /** * Copyright (C) 2018 EURO-LOG AG - * + * Copyright (c) 2021 Deciso B.V. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,7 +30,7 @@ namespace OPNsense\Relayd\Api; -use OPNsense\Base\ApiControllerBase; +use OPNsense\Base\ApiMutableModelControllerBase; use OPNsense\Core\Config; use OPNsense\Relayd\Relayd; use OPNsense\Base\UIModelGrid; @@ -39,25 +39,17 @@ use OPNsense\Base\UIModelGrid; * Class SettingsController * @package OPNsense\Relayd */ -class SettingsController extends ApiControllerBase +class SettingsController extends ApiMutableModelControllerBase { protected static $internalModelName = 'relayd'; protected static $internalModelClass = '\OPNsense\Relayd\Relayd'; - public $mdlRelayd = null; /** * list with valid model node types */ private $nodeTypes = array('general', 'host', 'tablecheck', 'table', 'protocol', 'virtualserver'); - /** - * initialize object properties - */ - public function onConstruct() - { - $this->mdlRelayd = new Relayd(); - } /** * check if changes to the relayd settings were made @@ -66,7 +58,7 @@ class SettingsController extends ApiControllerBase public function dirtyAction() { $result = array('status' => 'ok'); - $result['relayd']['dirty'] = $this->mdlRelayd->configChanged(); + $result['relayd']['dirty'] = $this->getModel()->configChanged(); return $result; } @@ -82,12 +74,12 @@ class SettingsController extends ApiControllerBase if ($this->request->isGet() && $nodeType != null) { $this->validateNodeType($nodeType); if ($nodeType == 'general') { - $node = $this->mdlRelayd->getNodeByReference($nodeType); + $node = $this->getModel()->getNodeByReference($nodeType); } else { if ($uuid != null) { - $node = $this->mdlRelayd->getNodeByReference($nodeType . '.' . $uuid); + $node = $this->getModel()->getNodeByReference($nodeType . '.' . $uuid); } else { - $node = $this->mdlRelayd->$nodeType->Add(); + $node = $this->getModel()->$nodeType->Add(); } } if ($node != null) { @@ -111,12 +103,12 @@ class SettingsController extends ApiControllerBase if ($this->request->isPost() && $this->request->hasPost('relayd') && $nodeType != null) { $this->validateNodeType($nodeType); if ($nodeType == 'general') { - $node = $this->mdlRelayd->getNodeByReference($nodeType); + $node = $this->getModel()->getNodeByReference($nodeType); } else { if ($uuid != null) { - $node = $this->mdlRelayd->getNodeByReference($nodeType . '.' . $uuid); + $node = $this->getModel()->getNodeByReference($nodeType . '.' . $uuid); } else { - $node = $this->mdlRelayd->$nodeType->Add(); + $node = $this->getModel()->$nodeType->Add(); } } if ($node != null) { @@ -207,16 +199,16 @@ class SettingsController extends ApiControllerBase } $node->setNodes($relaydInfo[$nodeType]); - $valMsgs = $this->mdlRelayd->performValidation(); + $valMsgs = $this->getModel()->performValidation(); foreach ($valMsgs as $field => $msg) { $fieldnm = str_replace($node->__reference, "relayd." . $nodeType, $msg->getField()); $result["validations"][$fieldnm] = $msg->getMessage(); } if (empty($result["validations"])) { unset($result["validations"]); - $this->mdlRelayd->serializeToConfig(); + $this->getModel()->serializeToConfig(); $cfgRelayd = Config::getInstance()->save(); - if ($this->mdlRelayd->configDirty()) { + if ($this->getModel()->configDirty()) { $result['status'] = 'ok'; } } @@ -234,13 +226,14 @@ class SettingsController extends ApiControllerBase public function delAction($nodeType = null, $uuid = null) { $result = array("result" => "failed"); + Config::getInstance()->lock(); if ($nodeType != null) { $this->validateNodeType($nodeType); if ($uuid != null) { - $node = $this->mdlRelayd->getNodeByReference($nodeType . '.' . $uuid); + $node = $this->getModel()->getNodeByReference($nodeType . '.' . $uuid); if ($node != null) { - $nodeName = $this->mdlRelayd->getNodeByReference($nodeType . '.' . $uuid . '.name')->__toString(); - if ($this->mdlRelayd->$nodeType->del($uuid) == true) { + $nodeName = $this->getModel()->getNodeByReference($nodeType . '.' . $uuid . '.name')->__toString(); + if ($this->getModel()->$nodeType->del($uuid) == true) { // delete relations switch ($nodeType) { case 'host': @@ -250,7 +243,7 @@ class SettingsController extends ApiControllerBase $uuid, 'host', $nodeName, - $this->mdlRelayd + $this->getModel() ); break; case 'tablecheck': @@ -260,7 +253,7 @@ class SettingsController extends ApiControllerBase $uuid, 'tablecheck', $nodeName, - $this->mdlRelayd + $this->getModel() ); $this->deleteRelations( 'virtualserver', @@ -268,7 +261,7 @@ class SettingsController extends ApiControllerBase $uuid, 'tablecheck', $nodeName, - $this->mdlRelayd + $this->getModel() ); break; case 'table': @@ -278,7 +271,7 @@ class SettingsController extends ApiControllerBase $uuid, 'table', $nodeName, - $this->mdlRelayd + $this->getModel() ); $this->deleteRelations( 'virtualserver', @@ -286,7 +279,7 @@ class SettingsController extends ApiControllerBase $uuid, 'table', $nodeName, - $this->mdlRelayd + $this->getModel() ); break; case 'protocol': @@ -296,13 +289,13 @@ class SettingsController extends ApiControllerBase $uuid, 'protocol', $nodeName, - $this->mdlRelayd + $this->getModel() ); break; } - $this->mdlRelayd->serializeToConfig(); + $this->getModel()->serializeToConfig(); Config::getInstance()->save(); - if ($this->mdlRelayd->configDirty()) { + if ($this->getModel()->configDirty()) { $result['status'] = 'ok'; } } @@ -312,6 +305,21 @@ class SettingsController extends ApiControllerBase return $result; } + /** + * toggle status + * @param string $nodeType node type to address + * @param string $uuid id to toggled + * @param string|null $enabled set enabled by default + * @return array status + * @throws \Phalcon\Validation\Exception when field validations fail + * @throws \ReflectionException when not bound to model + */ + public function toggleAction($nodeType, $uuid, $enabled = null) + { + $this->getModel()->configDirty(); + return $this->toggleBase($nodeType, $uuid, $enabled); + } + /** * search relayd settings * @param $nodeType @@ -322,11 +330,11 @@ class SettingsController extends ApiControllerBase $this->sessionClose(); if ($this->request->isPost() && $nodeType != null) { $this->validateNodeType($nodeType); - $grid = new UIModelGrid($this->mdlRelayd->$nodeType); + $grid = new UIModelGrid($this->getModel()->$nodeType); $fields = array(); switch ($nodeType) { case 'host': - $fields = array('name', 'address'); + $fields = array('enabled', 'name', 'address'); break; case 'tablecheck': $fields = array('name', 'type'); @@ -342,7 +350,7 @@ class SettingsController extends ApiControllerBase break; } $result = $grid->fetchBindRequest($this->request, $fields); - $result['dirty'] = $this->mdlRelayd->configChanged(); + $result['dirty'] = $this->getModel()->configChanged(); return $result; } } @@ -374,7 +382,7 @@ class SettingsController extends ApiControllerBase $relNodeType = null, $relNodeName = null ) { - $nodes = $this->mdlRelayd->$nodeType->getNodes(); + $nodes = $this->getModel()->$nodeType->getNodes(); // get nodes with relations foreach ($nodes as $nodeUuid => $node) { // get relation uuids @@ -382,14 +390,14 @@ class SettingsController extends ApiControllerBase // remove uuid from field if ($fieldUuid == $relUuid) { $refField = $nodeType . '.' . $nodeUuid . '.' . $nodeField; - $relNode = $this->mdlRelayd->getNodeByReference($refField); + $relNode = $this->getModel()->getNodeByReference($refField); $nodeRels = str_replace($relUuid, '', $relNode->__toString()); $nodeRels = str_replace(',,', ',', $nodeRels); $nodeRels = rtrim($nodeRels, ','); $nodeRels = ltrim($nodeRels, ','); - $this->mdlRelayd->setNodeByReference($refField, $nodeRels); + $this->getModel()->setNodeByReference($refField, $nodeRels); if ($relNode->isEmptyAndRequired()) { - $nodeName = $this->mdlRelayd->getNodeByReference("{$nodeType}.{$nodeUuid}.name")->__toString(); + $nodeName = $this->getModel()->getNodeByReference("{$nodeType}.{$nodeUuid}.name")->__toString(); throw new \Exception("Cannot delete $relNodeType '$relNodeName' from $nodeType '$nodeName'"); } } diff --git a/net/relayd/src/opnsense/mvc/app/controllers/OPNsense/Relayd/Api/StatusController.php b/net/relayd/src/opnsense/mvc/app/controllers/OPNsense/Relayd/Api/StatusController.php index deb9a75e6..dfd721fcb 100644 --- a/net/relayd/src/opnsense/mvc/app/controllers/OPNsense/Relayd/Api/StatusController.php +++ b/net/relayd/src/opnsense/mvc/app/controllers/OPNsense/Relayd/Api/StatusController.php @@ -2,6 +2,7 @@ /** * Copyright (C) 2018 EURO-LOG AG + * Copyright (c) 2021 Deciso B.V. * * All rights reserved. * @@ -32,6 +33,7 @@ namespace OPNsense\Relayd\Api; use OPNsense\Base\ApiControllerBase; use OPNsense\Core\Backend; +use OPNsense\Core\Config; use OPNsense\Relayd\Relayd; /** @@ -43,15 +45,32 @@ class StatusController extends ApiControllerBase /** * get relayd summary */ - public function sumAction() + public function sumAction($wait=0) { $result = array("result" => "failed"); $backend = new Backend(); + $relaydMdl = new Relayd(); + + // when $wait is set, try for max 10 seconds to receive a sensible status (wait for unknowns to resolve) + $max_tries = !empty($wait) ? 10 : 1; $output = array(); - $output = explode("\n", trim($backend->configdRun('relayd summary'))); + for ($i = 0; $i < $max_tries; $i++) { + $output = explode("\n", trim($backend->configdRun('relayd summary'))); + $unknowns = 0; + foreach ($output as $line) { + if (substr($line, -strlen("unknown")) == "unknown") { + $unknowns++; + } + } + if (!empty($output[0]) && $unknowns == 0) { + break; + } + sleep(1); + } if (empty($output[0])) { return $result; } + $output[] = "0\t****\t"; // end of data marker $result["result"] = 'ok'; $virtualServerId = 0; $virtualServerType = ''; @@ -59,40 +78,119 @@ class StatusController extends ApiControllerBase $virtualserver = array(); $rows = array(); foreach ($output as $line) { - $words = explode("\t", $line); - $id = trim($words[0]); - $type = trim($words[1]); - if ($type == 'redirect' || $type == 'relay') { + $words = array_map('trim', explode("\t", $line)); + $id = $words[0]; + $type = $words[1]; + if ($type == 'redirect' || $type == 'relay' || $type == '****') { // new virtual server id/type means new record if ( - ($id != $virtualServerId - && $virtualServerId > 0) - || ($type != $virtualServerType - && strlen($virtualServerType) > 5) + ($id != $virtualServerId && $virtualServerId > 0) || + ($type != $virtualServerType && strlen($virtualServerType) > 5) || + ($type == '****' && !empty($virtualserver)) ) { + // append backend hosts not found in the list, since relayd only supports disabled tables + // you might loose track of hosts that are disabled + if (!empty($virtualserver['tables'])) { + foreach ($virtualserver['tables'] as &$table) { + if (!empty($table['uuid'])) { + $tblnode = $relaydMdl->getNodeByReference("table.".$table['uuid']); + foreach (explode(",", (string)$tblnode->hosts) as $host_uuid) { + $found = false; + if (!empty($table['hosts'])) { + foreach ($table['hosts'] as $tblhost) { + foreach ($tblhost['properties'] as $hprops) { + if ($hprops['uuid'] == $host_uuid) { + $found = true; + } + } + } + } else { + $table['hosts'] = []; + } + if (!$found) { + $hostnode = $relaydMdl->getNodeByReference("host.".$host_uuid); + $table['hosts'][$host_uuid] = [ + "name" => (string)$hostnode->address, + "description" => (string)$hostnode->name, + "avlblty" => null, + "status" => empty((string)$hostnode->enabled) ? "disabled" : "-", + "properties" => [ + [ + "uuid" => $host_uuid, + "name" => (string)$hostnode->name, + "enabled" => (string)$hostnode->enabled + ] + ] + ]; + } + } + } + } + } $rows[] = $virtualserver; - $virtualserver = array(); + if ($type == '****') { + break; // end + } + $virtualserver = []; } $virtualServerId = $id; $virtualServerType = $type; $virtualserver['id'] = $id; $virtualserver['type'] = $type; - $virtualserver['name'] = trim($words[2]); - $virtualserver['status'] = trim($words[4]); - } - if ($type == 'table') { + $virtualserver['name'] = $words[2]; + $virtualserver['status'] = $words[4]; + $objs = $relaydMdl->getObjectsByAttribute("virtualserver", "name", $virtualserver['name']); + if (count($objs) > 0) { + $obj = $objs[0]; + $virtualserver['uuid'] = $obj->getAttribute('uuid'); + $virtualserver['listen_address'] = (string)$obj->listen_address; + $virtualserver['listen_startport'] = (string)$obj->listen_startport; + $virtualserver['listen_endport'] = (string)$obj->listen_endport; + } + } elseif ($type == 'table') { $tableId = $id; - $virtualserver['tables'][$tableId]['name'] = trim($words[2]); - $virtualserver['tables'][$tableId]['status'] = trim($words[4]); - } - if ($type == 'host') { + if (empty($virtualserver['tables'])) { + $virtualserver['tables'] = []; + } + $virtualserver['tables'][$tableId] = []; + $virtualserver['tables'][$tableId]['name'] = $words[2]; + $virtualserver['tables'][$tableId]['status'] = $words[4]; + $objs = $relaydMdl->getObjectsByAttribute("table", "name", explode(":", $words[2])[0]); + if (count($objs) > 0) { + $virtualserver['tables'][$tableId]['uuid'] = $objs[0]->getAttribute('uuid'); + } + } elseif ($type == 'host') { $hostId = trim($words[0]); - $virtualserver['tables'][$tableId]['hosts'][$hostId]['name'] = trim($words[2]); - $virtualserver['tables'][$tableId]['hosts'][$hostId]['avlblty'] = trim($words[3]); - $virtualserver['tables'][$tableId]['hosts'][$hostId]['status'] = trim($words[4]); + if (empty($virtualserver['tables'][$tableId]['hosts'])) { + $virtualserver['tables'][$tableId]['hosts'] = []; + } + $virtualserver['tables'][$tableId]['hosts'][$hostId] = ['properties' => []]; + $virtualserver['tables'][$tableId]['hosts'][$hostId]['name'] = $words[2]; + $virtualserver['tables'][$tableId]['hosts'][$hostId]['avlblty'] = $words[3]; + $status = $words[4] == 'disabled' ? 'stopped' : $words[4]; + $virtualserver['tables'][$tableId]['hosts'][$hostId]['status'] = $status; + // XXX: `relayctl show summary` name is actually the number, append name as description when found + $objs = $relaydMdl->getObjectsByAttribute("host", "address", $words[2]); + if (count($objs) > 0) { + $linked_hosts = []; + if (!empty($virtualserver['tables'][$tableId]['uuid'])) { + $tblnode = $relaydMdl->getNodeByReference("table.".$virtualserver['tables'][$tableId]['uuid']); + $linked_hosts = explode(",", (string)$tblnode->hosts); + } + // hosts aren't necessarily unique due to address matching + foreach ($objs as $obj) { + $this_uuid = $obj->getAttribute('uuid'); + if (empty($linked_hosts) || in_array($this_uuid, $linked_hosts)) { + $virtualserver['tables'][$tableId]['hosts'][$hostId]['properties'][] = [ + 'uuid' => $this_uuid, + 'name' => (string)$obj->name, + "enabled" => (string)$obj->enabled + ]; + } + } + } } } - $rows[] = $virtualserver; $result["rows"] = $rows; return $result; } @@ -102,29 +200,32 @@ class StatusController extends ApiControllerBase */ public function toggleAction($nodeType = null, $id = null, $action = null) { + $result = array("result" => "failed", "function" => "toggle"); if ($this->request->isPost()) { $this->sessionClose(); - } - $result = array("result" => "failed", "function" => "toggle"); - if ( - $nodeType != null && - ($nodeType == 'redirect' || - $nodeType == 'table' || - $nodeType == 'host') - ) { - if ( - $action != null && - ($action == 'enable' || - $action == 'disable') - ) { + $backend = new Backend(); + if (in_array($nodeType, ['redirect', 'table', 'host']) && in_array($action, ['enable', 'disable'])){ if ($id != null && $id > 0) { - $backend = new Backend(); - $result["output"] = $backend->configdRun("relayd toggle $nodeType $action $id"); + $result["output"] = $backend->configdpRun("relayd toggle",[$nodeType, $action, $id]); if (isset($result["output"])) { $result["result"] = 'ok'; } $result["output"] = trim($result["output"]); } + } elseif ($nodeType == 'host' && in_array($action, ['remove', 'add'])) { + Config::getInstance()->lock(); + $new_status = $action == "remove" ? "0" : "1"; + $relaydMdl = new Relayd(); + foreach (explode(",", $id) as $host_uuid) { + $obj = $relaydMdl->getNodeByReference("host.".$host_uuid); + if ($obj != null) { + $obj->enabled = $new_status; + } + } + $relaydMdl->serializeToConfig(); + Config::getInstance()->save(); + // invoke service controller + return (new ServiceController())->reconfigureAction(); } } return $result; diff --git a/net/relayd/src/opnsense/mvc/app/controllers/OPNsense/Relayd/forms/host.xml b/net/relayd/src/opnsense/mvc/app/controllers/OPNsense/Relayd/forms/host.xml index 1c6967ae0..09dcea4fa 100644 --- a/net/relayd/src/opnsense/mvc/app/controllers/OPNsense/Relayd/forms/host.xml +++ b/net/relayd/src/opnsense/mvc/app/controllers/OPNsense/Relayd/forms/host.xml @@ -1,4 +1,10 @@
+ + relayd.host.enabled + + checkbox + Set this option to enable this destination. + relayd.host.name diff --git a/net/relayd/src/opnsense/mvc/app/models/OPNsense/Relayd/Relayd.php b/net/relayd/src/opnsense/mvc/app/models/OPNsense/Relayd/Relayd.php index e80a832e0..0669849ed 100644 --- a/net/relayd/src/opnsense/mvc/app/models/OPNsense/Relayd/Relayd.php +++ b/net/relayd/src/opnsense/mvc/app/models/OPNsense/Relayd/Relayd.php @@ -64,4 +64,21 @@ class Relayd extends BaseModel { return @unlink("/tmp/relayd.dirty"); } + + /** + * @param string $type type of object (host, table, virtualserver) + * @param string $name name of the attribute + * @param string $value value to match + * @return ArrayField[] items found + */ + public function getObjectsByAttribute($type, $name, $value) + { + $results = []; + foreach ($this->$type->iterateItems() as $item) { + if ((string)$item->$name == $value) { + $results[] = $item; + } + } + return $results; + } } diff --git a/net/relayd/src/opnsense/mvc/app/models/OPNsense/Relayd/Relayd.xml b/net/relayd/src/opnsense/mvc/app/models/OPNsense/Relayd/Relayd.xml index a67061d67..60852198b 100644 --- a/net/relayd/src/opnsense/mvc/app/models/OPNsense/Relayd/Relayd.xml +++ b/net/relayd/src/opnsense/mvc/app/models/OPNsense/Relayd/Relayd.xml @@ -1,6 +1,6 @@ //OPNsense/relayd - 1.0.2 + 1.0.3 Relayd settings @@ -35,10 +35,20 @@ + + 1 + Y + Y /^([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. + + + Host names should be unique. + UniqueConstraint + +
Y @@ -67,6 +77,12 @@ Y /^([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. + + + Table names should be unique. + UniqueConstraint + + 0 @@ -134,6 +150,12 @@ Y /^([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. + + + Virtual server names should be unique. + UniqueConstraint + + 0 diff --git a/net/relayd/src/opnsense/mvc/app/views/OPNsense/Relayd/index.volt b/net/relayd/src/opnsense/mvc/app/views/OPNsense/Relayd/index.volt index 0544e23d1..0b1ea7e48 100644 --- a/net/relayd/src/opnsense/mvc/app/views/OPNsense/Relayd/index.volt +++ b/net/relayd/src/opnsense/mvc/app/views/OPNsense/Relayd/index.volt @@ -1,6 +1,7 @@ {# Copyright © 2018 by EURO-LOG AG +Copyright (c) 2021 Deciso B.V. All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -95,13 +96,17 @@ POSSIBILITY OF SUCH DAMAGE. }); ['host', 'tablecheck', 'table', 'protocol', 'virtualserver'].forEach(function(element) { - $("#grid-" + element).UIBootgrid({ + let endpoints = { 'search': '/api/relayd/settings/search/' + element + '/', 'get': '/api/relayd/settings/get/' + element + '/', 'set': '/api/relayd/settings/set/' + element + '/', 'add': '/api/relayd/settings/set/' + element + '/', 'del': '/api/relayd/settings/del/' + element + '/' - }); + }; + if (['virtualserver', 'host', 'table'].includes(element)) { + endpoints['toggle'] = '/api/relayd/settings/toggle/' + element + '/'; + } + $("#grid-" + element).UIBootgrid(endpoints); }); // show/hide options depending on other options @@ -239,6 +244,7 @@ POSSIBILITY OF SUCH DAMAGE. + @@ -285,7 +291,7 @@ POSSIBILITY OF SUCH DAMAGE.
{{ lang._('Enabled') }} {{ lang._('Name') }} {{ lang._('Address') }} {{ lang._('ID') }}
- + @@ -331,7 +337,7 @@ POSSIBILITY OF SUCH DAMAGE.
{{ lang._('Enabled') }}{{ lang._('Enabled') }} {{ lang._('Name') }} {{ lang._('ID') }} {{ lang._('Edit') }} | {{ lang._('Delete') }}
- + diff --git a/net/relayd/src/opnsense/mvc/app/views/OPNsense/Relayd/status.volt b/net/relayd/src/opnsense/mvc/app/views/OPNsense/Relayd/status.volt index 0bcee42f7..c3a15c73b 100644 --- a/net/relayd/src/opnsense/mvc/app/views/OPNsense/Relayd/status.volt +++ b/net/relayd/src/opnsense/mvc/app/views/OPNsense/Relayd/status.volt @@ -1,6 +1,7 @@ {# Copyright © 2018 by EURO-LOG AG +Copyright (c) 2021 Deciso B.V. All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -27,128 +28,462 @@ POSSIBILITY OF SUCH DAMAGE. #} -
-
{{ lang._('Enabled') }}{{ lang._('Enabled') }} {{ lang._('Name') }} {{ lang._('Type') }} {{ lang._('ID') }}
- - -
{{ lang._('Virtual Server') }}{{ lang._('Table') }}{{ lang._('Host') }}
-
-
- - - - -
-
- -
-
+ + + + + +
+
+ + {{ lang._('Presets') }} +
+
+ +
+ + + +
+ + +
+
+
+
+ + + + + + + + + + + + + + + + + + + +
{{ lang._('Virtual Server') }}{{ lang._('Table') }}{{ lang._('Host') }}
+
+ +
+
+
diff --git a/net/relayd/src/opnsense/service/templates/OPNsense/Relayd/relayd.conf b/net/relayd/src/opnsense/service/templates/OPNsense/Relayd/relayd.conf index f8b6b9bbc..5f99db895 100644 --- a/net/relayd/src/opnsense/service/templates/OPNsense/Relayd/relayd.conf +++ b/net/relayd/src/opnsense/service/templates/OPNsense/Relayd/relayd.conf @@ -1,6 +1,7 @@ # DO NOT EDIT THIS FILE -- OPNsense auto-generated file {% from 'OPNsense/Macros/interface.macro' import physical_interface %} +{% set all_active_tables = [] %} {% if helpers.exists('OPNsense.relayd.general') %} {% if helpers.exists('OPNsense.relayd.general.interval') %} interval {{ OPNsense.relayd.general.interval }} @@ -18,21 +19,30 @@ timeout {{ OPNsense.relayd.general.timeout }} {% if helpers.exists('OPNsense.relayd.table') %} {% for table in helpers.toList('OPNsense.relayd.table') %} -{% set name = table.name %} {% set disable = '' %} -{% set hosts = '' %} +{% set hosts = [] %} {% if table.enabled|default('1') == '0' %} {% set disable = ' disable' %} {% endif %} -table <{{ name }}>{{ disable }} { -{% for host in table.hosts.split(",") %} -{% set host = helpers.getUUID(host) %} -{% set ipTTL = " ip ttl " ~ host.ipTTL if host.ipTTL is defined %} -{% set priority = " priority " ~ host.priority if host.priority is defined %} -{% set retry = " retry " ~ host.retry if host.retry is defined %} +{% for hostid in table.hosts.split(",") %} +{% set host = helpers.getUUID(hostid) %} +{% if host.enabled|default("1") == "1" %} +{% do hosts.append(host) %} +{% endif %} +{% endfor %} +{% if hosts|length > 0 %} +table <{{ table.name }}>{{ disable }} { +{% do all_active_tables.append(table['@uuid']) %} +{% for host in hosts %} +{% set ipTTL = " ip ttl " ~ host.ipTTL if host.ipTTL is defined %} +{% set priority = " priority " ~ host.priority if host.priority is defined %} +{% set retry = " retry " ~ host.retry if host.retry is defined %} +{% if host.enabled|default("1") == "1" %} {{ host.address }}{{ ipTTL }}{{ priority }}{{ retry }} -{% endfor %} +{% endif %} +{% endfor %} } +{% endif %} {% endfor %} {% endif %} @@ -45,106 +55,110 @@ table <{{ name }}>{{ disable }} { {% endif %} {% if helpers.exists('OPNsense.relayd.virtualserver') %} -{% for virtualserver in helpers.toList('OPNsense.relayd.virtualserver') %} +{% for virtualserver in helpers.toList('OPNsense.relayd.virtualserver') %} +{% if virtualserver.transport_table in all_active_tables or virtualserver.backuptransport_table in all_active_tables %} {{ virtualserver.type }} "{{virtualserver.name}}" { -{% if virtualserver.enabled|default('1') == '0' %} +{% if virtualserver.enabled|default('1') == '0' %} disable -{% endif %} -{% set listen = "listen on " ~ virtualserver.listen_address %} -{% if virtualserver.listen_startport is defined %} -{% set listen = listen ~ " port " ~ virtualserver.listen_startport %} -{% if virtualserver.listen_endport is defined and virtualserver.type == 'redirect'%} -{% set listen = listen ~ ":" ~ virtualserver.listen_endport %} -{% endif %} -{% endif %} -{% if virtualserver.listen_interface is defined and virtualserver.type == 'redirect' %} -{% set listen = listen ~ " interface " ~ physical_interface(virtualserver.listen_interface) %} -{% endif %} +{% endif %} +{% set listen = "listen on " ~ virtualserver.listen_address %} +{% if virtualserver.listen_startport is defined %} +{% set listen = listen ~ " port " ~ virtualserver.listen_startport %} +{% if virtualserver.listen_endport is defined and virtualserver.type == 'redirect'%} +{% set listen = listen ~ ":" ~ virtualserver.listen_endport %} +{% endif %} +{% endif %} +{% if virtualserver.listen_interface is defined and virtualserver.type == 'redirect' %} +{% set listen = listen ~ " interface " ~ physical_interface(virtualserver.listen_interface) %} +{% endif %} {{ listen }} -{% set transport_type = 'forward' %} -{% if virtualserver.type == 'redirect' %} -{% set transport_type = virtualserver.transport_type %} -{% if virtualserver.transport_type == 'route' %} -{% set routing_interface = " interface " ~ virtualserver.routing_interface %} -{% endif %} -{% endif %} -{% set table = helpers.getUUID(virtualserver.transport_table) %} -{% set tablecheck = helpers.getUUID(virtualserver.transport_tablecheck) %} -{% set _tablecheck = '' %} -{% if tablecheck.type == 'http' and tablecheck.path is defined %} -{% set _tablecheck = 'check ' ~ tablecheck.type %} -{% if tablecheck.ssl|default('0') == '1' %} -{% set _tablecheck = _tablecheck ~ 's' %} -{% endif %} -{% set _tablecheck = _tablecheck ~ ' "' ~ tablecheck.path ~ '"' %} -{% if tablecheck.host is defined %} -{% set _tablecheck = _tablecheck ~ ' host ' ~ tablecheck.host %} -{% endif %} -{% if tablecheck.code is defined %} -{% set _tablecheck = _tablecheck ~ ' code ' ~ tablecheck.code %} -{% elif tablecheck.digest is defined %} -{% set _tablecheck = _tablecheck ~ ' digest "' ~ tablecheck.digest ~ '"' %} -{% else %} -{% set _tablecheck = '' %} -{% endif %} -{% elif tablecheck.type == 'script' and tablecheck.path is defined %} -{% set _tablecheck = 'check ' ~ tablecheck.type ~ ' "' ~ tablecheck.path ~ '"' %} -{% elif tablecheck.type == 'send' and tablecheck.expect is defined %} -{% set _tablecheck = 'check ' ~ tablecheck.type ~ ' "' ~ tablecheck.data ~ '" expect "' ~ tablecheck.expect ~ '"' %} -{% if tablecheck.ssl|default('0') == '1' %} -{% set _tablecheck = _tablecheck ~ ' ssl' %} -{% endif %} -{% else %} -{% set _tablecheck = 'check ' ~ tablecheck.type %} -{% endif %} -{% set port = " port " ~ virtualserver.transport_port if virtualserver.transport_port is defined %} -{% set timeout = " timeout " ~ virtualserver.transport_timeout if virtualserver.transport_timeout is defined %} -{% set interval = " interval " ~ virtualserver.transport_interval if virtualserver.transport_interval is defined %} +{% set transport_type = 'forward' %} +{% if virtualserver.type == 'redirect' %} +{% set transport_type = virtualserver.transport_type %} +{% if virtualserver.transport_type == 'route' %} +{% set routing_interface = " interface " ~ virtualserver.routing_interface %} +{% endif %} +{% endif %} +{% if virtualserver.transport_table in all_active_tables %} +{% set table = helpers.getUUID(virtualserver.transport_table) %} +{% set tablecheck = helpers.getUUID(virtualserver.transport_tablecheck) %} +{% set _tablecheck = '' %} +{% if tablecheck.type == 'http' and tablecheck.path is defined %} +{% set _tablecheck = 'check ' ~ tablecheck.type %} +{% if tablecheck.ssl|default('0') == '1' %} +{% set _tablecheck = _tablecheck ~ 's' %} +{% endif %} +{% set _tablecheck = _tablecheck ~ ' "' ~ tablecheck.path ~ '"' %} +{% if tablecheck.host is defined %} +{% set _tablecheck = _tablecheck ~ ' host ' ~ tablecheck.host %} +{% endif %} +{% if tablecheck.code is defined %} +{% set _tablecheck = _tablecheck ~ ' code ' ~ tablecheck.code %} +{% elif tablecheck.digest is defined %} +{% set _tablecheck = _tablecheck ~ ' digest "' ~ tablecheck.digest ~ '"' %} +{% else %} +{% set _tablecheck = '' %} +{% endif %} +{% elif tablecheck.type == 'script' and tablecheck.path is defined %} +{% set _tablecheck = 'check ' ~ tablecheck.type ~ ' "' ~ tablecheck.path ~ '"' %} +{% elif tablecheck.type == 'send' and tablecheck.expect is defined %} +{% set _tablecheck = 'check ' ~ tablecheck.type ~ ' "' ~ tablecheck.data ~ '" expect "' ~ tablecheck.expect ~ '"' %} +{% if tablecheck.ssl|default('0') == '1' %} +{% set _tablecheck = _tablecheck ~ ' ssl' %} +{% endif %} +{% else %} +{% set _tablecheck = 'check ' ~ tablecheck.type %} +{% endif %} +{% set port = " port " ~ virtualserver.transport_port if virtualserver.transport_port is defined %} +{% set timeout = " timeout " ~ virtualserver.transport_timeout if virtualserver.transport_timeout is defined %} +{% set interval = " interval " ~ virtualserver.transport_interval if virtualserver.transport_interval is defined %} {{ transport_type }} to <{{ table.name }}>{{ port }} mode {{ virtualserver.transport_tablemode }}{{ timeout }} {{ interval }} {{ _tablecheck }} {{ routing_interface }} -{% if virtualserver.backuptransport_table is defined and virtualserver.transport_type == 'forward' %} -{% set backuptable = helpers.getUUID(virtualserver.backuptransport_table) %} -{% set backuptablecheck = helpers.getUUID(virtualserver.backuptransport_tablecheck) if virtualserver.backuptransport_tablecheck is defined %} -{% set _backuptablecheck = '' %} -{% if backuptablecheck.type == 'http' and backuptablecheck.path is defined%} -{% set _backuptablecheck = 'check ' ~ backuptablecheck.type %} -{% if backuptablecheck.ssl|default('0') == '1' %} -{% set _backuptablecheck = _backuptablecheck ~ 's' %} -{% endif %} -{% set _backuptablecheck = _backuptablecheck ~ ' "' ~ backuptablecheck.path ~ '"' %} -{% if backuptablecheck.host is defined %} -{% set _backuptablecheck = _backuptablecheck ~ ' host ' ~ backuptablecheck.host %} -{% endif %} -{% if backuptablecheck.code is defined %} -{% set _backuptablecheck = _backuptablecheck ~ ' code ' ~ backuptablecheck.code %} -{% elif backuptablecheck.digest is defined %} -{% set _backuptablecheck = _backuptablecheck ~ ' digest "' ~ backuptablecheck.digest ~ '"' %} -{% else %} -{% set _backuptablecheck = '' %} -{% endif %} -{% elif backuptablecheck.type == 'script' and backuptablecheck.path is defined %} -{% set _backuptablecheck = 'check ' ~ backuptablecheck.type ~ ' "' ~ backuptablecheck.path ~ '"' %} -{% elif backuptablecheck.type == 'send' and backuptablecheck.expect is defined %} -{% set _backuptablecheck = 'check ' ~ backuptablecheck.type ~ ' "' ~ backuptablecheck.data ~ '" expect "' ~ backuptablecheck.expect ~ '"' %} -{% if backuptablecheck.ssl|default('0') == '1' %} -{% set _backuptablecheck = _backuptablecheck ~ ' ssl' %} -{% endif %} -{% else %} -{% set _backuptablecheck = 'check ' ~ backuptablecheck.type %} -{% endif %} -{% set backuptimeout = " timeout " ~ virtualserver.backuptransport_timeout if virtualserver.backuptransport_timeout is defined %} -{% set backupinterval = " interval " ~ virtualserver.backuptransport_interval if virtualserver.backuptransport_interval is defined %} +{% endif %} +{% set backuptablecheck = helpers.getUUID(virtualserver.backuptransport_tablecheck) if virtualserver.backuptransport_tablecheck is defined else None%} +{% if backuptablecheck and virtualserver.backuptransport_table is defined and virtualserver.backuptransport_table in all_active_tables and virtualserver.transport_type == 'forward' %} +{% set backuptable = helpers.getUUID(virtualserver.backuptransport_table) %} +{% set _backuptablecheck = '' %} +{% if backuptablecheck.type == 'http' and backuptablecheck.path is defined%} +{% set _backuptablecheck = 'check ' ~ backuptablecheck.type %} +{% if backuptablecheck.ssl|default('0') == '1' %} +{% set _backuptablecheck = _backuptablecheck ~ 's' %} +{% endif %} +{% set _backuptablecheck = _backuptablecheck ~ ' "' ~ backuptablecheck.path ~ '"' %} +{% if backuptablecheck.host is defined %} +{% set _backuptablecheck = _backuptablecheck ~ ' host ' ~ backuptablecheck.host %} +{% endif %} +{% if backuptablecheck.code is defined %} +{% set _backuptablecheck = _backuptablecheck ~ ' code ' ~ backuptablecheck.code %} +{% elif backuptablecheck.digest is defined %} +{% set _backuptablecheck = _backuptablecheck ~ ' digest "' ~ backuptablecheck.digest ~ '"' %} +{% else %} +{% set _backuptablecheck = '' %} +{% endif %} +{% elif backuptablecheck.type == 'script' and backuptablecheck.path is defined %} +{% set _backuptablecheck = 'check ' ~ backuptablecheck.type ~ ' "' ~ backuptablecheck.path ~ '"' %} +{% elif backuptablecheck.type == 'send' and backuptablecheck.expect is defined %} +{% set _backuptablecheck = 'check ' ~ backuptablecheck.type ~ ' "' ~ backuptablecheck.data ~ '" expect "' ~ backuptablecheck.expect ~ '"' %} +{% if backuptablecheck.ssl|default('0') == '1' %} +{% set _backuptablecheck = _backuptablecheck ~ ' ssl' %} +{% endif %} +{% else %} +{% set _backuptablecheck = 'check ' ~ backuptablecheck.type %} +{% endif %} +{% set backuptimeout = " timeout " ~ virtualserver.backuptransport_timeout if virtualserver.backuptransport_timeout is defined %} +{% set backupinterval = " interval " ~ virtualserver.backuptransport_interval if virtualserver.backuptransport_interval is defined %} {{ transport_type }} to <{{ backuptable.name }}>{{ port }} mode {{ virtualserver.transport_tablemode }}{{ backuptimeout }} {{ backupinterval }} {{ _backuptablecheck }} -{% endif %} -{% if virtualserver.sessiontimeout is defined %} +{% endif %} +{% if virtualserver.sessiontimeout is defined %} session timeout {{ virtualserver.sessiontimeout }} -{% endif %} -{% if virtualserver.stickyaddress|default('0') == '1' and virtualserver.type == 'redirect' %} +{% endif %} +{% if virtualserver.stickyaddress|default('0') == '1' and virtualserver.type == 'redirect' %} sticky-address -{% endif %} -{% if virtualserver.protocol is defined and virtualserver.type == 'relay' %} -{% set protocol = helpers.getUUID(virtualserver.protocol) %} +{% endif %} +{% if virtualserver.protocol is defined and virtualserver.type == 'relay' %} +{% set protocol = helpers.getUUID(virtualserver.protocol) %} protocol "{{ protocol.name }}" -{% endif %} +{% endif %} } -{% endfor %} +{% endif %} +{% endfor %} {% endif %}