mirror of
https://github.com/opnsense/core.git
synced 2026-05-28 04:34:51 -04:00
System: Configuration: Defaults - refactor to mvc and add "components" which offers a configuration reset function per model (when not installed, it uses the version tags to identify them). closes https://github.com/opnsense/core/issues/8768
This commit is contained in:
parent
420a9cc2ec
commit
c485a33ab7
10 changed files with 525 additions and 121 deletions
6
plist
6
plist
|
|
@ -199,6 +199,7 @@
|
|||
/usr/local/opnsense/mvc/app/controllers/OPNsense/CaptivePortal/forms/dialogZone.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Core/Api/BackupController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Core/Api/DashboardController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Core/Api/DefaultsController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Core/Api/FirmwareController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Core/Api/HasyncController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Core/Api/HasyncStatusController.php
|
||||
|
|
@ -210,6 +211,7 @@
|
|||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Core/Api/TunablesController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Core/BackupController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Core/DashboardController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Core/DefaultsController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Core/FirmwareController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Core/HaltController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Core/HasyncController.php
|
||||
|
|
@ -520,6 +522,7 @@
|
|||
/usr/local/opnsense/mvc/app/library/OPNsense/Core/Backend.php
|
||||
/usr/local/opnsense/mvc/app/library/OPNsense/Core/Config.php
|
||||
/usr/local/opnsense/mvc/app/library/OPNsense/Core/ConfigException.php
|
||||
/usr/local/opnsense/mvc/app/library/OPNsense/Core/ConfigMaintenance.php
|
||||
/usr/local/opnsense/mvc/app/library/OPNsense/Core/File.php
|
||||
/usr/local/opnsense/mvc/app/library/OPNsense/Core/FileObject.php
|
||||
/usr/local/opnsense/mvc/app/library/OPNsense/Core/SanitizeFilter.php
|
||||
|
|
@ -888,6 +891,7 @@
|
|||
/usr/local/opnsense/mvc/app/views/OPNsense/CaptivePortal/vouchers.volt
|
||||
/usr/local/opnsense/mvc/app/views/OPNsense/Core/backup_history.volt
|
||||
/usr/local/opnsense/mvc/app/views/OPNsense/Core/dashboard.volt
|
||||
/usr/local/opnsense/mvc/app/views/OPNsense/Core/defaults.volt
|
||||
/usr/local/opnsense/mvc/app/views/OPNsense/Core/firmware.volt
|
||||
/usr/local/opnsense/mvc/app/views/OPNsense/Core/halt.volt
|
||||
/usr/local/opnsense/mvc/app/views/OPNsense/Core/hasync.volt
|
||||
|
|
@ -1316,6 +1320,7 @@
|
|||
/usr/local/opnsense/scripts/system/certctl.py
|
||||
/usr/local/opnsense/scripts/system/cpu.py
|
||||
/usr/local/opnsense/scripts/system/crl_fetch.py
|
||||
/usr/local/opnsense/scripts/system/factory_defaults.php
|
||||
/usr/local/opnsense/scripts/system/flush_config_history
|
||||
/usr/local/opnsense/scripts/system/get_locales.php
|
||||
/usr/local/opnsense/scripts/system/get_timezones.php
|
||||
|
|
@ -2438,7 +2443,6 @@
|
|||
/usr/local/www/csrf.inc
|
||||
/usr/local/www/diag_authentication.php
|
||||
/usr/local/www/diag_backup.php
|
||||
/usr/local/www/diag_defaults.php
|
||||
/usr/local/www/fbegin.inc
|
||||
/usr/local/www/firewall_nat.php
|
||||
/usr/local/www/firewall_nat_edit.php
|
||||
|
|
|
|||
|
|
@ -0,0 +1,133 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2025 Deciso B.V.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace OPNsense\Core\Api;
|
||||
|
||||
use OPNsense\Base\ApiControllerBase;
|
||||
use OPNsense\Core\ACL;
|
||||
use OPNsense\Core\Backend;
|
||||
use OPNsense\Core\Config;
|
||||
use OPNsense\Core\ConfigMaintenance;
|
||||
|
||||
/**
|
||||
* Class DefaultsController
|
||||
* @package OPNsense\Core\Api
|
||||
*/
|
||||
class DefaultsController extends ApiControllerBase
|
||||
{
|
||||
/**
|
||||
* when the user-config-readonly privilege is set, raise an error
|
||||
*/
|
||||
private function throwReadOnly()
|
||||
{
|
||||
if ((new ACL())->hasPrivilege($this->getUserName(), 'user-config-readonly')) {
|
||||
throw new UserException(
|
||||
sprintf("User %s denied for write access (user-config-readonly set)", $this->getUserName())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return defaults
|
||||
*/
|
||||
public function getAction()
|
||||
{
|
||||
$default_ip = '192.168.1.1';
|
||||
if (is_file('/usr/local/etc/config.xml')) {
|
||||
$cfg = Config::getInstance()->toArrayFromFile('/usr/local/etc/config.xml');
|
||||
if (is_array($cfg) &&
|
||||
!empty($cfg['interfaces']) &&
|
||||
!empty($cfg['interfaces']['lan']) &&
|
||||
!empty($cfg['interfaces']['lan']['ipaddr'])
|
||||
) {
|
||||
$default_ip = $cfg['interfaces']['lan']['ipaddr'];
|
||||
}
|
||||
}
|
||||
return ['default_ip' => $default_ip];
|
||||
}
|
||||
|
||||
/**
|
||||
* reset to defaults
|
||||
*/
|
||||
public function factoryDefaultsAction()
|
||||
{
|
||||
$this->throwReadOnly();
|
||||
if (!$this->request->isPost()) {
|
||||
return ['status' => 'failed'];
|
||||
}
|
||||
|
||||
/* schedule factory defaults so we can safely respond to the client */
|
||||
(new Backend())->configdRun('system reset_factory_defaults', true);
|
||||
return ['status' => 'ok'];
|
||||
}
|
||||
|
||||
/**
|
||||
* return used configuration items
|
||||
*/
|
||||
public function getInstalledSectionsAction()
|
||||
{
|
||||
$result = ['items' => []];
|
||||
$cm = new ConfigMaintenance();
|
||||
foreach($cm->traverseConfig() as $item) {
|
||||
$result['items'][] = $item;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* reset a (list of) section(s)
|
||||
*/
|
||||
public function resetAction()
|
||||
{
|
||||
$this->throwReadOnly();
|
||||
if (
|
||||
!$this->request->isPost() ||
|
||||
!is_array($this->request->getPost('items')) ||
|
||||
empty($this->request->getPost('items'))
|
||||
) {
|
||||
return ['status' => 'failed'];
|
||||
}
|
||||
$cm = new ConfigMaintenance();
|
||||
$modelmap = $cm->getMap();
|
||||
foreach ($this->request->getPost('items') as $section) {
|
||||
if (isset($modelmap[$section])) {
|
||||
/* installed model flush */
|
||||
$mdl = new $modelmap[$section]['class'](true);
|
||||
$mdl->Default();
|
||||
$mdl->serializeToConfig(false, true);
|
||||
} else {
|
||||
$cm->delItem($section);
|
||||
}
|
||||
}
|
||||
|
||||
Config::getInstance()->save();
|
||||
|
||||
return ['status' => 'ok'];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2025 Deciso B.V.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace OPNsense\Core;
|
||||
|
||||
/**
|
||||
* Class DefaultsController
|
||||
* @package OPNsense\Core
|
||||
*/
|
||||
class DefaultsController extends \OPNsense\Base\IndexController
|
||||
{
|
||||
public function indexAction()
|
||||
{
|
||||
$this->view->pick('OPNsense/Core/defaults');
|
||||
}
|
||||
}
|
||||
145
src/opnsense/mvc/app/library/OPNsense/Core/ConfigMaintenance.php
Normal file
145
src/opnsense/mvc/app/library/OPNsense/Core/ConfigMaintenance.php
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2025 Deciso B.V.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace OPNsense\Core;
|
||||
|
||||
use OPNsense\Core\AppConfig;
|
||||
use OPNsense\Core\Syslog;
|
||||
|
||||
class ConfigMaintenance
|
||||
{
|
||||
private $modelmap = [];
|
||||
private $foundrefs = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->modelmap = $this->loadModels();
|
||||
}
|
||||
|
||||
/**
|
||||
* collect all installed modules
|
||||
*/
|
||||
private function loadModels()
|
||||
{
|
||||
$modelfiles = [];
|
||||
$model_dir = dirname((new \ReflectionClass("OPNsense\\Base\\BaseModel"))->getFileName()) . "/../../";
|
||||
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($model_dir)) as $x) {
|
||||
$pinfo = pathinfo(realpath($x->getPathname()));
|
||||
$xmlname = sprintf("%s/%s.xml", $pinfo['dirname'], $pinfo['filename']);
|
||||
$classname = str_replace('/', '\\', explode('.', str_replace($model_dir, '', $x->getPathname()))[0]);
|
||||
if (file_exists($xmlname) && isset($pinfo['extension']) && $pinfo['extension'] == 'php') {
|
||||
$parent = (new \ReflectionClass($classname))->getParentClass();
|
||||
if ($parent && $parent->name == 'OPNsense\Base\BaseModel') {
|
||||
$modelfiles[$xmlname] = $classname;
|
||||
}
|
||||
}
|
||||
}
|
||||
$map = [];
|
||||
foreach ($modelfiles as $filename => $classname) {
|
||||
$model_xml = simplexml_load_file($filename);
|
||||
if ($model_xml !== false && str_starts_with($model_xml->mount, '/')) {
|
||||
$mount = str_replace('/', '.', ltrim(rtrim($model_xml->mount, '+'), '/'));
|
||||
$map[$mount] = [
|
||||
'filename' => $filename,
|
||||
'class' => $classname,
|
||||
'description' => trim((string)$model_xml->description ?? '')
|
||||
];
|
||||
}
|
||||
}
|
||||
return $map;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* collect all "flushable" configuration items (models)
|
||||
*/
|
||||
public function traverseConfig($node=null, $path='')
|
||||
{
|
||||
if ($node === null) {
|
||||
$node = (Config::getInstance())->object();
|
||||
$this->foundrefs = [];
|
||||
}
|
||||
foreach ($node->children() as $xmlNode) {
|
||||
if ($xmlNode->count() > 0) {
|
||||
$this_path = ltrim($path . '.' . $xmlNode->getName(), '.');
|
||||
if (in_array($this_path, $this->foundrefs)) {
|
||||
continue;
|
||||
} elseif (isset($this->modelmap[$this_path]) || !empty($xmlNode->attributes()['version'])) {
|
||||
/* found a registered model or a container with a version tag (likely model, but not installed) */
|
||||
$this->foundrefs[] = $this_path;
|
||||
if (isset($this->modelmap[$this_path])) {
|
||||
yield [
|
||||
'id' => $this_path,
|
||||
'description' => $this->modelmap[$this_path]['description']
|
||||
];
|
||||
} else {
|
||||
$tmp = explode('.', $this_path);
|
||||
yield [
|
||||
'id' => $this_path,
|
||||
'description' => end($tmp)
|
||||
];
|
||||
}
|
||||
} else {
|
||||
yield from $this->traverseConfig($xmlNode, $this_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* del model item, requires a version attribute to identify itself as a model.
|
||||
*/
|
||||
public function delItem($item, $node=null, $path='')
|
||||
{
|
||||
if ($node === null) {
|
||||
$node = (Config::getInstance())->object();
|
||||
}
|
||||
foreach ($node->children() as $xmlNode) {
|
||||
if ($xmlNode->count() > 0) {
|
||||
$this_path = ltrim($path . '.' . $xmlNode->getName(), '.');
|
||||
if (!empty($xmlNode->attributes()['version'])) {
|
||||
if ($this_path == $item) {
|
||||
unset($xmlNode[0]);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
$this->delItem($item, $xmlNode, $this_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve model map
|
||||
*/
|
||||
public function getMap()
|
||||
{
|
||||
return $this->modelmap;
|
||||
}
|
||||
}
|
||||
|
|
@ -60,7 +60,8 @@
|
|||
<page-diagnostics-factorydefaults>
|
||||
<name>Diagnostics: Factory defaults</name>
|
||||
<patterns>
|
||||
<pattern>diag_defaults.php*</pattern>
|
||||
<pattern>ui/core/defaults</pattern>
|
||||
<pattern>api/core/defaults/*</pattern>
|
||||
</patterns>
|
||||
</page-diagnostics-factorydefaults>
|
||||
<page-diagnostics-haltsystem>
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
</Access>
|
||||
<Configuration cssClass="fa fa-history fa-fw">
|
||||
<Backups url="/diag_backup.php"/>
|
||||
<Defaults url="/diag_defaults.php"/>
|
||||
<Defaults url="/ui/core/defaults"/>
|
||||
<History url="/ui/core/backup/history/this"/>
|
||||
<Wizard url="/ui/core/initial_setup"/>
|
||||
</Configuration>
|
||||
|
|
|
|||
151
src/opnsense/mvc/app/views/OPNsense/Core/defaults.volt
Normal file
151
src/opnsense/mvc/app/views/OPNsense/Core/defaults.volt
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
{#
|
||||
# Copyright (c) 2025 Deciso B.V.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#}
|
||||
|
||||
<script>
|
||||
|
||||
$( document ).ready(function() {
|
||||
/* update default address and show form */
|
||||
ajaxGet('/api/core/defaults/get', {}, function(data){
|
||||
if (data.default_ip) {
|
||||
$("#ip_placeholder").text($("#ip_placeholder").text().replace('%s', data.default_ip));
|
||||
$("#defaults_form").show();
|
||||
}
|
||||
});
|
||||
/* full system defauls */
|
||||
$("#system_defaults").click(function(){
|
||||
BootstrapDialog.show({
|
||||
type:BootstrapDialog.TYPE_INFO,
|
||||
title: '{{ lang._('Configuration defaults') }}',
|
||||
closable: false,
|
||||
message: '{{ lang._('The system will install the configuration defaults now and power off when finished.') }}',
|
||||
onshow: function (dialogRef) {
|
||||
ajaxCall('/api/core/defaults/factory_defaults');
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
function load_section()
|
||||
{
|
||||
ajaxGet('/api/core/defaults/get_installed_sections', {}, function(data){
|
||||
if (data.items) {
|
||||
$("#sections").empty();
|
||||
data.items.forEach(function (item, index) {
|
||||
$("#sections").append($("<option/>").val(item.id).text(
|
||||
item.description + ' [' + item.id + ']'
|
||||
));
|
||||
});
|
||||
$("#sections").selectpicker('refresh');
|
||||
}
|
||||
});
|
||||
}
|
||||
load_section();
|
||||
|
||||
$("#reset_sections").click(function(event){
|
||||
event.preventDefault();
|
||||
BootstrapDialog.show({
|
||||
type:BootstrapDialog.TYPE_DANGER,
|
||||
title: "{{ lang._('Reset') }}",
|
||||
message: "{{ lang._('Are you sure you want to reset selected configuration sections?\n Removing parts of the configuration does not warrant consistency and may lead to unexpected behavior.')}}",
|
||||
buttons: [
|
||||
{
|
||||
label: "{{ lang._('No') }}",
|
||||
action: function(dialogRef) {
|
||||
dialogRef.close();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "{{ lang._('Yes') }}",
|
||||
action: function(dialogRef) {
|
||||
ajaxCall('/api/core/defaults/reset', {'items': $("#sections").val()}, function(){
|
||||
dialogRef.close();
|
||||
load_section();
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<ul class="nav nav-tabs" data-tabs="tabs" id="maintabs">
|
||||
<li class="active"><a id="systemtab" data-toggle="tab" href="#full_defaults">{{ lang._('Full') }}</a></li>
|
||||
<li id="componentstab"><a data-toggle="tab" href="#components">{{ lang._('Components') }}</a></li>
|
||||
</ul>
|
||||
<div class="tab-content content-box">
|
||||
<div id="full_defaults" class="tab-pane fade in active">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<section class="col-xs-12" style="display: none;" id="defaults_form">
|
||||
<br/>
|
||||
<p><strong> {{ lang._('If you click "Yes", the system will:') }}</strong></p>
|
||||
<ul>
|
||||
<li>{{ lang._('Reset to factory defaults') }}</li>
|
||||
<li id="ip_placeholder">{{ lang._('LAN IP address will be reset to %s') }}</li>
|
||||
<li>{{ lang._('System will be configured as a DHCP server on the default LAN interface') }}</li>
|
||||
<li>{{ lang._('WAN interface will be set to obtain an address automatically from a DHCP server') }}</li>
|
||||
<li>{{ lang._('Admin user name and password will be reset') }}</li>
|
||||
<li>{{ lang._('Shut down after changes are complete') }}</li>
|
||||
</ul>
|
||||
<p><strong>{{ lang._('Are you sure you want to proceed?') }}</strong></p>
|
||||
<div class="btn-group">
|
||||
<button id="system_defaults" class="btn btn-primary">{{ lang._('Yes')}}</button>
|
||||
<a href="/" class="btn btn-default">{{ lang._('No')}}</a>
|
||||
<br/><br/><br/>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="components" class="tab-pane fade in">
|
||||
<table class="table table-condensed table-striped">
|
||||
<br/>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">
|
||||
{{ lang._('Danger zone, only reset configuration sections if you understand the impact.') }}
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ lang._('Sections')}}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<select id="sections" data-size="10" data-width="100%" data-live-search="true" multiple="multiple"></select>
|
||||
</td>
|
||||
<td>
|
||||
<button id="reset_sections" class="btn btn-primary">{{ lang._('Reset')}}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
41
src/opnsense/scripts/system/factory_defaults.php
Executable file
41
src/opnsense/scripts/system/factory_defaults.php
Executable file
|
|
@ -0,0 +1,41 @@
|
|||
#!/usr/local/bin/php
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2025 Deciso B.V.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
require_once 'config.inc';
|
||||
require_once 'system.inc';
|
||||
require_once 'util.inc';
|
||||
|
||||
echo "waiting before shutdown..";
|
||||
for ($i=0; $i < 5; ++$i) {
|
||||
echo ".";
|
||||
sleep(1);
|
||||
}
|
||||
echo "down\n";
|
||||
|
||||
reset_factory_defaults();
|
||||
|
|
@ -102,6 +102,12 @@ type:script
|
|||
description:Halt and power off the system
|
||||
message:Halting system
|
||||
|
||||
[reset_factory_defaults]
|
||||
command:/usr/local/opnsense/scripts/system/factory_defaults.php
|
||||
parameters:
|
||||
type:script_output
|
||||
message:Revert to system defaults and power down the system
|
||||
|
||||
[sensors]
|
||||
command:sysctl -aF | awk -F ": " '$2 ~ "^IK" { print $1 }' | grep -v -e "\._" -e "\.ctt" -e "\.[pt][m012]" -e "\.tjmax" | sort
|
||||
parameters:
|
||||
|
|
|
|||
|
|
@ -1,118 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Deciso B.V.
|
||||
* Copyright (C) 2004-2009 Scott Ullrich <sullrich@gmail.com>
|
||||
* Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
require_once("guiconfig.inc");
|
||||
require_once("system.inc");
|
||||
|
||||
$input_errors = [];
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (!empty($_POST['Submit'])) {
|
||||
$user = getUserEntry($_SESSION['Username']);
|
||||
if (userHasPrivilege($user, 'user-config-readonly')) {
|
||||
$input_errors[] = gettext('You do not have the permission to perform this action.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$default_config_ip = '192.168.1.1'; /* failsafe default */
|
||||
if (is_file('/usr/local/etc/config.xml')) {
|
||||
try {
|
||||
$restore_conf = load_config_from_file('/usr/local/etc/config.xml');
|
||||
if (
|
||||
is_array($restore_conf) &&
|
||||
!empty($restore_conf['interfaces']) &&
|
||||
!empty($restore_conf['interfaces']['lan']) &&
|
||||
!empty($restore_conf['interfaces']['lan']['ipaddr'])
|
||||
) {
|
||||
$default_config_ip = $restore_conf['interfaces']['lan']['ipaddr'];
|
||||
}
|
||||
} catch (Exception $e) { }
|
||||
}
|
||||
|
||||
include("head.inc");
|
||||
|
||||
?>
|
||||
<body>
|
||||
<?php
|
||||
|
||||
include("fbegin.inc");
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['Submit']) && !count($input_errors)): ?>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
BootstrapDialog.show({
|
||||
type:BootstrapDialog.TYPE_INFO,
|
||||
title: '<?= html_safe(gettext('Your device is powering off')) ?>',
|
||||
closable: false,
|
||||
message: '<?= html_safe(gettext('The system has been reset to factory defaults and is shutting down.')) ?>',
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php endif ?>
|
||||
|
||||
<section class="page-content-main">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<?php if (count($input_errors)) print_input_errors($input_errors); ?>
|
||||
<section class="col-xs-12">
|
||||
<form method="post">
|
||||
<p><strong> <?=gettext('If you click "Yes", the system will:')?></strong></p>
|
||||
<ul>
|
||||
<li><?= gettext('Reset to factory defaults') ?></li>
|
||||
<li><?= sprintf(gettext('LAN IP address will be reset to %s'), $default_config_ip) ?></li>
|
||||
<li><?= gettext('System will be configured as a DHCP server on the default LAN interface') ?></li>
|
||||
<li><?= gettext('WAN interface will be set to obtain an address automatically from a DHCP server') ?></li>
|
||||
<li><?= gettext('Admin user name and password will be reset') ?></li>
|
||||
<li><?= gettext('Shut down after changes are complete') ?></li>
|
||||
</ul>
|
||||
<p><strong><?=gettext("Are you sure you want to proceed?");?></strong></p>
|
||||
<div class="btn-group">
|
||||
<input type="submit" name="Submit" class="btn btn-primary" value="<?= html_safe(gettext('Yes')) ?>" />
|
||||
<a href="/" class="btn btn-default"><?=gettext("No");?></a>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<?php
|
||||
|
||||
include("foot.inc");
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (!empty($_POST['Submit'])) {
|
||||
if (!count($input_errors)) {
|
||||
reset_factory_defaults(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue