Merge branch 'ent-11830-reemplazar-sistema-de-websocket-gotty-actual' into 'develop'
11830 adding package preparation for rpm gotty See merge request artica/pandorafms!6462
This commit is contained in:
commit
b2019fad9a
|
@ -0,0 +1 @@
|
|||
src/pandora_gotty filter=lfs diff=lfs merge=lfs -text
|
|
@ -0,0 +1,2 @@
|
|||
*.rpm
|
||||
*.deb
|
|
@ -0,0 +1,8 @@
|
|||
FROM rockylinux:8
|
||||
|
||||
RUN dnf install -y rpm-build rpmdevtools
|
||||
RUN rpmdev-setuptree
|
||||
RUN mkdir /root/pandora_gotty
|
||||
WORKDIR /root/pandora_gotty
|
||||
|
||||
#CMD bash build.sh
|
|
@ -0,0 +1,6 @@
|
|||
FROM ubuntu:22.04
|
||||
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y dh-make debhelper build-essential
|
||||
RUN mkdir /root/pandora_gotty
|
||||
WORKDIR /root/pandora_gotty
|
|
@ -0,0 +1 @@
|
|||
To create the .deb and .rpm package need to hace docker installed on main system and execit `build_all_docker.sh`
|
|
@ -0,0 +1,11 @@
|
|||
#Build RPM
|
||||
docker build -t pandora_gotty_builder_rpm -f Dockerfile-RPM . || exit 1
|
||||
docker run --rm -it -v `pwd`:/root/pandora_gotty pandora_gotty_builder_rpm /root/pandora_gotty/build_rpm.sh || exit 1
|
||||
|
||||
#Buikd DEB
|
||||
docker build -t pandora_gotty_builder_deb -f Dockerfile-deb . || exit 1
|
||||
docker run --rm -it -v `pwd`:/root/pandora_gotty pandora_gotty_builder_deb /root/pandora_gotty/build_deb.sh || exit 1
|
||||
|
||||
echo " - Done"
|
||||
pwd
|
||||
ls -l | grep -E "(\.deb|\.rpm)"
|
|
@ -0,0 +1,17 @@
|
|||
#!/bin/bash
|
||||
#DEB
|
||||
cd deb
|
||||
VERSION=$(grep 'Version:' pandora_gotty/DEBIAN/control | awk '{print $2}')
|
||||
mkdir -p pandora_gotty/usr/bin
|
||||
mkdir -p pandora_gotty/etc/pandora_gotty
|
||||
cp -a ../src/pandora_gotty pandora_gotty/usr/bin
|
||||
cp -a ../src/pandora_gotty.conf pandora_gotty/etc/pandora_gotty
|
||||
curl -SsL --output pandora_gotty/usr/bin/pandora_gotty_exec http://192.168.50.31/installers/installers/Linux/x86_64/pandora_gotty_exec
|
||||
chmod +x pandora_gotty/usr/bin/pandora_gotty_exec
|
||||
dpkg-deb --build pandora_gotty
|
||||
mv pandora_gotty.deb ../
|
||||
rm -rf pandora_gotty/usr/
|
||||
rm -rf pandora_gotty/etc/
|
||||
cd ..
|
||||
mv pandora_gotty.deb pandora_gotty_${VERSION}.deb
|
||||
chmod 777 pandora_gotty_${VERSION}.deb
|
|
@ -0,0 +1,15 @@
|
|||
#!/bin/bash
|
||||
#RPM
|
||||
VERSION=$(grep '%define version' pandora_gotty.spec | awk '{print $3}')
|
||||
mkdir -p pandora_gotty-${VERSION}
|
||||
cp src/pandora_gotty pandora_gotty-${VERSION}/
|
||||
cp src/pandora_gotty.conf pandora_gotty-${VERSION}/
|
||||
curl -SsL --output pandora_gotty-${VERSION}/pandora_gotty_exec http://192.168.50.31/installers/installers/Linux/x86_64/pandora_gotty_exec
|
||||
chmod +x pandora_gotty-${VERSION}/pandora_gotty_exec
|
||||
tar -cvzf pandora_gotty-${VERSION}.tar.gz pandora_gotty-${VERSION}/*
|
||||
mv pandora_gotty-${VERSION}.tar.gz ${HOME}/rpmbuild/SOURCES/
|
||||
rm -rf ${HOME}/rpmbuild/RPMS/x86_64/pandora_gotty*
|
||||
rpmbuild -ba pandora_gotty.spec
|
||||
rm -rf pandora_gotty-${VERSION}
|
||||
mv ${HOME}/rpmbuild/RPMS/x86_64/pandora_gotty* .
|
||||
chmod 777 *.rpm
|
|
@ -0,0 +1,3 @@
|
|||
*.deb
|
||||
**/usr
|
||||
**/etc
|
|
@ -0,0 +1,5 @@
|
|||
pandora_gotty (1.0-1) stable; urgency=low
|
||||
|
||||
* Initial release.
|
||||
|
||||
-- PandoraFMS Mon, 18 Sep 2023 00:00:00 +0000
|
|
@ -0,0 +1,9 @@
|
|||
Source: pandora_gotty
|
||||
Section: utils
|
||||
Version: 1.0.0
|
||||
Priority: optional
|
||||
Maintainer: PandoraFMS
|
||||
Build-Depends: debhelper (>= 12)
|
||||
Package: pandora-gotty
|
||||
Architecture: amd64
|
||||
Description: pandora_gotty for Pandora FMS.
|
|
@ -0,0 +1,41 @@
|
|||
%define name pandora_gotty
|
||||
%define version 1.0
|
||||
%define release 1%{?dist}
|
||||
Summary: pandora_gptty for Pandora FMS
|
||||
Name: %{name}
|
||||
Version: %{version}
|
||||
Release: %{release}
|
||||
License: GPL
|
||||
Vendor: PandoraFMS
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
URL: https://pandorafms.com
|
||||
Group: System/Monitoring
|
||||
Packager: PandoraFMS
|
||||
BuildArch: x86_64
|
||||
Provides: %{name}-%{version}
|
||||
|
||||
%description
|
||||
pandora_gotty for Pandora FMS.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
mkdir -p $RPM_BUILD_ROOT/%{_bindir}
|
||||
mkdir -p %{buildroot}/etc/pandora_gotty/
|
||||
cp %{name} $RPM_BUILD_ROOT/%{_bindir}
|
||||
cp pandora_gotty_exec $RPM_BUILD_ROOT/%{_bindir}
|
||||
cp pandora_gotty.conf %{buildroot}/etc/pandora_gotty/
|
||||
%clean
|
||||
rm -Rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
%config(noreplace) /etc/pandora_gotty/pandora_gotty.conf
|
||||
%{_bindir}/%{name}
|
||||
%{_bindir}/pandora_gotty_exec
|
||||
|
||||
%changelog
|
||||
* Mon Sep 18 2023 PandoraFMS - 1.0-1
|
||||
- Initial RPM release
|
|
@ -0,0 +1,2 @@
|
|||
*rpm
|
||||
bin/*
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3758eddb64db79c6ea1dac4cb200ee8ec86ef3f51723dad5be4365a1315b952b
|
||||
size 13642854
|
|
@ -0,0 +1,29 @@
|
|||
//Pandora Gotty config file
|
||||
|
||||
// [bool] Permit clients to write to the TTY
|
||||
permit_write = true
|
||||
|
||||
// [bool] Permit clients to send command line arguments in URL (e.g. http://example.com:8080/?arg=AAA&arg=BBB)
|
||||
permit_arguments = true
|
||||
|
||||
// [bool] Enable random URL generation
|
||||
enable_random_url = true
|
||||
|
||||
// [int] Default length of random strings appended to URL
|
||||
// To enable random URL generation, set `true` to `enable_random_url`
|
||||
random_url_length = 32
|
||||
|
||||
// [bool] Enable TLS/SSL
|
||||
// enable_tls = false
|
||||
|
||||
// [string] Default TLS certificate file path
|
||||
// tls_crt_file = "~/.gotty.crt"
|
||||
|
||||
// [string] Default TLS key file path
|
||||
// tls_key_file = "~/.gotty.key"
|
||||
|
||||
// [bool] Enable client certificate authentication
|
||||
// enable_tls_client_auth = false
|
||||
|
||||
// [string] Certificate file of CA for client certificates
|
||||
// tls_ca_crt_file = "~/.gotty.ca.crt"
|
|
@ -0,0 +1,110 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
__author__ = "PandoraFMS Team"
|
||||
__copyright__ = "Copyright 2023, PandoraFMS"
|
||||
#__credits__ = ["Rob Knight", "Peter Maxwell", "Gavin Huttley", "Matthew Wakefield"]
|
||||
__maintainer__ = "Projects/QA department"
|
||||
__status__ = "Prod"
|
||||
__version__ = "1.0"
|
||||
|
||||
import sys, argparse, signal, re, datetime, subprocess
|
||||
|
||||
info= f"""
|
||||
SSH and TELNET helper for pandora_gotty.
|
||||
Version: {__version__}
|
||||
"""
|
||||
|
||||
parser = argparse.ArgumentParser(description= info, formatter_class=argparse.RawTextHelpFormatter)
|
||||
parser.add_argument('exec_cmd',
|
||||
help='Aplication to be executed, avalibles: ssh or telnet',type=str, choices=['ssh', 'telnet'])
|
||||
parser.add_argument('address',
|
||||
help='IP addres or dns name to connect', type=str, default="")
|
||||
parser.add_argument('port',
|
||||
help='Port to connect', type=int, default=23)
|
||||
parser.add_argument('user',
|
||||
help='Username, only requiered for ssh connection', type=str, default="", nargs='?')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Define a function to handle the SIGINT signal
|
||||
def sigint_handler(signal, frame):
|
||||
print ('\nInterrupted by user', file=sys.stderr)
|
||||
sys.exit(0)
|
||||
signal.signal(signal.SIGINT, sigint_handler)
|
||||
|
||||
# Define a function to handle the SIGTERM signal
|
||||
def sigterm_handler(signum, frame):
|
||||
print("Received SIGTERM signal.", file=sys.stderr)
|
||||
sys.exit(0)
|
||||
signal.signal(signal.SIGTERM, sigterm_handler)
|
||||
|
||||
# Functions
|
||||
def is_valid_add(add:str):
|
||||
# Regular expression to match an IP address
|
||||
ip_pattern = r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'
|
||||
|
||||
# Regular expression to match a DNS name (domain name)
|
||||
dns_pattern = r'^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
|
||||
|
||||
if re.match(ip_pattern, add) or re.match(dns_pattern, add):
|
||||
return True
|
||||
else:
|
||||
print(f"Error not valid address: {add}", file=sys.stderr)
|
||||
return False
|
||||
|
||||
def is_valid_username(username:str):
|
||||
# Regular expression to match a valid Linux username
|
||||
username_pattern = r'^[a-zA-Z_][a-zA-Z0-9_]{0,31}$'
|
||||
if re.match(username_pattern, username) is not None:
|
||||
return True
|
||||
else:
|
||||
print(f"Error not valid username: {username}", file=sys.stderr)
|
||||
return False
|
||||
|
||||
def exec_ssh (user:str, add:str, port:int):
|
||||
# Previus checks
|
||||
if is_valid_username(user) == False:
|
||||
return False
|
||||
if is_valid_add(add) == False:
|
||||
return False
|
||||
if port == 0 :
|
||||
return False
|
||||
|
||||
try:
|
||||
print("> Starting SSH connection...")
|
||||
ssh_command = f"ssh {user}@{add} -p {port}"
|
||||
subprocess.run(ssh_command, shell=True)
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise SystemExit(e)
|
||||
return True
|
||||
|
||||
def exec_telnet (add:str, port:int):
|
||||
# Previus checks
|
||||
if is_valid_add(add) == False:
|
||||
return False
|
||||
|
||||
try:
|
||||
print("> Starting Telnet connection...")
|
||||
ssh_command = f"telnet -E {add} {port}"
|
||||
subprocess.run(ssh_command, shell=True)
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise SystemExit(e)
|
||||
return True
|
||||
|
||||
|
||||
# Main
|
||||
if __name__ == "__main__":
|
||||
if args.exec_cmd == "ssh":
|
||||
exec_ssh(args.user, args.address, args.port)
|
||||
print ("> ssh session finished")
|
||||
sys.exit(0)
|
||||
|
||||
if args.exec_cmd == "telnet":
|
||||
exec_telnet(args.address, args.port)
|
||||
print ("> telnet session finished")
|
||||
sys.exit(0)
|
||||
|
||||
sys.exit(0)
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
require_once 'include/config.php';
|
||||
require_once 'include/auth/mysql.php';
|
||||
require_once 'include/functions.php';
|
||||
require_once 'include/functions_db.php';
|
||||
|
||||
global $config;
|
||||
|
||||
if ((bool) $config['enterprise_installed'] === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Load classes.
|
||||
require_once 'include/class/DiscoveryConsoleTask.php';
|
||||
require_once 'include/class/ConsoleSupervisor.php';
|
||||
|
||||
db_process_sql_update(
|
||||
'tconfig',
|
||||
['value' => get_system_time()],
|
||||
['token' => 'cron_last_run']
|
||||
);
|
||||
|
||||
$tasks = new DiscoveryConsoleTask();
|
||||
|
||||
$tasks->run();
|
||||
|
||||
if (is_reporting_console_node() === true) {
|
||||
$supervisor = new ConsoleSupervisor();
|
||||
$supervisor->run();
|
||||
}
|
|
@ -31,6 +31,7 @@ global $config;
|
|||
|
||||
require_once $config['homedir'].'/include/functions_agents.php';
|
||||
require_once $config['homedir'].'/godmode/wizards/Wizard.main.php';
|
||||
require_once $config['homedir'].'/include/functions_cron_task.php';
|
||||
|
||||
|
||||
/**
|
||||
|
@ -78,91 +79,78 @@ function quickShell()
|
|||
return;
|
||||
}
|
||||
|
||||
$form_sent = get_parameter('form-sent', false);
|
||||
$method = get_parameter('method', null);
|
||||
|
||||
$setup_anchor = html_print_anchor(
|
||||
[
|
||||
'href' => 'index.php?sec=gsetup&sec2=godmode/setup/setup§ion=quickshell',
|
||||
'content' => __('GoTTY setup'),
|
||||
],
|
||||
true
|
||||
);
|
||||
|
||||
if ((bool) $config['gotty_ssh_enabled'] === false
|
||||
&& (bool) $config['gotty_telnet_enabled'] === false
|
||||
) {
|
||||
ui_print_warning_message(__('Please, enable GoTTY in %s', $setup_anchor));
|
||||
return;
|
||||
}
|
||||
|
||||
$agent_id = get_parameter('id_agente', 0);
|
||||
$username = get_parameter('username', null);
|
||||
$method = get_parameter('method', null);
|
||||
$method_port = get_parameter('port', null);
|
||||
|
||||
// Retrieve main IP Address.
|
||||
$address = agents_get_address($agent_id);
|
||||
$agent_address = agents_get_address($agent_id);
|
||||
|
||||
ui_require_css_file('wizard');
|
||||
ui_require_css_file('discovery');
|
||||
|
||||
// Settings.
|
||||
// WebSocket host, where client should connect.
|
||||
if (isset($config['ws_port']) === false) {
|
||||
config_update_value('ws_port', 8080);
|
||||
// Build URL args.
|
||||
if ($method === 'ssh') {
|
||||
// SSH.
|
||||
$args .= '&arg='.$agent_address.'&arg='.$method_port.'&arg='.$username;
|
||||
} else if ($method == 'telnet') {
|
||||
// Telnet.
|
||||
$args .= '&arg='.$agent_address.'&arg='.$method_port;
|
||||
}
|
||||
|
||||
if (empty($config['ws_proxy_url']) === true) {
|
||||
$ws_url = 'http://'.$_SERVER['SERVER_ADDR'].':'.$config['ws_port'];
|
||||
} else {
|
||||
preg_match('/\/\/(.*)/', $config['ws_proxy_url'], $matches);
|
||||
if (isset($_SERVER['HTTPS']) === true) {
|
||||
$ws_url = 'https://'.$matches[1];
|
||||
} else {
|
||||
$ws_url = 'http://'.$matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
// Gotty settings. Internal communication (WS).
|
||||
if (isset($config['gotty_host']) === false) {
|
||||
config_update_value('gotty_host', '127.0.0.1');
|
||||
}
|
||||
|
||||
if (isset($config['gotty_telnet_port']) === false) {
|
||||
config_update_value('gotty_telnet_port', 8082);
|
||||
}
|
||||
|
||||
if (isset($config['gotty_ssh_port']) === false) {
|
||||
config_update_value('gotty_ssh_port', 8081);
|
||||
}
|
||||
|
||||
// Context to allow self-signed certs.
|
||||
$context = stream_context_create(
|
||||
[
|
||||
'http' => [ 'method' => 'GET'],
|
||||
'ssl' => [
|
||||
'verify_peer' => false,
|
||||
'verify_peer_name' => false,
|
||||
],
|
||||
]
|
||||
);
|
||||
$connectionURL = buildConnectionURL($method);
|
||||
$gotty_addr = $connectionURL.$args;
|
||||
|
||||
// Username. Retrieve from form.
|
||||
if (empty($username) === true) {
|
||||
if ($form_sent === false) {
|
||||
// No username provided, ask for it.
|
||||
$wiz = new Wizard();
|
||||
|
||||
$test = curl($ws_url, []);
|
||||
if ($test === false) {
|
||||
ui_print_error_message(__('WebService engine has not been started, please check documentation.'));
|
||||
$wiz->printForm(
|
||||
[
|
||||
'form' => [
|
||||
'method' => 'POST',
|
||||
'action' => '#',
|
||||
'id' => 'retry_form',
|
||||
],
|
||||
]
|
||||
);
|
||||
$method_fields = [];
|
||||
|
||||
html_print_action_buttons(
|
||||
html_print_submit_button(
|
||||
__('Retry'),
|
||||
'submit',
|
||||
false,
|
||||
[
|
||||
'icon' => 'next',
|
||||
'form' => 'retry_form',
|
||||
],
|
||||
true
|
||||
)
|
||||
);
|
||||
return;
|
||||
if ($config['gotty_telnet_enabled']) {
|
||||
$method_fields['telnet'] = __('Telnet');
|
||||
$port_value = 23;
|
||||
}
|
||||
|
||||
if ($config['gotty_ssh_enabled']) {
|
||||
$method_fields['ssh'] = __('SSH');
|
||||
$port_value = 22;
|
||||
}
|
||||
|
||||
$method_script = "
|
||||
var wizard = document.querySelector('.wizard');
|
||||
p=22;
|
||||
wizard.querySelector('ul > li').classList.remove('invisible_important');
|
||||
wizard.querySelector('ul > li').classList.add('visible');
|
||||
if(this.value == 'telnet') {
|
||||
p=23;
|
||||
wizard.querySelector('ul > li').classList.remove('visible');
|
||||
wizard.querySelector('ul > li').classList.add('invisible_important');
|
||||
$('#text-username').prop('required', false);
|
||||
} else {
|
||||
$('#text-username').prop('required', true);
|
||||
}
|
||||
$('#text-port').val(p);";
|
||||
|
||||
$wiz->printForm(
|
||||
[
|
||||
'form' => [
|
||||
|
@ -175,8 +163,9 @@ function quickShell()
|
|||
[
|
||||
'label' => __('Username'),
|
||||
'arguments' => [
|
||||
'type' => 'text',
|
||||
'name' => 'username',
|
||||
'type' => 'text',
|
||||
'name' => 'username',
|
||||
'required' => true,
|
||||
],
|
||||
],
|
||||
[
|
||||
|
@ -185,7 +174,7 @@ function quickShell()
|
|||
'type' => 'text',
|
||||
'id' => 'port',
|
||||
'name' => 'port',
|
||||
'value' => 22,
|
||||
'value' => $port_value,
|
||||
],
|
||||
],
|
||||
[
|
||||
|
@ -193,13 +182,17 @@ function quickShell()
|
|||
'arguments' => [
|
||||
'type' => 'select',
|
||||
'name' => 'method',
|
||||
'fields' => [
|
||||
'ssh' => __('SSH'),
|
||||
'telnet' => __('Telnet'),
|
||||
],
|
||||
'script' => "p=22; if(this.value == 'telnet') { p=23; } $('#text-port').val(p);",
|
||||
'fields' => $method_fields,
|
||||
'script' => $method_script,
|
||||
],
|
||||
],
|
||||
[
|
||||
'arguments' => [
|
||||
'type' => 'hidden',
|
||||
'name' => 'form-sent',
|
||||
'value' => true,
|
||||
],
|
||||
]
|
||||
],
|
||||
],
|
||||
false,
|
||||
|
@ -221,119 +214,71 @@ function quickShell()
|
|||
return;
|
||||
}
|
||||
|
||||
// Initialize Gotty Client.
|
||||
$host = $config['gotty_host'];
|
||||
if ($method == 'ssh') {
|
||||
// SSH.
|
||||
$port = $config['gotty_ssh_port'];
|
||||
$command_arguments = "var args = '?arg=".$username.'@'.$address;
|
||||
$command_arguments .= '&arg=-p '.$method_port."';";
|
||||
} else if ($method == 'telnet') {
|
||||
// Telnet.
|
||||
$port = $config['gotty_telnet_port'];
|
||||
$username = preg_replace('/[^a-zA-Z0-9\-\.]/', '', $username);
|
||||
$command_arguments = "var args = '?arg=-l ".$username;
|
||||
$command_arguments .= '&arg='.$address;
|
||||
$command_arguments .= '&arg='.$method_port."&arg=-E';";
|
||||
} else {
|
||||
ui_print_error_message(__('Please use SSH or Telnet.'));
|
||||
return;
|
||||
// Check gotty connection before trying to load iframe.
|
||||
$ch = curl_init($gotty_addr);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
// Maximum time for the entire request.
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 3);
|
||||
// Maximum time to establish a connection.
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$finalUrl = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
|
||||
|
||||
curl_close($ch);
|
||||
|
||||
if ($responseCode !== 200) {
|
||||
ui_print_error_message(__('Connection error. Please check your settings at %s', $setup_anchor));
|
||||
exit;
|
||||
}
|
||||
|
||||
// If rediretion is enabled, we will try to connect using
|
||||
// http:// or https:// endpoint.
|
||||
$test = get_headers($ws_url, false, $context);
|
||||
if ($test === false) {
|
||||
if (empty($wiz) === true) {
|
||||
$wiz = new Wizard();
|
||||
}
|
||||
|
||||
ui_print_error_message(__('WebService engine has not been started, please check documentation.'));
|
||||
echo $wiz->printGoBackButton('#');
|
||||
return;
|
||||
}
|
||||
|
||||
// Check credentials.
|
||||
$auth_str = '';
|
||||
$gotty_url = $host.':'.$port;
|
||||
if (empty($config['gotty_user']) === false
|
||||
&& empty($config['gotty_pass']) === false
|
||||
) {
|
||||
$auth_str = io_safe_output($config['gotty_user']);
|
||||
$auth_str .= ':'.io_output_password($config['gotty_pass']);
|
||||
$gotty_url = $auth_str.'@'.$host.':'.$port;
|
||||
}
|
||||
|
||||
$r = file_get_contents('http://'.$gotty_url.'/js/hterm.js');
|
||||
if (empty($r) === true) {
|
||||
if (empty($wiz) === true) {
|
||||
$wiz = new Wizard();
|
||||
}
|
||||
|
||||
ui_print_error_message(__('WebService engine is not working properly, please check documentation.'));
|
||||
echo $wiz->printGoBackButton('#');
|
||||
return;
|
||||
}
|
||||
|
||||
// Override gotty client settings.
|
||||
if (empty($auth_str) === true) {
|
||||
$r .= "var gotty_auth_token = '';";
|
||||
} else {
|
||||
$r .= "var gotty_auth_token = '";
|
||||
$r .= $auth_str."';";
|
||||
}
|
||||
|
||||
// Set websocket target and method.
|
||||
$gotty = file_get_contents('http://'.$gotty_url.'/js/gotty.js');
|
||||
$url = "var url = (httpsEnabled ? 'wss://' : 'ws://') + window.location.host + window.location.pathname + 'ws';";
|
||||
if (empty($config['ws_proxy_url']) === true) {
|
||||
$new = "var url = (httpsEnabled ? 'wss://' : 'ws://')";
|
||||
$new .= " + window.location.host + ':";
|
||||
$new .= $config['ws_port'].'/'.$method."';";
|
||||
} else {
|
||||
$new = "var url = '";
|
||||
$new .= $config['ws_proxy_url'].'/'.$method."';";
|
||||
}
|
||||
|
||||
// Update firefox issue.
|
||||
$original = ' this.iframe_.src = \'#\';';
|
||||
$trick = 'this.iframe_.src = \'javascript:\';';
|
||||
|
||||
$r = str_replace($original, $trick, $r);
|
||||
|
||||
// Update url.
|
||||
$gotty = str_replace($url, $new, $gotty);
|
||||
|
||||
// Update websocket arguments.
|
||||
$args = 'var args = window.location.search;';
|
||||
$new = $command_arguments;
|
||||
|
||||
// Update arguments.
|
||||
$gotty = str_replace($args, $new, $gotty);
|
||||
|
||||
?>
|
||||
<style>#terminal {
|
||||
height: 650px;
|
||||
width: 100%;
|
||||
margin: 0px;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: calc(100vh - 205px);
|
||||
}
|
||||
#terminal > iframe {
|
||||
width:100%;
|
||||
height:100%;
|
||||
position: relative!important;
|
||||
flex-grow: 1;
|
||||
border: 0px;
|
||||
}
|
||||
</style>
|
||||
<div id="terminal"></div>
|
||||
<script type="text/javascript">
|
||||
<?php echo $r; ?>
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
<?php echo $gotty; ?>
|
||||
</script>
|
||||
|
||||
<div id="terminal"><iframe id="gotty-iframe" src="<?php echo $gotty_addr; ?>"></iframe></div>
|
||||
|
||||
<?php
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Build Connection URL based on provided connection method.
|
||||
*
|
||||
* @param string $method Connection method (SSH/Telnet).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function buildConnectionURL($method)
|
||||
{
|
||||
global $config;
|
||||
|
||||
$address = (empty($config['gotty_addr']) === true) ? $_SERVER['SERVER_ADDR'] : $config['gotty_addr'];
|
||||
$use_ssl = ($method === 'ssh') ? $config['gotty_ssh_use_ssl'] : $config['gotty_telnet_use_ssl'];
|
||||
$protocol = ((bool) $use_ssl === true) ? 'https://' : 'http://';
|
||||
|
||||
return $protocol.$address.':'.$config['gotty_port'].'/'.$config['gotty_connection_hash'].'/?arg='.$method;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Provide an interface where configure all settings.
|
||||
*
|
||||
|
@ -347,116 +292,108 @@ function quickShellSettings()
|
|||
ui_require_css_file('discovery');
|
||||
|
||||
// Gotty settings. Internal communication (WS).
|
||||
|
||||
if (isset($config['gotty_ssh_enabled']) === false) {
|
||||
config_update_value('gotty_ssh_enabled', 1);
|
||||
}
|
||||
|
||||
if (isset($config['gotty_telnet_enabled']) === false) {
|
||||
config_update_value('gotty_telnet_enabled', 0);
|
||||
}
|
||||
|
||||
if (isset($config['gotty_host']) === false) {
|
||||
config_update_value('gotty_host', '127.0.0.1');
|
||||
}
|
||||
|
||||
if (isset($config['gotty_telnet_port']) === false) {
|
||||
config_update_value('gotty_telnet_port', 8082);
|
||||
if (isset($config['gotty_port']) === false) {
|
||||
config_update_value('gotty_port', 8080);
|
||||
}
|
||||
|
||||
if (isset($config['gotty_ssh_port']) === false) {
|
||||
config_update_value('gotty_ssh_port', 8081);
|
||||
}
|
||||
$changes = 0;
|
||||
$critical = 0;
|
||||
|
||||
// Parser.
|
||||
if (get_parameter('update_config', false) !== false) {
|
||||
// Gotty settings. Internal communication (WS).
|
||||
$gotty = get_parameter(
|
||||
'gotty',
|
||||
''
|
||||
$gotty_ssh_enabled = get_parameter(
|
||||
'gotty_ssh_enabled',
|
||||
0
|
||||
);
|
||||
$gotty_host = get_parameter(
|
||||
'gotty_host',
|
||||
''
|
||||
|
||||
$gotty_telnet_enabled = get_parameter(
|
||||
'gotty_telnet_enabled',
|
||||
0
|
||||
);
|
||||
$gotty_ssh_port = get_parameter(
|
||||
'gotty_ssh_port',
|
||||
''
|
||||
);
|
||||
$gotty_telnet_port = get_parameter(
|
||||
'gotty_telnet_port',
|
||||
|
||||
$gotty_addr = get_parameter(
|
||||
'gotty_addr',
|
||||
''
|
||||
);
|
||||
|
||||
$gotty_user = get_parameter(
|
||||
'gotty_user',
|
||||
$gotty_port = get_parameter(
|
||||
'gotty_port',
|
||||
''
|
||||
);
|
||||
|
||||
$gotty_pass = get_parameter(
|
||||
'gotty_pass',
|
||||
''
|
||||
$gotty_ssh_use_ssl = get_parameter(
|
||||
'gotty_ssh_use_ssl',
|
||||
false
|
||||
);
|
||||
|
||||
$gotty_pass = io_input_password($gotty_pass);
|
||||
$gotty_telnet_use_ssl = get_parameter(
|
||||
'gotty_telnet_use_ssl',
|
||||
false
|
||||
);
|
||||
|
||||
$changes = 0;
|
||||
$critical = 0;
|
||||
if ($config['gotty'] != $gotty) {
|
||||
config_update_value('gotty', $gotty);
|
||||
$changes++;
|
||||
$critical++;
|
||||
if ($config['gotty_ssh_enabled'] != $gotty_ssh_enabled) {
|
||||
config_update_value('gotty_ssh_enabled', $gotty_ssh_enabled);
|
||||
}
|
||||
|
||||
if ($config['gotty_host'] != $gotty_host) {
|
||||
config_update_value('gotty_host', $gotty_host);
|
||||
$changes++;
|
||||
if ($config['gotty_telnet_enabled'] != $gotty_telnet_enabled) {
|
||||
config_update_value('gotty_telnet_enabled', $gotty_telnet_enabled);
|
||||
}
|
||||
|
||||
if ($config['gotty_telnet_port'] != $gotty_telnet_port) {
|
||||
config_update_value('gotty_telnet_port', $gotty_telnet_port);
|
||||
$changes++;
|
||||
if ($config['gotty_addr'] != $gotty_addr) {
|
||||
config_update_value('gotty_addr', $gotty_addr);
|
||||
}
|
||||
|
||||
if ($config['gotty_ssh_port'] != $gotty_ssh_port) {
|
||||
config_update_value('gotty_ssh_port', $gotty_ssh_port);
|
||||
$changes++;
|
||||
if ($config['gotty_port'] != $gotty_port) {
|
||||
// Mark gotty for restart (should kill the process in the current port).
|
||||
if ($config['restart_gotty_next_cron_port'] === ''
|
||||
|| $config['restart_gotty_next_cron_port'] === null
|
||||
) {
|
||||
config_update_value('restart_gotty_next_cron_port', $config['gotty_port']);
|
||||
}
|
||||
|
||||
config_update_value('gotty_port', $gotty_port);
|
||||
}
|
||||
|
||||
if ($config['gotty_user'] != $gotty_user) {
|
||||
config_update_value('gotty_user', $gotty_user);
|
||||
$changes++;
|
||||
$critical++;
|
||||
if ($config['gotty_ssh_use_ssl'] != $gotty_ssh_use_ssl) {
|
||||
config_update_value('gotty_ssh_use_ssl', $gotty_ssh_use_ssl);
|
||||
}
|
||||
|
||||
if ($config['gotty_pass'] != $gotty_pass) {
|
||||
$gotty_pass = io_input_password($gotty_pass);
|
||||
config_update_value('gotty_pass', $gotty_pass);
|
||||
$changes++;
|
||||
$critical++;
|
||||
if ($config['gotty_telnet_use_ssl'] != $gotty_telnet_use_ssl) {
|
||||
config_update_value('gotty_telnet_use_ssl', $gotty_telnet_use_ssl);
|
||||
}
|
||||
|
||||
cron_task_start_gotty();
|
||||
}
|
||||
|
||||
if ($changes > 0) {
|
||||
$msg = __('%d Updated', $changes);
|
||||
if ($critical > 0) {
|
||||
$msg = __(
|
||||
'%d Updated, please restart WebSocket engine service',
|
||||
$changes
|
||||
);
|
||||
}
|
||||
|
||||
ui_print_success_message($msg);
|
||||
}
|
||||
|
||||
// Form. Using old style.
|
||||
echo '<fieldset class="margin-bottom-10">';
|
||||
echo '<legend>'.__('Quickshell').'</legend>';
|
||||
echo '<legend>'.__('GoTTY general parameters').'</legend>';
|
||||
|
||||
$t = new StdClass();
|
||||
$t->data = [];
|
||||
$t->width = '100%';
|
||||
$t->class = 'filter-table-adv';
|
||||
$t->data = [];
|
||||
$t->style = [];
|
||||
$t->style[0] = 'width: 50%;';
|
||||
$general_table = new StdClass();
|
||||
$general_table->data = [];
|
||||
$general_table->width = '100%';
|
||||
$general_table->class = 'filter-table-adv';
|
||||
$general_table->data = [];
|
||||
$general_table->style = [];
|
||||
$general_table->style[0] = 'width: 50%;';
|
||||
|
||||
$t->data[0][] = html_print_label_input_block(
|
||||
__('Gotty path'),
|
||||
$general_table->data[0][] = html_print_label_input_block(
|
||||
__('Address'),
|
||||
html_print_input_text(
|
||||
'gotty',
|
||||
$config['gotty'],
|
||||
'gotty_addr',
|
||||
$config['gotty_addr'],
|
||||
'',
|
||||
30,
|
||||
100,
|
||||
|
@ -464,11 +401,11 @@ function quickShellSettings()
|
|||
)
|
||||
);
|
||||
|
||||
$t->data[0][] = html_print_label_input_block(
|
||||
__('Gotty host'),
|
||||
$general_table->data[0][] = html_print_label_input_block(
|
||||
__('Port'),
|
||||
html_print_input_text(
|
||||
'gotty_host',
|
||||
$config['gotty_host'],
|
||||
'gotty_port',
|
||||
$config['gotty_port'],
|
||||
'',
|
||||
30,
|
||||
100,
|
||||
|
@ -476,79 +413,154 @@ function quickShellSettings()
|
|||
)
|
||||
);
|
||||
|
||||
$t->data[1][] = html_print_label_input_block(
|
||||
__('Gotty ssh port'),
|
||||
html_print_input_text(
|
||||
'gotty_ssh_port',
|
||||
$config['gotty_ssh_port'],
|
||||
'',
|
||||
30,
|
||||
100,
|
||||
html_print_table($general_table);
|
||||
echo '</fieldset>';
|
||||
|
||||
echo '<fieldset class="margin-bottom-10">';
|
||||
echo '<legend>'.__('GoTTY SSH connection parameters').'</legend>';
|
||||
|
||||
$ssh_table = new StdClass();
|
||||
$ssh_table->data = [];
|
||||
$ssh_table->width = '100%';
|
||||
$ssh_table->class = 'filter-table-adv';
|
||||
$ssh_table->data = [];
|
||||
$ssh_table->style = [];
|
||||
$ssh_table->style[0] = 'width: 50%;';
|
||||
|
||||
$ssh_table->data[0][] = html_print_label_input_block(
|
||||
__('Enable SSH method'),
|
||||
html_print_checkbox_switch(
|
||||
'gotty_ssh_enabled',
|
||||
1,
|
||||
$config['gotty_ssh_enabled'],
|
||||
true
|
||||
)
|
||||
);
|
||||
|
||||
$t->data[1][] = html_print_label_input_block(
|
||||
__('Gotty telnet port'),
|
||||
html_print_input_text(
|
||||
'gotty_telnet_port',
|
||||
$config['gotty_telnet_port'],
|
||||
'',
|
||||
30,
|
||||
100,
|
||||
true
|
||||
$ssh_table->data[1][] = html_print_label_input_block(
|
||||
__('Use SSL'),
|
||||
html_print_checkbox_switch(
|
||||
'gotty_ssh_use_ssl',
|
||||
1,
|
||||
$config['gotty_ssh_use_ssl'],
|
||||
true,
|
||||
$disable_agentaccess
|
||||
)
|
||||
);
|
||||
|
||||
$hidden = new stdClass();
|
||||
$hidden->data = [];
|
||||
$hidden->width = '100%';
|
||||
$hidden->class = 'filter-table-adv';
|
||||
$hidden->data = [];
|
||||
$hidden->style[0] = 'width: 50%;';
|
||||
// Test.
|
||||
$row = [];
|
||||
$test_start = '<span id="test-gotty-spinner-ssh" class="invisible"> '.html_print_image('images/spinner.gif', true).'</span>';
|
||||
$test_start .= ' <span id="test-gotty-message-ssh" class="invisible"></span>';
|
||||
|
||||
$hidden->data[0][] = html_print_label_input_block(
|
||||
__('Gotty user'),
|
||||
html_print_input_text(
|
||||
'gotty_user',
|
||||
$config['gotty_user'],
|
||||
'',
|
||||
30,
|
||||
100,
|
||||
true
|
||||
)
|
||||
);
|
||||
|
||||
$hidden->data[0][] = html_print_label_input_block(
|
||||
__('Gotty password'),
|
||||
html_print_input_password(
|
||||
'gotty_pass',
|
||||
io_output_password($config['gotty_pass']),
|
||||
'',
|
||||
30,
|
||||
100,
|
||||
true
|
||||
)
|
||||
);
|
||||
|
||||
html_print_table($t);
|
||||
|
||||
ui_print_toggle(
|
||||
$ssh_table->data[3][] = html_print_button(
|
||||
__('Test'),
|
||||
'test-gotty-ssh',
|
||||
false,
|
||||
'handleTestSSH()',
|
||||
[
|
||||
'content' => html_print_table($hidden, true),
|
||||
'name' => __('Advanced options'),
|
||||
'clean' => false,
|
||||
'main_class' => 'no-border-imp',
|
||||
'container_class' => 'no-border-imp',
|
||||
]
|
||||
);
|
||||
'icon' => 'cog',
|
||||
'mode' => 'secondary',
|
||||
'style' => 'width: 115px;',
|
||||
],
|
||||
true
|
||||
).$test_start;
|
||||
|
||||
html_print_table($ssh_table);
|
||||
|
||||
echo '</fieldset>';
|
||||
|
||||
echo '<fieldset class="margin-bottom-10">';
|
||||
echo '<legend>'.__('GoTTY telnet connection parameters').'</legend>';
|
||||
|
||||
$telnet_table = new StdClass();
|
||||
$telnet_table->data = [];
|
||||
$telnet_table->width = '100%';
|
||||
$telnet_table->class = 'filter-table-adv';
|
||||
$telnet_table->data = [];
|
||||
$telnet_table->style = [];
|
||||
$telnet_table->style[0] = 'width: 50%;';
|
||||
|
||||
$telnet_table->data[0][] = html_print_label_input_block(
|
||||
__('Enable telnet method'),
|
||||
html_print_checkbox_switch(
|
||||
'gotty_telnet_enabled',
|
||||
1,
|
||||
$config['gotty_telnet_enabled'],
|
||||
true
|
||||
)
|
||||
);
|
||||
|
||||
$telnet_table->data[1][] = html_print_label_input_block(
|
||||
__('Use SSL'),
|
||||
html_print_checkbox_switch(
|
||||
'gotty_telnet_use_ssl',
|
||||
1,
|
||||
$config['gotty_telnet_use_ssl'],
|
||||
true
|
||||
)
|
||||
);
|
||||
|
||||
// Test.
|
||||
$row = [];
|
||||
$test_start = '<span id="test-gotty-spinner-telnet" class="invisible"> '.html_print_image('images/spinner.gif', true).'</span>';
|
||||
$test_start .= ' <span id="test-gotty-message-telnet" class="invisible"></span>';
|
||||
|
||||
$telnet_table->data[3][] = html_print_button(
|
||||
__('Test'),
|
||||
'test-gotty-telnet',
|
||||
false,
|
||||
'handleTestTelnet()',
|
||||
[
|
||||
'icon' => 'cog',
|
||||
'mode' => 'secondary',
|
||||
'style' => 'width: 115px;',
|
||||
],
|
||||
true
|
||||
).$test_start;
|
||||
|
||||
html_print_table($telnet_table);
|
||||
html_print_input_hidden('update_config', 1);
|
||||
|
||||
echo '</fieldset>';
|
||||
}
|
||||
|
||||
|
||||
// This extension is usefull only if the agent has associated IP.
|
||||
if (is_ajax() === true) {
|
||||
$method = (string) get_parameter('method', '');
|
||||
|
||||
if (empty($method) === false) {
|
||||
$address = buildConnectionURL($method);
|
||||
|
||||
$ch = curl_init($address);
|
||||
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
|
||||
// Maximum time for the entire request.
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 2);
|
||||
|
||||
// Maximum time to establish a connection.
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1);
|
||||
|
||||
curl_exec($ch);
|
||||
$response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
if ($response_code === 200) {
|
||||
$result = ['status' => 'success'];
|
||||
} else {
|
||||
$result = ['status' => 'error'];
|
||||
}
|
||||
|
||||
echo json_encode($result);
|
||||
return;
|
||||
}
|
||||
|
||||
$result = ['status' => 'error'];
|
||||
return;
|
||||
}
|
||||
|
||||
// This extension is useful only if the agent has associated IP.
|
||||
$agent_id = get_parameter('id_agente');
|
||||
if (empty($agent_id) === false
|
||||
&& get_parameter('sec2', '') == 'operation/agentes/ver_agente'
|
||||
|
@ -573,4 +585,136 @@ if (empty($agent_id) === false
|
|||
}
|
||||
}
|
||||
|
||||
echo '<script>';
|
||||
|
||||
echo 'var server_addr = "'.$_SERVER['SERVER_ADDR'].'";';
|
||||
echo "function checkAddressReachability(method, callback) {
|
||||
$.ajax({
|
||||
url: 'ajax.php',
|
||||
data: {
|
||||
page: 'extensions/quick_shell',
|
||||
method
|
||||
},
|
||||
type: 'GET',
|
||||
async: false,
|
||||
dataType: 'json',
|
||||
success: function (data) {
|
||||
if (data.status === 'success') {
|
||||
callback(true);
|
||||
} else {
|
||||
callback(false);
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
callback(false);
|
||||
}
|
||||
});
|
||||
}";
|
||||
|
||||
$handle_test_telnet = "var handleTestTelnet = function (event) {
|
||||
var gotty_addr = $('input#text-gotty_addr').val();
|
||||
var gotty_port = $('input#text-gotty_port').val();
|
||||
var gotty_telnet_use_ssl = $('input#checkbox-gotty_telnet_use_ssl').is(':checked');
|
||||
|
||||
if (gotty_addr === '') {
|
||||
url = (gotty_telnet_use_ssl ? 'https://' : 'http://') + server_addr + ':' + gotty_port;
|
||||
} else {
|
||||
url = (gotty_telnet_use_ssl ? 'https://' : 'http://') + gotty_addr + ':' + gotty_port;
|
||||
}
|
||||
|
||||
var showLoadingImage = function () {
|
||||
$('#button-test-gotty-telnet').children('div').attr('class', 'subIcon cog rotation secondary mini');
|
||||
}
|
||||
|
||||
var showSuccessImage = function () {
|
||||
$('#button-test-gotty-telnet').children('div').attr('class', 'subIcon tick secondary mini');
|
||||
}
|
||||
|
||||
var showFailureImage = function () {
|
||||
$('#button-test-gotty-telnet').children('div').attr('class', 'subIcon fail secondary mini');
|
||||
}
|
||||
|
||||
var hideMessage = function () {
|
||||
$('span#test-gotty-message-telnet').hide();
|
||||
}
|
||||
var showMessage = function () {
|
||||
$('span#test-gotty-message-telnet').show();
|
||||
}
|
||||
var changeTestMessage = function (message) {
|
||||
$('span#test-gotty-message-telnet').text(message);
|
||||
}
|
||||
|
||||
var errorMessage = '".__('Unable to connect.')."';
|
||||
|
||||
hideMessage();
|
||||
showLoadingImage();
|
||||
|
||||
checkAddressReachability('telnet', function(isReachable) {
|
||||
if (isReachable) {
|
||||
showSuccessImage();
|
||||
hideMessage();
|
||||
} else {
|
||||
showFailureImage();
|
||||
changeTestMessage(errorMessage);
|
||||
showMessage();
|
||||
}
|
||||
});
|
||||
|
||||
};";
|
||||
|
||||
$handle_test_ssh = "var handleTestSSH = function (event) {
|
||||
var gotty_addr = $('input#text-gotty_addr').val();
|
||||
var gotty_port = $('input#text-gotty_port').val();
|
||||
var gotty_ssh_use_ssl = $('input#checkbox-gotty_ssh_use_ssl').is(':checked');
|
||||
|
||||
if (gotty_addr === '') {
|
||||
url = (gotty_ssh_use_ssl ? 'https://' : 'http://') + server_addr + ':' + gotty_port;
|
||||
} else {
|
||||
url = (gotty_ssh_use_ssl ? 'https://' : 'http://') + gotty_addr + ':' + gotty_port;
|
||||
}
|
||||
|
||||
var showLoadingImage = function () {
|
||||
$('#button-test-gotty-ssh').children('div').attr('class', 'subIcon cog rotation secondary mini');
|
||||
}
|
||||
|
||||
var showSuccessImage = function () {
|
||||
$('#button-test-gotty-ssh').children('div').attr('class', 'subIcon tick secondary mini');
|
||||
}
|
||||
|
||||
var showFailureImage = function () {
|
||||
$('#button-test-gotty-ssh').children('div').attr('class', 'subIcon fail secondary mini');
|
||||
}
|
||||
|
||||
var hideMessage = function () {
|
||||
$('span#test-gotty-message-ssh').hide();
|
||||
}
|
||||
var showMessage = function () {
|
||||
$('span#test-gotty-message-ssh').show();
|
||||
}
|
||||
var changeTestMessage = function (message) {
|
||||
$('span#test-gotty-message-ssh').text(message);
|
||||
}
|
||||
|
||||
var errorMessage = '".__('Unable to connect.')."';
|
||||
|
||||
|
||||
hideMessage();
|
||||
showLoadingImage();
|
||||
|
||||
checkAddressReachability('ssh', function(isReachable) {
|
||||
if (isReachable) {
|
||||
showSuccessImage();
|
||||
hideMessage();
|
||||
} else {
|
||||
showFailureImage();
|
||||
changeTestMessage(errorMessage);
|
||||
showMessage();
|
||||
}
|
||||
});
|
||||
};";
|
||||
|
||||
echo $handle_test_ssh;
|
||||
echo $handle_test_telnet;
|
||||
echo '</script>';
|
||||
|
||||
extensions_add_godmode_function('quickShellSettings');
|
||||
|
|
|
@ -1708,6 +1708,7 @@ enterprise/godmode/wizards/Cloud.class.php
|
|||
enterprise/images/wizard/applications.png
|
||||
enterprise/images/wizard/cloud.png
|
||||
enterprise/images/wizard/consoletasks.png
|
||||
pandora_websocket_engine
|
||||
operation/incidents/configure_integriaims_incident.php
|
||||
operation/incidents/dashboard_detail_integriaims_incident.php
|
||||
operation/incidents/incident_statistics.php
|
||||
|
|
|
@ -486,8 +486,8 @@ if ($access_console_node === true) {
|
|||
$sub2['godmode/setup/setup§ion=notifications']['text'] = __('Notifications');
|
||||
$sub2['godmode/setup/setup§ion=notifications']['refr'] = 0;
|
||||
|
||||
$sub2['godmode/setup/setup§ion=websocket_engine']['text'] = __('Websocket Engine');
|
||||
$sub2['godmode/setup/setup§ion=websocket_engine']['refr'] = 0;
|
||||
$sub2['godmode/setup/setup§ion=quickshell']['text'] = __('QuickShell');
|
||||
$sub2['godmode/setup/setup§ion=quickshell']['refr'] = 0;
|
||||
|
||||
$sub2['godmode/setup/setup§ion=external_tools']['text'] = __('External Tools');
|
||||
$sub2['godmode/setup/setup§ion=external_tools']['refr'] = 0;
|
||||
|
|
|
@ -221,13 +221,13 @@ $buttons['notifications'] = [
|
|||
).'</a>',
|
||||
];
|
||||
|
||||
$buttons['websocket_engine'] = [
|
||||
$buttons['quickshell'] = [
|
||||
'active' => false,
|
||||
'text' => '<a href="'.ui_get_full_url('index.php?sec=gsetup&sec2=godmode/setup/setup§ion=websocket_engine').'">'.html_print_image(
|
||||
'text' => '<a href="'.ui_get_full_url('index.php?sec=gsetup&sec2=godmode/setup/setup§ion=quickshell').'">'.html_print_image(
|
||||
'images/websocket_small.png',
|
||||
true,
|
||||
[
|
||||
'title' => __('Websocket engine'),
|
||||
'title' => __('QuickShell'),
|
||||
'class' => 'invert_filter',
|
||||
]
|
||||
).'</a>',
|
||||
|
@ -325,9 +325,9 @@ switch ($section) {
|
|||
$subpage = __('Notifications');
|
||||
break;
|
||||
|
||||
case 'websocket_engine':
|
||||
$buttons['websocket_engine']['active'] = true;
|
||||
$subpage = __('Pandora Websocket Engine');
|
||||
case 'quickshell':
|
||||
$buttons['quickshell']['active'] = true;
|
||||
$subpage = __('QuickShell');
|
||||
$help_header = 'quickshell_settings';
|
||||
break;
|
||||
|
||||
|
@ -454,8 +454,8 @@ switch ($section) {
|
|||
include_once $config['homedir'].'/godmode/setup/setup_notifications.php';
|
||||
break;
|
||||
|
||||
case 'websocket_engine':
|
||||
include_once $config['homedir'].'/godmode/setup/setup_websocket_engine.php';
|
||||
case 'quickshell':
|
||||
include_once $config['homedir'].'/godmode/setup/setup_quickshell.php';
|
||||
break;
|
||||
|
||||
case 'external_tools':
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
/**
|
||||
* Settings for Pandora Websocket engine.
|
||||
*
|
||||
* @category UI file
|
||||
* @package Pandora FMS
|
||||
* @subpackage Community
|
||||
* @version 1.0.0
|
||||
* @license See below
|
||||
*
|
||||
* ______ ___ _______ _______ ________
|
||||
* | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __|
|
||||
* | __/| _ | | _ || _ | _| _ | | ___| |__ |
|
||||
* |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
|
||||
*
|
||||
* ============================================================================
|
||||
* Copyright (c) 2005-2023 Pandora FMS
|
||||
* Please see https://pandorafms.com/community/ for full contribution list
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation for version 2.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
global $config;
|
||||
|
||||
$url = ui_get_full_url(
|
||||
'index.php?sec=gsetup&sec2=godmode/setup/setup&section=quickshell&pure='.$config['pure']
|
||||
);
|
||||
|
||||
echo '<form class="max_floating_element_size" id="form_setup" method="post" action="'.$url.'">';
|
||||
|
||||
if (function_exists('quickShellSettings') === true) {
|
||||
quickShellSettings();
|
||||
}
|
||||
|
||||
$action_btns = html_print_submit_button(
|
||||
__('Update'),
|
||||
'update_button',
|
||||
false,
|
||||
[ 'icon' => 'update' ],
|
||||
true
|
||||
);
|
||||
|
||||
html_print_action_buttons(
|
||||
$action_btns
|
||||
);
|
||||
|
||||
echo '</form>';
|
|
@ -1,195 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Settings for Pandora Websocket engine.
|
||||
*
|
||||
* @category UI file
|
||||
* @package Pandora FMS
|
||||
* @subpackage Community
|
||||
* @version 1.0.0
|
||||
* @license See below
|
||||
*
|
||||
* ______ ___ _______ _______ ________
|
||||
* | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __|
|
||||
* | __/| _ | | _ || _ | _| _ | | ___| |__ |
|
||||
* |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
|
||||
*
|
||||
* ============================================================================
|
||||
* Copyright (c) 2005-2023 Pandora FMS
|
||||
* Please see https://pandorafms.com/community/ for full contribution list
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation for version 2.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
global $config;
|
||||
|
||||
$url = ui_get_full_url(
|
||||
'index.php?sec=gsetup&sec2=godmode/setup/setup&section=websocket_engine&pure='.$config['pure']
|
||||
);
|
||||
|
||||
echo '<form class="max_floating_element_size" id="form_setup" method="post" action="'.$url.'">';
|
||||
|
||||
echo '<fieldset class="margin-bottom-10">';
|
||||
echo '<legend>'.__('WebSocket settings').'</legend>';
|
||||
|
||||
$t = new StdClass();
|
||||
$t->data = [];
|
||||
$t->width = '100%';
|
||||
$t->class = 'databox filter-table-adv';
|
||||
$t->data = [];
|
||||
|
||||
$t->data[0][] = html_print_label_input_block(
|
||||
__('Bind address'),
|
||||
html_print_input_text(
|
||||
'ws_bind_address',
|
||||
$config['ws_bind_address'],
|
||||
'',
|
||||
30,
|
||||
100,
|
||||
true
|
||||
)
|
||||
);
|
||||
|
||||
$t->data[0][] = html_print_label_input_block(
|
||||
__('Bind port'),
|
||||
html_print_input_text(
|
||||
'ws_port',
|
||||
$config['ws_port'],
|
||||
'',
|
||||
30,
|
||||
100,
|
||||
true
|
||||
)
|
||||
);
|
||||
|
||||
$t->data[1][] = html_print_label_input_block(
|
||||
__('WebSocket proxy url'),
|
||||
html_print_input_text(
|
||||
'ws_proxy_url',
|
||||
$config['ws_proxy_url'],
|
||||
'',
|
||||
30,
|
||||
100,
|
||||
true
|
||||
)
|
||||
);
|
||||
|
||||
html_print_input_hidden('update_config', 1);
|
||||
|
||||
// Test.
|
||||
$row = [];
|
||||
$test_start = '<span id="test-gotty-spinner" class="invisible"> '.html_print_image('images/spinner.gif', true).'</span>';
|
||||
$test_start .= ' <span id="test-gotty-message" class="invisible"></span>';
|
||||
$row['gotty_test'] = html_print_label_input_block(
|
||||
__('Test connection'),
|
||||
html_print_button(
|
||||
__('Test'),
|
||||
'test-gotty',
|
||||
false,
|
||||
'handleTest()',
|
||||
[
|
||||
'icon' => 'cog',
|
||||
'mode' => 'secondary mini',
|
||||
'style' => 'width: 115px;',
|
||||
],
|
||||
true
|
||||
).$test_start,
|
||||
['div_class' => 'inline_flex row']
|
||||
);
|
||||
|
||||
$t->data['gotty_test'] = $row;
|
||||
|
||||
html_print_table($t);
|
||||
|
||||
echo '</fieldset>';
|
||||
|
||||
if (function_exists('quickShellSettings') === true) {
|
||||
quickShellSettings();
|
||||
}
|
||||
|
||||
html_print_action_buttons(
|
||||
html_print_submit_button(
|
||||
__('Update'),
|
||||
'update_button',
|
||||
false,
|
||||
[ 'icon' => 'update' ],
|
||||
true
|
||||
)
|
||||
);
|
||||
|
||||
echo '</form>';
|
||||
|
||||
echo '<script>';
|
||||
echo 'var server_addr = "'.$_SERVER['SERVER_ADDR'].'";';
|
||||
$handle_test_js = "var handleTest = function (event) {
|
||||
|
||||
var ws_proxy_url = $('input#text-ws_proxy_url').val();
|
||||
var ws_port = $('input#text-ws_port').val();
|
||||
var httpsEnabled = window.location.protocol == 'https' ? true : false;
|
||||
if (ws_proxy_url == '') {
|
||||
ws_url = (httpsEnabled ? 'wss://' : 'ws://') + window.location.host + ':' + ws_port;
|
||||
} else {
|
||||
ws_url = ws_proxy_url;
|
||||
}
|
||||
|
||||
var showLoadingImage = function () {
|
||||
$('#button-test-gotty').children('div').attr('class', 'subIcon cog rotation secondary mini');
|
||||
}
|
||||
|
||||
var showSuccessImage = function () {
|
||||
$('#button-test-gotty').children('div').attr('class', 'subIcon tick secondary mini');
|
||||
}
|
||||
|
||||
var showFailureImage = function () {
|
||||
$('#button-test-gotty').children('div').attr('class', 'subIcon fail secondary mini');
|
||||
}
|
||||
|
||||
var hideMessage = function () {
|
||||
$('span#test-gotty-message').hide();
|
||||
}
|
||||
var showMessage = function () {
|
||||
$('span#test-gotty-message').show();
|
||||
}
|
||||
var changeTestMessage = function (message) {
|
||||
$('span#test-gotty-message').text(message);
|
||||
}
|
||||
|
||||
var errorMessage = '".__('WebService engine has not been started, please check documentation.')."';
|
||||
|
||||
|
||||
hideMessage();
|
||||
showLoadingImage();
|
||||
|
||||
var ws = new WebSocket(ws_url);
|
||||
// Catch errors.
|
||||
|
||||
ws.onerror = () => {
|
||||
showFailureImage();
|
||||
changeTestMessage(errorMessage);
|
||||
showMessage();
|
||||
ws.close();
|
||||
};
|
||||
|
||||
ws.onopen = () => {
|
||||
showSuccessImage();
|
||||
hideMessage();
|
||||
ws.close();
|
||||
};
|
||||
|
||||
ws.onclose = (event) => {
|
||||
changeTestMessage(errorMessage);
|
||||
hideLoadingImage();
|
||||
showMessage();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
$('#button-test-ehorus').click(handleTest);";
|
||||
|
||||
echo $handle_test_js;
|
||||
echo '</script>';
|
|
@ -160,10 +160,9 @@ class DiscoveryTaskList extends HTML
|
|||
return $this->enableTask();
|
||||
}
|
||||
|
||||
if (enterprise_installed()) {
|
||||
// This check only applies to enterprise users.
|
||||
enterprise_hook('tasklist_checkrunning');
|
||||
enterprise_hook('tasklist_checkrunning');
|
||||
|
||||
if (enterprise_installed()) {
|
||||
$ret = $this->showListConsoleTask();
|
||||
} else {
|
||||
$ret = false;
|
||||
|
|
|
@ -200,9 +200,7 @@ class ConsoleSupervisor
|
|||
* NOTIF.CRON.CONFIGURED
|
||||
*/
|
||||
|
||||
if (enterprise_installed()) {
|
||||
$this->checkCronRunning();
|
||||
}
|
||||
$this->checkCronRunning();
|
||||
|
||||
/*
|
||||
* Check if instance is registered.
|
||||
|
@ -501,9 +499,7 @@ class ConsoleSupervisor
|
|||
* NOTIF.CRON.CONFIGURED
|
||||
*/
|
||||
|
||||
if (enterprise_installed()) {
|
||||
$this->checkCronRunning();
|
||||
}
|
||||
$this->checkCronRunning();
|
||||
|
||||
/*
|
||||
* Check if instance is registered.
|
||||
|
@ -2651,14 +2647,20 @@ class ConsoleSupervisor
|
|||
if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
|
||||
$message_conf_cron .= __('Discovery relies on an appropriate cron setup.');
|
||||
$message_conf_cron .= '. '.__('Please, add the following line to your crontab file:');
|
||||
$message_conf_cron .= '<b><pre class=""ui-dialog>* * * * * <user> wget -q -O - --no-check-certificate --load-cookies /tmp/cron-session-cookies --save-cookies /tmp/cron-session-cookies --keep-session-cookies ';
|
||||
$message_conf_cron .= str_replace(
|
||||
ENTERPRISE_DIR.'/meta/',
|
||||
'',
|
||||
ui_get_full_url(false)
|
||||
);
|
||||
$message_conf_cron .= ENTERPRISE_DIR.'/'.EXTENSIONS_DIR;
|
||||
$message_conf_cron .= '/cron/cron.php >> </pre>';
|
||||
if (enterprise_installed()) {
|
||||
$message_conf_cron .= '<b><pre class=""ui-dialog>* * * * * <user> wget -q -O - --no-check-certificate --load-cookies /tmp/cron-session-cookies --save-cookies /tmp/cron-session-cookies --keep-session-cookies ';
|
||||
$message_conf_cron .= str_replace(
|
||||
ENTERPRISE_DIR.'/meta/',
|
||||
'',
|
||||
ui_get_full_url(false)
|
||||
);
|
||||
$message_conf_cron .= ENTERPRISE_DIR.'/'.EXTENSIONS_DIR;
|
||||
$message_conf_cron .= '/cron/cron.php >> </pre>';
|
||||
} else {
|
||||
$message_conf_cron .= '<b><pre class=""ui-dialog>* * * * * <user> wget -q -O - --no-check-certificate --load-cookies /tmp/cron-session-cookies --save-cookies /tmp/cron-session-cookies --keep-session-cookies ';
|
||||
$message_conf_cron .= ui_get_full_url(false).'cron.php >> </pre>';
|
||||
}
|
||||
|
||||
$message_conf_cron .= $config['homedir'].'/log/cron.log</pre>';
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,345 @@
|
|||
<?php
|
||||
/**
|
||||
* Extension to schedule tasks on Pandora FMS Console
|
||||
*
|
||||
* @category Extensions
|
||||
* @package Pandora FMS
|
||||
* @subpackage Enterprise
|
||||
* @version 1.0.0
|
||||
* @license See below
|
||||
*
|
||||
* ______ ___ _______ _______ ________
|
||||
* | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __|
|
||||
* | __/| _ | | _ || _ | _| _ | | ___| |__ |
|
||||
* |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
|
||||
*
|
||||
* ============================================================================
|
||||
* Copyright (c) 2005-2023 Pandora FMS
|
||||
* Please see https://pandorafms.com/community/ for full contribution list
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation for version 2.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
if ((bool) $config['enterprise_installed'] === true) {
|
||||
enterprise_include_once('/include/functions_cron.php');
|
||||
} else {
|
||||
include_once $config['homedir'].'/include/functions_cron_task.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class to run scheduled tasks in cron extension
|
||||
*/
|
||||
class DiscoveryConsoleTask
|
||||
{
|
||||
public const SCHEDULES = [
|
||||
'no',
|
||||
'hourly',
|
||||
'daily',
|
||||
'weekly',
|
||||
'monthly',
|
||||
'yearly',
|
||||
'custom',
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve scheduled tasks given filters.
|
||||
*
|
||||
* @param array $filter Tasks filtered.
|
||||
*
|
||||
* @return array List of scheduled tasks.
|
||||
*/
|
||||
public function list(array $filter)
|
||||
{
|
||||
$tasks = db_get_all_rows_filter(
|
||||
'tuser_task_scheduled INNER JOIN tuser_task ON tuser_task.id = tuser_task_scheduled.id_user_task',
|
||||
$filter,
|
||||
'tuser_task_scheduled.*'
|
||||
);
|
||||
|
||||
if ($tasks === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$tasks = array_map(
|
||||
function ($item) {
|
||||
$item['args'] = unserialize($item['args']);
|
||||
return $item;
|
||||
},
|
||||
$tasks
|
||||
);
|
||||
|
||||
return $tasks;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Should execute task.
|
||||
*
|
||||
* @param array $task Info task.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function shouldTaskRun($task)
|
||||
{
|
||||
global $config;
|
||||
|
||||
if (isset($config['reporting_console_enable']) === true
|
||||
&& (bool) $config['reporting_console_enable'] === true
|
||||
) {
|
||||
$task_info = db_get_row('tuser_task', 'id', $task['id_user_task']);
|
||||
|
||||
if (isset($config['reporting_console_node']) === true
|
||||
&& (bool) $config['reporting_console_node'] === true
|
||||
) {
|
||||
if (($task_info['function_name'] !== 'cron_task_generate_report_by_template'
|
||||
&& $task_info['function_name'] !== 'cron_task_generate_report'
|
||||
&& $task_info['function_name'] !== 'cron_task_save_report_to_disk')
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (($task_info['function_name'] === 'cron_task_generate_report_by_template'
|
||||
|| $task_info['function_name'] === 'cron_task_generate_report'
|
||||
|| $task_info['function_name'] === 'cron_task_save_report_to_disk')
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Manage scheduled tasks.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
global $config;
|
||||
global $pandora_version;
|
||||
|
||||
// Maintenance tasks for tconsole table.
|
||||
// Must do at every Cron execution.
|
||||
if (isset($config['id_console']) === true && $config['id_console'] > 0) {
|
||||
$console_exists = db_get_row('tconsole', 'id_console', $config['id_console']);
|
||||
if ($console_exists === false) {
|
||||
db_process_sql_insert(
|
||||
'tconsole',
|
||||
[
|
||||
'id_console' => $config['id_console'],
|
||||
'description' => $config['console_description'],
|
||||
'version' => $pandora_version,
|
||||
'console_type' => ($config['reporting_console_node'] === true) ? 1 : 0,
|
||||
'timezone' => $config['timezone'],
|
||||
'public_url' => $config['public_url'],
|
||||
]
|
||||
);
|
||||
} else {
|
||||
db_process_sql_update(
|
||||
'tconsole',
|
||||
[
|
||||
'description' => $config['console_description'],
|
||||
'timezone' => $config['timezone'],
|
||||
'public_url' => $config['public_url'],
|
||||
'console_type' => (int) $config['reporting_console_node'],
|
||||
'version' => $pandora_version,
|
||||
],
|
||||
[
|
||||
'id_console' => $config['id_console'],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Maintenance task: schedule daily task to manage GoTTY processes if not defined yet.
|
||||
// Must do at every Cron execution.
|
||||
$gotty_ssh_enabled = (bool) $config['gotty_ssh_enabled'];
|
||||
$gotty_telnet_enabled = (bool) $config['gotty_telnet_enabled'];
|
||||
|
||||
if ($gotty_ssh_enabled === true || $gotty_telnet_enabled === true) {
|
||||
// Create necessary data in task tables when some method of GoTTY is enabled in setup.
|
||||
if ((bool) $config['enterprise_installed'] === false) {
|
||||
$call_func_user_task_id = db_get_value_sql('SELECT id FROM `tuser_task` WHERE `function_name` = "cron_task_call_user_function"');
|
||||
if ($call_func_user_task_id === false) {
|
||||
db_process_sql("INSERT INTO `tuser_task` (`function_name`, `parameters`, `name`) VALUES ('cron_task_call_user_function','a:1:{i:0;a:2:{s:11:\"description\";s:13:\"Function name\";s:4:\"type\";s:4:\"text\";}}','Call PHP function')");
|
||||
}
|
||||
}
|
||||
|
||||
$user_function_task_id = db_get_value_sql('SELECT id FROM `tuser_task_scheduled` WHERE `args` LIKE "%cron_task_start_gotty%"');
|
||||
|
||||
if ($user_function_task_id === false) {
|
||||
// Schedule task to manage GoTTY processes daily if it is not scheduled yet.
|
||||
$this->schedule(
|
||||
'cron_task_call_user_function',
|
||||
[
|
||||
0 => 'cron_task_start_gotty',
|
||||
'function_name' => 'cron_task_start_gotty',
|
||||
'internal' => 1,
|
||||
],
|
||||
'daily',
|
||||
0,
|
||||
0,
|
||||
strtotime('tomorrow')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Maintenance task: check whether start GoTTY SSH and Telnet processes are running and start otherwise.
|
||||
// Must do at every Cron execution.
|
||||
cron_task_start_gotty(false);
|
||||
|
||||
// Do not output anything until is completed. There're session
|
||||
// operations inside cron_task_run function.
|
||||
ob_start();
|
||||
|
||||
if (cron_task_lock() === false) {
|
||||
// Cannot continue. Locked.
|
||||
echo ob_get_clean();
|
||||
exit;
|
||||
}
|
||||
|
||||
$time = get_system_time();
|
||||
$scheduled_tasks = db_get_all_rows_in_table('tuser_task_scheduled');
|
||||
if (!$scheduled_tasks) {
|
||||
$scheduled_tasks = [];
|
||||
}
|
||||
|
||||
/*
|
||||
Watch out! First_execution corresponds to next_execution the name
|
||||
of the bbdd is maintained to ensure integrity.
|
||||
*/
|
||||
|
||||
foreach ($scheduled_tasks as $task) {
|
||||
$params = unserialize($task['args']);
|
||||
if ($this->shouldTaskRun($task) === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($task['scheduled'] == 'no') {
|
||||
if (($params['first_execution']) < $time) {
|
||||
echo date('Y/m/d H:i:s').' Execute once time cron task: ';
|
||||
echo $task['id'];
|
||||
echo "\n\n";
|
||||
cron_task_run($task['id']);
|
||||
// The task was not scheduled and was executed once.
|
||||
db_process_sql_delete(
|
||||
'tuser_task_scheduled',
|
||||
['id' => $task['id']]
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (($params['first_execution']) < $time) {
|
||||
echo date('Y/m/d H:i:s').' EXECUTED CRON TASK: '.$task['id'];
|
||||
echo "\n";
|
||||
echo "\n";
|
||||
cron_task_run($task['id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dump to output.
|
||||
echo ob_get_clean();
|
||||
|
||||
// Release the lock.
|
||||
cron_task_release_lock();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Schedules a discovery console task to be executed by cron.
|
||||
*
|
||||
* @param string $function_name Name of the function:
|
||||
* cron_task_generate_report
|
||||
* cron_task_generate_report_by_template
|
||||
* cron_task_save_report_to_disk
|
||||
* cron_task_do_backup
|
||||
* cron_task_execute_custom_script
|
||||
* cron_task_save_xml_report_to_disk
|
||||
* cron_task_feedback_send_mail
|
||||
* cron_task_generate_csv_log.
|
||||
* @param array $arguments Task execution arguments (if needed).
|
||||
* @param string $schedule Task schedule options:
|
||||
* 'no',
|
||||
* 'hourly',
|
||||
* 'daily',
|
||||
* 'weekly',
|
||||
* 'monthly',
|
||||
* 'yearly',
|
||||
* 'custom'.
|
||||
* @param integer $group_id Group id (0 => all).
|
||||
* @param string|null $id_user User id, if null, current user.
|
||||
* @param integer|null $time_start When to start, if null, now.
|
||||
*
|
||||
* @return boolean Sucessfully scheduled or not.
|
||||
*/
|
||||
public function schedule(
|
||||
string $function_name,
|
||||
array $arguments=[],
|
||||
string $schedule='no',
|
||||
int $group_id=0,
|
||||
?string $id_user=null,
|
||||
?int $time_start=null
|
||||
) {
|
||||
global $config;
|
||||
|
||||
if ($id_user === null) {
|
||||
$id_user = $config['id_user'];
|
||||
}
|
||||
|
||||
$idUserTask = db_get_value(
|
||||
'id',
|
||||
'tuser_task',
|
||||
'function_name',
|
||||
$function_name
|
||||
);
|
||||
|
||||
if ($idUserTask === false) {
|
||||
// Failed to identify function.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (in_array($schedule, self::SCHEDULES) === false) {
|
||||
// Failed to schedule. Not a valid schedule option.
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($time_start === null) {
|
||||
$time_start = strtotime('now');
|
||||
}
|
||||
|
||||
// Params for send mail with cron.
|
||||
$parameters = array_merge(
|
||||
$arguments,
|
||||
[ 'first_execution' => $time_start ]
|
||||
);
|
||||
|
||||
// Values insert task cron.
|
||||
$task = [
|
||||
'id_usuario' => $id_user,
|
||||
'id_user_task' => $idUserTask,
|
||||
'args' => serialize($parameters),
|
||||
'scheduled' => $schedule,
|
||||
'id_grupo' => $group_id,
|
||||
];
|
||||
|
||||
$result = db_process_sql_insert(
|
||||
'tuser_task_scheduled',
|
||||
$task
|
||||
);
|
||||
|
||||
return ($result !== false);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1497,7 +1497,6 @@ function config_update_config()
|
|||
$interval_values = implode(',', $interval_values_array);
|
||||
}
|
||||
|
||||
hd($interval_values, true);
|
||||
if (config_update_value('interval_values', $interval_values, true) === false) {
|
||||
$error_update[] = __('Delete interval');
|
||||
}
|
||||
|
@ -2034,20 +2033,6 @@ function config_update_config()
|
|||
}
|
||||
break;
|
||||
|
||||
case 'websocket_engine':
|
||||
if (config_update_value('ws_bind_address', get_parameter('ws_bind_address'), true) === false) {
|
||||
$error_update[] = __('WebSocket bind address');
|
||||
}
|
||||
|
||||
if (config_update_value('ws_port', get_parameter('ws_port'), true) === false) {
|
||||
$error_update[] = __('WebSocket port');
|
||||
}
|
||||
|
||||
if (config_update_value('ws_proxy_url', get_parameter('ws_proxy_url'), true) === false) {
|
||||
$error_update[] = __('WebSocket proxy url');
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Ignore.
|
||||
break;
|
||||
|
@ -2504,6 +2489,18 @@ function config_process_config()
|
|||
config_update_value('2Fa_auth', '');
|
||||
}
|
||||
|
||||
if (!isset($config['gotty_ssh_enabled'])) {
|
||||
config_update_value('gotty_ssh_enabled', 1);
|
||||
}
|
||||
|
||||
if (!isset($config['gotty_telnet_enabled'])) {
|
||||
config_update_value('gotty_telnet_enabled', 0);
|
||||
}
|
||||
|
||||
if (!isset($config['gotty_port'])) {
|
||||
config_update_value('gotty_port', 8080);
|
||||
}
|
||||
|
||||
if (isset($config['performance_variables_control']) === false) {
|
||||
config_update_value(
|
||||
'performance_variables_control',
|
||||
|
|
|
@ -463,7 +463,6 @@ function cron_list_table()
|
|||
);
|
||||
|
||||
$defined_tasks = db_get_all_rows_sql($sql);
|
||||
|
||||
if (!check_acl($config['id_user'], 0, 'PM')) {
|
||||
$read_tasks = [];
|
||||
foreach ($defined_tasks as $task) {
|
||||
|
|
|
@ -0,0 +1,542 @@
|
|||
<?php
|
||||
/**
|
||||
* Schedule tasks on Pandora FMS Console
|
||||
*
|
||||
* @category library
|
||||
* @package Pandora FMS
|
||||
* @subpackage cron
|
||||
* @version 1.0.0
|
||||
* @license See below
|
||||
*
|
||||
* ______ ___ _______ _______ ________
|
||||
* | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __|
|
||||
* | __/| _ | | _ || _ | _| _ | | ___| |__ |
|
||||
* |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
|
||||
*
|
||||
* ============================================================================
|
||||
* Copyright (c) 2005-2023 Pandora FMS
|
||||
* Please see https://pandorafms.com/community/ for full contribution list
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation for version 2.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Generate a lock system to avoid multiple executions.
|
||||
*
|
||||
* @param string $lockfile Filename to use as lock.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function cron_lock(string $lockfile)
|
||||
{
|
||||
global $config;
|
||||
|
||||
if (empty($lockfile) === true) {
|
||||
$lockfile = 'cron.lock';
|
||||
}
|
||||
|
||||
$ignore_lock = 0;
|
||||
// Lock to prevent multiple instances of the cron extension.
|
||||
$lock = $config['attachment_store'].'/'.$lockfile;
|
||||
if (file_exists($lock) === true) {
|
||||
// Lock file exists.
|
||||
$read_PID = file_get_contents($lock);
|
||||
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
||||
// Windows check.
|
||||
$processes = explode("\n", shell_exec('tasklist.exe'));
|
||||
$ignore_lock = 1;
|
||||
foreach ($processes as $process) {
|
||||
if (empty($process) === true
|
||||
|| strpos('===', $process) === 0
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$matches = false;
|
||||
preg_match('/(.*?)\s+(\d+).*$/', $process, $matches);
|
||||
$pid = $matches[2];
|
||||
|
||||
if ((int) $pid === (int) $read_PID) {
|
||||
$ignore_lock = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Linux check.
|
||||
if (file_exists('/proc/'.$read_PID) === true) {
|
||||
// Process with a pid = $pid is running.
|
||||
// CRON already running: [$read_PID].
|
||||
$ignore_lock = 0;
|
||||
} else {
|
||||
// CRON process [$read_PID] does not exist.
|
||||
// process not found, ignore $lock.
|
||||
$ignore_lock = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// The lock automatically expires after 24 hours.
|
||||
$lock_mtime = filemtime($lock);
|
||||
if (($ignore_lock === 0 )
|
||||
&& ($lock_mtime !== false && $lock_mtime + SECONDS_1DAY > time())
|
||||
) {
|
||||
// Locked!
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to get a lock from DB.
|
||||
$dblock = db_get_lock($config['dbname'].'.'.$lockfile);
|
||||
if ($dblock !== 1) {
|
||||
// Locked!
|
||||
return false;
|
||||
}
|
||||
|
||||
// Store PID in lock file.
|
||||
$PID = getmypid();
|
||||
echo 'CRON running ['.$PID."]\n";
|
||||
file_put_contents($lock, $PID);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if CRON.task is available to start.
|
||||
*
|
||||
* @return boolean True, available. False not available.
|
||||
*/
|
||||
function cron_task_lock()
|
||||
{
|
||||
return cron_lock('cron.lock');
|
||||
}
|
||||
|
||||
/**
|
||||
* Release CRON.task lock
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function cron_task_release_lock()
|
||||
{
|
||||
global $config;
|
||||
|
||||
// Release DB lock.
|
||||
$dblock = db_release_lock($config['dbname'].'.cron.lock');
|
||||
unlink($config['attachment_store'].'/cron.lock');
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates target schedule time
|
||||
*
|
||||
* @param string $scheduled_time Desired scheduled time.
|
||||
* @param integer $custom_data Custom scheduled time.
|
||||
* @param integer|null $timestamp Custom timestamp.
|
||||
*
|
||||
* @return integer amount of time.
|
||||
*/
|
||||
function cron_get_scheduled_time(
|
||||
string $scheduled_time,
|
||||
int $custom_data=0,
|
||||
$timestamp=null
|
||||
) {
|
||||
if ($scheduled_time == 'no') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($scheduled_time == 'hourly') {
|
||||
return SECONDS_1HOUR;
|
||||
}
|
||||
|
||||
if ($scheduled_time == 'daily') {
|
||||
return SECONDS_1DAY;
|
||||
}
|
||||
|
||||
if ($scheduled_time == 'weekly') {
|
||||
return SECONDS_1WEEK;
|
||||
}
|
||||
|
||||
if ($scheduled_time == 'monthly') {
|
||||
$month = (($timestamp === null) ? date('m') : date('m', $timestamp));
|
||||
$year = (($timestamp === null) ? date('Y') : date('Y', $timestamp));
|
||||
|
||||
$days_month = (cal_days_in_month(
|
||||
CAL_GREGORIAN,
|
||||
$month,
|
||||
$year
|
||||
) * SECONDS_1DAY);
|
||||
|
||||
return $days_month;
|
||||
}
|
||||
|
||||
if ($scheduled_time == 'yearly') {
|
||||
return SECONDS_1YEAR;
|
||||
}
|
||||
|
||||
if ($scheduled_time == 'custom') {
|
||||
return $custom_data;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run scheduled task.
|
||||
*
|
||||
* @param integer $id_user_task Task to be run.
|
||||
* @param boolean $force_run Force run.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function cron_task_run(
|
||||
int $id_user_task,
|
||||
bool $force_run=false
|
||||
) {
|
||||
global $config;
|
||||
|
||||
if (isset($config['id_console']) === true && $config['id_console'] > 0) {
|
||||
$sql = sprintf(
|
||||
'SELECT *
|
||||
FROM tuser_task_scheduled
|
||||
WHERE id=%d AND id_console IN (0, %d)',
|
||||
$id_user_task,
|
||||
$config['id_console']
|
||||
);
|
||||
|
||||
$task_scheduled = db_get_row_sql($sql);
|
||||
|
||||
if ($task_scheduled !== false) {
|
||||
db_process_sql_update(
|
||||
'tconsole',
|
||||
['last_execution' => time()],
|
||||
['id_console' => $config['id_console']]
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$filter = [
|
||||
'id' => $id_user_task,
|
||||
'id_console' => 0,
|
||||
];
|
||||
|
||||
$task_scheduled = db_get_row_filter('tuser_task_scheduled', $filter, false);
|
||||
}
|
||||
|
||||
$args = unserialize($task_scheduled['args']);
|
||||
|
||||
if ((bool) $config['enterprise_installed'] === false
|
||||
&& isset($args['function_name']) === true
|
||||
&& $args['function_name'] !== 'cron_task_start_gotty'
|
||||
) {
|
||||
// Only cron_task_start_gotty is allowed to run in non enterprise environments.
|
||||
return;
|
||||
}
|
||||
|
||||
if ((bool) $config['enterprise_installed'] === true) {
|
||||
$task = db_get_row('tuser_task', 'id', $task_scheduled['id_user_task']);
|
||||
} else {
|
||||
$task = [
|
||||
'name' => 'Call PHP function',
|
||||
'function_name' => 'cron_task_call_user_function',
|
||||
];
|
||||
}
|
||||
|
||||
// Register shutdown function in case of fatal error, like.
|
||||
register_shutdown_function('cron_task_handle_error', $task_scheduled, $task, $force_run);
|
||||
|
||||
if (is_metaconsole() && !defined('METACONSOLE')) {
|
||||
define('METACONSOLE', 1);
|
||||
}
|
||||
|
||||
if (! function_exists($task['function_name'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the task is disable, not run.
|
||||
if ((bool) $task_scheduled['enabled'] === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (session_status() === PHP_SESSION_DISABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
$old_user = '';
|
||||
if (isset($config['id_user']) === false) {
|
||||
$config['id_user'] = $task_scheduled['id_usuario'];
|
||||
}
|
||||
|
||||
$old_user = $config['id_user'];
|
||||
|
||||
$old_session_id = session_id();
|
||||
$new_session_id = 'cron-'.uniqid();
|
||||
|
||||
// Simulate user login.
|
||||
session_id($new_session_id);
|
||||
session_start();
|
||||
$_SESSION['id_usuario'] = $config['id_user'];
|
||||
session_write_close();
|
||||
|
||||
set_time_limit(0);
|
||||
|
||||
if ($task['function_name'] == 'cron_task_generate_report_by_template'
|
||||
|| $task['function_name'] == 'cron_task_generate_report'
|
||||
) {
|
||||
// If empty agent position, add it.
|
||||
if (!isset($args[1])) {
|
||||
array_splice($args, 1, 0, '');
|
||||
}
|
||||
|
||||
$args[] = $task_scheduled['scheduled'];
|
||||
}
|
||||
|
||||
call_user_func_array(
|
||||
$task['function_name'],
|
||||
array_merge(array_values(($args ?? [])), [$id_user_task])
|
||||
);
|
||||
|
||||
if (session_status() === PHP_SESSION_ACTIVE) {
|
||||
@session_destroy();
|
||||
}
|
||||
|
||||
session_id($old_session_id);
|
||||
session_start();
|
||||
|
||||
$config['id_user'] = $old_user;
|
||||
$sql = '';
|
||||
$sql2 = '';
|
||||
|
||||
if (!$force_run) {
|
||||
$period = cron_get_scheduled_time(
|
||||
$task_scheduled['scheduled'],
|
||||
$task_scheduled['custom_data']
|
||||
);
|
||||
$old_args = unserialize($task_scheduled['args']);
|
||||
if ($period > 3600) {
|
||||
$array_explode = explode(
|
||||
':',
|
||||
date('H:i', $old_args['first_execution'])
|
||||
);
|
||||
$hora_en_segundos = (($array_explode[0] * 3600 ) + ($array_explode[1] * 60));
|
||||
|
||||
$array_explode_period = explode(
|
||||
':',
|
||||
date('H:i', ($old_args['first_execution'] + $period))
|
||||
);
|
||||
$hora_en_segundos2 = (($array_explode_period[0] * 3600 ) + ($array_explode_period[1] * 60));
|
||||
|
||||
if ($hora_en_segundos !== $hora_en_segundos2) {
|
||||
$period = ($period + ($hora_en_segundos - $hora_en_segundos2));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
/*
|
||||
Calculate the number of periods between last execution and
|
||||
current time.
|
||||
*/
|
||||
|
||||
$num_of_periods = 0;
|
||||
if ($period !== 0) {
|
||||
$num_of_periods = ceil(
|
||||
(time() - $old_args['first_execution']) / $period
|
||||
);
|
||||
}
|
||||
|
||||
if ($task_scheduled['scheduled'] == 'monthly') {
|
||||
$updated_time = $old_args['first_execution'];
|
||||
|
||||
// Update updated_time adding the period for each month individually since it is a variable value depending on the number of days a month has.
|
||||
while ($num_of_periods > 0) {
|
||||
// Get days of current month.
|
||||
$monthly_period = cron_get_scheduled_time(
|
||||
'monthly',
|
||||
$task_scheduled['custom_data'],
|
||||
$updated_time
|
||||
);
|
||||
$updated_time += $monthly_period;
|
||||
$num_of_periods--;
|
||||
}
|
||||
|
||||
$old_args['first_execution'] = $updated_time;
|
||||
} else if ($task_scheduled['scheduled'] == 'weekly') {
|
||||
$weekly_schedule = json_decode(io_safe_output($old_args['weekly_schedule']), true);
|
||||
if (empty($weekly_schedule) !== true) {
|
||||
$datetime = new DateTime('tomorrow');
|
||||
$nameday = strtolower($datetime->format('l'));
|
||||
$continue = true;
|
||||
while ($continue === true) {
|
||||
if (isset($weekly_schedule[$nameday]) === true) {
|
||||
$weekly_date = $datetime->format('Y-m-d');
|
||||
$weekly_time = $weekly_schedule[$nameday][0]['start'];
|
||||
$old_args['first_execution'] = strtotime($weekly_date.' '.$weekly_time);
|
||||
|
||||
$continue = false;
|
||||
} else {
|
||||
$datetime->modify('+1 day');
|
||||
$nameday = strtolower($datetime->format('l'));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Add it to next execution.
|
||||
$old_args['first_execution'] += ($period * $num_of_periods);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// If some error (ex $period=0) next execution=current time+period.
|
||||
$old_args['first_execution'] = (time() + $period);
|
||||
}
|
||||
|
||||
$new_args = serialize($old_args);
|
||||
}
|
||||
|
||||
if ($config['timesource'] == 'sql') {
|
||||
$sql = sprintf(
|
||||
'UPDATE tuser_task_scheduled
|
||||
SET last_run=UNIX_TIMESTAMP()
|
||||
WHERE id=%d',
|
||||
$id_user_task
|
||||
);
|
||||
} else {
|
||||
$sql = sprintf(
|
||||
'UPDATE tuser_task_scheduled
|
||||
SET last_run= %d
|
||||
WHERE id=%d',
|
||||
time(),
|
||||
$id_user_task
|
||||
);
|
||||
}
|
||||
|
||||
if (!$force_run) {
|
||||
$sql2 = "UPDATE tuser_task_scheduled
|
||||
SET args = '".$new_args."'
|
||||
WHERE id=".$id_user_task;
|
||||
}
|
||||
|
||||
db_process_sql($sql);
|
||||
db_process_sql($sql2);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execuytes custom function defined in PHP.
|
||||
*
|
||||
* @param string $function_name Name to execute.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function cron_task_call_user_function(string $function_name)
|
||||
{
|
||||
global $config;
|
||||
|
||||
include_once $config['homedir'].'/vendor/autoload.php';
|
||||
|
||||
call_user_func($function_name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check whether GoTTY SSH and Telnet processes are running and start otherwise.
|
||||
*
|
||||
* @param boolean $restart_mode Restart the processes if running.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function cron_task_start_gotty(bool $restart_mode=true)
|
||||
{
|
||||
global $config;
|
||||
|
||||
include_once $config['homedir'].'/include/functions_config.php';
|
||||
|
||||
$gotty_ssh_enabled = (bool) $config['gotty_ssh_enabled'];
|
||||
$gotty_telnet_enabled = (bool) $config['gotty_telnet_enabled'];
|
||||
|
||||
// Check prev process running and kill it (only if port changed in setup params).
|
||||
if (empty($config['restart_gotty_next_cron_port']) === false) {
|
||||
config_update_value('restart_gotty_next_cron_port', '');
|
||||
|
||||
$prevProcessRunning = shell_exec("pgrep -f 'pandora_gotty.*-p ".$config['restart_gotty_next_cron_port']."'");
|
||||
|
||||
if (empty($prevProcessRunning) === false) {
|
||||
shell_exec("pkill -f 'pandora_gotty.*-p ".$config['restart_gotty_next_cron_port']."'");
|
||||
}
|
||||
}
|
||||
|
||||
// Check if gotty is running on the configured port.
|
||||
$processRunning = shell_exec("pgrep -f 'pandora_gotty.*-p ".$config['gotty_port']."'");
|
||||
|
||||
$start_proc = true;
|
||||
|
||||
// If both methods are disabled, do not start process.
|
||||
if ($gotty_ssh_enabled === false && $gotty_telnet_enabled === false) {
|
||||
$start_proc = false;
|
||||
}
|
||||
|
||||
if (empty($processRunning) === false) {
|
||||
// Process is running.
|
||||
if ($restart_mode === true || $start_proc === false) {
|
||||
// Stop the process for restarting or in case GoTTY method is disabled in this iteration.
|
||||
shell_exec("pkill -f 'pandora_gotty.*-p ".$config['gotty_port']."'");
|
||||
} else {
|
||||
// Prevent starting if already running and must not be restarted or terminated.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ($start_proc === true) {
|
||||
$logFilePath = $config['homedir'].'/log/gotty_cron_tmp.log';
|
||||
shell_exec('touch '.$logFilePath);
|
||||
|
||||
// Start gotty process and capture the output.
|
||||
$command = '/usr/bin/nohup /usr/bin/pandora_gotty --config /etc/pandora_gotty/pandora_gotty.conf -p '.$config['gotty_port'].' /usr/bin/pandora_gotty_exec > '.$logFilePath.' 2>&1 &';
|
||||
shell_exec($command);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
$hash_read = false;
|
||||
|
||||
// Maximum wait time to read asynchronously the output of the executed commands (seconds).
|
||||
$maxWaitTime = 10;
|
||||
|
||||
// Wait for content to appear in the log file.
|
||||
$startTime = time();
|
||||
|
||||
// Workaround to wait until process inputs data in the log.
|
||||
while (time() - $startTime < $maxWaitTime) {
|
||||
if ($start_proc === true) {
|
||||
// Read command output.
|
||||
$log_content = file_get_contents($logFilePath);
|
||||
}
|
||||
|
||||
if ($start_proc === true
|
||||
&& !empty($log_content)
|
||||
&& $hash_read === false
|
||||
) {
|
||||
// Extract the URL from the output.
|
||||
if (preg_match('/.*?HTTP server is listening at:\s+(\S+)/', $log_content, $matches)) {
|
||||
$url = $matches[1];
|
||||
|
||||
// Extract the hash.
|
||||
$parts = explode('/', $url);
|
||||
$hash = array_slice($parts, -2, 1)[0];
|
||||
|
||||
config_update_value('gotty_connection_hash', $hash);
|
||||
$hash_read = true;
|
||||
}
|
||||
|
||||
unlink($logFilePath);
|
||||
}
|
||||
|
||||
if ($start_proc === false || $hash_read === true) {
|
||||
// As soon as the read has completed, the timing loop will terminate.
|
||||
break;
|
||||
}
|
||||
|
||||
// Sleep for a short interval before checking again.
|
||||
usleep(100000);
|
||||
}
|
||||
}
|
|
@ -1,175 +0,0 @@
|
|||
#!/bin/bash
|
||||
# Copyright (c) 2005-2023 Pandora FMS
|
||||
#
|
||||
# /etc/init.d/websocket
|
||||
#
|
||||
# System startup script for Pandora FMS Console websocket engine
|
||||
#
|
||||
# Comments to support chkconfig on RedHat Linux
|
||||
# chkconfig: 2345 90 10
|
||||
# description: Pandora FMS Console webscoket engine startup script
|
||||
#
|
||||
# Comments to support LSB init script conventions
|
||||
### BEGIN INIT INFO
|
||||
# Provides: websocket
|
||||
# Required-Start: $syslog cron
|
||||
# Should-Start: $network cron mysql
|
||||
# Required-Stop: $syslog
|
||||
# Should-Stop: $network
|
||||
# Default-Start: 2 3 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Pandora FMS Console websocket engine startup script
|
||||
# Description: Pandora FMS Console websocket engine startup script
|
||||
### END INIT INFO
|
||||
|
||||
if [ -x /lib/lsb/init-functions ]; then
|
||||
. /lib/lsb/init-functions
|
||||
fi
|
||||
|
||||
# If you want to run several pandora Console Websocket engines in this machine, just copy
|
||||
# this script to another name, editing PANDORA_HOME to the new .conf
|
||||
|
||||
export WS_ENGINE="/var/www/html/pandora_console/ws.php"
|
||||
export PHP=/usr/bin/php
|
||||
export WS_LOG="/var/log/pandora/web_socket.log"
|
||||
export GOTTY="/tmp/"
|
||||
|
||||
# Environment variables
|
||||
if [[ -z ${PANDORA_RB_PRODUCT_NAME} ]]; then
|
||||
PANDORA_RB_PRODUCT_NAME="Pandora FMS"
|
||||
fi
|
||||
if [[ -z ${PANDORA_RB_COPYRIGHT_NOTICE} ]]; then
|
||||
PANDORA_RB_COPYRIGHT_NOTICE="Pandora FMS"
|
||||
fi
|
||||
|
||||
export PANDORA_RB_PRODUCT_NAME=$PANDORA_RB_PRODUCT_NAME
|
||||
export PANDORA_RB_COPYRIGHT_NOTICE=$PANDORA_RB_COPYRIGHT_NOTICE
|
||||
|
||||
# Uses a wait limit before sending a KILL signal, before trying to stop
|
||||
# Pandora FMS Console Websocket engine nicely. Some big systems need some time before close
|
||||
# all pending tasks / threads.
|
||||
|
||||
export MAXWAIT=60
|
||||
|
||||
# Check for SUSE status scripts
|
||||
if [ -f /etc/rc.status ]
|
||||
then
|
||||
. /etc/rc.status
|
||||
rc_reset
|
||||
else
|
||||
# Define part of rc functions for non-suse systems
|
||||
function rc_status () {
|
||||
RETVAL=$?
|
||||
case $1 in
|
||||
-v) RETVAL=0;;
|
||||
esac
|
||||
}
|
||||
function rc_exit () { exit $RETVAL; }
|
||||
function rc_failed () { RETVAL=${1:-1}; }
|
||||
RETVAL=0
|
||||
fi
|
||||
|
||||
# This function replace pidof, not working in the same way in different linux distros
|
||||
|
||||
function pidof_pandora () {
|
||||
# This sets COLUMNS to XXX chars, because if command is run
|
||||
# in a "strech" term, ps aux don't report more than COLUMNS
|
||||
# characters and this will not work.
|
||||
COLUMNS=300
|
||||
PANDORA_PID=`ps aux | grep "$PHP $WS_ENGINE" | grep -v grep | tail -1 | awk '{ print $2 }'`
|
||||
echo $PANDORA_PID
|
||||
}
|
||||
|
||||
# Main script
|
||||
|
||||
if [ ! -x $GOTTY ]
|
||||
then
|
||||
echo "Gotty not found in $GOTTY"
|
||||
rc_failed 5 # program is not installed
|
||||
rc_exit
|
||||
fi
|
||||
|
||||
if [ ! -f $PHP ]
|
||||
then
|
||||
echo "$PHP not found, please install version >= 7.0"
|
||||
rc_failed 5 # program is not installed
|
||||
rc_exit
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
PANDORA_PID=`pidof_pandora`
|
||||
if [ ! -z "$PANDORA_PID" ]
|
||||
then
|
||||
echo "$PANDORA_RB_PRODUCT_NAME Console Websocket engine is currently running on this machine with PID ($PANDORA_PID)."
|
||||
rc_exit # running start on a service already running
|
||||
fi
|
||||
|
||||
export PERL_LWP_SSL_VERIFY_HOSTNAME=0
|
||||
$PHP $WS_ENGINE >> $WS_LOG 2>&1 &
|
||||
sleep 1
|
||||
|
||||
PANDORA_PID=`pidof_pandora`
|
||||
|
||||
if [ ! -z "$PANDORA_PID" ]
|
||||
then
|
||||
echo "$PANDORA_RB_PRODUCT_NAME Console Websocket engine is now running with PID $PANDORA_PID"
|
||||
rc_status -v
|
||||
else
|
||||
echo "Cannot start $PANDORA_RB_PRODUCT_NAME Console Websocket engine. Aborted."
|
||||
echo "Check $PANDORA_RB_PRODUCT_NAME log files at $WS_LOG"
|
||||
rc_failed 7 # program is not running
|
||||
fi
|
||||
;;
|
||||
|
||||
stop)
|
||||
PANDORA_PID=`pidof_pandora`
|
||||
if [ -z "$PANDORA_PID" ]
|
||||
then
|
||||
echo "$PANDORA_RB_PRODUCT_NAME Console Websocket engine is not running, cannot stop it."
|
||||
rc_exit # running stop on a service already stopped or not running
|
||||
else
|
||||
echo "Stopping $PANDORA_RB_PRODUCT_NAME Console Websocket engine"
|
||||
kill $PANDORA_PID > /dev/null 2>&1
|
||||
COUNTER=0
|
||||
|
||||
while [ $COUNTER -lt $MAXWAIT ]
|
||||
do
|
||||
_PID=`pidof_pandora`
|
||||
if [ "$_PID" != "$PANDORA_PID" ]
|
||||
then
|
||||
COUNTER=$MAXWAIT
|
||||
fi
|
||||
COUNTER=`expr $COUNTER + 1`
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Send a KILL -9 signal to process, if it's alive after 60secs, we need
|
||||
# to be sure is really dead, and not pretending...
|
||||
if [ "$_PID" = "$PANDORA_PID" ]
|
||||
then
|
||||
kill -9 $PANDORA_PID > /dev/null 2>&1
|
||||
fi
|
||||
rc_status -v
|
||||
fi
|
||||
;;
|
||||
status)
|
||||
PANDORA_PID=`pidof_pandora`
|
||||
if [ -z "$PANDORA_PID" ]
|
||||
then
|
||||
echo "$PANDORA_RB_PRODUCT_NAME Console Websocket engine is not running."
|
||||
rc_failed 7 # program is not running
|
||||
else
|
||||
echo "$PANDORA_RB_PRODUCT_NAME Console Websocket engine is running with PID $PANDORA_PID."
|
||||
rc_status
|
||||
fi
|
||||
;;
|
||||
force-reload|restart)
|
||||
$0 stop
|
||||
$0 start
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 { start | stop | restart | status }"
|
||||
exit 1
|
||||
esac
|
||||
rc_exit
|
Loading…
Reference in New Issue