Skip to content

Commit 8acdcb3

Browse files
committed
Services: Kea DHCP [new]: Kea DHCPv4 - add Custom options tab
Since our efforts to implement #7361 hasn't reached a functional state, lets move the code into a separate branch to keep master clean.
1 parent 526d747 commit 8acdcb3

File tree

7 files changed

+215
-0
lines changed

7 files changed

+215
-0
lines changed

plist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@
419419
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/Api/ServiceController.php
420420
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/DhcpController.php
421421
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/agentSettings.xml
422+
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogOption4.xml
422423
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogPeer4.xml
423424
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogReservation4.xml
424425
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogSubnet4.xml

src/opnsense/mvc/app/controllers/OPNsense/Kea/Api/Dhcpv4Controller.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,4 +160,29 @@ public function delPeerAction($uuid)
160160
{
161161
return $this->delBase("ha_peers.peer", $uuid);
162162
}
163+
164+
public function searchOptionAction()
165+
{
166+
return $this->searchBase("custom_options.option", null, "name");
167+
}
168+
169+
public function setOptionAction($uuid)
170+
{
171+
return $this->setBase("option", "custom_options.option", $uuid);
172+
}
173+
174+
public function addOptionAction()
175+
{
176+
return $this->addBase("option", "custom_options.option");
177+
}
178+
179+
public function getOptionAction($uuid = null)
180+
{
181+
return $this->getBase("option", "custom_options.option", $uuid);
182+
}
183+
184+
public function delOptionAction($uuid)
185+
{
186+
return $this->delBase("custom_options.option", $uuid);
187+
}
163188
}

src/opnsense/mvc/app/controllers/OPNsense/Kea/DhcpController.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public function v4Action()
5353
$this->view->formDialogSubnet = $this->getForm("dialogSubnet4");
5454
$this->view->formDialogReservation = $this->getForm("dialogReservation4");
5555
$this->view->formDialogPeer = $this->getForm("dialogPeer4");
56+
$this->view->formDialogOption = $this->getForm("dialogOption4");
5657
}
5758

5859
public function leases4Action()
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<form>
2+
<field>
3+
<id>option.description</id>
4+
<label>Description</label>
5+
<type>text</type>
6+
</field>
7+
<field>
8+
<id>option.subnet</id>
9+
<label>Subnet</label>
10+
<type>select_multiple</type>
11+
<help>Subnet this custom option belongs to</help>
12+
</field>
13+
<field>
14+
<id>option.code</id>
15+
<label>DHCP option</label>
16+
<type>text</type>
17+
</field>
18+
<field>
19+
<id>option.space</id>
20+
<label>Space</label>
21+
<type>dropdown</type>
22+
</field>
23+
<field>
24+
<id>option.type</id>
25+
<label>Type</label>
26+
<type>dropdown</type>
27+
<help><![CDATA[A <a rel="help" href="https://kea.readthedocs.io/en/latest/arm/dhcp4-srv.html#dhcp-types">DHCP option type</a>.]]></help>
28+
</field>
29+
<field>
30+
<id>option.array</id>
31+
<label>Array</label>
32+
<type>checkbox</type>
33+
</field>
34+
<field>
35+
<id>option.data</id>
36+
<label>Data</label>
37+
<type>text</type>
38+
</field>
39+
</form>

src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,36 @@ public function performValidation($validateFullModel = false)
9090
}
9191
}
9292

93+
foreach ($this->custom_options->option->iterateItems() as $option) {
94+
if (!$option && !$option->isFieldChanged()) {
95+
continue;
96+
}
97+
$key = $option->__reference;
98+
foreach ($this->custom_options->option->iterateItems() as $checkopt) {
99+
if (
100+
(string)$checkopt->code == (string)$option->code &&
101+
(string)$checkopt->space == (string)$option->space
102+
) {
103+
if ((string)$checkopt->type != (string)$option->type) {
104+
$messages->appendMessage(new Message(
105+
sprintf(
106+
gettext("Unable to redefine code %s, defined as %s in another option."),
107+
$option->code,
108+
$checkopt->type
109+
),
110+
$key . ".type"
111+
));
112+
}
113+
if ((string)$checkopt->array != (string)$option->array) {
114+
$messages->appendMessage(new Message(
115+
sprintf(gettext("Unable to redefine code %s with different definition"), $option->code),
116+
$key . ".array"
117+
));
118+
}
119+
}
120+
}
121+
}
122+
93123
return $messages;
94124
}
95125

@@ -162,6 +192,17 @@ private function getConfigSubnets()
162192
];
163193
}
164194
}
195+
/* custom dhcp options */
196+
foreach ($this->custom_options->option->iterateItems() as $option) {
197+
if (in_array($subnet_uuid, explode(',', $option->subnet))) {
198+
$record['option-data'][] = [
199+
"name" => sprintf("%s_%s", $option->space, $option->code),
200+
"code" => (int)((string)$option->code),
201+
"space" => (string)$option->space,
202+
"data" => (string)$option->data
203+
];
204+
}
205+
}
165206
/* add pools */
166207
foreach (array_filter(explode("\n", $subnet->pools)) as $pool) {
167208
$record['pools'][] = ['pool' => $pool];
@@ -215,6 +256,21 @@ public function generateConfig($target = '/usr/local/etc/kea/kea-dhcp4.conf')
215256
'subnet4' => $this->getConfigSubnets(),
216257
]
217258
];
259+
$option_def = [];
260+
foreach ($this->custom_options->option->iterateItems() as $option) {
261+
$option_def[sprintf("%s_%s", $option->space, $option->code)] = [
262+
"name" => sprintf("%s_%s", $option->space, $option->code),
263+
"code" => (int)((string)$option->code),
264+
"type" => (string)$option->type,
265+
"array" => !empty((string)$option->array),
266+
"record-types" => "",
267+
"space" => (string)$option->space,
268+
"encapsulate" => ""
269+
];
270+
}
271+
if (!empty($option_def)) {
272+
$cnf['Dhcp4']['option-def'] = array_values($option_def);
273+
}
218274
if (!empty((string)(new KeaCtrlAgent())->general->enabled)) {
219275
$cnf['Dhcp4']['hooks-libraries'] = [];
220276
$cnf['Dhcp4']['hooks-libraries'][] = [

src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.xml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,5 +187,61 @@
187187
</url>
188188
</peer>
189189
</ha_peers>
190+
<custom_options>
191+
<option type="ArrayField">
192+
<description type="DescriptionField"/>
193+
<code type="IntegerField">
194+
<Required>Y</Required>
195+
<MinimumValue>0</MinimumValue>
196+
<MaximumValue>255</MaximumValue>
197+
</code>
198+
<space type="OptionField">
199+
<Required>Y</Required>
200+
<Default>vendor</Default>
201+
<OptionValues>
202+
<vendor value='vendor-encapsulated-options-space'>vendor-encapsulated-options-space</vendor>
203+
</OptionValues>
204+
</space>
205+
<type type="OptionField">
206+
<Required>Y</Required>
207+
<OptionValues>
208+
<binary>binary</binary>
209+
<boolean>boolean</boolean>
210+
<fqdn>fqdn</fqdn>
211+
<ipv4_address>ipv4-address</ipv4_address>
212+
<ipv6_address>ipv6-address</ipv6_address>
213+
<ipv6_prefix>ipv6-prefix</ipv6_prefix>
214+
<psid>psid</psid>
215+
<string>string</string>
216+
<tuple>tuple</tuple>
217+
<uint8>uint8</uint8>
218+
<uint16>uint16</uint16>
219+
<uint32>uint32</uint32>
220+
<int8>int8</int8>
221+
<int16>int16</int16>
222+
<int32>int32</int32>
223+
</OptionValues>
224+
</type>
225+
<array type="BooleanField">
226+
<Required>Y</Required>
227+
<Default>0</Default>
228+
</array>
229+
<subnet type="ModelRelationField">
230+
<Model>
231+
<subnets>
232+
<source>OPNsense.Kea.KeaDhcpv4</source>
233+
<items>subnets.subnet4</items>
234+
<display>subnet</display>
235+
</subnets>
236+
</Model>
237+
<ValidationMessage>Related subnet not found</ValidationMessage>
238+
<Required>Y</Required>
239+
<Multiple>Y</Multiple>
240+
</subnet>
241+
<data type="TextField">
242+
<Required>Y</Required>
243+
</data>
244+
</option>
245+
</custom_options>
190246
</items>
191247
</model>

src/opnsense/mvc/app/views/OPNsense/Kea/dhcpv4.volt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,15 @@
6969
}
7070
);
7171

72+
$("#grid-options").UIBootgrid(
73+
{ search:'/api/kea/dhcpv4/search_option',
74+
get:'/api/kea/dhcpv4/get_option/',
75+
set:'/api/kea/dhcpv4/set_option/',
76+
add:'/api/kea/dhcpv4/add_option/',
77+
del:'/api/kea/dhcpv4/del_option/'
78+
}
79+
);
80+
7281
$("#reconfigureAct").SimpleActionButton({
7382
onPreAction: function() {
7483
const dfObj = new $.Deferred();
@@ -111,6 +120,7 @@
111120
<li class="active"><a data-toggle="tab" href="#settings" id="tab_settings">{{ lang._('Settings') }}</a></li>
112121
<li><a data-toggle="tab" href="#subnets" id="tab_pools"> {{ lang._('Subnets') }} </a></li>
113122
<li><a data-toggle="tab" href="#reservations" id="tab_reservations"> {{ lang._('Reservations') }} </a></li>
123+
<li><a data-toggle="tab" href="#options" id="tab_options"> {{ lang._('Custom Options') }} </a></li>
114124
<li><a data-toggle="tab" href="#ha-peers" id="tab_ha-peers"> {{ lang._('HA Peers') }} </a></li>
115125
</ul>
116126
<div class="tab-content content-box">
@@ -177,6 +187,32 @@
177187
</tfoot>
178188
</table>
179189
</div>
190+
<!-- Options -->
191+
<div id="options" class="tab-pane fade in">
192+
<table id="grid-options" class="table table-condensed table-hover table-striped" data-editDialog="DialogOption">
193+
<thead>
194+
<tr>
195+
<th data-column-id="uuid" data-type="string" data-identifier="true" data-visible="false">{{ lang._('ID') }}</th>
196+
<th data-column-id="description" data-type="string">{{ lang._('Description') }}</th>
197+
<th data-column-id="code" data-type="number">{{ lang._('Option') }}</th>
198+
<th data-column-id="space" data-type="string">{{ lang._('Space') }}</th>
199+
<th data-column-id="type" data-type="string">{{ lang._('Type') }}</th>
200+
<th data-column-id="data" data-type="string">{{ lang._('Data') }}</th>
201+
<th data-column-id="commands" data-width="7em" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
202+
</tr>
203+
</thead>
204+
<tbody>
205+
</tbody>
206+
<tfoot>
207+
<tr>
208+
<td></td>
209+
<td>
210+
<button data-action="add" type="button" class="btn btn-xs btn-primary"><span class="fa fa-fw fa-plus"></span></button>
211+
</td>
212+
</tr>
213+
</tfoot>
214+
</table>
215+
</div>
180216
<!-- HA - peers -->
181217
<div id="ha-peers" class="tab-pane fade in">
182218
<table id="grid-ha-peers" class="table table-condensed table-hover table-striped" data-editDialog="DialogPeer" data-editAlert="keaChangeMessage">
@@ -223,3 +259,4 @@
223259
{{ partial("layout_partials/base_dialog",['fields':formDialogSubnet,'id':'DialogSubnet','label':lang._('Edit Subnet')])}}
224260
{{ partial("layout_partials/base_dialog",['fields':formDialogReservation,'id':'DialogReservation','label':lang._('Edit Reservation')])}}
225261
{{ partial("layout_partials/base_dialog",['fields':formDialogPeer,'id':'DialogPeer','label':lang._('Edit Peer')])}}
262+
{{ partial("layout_partials/base_dialog",['fields':formDialogOption,'id':'DialogOption','label':lang._('Edit Option')])}}

0 commit comments

Comments
 (0)