add icon to display detailed commands/file-contents from config-templates in admin_configfiles

Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
Michael Kaufmann
2022-04-24 11:08:09 +02:00
parent 000cb93def
commit b5794e463f
7 changed files with 300 additions and 27 deletions

View File

@@ -3,6 +3,8 @@
namespace Froxlor\Ajax;
use Exception;
use Froxlor\Froxlor;
use Froxlor\FileDir;
use Froxlor\Database\Database;
use Froxlor\Http\HttpClient;
use Froxlor\Validate\Validate;
@@ -10,6 +12,8 @@ use Froxlor\Settings;
use Froxlor\UI\Listing;
use Froxlor\UI\Panel\UI;
use Froxlor\UI\Request;
use Froxlor\Config\ConfigParser;
use Froxlor\Config\ConfigDisplay;
/**
* This file is part of the Froxlor project.
@@ -320,14 +324,46 @@ class Ajax
return $this->jsonResponse(['allowed_from' => $allowed_from, 'valid_until' => $valid_until]);
}
/**
* return parsed commands/files of configuration templates
*/
private function getConfigDetails()
{
$distro = isset($_POST['distro,']) ? $_POST['distro,'] : "";
$section = isset($_POST['section']) ? $_POST['section'] : "";
$daemon = isset($_POST['daemon']) ? $_POST['daemon'] : "";
if (isset($this->userinfo['adminsession']) && $this->userinfo['adminsession'] == 1 && $this->userinfo['change_serversettings'] == 1) {
$distribution = isset($_POST['distro']) ? $_POST['distro'] : "";
$section = isset($_POST['section']) ? $_POST['section'] : "";
$daemon = isset($_POST['daemon']) ? $_POST['daemon'] : "";
// @todo
// validate distribution config-xml exists
$config_dir = FileDir::makeCorrectDir(Froxlor::getInstallDir() . '/lib/configfiles/');
if (!file_exists($config_dir . "/" . $distribution . ".xml")) {
return $this->errorResponse("Unknown distribution. The configuration could not be found.");
}
// read in all configurations
$configfiles = new ConfigParser($config_dir . "/" . $distribution . ".xml");
// get the services
$services = $configfiles->getServices();
// validate selected service exists for this distribution
if (!isset($services[$section])) {
return $this->errorResponse("Unknown category for selected distribution");
}
// get the daemons
$daemons = $services[$section]->getDaemons();
// validate selected daemon exists for this section
if (!isset($daemons[$daemon])) {
return $this->errorResponse("Unknown service for selected category");
}
// finally the config-steps
$confarr = $daemons[$daemon]->getConfig();
// get parsed content
UI::initTwig();
$content = ConfigDisplay::fromConfigArr($confarr, $configfiles->distributionEditor, $this->theme);
return $this->jsonResponse(['title' => 'TODO', 'content' => '<div class="alert alert-warning" role="alert">TODO</div>']);
return $this->jsonResponse([
'title' => $configfiles->getCompleteDistroName() . '&nbsp;&raquo;&nbsp' . $services[$section]->title . '&nbsp;&raquo;&nbsp' . $daemons[$daemon]->title,
'content' => $content
]);
}
return $this->errorResponse('Not allowed', 403);
}
}

View File

@@ -0,0 +1,224 @@
<?php
namespace Froxlor\Config;
use Froxlor\Froxlor;
use Froxlor\Settings;
use Froxlor\PhpHelper;
use Froxlor\FileDir;
use Froxlor\Database\Database;
use Froxlor\UI\Panel\UI;
/**
* This file is part of the Froxlor project.
* Copyright (c) 2010 the Froxlor Team (see authors).
*
* For the full copyright and license information, please view the COPYING
* file that was distributed with this source code. You can also view the
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
*
* @copyright (c) the authors
* @author Froxlor team <team@froxlor.org> (2010-)
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package Config
*
*/
class ConfigDisplay
{
/**
* @var array
*/
private static $replace_arr;
/**
* @var string
*/
private static $editor;
/**
* @var string
*/
private static $theme;
/**
* @param array $confarr
* @param string $editor
* @param string $theme
*/
public static function fromConfigArr(array $confarr, string $editor, string $theme)
{
self::$editor = $editor;
self::$theme = $theme;
$customer_tmpdir = '/tmp/';
if (Settings::Get('system.mod_fcgid') == '1' && Settings::Get('system.mod_fcgid_tmpdir') != '') {
$customer_tmpdir = Settings::Get('system.mod_fcgid_tmpdir');
} elseif (Settings::Get('phpfpm.enabled') == '1' && Settings::Get('phpfpm.tmpdir') != '') {
$customer_tmpdir = Settings::Get('phpfpm.tmpdir');
}
// try to convert namserver hosts to ip's
$ns_ips = "";
$known_ns_ips = [];
if (Settings::Get('system.nameservers') != '') {
$nameservers = explode(',', Settings::Get('system.nameservers'));
foreach ($nameservers as $nameserver) {
$nameserver = trim($nameserver);
// DNS servers might be multi homed; allow transfer from all ip
// addresses of the DNS server
$nameserver_ips = PhpHelper::gethostbynamel6($nameserver);
// append dot to hostname
if (substr($nameserver, -1, 1) != '.') {
$nameserver .= '.';
}
// ignore invalid responses
if (!is_array($nameserver_ips)) {
// act like \Froxlor\PhpHelper::gethostbynamel6() and return unmodified hostname on error
$nameserver_ips = array(
$nameserver
);
} else {
$known_ns_ips = array_merge($known_ns_ips, $nameserver_ips);
}
if (!empty($ns_ips)) {
$ns_ips .= ',';
}
$ns_ips .= implode(",", $nameserver_ips);
}
}
// AXFR server
if (Settings::Get('system.axfrservers') != '') {
$axfrservers = explode(',', Settings::Get('system.axfrservers'));
foreach ($axfrservers as $axfrserver) {
if (!in_array(trim($axfrserver), $known_ns_ips)) {
if (!empty($ns_ips)) {
$ns_ips .= ',';
}
$ns_ips .= trim($axfrserver);
}
}
}
Database::needSqlData(true);
$sql = Database::getSqlData();
self::$replace_arr = array(
'<SQL_UNPRIVILEGED_USER>' => $sql['user'],
'<SQL_UNPRIVILEGED_PASSWORD>' => 'FROXLOR_MYSQL_PASSWORD',
'<SQL_DB>' => $sql['db'],
'<SQL_HOST>' => $sql['host'],
'<SQL_SOCKET>' => isset($sql['socket']) ? $sql['socket'] : null,
'<SERVERNAME>' => Settings::Get('system.hostname'),
'<SERVERIP>' => Settings::Get('system.ipaddress'),
'<NAMESERVERS>' => Settings::Get('system.nameservers'),
'<NAMESERVERS_IP>' => $ns_ips,
'<VIRTUAL_MAILBOX_BASE>' => Settings::Get('system.vmail_homedir'),
'<VIRTUAL_UID_MAPS>' => Settings::Get('system.vmail_uid'),
'<VIRTUAL_GID_MAPS>' => Settings::Get('system.vmail_gid'),
'<SSLPROTOCOLS>' => (Settings::Get('system.use_ssl') == '1') ? 'imaps pop3s' : '',
'<CUSTOMER_TMP>' => FileDir::makeCorrectDir($customer_tmpdir),
'<BASE_PATH>' => FileDir::makeCorrectDir(Froxlor::getInstallDir()),
'<BIND_CONFIG_PATH>' => FileDir::makeCorrectDir(Settings::Get('system.bindconf_directory')),
'<WEBSERVER_RELOAD_CMD>' => Settings::Get('system.apachereload_command'),
'<CUSTOMER_LOGS>' => FileDir::makeCorrectDir(Settings::Get('system.logfiles_directory')),
'<FPM_IPCDIR>' => FileDir::makeCorrectDir(Settings::Get('phpfpm.fastcgi_ipcdir')),
'<WEBSERVER_GROUP>' => Settings::Get('system.httpgroup')
);
$commands_pre = "";
$commands_file = "";
$commands_post = "";
$lasttype = '';
$commands = '';
$configpage = "";
foreach ($confarr as $_action) {
if ($lasttype != '' && $lasttype != $_action['type']) {
$commands = trim($commands);
$numbrows = count(explode("\n", $commands));
$configpage .= UI::twig()->render(self::$theme . '/settings/conf/command.html.twig', ['commands' => $commands, 'numbrows' => $numbrows]);
$lasttype = '';
$commands = '';
}
switch ($_action['type']) {
case "install":
$commands .= strtr($_action['content'], self::$replace_arr) . "\n";
$lasttype = "install";
break;
case "command":
$commands .= strtr($_action['content'], self::$replace_arr) . "\n";
$lasttype = "command";
break;
case "file":
if (array_key_exists('content', $_action)) {
$commands_file = self::getFileContentContainer($_action['content'], $_action['name']);
} elseif (array_key_exists('subcommands', $_action)) {
foreach ($_action['subcommands'] as $fileaction) {
if (array_key_exists('execute', $fileaction) && $fileaction['execute'] == "pre") {
$commands_pre .= $fileaction['content'] . "\n";
} elseif (array_key_exists('execute', $fileaction) && $fileaction['execute'] == "post") {
$commands_post .= $fileaction['content'] . "\n";
} elseif ($fileaction['type'] == 'file') {
$commands_file = self::getFileContentContainer($fileaction['content'], $_action['name']);
}
}
}
$realname = $_action['name'];
$commands = trim($commands_pre);
if ($commands != "") {
$numbrows = count(explode("\n", $commands));
$commands_pre = UI::twig()->render(self::$theme . '/settings/conf/command.html.twig', ['commands' => $commands, 'numbrows' => $numbrows]);
}
$commands = trim($commands_post);
if ($commands != "") {
$numbrows = count(explode("\n", $commands));
$commands_post = UI::twig()->render(self::$theme . '/settings/conf/command.html.twig', ['commands' => $commands, 'numbrows' => $numbrows]);
}
$configpage .= UI::twig()->render(self::$theme . '/settings/conf/fileblock.html.twig', [
'realname' => $realname,
'commands_pre' => $commands_pre,
'commands_file' => $commands_file,
'commands_post' => $commands_post
]);
$commands = '';
$commands_pre = '';
$commands_post = '';
break;
}
}
$commands = trim($commands);
if ($commands != '') {
$numbrows = count(explode("\n", $commands));
$configpage .= UI::twig()->render(self::$theme . '/settings/conf/command.html.twig', ['commands' => $commands, 'numbrows' => $numbrows]);
}
return $configpage;
}
/**
* @param string $file_content
* @param string $realname
*
* @return string
*/
private static function getFileContentContainer(string $file_content, string $realname): string
{
$files = "";
$file_content = trim($file_content);
if ($file_content != '') {
$file_content = strtr($file_content, self::$replace_arr);
$file_content = htmlspecialchars($file_content);
$numbrows = count(explode("\n", $file_content));
//eval("\$files=\"" . \Froxlor\UI\Template::getTemplate("configfiles/configfiles_file") . "\";");
$files = UI::twig()->render(self::$theme . '/settings/conf/file.html.twig', [
'distro_editor' => self::$editor,
'realname' => $realname,
'numbrows' => $numbrows,
'file_content' => $file_content
]);
}
return $files;
}
}

View File

@@ -1,4 +1,5 @@
<?php
namespace Froxlor\Config;
/**
@@ -106,7 +107,7 @@ class ConfigParser
*/
public function __construct($filename)
{
if (! is_readable($filename)) {
if (!is_readable($filename)) {
throw new \Exception('File not readable');
}
@@ -123,7 +124,7 @@ class ConfigParser
$distribution = $this->xml->xpath('//distribution');
// No distribution found - can't use this file
if (! is_array($distribution)) {
if (!is_array($distribution)) {
throw new \Exception('Invalid XML, no distribution found');
}
@@ -235,4 +236,25 @@ class ConfigParser
// Return our carefully searched for defaults
return $this->defaults;
}
/**
* return complete distribution string "Name [codename] [ (version)] [deprecated]
*
* @return string
*/
public function getCompleteDistroName(): string
{
// get distro-info
$dist_display = $this->distributionName;
if ($this->distributionCodename != '') {
$dist_display .= " " . $this->distributionCodename;
}
if ($this->distributionVersion != '') {
$dist_display .= " (" . $this->distributionVersion . ")";
}
if ($this->deprecated) {
$dist_display .= " [deprecated]";
}
return $dist_display;
}
}