From 949d8ba28444a44e9aa5a5683423bc0a460fa73c Mon Sep 17 00:00:00 2001 From: Jared Hendrickson Date: Wed, 22 Apr 2020 16:31:28 -0600 Subject: [PATCH] v0.0.2 commit includes optimization for /services/unbound/ calls, allowed configuration to be added without applying changes at the same time, added separate API call to apply unbound configuration --- .gitignore | 1 + README.md | 4 +- pfSense-pkg-API/Makefile | 6 +- pfSense-pkg-API/files/etc/inc/api.inc | 13 ++++ pfSense-pkg-API/files/etc/inc/apicalls.inc | 78 +++++++++++++++---- .../usr/local/share/pfSense-pkg-API/info.xml | 2 +- .../api/v1/services/unbound/apply/index.php | 10 +++ pfSense-pkg-API/pkg-plist | 2 + 8 files changed, 97 insertions(+), 19 deletions(-) create mode 100644 pfSense-pkg-API/files/usr/local/www/api/v1/services/unbound/apply/index.php diff --git a/.gitignore b/.gitignore index c6ef2182b..e6d84e3ff 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .idea +*.DS_Store diff --git a/README.md b/README.md index 5c80a2615..cdc1de4c6 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ --- # Introduction -pfSense API is a fast, safe, full-fledged API based on REST architecture. This works by leveraging the same PHP functions and processes used by pfSense's webConfigurator into API endpoints to create, read, update and delete pfSense configurations. All API endpoints enforce input validation to prevent invalid configurations from being made. Configurations made via API are properly written to the master XML configuration and the correct backend configurations are made preventing the need for a reboot. All this results in the fastest, safest, and easiest way to automate pfSense! +pfSense API is a fast, safe, full-fledged HTTP API. This works by leveraging the same PHP functions and processes used by pfSense's webConfigurator into API endpoints to create, read, update and delete pfSense configurations. All API endpoints enforce input validation to prevent invalid configurations from being made. Configurations made via API are properly written to the master XML configuration and the correct backend configurations are made preventing the need for a reboot. All this results in the fastest, safest, and easiest way to automate pfSense! # Installation To install pfSense API, simply run the following command from the pfSense shell:
-`pkg add https://github.com/jaredhendrickson13/pfsense-api/releases/v0.0.1/pfSense-pkg-API-0.0_1.txz`
+`pkg add https://github.com/jaredhendrickson13/pfsense-api/releases/v0.0.2/pfSense-2-4-pkg-API-0.0_2.txz`
To uninstall, run the following command:
`pkg delete pfSense-pkg-API`
diff --git a/pfSense-pkg-API/Makefile b/pfSense-pkg-API/Makefile index 94e80995e..2c846086f 100644 --- a/pfSense-pkg-API/Makefile +++ b/pfSense-pkg-API/Makefile @@ -2,7 +2,7 @@ PORTNAME= pfSense-pkg-API PORTVERSION= 0.0 -PORTREVISION= 1 +PORTREVISION= 2 CATEGORIES= sysutils MASTER_SITES= # empty DISTFILES= # empty @@ -412,6 +412,10 @@ do-install: ${MKDIR} ${STAGEDIR}${PREFIX}/www/api/v1/services/unbound/modify/hosts ${INSTALL_DATA} ${FILESDIR}${PREFIX}/www/api/v1/services/unbound/modify/hosts/index.php \ ${STAGEDIR}${PREFIX}/www/api/v1/services/unbound/modify/hosts + # Unbound apply + ${MKDIR} ${STAGEDIR}${PREFIX}/www/api/v1/services/unbound/apply + ${INSTALL_DATA} ${FILESDIR}${PREFIX}/www/api/v1/services/unbound/apply/index.php \ + ${STAGEDIR}${PREFIX}/www/api/v1/services/unbound/apply # INSTALL OUR PKG INFO ${MKDIR} ${STAGEDIR}${DATADIR} diff --git a/pfSense-pkg-API/files/etc/inc/api.inc b/pfSense-pkg-API/files/etc/inc/api.inc index 4163a7f1d..e2ced5cf7 100644 --- a/pfSense-pkg-API/files/etc/inc/api.inc +++ b/pfSense-pkg-API/files/etc/inc/api.inc @@ -445,6 +445,19 @@ function get_arp_entry($search, $value) { return $arp_match; } +// Reload our unbound configuration, restart associated services and clear config locks +function unbound_reload_config() { + $reload_unbound = 0; + $reload_unbound |= services_unbound_configure(); + // Check if application was successful + if ($reload_unbound === 0) { + system_resolvconf_generate(); // Update resolveconf + system_dhcpleases_configure(); // Update DHCPD + clear_subsystem_dirty("unbound"); + return true; + } +} + // Check if a DNS Resolver (Unbound) host override already exists function unbound_host_override_exists($hostname, $domain) { // Local variables diff --git a/pfSense-pkg-API/files/etc/inc/apicalls.inc b/pfSense-pkg-API/files/etc/inc/apicalls.inc index f3402e983..2cb69d3f3 100644 --- a/pfSense-pkg-API/files/etc/inc/apicalls.inc +++ b/pfSense-pkg-API/files/etc/inc/apicalls.inc @@ -5059,6 +5059,9 @@ function api_services_unbound_delete_hosts() { if ($client_params['aliases'] === true) { $a_mode = true; } + if ($client_params['apply'] === true) { + $apply = $client_params['apply']; + } // Determine criteria for deletion if ($h_mode and !$d_mode and !$i_mode) { $del_mode = "h"; @@ -5091,6 +5094,8 @@ function api_services_unbound_delete_hosts() { echo var_dump($a_mode) . PHP_EOL; echo "MODE:" . PHP_EOL; echo var_dump($del_mode) . PHP_EOL; + echo "APPLY:" . PHP_EOL; + echo var_dump($apply) . PHP_EOL; } // Check that our configuration is a list and loop through each item, otherwise return ok resp if (array_key_exists("hosts", $config["unbound"]) and is_array($config["unbound"]["hosts"])) { @@ -5173,11 +5178,13 @@ function api_services_unbound_delete_hosts() { usort($hosts_conf, "strcmp"); $config["unbound"]["hosts"] = $hosts_conf; write_config(sprintf(gettext($change_note))); - $reload_unbound = 0; - $reload_unbound |= services_unbound_configure(); - if ($reload_unbound == 0) { - system_resolvconf_generate(); // Update resolveconf - system_dhcpleases_configure(); // Update DHCPD + mark_subsystem_dirty("unbound"); + # If user requests immediately application + if ($apply === true) { + $applied = unbound_reload_config(); + } + // Return success if our function was successful + if ($applied === true or $apply !== true) { $api_resp = array("status" => "ok", "code" => 200, "return" => 0); $api_resp["message"] = "host override deleted"; $api_resp["data"] = $del_list; @@ -5255,6 +5262,9 @@ function api_services_unbound_modify_hosts() { if (isset($client_params['aliases'])) { $aliases = $client_params['aliases']; } + if ($client_params['apply'] === true) { + $apply = $client_params['apply']; + } // Add debug data if requested if (array_key_exists("debug", $client_params)) { echo "HOSTNAME:" . PHP_EOL; @@ -5273,6 +5283,8 @@ function api_services_unbound_modify_hosts() { echo var_dump($descr) . PHP_EOL; echo "ALIASES:" . PHP_EOL; echo var_dump($aliases) . PHP_EOL; + echo "APPLY:" . PHP_EOL; + echo var_dump($aliases) . PHP_EOL; } // Validate our input against our exist configuration if (unbound_host_override_exists($hostname, $domain) or $i_mode) { @@ -5377,11 +5389,13 @@ function api_services_unbound_modify_hosts() { usort($hosts_conf, "strcmp"); $config["unbound"]["hosts"] = $hosts_conf; write_config(sprintf(gettext($change_note))); - $reload_unbound = 0; - $reload_unbound |= services_unbound_configure(); - if ($reload_unbound == 0) { - system_resolvconf_generate(); // Update resolveconf - system_dhcpleases_configure(); // Update DHCPD + mark_subsystem_dirty("unbound"); + # If user requests immediately application + if ($apply === true) { + $applied = unbound_reload_config(); + } + // Return success if our function was successful + if ($applied === true or $apply !== true) { $api_resp = array("status" => "ok", "code" => 200, "return" => 0); $api_resp["message"] = "Successfully updated unbound host override"; $api_resp["data"] = $update_list; @@ -5598,6 +5612,9 @@ function api_services_unbound_add_hosts() { if (isset($client_params['aliases'])) { $aliases = $client_params['aliases']; } + if ($client_params['apply'] === true) { + $apply = $client_params['apply']; + } // Add debug data if requested if (array_key_exists("debug", $client_params)) { echo "HOSTNAME:" . PHP_EOL; @@ -5610,6 +5627,8 @@ function api_services_unbound_add_hosts() { echo var_dump($descr) . PHP_EOL; echo "ALIASES:" . PHP_EOL; echo var_dump($aliases) . PHP_EOL; + echo "APPLY:" . PHP_EOL; + echo var_dump($apply) . PHP_EOL; } // Validate our input against our exist configuration if (!unbound_host_override_exists($hostname, $domain)) { @@ -5627,11 +5646,13 @@ function api_services_unbound_add_hosts() { $config["unbound"]["hosts"][] = $host_ent; usort($config["unbound"]["hosts"], "host_cmp"); write_config(sprintf(gettext($change_note))); - $reload_unbound = 0; - $reload_unbound |= services_unbound_configure(); - if ($reload_unbound == 0) { - system_resolvconf_generate(); // Update resolveconf - system_dhcpleases_configure(); // Update DHCPD + mark_subsystem_dirty("unbound"); + # If user requests immediately application + if ($apply === true) { + $applied = unbound_reload_config(); + } + // Return success if our function was successful + if ($applied === true or $apply !== true) { $api_resp = array("status" => "ok", "code" => 200, "return" => 0); $api_resp["message"] = "Successfully added unbound host override"; $api_resp["data"] = $host_ent; @@ -5662,6 +5683,33 @@ function api_services_unbound_add_hosts() { } } +function api_services_unbound_apply() { + # VARIABLES; + global $err_lib; + $read_only_action = false; // Set whether this action requires read only access + $req_privs = array("page-all", "page-services-dnsresolver-edithost"); // Array of privileges allowing this action + $http_method = $_SERVER['REQUEST_METHOD']; // Save our HTTP method + # RUN TIME + // Check that client is authenticated and authorized + if (api_authorized($req_privs, $read_only_action)) { + // Check that our HTTP method is POST (CREATE) + if ($http_method === 'POST') { + // Check if application was successful + if (unbound_reload_config() === true) { + $api_resp = array("status" => "ok", "code" => 200, "return" => 0); + $api_resp["message"] = "Successfully applied unbound configuration"; + $api_resp["data"] = ""; + return $api_resp; + } else { + $api_resp = array("status" => "server error", "code" => 500, "return" => 1); + $api_resp["message"] = $err_lib[$api_resp["return"]]; + return $api_resp; + } + } + } +} + + function api_interfaces_vlans() { # VARIABLES global $err_lib, $g, $config, $argv, $userindex, $api_resp, $client_params; diff --git a/pfSense-pkg-API/files/usr/local/share/pfSense-pkg-API/info.xml b/pfSense-pkg-API/files/usr/local/share/pfSense-pkg-API/info.xml index 2a7a4f3ac..2ecb87090 100644 --- a/pfSense-pkg-API/files/usr/local/share/pfSense-pkg-API/info.xml +++ b/pfSense-pkg-API/files/usr/local/share/pfSense-pkg-API/info.xml @@ -4,7 +4,7 @@ API api - https://github.com/jaredhendrickson13 + pfsense-api.jaredhendrickson.com System %%PKGVERSION%% api.xml diff --git a/pfSense-pkg-API/files/usr/local/www/api/v1/services/unbound/apply/index.php b/pfSense-pkg-API/files/usr/local/www/api/v1/services/unbound/apply/index.php new file mode 100644 index 000000000..8245d6352 --- /dev/null +++ b/pfSense-pkg-API/files/usr/local/www/api/v1/services/unbound/apply/index.php @@ -0,0 +1,10 @@ +