Closed Monviech closed 6 months ago
A good example can be seen here:
I have defined an "onPreAction" with a deferred promise, that is resolved only when the "saveFormToEndpoint" was successful.
The same behavior can be extended to also include a validation action afterwards.
The validation should reload the template, afterwards use the "caddy fmt --overwrite" to correct all formatting errors, and then use "caddy validate /usr/local/etc/caddy/Caddyfile", parsing the output if the configuration is valid. If not, then the deferred promise should be rejected and a popup should inform the user of it.
The exact error could be printed, but maybe it's too hard to pass it to such an error message, so a general message "Validation of Caddyfile failed" would be the best choice.
I have opted to create a new "Validate Configuration" Button that can be pressed optionally. It will validate the current Caddyfile, and inform the user of any error that might be with it. That way, the validation can be triggered optionally before restarting the service, mitigating the risk of reloading Caddy with a bad Caddyfile.
I will try to implement this into the Apply button instead so its working automatically.
The additional validation prevents the service from being reloaded if the Caddyfile is invalid, and displays the exact error message (of "caddy validate") so the user can fix it.
Here's a screenshot with an example of multiple domains with the same name.
The API to support this validation can be requested at any time using this endpoint:
/api/caddy/service/validate
And it shows this example data:
{"status":"failed","message":"Error: adapting config using caddyfile: ambiguous site definition: *.example.com"}
Configd run with invalid configuration:
<13>1 2024-02-19T12:29:44+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="4"] [1f994d24-8792-42f6-95b5-2ac892fb6fdf] generate template Pischem/Caddy
<13>1 2024-02-19T12:29:44+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="5"] generate template container Pischem/Caddy
<15>1 2024-02-19T12:29:44+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="6"] Pischem/Caddy generated //usr/local/etc/caddy/Caddyfile
<15>1 2024-02-19T12:29:44+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="7"] Pischem/Caddy generated //etc/rc.conf.d/caddy
<15>1 2024-02-19T12:29:44+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="8"] Pischem/Caddy generated //usr/local/etc/syslog-ng.conf.d/caddy.conf
<13>1 2024-02-19T12:29:44+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="9"] [2ab2460d-208a-4f64-b827-6339156df187] Validating Caddy configuration
Configd run with valid configuration:
<13>1 2024-02-19T12:31:15+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="1"] [4b0b08be-c927-487f-a1e9-c76579328345] trigger config changed event
<13>1 2024-02-19T12:31:17+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="2"] [85a200db-9ced-465f-9f09-65c085cd5e11] generate template Pischem/Caddy
<13>1 2024-02-19T12:31:17+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="3"] generate template container Pischem/Caddy
<15>1 2024-02-19T12:31:17+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="4"] Pischem/Caddy generated //usr/local/etc/caddy/Caddyfile
<15>1 2024-02-19T12:31:17+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="5"] Pischem/Caddy generated //etc/rc.conf.d/caddy
<15>1 2024-02-19T12:31:17+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="6"] Pischem/Caddy generated //usr/local/etc/syslog-ng.conf.d/caddy.conf
<13>1 2024-02-19T12:31:17+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="7"] [7e96b94c-3d28-4784-b4c6-95ea9b831ea1] Validating Caddy configuration
<13>1 2024-02-19T12:31:17+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="8"] [d36879bc-489d-48eb-9d26-790dda0c6ab5] Stopping Caddy service
<13>1 2024-02-19T12:31:17+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="9"] [9c07bf9a-71c2-4555-be1e-eb29287366cc] generate template Pischem/Caddy
<13>1 2024-02-19T12:31:17+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="10"] generate template container Pischem/Caddy
<15>1 2024-02-19T12:31:17+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="11"] Pischem/Caddy generated //usr/local/etc/caddy/Caddyfile
<15>1 2024-02-19T12:31:17+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="12"] Pischem/Caddy generated //etc/rc.conf.d/caddy
<15>1 2024-02-19T12:31:17+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="13"] Pischem/Caddy generated //usr/local/etc/syslog-ng.conf.d/caddy.conf
<13>1 2024-02-19T12:31:17+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="14"] [fe58a466-80f7-47c3-8ce4-fae0ce393a9e] Request Caddy status
<13>1 2024-02-19T12:31:18+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="15"] [4562070c-d016-4652-bbe2-31e660e79c08] IPsec list legacy VirtualTunnelInterfaces
<13>1 2024-02-19T12:31:18+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="16"] [92021263-f8bb-4231-b783-569394a9b3a4] Starting Caddy service
<13>1 2024-02-19T12:31:18+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="17"] [f1b2cab5-355c-45c7-9f96-4aae60011657] Request Caddy status
<13>1 2024-02-19T12:31:18+00:00 OPNsense.localdomain configd.py 230 - [meta sequenceId="18"] [e269dfb6-c6d0-425b-b12e-9def9cfbcca0] IPsec list legacy VirtualTunnelInterfaces
Since there are a lot of options and the validation model can't catch all errors, a validation check should be implemented.
I had an invalid configuration a few times because I cloned a domain (I use one domain with like 20 different ports for a very complex setup) and I accidentally had a duplicate port.
Caddy looks like it has started, but it's actually not working then.
The "reconfigure Act" needs another deferred promise, which calls a new "validate" action. A validate script needs to be written that checks the output of "caddy validate /usr/local/etc/caddy/Caddyfile" after it has been regenerated by the template.
If the validation fails and the promise isn't kept, a popup should inform the user that the current configuration is invalid, and the reload of Caddy should not take place.