From 56eeee5f1e59b7766ca9fba6dd0eece8f777e111 Mon Sep 17 00:00:00 2001 From: Ad Schellevis Date: Wed, 15 May 2024 17:48:26 +0200 Subject: [PATCH] Services: Kea DHCP [new]: Kea DHCPv4 - add Custom options tab Since our efforts to implement https://github.com/opnsense/core/pull/7361 hasn't reached a functional state, lets move the code into a separate branch to keep master clean. --- plist | 1 + .../OPNsense/Kea/Api/Dhcpv4Controller.php | 25 +++++++++ .../OPNsense/Kea/DhcpController.php | 1 + .../OPNsense/Kea/forms/dialogOption4.xml | 39 +++++++++++++ .../mvc/app/models/OPNsense/Kea/KeaDhcpv4.php | 56 +++++++++++++++++++ .../mvc/app/models/OPNsense/Kea/KeaDhcpv4.xml | 56 +++++++++++++++++++ .../mvc/app/views/OPNsense/Kea/dhcpv4.volt | 11 ++++ 7 files changed, 189 insertions(+) create mode 100644 src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogOption4.xml diff --git a/plist b/plist index 9be0169d44f..84327d51ce0 100644 --- a/plist +++ b/plist @@ -394,6 +394,7 @@ /usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/Api/ServiceController.php /usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/DhcpController.php /usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/agentSettings.xml +/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogOption4.xml /usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogPeer4.xml /usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogReservation4.xml /usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogSubnet4.xml diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Kea/Api/Dhcpv4Controller.php b/src/opnsense/mvc/app/controllers/OPNsense/Kea/Api/Dhcpv4Controller.php index f1dce5bfb1e..43f23bbde94 100644 --- a/src/opnsense/mvc/app/controllers/OPNsense/Kea/Api/Dhcpv4Controller.php +++ b/src/opnsense/mvc/app/controllers/OPNsense/Kea/Api/Dhcpv4Controller.php @@ -162,4 +162,29 @@ public function delPeerAction($uuid) { return $this->delBase("ha_peers.peer", $uuid); } + + public function searchOptionAction() + { + return $this->searchBase("custom_options.option", null, "name"); + } + + public function setOptionAction($uuid) + { + return $this->setBase("option", "custom_options.option", $uuid); + } + + public function addOptionAction() + { + return $this->addBase("option", "custom_options.option"); + } + + public function getOptionAction($uuid = null) + { + return $this->getBase("option", "custom_options.option", $uuid); + } + + public function delOptionAction($uuid) + { + return $this->delBase("custom_options.option", $uuid); + } } diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Kea/DhcpController.php b/src/opnsense/mvc/app/controllers/OPNsense/Kea/DhcpController.php index c01a11adbb7..cc33ae94bdf 100644 --- a/src/opnsense/mvc/app/controllers/OPNsense/Kea/DhcpController.php +++ b/src/opnsense/mvc/app/controllers/OPNsense/Kea/DhcpController.php @@ -53,6 +53,7 @@ public function v4Action() $this->view->formDialogSubnet = $this->getForm("dialogSubnet4"); $this->view->formDialogReservation = $this->getForm("dialogReservation4"); $this->view->formDialogPeer = $this->getForm("dialogPeer4"); + $this->view->formDialogOption = $this->getForm("dialogOption4"); } public function leases4Action() diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogOption4.xml b/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogOption4.xml new file mode 100644 index 00000000000..f1c92972eda --- /dev/null +++ b/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogOption4.xml @@ -0,0 +1,39 @@ +
+ + option.description + + text + + + option.subnet + + select_multiple + Subnet this custom option belongs to + + + option.code + + text + + + option.space + + dropdown + + + option.type + + dropdown + DHCP option type.]]> + + + option.array + + checkbox + + + option.data + + text + +
diff --git a/src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.php b/src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.php index c726e58682d..2d1b0ae8745 100644 --- a/src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.php +++ b/src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.php @@ -90,6 +90,36 @@ public function performValidation($validateFullModel = false) } } + foreach ($this->custom_options->option->iterateItems() as $option) { + if (!$option && !$option->isFieldChanged()) { + continue; + } + $key = $option->__reference; + foreach ($this->custom_options->option->iterateItems() as $checkopt) { + if ( + (string)$checkopt->code == (string)$option->code && + (string)$checkopt->space == (string)$option->space + ) { + if ((string)$checkopt->type != (string)$option->type) { + $messages->appendMessage(new Message( + sprintf( + gettext("Unable to redefine code %s, defined as %s in another option."), + $option->code, + $checkopt->type + ), + $key . ".type" + )); + } + if ((string)$checkopt->array != (string)$option->array) { + $messages->appendMessage(new Message( + sprintf(gettext("Unable to redefine code %s with different definition"), $option->code), + $key . ".array" + )); + } + } + } + } + return $messages; } @@ -160,6 +190,17 @@ private function getConfigSubnets() ]; } } + /* custom dhcp options */ + foreach ($this->custom_options->option->iterateItems() as $option) { + if (in_array($subnet_uuid, explode(',', $option->subnet))) { + $record['option-data'][] = [ + "name" => sprintf("%s_%s", $option->space, $option->code), + "code" => (int)((string)$option->code), + "space" => (string)$option->space, + "data" => (string)$option->data + ]; + } + } /* add pools */ foreach (array_filter(explode("\n", $subnet->pools)) as $pool) { $record['pools'][] = ['pool' => $pool]; @@ -212,6 +253,21 @@ public function generateConfig($target = '/usr/local/etc/kea/kea-dhcp4.conf') 'subnet4' => $this->getConfigSubnets(), ] ]; + $option_def = []; + foreach ($this->custom_options->option->iterateItems() as $option) { + $option_def[sprintf("%s_%s", $option->space, $option->code)] = [ + "name" => sprintf("%s_%s", $option->space, $option->code), + "code" => (int)((string)$option->code), + "type" => (string)$option->type, + "array" => !empty((string)$option->array), + "record-types" => "", + "space" => (string)$option->space, + "encapsulate" => "" + ]; + } + if (!empty($option_def)) { + $cnf['Dhcp4']['option-def'] = array_values($option_def); + } if (!empty((string)(new KeaCtrlAgent())->general->enabled)) { $cnf['Dhcp4']['hooks-libraries'] = []; $cnf['Dhcp4']['hooks-libraries'][] = [ diff --git a/src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.xml b/src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.xml index 2364c824e71..a7e24a7a883 100644 --- a/src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.xml +++ b/src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.xml @@ -158,5 +158,61 @@ + + + diff --git a/src/opnsense/mvc/app/views/OPNsense/Kea/dhcpv4.volt b/src/opnsense/mvc/app/views/OPNsense/Kea/dhcpv4.volt index b82e869d4ec..c01e7188eb1 100644 --- a/src/opnsense/mvc/app/views/OPNsense/Kea/dhcpv4.volt +++ b/src/opnsense/mvc/app/views/OPNsense/Kea/dhcpv4.volt @@ -69,6 +69,15 @@ } ); + $("#grid-options").UIBootgrid( + { search:'/api/kea/dhcpv4/search_option', + get:'/api/kea/dhcpv4/get_option/', + set:'/api/kea/dhcpv4/set_option/', + add:'/api/kea/dhcpv4/add_option/', + del:'/api/kea/dhcpv4/del_option/' + } + ); + $("#reconfigureAct").SimpleActionButton({ onPreAction: function() { const dfObj = new $.Deferred(); @@ -111,6 +120,7 @@
  • {{ lang._('Settings') }}
  • {{ lang._('Subnets') }}
  • {{ lang._('Reservations') }}
  • +
  • {{ lang._('Custom Options') }}
  • {{ lang._('HA Peers') }}
  • @@ -246,3 +256,4 @@ {{ partial("layout_partials/base_dialog",['fields':formDialogSubnet,'id':'DialogSubnet','label':lang._('Edit Subnet')])}} {{ partial("layout_partials/base_dialog",['fields':formDialogReservation,'id':'DialogReservation','label':lang._('Edit Reservation')])}} {{ partial("layout_partials/base_dialog",['fields':formDialogPeer,'id':'DialogPeer','label':lang._('Edit Peer')])}} +{{ partial("layout_partials/base_dialog",['fields':formDialogOption,'id':'DialogOption','label':lang._('Edit Option')])}}