Skip to content

Commit

Permalink
Services: Kea DHCP [new]: Kea DHCPv4 - move json file generation to a…
Browse files Browse the repository at this point in the history
… plugin configure hook, keep empty templates to inform people.

(ref; #7361)
  • Loading branch information
AdSchellevis committed Apr 16, 2024
1 parent 597b65a commit d241cfd
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 146 deletions.
36 changes: 32 additions & 4 deletions src/etc/inc/plugins.inc.d/kea.inc
Expand Up @@ -34,17 +34,45 @@ function kea_services()
$services[] = [
'description' => gettext('KEA DHCPv4 server'),
'pidfile' => '/var/run/kea/kea-dhcp4.kea-dhcp4.pid',
'configd' => [
'restart' => ['kea restart'],
'start' => ['kea start'],
'stop' => ['kea stop'],
'php' => [
'restart' => ['kea_configure_do'],
'start' => ['kea_configure_do'],
'stop' => ['kea_service_stop'],
],
'name' => 'kea-dhcpv4',
];
}
return $services;
}

function kea_configure()
{
return [
'bootup' => ['kea_configure_do'],
'kea_start' => ['kea_configure_do'],
'kea_stop' => ['kea_service_stop']
];
}

function kea_configure_do($verbose = false)
{
$keaDhcpv4 = new \OPNsense\Kea\KeaDhcpv4();
if ($keaDhcpv4->isEnabled()) {
service_log('Starting KEA DHCP...', $verbose);
$keaDhcpv4->generateConfig();
(new \OPNsense\Kea\KeaCtrlAgent())->generateConfig();
if (isvalidpid('/var/run/kea/kea-dhcp4.kea-dhcp4.pid')) {
mwexec("/usr/local/etc/rc.d/kea onestop", false);

This comment has been minimized.

Copy link
@fichtner

fichtner Apr 17, 2024

Member

What are we going to accomplish hardcoding kea_enable to NO and still using kea script with "onexxx" actions? I think either we don't want to use rc.d at all or use it in full, which is also what the mutable service controller will do.

This comment has been minimized.

Copy link
@AdSchellevis

AdSchellevis Apr 17, 2024

Author Member

@fichtner we do want to use the rc scripts, but if we move the template generation hooks as discussed, we end up with a similar construction as in other spots (see ipsec for example)

}
mwexec_bg("/usr/local/etc/rc.d/kea onestart", false);

This comment has been minimized.

Copy link
@fichtner

fichtner Apr 17, 2024

Member

Backgrounding here will cause issues on the GUI asking for kea status on the widget so it will likely appear as offline.

This comment has been minimized.

Copy link
@AdSchellevis

AdSchellevis Apr 17, 2024

Author Member

@fichtner see ipsec, quite some rc scripts don't seem to detach stdin properly it seems (which freezes execution)

This comment has been minimized.

Copy link
@fichtner

fichtner Apr 17, 2024

Member

we fixed such problems for unbound mvc move though using e.g. waitforpid() to serialize a bit

service_log("done.\n", $verbose);
}
}

function kea_service_stop()
{
mwexec("/usr/local/etc/rc.d/kea onestop", false);

This comment has been minimized.

Copy link
@fichtner

fichtner Apr 17, 2024

Member

the service framework can deal with this by PID anyway. It all feels like going a small step backwards :/

This comment has been minimized.

Copy link
@AdSchellevis

AdSchellevis Apr 17, 2024

Author Member

it depends on the plugin hooks you want to use, if we don't stop here, we end up with starting via php->configd->php. so, it's either not to great for the stop action or not too great for the start action....

}

function kea_syslog()
{
Expand Down
4 changes: 4 additions & 0 deletions src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.php
Expand Up @@ -92,6 +92,10 @@ public function performValidation($validateFullModel = false)
return $messages;
}

public function isEnabled()
{
return (string)$this->general->enabled == '1' && !empty((string)(string)$this->general->interfaces);
}

/**
* should filter rules be enabled
Expand Down
6 changes: 3 additions & 3 deletions src/opnsense/service/conf/actions.d/actions_kea.conf
@@ -1,17 +1,17 @@
[stop]
command:/usr/local/etc/rc.d/kea stop
command:/usr/local/sbin/pluginctl -c kea_stop
parameters:
type:script
message:stop kea daemon

[start]
command:/usr/local/etc/rc.d/kea start
command:/usr/local/sbin/pluginctl -c kea_start
parameters:
type:script
message:start kea daemon

[restart]
command:/usr/local/etc/rc.d/kea restart
command:/usr/local/sbin/pluginctl -c kea_start
parameters:
type:script
message:restart kea daemon
Expand Down
2 changes: 0 additions & 2 deletions src/opnsense/service/templates/OPNsense/Kea/+TARGETS
@@ -1,4 +1,2 @@
kea-dhcp4.conf:/usr/local/etc/kea/kea-dhcp4.conf
rc.conf.d:/etc/rc.conf.d/kea
keactrl.conf:/usr/local/etc/kea/keactrl.conf
kea-ctrl-agent.conf:/usr/local/etc/kea/kea-ctrl-agent.conf
33 changes: 1 addition & 32 deletions src/opnsense/service/templates/OPNsense/Kea/kea-ctrl-agent.conf
@@ -1,32 +1 @@
{
"Control-agent": {
"http-host": "{{ OPNsense.Kea.ctrl_agent.general.http_host|default('127.0.0.1')}}",
"http-port": {{ OPNsense.Kea.ctrl_agent.general.http_port|default('8000')}},
"control-sockets": {
"dhcp4": {
"socket-type": "unix",
"socket-name": "/var/run/kea4-ctrl-socket"
},
"dhcp6": {
"socket-type": "unix",
"socket-name": "/var/run/kea6-ctrl-socket"
},
"d2": {
"socket-type": "unix",
"socket-name": "/var/run/kea-ddns-ctrl-socket"
}
},
"loggers": [
{
"name": "kea-ctrl-agent",
"output_options": [
{
"output": "syslog"
}
],
"severity": "INFO",
"debuglevel": 0
}
]
}
}
## json output constructed in kea_configure_do()
102 changes: 1 addition & 101 deletions src/opnsense/service/templates/OPNsense/Kea/kea-dhcp4.conf
@@ -1,101 +1 @@
{%- if not helpers.empty('OPNsense.Kea.dhcp4.general.interfaces') and not helpers.empty('OPNsense.Kea.dhcp4.general.enabled') -%}
{%- set reservation_fields = ({
'hw-address': 'hw_address',
'ip-address': 'ip_address',
'hostname': 'hostname'
}) -%}
{%- set option_data_defaults = ({
'domain_name': system.domain
}) -%}
{%- set general = OPNsense.Kea.dhcp4.general -%}
{
"Dhcp4": {
"valid-lifetime": {{general.valid_lifetime}},
"interfaces-config": {
"interfaces": ["{{helpers.physical_interfaces(general.interfaces.split(','))|join('","')}}"]
},
"lease-database": {
"type": "memfile",
"persist": true
},
"control-socket": {
"socket-type": "unix",
"socket-name": "/var/run/kea4-ctrl-socket"
},
"loggers": [
{
"name": "kea-dhcp4",
"output_options": [
{
"output": "syslog"
}
],
"severity": "INFO"
}
],
"subnet4": [
{% for subnet in helpers.toList('OPNsense.Kea.dhcp4.subnets.subnet4') %}
{
"id": {{loop.index}},
"subnet": "{{subnet.subnet}}",
"option-data": [
{% for od_attr in (subnet.option_data|list + option_data_defaults|list)|unique if subnet.option_data[od_attr]|length > 1 or od_attr in option_data_defaults %}
{
"name": "{{od_attr.replace('_','-')}}",
"data": {{subnet.option_data[od_attr]|default(option_data_defaults[od_attr])|tojson}}
}{% if not loop.last %},{% endif +%}
{% endfor %}
],
"pools": [
{% for pool in (subnet.pools|default('')).split("\n") if pool|length > 1%}
{ "pool": "{{pool}}" }{% if not loop.last %},{% endif +%}
{% endfor %}
],
"reservations": [
{% for reservation in helpers.toList('OPNsense.Kea.dhcp4.reservations.reservation') if reservation.subnet == subnet['@uuid'] %}
{
{% for res_key, res_prop in reservation_fields.items() if reservation[res_prop]|length > 1 %}
"{{res_key}}": {{reservation[res_prop]|tojson}}{% if not loop.last %},{% endif +%}
{% endfor %}
}{% if not loop.last %},{% endif +%}
{% endfor %}
]
}{% if not loop.last %},{% endif +%}
{% endfor %}
]
{% if not helpers.empty('OPNsense.Kea.ctrl_agent.general.enabled') %}
,"hooks-libraries": [
{
"library": "/usr/local/lib/kea/hooks/libdhcp_lease_cmds.so",
"parameters": { }
},
{% if not helpers.empty('OPNsense.Kea.dhcp4.ha.enabled') %}
{
"library": "/usr/local/lib/kea/hooks/libdhcp_ha.so",
"parameters": {
"high-availability": [ {
"this-server-name": {{OPNsense.Kea.dhcp4.ha.this_server_name|default(system.hostname)|tojson}},
"mode": "hot-standby",
"heartbeat-delay": 10000,
"max-response-delay": 60000,
"max-ack-delay": 5000,
"max-unacked-clients": 5,
"sync-timeout": 60000,
"peers": [
{% for peer in helpers.toList('OPNsense.Kea.dhcp4.ha_peers.peer') %}
{
"name": {{peer.name|tojson}},
"role": {{peer.role|tojson}},
"url": {{peer.url|default('')|tojson}}
}{% if not loop.last %},{% endif +%}
{% endfor %}
]
} ]
}
}
{% endif %}
]
{% endif %}
}
}
{%- endif -%}
## json output constructed in kea_configure_do()
4 changes: 0 additions & 4 deletions src/opnsense/service/templates/OPNsense/Kea/rc.conf.d
@@ -1,5 +1 @@
{% if not helpers.empty('OPNsense.Kea.dhcp4.general.interfaces') and not helpers.empty('OPNsense.Kea.dhcp4.general.enabled') %}
kea_enable="YES"
{% else %}
kea_enable="NO"
{% endif %}

3 comments on commit d241cfd

@fichtner
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thinking more.. didn't you just have to add a setup.sh for kea that runs the configuration render via pluginctl?

@AdSchellevis
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fichtner that might work indeed, let me put that on the list to try. none of the options are great, but also opens the discussion if we need a template helper to render model json output.

@fichtner
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kinda like the kea_setup use... but I'm also thinking we could extend the plugin system for this "template" based action and add more shims to make it less code and reusable (for the pseudo-legacy parts we have). All in all I think that's a good direction to keep moving and improving all using newer approaches that are easier to maintain and extend. :)

Please sign in to comment.