#11206 Resolve conflicts
This commit is contained in:
commit
384fb8d115
|
@ -1,5 +1,5 @@
|
||||||
# Base config file for Pandora FMS agents
|
# Base config file for Pandora FMS agents
|
||||||
# Version 7.0NG.773, AIX version
|
# Version 7.0NG.773.1, AIX version
|
||||||
# Licensed under GPL license v2,
|
# Licensed under GPL license v2,
|
||||||
# Copyright (c) 2003-2023 Pandora FMS
|
# Copyright (c) 2003-2023 Pandora FMS
|
||||||
# http://www.pandorafms.com
|
# http://www.pandorafms.com
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Base config file for Pandora FMS agents
|
# Base config file for Pandora FMS agents
|
||||||
# Version 7.0NG.773, FreeBSD Version
|
# Version 7.0NG.773.1, FreeBSD Version
|
||||||
# Licensed under GPL license v2,
|
# Licensed under GPL license v2,
|
||||||
# Copyright (c) 2003-2023 Pandora FMS
|
# Copyright (c) 2003-2023 Pandora FMS
|
||||||
# http://www.pandorafms.com
|
# http://www.pandorafms.com
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Base config file for Pandora FMS agents
|
# Base config file for Pandora FMS agents
|
||||||
# Version 7.0NG.773, HP-UX Version
|
# Version 7.0NG.773.1, HP-UX Version
|
||||||
# Licensed under GPL license v2,
|
# Licensed under GPL license v2,
|
||||||
# Copyright (c) 2003-2023 Pandora FMS
|
# Copyright (c) 2003-2023 Pandora FMS
|
||||||
# http://www.pandorafms.com
|
# http://www.pandorafms.com
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Base config file for Pandora FMS agents
|
# Base config file for Pandora FMS agents
|
||||||
# Version 7.0NG.773, GNU/Linux
|
# Version 7.0NG.773.1, GNU/Linux
|
||||||
# Licensed under GPL license v2,
|
# Licensed under GPL license v2,
|
||||||
# Copyright (c) 2003-2023 Pandora FMS
|
# Copyright (c) 2003-2023 Pandora FMS
|
||||||
# http://www.pandorafms.com
|
# http://www.pandorafms.com
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Base config file for Pandora FMS agents
|
# Base config file for Pandora FMS agents
|
||||||
# Version 7.0NG.773, GNU/Linux
|
# Version 7.0NG.773.1, GNU/Linux
|
||||||
# Licensed under GPL license v2,
|
# Licensed under GPL license v2,
|
||||||
# Copyright (c) 2003-2023 Pandora FMS
|
# Copyright (c) 2003-2023 Pandora FMS
|
||||||
# http://www.pandorafms.com
|
# http://www.pandorafms.com
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Base config file for Pandora FMS agents
|
# Base config file for Pandora FMS agents
|
||||||
# Version 7.0NG.773, Solaris Version
|
# Version 7.0NG.773.1, Solaris Version
|
||||||
# Licensed under GPL license v2,
|
# Licensed under GPL license v2,
|
||||||
# Copyright (c) 2003-2023 Pandora FMS
|
# Copyright (c) 2003-2023 Pandora FMS
|
||||||
# http://www.pandorafms.com
|
# http://www.pandorafms.com
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Base config file for Pandora FMS Windows Agent
|
# Base config file for Pandora FMS Windows Agent
|
||||||
# (c) 2006-2023 Pandora FMS
|
# (c) 2006-2023 Pandora FMS
|
||||||
# Version 7.0NG.773
|
# Version 7.0NG.773.1
|
||||||
# This program is Free Software, you can redistribute it and/or modify it
|
# This program is Free Software, you can redistribute it and/or modify it
|
||||||
# under the terms of the GNU General Public Licence as published by the Free Software
|
# under the terms of the GNU General Public Licence as published by the Free Software
|
||||||
# Foundation; either version 2 of the Licence or any later version
|
# Foundation; either version 2 of the Licence or any later version
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Fichero de configuracion base de agentes de Pandora
|
# Fichero de configuracion base de agentes de Pandora
|
||||||
# Base config file for Pandora agents
|
# Base config file for Pandora agents
|
||||||
# Version 7.0NG.773, AIX version
|
# Version 7.0NG.773.1, AIX version
|
||||||
|
|
||||||
# General Parameters
|
# General Parameters
|
||||||
# ==================
|
# ==================
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Fichero de configuracion base de agentes de Pandora
|
# Fichero de configuracion base de agentes de Pandora
|
||||||
# Base config file for Pandora agents
|
# Base config file for Pandora agents
|
||||||
# Version 7.0NG.773
|
# Version 7.0NG.773.1
|
||||||
# FreeBSD/IPSO version
|
# FreeBSD/IPSO version
|
||||||
# Licenced under GPL licence, 2003-2007 Sancho Lerena
|
# Licenced under GPL licence, 2003-2007 Sancho Lerena
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Fichero de configuracion base de agentes de Pandora
|
# Fichero de configuracion base de agentes de Pandora
|
||||||
# Base config file for Pandora agents
|
# Base config file for Pandora agents
|
||||||
# Version 7.0NG.773, HPUX Version
|
# Version 7.0NG.773.1, HPUX Version
|
||||||
|
|
||||||
# General Parameters
|
# General Parameters
|
||||||
# ==================
|
# ==================
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Base config file for Pandora FMS agents
|
# Base config file for Pandora FMS agents
|
||||||
# Version 7.0NG.773
|
# Version 7.0NG.773.1
|
||||||
# Licensed under GPL license v2,
|
# Licensed under GPL license v2,
|
||||||
# (c) 2003-2023 Pandora FMS
|
# (c) 2003-2023 Pandora FMS
|
||||||
# please visit http://pandora.sourceforge.net
|
# please visit http://pandora.sourceforge.net
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Base config file for Pandora FMS agents
|
# Base config file for Pandora FMS agents
|
||||||
# Version 7.0NG.773
|
# Version 7.0NG.773.1
|
||||||
# Licensed under GPL license v2,
|
# Licensed under GPL license v2,
|
||||||
# (c) 2003-2023 Pandora FMS
|
# (c) 2003-2023 Pandora FMS
|
||||||
# please visit http://pandora.sourceforge.net
|
# please visit http://pandora.sourceforge.net
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Base config file for Pandora FMS agents
|
# Base config file for Pandora FMS agents
|
||||||
# Version 7.0NG.773
|
# Version 7.0NG.773.1
|
||||||
# Licensed under GPL license v2,
|
# Licensed under GPL license v2,
|
||||||
# please visit http://pandora.sourceforge.net
|
# please visit http://pandora.sourceforge.net
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Fichero de configuracion base de agentes de Pandora
|
# Fichero de configuracion base de agentes de Pandora
|
||||||
# Base config file for Pandora agents
|
# Base config file for Pandora agents
|
||||||
# Version 7.0NG.773, Solaris version
|
# Version 7.0NG.773.1, Solaris version
|
||||||
|
|
||||||
# General Parameters
|
# General Parameters
|
||||||
# ==================
|
# ==================
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Base config file for Pandora FMS agents
|
# Base config file for Pandora FMS agents
|
||||||
# Version 7.0NG.773, AIX version
|
# Version 7.0NG.773.1, AIX version
|
||||||
# Licensed under GPL license v2,
|
# Licensed under GPL license v2,
|
||||||
# Copyright (c) 2003-2023 Pandora FMS
|
# Copyright (c) 2003-2023 Pandora FMS
|
||||||
# http://www.pandorafms.com
|
# http://www.pandorafms.com
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
package: pandorafms-agent-unix
|
package: pandorafms-agent-unix
|
||||||
Version: 7.0NG.773-230821
|
Version: 7.0NG.773.1-230822
|
||||||
Architecture: all
|
Architecture: all
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Section: admin
|
Section: admin
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
pandora_version="7.0NG.773-230821"
|
pandora_version="7.0NG.773.1-230822"
|
||||||
|
|
||||||
echo "Test if you has the tools for to make the packages."
|
echo "Test if you has the tools for to make the packages."
|
||||||
whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null
|
whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null
|
||||||
|
|
|
@ -31,7 +31,7 @@ fi
|
||||||
if [ "$#" -ge 2 ]; then
|
if [ "$#" -ge 2 ]; then
|
||||||
VERSION="$2"
|
VERSION="$2"
|
||||||
else
|
else
|
||||||
VERSION="7.0NG.773"
|
VERSION="7.0NG.773.1"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Path for the generated DMG file
|
# Path for the generated DMG file
|
||||||
|
|
|
@ -19,11 +19,11 @@
|
||||||
<choice id="com.pandorafms.pandorafms_src" visible="false">
|
<choice id="com.pandorafms.pandorafms_src" visible="false">
|
||||||
<pkg-ref id="com.pandorafms.pandorafms_src"/>
|
<pkg-ref id="com.pandorafms.pandorafms_src"/>
|
||||||
</choice>
|
</choice>
|
||||||
<pkg-ref id="com.pandorafms.pandorafms_src" version="7.0NG.773" onConclusion="none">pandorafms_src.pdk</pkg-ref>
|
<pkg-ref id="com.pandorafms.pandorafms_src" version="7.0NG.773.1" onConclusion="none">pandorafms_src.pdk</pkg-ref>
|
||||||
<choice id="com.pandorafms.pandorafms_uninstall" visible="true" customLocation="/Applications">
|
<choice id="com.pandorafms.pandorafms_uninstall" visible="true" customLocation="/Applications">
|
||||||
<pkg-ref id="com.pandorafms.pandorafms_uninstall"/>
|
<pkg-ref id="com.pandorafms.pandorafms_uninstall"/>
|
||||||
</choice>
|
</choice>
|
||||||
<pkg-ref id="com.pandorafms.pandorafms_uninstall" version="7.0NG.773" onConclusion="none">pandorafms_uninstall.pdk</pkg-ref>
|
<pkg-ref id="com.pandorafms.pandorafms_uninstall" version="7.0NG.773.1" onConclusion="none">pandorafms_uninstall.pdk</pkg-ref>
|
||||||
<!-- <installation-check script="check()" />
|
<!-- <installation-check script="check()" />
|
||||||
<script>
|
<script>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
<key>CFBundleIconFile</key> <string>pandorafms.icns</string>
|
<key>CFBundleIconFile</key> <string>pandorafms.icns</string>
|
||||||
<key>CFBundleIdentifier</key> <string>com.pandorafms.pandorafms_uninstall</string>
|
<key>CFBundleIdentifier</key> <string>com.pandorafms.pandorafms_uninstall</string>
|
||||||
|
|
||||||
<key>CFBundleVersion</key> <string>7.0NG.773</string>
|
<key>CFBundleVersion</key> <string>7.0NG.773.1</string>
|
||||||
<key>CFBundleGetInfoString</key> <string>7.0NG.773 Pandora FMS on Aug 2020</string>
|
<key>CFBundleGetInfoString</key> <string>7.0NG.773.1 Pandora FMS on Aug 2020</string>
|
||||||
<key>CFBundleShortVersionString</key> <string>7.0NG.773</string>
|
<key>CFBundleShortVersionString</key> <string>7.0NG.773.1</string>
|
||||||
|
|
||||||
<key>NSPrincipalClass</key><string>NSApplication</string>
|
<key>NSPrincipalClass</key><string>NSApplication</string>
|
||||||
<key>NSMainNibFile</key><string>MainMenu</string>
|
<key>NSMainNibFile</key><string>MainMenu</string>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Base config file for Pandora FMS agents
|
# Base config file for Pandora FMS agents
|
||||||
# Version 7.0NG.773, GNU/Linux
|
# Version 7.0NG.773.1, GNU/Linux
|
||||||
# Licensed under GPL license v2,
|
# Licensed under GPL license v2,
|
||||||
# Copyright (c) 2003-2023 Pandora FMS
|
# Copyright (c) 2003-2023 Pandora FMS
|
||||||
# http://www.pandorafms.com
|
# http://www.pandorafms.com
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Base config file for Pandora FMS agents
|
# Base config file for Pandora FMS agents
|
||||||
# Version 7.0NG.773, FreeBSD Version
|
# Version 7.0NG.773.1, FreeBSD Version
|
||||||
# Licensed under GPL license v2,
|
# Licensed under GPL license v2,
|
||||||
# Copyright (c) 2003-2023 Pandora FMS
|
# Copyright (c) 2003-2023 Pandora FMS
|
||||||
# http://www.pandorafms.com
|
# http://www.pandorafms.com
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Base config file for Pandora FMS agents
|
# Base config file for Pandora FMS agents
|
||||||
# Version 7.0NG.773, HP-UX Version
|
# Version 7.0NG.773.1, HP-UX Version
|
||||||
# Licensed under GPL license v2,
|
# Licensed under GPL license v2,
|
||||||
# Copyright (c) 2003-2023 Pandora FMS
|
# Copyright (c) 2003-2023 Pandora FMS
|
||||||
# http://www.pandorafms.com
|
# http://www.pandorafms.com
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Base config file for Pandora FMS agents
|
# Base config file for Pandora FMS agents
|
||||||
# Version 7.0NG.773
|
# Version 7.0NG.773.1
|
||||||
# Licensed under GPL license v2,
|
# Licensed under GPL license v2,
|
||||||
# Copyright (c) 2004-2023 Pandora FMS
|
# Copyright (c) 2004-2023 Pandora FMS
|
||||||
# https://pandorafms.com
|
# https://pandorafms.com
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Base config file for Pandora FMS agents
|
# Base config file for Pandora FMS agents
|
||||||
# Version 7.0NG.773, GNU/Linux
|
# Version 7.0NG.773.1, GNU/Linux
|
||||||
# Licensed under GPL license v2,
|
# Licensed under GPL license v2,
|
||||||
# Copyright (c) 2003-2023 Pandora FMS
|
# Copyright (c) 2003-2023 Pandora FMS
|
||||||
# http://www.pandorafms.com
|
# http://www.pandorafms.com
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Base config file for Pandora FMS agents
|
# Base config file for Pandora FMS agents
|
||||||
# Version 7.0NG.773, NetBSD Version
|
# Version 7.0NG.773.1, NetBSD Version
|
||||||
# Licensed under GPL license v2,
|
# Licensed under GPL license v2,
|
||||||
# Copyright (c) 2003-2023 Pandora FMS
|
# Copyright (c) 2003-2023 Pandora FMS
|
||||||
# http://www.pandorafms.com
|
# http://www.pandorafms.com
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Base config file for Pandora FMS agents
|
# Base config file for Pandora FMS agents
|
||||||
# Version 7.0NG.773, Solaris Version
|
# Version 7.0NG.773.1, Solaris Version
|
||||||
# Licensed under GPL license v2,
|
# Licensed under GPL license v2,
|
||||||
# Copyright (c) 2003-2023 Pandora FMS
|
# Copyright (c) 2003-2023 Pandora FMS
|
||||||
# http://www.pandorafms.com
|
# http://www.pandorafms.com
|
||||||
|
|
|
@ -1030,8 +1030,8 @@ my $Sem = undef;
|
||||||
# Semaphore used to control the number of threads
|
# Semaphore used to control the number of threads
|
||||||
my $ThreadSem = undef;
|
my $ThreadSem = undef;
|
||||||
|
|
||||||
use constant AGENT_VERSION => '7.0NG.773';
|
use constant AGENT_VERSION => '7.0NG.773.1';
|
||||||
use constant AGENT_BUILD => '230821';
|
use constant AGENT_BUILD => '230822';
|
||||||
|
|
||||||
# Agent log default file size maximum and instances
|
# Agent log default file size maximum and instances
|
||||||
use constant DEFAULT_MAX_LOG_SIZE => 600000;
|
use constant DEFAULT_MAX_LOG_SIZE => 600000;
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
#
|
#
|
||||||
%global __os_install_post %{nil}
|
%global __os_install_post %{nil}
|
||||||
%define name pandorafms_agent_linux
|
%define name pandorafms_agent_linux
|
||||||
%define version 7.0NG.773
|
%define version 7.0NG.773.1
|
||||||
%define release 230821
|
%define release 230822
|
||||||
|
|
||||||
Summary: Pandora FMS Linux agent, PERL version
|
Summary: Pandora FMS Linux agent, PERL version
|
||||||
Name: %{name}
|
Name: %{name}
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
#
|
#
|
||||||
%global __os_install_post %{nil}
|
%global __os_install_post %{nil}
|
||||||
%define name pandorafms_agent_linux
|
%define name pandorafms_agent_linux
|
||||||
%define version 7.0NG.773
|
%define version 7.0NG.773.1
|
||||||
%define release 230821
|
%define release 230822
|
||||||
|
|
||||||
Summary: Pandora FMS Linux agent, PERL version
|
Summary: Pandora FMS Linux agent, PERL version
|
||||||
Name: %{name}
|
Name: %{name}
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
# Please see http://www.pandorafms.org. This code is licensed under GPL 2.0 license.
|
# Please see http://www.pandorafms.org. This code is licensed under GPL 2.0 license.
|
||||||
# **********************************************************************
|
# **********************************************************************
|
||||||
|
|
||||||
PI_VERSION="7.0NG.773"
|
PI_VERSION="7.0NG.773.1"
|
||||||
PI_BUILD="230821"
|
PI_BUILD="230822"
|
||||||
OS_NAME=`uname -s`
|
OS_NAME=`uname -s`
|
||||||
|
|
||||||
FORCE=0
|
FORCE=0
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Base config file for Pandora FMS Windows Agent
|
# Base config file for Pandora FMS Windows Agent
|
||||||
# (c) 2006-2023 Pandora FMS
|
# (c) 2006-2023 Pandora FMS
|
||||||
# Version 7.0NG.773
|
# Version 7.0NG.773.1
|
||||||
# This program is Free Software, you can redistribute it and/or modify it
|
# This program is Free Software, you can redistribute it and/or modify it
|
||||||
# under the terms of the GNU General Public Licence as published by the Free Software
|
# under the terms of the GNU General Public Licence as published by the Free Software
|
||||||
# Foundation; either version 2 of the Licence or any later version
|
# Foundation; either version 2 of the Licence or any later version
|
||||||
|
|
|
@ -3,7 +3,7 @@ AllowLanguageSelection
|
||||||
{Yes}
|
{Yes}
|
||||||
|
|
||||||
AppName
|
AppName
|
||||||
{Pandora FMS Windows Agent v7.0NG.773}
|
{Pandora FMS Windows Agent v7.0NG.773.1}
|
||||||
|
|
||||||
ApplicationID
|
ApplicationID
|
||||||
{17E3D2CF-CA02-406B-8A80-9D31C17BD08F}
|
{17E3D2CF-CA02-406B-8A80-9D31C17BD08F}
|
||||||
|
@ -186,7 +186,7 @@ UpgradeApplicationID
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Version
|
Version
|
||||||
{230821}
|
{230822}
|
||||||
|
|
||||||
ViewReadme
|
ViewReadme
|
||||||
{Yes}
|
{Yes}
|
||||||
|
|
|
@ -30,7 +30,7 @@ using namespace Pandora;
|
||||||
using namespace Pandora_Strutils;
|
using namespace Pandora_Strutils;
|
||||||
|
|
||||||
#define PATH_SIZE _MAX_PATH+1
|
#define PATH_SIZE _MAX_PATH+1
|
||||||
#define PANDORA_VERSION ("7.0NG.773 Build 230821")
|
#define PANDORA_VERSION ("7.0NG.773.1 Build 230822")
|
||||||
|
|
||||||
string pandora_path;
|
string pandora_path;
|
||||||
string pandora_dir;
|
string pandora_dir;
|
||||||
|
|
|
@ -11,7 +11,7 @@ BEGIN
|
||||||
VALUE "LegalCopyright", "Pandora FMS"
|
VALUE "LegalCopyright", "Pandora FMS"
|
||||||
VALUE "OriginalFilename", "PandoraAgent.exe"
|
VALUE "OriginalFilename", "PandoraAgent.exe"
|
||||||
VALUE "ProductName", "Pandora FMS Windows Agent"
|
VALUE "ProductName", "Pandora FMS Windows Agent"
|
||||||
VALUE "ProductVersion", "(7.0NG.773(Build 230821))"
|
VALUE "ProductVersion", "(7.0NG.773.1(Build 230822))"
|
||||||
VALUE "FileVersion", "1.0.0.0"
|
VALUE "FileVersion", "1.0.0.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
package: pandorafms-console
|
package: pandorafms-console
|
||||||
Version: 7.0NG.773-230821
|
Version: 7.0NG.773.1-230822
|
||||||
Architecture: all
|
Architecture: all
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Section: admin
|
Section: admin
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
pandora_version="7.0NG.773-230821"
|
pandora_version="7.0NG.773.1-230822"
|
||||||
|
|
||||||
package_pear=0
|
package_pear=0
|
||||||
package_pandora=1
|
package_pandora=1
|
||||||
|
|
|
@ -261,12 +261,27 @@ function agents_modules_load_js()
|
||||||
}
|
}
|
||||||
|
|
||||||
function select_selected () {
|
function select_selected () {
|
||||||
// $('#id_agents2 option').each(function(){
|
var f = document.forms.filter_form;
|
||||||
// if($(this).attr('selected') === 'selected'){
|
f.action = "index.php?sec=view&sec2=extensions/agents_modules";
|
||||||
// $(this).prop('selected', true);
|
$('#filter_form').submit();
|
||||||
// }
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
/* <![CDATA[ */
|
||||||
|
function export_csv() {
|
||||||
|
let group_id = $('#group_id option:selected').val();
|
||||||
|
let module_group_id = $('#modulegroup option:selected').val();
|
||||||
|
let agent_id = $('#id_agents2 option:selected').map((_, e) => e.value).get();
|
||||||
|
let module_id = $('#module option:selected').map((_, e) => e.value).get();
|
||||||
|
|
||||||
|
let filters_array = {group_id: group_id, module_group_id:module_group_id, agent_id:agent_id, module_id:module_id}
|
||||||
|
let jsonFilters = JSON.stringify(filters_array)
|
||||||
|
let filters = window.btoa(jsonFilters)
|
||||||
|
var f = document.forms.filter_form;
|
||||||
|
|
||||||
|
blockResubmit($(this));
|
||||||
|
f.action = "extensions/agents_modules_csv.php?get_agents_module_csv=1&filters="+filters;
|
||||||
|
$("#filter_form").submit();
|
||||||
|
}
|
||||||
|
/* ]]> */
|
||||||
</script>
|
</script>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
|
@ -653,7 +668,7 @@ function mainAgentsModules()
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($config['pure'] != 1) {
|
if ($config['pure'] != 1) {
|
||||||
$show_filters = '<form method="post" action="index.php?sec=view&sec2=extensions/agents_modules" class="w100p">';
|
$show_filters = '<form id="filter_form" method="post" action="index.php?sec=view&sec2=extensions/agents_modules" class="w100p">';
|
||||||
$show_filters .= '<table class="filter-table-adv w100p no-border" cellpadding="4" cellspacing="4">';
|
$show_filters .= '<table class="filter-table-adv w100p no-border" cellpadding="4" cellspacing="4">';
|
||||||
$show_filters .= '<tr>';
|
$show_filters .= '<tr>';
|
||||||
$show_filters .= '<td width="33%">'.$filter_type.'</td>';
|
$show_filters .= '<td width="33%">'.$filter_type.'</td>';
|
||||||
|
@ -679,6 +694,13 @@ function mainAgentsModules()
|
||||||
'onclick' => 'select_selected()',
|
'onclick' => 'select_selected()',
|
||||||
],
|
],
|
||||||
true
|
true
|
||||||
|
).html_print_button(
|
||||||
|
__('Export to CSV'),
|
||||||
|
'srcbutton_csv',
|
||||||
|
false,
|
||||||
|
'export_csv()',
|
||||||
|
['class' => 'secondary mini'],
|
||||||
|
true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
true
|
true
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Export data.
|
||||||
|
*
|
||||||
|
* @category Tools
|
||||||
|
* @package Pandora FMS
|
||||||
|
* @subpackage Operation
|
||||||
|
* @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.
|
||||||
|
* ============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
require_once $config['homedir'].'/include/config.php';
|
||||||
|
require_once $config['homedir'].'/include/functions_reporting.php';
|
||||||
|
require_once $config['homedir'].'/include/functions_modules.php';
|
||||||
|
*/
|
||||||
|
require_once '../include/config.php';
|
||||||
|
require_once '../include/functions_agents.php';
|
||||||
|
require_once '../include/functions_reporting.php';
|
||||||
|
require_once '../include/functions_modules.php';
|
||||||
|
require_once '../include/functions_users.php';
|
||||||
|
|
||||||
|
global $config;
|
||||||
|
|
||||||
|
check_login();
|
||||||
|
|
||||||
|
// ACL Check.
|
||||||
|
if (! check_acl($config['id_user'], 0, 'AR')) {
|
||||||
|
db_pandora_audit(
|
||||||
|
AUDIT_LOG_ACL_VIOLATION,
|
||||||
|
'Trying to access Agent view (Grouped)'
|
||||||
|
);
|
||||||
|
include 'general/noaccess.php';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$get_agents_module_csv = get_parameter('get_agents_module_csv', 0);
|
||||||
|
|
||||||
|
|
||||||
|
if ($get_agents_module_csv === '1') {
|
||||||
|
// ***************************************************
|
||||||
|
// Header output
|
||||||
|
// ***************************************************
|
||||||
|
$config['ignore_callback'] = true;
|
||||||
|
while (@ob_end_clean()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
$filename = 'agents_module_view_'.date('Ymd').'-'.date('His');
|
||||||
|
|
||||||
|
// Set cookie for download control.
|
||||||
|
setDownloadCookieToken();
|
||||||
|
|
||||||
|
header('Content-Type: text/csv');
|
||||||
|
header('Content-Disposition: attachment; filename="'.$filename.'.csv"');
|
||||||
|
// ***************************************************
|
||||||
|
// Data processing
|
||||||
|
// ***************************************************
|
||||||
|
echo pack('C*', 0xEF, 0xBB, 0xBF);
|
||||||
|
|
||||||
|
$json_filters = get_parameter('filters', '');
|
||||||
|
|
||||||
|
$filters = json_decode(
|
||||||
|
base64_decode(
|
||||||
|
get_parameter('filters', '')
|
||||||
|
),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
$results = export_agents_module_csv($filters);
|
||||||
|
|
||||||
|
$divider = $config['csv_divider'];
|
||||||
|
$dataend = PHP_EOL;
|
||||||
|
|
||||||
|
$header_fields = [
|
||||||
|
__('Agent'),
|
||||||
|
__('Module'),
|
||||||
|
__('Data'),
|
||||||
|
];
|
||||||
|
|
||||||
|
$out_csv = '';
|
||||||
|
foreach ($header_fields as $key => $value) {
|
||||||
|
$out_csv .= $value.$divider;
|
||||||
|
}
|
||||||
|
|
||||||
|
$out_csv .= "\n";
|
||||||
|
|
||||||
|
foreach ($results as $result) {
|
||||||
|
foreach ($result as $key => $value) {
|
||||||
|
$out_csv .= io_safe_output($value).$divider;
|
||||||
|
}
|
||||||
|
|
||||||
|
$out_csv .= "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo io_safe_output($out_csv);
|
||||||
|
|
||||||
|
exit;
|
||||||
|
}
|
|
@ -532,6 +532,54 @@ echo sprintf('<div id="header_table" class="header_table_%s">', $menuTypeClass);
|
||||||
element.style.display = "none"
|
element.style.display = "none"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function notifications_clean_all() {
|
||||||
|
let wrapper_inner = document.getElementById('notification-wrapper-inner');
|
||||||
|
while (wrapper_inner.firstChild) {
|
||||||
|
wrapper_inner.removeChild(wrapper_inner.firstChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mark_all_notification_as_read() {
|
||||||
|
jQuery.post ("ajax.php",
|
||||||
|
{
|
||||||
|
"page" : "godmode/setup/setup_notifications",
|
||||||
|
"mark_all_notification_as_read" : 1
|
||||||
|
},
|
||||||
|
function (data, status) {
|
||||||
|
notifications_clean_all();
|
||||||
|
location.reload();
|
||||||
|
},
|
||||||
|
"json"
|
||||||
|
)
|
||||||
|
.fail(function(xhr, textStatus, errorThrown){
|
||||||
|
console.error(
|
||||||
|
"Failed to mark al notification as read. Error: ",
|
||||||
|
xhr.responseText
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function filter_notification() {
|
||||||
|
let notification_type = '';
|
||||||
|
$('.notification-item').hide();
|
||||||
|
$(".checkbox_filter_notifications:checkbox:checked").each(function() {
|
||||||
|
notification_type = $(this).val();
|
||||||
|
console.log(notification_type);
|
||||||
|
$('.notification-item[value='+notification_type+']').show();
|
||||||
|
if (notification_type == 'All'){
|
||||||
|
$('.notification-item').show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (notification_type == 'All'){
|
||||||
|
$('.notification-item').show();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notification_type == ''){
|
||||||
|
$('.notification-item').hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function click_on_notification_toast(event) {
|
function click_on_notification_toast(event) {
|
||||||
var match = /notification-(.*)-id-([0-9]+)/.exec(event.target.id);
|
var match = /notification-(.*)-id-([0-9]+)/.exec(event.target.id);
|
||||||
if (!match) {
|
if (!match) {
|
||||||
|
|
|
@ -187,6 +187,27 @@ if (get_parameter('mark_notification_as_read', 0)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (get_parameter('mark_all_notification_as_read', 0)) {
|
||||||
|
$unread_messages = db_get_all_rows_sql('SELECT id_mensaje FROM tnotification_user WHERE utimestamp_read is NULL');
|
||||||
|
|
||||||
|
if ($unread_messages !== false) {
|
||||||
|
foreach ($unread_messages as $messages) {
|
||||||
|
messages_process_read($messages['id_mensaje']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = true;
|
||||||
|
} else {
|
||||||
|
$result = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is new messages, get the info.
|
||||||
|
echo json_encode(
|
||||||
|
['result' => $result]
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (get_parameter('get_notifications_dropdown', 0)) {
|
if (get_parameter('get_notifications_dropdown', 0)) {
|
||||||
echo notifications_print_dropdown();
|
echo notifications_print_dropdown();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -169,6 +169,7 @@ class ConsoleSupervisor
|
||||||
* NOTIF.PHP.DISABLE_FUNCTIONS
|
* NOTIF.PHP.DISABLE_FUNCTIONS
|
||||||
* NOTIF.PHP.CHROMIUM
|
* NOTIF.PHP.CHROMIUM
|
||||||
* NOTIF.PHP.VERSION
|
* NOTIF.PHP.VERSION
|
||||||
|
* NOTIF.PHP.VERSION.SUPPORT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$this->checkPHPSettings();
|
$this->checkPHPSettings();
|
||||||
|
@ -383,6 +384,7 @@ class ConsoleSupervisor
|
||||||
* NOTIF.PHP.DISABLE_FUNCTIONS
|
* NOTIF.PHP.DISABLE_FUNCTIONS
|
||||||
* NOTIF.PHP.CHROMIUM
|
* NOTIF.PHP.CHROMIUM
|
||||||
* NOTIF.PHP.VERSION
|
* NOTIF.PHP.VERSION
|
||||||
|
* NOTIF.PHP.VERSION.SUPPORT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$this->checkPHPSettings();
|
$this->checkPHPSettings();
|
||||||
|
@ -874,6 +876,7 @@ class ConsoleSupervisor
|
||||||
case 'NOTIF.PHP.DISABLE_FUNCTIONS':
|
case 'NOTIF.PHP.DISABLE_FUNCTIONS':
|
||||||
case 'NOTIF.PHP.CHROMIUM':
|
case 'NOTIF.PHP.CHROMIUM':
|
||||||
case 'NOTIF.PHP.VERSION':
|
case 'NOTIF.PHP.VERSION':
|
||||||
|
case 'NOTIF.PHP.VERSION.SUPPORT':
|
||||||
case 'NOTIF.HISTORYDB':
|
case 'NOTIF.HISTORYDB':
|
||||||
case 'NOTIF.PANDORADB':
|
case 'NOTIF.PANDORADB':
|
||||||
case 'NOTIF.PANDORADB.HISTORICAL':
|
case 'NOTIF.PANDORADB.HISTORICAL':
|
||||||
|
@ -1830,14 +1833,14 @@ class ConsoleSupervisor
|
||||||
$url = 'https://www.php.net/supported-versions.php';
|
$url = 'https://www.php.net/supported-versions.php';
|
||||||
$this->notify(
|
$this->notify(
|
||||||
[
|
[
|
||||||
'type' => 'NOTIF.PHP.VERSION',
|
'type' => 'NOTIF.PHP.VERSION.SUPPORT',
|
||||||
'title' => __('PHP UPDATE REQUIRED'),
|
'title' => __('PHP UPDATE REQUIRED'),
|
||||||
'message' => __('You should update your PHP version because it will be out of official support').'<br>'.__('Current PHP version: ').PHP_VERSION,
|
'message' => __('You should update your PHP version because it will be out of official support').'<br>'.__('Current PHP version: ').PHP_VERSION,
|
||||||
'url' => $url,
|
'url' => $url,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$this->cleanNotifications('NOTIF.PHP.VERSION');
|
$this->cleanNotifications('NOTIF.PHP.VERSION.SUPPORT');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
/**
|
/**
|
||||||
* Pandora build version and version
|
* Pandora build version and version
|
||||||
*/
|
*/
|
||||||
$build_version = 'PC230821';
|
$build_version = 'PC230822';
|
||||||
$pandora_version = 'v7.0NG.773';
|
$pandora_version = 'v7.0NG.773.1';
|
||||||
|
|
||||||
// Do not overwrite default timezone set if defined.
|
// Do not overwrite default timezone set if defined.
|
||||||
$script_tz = @date_default_timezone_get();
|
$script_tz = @date_default_timezone_get();
|
||||||
|
|
|
@ -2904,6 +2904,8 @@ function html_print_anchor(
|
||||||
|
|
||||||
$output .= '>';
|
$output .= '>';
|
||||||
|
|
||||||
|
$output .= (isset($options['text']) === true) ? $options['text'] : '';
|
||||||
|
|
||||||
$output .= (isset($options['content']) === true) ? io_safe_input_html($options['content']) : '';
|
$output .= (isset($options['content']) === true) ? io_safe_input_html($options['content']) : '';
|
||||||
|
|
||||||
$output .= '</a>';
|
$output .= '</a>';
|
||||||
|
@ -7118,6 +7120,7 @@ function html_print_menu_button(array $options, bool $return=false)
|
||||||
'class' => ($options['class'] ?? ''),
|
'class' => ($options['class'] ?? ''),
|
||||||
'style' => ($options['style'] ?? ''),
|
'style' => ($options['style'] ?? ''),
|
||||||
'onClick' => ($options['onClick'] ?? ''),
|
'onClick' => ($options['onClick'] ?? ''),
|
||||||
|
'text' => ($options['text'] ?? ''),
|
||||||
'content' => $content,
|
'content' => $content,
|
||||||
],
|
],
|
||||||
$return
|
$return
|
||||||
|
|
|
@ -4687,3 +4687,75 @@ function get_agent_module_childs(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function for export a csv file from Agents/Module view
|
||||||
|
*
|
||||||
|
* @param array $filters Data from agents/module filter.
|
||||||
|
*
|
||||||
|
* @return array Returns the data that will be saved in the csv file
|
||||||
|
*/
|
||||||
|
function export_agents_module_csv($filters)
|
||||||
|
{
|
||||||
|
$query_filter = '';
|
||||||
|
foreach ($filters as $key => $filter) {
|
||||||
|
switch ($key) {
|
||||||
|
case 'group_id':
|
||||||
|
if ($filter != 0) {
|
||||||
|
$query_filter .= ' AND ta.id_grupo = '.$filter.' ';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'module_group_id':
|
||||||
|
if ($filter != 0) {
|
||||||
|
$query_filter .= ' AND tam.id_module_group = '.$filter.' ';
|
||||||
|
;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'agent_id':
|
||||||
|
if (count($filter) > 0) {
|
||||||
|
$agent_filter = '('.implode(', ', $filter).')';
|
||||||
|
$query_filter .= ' AND ta.id_agente IN '.$agent_filter.' ';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'module_id':
|
||||||
|
if (count($filter) > 0) {
|
||||||
|
if (is_numeric($filter[0]) === false) {
|
||||||
|
foreach ($filter as $key => $module) {
|
||||||
|
$filter[$key] = io_safe_input($module);
|
||||||
|
}
|
||||||
|
|
||||||
|
$module_filter = '(\''.implode("', '", $filter).'\')';
|
||||||
|
$query_filter .= ' AND tam.nombre IN '.$module_filter.' ';
|
||||||
|
} else {
|
||||||
|
$module_filter = '('.implode(', ', $filter).')';
|
||||||
|
$query_filter .= ' AND tam.id_tipo_modulo IN '.$module_filter.' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Nothing to do
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query fields result.
|
||||||
|
$query = sprintf(
|
||||||
|
'SELECT ta.alias as agent, tam.nombre as module, tae.datos as data
|
||||||
|
FROM tagente_modulo as tam
|
||||||
|
INNER JOIN tagente as ta ON tam.id_agente = ta.id_agente
|
||||||
|
INNER JOIN tagente_estado as tae ON tam.id_agente_modulo = tae.id_agente_modulo
|
||||||
|
WHERE ta.disabled = 0
|
||||||
|
%s
|
||||||
|
',
|
||||||
|
$query_filter
|
||||||
|
);
|
||||||
|
|
||||||
|
$result = db_get_all_rows_sql($query);
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
|
@ -136,6 +136,7 @@ function notifications_get_subtypes(?string $source=null)
|
||||||
'NOTIF.PHP.DISABLE_FUNCTIONS',
|
'NOTIF.PHP.DISABLE_FUNCTIONS',
|
||||||
'NOTIF.PHP.CHROMIUM',
|
'NOTIF.PHP.CHROMIUM',
|
||||||
'NOTIF.PHP.VERSION',
|
'NOTIF.PHP.VERSION',
|
||||||
|
'NOTIF.PHP.VERSION.SUPPORT',
|
||||||
'NOTIF.HISTORYDB',
|
'NOTIF.HISTORYDB',
|
||||||
'NOTIF.PANDORADB',
|
'NOTIF.PANDORADB',
|
||||||
'NOTIF.PANDORADB.HISTORICAL',
|
'NOTIF.PANDORADB.HISTORICAL',
|
||||||
|
@ -1010,6 +1011,106 @@ function notifications_print_user_switch($source, $user, $label)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates an HTML of notification filter types.
|
||||||
|
*
|
||||||
|
* @return string HTML filter notification.
|
||||||
|
*/
|
||||||
|
function notification_filter()
|
||||||
|
{
|
||||||
|
$types_list[] = 'All';
|
||||||
|
$notification_types = db_get_all_rows_sql('SELECT DISTINCT tm.subtype FROM tmensajes as tm INNER JOIN tnotification_user as tnu ON tm.id_mensaje = tnu.id_mensaje WHERE tnu.utimestamp_read IS NULL');
|
||||||
|
if ($notification_types !== false) {
|
||||||
|
foreach ($notification_types as $notification_type) {
|
||||||
|
$type = explode('.', $notification_type['subtype'])[1];
|
||||||
|
$types_list[] = $type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$types_list = array_unique($types_list);
|
||||||
|
$notification_filter = "<ul id='menu-filter_notification'>";
|
||||||
|
|
||||||
|
$notification_filter .= "<li>
|
||||||
|
<input type='checkbox' name='filter_menu' id='filter_menu'>
|
||||||
|
<label for='filter_menu' id='filter_menu_label'>".__('Filter').'</label>';
|
||||||
|
|
||||||
|
$notification_filter .= "<ul class='sublevel-filter_notification'>";
|
||||||
|
foreach ($types_list as $type) {
|
||||||
|
if ($type === 'All') {
|
||||||
|
$checked = 'checked';
|
||||||
|
} else {
|
||||||
|
$checked = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($type) {
|
||||||
|
case 'HISTORYDB':
|
||||||
|
$type_name = 'HISTORY DB';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'PANDORADB':
|
||||||
|
$type_name = 'PANDORA DB';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'UPDATEMANAGER':
|
||||||
|
$type_name = 'UPDATE MANAGER';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'ALLOWOVERRIDE':
|
||||||
|
$type_name = 'ALLOW OVERRIDE';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'DISCOVERYTASK':
|
||||||
|
$type_name = 'DISCOVERY TASK';
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
$type_name = $type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$notification_filter .= "<li><div class='item-filter'>
|
||||||
|
<input type='checkbox'
|
||||||
|
class='checkbox_filter_notifications'
|
||||||
|
value=".$type."
|
||||||
|
name='filter_".$type."'
|
||||||
|
".$checked."
|
||||||
|
id='filter_".$type."'>
|
||||||
|
<label for='filter_".$type."'>".$type_name.'</label>
|
||||||
|
</div>
|
||||||
|
</li>';
|
||||||
|
}
|
||||||
|
|
||||||
|
$notification_filter .= "<li><div class='item-filter'>";
|
||||||
|
$notification_filter .= html_print_div(
|
||||||
|
[
|
||||||
|
'class' => 'action-buttons w100p',
|
||||||
|
'content' => html_print_submit_button(
|
||||||
|
__('Filter'),
|
||||||
|
'btn_submit',
|
||||||
|
false,
|
||||||
|
[
|
||||||
|
'class' => 'mini sub filter',
|
||||||
|
'icon' => 'search mini',
|
||||||
|
'onClick' => 'filter_notification()',
|
||||||
|
],
|
||||||
|
true
|
||||||
|
),
|
||||||
|
],
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
$notification_filter .= '</div>
|
||||||
|
</li>';
|
||||||
|
|
||||||
|
$notification_filter .= '</ul>';
|
||||||
|
|
||||||
|
$notification_filter .= '</li>';
|
||||||
|
|
||||||
|
$notification_filter .= '</ul>';
|
||||||
|
return $notification_filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates the dropdown notifications menu.
|
* Generates the dropdown notifications menu.
|
||||||
*
|
*
|
||||||
|
@ -1022,9 +1123,24 @@ function notifications_print_dropdown()
|
||||||
$mess = [];
|
$mess = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$notification_menu = html_print_menu_button(
|
||||||
|
[
|
||||||
|
'href' => 'javascript:',
|
||||||
|
'class' => 'notification_menu_actions',
|
||||||
|
'text' => __('Mark all as read'),
|
||||||
|
'onClick' => 'mark_all_notification_as_read()',
|
||||||
|
],
|
||||||
|
true
|
||||||
|
);
|
||||||
|
$notification_filter = notification_filter();
|
||||||
|
|
||||||
return sprintf(
|
return sprintf(
|
||||||
"<div id='notification-wrapper'>
|
"<div id='notification-wrapper'>
|
||||||
<div id='notification-wrapper-inner'>
|
<div id='notification-wrapper-inner'>
|
||||||
|
<div class='notificaion_menu_container'>
|
||||||
|
<div class='menu_tab filter_notification'>%s</div>
|
||||||
|
<div class='menu_tab notification_menu'>%s</div>
|
||||||
|
</div>
|
||||||
%s
|
%s
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1034,6 +1150,8 @@ function notifications_print_dropdown()
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
",
|
",
|
||||||
|
$notification_filter,
|
||||||
|
$notification_menu,
|
||||||
array_reduce(
|
array_reduce(
|
||||||
$mess,
|
$mess,
|
||||||
function ($carry, $message) {
|
function ($carry, $message) {
|
||||||
|
@ -1093,6 +1211,8 @@ function notifications_print_dropdown_element($message_info)
|
||||||
$message_info['subject'] = io_safe_input($img);
|
$message_info['subject'] = io_safe_input($img);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$type = explode('.', $message_info['subtype'])[1];
|
||||||
|
|
||||||
if (strlen($body_preview) >= 170) {
|
if (strlen($body_preview) >= 170) {
|
||||||
$body_preview = substr($body_preview, 0, 150);
|
$body_preview = substr($body_preview, 0, 150);
|
||||||
$body_preview .= __('. Read More...');
|
$body_preview .= __('. Read More...');
|
||||||
|
@ -1103,6 +1223,7 @@ function notifications_print_dropdown_element($message_info)
|
||||||
class='notification-item'
|
class='notification-item'
|
||||||
onclick='%s'
|
onclick='%s'
|
||||||
id='notification-item-id-%s'
|
id='notification-item-id-%s'
|
||||||
|
value='%s'
|
||||||
href='%s'
|
href='%s'
|
||||||
target='%s'
|
target='%s'
|
||||||
>
|
>
|
||||||
|
@ -1116,8 +1237,9 @@ function notifications_print_dropdown_element($message_info)
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</a>",
|
</a>",
|
||||||
$action.';click_on_notification_toast(event)',
|
$action.'; click_on_notification_toast(event)',
|
||||||
$message_info['id_mensaje'],
|
$message_info['id_mensaje'],
|
||||||
|
$type,
|
||||||
messages_get_url($message_info['id_mensaje']),
|
messages_get_url($message_info['id_mensaje']),
|
||||||
$target,
|
$target,
|
||||||
html_print_image('images/info.svg', true, ['style' => 'height: 40px;margin-left: -20px;margin-top: -40px;']),
|
html_print_image('images/info.svg', true, ['style' => 'height: 40px;margin-left: -20px;margin-top: -40px;']),
|
||||||
|
|
|
@ -12395,6 +12395,59 @@ form.cfv_status_agent input:checked + label:before {
|
||||||
content: "✓ ";
|
content: "✓ ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.notificaion_menu_container {
|
||||||
|
display: flex;
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-left: 15px;
|
||||||
|
}
|
||||||
|
.notification_menu {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter_notification {
|
||||||
|
width: auto;
|
||||||
|
min-width: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#menu-filter_notification * {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
#menu-filter_notification li {
|
||||||
|
line-height: 180%;
|
||||||
|
}
|
||||||
|
#menu-filter_notification input[name="filter_menu"] {
|
||||||
|
position: absolute;
|
||||||
|
left: -1000em;
|
||||||
|
}
|
||||||
|
#menu-filter_notification label[id="filter_menu_label"]:before {
|
||||||
|
content: "\025b8";
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
#menu-filter_notification
|
||||||
|
input[name="filter_menu"]:checked
|
||||||
|
~ label[id="filter_menu_label"]:before {
|
||||||
|
content: "\025be";
|
||||||
|
}
|
||||||
|
#menu-filter_notification .sublevel-filter_notification {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#menu-filter_notification input[name="filter_menu"]:checked ~ ul {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-filter > label {
|
||||||
|
display: inline-block;
|
||||||
|
width: auto;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-filter > input[type="checkbox"] {
|
||||||
|
display: inline-block;
|
||||||
|
width: 40px;
|
||||||
|
height: 100%;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
/* --- Custom fields view --- */
|
/* --- Custom fields view --- */
|
||||||
.custom_fields_view_layout {
|
.custom_fields_view_layout {
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
|
|
|
@ -130,8 +130,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div style='padding-bottom: 50px'>
|
<div style='padding-bottom: 50px'>
|
||||||
<?php
|
<?php
|
||||||
$version = '7.0NG.773';
|
$version = '7.0NG.773.1';
|
||||||
$build = '230821';
|
$build = '230822';
|
||||||
$banner = "v$version Build $build";
|
$banner = "v$version Build $build";
|
||||||
error_reporting(0);
|
error_reporting(0);
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
# Pandora FMS Console
|
# Pandora FMS Console
|
||||||
#
|
#
|
||||||
%define name pandorafms_console
|
%define name pandorafms_console
|
||||||
%define version 7.0NG.773
|
%define version 7.0NG.773.1
|
||||||
%define release 230821
|
%define release 230822
|
||||||
|
|
||||||
# User and Group under which Apache is running
|
# User and Group under which Apache is running
|
||||||
%define httpd_name httpd
|
%define httpd_name httpd
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
# Pandora FMS Console
|
# Pandora FMS Console
|
||||||
#
|
#
|
||||||
%define name pandorafms_console
|
%define name pandorafms_console
|
||||||
%define version 7.0NG.773
|
%define version 7.0NG.773.1
|
||||||
%define release 230821
|
%define release 230822
|
||||||
|
|
||||||
# User and Group under which Apache is running
|
# User and Group under which Apache is running
|
||||||
%define httpd_name httpd
|
%define httpd_name httpd
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
# Pandora FMS Console
|
# Pandora FMS Console
|
||||||
#
|
#
|
||||||
%define name pandorafms_console
|
%define name pandorafms_console
|
||||||
%define version 7.0NG.773
|
%define version 7.0NG.773.1
|
||||||
%define release 230821
|
%define release 230822
|
||||||
%define httpd_name httpd
|
%define httpd_name httpd
|
||||||
# User and Group under which Apache is running
|
# User and Group under which Apache is running
|
||||||
%define httpd_name apache2
|
%define httpd_name apache2
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
# This code is licensed under GPL 2.0 license.
|
# This code is licensed under GPL 2.0 license.
|
||||||
# **********************************************************************
|
# **********************************************************************
|
||||||
|
|
||||||
PI_VERSION="7.0NG.773"
|
PI_VERSION="7.0NG.773.1"
|
||||||
FORCE=0
|
FORCE=0
|
||||||
DESTDIR=""
|
DESTDIR=""
|
||||||
LOG_TIMESTAMP=`date +"%Y/%m/%d %H:%M:%S"`
|
LOG_TIMESTAMP=`date +"%Y/%m/%d %H:%M:%S"`
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
package: pandorafms-server
|
package: pandorafms-server
|
||||||
Version: 7.0NG.773-230821
|
Version: 7.0NG.773.1-230822
|
||||||
Architecture: all
|
Architecture: all
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Section: admin
|
Section: admin
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
pandora_version="7.0NG.773-230821"
|
pandora_version="7.0NG.773.1-230822"
|
||||||
|
|
||||||
package_cpan=0
|
package_cpan=0
|
||||||
package_pandora=1
|
package_pandora=1
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#############################################################################
|
#############################################################################
|
||||||
# Pandora FMS Server Parameters
|
# Pandora FMS Server Parameters
|
||||||
# Pandora FMS, the Flexible Monitoring System.
|
# Pandora FMS, the Flexible Monitoring System.
|
||||||
# Version 7.0NG.773
|
# Version 7.0NG.773.1
|
||||||
# Licensed under GPL license v2,
|
# Licensed under GPL license v2,
|
||||||
# (c) 2003-2023 Pandora FMS
|
# (c) 2003-2023 Pandora FMS
|
||||||
# http://www.pandorafms.com
|
# http://www.pandorafms.com
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
# Python: module plugintools for PandoraFMS Developers
|
||||||
|
|
||||||
|
pandoraPluginTools is a library that aims to help the creation of scripts and their integration in Pandora FMS.
|
||||||
|
|
||||||
|
[PluginTools Reference Documentation](https://pandorafms.com/guides/public/books/plugintools)
|
||||||
|
|
||||||
|
The package includes the following modules. Each one has different functions that facilitate and automate the data integration in Pandora FMS:
|
||||||
|
|
||||||
|
**general**
|
||||||
|
Module containing general purpose functions, useful in the creation of plugins for PandoraFMS.
|
||||||
|
|
||||||
|
**threads**
|
||||||
|
Module containing threading purpose functions, useful to run parallel functions.
|
||||||
|
|
||||||
|
**agents**
|
||||||
|
Module that contains functions oriented to the creation of Pandora FMS agents
|
||||||
|
|
||||||
|
**modules**
|
||||||
|
Module that contains functions oriented to the creation of Pandora FMS modules.
|
||||||
|
|
||||||
|
**transfer**
|
||||||
|
Module containing functions oriented to file transfer and data sending to Pandora FMS server.
|
||||||
|
|
||||||
|
**discovery**
|
||||||
|
Module containing functions oriented to the creation of Pandora FMS discovery plugins.
|
||||||
|
|
||||||
|
**http**
|
||||||
|
Module containing functions oriented to HTTP API calls.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```python
|
||||||
|
import pandoraPluginTools as ppt
|
||||||
|
|
||||||
|
## Define agent
|
||||||
|
server_name = "WIN-SERV"
|
||||||
|
|
||||||
|
agent=ppt.init_agent({
|
||||||
|
"agent_name" : ppt.generate_md5(server_name),
|
||||||
|
"agent_alias" : server_name,
|
||||||
|
"description" : "Default Windows server"
|
||||||
|
})
|
||||||
|
|
||||||
|
## Define modules
|
||||||
|
modules=[]
|
||||||
|
|
||||||
|
data = 10
|
||||||
|
modules.append({
|
||||||
|
"name" : "CPU usage",
|
||||||
|
"type" : "generic_data",
|
||||||
|
"value": data,
|
||||||
|
"desc" : "Percentage of CPU utilization",
|
||||||
|
"unit" : "%"
|
||||||
|
})
|
||||||
|
|
||||||
|
## Generate and transfer XML
|
||||||
|
xml_content = ppt.print_agent(agent, modules)
|
||||||
|
xml_file = ppt.write_xml(xml_content, agent["agent_name"])
|
||||||
|
ppt.transfer_xml(
|
||||||
|
xml_file,
|
||||||
|
transfer_mode="tentacle",
|
||||||
|
tentacle_ip="192.168.1.20",
|
||||||
|
tentacle_port="41121",
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
The package has the following dependencies:
|
||||||
|
|
||||||
|
- Hashlib
|
||||||
|
- datetime.datetime
|
||||||
|
- hashlib
|
||||||
|
- json
|
||||||
|
- os
|
||||||
|
- print_agent
|
||||||
|
- print_log_module
|
||||||
|
- print_module
|
||||||
|
- queue.Queue
|
||||||
|
- requests.auth.HTTPBasicAuth
|
||||||
|
- requests.auth.HTTPDigestAuth
|
||||||
|
- requests.sessions.Session
|
||||||
|
- requests_ntlm.HttpNtlmAuth
|
||||||
|
- shutil
|
||||||
|
- subprocess.Popen
|
||||||
|
- sys
|
||||||
|
- threading.Thread
|
|
@ -0,0 +1,10 @@
|
||||||
|
from .general import *
|
||||||
|
from .output import *
|
||||||
|
from .encryption import *
|
||||||
|
from .threads import *
|
||||||
|
from .agents import *
|
||||||
|
from .modules import *
|
||||||
|
from .transfer import *
|
||||||
|
from .discovery import *
|
||||||
|
from .http import *
|
||||||
|
from .snmp import *
|
|
@ -0,0 +1,409 @@
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
####
|
||||||
|
# Define global variables dict, used in functions as default values.
|
||||||
|
# Its values can be changed.
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
_GLOBAL_VARIABLES = {
|
||||||
|
'agents_group_name' : '',
|
||||||
|
'interval' : 300
|
||||||
|
}
|
||||||
|
|
||||||
|
####
|
||||||
|
# Define some global variables
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
_WINDOWS = os.name == "nt" or os.name == "ce"
|
||||||
|
_LINUX = sys.platform.startswith("linux")
|
||||||
|
_MACOS = sys.platform.startswith("darwin")
|
||||||
|
_OSX = _MACOS # deprecated alias
|
||||||
|
_FREEBSD = sys.platform.startswith("freebsd")
|
||||||
|
_OPENBSD = sys.platform.startswith("openbsd")
|
||||||
|
_NETBSD = sys.platform.startswith("netbsd")
|
||||||
|
_BSD = _FREEBSD or _OPENBSD or _NETBSD
|
||||||
|
_SUNOS = sys.platform.startswith(("sunos", "solaris"))
|
||||||
|
_AIX = sys.platform.startswith("aix")
|
||||||
|
|
||||||
|
####
|
||||||
|
# Internal: Alias for output.print_debug function
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def _print_debug(
|
||||||
|
var = "",
|
||||||
|
print_errors: bool = False
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Prints any list, dict, string, float or integer as a json
|
||||||
|
"""
|
||||||
|
from .output import print_debug
|
||||||
|
print_debug(var, print_errors)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Set a global variable with the specified name and assigns a value to it.
|
||||||
|
#########################################################################################
|
||||||
|
def set_global_variable(
|
||||||
|
variable_name: str = "",
|
||||||
|
value = None
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Sets the value of a global variable in the '_GLOBAL_VARIABLES' dictionary.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
variable_name (str): Name of the variable to set.
|
||||||
|
value (any): Value to assign to the variable.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
from .general import set_dict_key_value
|
||||||
|
|
||||||
|
set_dict_key_value(_GLOBAL_VARIABLES, variable_name, value)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Get a global variable with the specified name.
|
||||||
|
#########################################################################################
|
||||||
|
def get_global_variable(
|
||||||
|
variable_name: str = ""
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Gets the value of a global variable in the '_GLOBAL_VARIABLES' dictionary.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
variable_name (str): Name of the variable to set.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
from .general import get_dict_key_value
|
||||||
|
|
||||||
|
get_dict_key_value(_GLOBAL_VARIABLES, variable_name)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Agent class
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
class Agent:
|
||||||
|
"""
|
||||||
|
Basic agent class. Requires agent parameters (config {dictionary})
|
||||||
|
and module definition (modules_def [list of dictionaries])
|
||||||
|
"""
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
config: dict = {},
|
||||||
|
modules_def: list = [],
|
||||||
|
log_modules_def: list = []
|
||||||
|
):
|
||||||
|
|
||||||
|
self.modules_def = []
|
||||||
|
self.added_modules = []
|
||||||
|
self.log_modules_def = []
|
||||||
|
|
||||||
|
self.config = init_agent(config)
|
||||||
|
|
||||||
|
for module in modules_def:
|
||||||
|
self.add_module(module)
|
||||||
|
|
||||||
|
for log_module in log_modules_def:
|
||||||
|
self.add_log_module(log_module)
|
||||||
|
|
||||||
|
def update_config(
|
||||||
|
self,
|
||||||
|
config: dict = {}
|
||||||
|
)-> None:
|
||||||
|
'''
|
||||||
|
Update the configuration settings with new values.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config (dict): A dictionary containing configuration keys and their new values.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
'''
|
||||||
|
for key, value in config.items():
|
||||||
|
if key in self.config:
|
||||||
|
self.config[key] = value
|
||||||
|
|
||||||
|
def get_config(
|
||||||
|
self
|
||||||
|
) -> dict:
|
||||||
|
'''
|
||||||
|
Retrieve the current configuration settings.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: A dictionary containing the current configuration settings.
|
||||||
|
'''
|
||||||
|
return self.config
|
||||||
|
|
||||||
|
def add_module(
|
||||||
|
self,
|
||||||
|
module: dict = {}
|
||||||
|
)-> None:
|
||||||
|
'''
|
||||||
|
Add a new module to the list of modules.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
module (dict): A dictionary containing module information.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
'''
|
||||||
|
from .general import generate_md5
|
||||||
|
from .modules import init_module
|
||||||
|
|
||||||
|
if "name" in module and type(module["name"]) == str and len(module["name"].strip()) > 0:
|
||||||
|
self.modules_def.append(init_module(module))
|
||||||
|
self.added_modules.append(generate_md5(module["name"]))
|
||||||
|
|
||||||
|
def del_module(
|
||||||
|
self,
|
||||||
|
module_name: str = ""
|
||||||
|
)-> None:
|
||||||
|
'''
|
||||||
|
Delete a module based on its name.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
module_name (str): The name of the module to be deleted.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
'''
|
||||||
|
from .general import generate_md5
|
||||||
|
|
||||||
|
if len(module_name.strip()) > 0:
|
||||||
|
try:
|
||||||
|
module_id = self.added_modules.index(generate_md5(module_name))
|
||||||
|
except:
|
||||||
|
module_id = None
|
||||||
|
|
||||||
|
if module_id is not None:
|
||||||
|
self.added_modules.pop(module_id)
|
||||||
|
self.modules_def.pop(module_id)
|
||||||
|
|
||||||
|
def update_module(
|
||||||
|
self,
|
||||||
|
module_name: str = "",
|
||||||
|
module: dict = {}
|
||||||
|
)-> None:
|
||||||
|
'''
|
||||||
|
Update a module based on its name.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
module_name (str): The name of the module to be updated.
|
||||||
|
module (dict): A dictionary containing updated module information.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
'''
|
||||||
|
module_def = self.get_module(module_name)
|
||||||
|
|
||||||
|
if module_def:
|
||||||
|
if "name" not in module:
|
||||||
|
module["name"] = module_name
|
||||||
|
|
||||||
|
module_def.update(module)
|
||||||
|
|
||||||
|
self.del_module(module_name)
|
||||||
|
self.add_module(module_def)
|
||||||
|
|
||||||
|
def get_module(
|
||||||
|
self,
|
||||||
|
module_name: str = ""
|
||||||
|
) -> dict:
|
||||||
|
'''
|
||||||
|
Retrieve module information based on its name.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
module_name (str): The name of the module to retrieve.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: A dictionary containing module information if found, otherwise an empty dictionary.
|
||||||
|
'''
|
||||||
|
from .general import generate_md5
|
||||||
|
|
||||||
|
if len(module_name.strip()) > 0:
|
||||||
|
try:
|
||||||
|
module_id = self.added_modules.index(generate_md5(module_name))
|
||||||
|
except:
|
||||||
|
module_id = None
|
||||||
|
|
||||||
|
if module_id is not None:
|
||||||
|
return self.modules_def[module_id]
|
||||||
|
else:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def get_modules_def(
|
||||||
|
self
|
||||||
|
) -> dict:
|
||||||
|
'''
|
||||||
|
Retrieve the definitions of all added modules.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: A dictionary containing the definitions of all added modules.
|
||||||
|
'''
|
||||||
|
return self.modules_def
|
||||||
|
|
||||||
|
def add_log_module(
|
||||||
|
self,
|
||||||
|
log_module: dict = {}
|
||||||
|
)-> None:
|
||||||
|
'''
|
||||||
|
Add a new log module to the list of log modules.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
log_module (dict): A dictionary containing log module information.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
'''
|
||||||
|
from .modules import init_log_module
|
||||||
|
|
||||||
|
if "source" in log_module and type(log_module["source"]) == str and len(log_module["source"].strip()) > 0:
|
||||||
|
self.log_modules_def.append(init_log_module(log_module))
|
||||||
|
|
||||||
|
def get_log_modules_def(
|
||||||
|
self
|
||||||
|
) -> dict:
|
||||||
|
'''
|
||||||
|
Retrieve the definitions of all added log modules.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: A dictionary containing the definitions of all added log modules.
|
||||||
|
'''
|
||||||
|
return self.log_modules_def
|
||||||
|
|
||||||
|
def print_xml(
|
||||||
|
self,
|
||||||
|
print_flag: bool = False
|
||||||
|
) -> str:
|
||||||
|
'''
|
||||||
|
Generate and optionally print the XML representation of the agent.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
print_flag (bool): A flag indicating whether to print the XML representation.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The XML representation of the agent.
|
||||||
|
'''
|
||||||
|
return print_agent(self.get_config(), self.get_modules_def(), self.get_log_modules_def(), print_flag)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Gets system OS name
|
||||||
|
#########################################################################################
|
||||||
|
def get_os() -> str:
|
||||||
|
"""
|
||||||
|
Gets system OS name
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: OS name.
|
||||||
|
"""
|
||||||
|
os = "Other"
|
||||||
|
|
||||||
|
if _WINDOWS:
|
||||||
|
os = "Windows"
|
||||||
|
|
||||||
|
if _LINUX:
|
||||||
|
os = "Linux"
|
||||||
|
|
||||||
|
if _MACOS or _OSX:
|
||||||
|
os = "MacOS"
|
||||||
|
|
||||||
|
if _FREEBSD or _OPENBSD or _NETBSD or _BSD:
|
||||||
|
os = "BSD"
|
||||||
|
|
||||||
|
if _SUNOS:
|
||||||
|
os = "Solaris"
|
||||||
|
|
||||||
|
if _AIX:
|
||||||
|
os = "AIX"
|
||||||
|
|
||||||
|
return os
|
||||||
|
|
||||||
|
####
|
||||||
|
# Init agent template
|
||||||
|
#########################################################################################
|
||||||
|
def init_agent(
|
||||||
|
default_values: dict = {}
|
||||||
|
) -> dict:
|
||||||
|
"""
|
||||||
|
Initialize an agent template with default values.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
default_values (dict): A dictionary containing custom default values for the agent template.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: A dictionary representing the agent template with default and custom values.
|
||||||
|
"""
|
||||||
|
from .general import now
|
||||||
|
|
||||||
|
agent = {
|
||||||
|
"agent_name" : "",
|
||||||
|
"agent_alias" : "",
|
||||||
|
"parent_agent_name" : "",
|
||||||
|
"description" : "",
|
||||||
|
"version" : "",
|
||||||
|
"os_name" : "",
|
||||||
|
"os_version" : "",
|
||||||
|
"timestamp" : now(),
|
||||||
|
"address" : "",
|
||||||
|
"group" : _GLOBAL_VARIABLES['agents_group_name'],
|
||||||
|
"interval" : _GLOBAL_VARIABLES['interval'],
|
||||||
|
"agent_mode" : "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value in default_values.items():
|
||||||
|
if key in agent:
|
||||||
|
agent[key] = value
|
||||||
|
|
||||||
|
return agent
|
||||||
|
|
||||||
|
####
|
||||||
|
# Prints agent XML. Requires agent conf (dict) and modules (list) as arguments.
|
||||||
|
#########################################################################################
|
||||||
|
def print_agent(
|
||||||
|
agent: dict = None,
|
||||||
|
modules: list = [],
|
||||||
|
log_modules: list = [],
|
||||||
|
print_flag: bool = False
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
Print the XML representation of an agent.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent (dict): A dictionary containing agent configuration.
|
||||||
|
modules (list): A list of dictionaries representing modules.
|
||||||
|
log_modules (list): A list of dictionaries representing log modules.
|
||||||
|
print_flag (bool): A flag indicating whether to print the XML representation.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The XML representation of the agent.
|
||||||
|
"""
|
||||||
|
from .output import print_stdout
|
||||||
|
from .modules import print_module,print_log_module
|
||||||
|
|
||||||
|
xml = ""
|
||||||
|
data_file = None
|
||||||
|
|
||||||
|
if agent is not None:
|
||||||
|
header = "<?xml version='1.0' encoding='UTF-8'?>\n"
|
||||||
|
header += "<agent_data"
|
||||||
|
for dato in agent:
|
||||||
|
header += " " + str(dato) + "='" + str(agent[dato]) + "'"
|
||||||
|
header += ">\n"
|
||||||
|
xml = header
|
||||||
|
|
||||||
|
for module in modules:
|
||||||
|
modules_xml = print_module(module)
|
||||||
|
xml += str(modules_xml)
|
||||||
|
|
||||||
|
for log_module in log_modules:
|
||||||
|
modules_xml = print_log_module(log_module)
|
||||||
|
xml += str(modules_xml)
|
||||||
|
|
||||||
|
xml += "</agent_data>"
|
||||||
|
|
||||||
|
if print_flag:
|
||||||
|
print_stdout(xml)
|
||||||
|
|
||||||
|
return xml
|
|
@ -0,0 +1,225 @@
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
|
||||||
|
####
|
||||||
|
# Define some global variables
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
_ERROR_LEVEL = 0
|
||||||
|
_SUMMARY = {}
|
||||||
|
_INFO = ""
|
||||||
|
_MONITORING_DATA = []
|
||||||
|
|
||||||
|
####
|
||||||
|
# Internal: Alias for output.print_debug function
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def _print_debug(
|
||||||
|
var = "",
|
||||||
|
print_errors: bool = False
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Print the variable as a JSON-like representation for debugging purposes.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
var (any): The variable to be printed.
|
||||||
|
print_errors (bool): A flag indicating whether to print errors during debugging.
|
||||||
|
"""
|
||||||
|
from .output import print_debug
|
||||||
|
print_debug(var, print_errors)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Set error level to value
|
||||||
|
#########################################################################################
|
||||||
|
def set_disco_error_level(
|
||||||
|
value: int = 0
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Sets the error level to the specified value.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
value (int, optional): The error level value. Default is 0.
|
||||||
|
"""
|
||||||
|
global _ERROR_LEVEL
|
||||||
|
|
||||||
|
_ERROR_LEVEL = value
|
||||||
|
|
||||||
|
####
|
||||||
|
# Set fixed value to summary dict
|
||||||
|
#########################################################################################
|
||||||
|
def set_disco_summary(
|
||||||
|
data: dict = {}
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Sets the disk summary data in the internal summary dictionary.
|
||||||
|
|
||||||
|
This function updates the summary dictionary with the provided disk summary data.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data (dict): A dictionary containing disk summary data.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
global _SUMMARY
|
||||||
|
|
||||||
|
_SUMMARY = {}
|
||||||
|
|
||||||
|
####
|
||||||
|
# Set fixed value to summary key
|
||||||
|
#########################################################################################
|
||||||
|
def set_disco_summary_value(
|
||||||
|
key: str = "",
|
||||||
|
value = None
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Sets a fixed value for a key in the '_SUMMARY' dictionary.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key (str): Key to set the value for.
|
||||||
|
value (any): Value to assign to the key.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
global _SUMMARY
|
||||||
|
|
||||||
|
_SUMMARY[key] = value
|
||||||
|
|
||||||
|
####
|
||||||
|
# Add value to summary key
|
||||||
|
#########################################################################################
|
||||||
|
def add_disco_summary_value(
|
||||||
|
key: str = "",
|
||||||
|
value = None
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Adds a value to a key in the 'SUMMARY' dictionary.
|
||||||
|
|
||||||
|
If the key already exists, the value will be incremented. Otherwise, a new key will be created.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key (str): Key to add the value to.
|
||||||
|
value (any): Value to add to the key.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
global _SUMMARY
|
||||||
|
|
||||||
|
if key in _SUMMARY:
|
||||||
|
_SUMMARY[key] += value
|
||||||
|
else:
|
||||||
|
set_disco_summary_value(key, value)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Set fixed value to info
|
||||||
|
#########################################################################################
|
||||||
|
def set_disco_info_value(
|
||||||
|
value: str = ""
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Sets a fixed value to the '_INFO' variable.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data (str, optional): The value to set in the '_INFO' variable. Default is an empty string.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
global _INFO
|
||||||
|
|
||||||
|
_INFO = value
|
||||||
|
|
||||||
|
####
|
||||||
|
# Add data to info
|
||||||
|
#########################################################################################
|
||||||
|
def add_disco_info_value(
|
||||||
|
value: str = ""
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Adds data to the '_INFO' variable.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data (str, optional): The data to add to the '_INFO' variable. Default is an empty string.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
global _INFO
|
||||||
|
|
||||||
|
_INFO += value
|
||||||
|
|
||||||
|
####
|
||||||
|
# Set fixed value to monitoring data
|
||||||
|
#########################################################################################
|
||||||
|
def set_disco_monitoring_data(
|
||||||
|
data: list = []
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Set the monitoring data for disk usage.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data (list): A list containing disk monitoring data.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
global _MONITORING_DATA
|
||||||
|
|
||||||
|
_MONITORING_DATA = data
|
||||||
|
|
||||||
|
####
|
||||||
|
# Add value to monitoring data
|
||||||
|
#########################################################################################
|
||||||
|
def add_disco_monitoring_data(
|
||||||
|
data: dict = {}
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Add disk monitoring data to the global monitoring dataset.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data (dict): A dictionary containing disk monitoring data.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
global _MONITORING_DATA
|
||||||
|
|
||||||
|
_MONITORING_DATA.append(data)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Print JSON output and exit script
|
||||||
|
#########################################################################################
|
||||||
|
def disco_output()-> None:
|
||||||
|
"""
|
||||||
|
Prints the JSON output and exits the script.
|
||||||
|
|
||||||
|
The function uses the global variables '_ERROR_LEVEL', '_SUMMARY', '_INFO' and '_MONITORING_DATA'
|
||||||
|
to create the JSON output. It then prints the JSON string and exits the script with
|
||||||
|
the '_ERROR_LEVEL' as the exit code.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
from .output import print_stdout
|
||||||
|
|
||||||
|
global _ERROR_LEVEL
|
||||||
|
global _SUMMARY
|
||||||
|
global _INFO
|
||||||
|
global _MONITORING_DATA
|
||||||
|
|
||||||
|
output={}
|
||||||
|
if _SUMMARY:
|
||||||
|
output["summary"] = _SUMMARY
|
||||||
|
|
||||||
|
if _INFO:
|
||||||
|
output["info"] = _INFO
|
||||||
|
|
||||||
|
if _MONITORING_DATA:
|
||||||
|
output["monitoring_data"] = _MONITORING_DATA
|
||||||
|
|
||||||
|
json_string = json.dumps(output)
|
||||||
|
|
||||||
|
print_stdout(json_string)
|
||||||
|
sys.exit(_ERROR_LEVEL)
|
|
@ -0,0 +1,116 @@
|
||||||
|
try:
|
||||||
|
from Crypto.Cipher import AES
|
||||||
|
from Crypto.Util.Padding import pad, unpad
|
||||||
|
except ImportError as e:
|
||||||
|
import sys
|
||||||
|
from .output import print_stderr
|
||||||
|
print_stderr("ModuleNotFoundError: No module named 'pycryptodome'")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
import hashlib
|
||||||
|
import base64
|
||||||
|
import hmac
|
||||||
|
from binascii import unhexlify
|
||||||
|
|
||||||
|
####
|
||||||
|
# Define encription internal global variables.
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
_PASSWORD = "default_salt"
|
||||||
|
|
||||||
|
####
|
||||||
|
# Internal: Alias for output.print_debug function
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def _print_debug(
|
||||||
|
var = "",
|
||||||
|
print_errors: bool = False
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Print the variable as a JSON-like representation for debugging purposes.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
var (any): The variable to be printed.
|
||||||
|
print_errors (bool): A flag indicating whether to print errors during debugging.
|
||||||
|
"""
|
||||||
|
from .output import print_debug
|
||||||
|
print_debug(var, print_errors)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Internal use only: Get AES cipher
|
||||||
|
#########################################################################################
|
||||||
|
def _get_cipher(
|
||||||
|
password: str = _PASSWORD
|
||||||
|
) -> AES:
|
||||||
|
'''
|
||||||
|
Internal use only: Get AES cipher for encryption and decryption.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
password (str): The password used to derive the encryption key.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
AES: An AES cipher instance for encryption and decryption.
|
||||||
|
'''
|
||||||
|
key = b''
|
||||||
|
msg = password.encode('utf-8')
|
||||||
|
hash_obj = hmac.new(key, msg, hashlib.sha256)
|
||||||
|
hash_result = hash_obj.digest()
|
||||||
|
hash_base64 = base64.b64encode(hash_result)[:16].decode()
|
||||||
|
|
||||||
|
iv = b'0000000000000000'
|
||||||
|
|
||||||
|
return AES.new(hash_base64.encode(), AES.MODE_CBC, iv)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Return encrypted string
|
||||||
|
#########################################################################################
|
||||||
|
def encrypt_AES(
|
||||||
|
str_to_encrypt: str = "",
|
||||||
|
password: str = _PASSWORD
|
||||||
|
) -> str:
|
||||||
|
'''
|
||||||
|
Encrypt a string using AES encryption.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
str_to_encrypt (str): The string to be encrypted.
|
||||||
|
password (str): The password used to derive the encryption key.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The encrypted string in base64 encoding.
|
||||||
|
'''
|
||||||
|
cipher = _get_cipher(password)
|
||||||
|
|
||||||
|
try:
|
||||||
|
msg_padded = pad(str_to_encrypt.encode(), AES.block_size, style='pkcs7')
|
||||||
|
cipher_text = cipher.encrypt(msg_padded)
|
||||||
|
b64str = base64.b64encode(cipher_text).decode()
|
||||||
|
except:
|
||||||
|
b64str = ''
|
||||||
|
|
||||||
|
return b64str
|
||||||
|
|
||||||
|
####
|
||||||
|
# Return decrypted string
|
||||||
|
#########################################################################################
|
||||||
|
def decrypt_AES(
|
||||||
|
str_to_decrypt: str = "",
|
||||||
|
password: str = _PASSWORD
|
||||||
|
) -> str:
|
||||||
|
'''
|
||||||
|
Decrypt an encrypted string using AES decryption.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
str_to_decrypt (str): The encrypted string to be decrypted.
|
||||||
|
password (str): The password used to derive the encryption key.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The decrypted string.
|
||||||
|
'''
|
||||||
|
cipher = _get_cipher(password)
|
||||||
|
|
||||||
|
try:
|
||||||
|
decrypted_str = unpad(cipher.decrypt(base64.b64decode(str_to_decrypt)), AES.block_size, style='pkcs7').decode().strip()
|
||||||
|
except:
|
||||||
|
decrypted_str = ''
|
||||||
|
|
||||||
|
return decrypted_str
|
|
@ -0,0 +1,652 @@
|
||||||
|
import sys
|
||||||
|
from datetime import datetime
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
####
|
||||||
|
# Define some global variables
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
# Entity to character mapping. Contains a few tweaks to make it backward compatible with the previous safe_input implementation.
|
||||||
|
_ENT2CHR = {
|
||||||
|
'#x00': chr(0),
|
||||||
|
'#x01': chr(1),
|
||||||
|
'#x02': chr(2),
|
||||||
|
'#x03': chr(3),
|
||||||
|
'#x04': chr(4),
|
||||||
|
'#x05': chr(5),
|
||||||
|
'#x06': chr(6),
|
||||||
|
'#x07': chr(7),
|
||||||
|
'#x08': chr(8),
|
||||||
|
'#x09': chr(9),
|
||||||
|
'#x0a': chr(10),
|
||||||
|
'#x0b': chr(11),
|
||||||
|
'#x0c': chr(12),
|
||||||
|
'#x0d': chr(13),
|
||||||
|
'#x0e': chr(14),
|
||||||
|
'#x0f': chr(15),
|
||||||
|
'#x10': chr(16),
|
||||||
|
'#x11': chr(17),
|
||||||
|
'#x12': chr(18),
|
||||||
|
'#x13': chr(19),
|
||||||
|
'#x14': chr(20),
|
||||||
|
'#x15': chr(21),
|
||||||
|
'#x16': chr(22),
|
||||||
|
'#x17': chr(23),
|
||||||
|
'#x18': chr(24),
|
||||||
|
'#x19': chr(25),
|
||||||
|
'#x1a': chr(26),
|
||||||
|
'#x1b': chr(27),
|
||||||
|
'#x1c': chr(28),
|
||||||
|
'#x1d': chr(29),
|
||||||
|
'#x1e': chr(30),
|
||||||
|
'#x1f': chr(31),
|
||||||
|
'#x20': chr(32),
|
||||||
|
'quot': chr(34),
|
||||||
|
'amp': chr(38),
|
||||||
|
'#039': chr(39),
|
||||||
|
'#40': chr(40),
|
||||||
|
'#41': chr(41),
|
||||||
|
'lt': chr(60),
|
||||||
|
'gt': chr(62),
|
||||||
|
'#92': chr(92),
|
||||||
|
'#x80': chr(128),
|
||||||
|
'#x81': chr(129),
|
||||||
|
'#x82': chr(130),
|
||||||
|
'#x83': chr(131),
|
||||||
|
'#x84': chr(132),
|
||||||
|
'#x85': chr(133),
|
||||||
|
'#x86': chr(134),
|
||||||
|
'#x87': chr(135),
|
||||||
|
'#x88': chr(136),
|
||||||
|
'#x89': chr(137),
|
||||||
|
'#x8a': chr(138),
|
||||||
|
'#x8b': chr(139),
|
||||||
|
'#x8c': chr(140),
|
||||||
|
'#x8d': chr(141),
|
||||||
|
'#x8e': chr(142),
|
||||||
|
'#x8f': chr(143),
|
||||||
|
'#x90': chr(144),
|
||||||
|
'#x91': chr(145),
|
||||||
|
'#x92': chr(146),
|
||||||
|
'#x93': chr(147),
|
||||||
|
'#x94': chr(148),
|
||||||
|
'#x95': chr(149),
|
||||||
|
'#x96': chr(150),
|
||||||
|
'#x97': chr(151),
|
||||||
|
'#x98': chr(152),
|
||||||
|
'#x99': chr(153),
|
||||||
|
'#x9a': chr(154),
|
||||||
|
'#x9b': chr(155),
|
||||||
|
'#x9c': chr(156),
|
||||||
|
'#x9d': chr(157),
|
||||||
|
'#x9e': chr(158),
|
||||||
|
'#x9f': chr(159),
|
||||||
|
'#xa0': chr(160),
|
||||||
|
'#xa1': chr(161),
|
||||||
|
'#xa2': chr(162),
|
||||||
|
'#xa3': chr(163),
|
||||||
|
'#xa4': chr(164),
|
||||||
|
'#xa5': chr(165),
|
||||||
|
'#xa6': chr(166),
|
||||||
|
'#xa7': chr(167),
|
||||||
|
'#xa8': chr(168),
|
||||||
|
'#xa9': chr(169),
|
||||||
|
'#xaa': chr(170),
|
||||||
|
'#xab': chr(171),
|
||||||
|
'#xac': chr(172),
|
||||||
|
'#xad': chr(173),
|
||||||
|
'#xae': chr(174),
|
||||||
|
'#xaf': chr(175),
|
||||||
|
'#xb0': chr(176),
|
||||||
|
'#xb1': chr(177),
|
||||||
|
'#xb2': chr(178),
|
||||||
|
'#xb3': chr(179),
|
||||||
|
'#xb4': chr(180),
|
||||||
|
'#xb5': chr(181),
|
||||||
|
'#xb6': chr(182),
|
||||||
|
'#xb7': chr(183),
|
||||||
|
'#xb8': chr(184),
|
||||||
|
'#xb9': chr(185),
|
||||||
|
'#xba': chr(186),
|
||||||
|
'#xbb': chr(187),
|
||||||
|
'#xbc': chr(188),
|
||||||
|
'#xbd': chr(189),
|
||||||
|
'#xbe': chr(190),
|
||||||
|
'Aacute': chr(193),
|
||||||
|
'Auml': chr(196),
|
||||||
|
'Eacute': chr(201),
|
||||||
|
'Euml': chr(203),
|
||||||
|
'Iacute': chr(205),
|
||||||
|
'Iuml': chr(207),
|
||||||
|
'Ntilde': chr(209),
|
||||||
|
'Oacute': chr(211),
|
||||||
|
'Ouml': chr(214),
|
||||||
|
'Uacute': chr(218),
|
||||||
|
'Uuml': chr(220),
|
||||||
|
'aacute': chr(225),
|
||||||
|
'auml': chr(228),
|
||||||
|
'eacute': chr(233),
|
||||||
|
'euml': chr(235),
|
||||||
|
'iacute': chr(237),
|
||||||
|
'iuml': chr(239),
|
||||||
|
'ntilde': chr(241),
|
||||||
|
'oacute': chr(243),
|
||||||
|
'ouml': chr(246),
|
||||||
|
'uacute': chr(250),
|
||||||
|
'uuml': chr(252),
|
||||||
|
'OElig': chr(338),
|
||||||
|
'oelig': chr(339),
|
||||||
|
'Scaron': chr(352),
|
||||||
|
'scaron': chr(353),
|
||||||
|
'Yuml': chr(376),
|
||||||
|
'fnof': chr(402),
|
||||||
|
'circ': chr(710),
|
||||||
|
'tilde': chr(732),
|
||||||
|
'Alpha': chr(913),
|
||||||
|
'Beta': chr(914),
|
||||||
|
'Gamma': chr(915),
|
||||||
|
'Delta': chr(916),
|
||||||
|
'Epsilon': chr(917),
|
||||||
|
'Zeta': chr(918),
|
||||||
|
'Eta': chr(919),
|
||||||
|
'Theta': chr(920),
|
||||||
|
'Iota': chr(921),
|
||||||
|
'Kappa': chr(922),
|
||||||
|
'Lambda': chr(923),
|
||||||
|
'Mu': chr(924),
|
||||||
|
'Nu': chr(925),
|
||||||
|
'Xi': chr(926),
|
||||||
|
'Omicron': chr(927),
|
||||||
|
'Pi': chr(928),
|
||||||
|
'Rho': chr(929),
|
||||||
|
'Sigma': chr(931),
|
||||||
|
'Tau': chr(932),
|
||||||
|
'Upsilon': chr(933),
|
||||||
|
'Phi': chr(934),
|
||||||
|
'Chi': chr(935),
|
||||||
|
'Psi': chr(936),
|
||||||
|
'Omega': chr(937),
|
||||||
|
'alpha': chr(945),
|
||||||
|
'beta': chr(946),
|
||||||
|
'gamma': chr(947),
|
||||||
|
'delta': chr(948),
|
||||||
|
'epsilon': chr(949),
|
||||||
|
'zeta': chr(950),
|
||||||
|
'eta': chr(951),
|
||||||
|
'theta': chr(952),
|
||||||
|
'iota': chr(953),
|
||||||
|
'kappa': chr(954),
|
||||||
|
'lambda': chr(955),
|
||||||
|
'mu': chr(956),
|
||||||
|
'nu': chr(957),
|
||||||
|
'xi': chr(958),
|
||||||
|
'omicron': chr(959),
|
||||||
|
'pi': chr(960),
|
||||||
|
'rho': chr(961),
|
||||||
|
'sigmaf': chr(962),
|
||||||
|
'sigma': chr(963),
|
||||||
|
'tau': chr(964),
|
||||||
|
'upsilon': chr(965),
|
||||||
|
'phi': chr(966),
|
||||||
|
'chi': chr(967),
|
||||||
|
'psi': chr(968),
|
||||||
|
'omega': chr(969),
|
||||||
|
'thetasym': chr(977),
|
||||||
|
'upsih': chr(978),
|
||||||
|
'piv': chr(982),
|
||||||
|
'ensp': chr(8194),
|
||||||
|
'emsp': chr(8195),
|
||||||
|
'thinsp': chr(8201),
|
||||||
|
'zwnj': chr(8204),
|
||||||
|
'zwj': chr(8205),
|
||||||
|
'lrm': chr(8206),
|
||||||
|
'rlm': chr(8207),
|
||||||
|
'ndash': chr(8211),
|
||||||
|
'mdash': chr(8212),
|
||||||
|
'lsquo': chr(8216),
|
||||||
|
'rsquo': chr(8217),
|
||||||
|
'sbquo': chr(8218),
|
||||||
|
'ldquo': chr(8220),
|
||||||
|
'rdquo': chr(8221),
|
||||||
|
'bdquo': chr(8222),
|
||||||
|
'dagger': chr(8224),
|
||||||
|
'Dagger': chr(8225),
|
||||||
|
'bull': chr(8226),
|
||||||
|
'hellip': chr(8230),
|
||||||
|
'permil': chr(8240),
|
||||||
|
'prime': chr(8242),
|
||||||
|
'Prime': chr(8243),
|
||||||
|
'lsaquo': chr(8249),
|
||||||
|
'rsaquo': chr(8250),
|
||||||
|
'oline': chr(8254),
|
||||||
|
'frasl': chr(8260),
|
||||||
|
'euro': chr(8364),
|
||||||
|
'image': chr(8465),
|
||||||
|
'weierp': chr(8472),
|
||||||
|
'real': chr(8476),
|
||||||
|
'trade': chr(8482),
|
||||||
|
'alefsym': chr(8501),
|
||||||
|
'larr': chr(8592),
|
||||||
|
'uarr': chr(8593),
|
||||||
|
'rarr': chr(8594),
|
||||||
|
'darr': chr(8595),
|
||||||
|
'harr': chr(8596),
|
||||||
|
'crarr': chr(8629),
|
||||||
|
'lArr': chr(8656),
|
||||||
|
'uArr': chr(8657),
|
||||||
|
'rArr': chr(8658),
|
||||||
|
'dArr': chr(8659),
|
||||||
|
'hArr': chr(8660),
|
||||||
|
'forall': chr(8704),
|
||||||
|
'part': chr(8706),
|
||||||
|
'exist': chr(8707),
|
||||||
|
'empty': chr(8709),
|
||||||
|
'nabla': chr(8711),
|
||||||
|
'isin': chr(8712),
|
||||||
|
'notin': chr(8713),
|
||||||
|
'ni': chr(8715),
|
||||||
|
'prod': chr(8719),
|
||||||
|
'sum': chr(8721),
|
||||||
|
'minus': chr(8722),
|
||||||
|
'lowast': chr(8727),
|
||||||
|
'radic': chr(8730),
|
||||||
|
'prop': chr(8733),
|
||||||
|
'infin': chr(8734),
|
||||||
|
'ang': chr(8736),
|
||||||
|
'and': chr(8743),
|
||||||
|
'or': chr(8744),
|
||||||
|
'cap': chr(8745),
|
||||||
|
'cup': chr(8746),
|
||||||
|
'int': chr(8747),
|
||||||
|
'there4': chr(8756),
|
||||||
|
'sim': chr(8764),
|
||||||
|
'cong': chr(8773),
|
||||||
|
'asymp': chr(8776),
|
||||||
|
'ne': chr(8800),
|
||||||
|
'equiv': chr(8801),
|
||||||
|
'le': chr(8804),
|
||||||
|
'ge': chr(8805),
|
||||||
|
'sub': chr(8834),
|
||||||
|
'sup': chr(8835),
|
||||||
|
'nsub': chr(8836),
|
||||||
|
'sube': chr(8838),
|
||||||
|
'supe': chr(8839),
|
||||||
|
'oplus': chr(8853),
|
||||||
|
'otimes': chr(8855),
|
||||||
|
'perp': chr(8869),
|
||||||
|
'sdot': chr(8901),
|
||||||
|
'lceil': chr(8968),
|
||||||
|
'rceil': chr(8969),
|
||||||
|
'lfloor': chr(8970),
|
||||||
|
'rfloor': chr(8971),
|
||||||
|
'lang': chr(9001),
|
||||||
|
'rang': chr(9002),
|
||||||
|
'loz': chr(9674),
|
||||||
|
'spades': chr(9824),
|
||||||
|
'clubs': chr(9827),
|
||||||
|
'hearts': chr(9829),
|
||||||
|
'diams': chr(9830),
|
||||||
|
}
|
||||||
|
|
||||||
|
# Construct the character to entity mapping.
|
||||||
|
_CHR2ENT = {v: "&" + k + ";" for k, v in _ENT2CHR.items()}
|
||||||
|
|
||||||
|
####
|
||||||
|
# Internal: Alias for output.print_debug function
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def _print_debug(
|
||||||
|
var = "",
|
||||||
|
print_errors: bool = False
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Print the variable as a JSON-like representation for debugging purposes.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
var (any): The variable to be printed.
|
||||||
|
print_errors (bool): A flag indicating whether to print errors during debugging.
|
||||||
|
"""
|
||||||
|
from .output import print_debug
|
||||||
|
print_debug(var, print_errors)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Convert the input_string encoded in html entity to clear char string.
|
||||||
|
#########################################################################################
|
||||||
|
def safe_input(
|
||||||
|
input_string: str = ""
|
||||||
|
) -> str:
|
||||||
|
'''
|
||||||
|
Convert an input string encoded in HTML entities to a clear character string.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
input_string (str): The input string encoded in HTML entities.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The decoded clear character string.
|
||||||
|
'''
|
||||||
|
if not input_string:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
return "".join(_CHR2ENT.get(char, char) for char in input_string)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Convert the html entities to input_string encoded to rebuild char string.
|
||||||
|
#########################################################################################
|
||||||
|
def safe_output(
|
||||||
|
input_string: str = ""
|
||||||
|
) -> str:
|
||||||
|
'''
|
||||||
|
Convert HTML entities back to their corresponding characters in the input string.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
input_string (str): The input string containing HTML entities.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The decoded clear character string.
|
||||||
|
'''
|
||||||
|
if not input_string:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
for char, entity in _CHR2ENT.items():
|
||||||
|
input_string = input_string.replace(entity, char)
|
||||||
|
|
||||||
|
return input_string
|
||||||
|
|
||||||
|
####
|
||||||
|
# Assign to a key in a dict a given value.
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def set_dict_key_value(
|
||||||
|
input_dict: dict = {},
|
||||||
|
input_key: str = "",
|
||||||
|
input_value = None
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Assign a given value to a specified key in a dictionary.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
input_dict (dict): The dictionary to which the value will be assigned.
|
||||||
|
input_key (str): The key in the dictionary to which the value will be assigned.
|
||||||
|
input_value (any): The value to be assigned to the specified key.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
key = input_key.strip()
|
||||||
|
|
||||||
|
if len(key) > 0:
|
||||||
|
input_dict[key] = input_value
|
||||||
|
|
||||||
|
####
|
||||||
|
# Return the value of a key in a given dict.
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def get_dict_key_value(
|
||||||
|
input_dict: dict = {},
|
||||||
|
input_key: str = ""
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Return the value associated with a given key in a provided dictionary.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
input_dict (dict): The dictionary to search for the key-value pair.
|
||||||
|
input_key (str): The key to look up in the dictionary.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The value associated with the specified key, or None if the key is not found.
|
||||||
|
"""
|
||||||
|
key = input_key.strip()
|
||||||
|
|
||||||
|
if key in input_dict:
|
||||||
|
return input_dict[key]
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
####
|
||||||
|
# Return MD5 hash string.
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def generate_md5(
|
||||||
|
input_string: str = ""
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
Generates an MD5 hash for the given input string.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
input_string (str): The string for which the MD5 hash will be generated.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The MD5 hash of the input string as a hexadecimal string.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
md5_hash = hashlib.md5(input_string.encode()).hexdigest()
|
||||||
|
except:
|
||||||
|
md5_hash = ""
|
||||||
|
|
||||||
|
return md5_hash
|
||||||
|
|
||||||
|
####
|
||||||
|
# Returns or print current time in date format or utimestamp.
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def now(
|
||||||
|
utimestamp: bool = False,
|
||||||
|
print_flag: bool = False
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
Get the current time in the specified format or as a Unix timestamp.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
utimestamp (bool): Set to True to get the Unix timestamp (epoch time).
|
||||||
|
print_flag (bool): Set to True to print the time to standard output.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The current time in the desired format or as a Unix timestamp.
|
||||||
|
"""
|
||||||
|
from .output import print_stdout
|
||||||
|
|
||||||
|
today = datetime.today()
|
||||||
|
|
||||||
|
if utimestamp:
|
||||||
|
time = datetime.timestamp(today)
|
||||||
|
else:
|
||||||
|
time = today.strftime('%Y/%m/%d %H:%M:%S')
|
||||||
|
|
||||||
|
if print_flag:
|
||||||
|
print_stdout(time)
|
||||||
|
|
||||||
|
return time
|
||||||
|
|
||||||
|
####
|
||||||
|
# Translate macros in string from a dict.
|
||||||
|
#########################################################################################
|
||||||
|
def translate_macros(
|
||||||
|
macro_dic: dict = {},
|
||||||
|
data: str = ""
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
Replace macros in the input string with their corresponding values.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
macro_dic (dict): A dictionary containing macro names and their corresponding values.
|
||||||
|
data (str): The input string in which macros should be replaced.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The input string with macros replaced by their values.
|
||||||
|
"""
|
||||||
|
for macro_name, macro_value in macro_dic.items():
|
||||||
|
data = data.replace(macro_name, macro_value)
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
####
|
||||||
|
# Parse configuration file line by line based on separator and return dict.
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def parse_configuration(
|
||||||
|
file: str = "/etc/pandora/pandora_server.conf",
|
||||||
|
separator: str = " ",
|
||||||
|
default_values: dict = {}
|
||||||
|
) -> dict:
|
||||||
|
"""
|
||||||
|
Parse a configuration file and return its data as a dictionary.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
file (str): The path to the configuration file. Defaults to "/etc/pandora/pandora_server.conf".
|
||||||
|
separator (str, optional): The separator between option and value. Defaults to " ".
|
||||||
|
default_values (dict, optional): A dictionary of default values. Defaults to an empty dictionary.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: A dictionary containing all keys and values from the configuration file.
|
||||||
|
"""
|
||||||
|
from .output import print_stderr
|
||||||
|
|
||||||
|
config = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open (file, "r") as conf:
|
||||||
|
lines = conf.read().splitlines()
|
||||||
|
for line in lines:
|
||||||
|
if line.strip().startswith("#") or len(line.strip()) < 1 :
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
option, value = line.strip().split(separator, maxsplit=1)
|
||||||
|
config[option.strip()] = value.strip()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print_stderr(f"{type(e).__name__}: {e}")
|
||||||
|
|
||||||
|
for option, value in default_values.items():
|
||||||
|
if option.strip() not in config:
|
||||||
|
config[option.strip()] = value.strip()
|
||||||
|
|
||||||
|
return config
|
||||||
|
|
||||||
|
####
|
||||||
|
# Parse csv file line by line and return list.
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def parse_csv_file(
|
||||||
|
file: str = "",
|
||||||
|
separator: str = ';',
|
||||||
|
count_parameters: int = 0,
|
||||||
|
print_errors: bool = False
|
||||||
|
) -> list:
|
||||||
|
"""
|
||||||
|
Parse a CSV configuration file and return its data in a list.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
file (str): The path to the CSV configuration file.
|
||||||
|
separator (str, optional): The separator between values in the CSV. Defaults to ";".
|
||||||
|
count_parameters (int, optional): The minimum number of parameters each line should have. Defaults to 0.
|
||||||
|
print_errors (bool, optional): Set to True to print errors for lines with insufficient parameters. Defaults to False.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list: A list containing lists of values for each line in the CSV.
|
||||||
|
"""
|
||||||
|
from .output import print_stderr
|
||||||
|
|
||||||
|
csv_arr = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open (file, "r") as csv:
|
||||||
|
lines = csv.read().splitlines()
|
||||||
|
for line in lines:
|
||||||
|
if line.strip().startswith("#") or len(line.strip()) < 1 :
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
value = line.strip().split(separator)
|
||||||
|
if len(value) >= count_parameters:
|
||||||
|
csv_arr.append(value)
|
||||||
|
elif print_errors==True:
|
||||||
|
print_stderr(f'Csv line: {line} does not match minimun parameter defined: {count_parameters}')
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print_stderr(f"{type(e).__name__}: {e}")
|
||||||
|
|
||||||
|
return csv_arr
|
||||||
|
|
||||||
|
####
|
||||||
|
# Parse given variable to integer.
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def parse_int(
|
||||||
|
var = None
|
||||||
|
) -> int:
|
||||||
|
"""
|
||||||
|
Parse given variable to integer.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
var (any): The variable to be parsed as an integer.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: The parsed integer value. If parsing fails, returns 0.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return int(var)
|
||||||
|
except:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
####
|
||||||
|
# Parse given variable to float.
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def parse_float(
|
||||||
|
var = None
|
||||||
|
) -> float:
|
||||||
|
"""
|
||||||
|
Parse given variable to float.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
var (any): The variable to be parsed as an float.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
float: The parsed float value. If parsing fails, returns 0.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return float(var)
|
||||||
|
except:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
####
|
||||||
|
# Parse given variable to string.
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def parse_str(
|
||||||
|
var = None
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
Parse given variable to string.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
var (any): The variable to be parsed as an string.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The parsed string value. If parsing fails, returns "".
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return str(var)
|
||||||
|
except:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
####
|
||||||
|
# Parse given variable to bool.
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def parse_bool(
|
||||||
|
var = None
|
||||||
|
) -> bool:
|
||||||
|
"""
|
||||||
|
Parse given variable to bool.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
var (any): The variable to be parsed as an bool.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: The parsed bool value. If parsing fails, returns False.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return bool(var)
|
||||||
|
except:
|
||||||
|
return False
|
|
@ -0,0 +1,113 @@
|
||||||
|
import urllib3
|
||||||
|
import warnings
|
||||||
|
from requests.sessions import Session
|
||||||
|
from requests_ntlm import HttpNtlmAuth
|
||||||
|
from requests.auth import HTTPBasicAuth
|
||||||
|
from requests.auth import HTTPDigestAuth
|
||||||
|
|
||||||
|
####
|
||||||
|
# Internal: Alias for output.print_debug function
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def _print_debug(
|
||||||
|
var = "",
|
||||||
|
print_errors: bool = False
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Print the provided variable as JSON, supporting various data types.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
var (any): The variable to be printed as JSON.
|
||||||
|
print_errors (bool): Set to True to print errors encountered during printing.
|
||||||
|
"""
|
||||||
|
from .output import print_debug
|
||||||
|
print_debug(var, print_errors)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Internal: Auth URL session
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def _auth_call(
|
||||||
|
session = None,
|
||||||
|
authtype: str = "basic",
|
||||||
|
user: str = "",
|
||||||
|
passw: str = ""
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Perform authentication for URL requests using various authentication types.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
session (object, optional): The request Session() object. Defaults to None.
|
||||||
|
authtype (str, optional): The authentication type. Supported values: 'ntlm', 'basic', or 'digest'. Defaults to 'basic'.
|
||||||
|
user (str, optional): The authentication user. Defaults to an empty string.
|
||||||
|
passw (str, optional): The authentication password. Defaults to an empty string.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
if session is not None:
|
||||||
|
if authtype == 'ntlm':
|
||||||
|
session.auth = HttpNtlmAuth(user, passw)
|
||||||
|
elif authtype == 'basic':
|
||||||
|
session.auth = HTTPBasicAuth(user, passw)
|
||||||
|
elif authtype == 'digest':
|
||||||
|
session.auth = HTTPDigestAuth(user, passw)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Call URL and return output
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def call_url(
|
||||||
|
url: str = "",
|
||||||
|
authtype: str = "basic",
|
||||||
|
user: str = "",
|
||||||
|
passw: str = "",
|
||||||
|
timeout: int = 1,
|
||||||
|
verify: bool = True,
|
||||||
|
print_errors: bool = False
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
Call a URL and return its contents.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
url (str): The URL to call.
|
||||||
|
authtype (str, optional): The authentication type. Supported values: 'ntlm', 'basic', 'digest'. Defaults to 'basic'.
|
||||||
|
user (str, optional): The authentication user. Defaults to an empty string.
|
||||||
|
passw (str, optional): The authentication password. Defaults to an empty string.
|
||||||
|
timeout (int, optional): The session timeout in seconds. Defaults to 1.
|
||||||
|
print_errors (bool, optional): Set to True to print errors encountered during the call. Defaults to False.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The output from the URL call.
|
||||||
|
"""
|
||||||
|
from .output import print_stderr
|
||||||
|
|
||||||
|
if url == "":
|
||||||
|
if print_errors:
|
||||||
|
print_stderr("Error: URL not provided")
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
# using with so we make sure the session is closed even when exceptions are encountered
|
||||||
|
with Session() as session:
|
||||||
|
if authtype is not None:
|
||||||
|
_auth_call(session, authtype, user, passw)
|
||||||
|
|
||||||
|
output = ""
|
||||||
|
|
||||||
|
try:
|
||||||
|
with warnings.catch_warnings():
|
||||||
|
warnings.filterwarnings("ignore", category=urllib3.exceptions.InsecureRequestWarning)
|
||||||
|
response = session.get(url, timeout=timeout, verify=verify)
|
||||||
|
response.raise_for_status() # Raise an exception for non-2xx responses
|
||||||
|
return response.content
|
||||||
|
except requests.exceptions.Timeout:
|
||||||
|
if print_errors:
|
||||||
|
print_stderr("Error: Request timed out")
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
if print_errors:
|
||||||
|
print_stderr(f"RequestException:\t{e}")
|
||||||
|
except ValueError:
|
||||||
|
if print_errors:
|
||||||
|
print_stderr("Error: URL format not valid (example http://myserver/page.php)")
|
||||||
|
|
||||||
|
return None
|
|
@ -0,0 +1,330 @@
|
||||||
|
####
|
||||||
|
# Internal: Alias for output.print_debug function
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def _print_debug(
|
||||||
|
var = "",
|
||||||
|
print_errors: bool = False
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Print the provided variable as JSON format, supporting various data types.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
var (any, optional): The variable to be printed as JSON. Defaults to an empty string.
|
||||||
|
print_errors (bool, optional): Set to True to print errors encountered during printing. Defaults to False.
|
||||||
|
"""
|
||||||
|
from .output import print_debug
|
||||||
|
print_debug(var, print_errors)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Init module template
|
||||||
|
#########################################################################################
|
||||||
|
def init_module(
|
||||||
|
default_values: dict = {}
|
||||||
|
) -> dict:
|
||||||
|
"""
|
||||||
|
Initializes a module template with default values.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
default_values (dict, optional): Dictionary containing default values to override template values. Defaults to an empty dictionary.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: Dictionary representing the module template with default values.
|
||||||
|
"""
|
||||||
|
module = {
|
||||||
|
"name" : None,
|
||||||
|
"type" : "generic_data_string",
|
||||||
|
"value" : "0",
|
||||||
|
"desc" : "",
|
||||||
|
"unit" : "",
|
||||||
|
"interval" : "",
|
||||||
|
"tags" : "",
|
||||||
|
"module_group" : "",
|
||||||
|
"module_parent" : "",
|
||||||
|
"min_warning" : "",
|
||||||
|
"min_warning_forced" : "",
|
||||||
|
"max_warning" : "",
|
||||||
|
"max_warning_forced" : "",
|
||||||
|
"min_critical" : "",
|
||||||
|
"min_critical_forced" : "",
|
||||||
|
"max_critical" : "",
|
||||||
|
"max_critical_forced" : "",
|
||||||
|
"str_warning" : "",
|
||||||
|
"str_warning_forced" : "",
|
||||||
|
"str_critical" : "",
|
||||||
|
"str_critical_forced" : "",
|
||||||
|
"critical_inverse" : "",
|
||||||
|
"warning_inverse" : "",
|
||||||
|
"max" : "",
|
||||||
|
"min" : "",
|
||||||
|
"post_process" : "",
|
||||||
|
"disabled" : "",
|
||||||
|
"min_ff_event" : "",
|
||||||
|
"status" : "",
|
||||||
|
"timestamp" : "",
|
||||||
|
"custom_id" : "",
|
||||||
|
"critical_instructions" : "",
|
||||||
|
"warning_instructions" : "",
|
||||||
|
"unknown_instructions" : "",
|
||||||
|
"quiet" : "",
|
||||||
|
"module_ff_interval" : "",
|
||||||
|
"crontab" : "",
|
||||||
|
"min_ff_event_normal" : "",
|
||||||
|
"min_ff_event_warning" : "",
|
||||||
|
"min_ff_event_critical" : "",
|
||||||
|
"ff_type" : "",
|
||||||
|
"ff_timeout" : "",
|
||||||
|
"each_ff" : "",
|
||||||
|
"module_parent_unlink" : "",
|
||||||
|
"alert" : []
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value in default_values.items():
|
||||||
|
if key in module:
|
||||||
|
module[key] = value
|
||||||
|
|
||||||
|
return module
|
||||||
|
|
||||||
|
####
|
||||||
|
# Returns module in XML format. Accepts only {dict}
|
||||||
|
#########################################################################################
|
||||||
|
def print_module(
|
||||||
|
module: dict = None,
|
||||||
|
print_flag: bool = False
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
Returns module in XML format. Accepts only {dict}.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
module (dict, optional): Dictionary containing module data. Defaults to None.
|
||||||
|
print_flag (bool, optional): Flag to print the module XML to STDOUT. Defaults to False.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Module data in XML format.
|
||||||
|
"""
|
||||||
|
from .output import print_stdout
|
||||||
|
|
||||||
|
module_xml = ""
|
||||||
|
|
||||||
|
if module is not None:
|
||||||
|
data = dict(module)
|
||||||
|
module_xml = ("<module>\n"
|
||||||
|
"\t<name><![CDATA[" + str(data["name"]) + "]]></name>\n"
|
||||||
|
"\t<type>" + str(data["type"]) + "</type>\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
if type(data["type"]) is not str and "string" not in data["type"]: #### Strip spaces if module not generic_data_string
|
||||||
|
data["value"] = data["value"].strip()
|
||||||
|
|
||||||
|
if isinstance(data["value"], list): # Checks if value is a list
|
||||||
|
module_xml += "\t<datalist>\n"
|
||||||
|
for value in data["value"]:
|
||||||
|
if type(value) is dict and "value" in value:
|
||||||
|
module_xml += "\t<data>\n"
|
||||||
|
module_xml += "\t\t<value><![CDATA[" + str(value["value"]) + "]]></value>\n"
|
||||||
|
if "timestamp" in value:
|
||||||
|
module_xml += "\t\t<timestamp><![CDATA[" + str(value["timestamp"]) + "]]></timestamp>\n"
|
||||||
|
module_xml += "\t</data>\n"
|
||||||
|
module_xml += "\t</datalist>\n"
|
||||||
|
else:
|
||||||
|
module_xml += "\t<data><![CDATA[" + str(data["value"]) + "]]></data>\n"
|
||||||
|
|
||||||
|
if "desc" in data and len(str(data["desc"]).strip()) > 0:
|
||||||
|
module_xml += "\t<description><![CDATA[" + str(data["desc"]) + "]]></description>\n"
|
||||||
|
|
||||||
|
if "unit" in data and len(str(data["unit"]).strip()) > 0:
|
||||||
|
module_xml += "\t<unit><![CDATA[" + str(data["unit"]) + "]]></unit>\n"
|
||||||
|
|
||||||
|
if "interval" in data and len(str(data["interval"]).strip()) > 0:
|
||||||
|
module_xml += "\t<module_interval><![CDATA[" + str(data["interval"]) + "]]></module_interval>\n"
|
||||||
|
|
||||||
|
if "tags" in data and len(str(data["tags"]).strip()) > 0:
|
||||||
|
module_xml += "\t<tags>" + str(data["tags"]) + "</tags>\n"
|
||||||
|
|
||||||
|
if "module_group" in data and len(str(data["module_group"]).strip()) > 0:
|
||||||
|
module_xml += "\t<module_group>" + str(data["module_group"]) + "</module_group>\n"
|
||||||
|
|
||||||
|
if "module_parent" in data and len(str(data["module_parent"]).strip()) > 0:
|
||||||
|
module_xml += "\t<module_parent>" + str(data["module_parent"]) + "</module_parent>\n"
|
||||||
|
|
||||||
|
if "min_warning" in data and len(str(data["min_warning"]).strip()) > 0:
|
||||||
|
module_xml += "\t<min_warning><![CDATA[" + str(data["min_warning"]) + "]]></min_warning>\n"
|
||||||
|
|
||||||
|
if "min_warning_forced" in data and len(str(data["min_warning_forced"]).strip()) > 0:
|
||||||
|
module_xml += "\t<min_warning_forced><![CDATA[" + str(data["min_warning_forced"]) + "]]></min_warning_forced>\n"
|
||||||
|
|
||||||
|
if "max_warning" in data and len(str(data["max_warning"]).strip()) > 0:
|
||||||
|
module_xml += "\t<max_warning><![CDATA[" + str(data["max_warning"]) + "]]></max_warning>\n"
|
||||||
|
|
||||||
|
if "max_warning_forced" in data and len(str(data["max_warning_forced"]).strip()) > 0:
|
||||||
|
module_xml += "\t<max_warning_forced><![CDATA[" + str(data["max_warning_forced"]) + "]]></max_warning_forced>\n"
|
||||||
|
|
||||||
|
if "min_critical" in data and len(str(data["min_critical"]).strip()) > 0:
|
||||||
|
module_xml += "\t<min_critical><![CDATA[" + str(data["min_critical"]) + "]]></min_critical>\n"
|
||||||
|
|
||||||
|
if "min_critical_forced" in data and len(str(data["min_critical_forced"]).strip()) > 0:
|
||||||
|
module_xml += "\t<min_critical_forced><![CDATA[" + str(data["min_critical_forced"]) + "]]></min_critical_forced>\n"
|
||||||
|
|
||||||
|
if "max_critical" in data and len(str(data["max_critical"]).strip()) > 0:
|
||||||
|
module_xml += "\t<max_critical><![CDATA[" + str(data["max_critical"]) + "]]></max_critical>\n"
|
||||||
|
|
||||||
|
if "max_critical_forced" in data and len(str(data["max_critical_forced"]).strip()) > 0:
|
||||||
|
module_xml += "\t<max_critical_forced><![CDATA[" + str(data["max_critical_forced"]) + "]]></max_critical_forced>\n"
|
||||||
|
|
||||||
|
if "str_warning" in data and len(str(data["str_warning"]).strip()) > 0:
|
||||||
|
module_xml += "\t<str_warning><![CDATA[" + str(data["str_warning"]) + "]]></str_warning>\n"
|
||||||
|
|
||||||
|
if "str_warning_forced" in data and len(str(data["str_warning_forced"]).strip()) > 0:
|
||||||
|
module_xml += "\t<str_warning_forced><![CDATA[" + str(data["str_warning_forced"]) + "]]></str_warning_forced>\n"
|
||||||
|
|
||||||
|
if "str_critical" in data and len(str(data["str_critical"]).strip()) > 0:
|
||||||
|
module_xml += "\t<str_critical><![CDATA[" + str(data["str_critical"]) + "]]></str_critical>\n"
|
||||||
|
|
||||||
|
if "str_critical_forced" in data and len(str(data["str_critical_forced"]).strip()) > 0:
|
||||||
|
module_xml += "\t<str_critical_forced><![CDATA[" + str(data["str_critical_forced"]) + "]]></str_critical_forced>\n"
|
||||||
|
|
||||||
|
if "critical_inverse" in data and len(str(data["critical_inverse"]).strip()) > 0:
|
||||||
|
module_xml += "\t<critical_inverse><![CDATA[" + str(data["critical_inverse"]) + "]]></critical_inverse>\n"
|
||||||
|
|
||||||
|
if "warning_inverse" in data and len(str(data["warning_inverse"]).strip()) > 0:
|
||||||
|
module_xml += "\t<warning_inverse><![CDATA[" + str(data["warning_inverse"]) + "]]></warning_inverse>\n"
|
||||||
|
|
||||||
|
if "max" in data and len(str(data["max"]).strip()) > 0:
|
||||||
|
module_xml += "\t<max><![CDATA[" + str(data["max"]) + "]]></max>\n"
|
||||||
|
|
||||||
|
if "min" in data and len(str(data["min"]).strip()) > 0:
|
||||||
|
module_xml += "\t<min><![CDATA[" + str(data["min"]) + "]]></min>\n"
|
||||||
|
|
||||||
|
if "post_process" in data and len(str(data["post_process"]).strip()) > 0:
|
||||||
|
module_xml += "\t<post_process><![CDATA[" + str(data["post_process"]) + "]]></post_process>\n"
|
||||||
|
|
||||||
|
if "disabled" in data and len(str(data["disabled"]).strip()) > 0:
|
||||||
|
module_xml += "\t<disabled><![CDATA[" + str(data["disabled"]) + "]]></disabled>\n"
|
||||||
|
|
||||||
|
if "min_ff_event" in data and len(str(data["min_ff_event"]).strip()) > 0:
|
||||||
|
module_xml += "\t<min_ff_event><![CDATA[" + str(data["min_ff_event"]) + "]]></min_ff_event>\n"
|
||||||
|
|
||||||
|
if "status" in data and len(str(data["status"]).strip()) > 0:
|
||||||
|
module_xml += "\t<status><![CDATA[" + str(data["status"]) + "]]></status>\n"
|
||||||
|
|
||||||
|
if "timestamp" in data and len(str(data["timestamp"]).strip()) > 0:
|
||||||
|
module_xml += "\t<timestamp><![CDATA[" + str(data["timestamp"]) + "]]></timestamp>\n"
|
||||||
|
|
||||||
|
if "custom_id" in data and len(str(data["custom_id"]).strip()) > 0:
|
||||||
|
module_xml += "\t<custom_id><![CDATA[" + str(data["custom_id"]) + "]]></custom_id>\n"
|
||||||
|
|
||||||
|
if "critical_instructions" in data and len(str(data["critical_instructions"]).strip()) > 0:
|
||||||
|
module_xml += "\t<critical_instructions><![CDATA[" + str(data["critical_instructions"]) + "]]></critical_instructions>\n"
|
||||||
|
|
||||||
|
if "warning_instructions" in data and len(str(data["warning_instructions"]).strip()) > 0:
|
||||||
|
module_xml += "\t<warning_instructions><![CDATA[" + str(data["warning_instructions"]) + "]]></warning_instructions>\n"
|
||||||
|
|
||||||
|
if "unknown_instructions" in data and len(str(data["unknown_instructions"]).strip()) > 0:
|
||||||
|
module_xml += "\t<unknown_instructions><![CDATA[" + str(data["unknown_instructions"]) + "]]></unknown_instructions>\n"
|
||||||
|
|
||||||
|
if "quiet" in data and len(str(data["quiet"]).strip()) > 0:
|
||||||
|
module_xml += "\t<quiet><![CDATA[" + str(data["quiet"]) + "]]></quiet>\n"
|
||||||
|
|
||||||
|
if "module_ff_interval" in data and len(str(data["module_ff_interval"]).strip()) > 0:
|
||||||
|
module_xml += "\t<module_ff_interval><![CDATA[" + str(data["module_ff_interval"]) + "]]></module_ff_interval>\n"
|
||||||
|
|
||||||
|
if "crontab" in data and len(str(data["crontab"]).strip()) > 0:
|
||||||
|
module_xml += "\t<crontab><![CDATA[" + str(data["crontab"]) + "]]></crontab>\n"
|
||||||
|
|
||||||
|
if "min_ff_event_normal" in data and len(str(data["min_ff_event_normal"]).strip()) > 0:
|
||||||
|
module_xml += "\t<min_ff_event_normal><![CDATA[" + str(data["min_ff_event_normal"]) + "]]></min_ff_event_normal>\n"
|
||||||
|
|
||||||
|
if "min_ff_event_warning" in data and len(str(data["min_ff_event_warning"]).strip()) > 0:
|
||||||
|
module_xml += "\t<min_ff_event_warning><![CDATA[" + str(data["min_ff_event_warning"]) + "]]></min_ff_event_warning>\n"
|
||||||
|
|
||||||
|
if "min_ff_event_critical" in data and len(str(data["min_ff_event_critical"]).strip()) > 0:
|
||||||
|
module_xml += "\t<min_ff_event_critical><![CDATA[" + str(data["min_ff_event_critical"]) + "]]></min_ff_event_critical>\n"
|
||||||
|
|
||||||
|
if "ff_type" in data and len(str(data["ff_type"]).strip()) > 0:
|
||||||
|
module_xml += "\t<ff_type><![CDATA[" + str(data["ff_type"]) + "]]></ff_type>\n"
|
||||||
|
|
||||||
|
if "ff_timeout" in data and len(str(data["ff_timeout"]).strip()) > 0:
|
||||||
|
module_xml += "\t<ff_timeout><![CDATA[" + str(data["ff_timeout"]) + "]]></ff_timeout>\n"
|
||||||
|
|
||||||
|
if "each_ff" in data and len(str(data["each_ff"]).strip()) > 0:
|
||||||
|
module_xml += "\t<each_ff><![CDATA[" + str(data["each_ff"]) + "]]></each_ff>\n"
|
||||||
|
|
||||||
|
if "module_parent_unlink" in data and len(str(data["module_parent_unlink"]).strip()) > 0:
|
||||||
|
module_xml += "\t<module_parent_unlink><![CDATA[" + str(data["module_parent_unlink"]) + "]]></module_parent_unlink>\n"
|
||||||
|
|
||||||
|
if "alert" in data:
|
||||||
|
for alert in data["alert"]:
|
||||||
|
if len(str(alert).strip()) > 0:
|
||||||
|
module_xml += "\t<alert_template><![CDATA[" + str(alert) + "]]></alert_template>\n"
|
||||||
|
module_xml += "</module>\n"
|
||||||
|
|
||||||
|
if print_flag:
|
||||||
|
print_stdout(module_xml)
|
||||||
|
|
||||||
|
return module_xml
|
||||||
|
|
||||||
|
####
|
||||||
|
# Init log module template
|
||||||
|
#########################################################################################
|
||||||
|
def init_log_module(
|
||||||
|
default_values: dict = {}
|
||||||
|
) -> dict:
|
||||||
|
"""
|
||||||
|
Initializes a log module template with default values.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
default_values (dict, optional): Default values to initialize the log module with. Defaults to an empty dictionary.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: Dictionary representing the log module template with default values.
|
||||||
|
"""
|
||||||
|
module = {
|
||||||
|
"source" : None,
|
||||||
|
"value" : ""
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value in default_values.items():
|
||||||
|
if key in module:
|
||||||
|
module[key] = value
|
||||||
|
|
||||||
|
return module
|
||||||
|
|
||||||
|
####
|
||||||
|
# Returns log module in XML format. Accepts only {dict}
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def print_log_module(
|
||||||
|
module: dict = None,
|
||||||
|
print_flag: bool = False
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
Returns log module in XML format. Accepts only {dict}.
|
||||||
|
- Only works with one module at a time: otherwise iteration is needed.
|
||||||
|
- Module "value" field accepts str type.
|
||||||
|
- Use not_print_flag to avoid printing the XML (only populates variables).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
module (dict, optional): Dictionary representing the log module. Defaults to None.
|
||||||
|
print_flag (bool, optional): Flag to indicate whether to print the XML. Defaults to False.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: XML representation of the log module.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from .output import print_stdout
|
||||||
|
|
||||||
|
module_xml = ""
|
||||||
|
|
||||||
|
if module is not None:
|
||||||
|
data = dict(module)
|
||||||
|
module_xml = ("<log_module>\n"
|
||||||
|
"\t<source><![CDATA[" + str(data["source"]) + "]]></source>\n"
|
||||||
|
"\t<data>\"" + str(data["value"]) + "\"</data>\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
module_xml += "</log_module>\n"
|
||||||
|
|
||||||
|
if print_flag:
|
||||||
|
print_stdout(module_xml)
|
||||||
|
|
||||||
|
return module_xml
|
|
@ -0,0 +1,137 @@
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
|
||||||
|
####
|
||||||
|
# Internal: Alias for output.print_debug function
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def _print_debug(
|
||||||
|
var = "",
|
||||||
|
print_errors: bool = False
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Prints any list, dict, string, float or integer as a json
|
||||||
|
|
||||||
|
Args:
|
||||||
|
var (any, optional): Variable to be printed. Defaults to "".
|
||||||
|
print_errors (bool, optional): Flag to indicate whether to print errors. Defaults to False.
|
||||||
|
"""
|
||||||
|
print_debug(var, print_errors)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Prints message in stdout
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def print_stdout(
|
||||||
|
message: str = ""
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Prints message in stdout
|
||||||
|
|
||||||
|
Args:
|
||||||
|
message (str, optional): Message to be printed. Defaults to "".
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
print(message)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Prints message in stderr
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def print_stderr(
|
||||||
|
message: str = ""
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Prints message in stderr
|
||||||
|
|
||||||
|
Args:
|
||||||
|
message (str, optional): Message to be printed. Defaults to "".
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
print(message, file=sys.stderr)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Prints dictionary in formatted json string.
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def print_debug(
|
||||||
|
var = "",
|
||||||
|
print_errors: bool = False
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Prints any list, dict, string, float or integer as a json
|
||||||
|
|
||||||
|
Args:
|
||||||
|
var: Variable to be printed.
|
||||||
|
print_errors (bool, optional): Whether to print errors. Defaults to False.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
debug_json = json.dumps(var, indent=4)
|
||||||
|
print_stdout(debug_json)
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
if print_errors:
|
||||||
|
print_stderr(f"debug_dict: Failed to dump. Error: {e}")
|
||||||
|
except Exception as e:
|
||||||
|
if print_errors:
|
||||||
|
print_stderr(f"debug_dict: Unexpected error: {e}")
|
||||||
|
|
||||||
|
####
|
||||||
|
# Add new line to log file
|
||||||
|
#########################################################################################
|
||||||
|
def logger(
|
||||||
|
log_file: str = "",
|
||||||
|
message: str = "",
|
||||||
|
log_level: str = "",
|
||||||
|
add_date: bool = True,
|
||||||
|
print_errors: bool = False
|
||||||
|
) -> bool:
|
||||||
|
'''
|
||||||
|
Add new line to log file
|
||||||
|
|
||||||
|
Args:
|
||||||
|
log_file (str): Path to the log file.
|
||||||
|
message (str): Message to be added to the log.
|
||||||
|
log_level (str): Log level, if applicable. Defaults to an empty string.
|
||||||
|
add_date (bool): Whether to add the current date and time to the log entry. Defaults to True.
|
||||||
|
print_errors (bool): Whether to print errors. Defaults to False.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if the log entry was successfully added, False otherwise.
|
||||||
|
'''
|
||||||
|
from .general import now
|
||||||
|
|
||||||
|
try:
|
||||||
|
if not os.path.exists(log_file):
|
||||||
|
with open(log_file, 'w') as file:
|
||||||
|
pass # Creates an empty file
|
||||||
|
elif not os.access(log_file, os.W_OK):
|
||||||
|
if print_errors:
|
||||||
|
print_stderr(f"Log file '{log_file}' is not writable.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
with open(log_file, 'a') as file:
|
||||||
|
final_message = ""
|
||||||
|
|
||||||
|
if add_date:
|
||||||
|
final_message += now() + " "
|
||||||
|
if log_level != "":
|
||||||
|
final_message += "[" + log_level + "] "
|
||||||
|
|
||||||
|
final_message += message + "\n"
|
||||||
|
|
||||||
|
file.write(final_message)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
if print_errors:
|
||||||
|
print_stderr(f"An error occurred while appending to the log: {e}")
|
||||||
|
return False
|
|
@ -0,0 +1,330 @@
|
||||||
|
from easysnmp import Session
|
||||||
|
from pysnmp.hlapi import *
|
||||||
|
|
||||||
|
####
|
||||||
|
# Define global variables dict, used in functions as default values.
|
||||||
|
# Its values can be changed.
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
_GLOBAL_VARIABLES = {
|
||||||
|
'hostname' : "",
|
||||||
|
'version' : 1,
|
||||||
|
'community' : "public",
|
||||||
|
'user' : "",
|
||||||
|
'auth_protocol' : "",
|
||||||
|
'auth_password' : "",
|
||||||
|
'privacy_protocol' : "",
|
||||||
|
'privacy_password' : "",
|
||||||
|
'security_level' : "noAuthNoPriv",
|
||||||
|
'timeout' : 2,
|
||||||
|
'retries' : 1,
|
||||||
|
'remote_port' : 161,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
####
|
||||||
|
# Set a global variable with the specified name and assigns a value to it.
|
||||||
|
#########################################################################################
|
||||||
|
def set_global_variable(
|
||||||
|
variable_name: str = "",
|
||||||
|
value = None
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Sets the value of a global variable in the '_GLOBAL_VARIABLES' dictionary.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
variable_name (str): Name of the variable to set.
|
||||||
|
value (any): Value to assign to the variable.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
from .general import set_dict_key_value
|
||||||
|
|
||||||
|
set_dict_key_value(_GLOBAL_VARIABLES, variable_name, value)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Get a global variable with the specified name.
|
||||||
|
#########################################################################################
|
||||||
|
def get_global_variable(
|
||||||
|
variable_name: str = ""
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Gets the value of a global variable in the '_GLOBAL_VARIABLES' dictionary.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
variable_name (str): Name of the variable to set.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
from .general import get_dict_key_value
|
||||||
|
|
||||||
|
get_dict_key_value(_GLOBAL_VARIABLES, variable_name)
|
||||||
|
|
||||||
|
####
|
||||||
|
# A class that represents an SNMP target, providing methods for setting up SNMP configuration and performing SNMP operations like GET and WALK.
|
||||||
|
#########################################################################################
|
||||||
|
class SNMPTarget:
|
||||||
|
"""
|
||||||
|
A class that represents an SNMP target, providing methods for setting up SNMP configuration
|
||||||
|
and performing SNMP operations like GET and WALK.
|
||||||
|
"""
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
host: str = _GLOBAL_VARIABLES['hostname'],
|
||||||
|
version: int = _GLOBAL_VARIABLES['version'],
|
||||||
|
community: str = _GLOBAL_VARIABLES['community'],
|
||||||
|
user: str = _GLOBAL_VARIABLES['user'],
|
||||||
|
auth_protocol: str = _GLOBAL_VARIABLES['auth_protocol'],
|
||||||
|
auth_password: str = _GLOBAL_VARIABLES['auth_password'],
|
||||||
|
privacy_protocol: str = _GLOBAL_VARIABLES['privacy_protocol'],
|
||||||
|
privacy_password: str = _GLOBAL_VARIABLES['privacy_password'],
|
||||||
|
security_level: str = _GLOBAL_VARIABLES['security_level'],
|
||||||
|
timeout: int = _GLOBAL_VARIABLES['timeout'],
|
||||||
|
retries: int = _GLOBAL_VARIABLES['retries'],
|
||||||
|
remote_port: int = _GLOBAL_VARIABLES['remote_port']):
|
||||||
|
|
||||||
|
self.session = create_snmp_session(
|
||||||
|
host,
|
||||||
|
version,
|
||||||
|
community,
|
||||||
|
user,
|
||||||
|
auth_protocol,
|
||||||
|
auth_password,
|
||||||
|
privacy_protocol,
|
||||||
|
privacy_password,
|
||||||
|
security_level,
|
||||||
|
timeout,
|
||||||
|
retries,
|
||||||
|
remote_port
|
||||||
|
)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Performs an SNMP GET operation to retrieve the value of a specified OID.
|
||||||
|
#########################################################################################
|
||||||
|
def snmp_get(self, oid):
|
||||||
|
"""
|
||||||
|
Performs an SNMP GET operation to retrieve the value of a specified OID.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
oid (str): The OID (Object Identifier) for the SNMP GET operation.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The value retrieved from the specified OID.
|
||||||
|
"""
|
||||||
|
return self.session.get(oid).value
|
||||||
|
|
||||||
|
####
|
||||||
|
# Performs an SNMP WALK operation to retrieve a list of values from a subtree of the MIB.
|
||||||
|
#########################################################################################
|
||||||
|
def snmp_walk(self, oid):
|
||||||
|
"""
|
||||||
|
Performs an SNMP WALK operation to retrieve a list of values from a subtree of the MIB.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
oid (str): The OID (Object Identifier) representing the root of the subtree.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list: A list of values retrieved from the specified subtree.
|
||||||
|
"""
|
||||||
|
|
||||||
|
oid_items = self.session.walk(oid)
|
||||||
|
|
||||||
|
oid_value_dict = {} # Initialize an empty dictionary
|
||||||
|
|
||||||
|
for item in oid_items:
|
||||||
|
oid_with_index = f"{item.oid}.{item.oid_index}"
|
||||||
|
oid_value_dict[oid_with_index] = item.value
|
||||||
|
|
||||||
|
return oid_value_dict
|
||||||
|
|
||||||
|
####
|
||||||
|
# Creates an SNMP session based on the global configuration variables.
|
||||||
|
#########################################################################################
|
||||||
|
def create_snmp_session(
|
||||||
|
host: str = _GLOBAL_VARIABLES['hostname'],
|
||||||
|
version: int = _GLOBAL_VARIABLES['version'],
|
||||||
|
community: str = _GLOBAL_VARIABLES['community'],
|
||||||
|
user: str = _GLOBAL_VARIABLES['user'],
|
||||||
|
auth_protocol: str = _GLOBAL_VARIABLES['auth_protocol'],
|
||||||
|
auth_password: str = _GLOBAL_VARIABLES['auth_password'],
|
||||||
|
privacy_protocol: str = _GLOBAL_VARIABLES['privacy_protocol'],
|
||||||
|
privacy_password: str = _GLOBAL_VARIABLES['privacy_password'],
|
||||||
|
security_level: str = _GLOBAL_VARIABLES['security_level'],
|
||||||
|
timeout: int = _GLOBAL_VARIABLES['timeout'],
|
||||||
|
retries: int = _GLOBAL_VARIABLES['retries'],
|
||||||
|
remote_port: int = _GLOBAL_VARIABLES['remote_port']
|
||||||
|
) -> Session:
|
||||||
|
"""
|
||||||
|
Creates an SNMP session based on the provided configuration or global variables.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
hostname (str): Hostname or IP address of the SNMP agent.
|
||||||
|
version (int): SNMP version (1, 2, or 3).
|
||||||
|
community (str): SNMP community string (for version 1 or 2).
|
||||||
|
user (str): SNMPv3 username (for version 3).
|
||||||
|
auth_protocol (str): SNMPv3 authentication protocol (e.g., 'MD5' or 'SHA').
|
||||||
|
auth_password (str): SNMPv3 authentication password.
|
||||||
|
privacy_protocol (str): SNMPv3 privacy protocol (e.g., 'AES' or 'DES').
|
||||||
|
privacy_password (str): SNMPv3 privacy password.
|
||||||
|
security_level (str): SNMPv3 security level ('noAuthNoPriv', 'authNoPriv', 'authPriv').
|
||||||
|
timeout (int): SNMP request timeout in seconds.
|
||||||
|
retries (int): Number of SNMP request retries.
|
||||||
|
remote_port (int): SNMP agent port.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Session: An SNMP session configured based on the provided or global variables.
|
||||||
|
"""
|
||||||
|
|
||||||
|
session_kwargs = {
|
||||||
|
"hostname": host,
|
||||||
|
"version": version,
|
||||||
|
"use_numeric": True,
|
||||||
|
"timeout": timeout,
|
||||||
|
"retries": retries,
|
||||||
|
"remote_port": remote_port
|
||||||
|
}
|
||||||
|
|
||||||
|
if version == 1 or version == 2:
|
||||||
|
session_kwargs["community"] = community
|
||||||
|
elif version == 3:
|
||||||
|
session_kwargs["security_username"] = user
|
||||||
|
|
||||||
|
if security_level == "authPriv":
|
||||||
|
session_kwargs.update({
|
||||||
|
"auth_protocol": auth_protocol,
|
||||||
|
"auth_password": auth_password,
|
||||||
|
"privacy_protocol": privacy_protocol,
|
||||||
|
"privacy_password": privacy_password,
|
||||||
|
"security_level": "auth_with_privacy"
|
||||||
|
})
|
||||||
|
elif security_level == "authNoPriv":
|
||||||
|
session_kwargs.update({
|
||||||
|
"auth_protocol": auth_protocol,
|
||||||
|
"auth_password": auth_password,
|
||||||
|
"security_level": "auth_without_privacy"
|
||||||
|
})
|
||||||
|
elif security_level == "noAuthNoPriv":
|
||||||
|
session_kwargs["security_level"] = "no_auth_or_privacy"
|
||||||
|
|
||||||
|
return Session(**session_kwargs)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Performs an SNMP GET operation to retrieve the value of a specified OID.
|
||||||
|
#########################################################################################
|
||||||
|
def snmp_get(
|
||||||
|
oid: str,
|
||||||
|
host: str = _GLOBAL_VARIABLES['hostname'],
|
||||||
|
version: int = _GLOBAL_VARIABLES['version'],
|
||||||
|
community: str = _GLOBAL_VARIABLES['community'],
|
||||||
|
user: str = _GLOBAL_VARIABLES['user'],
|
||||||
|
auth_protocol: str = _GLOBAL_VARIABLES['auth_protocol'],
|
||||||
|
auth_password: str = _GLOBAL_VARIABLES['auth_password'],
|
||||||
|
privacy_protocol: str = _GLOBAL_VARIABLES['privacy_protocol'],
|
||||||
|
privacy_password: str = _GLOBAL_VARIABLES['privacy_password'],
|
||||||
|
security_level: str = _GLOBAL_VARIABLES['security_level'],
|
||||||
|
timeout: int = _GLOBAL_VARIABLES['timeout'],
|
||||||
|
retries: int = _GLOBAL_VARIABLES['retries'],
|
||||||
|
remote_port: int = _GLOBAL_VARIABLES['remote_port']
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
Performs an SNMP GET operation to retrieve the value of a specified OID.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
oid (str): The OID (Object Identifier) for the SNMP GET operation.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The value retrieved from the specified OID.
|
||||||
|
"""
|
||||||
|
session = create_snmp_session(host,version,community,user,auth_protocol,auth_password,privacy_protocol,privacy_password,security_level,timeout,retries,remote_port)
|
||||||
|
return session.get(oid).value
|
||||||
|
|
||||||
|
####
|
||||||
|
# Performs an SNMP WALK operation to retrieve a list of values from a subtree of the MIB.
|
||||||
|
#########################################################################################
|
||||||
|
def snmp_walk(
|
||||||
|
oid: str,
|
||||||
|
host: str = _GLOBAL_VARIABLES['hostname'],
|
||||||
|
version: int = _GLOBAL_VARIABLES['version'],
|
||||||
|
community: str = _GLOBAL_VARIABLES['community'],
|
||||||
|
user: str = _GLOBAL_VARIABLES['user'],
|
||||||
|
auth_protocol: str = _GLOBAL_VARIABLES['auth_protocol'],
|
||||||
|
auth_password: str = _GLOBAL_VARIABLES['auth_password'],
|
||||||
|
privacy_protocol: str = _GLOBAL_VARIABLES['privacy_protocol'],
|
||||||
|
privacy_password: str = _GLOBAL_VARIABLES['privacy_password'],
|
||||||
|
security_level: str = _GLOBAL_VARIABLES['security_level'],
|
||||||
|
timeout: int = _GLOBAL_VARIABLES['timeout'],
|
||||||
|
retries: int = _GLOBAL_VARIABLES['retries'],
|
||||||
|
remote_port: int = _GLOBAL_VARIABLES['remote_port']
|
||||||
|
) -> dict:
|
||||||
|
"""
|
||||||
|
Performs an SNMP WALK operation to retrieve a list of values from a subtree of the MIB.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
oid (str): The OID (Object Identifier) representing the root of the subtree.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list: A list of values retrieved from the specified subtree.
|
||||||
|
"""
|
||||||
|
session = create_snmp_session(host,version,community,user,auth_protocol,auth_password,privacy_protocol,privacy_password,security_level,timeout,retries,remote_port)
|
||||||
|
oid_items = session.walk(oid)
|
||||||
|
|
||||||
|
oid_value_dict = {}
|
||||||
|
|
||||||
|
for item in oid_items:
|
||||||
|
oid_with_index = f"{item.oid}.{item.oid_index}"
|
||||||
|
oid_value_dict[oid_with_index] = item.value
|
||||||
|
|
||||||
|
return oid_value_dict
|
||||||
|
|
||||||
|
####
|
||||||
|
# Sends an SNMP trap to the specified destination IP using the given OID, value, and community.
|
||||||
|
#########################################################################################
|
||||||
|
def snmp_trap(
|
||||||
|
trap_oid: str,
|
||||||
|
trap_value: str,
|
||||||
|
destination_ip: str,
|
||||||
|
community: str) -> None:
|
||||||
|
"""
|
||||||
|
Sends an SNMP trap to the specified destination IP using the given OID, value, and community.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
trap_oid (str): The OID (Object Identifier) for the SNMP trap.
|
||||||
|
trap_value (str): The value associated with the trap.
|
||||||
|
destination_ip (str): The IP address of the trap's destination.
|
||||||
|
community (str): The SNMP community string for authentication.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
trap_object = ObjectIdentity(trap_oid)
|
||||||
|
trap_value = OctetString(trap_value)
|
||||||
|
|
||||||
|
errorIndication, errorStatus, errorIndex, varBinds = next(
|
||||||
|
sendNotification(
|
||||||
|
SnmpEngine(),
|
||||||
|
CommunityData(community),
|
||||||
|
UdpTransportTarget((destination_ip, 162)),
|
||||||
|
ContextData(),
|
||||||
|
'trap',
|
||||||
|
NotificationType(
|
||||||
|
ObjectIdentity('SNMPv2-MIB', 'coldStart')
|
||||||
|
).addVarBinds(
|
||||||
|
(trap_object, trap_value)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if errorIndication:
|
||||||
|
print('Error:', errorIndication)
|
||||||
|
elif errorStatus:
|
||||||
|
print(
|
||||||
|
'%s at %s' %
|
||||||
|
(
|
||||||
|
errorStatus.prettyPrint(),
|
||||||
|
errorIndex and varBinds[int(errorIndex) - 1][0] or '?'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
print('SNMP trap sent successfully.')
|
|
@ -0,0 +1,249 @@
|
||||||
|
import sys
|
||||||
|
from queue import Queue
|
||||||
|
from threading import Thread
|
||||||
|
from multiprocessing import Pool, Manager
|
||||||
|
|
||||||
|
####
|
||||||
|
# Define multi-processing internal global variables.
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
_MANAGER = Manager()
|
||||||
|
_SHARED_DICT = _MANAGER.dict()
|
||||||
|
_SHARED_DICT_LOCK = _MANAGER.Lock()
|
||||||
|
|
||||||
|
####
|
||||||
|
# Internal: Alias for output.print_debug function
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def _print_debug(
|
||||||
|
var = "",
|
||||||
|
print_errors: bool = False
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Prints the provided variable in a JSON-like format.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
var: The variable (list, dict, string, float, integer) to be printed.
|
||||||
|
print_errors (bool): If True, prints any errors that occur during formatting.
|
||||||
|
"""
|
||||||
|
from .output import print_debug
|
||||||
|
print_debug(var, print_errors)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Internal use only: Run a given function in a thread
|
||||||
|
#########################################################################################
|
||||||
|
def _single_thread(
|
||||||
|
q = None,
|
||||||
|
function: callable = None,
|
||||||
|
errors: list = []
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Internal use only: Runs a given function in a thread.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
q: A queue from which to get parameters for the function.
|
||||||
|
function (callable): The function to be executed in the thread.
|
||||||
|
errors (list): A list to store any errors encountered during execution.
|
||||||
|
"""
|
||||||
|
params=q.get()
|
||||||
|
q.task_done()
|
||||||
|
try:
|
||||||
|
function(params)
|
||||||
|
except Exception as e:
|
||||||
|
errors.append("Error while runing single thread: "+str(e))
|
||||||
|
|
||||||
|
####
|
||||||
|
# Run a given function for given items list in a given number of threads
|
||||||
|
#########################################################################################
|
||||||
|
def run_threads(
|
||||||
|
max_threads: int = 1,
|
||||||
|
function: callable = None,
|
||||||
|
items: list = [],
|
||||||
|
print_errors: bool = False
|
||||||
|
) -> bool:
|
||||||
|
"""
|
||||||
|
Run a given function for a list of items in multiple threads.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
max_threads (int): Maximum number of threads to use.
|
||||||
|
function (callable): The function to be executed in each thread.
|
||||||
|
items (list): List of items to process.
|
||||||
|
print_errors (bool): Whether to print errors encountered during execution.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if all threads executed successfully, False otherwise.
|
||||||
|
"""
|
||||||
|
from .output import print_stderr
|
||||||
|
|
||||||
|
# Assign threads
|
||||||
|
threads = max_threads
|
||||||
|
|
||||||
|
if threads > len(items):
|
||||||
|
threads = len(items)
|
||||||
|
|
||||||
|
if threads < 1:
|
||||||
|
threads = 1
|
||||||
|
|
||||||
|
# Distribute items per thread
|
||||||
|
items_per_thread = []
|
||||||
|
thread = 0
|
||||||
|
for item in items:
|
||||||
|
if not 0 <= thread < len(items_per_thread):
|
||||||
|
items_per_thread.append([])
|
||||||
|
|
||||||
|
items_per_thread[thread].append(item)
|
||||||
|
|
||||||
|
thread += 1
|
||||||
|
if thread >= threads:
|
||||||
|
thread=0
|
||||||
|
|
||||||
|
# Run threads
|
||||||
|
try:
|
||||||
|
q=Queue()
|
||||||
|
for n_thread in range(threads) :
|
||||||
|
q.put(items_per_thread[n_thread])
|
||||||
|
|
||||||
|
run_threads = []
|
||||||
|
errors = []
|
||||||
|
|
||||||
|
for n_thread in range(threads):
|
||||||
|
t = Thread(target=_single_thread, args=(q, function, errors))
|
||||||
|
t.daemon=True
|
||||||
|
t.start()
|
||||||
|
run_threads.append(t)
|
||||||
|
|
||||||
|
for t in run_threads:
|
||||||
|
t.join()
|
||||||
|
|
||||||
|
q.join()
|
||||||
|
|
||||||
|
if print_errors:
|
||||||
|
for error in errors:
|
||||||
|
print_stderr(str(error))
|
||||||
|
|
||||||
|
if len(errors) > 0:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
if print_errors:
|
||||||
|
print_stderr("Error while running threads: "+str(e))
|
||||||
|
return False
|
||||||
|
|
||||||
|
####
|
||||||
|
# Set a given value to a key in the internal shared dict.
|
||||||
|
# Used by all parallel processes.
|
||||||
|
#########################################################################################
|
||||||
|
def set_shared_dict_value(
|
||||||
|
key: str = None,
|
||||||
|
value = None
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Set a value for a key in the internal shared dictionary.
|
||||||
|
This function is used by all parallel processes.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key (str): The key in the shared dictionary.
|
||||||
|
value: The value to be assigned to the key.
|
||||||
|
"""
|
||||||
|
global _SHARED_DICT
|
||||||
|
|
||||||
|
if key is not None:
|
||||||
|
with _SHARED_DICT_LOCK:
|
||||||
|
_SHARED_DICT[key] = value
|
||||||
|
|
||||||
|
####
|
||||||
|
# Add a given value to a key in the internal shared dict.
|
||||||
|
# Used by all parallel processes.
|
||||||
|
#########################################################################################
|
||||||
|
def add_shared_dict_value(
|
||||||
|
key: str = None,
|
||||||
|
value = None
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Add a value to a key in the internal shared dictionary.
|
||||||
|
This function is used by all parallel processes.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key (str): The key in the shared dictionary.
|
||||||
|
value: The value to be added to the key.
|
||||||
|
"""
|
||||||
|
global _SHARED_DICT
|
||||||
|
|
||||||
|
if key is not None:
|
||||||
|
with _SHARED_DICT_LOCK:
|
||||||
|
if key in _SHARED_DICT:
|
||||||
|
_SHARED_DICT[key] += value
|
||||||
|
else:
|
||||||
|
set_shared_dict_value(key, value)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Get the value of a key in the internal shared dict.
|
||||||
|
# Used by all parallel processes.
|
||||||
|
#########################################################################################
|
||||||
|
def get_shared_dict_value(
|
||||||
|
key: str = None
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Get the value of a key in the internal shared dictionary.
|
||||||
|
This function is used by all parallel processes.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key (str): The key in the shared dictionary.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The value associated with the key, or None if the key does not exist.
|
||||||
|
"""
|
||||||
|
global _SHARED_DICT
|
||||||
|
|
||||||
|
with _SHARED_DICT_LOCK:
|
||||||
|
if key in _SHARED_DICT and key is not None:
|
||||||
|
return _SHARED_DICT[key]
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
####
|
||||||
|
# Run a given function for given items list in a given number of processes
|
||||||
|
# Given function receives each item as first parameter
|
||||||
|
#########################################################################################
|
||||||
|
def run_processes(
|
||||||
|
max_processes: int = 1,
|
||||||
|
function: callable = None,
|
||||||
|
items: list = [],
|
||||||
|
print_errors: bool = False
|
||||||
|
) -> bool:
|
||||||
|
"""
|
||||||
|
Run a given function for given items list in a given number of processes
|
||||||
|
|
||||||
|
Args:
|
||||||
|
max_processes (int): The maximum number of processes to run in parallel.
|
||||||
|
function (callable): The function to be executed for each item.
|
||||||
|
items (list): List of items to be processed.
|
||||||
|
print_errors (bool): Whether to print errors.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if all processes completed successfully, False otherwise.
|
||||||
|
"""
|
||||||
|
from .output import print_stderr
|
||||||
|
|
||||||
|
# Assign processes
|
||||||
|
processes = max_processes
|
||||||
|
|
||||||
|
if processes > len(items):
|
||||||
|
processes = len(items)
|
||||||
|
|
||||||
|
if processes < 1:
|
||||||
|
processes = 1
|
||||||
|
|
||||||
|
# Run processes
|
||||||
|
with Pool(processes) as pool:
|
||||||
|
try:
|
||||||
|
pool.map(function, items)
|
||||||
|
result = True
|
||||||
|
except Exception as error:
|
||||||
|
if print_errors:
|
||||||
|
print_stderr(str(error))
|
||||||
|
result = False
|
||||||
|
|
||||||
|
return result
|
|
@ -0,0 +1,258 @@
|
||||||
|
from datetime import datetime
|
||||||
|
from subprocess import *
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
####
|
||||||
|
# Define global variables dict, used in functions as default values.
|
||||||
|
# Its values can be changed.
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
_GLOBAL_VARIABLES = {
|
||||||
|
'transfer_mode' : 'tentacle',
|
||||||
|
'temporal' : '/tmp',
|
||||||
|
'data_dir' : '/var/spool/pandora/data_in/',
|
||||||
|
'tentacle_client' : 'tentacle_client',
|
||||||
|
'tentacle_ip' : '127.0.0.1',
|
||||||
|
'tentacle_port' : 41121,
|
||||||
|
'tentacle_extra_opts' : '',
|
||||||
|
'tentacle_retries' : 1
|
||||||
|
}
|
||||||
|
|
||||||
|
####
|
||||||
|
# Internal: Alias for output.print_debug function
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def _print_debug(
|
||||||
|
var = "",
|
||||||
|
print_errors: bool = False
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Prints any list, dict, string, float or integer as a json
|
||||||
|
|
||||||
|
Args:
|
||||||
|
var: The variable to be printed.
|
||||||
|
print_errors (bool): Whether to print errors.
|
||||||
|
"""
|
||||||
|
from .output import print_debug
|
||||||
|
print_debug(var, print_errors)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Set a global variable with the specified name and assigns a value to it.
|
||||||
|
#########################################################################################
|
||||||
|
def set_global_variable(
|
||||||
|
variable_name: str = "",
|
||||||
|
value = None
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Sets the value of a global variable in the '_GLOBAL_VARIABLES' dictionary.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
variable_name (str): Name of the variable to set.
|
||||||
|
value (any): Value to assign to the variable.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
from .general import set_dict_key_value
|
||||||
|
|
||||||
|
set_dict_key_value(_GLOBAL_VARIABLES, variable_name, value)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Get a global variable with the specified name.
|
||||||
|
#########################################################################################
|
||||||
|
def get_global_variable(
|
||||||
|
variable_name: str = ""
|
||||||
|
)-> None:
|
||||||
|
"""
|
||||||
|
Gets the value of a global variable in the '_GLOBAL_VARIABLES' dictionary.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
variable_name (str): Name of the variable to set.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
from .general import get_dict_key_value
|
||||||
|
|
||||||
|
get_dict_key_value(_GLOBAL_VARIABLES, variable_name)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Sends file using tentacle protocol
|
||||||
|
#########################################################################################
|
||||||
|
def tentacle_xml(
|
||||||
|
data_file: str = "",
|
||||||
|
tentacle_ops: dict = {},
|
||||||
|
tentacle_path: str = _GLOBAL_VARIABLES['tentacle_client'],
|
||||||
|
retry: bool = False,
|
||||||
|
debug: int = 0,
|
||||||
|
print_errors: bool = True
|
||||||
|
) -> bool:
|
||||||
|
"""
|
||||||
|
Sends file using tentacle protocol
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data_file (str): Path to the data file to be sent.
|
||||||
|
tentacle_ops (dict): Tentacle options as a dictionary (address [password] [port]).
|
||||||
|
tentacle_path (str): Custom path for the tentacle client executable.
|
||||||
|
retry (bool): Whether to retry sending the file if it fails.
|
||||||
|
debug (int): Debug mode flag. If enabled (1), the data file will not be removed after sending.
|
||||||
|
print_errors (bool): Whether to print error messages.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True for success, False for errors.
|
||||||
|
"""
|
||||||
|
from .output import print_stderr
|
||||||
|
|
||||||
|
if data_file is not None :
|
||||||
|
|
||||||
|
if not 'address' in tentacle_ops:
|
||||||
|
tentacle_ops['address'] = _GLOBAL_VARIABLES['tentacle_ip']
|
||||||
|
if not 'port' in tentacle_ops:
|
||||||
|
tentacle_ops['port'] = _GLOBAL_VARIABLES['tentacle_port']
|
||||||
|
if not 'extra_opts' in tentacle_ops:
|
||||||
|
tentacle_ops['extra_opts'] = _GLOBAL_VARIABLES['tentacle_extra_opts']
|
||||||
|
|
||||||
|
if tentacle_ops['address'] is None :
|
||||||
|
if print_errors:
|
||||||
|
print_stderr("Tentacle error: No address defined")
|
||||||
|
return False
|
||||||
|
|
||||||
|
try :
|
||||||
|
with open(data_file.strip(), 'r') as data:
|
||||||
|
data.read()
|
||||||
|
data.close()
|
||||||
|
except Exception as e :
|
||||||
|
if print_errors:
|
||||||
|
print_stderr(f"Tentacle error: {type(e).__name__} {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
tentacle_cmd = f"{tentacle_path} -v -a {tentacle_ops['address']} -p {tentacle_ops['port']} {tentacle_ops['extra_opts']} {data_file.strip()}"
|
||||||
|
tentacle_exe=subprocess.Popen(tentacle_cmd, stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True)
|
||||||
|
rc=tentacle_exe.wait()
|
||||||
|
|
||||||
|
result = True
|
||||||
|
|
||||||
|
if rc != 0 :
|
||||||
|
|
||||||
|
if retry:
|
||||||
|
|
||||||
|
tentacle_retries = _GLOBAL_VARIABLES['tentacle_retries']
|
||||||
|
|
||||||
|
if tentacle_retries < 1:
|
||||||
|
tentacle_retries = 1
|
||||||
|
|
||||||
|
retry_count = 0
|
||||||
|
|
||||||
|
while retry_count < tentacle_retries :
|
||||||
|
|
||||||
|
tentacle_exe=subprocess.Popen(tentacle_cmd, stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True)
|
||||||
|
rc=tentacle_exe.wait()
|
||||||
|
|
||||||
|
if rc == 0:
|
||||||
|
break
|
||||||
|
|
||||||
|
if print_errors:
|
||||||
|
stderr = tentacle_exe.stderr.read().decode()
|
||||||
|
msg = f"Tentacle error (Retry {retry_count + 1}/{tentacle_retries}): {stderr}"
|
||||||
|
print_stderr(str(datetime.today().strftime('%Y-%m-%d %H:%M')) + msg)
|
||||||
|
|
||||||
|
retry_count += 1
|
||||||
|
|
||||||
|
if retry_count >= tentacle_retries:
|
||||||
|
result = False
|
||||||
|
else:
|
||||||
|
|
||||||
|
if print_errors:
|
||||||
|
stderr = tentacle_exe.stderr.read().decode()
|
||||||
|
msg="Tentacle error:" + str(stderr)
|
||||||
|
print_stderr(str(datetime.today().strftime('%Y-%m-%d %H:%M')) + msg)
|
||||||
|
result = False
|
||||||
|
|
||||||
|
if debug == 0 :
|
||||||
|
os.remove(data_file.strip())
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
else:
|
||||||
|
if print_errors:
|
||||||
|
print_stderr("Tentacle error: file path is required.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
####
|
||||||
|
# Detect transfer mode and send XML.
|
||||||
|
#########################################################################################
|
||||||
|
def transfer_xml(
|
||||||
|
file: str = "",
|
||||||
|
transfer_mode: str = _GLOBAL_VARIABLES['transfer_mode'],
|
||||||
|
tentacle_ip: str = _GLOBAL_VARIABLES['tentacle_ip'],
|
||||||
|
tentacle_port: int = _GLOBAL_VARIABLES['tentacle_port'],
|
||||||
|
tentacle_extra_opts: str = _GLOBAL_VARIABLES['tentacle_extra_opts'],
|
||||||
|
data_dir: str = _GLOBAL_VARIABLES['data_dir']
|
||||||
|
)-> None:
|
||||||
|
|
||||||
|
"""
|
||||||
|
Detects the transfer mode and calls the agentplugin() function to perform the transfer.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
file (str): Path to file to send.
|
||||||
|
transfer_mode (str, optional): Transfer mode. Default is _GLOBAL_VARIABLES['transfer_mode'].
|
||||||
|
tentacle_ip (str, optional): IP address for Tentacle. Default is _GLOBAL_VARIABLES['tentacle_ip'].
|
||||||
|
tentacle_port (str, optional): Port for Tentacle. Default is _GLOBAL_VARIABLES['tentacle_port'].
|
||||||
|
data_dir (str, optional): Path to data dir with local transfer mode. Default is _GLOBAL_VARIABLES['data_dir'].
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
if file is not None:
|
||||||
|
if transfer_mode != "local":
|
||||||
|
tentacle_conf = {
|
||||||
|
'address' : tentacle_ip,
|
||||||
|
'port' : tentacle_port,
|
||||||
|
'extra_opts' : tentacle_extra_opts
|
||||||
|
}
|
||||||
|
tentacle_xml(file, tentacle_conf)
|
||||||
|
else:
|
||||||
|
shutil.move(file, data_dir)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Creates a agent .data file in the specified data_dir folder
|
||||||
|
#########################################################################################
|
||||||
|
def write_xml(
|
||||||
|
xml: str = "",
|
||||||
|
agent_name: str = "",
|
||||||
|
data_dir: str = _GLOBAL_VARIABLES['temporal'],
|
||||||
|
print_errors: bool = False
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
Creates an agent .data file in the specified data_dir folder
|
||||||
|
|
||||||
|
Args:
|
||||||
|
xml (str): XML string to be written in the file.
|
||||||
|
agent_name (str): Agent name for the XML and file name.
|
||||||
|
data_dir (str): Folder in which the file will be created.
|
||||||
|
print_errors (bool): Whether to print error messages.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Path to the created .data file.
|
||||||
|
"""
|
||||||
|
from .general import generate_md5
|
||||||
|
from .output import print_stderr
|
||||||
|
|
||||||
|
Utime = datetime.now().strftime('%s')
|
||||||
|
agent_name_md5 = generate_md5(agent_name)
|
||||||
|
data_file = "%s/%s.%s.data" %(str(data_dir),agent_name_md5,str(Utime))
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(data_file, 'x') as data:
|
||||||
|
data.write(xml)
|
||||||
|
except OSError as o:
|
||||||
|
if print_errors:
|
||||||
|
print_stderr(f"ERROR - Could not write file: {o}, please check directory permissions")
|
||||||
|
except Exception as e:
|
||||||
|
if print_errors:
|
||||||
|
print_stderr(f"{type(e).__name__}: {e}")
|
||||||
|
|
||||||
|
return data_file
|
|
@ -45,8 +45,8 @@ our @EXPORT = qw(
|
||||||
);
|
);
|
||||||
|
|
||||||
# version: Defines actual version of Pandora Server for this module only
|
# version: Defines actual version of Pandora Server for this module only
|
||||||
my $pandora_version = "7.0NG.773";
|
my $pandora_version = "7.0NG.773.1";
|
||||||
my $pandora_build = "230821";
|
my $pandora_build = "230822";
|
||||||
our $VERSION = $pandora_version." ".$pandora_build;
|
our $VERSION = $pandora_version." ".$pandora_build;
|
||||||
|
|
||||||
# Setup hash
|
# Setup hash
|
||||||
|
|
|
@ -2058,6 +2058,8 @@ sub PandoraFMS::Recon::Base::report_scanned_agents($;$) {
|
||||||
'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz=tasklist#'
|
'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz=tasklist#'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$notification->{'subtype'} .= safe_input('NOTIF.DISCOVERYTASK.REVIEW');
|
||||||
|
|
||||||
$notification->{'mensaje'} = safe_input(
|
$notification->{'mensaje'} = safe_input(
|
||||||
'Discovery task (host&devices) \''.safe_output($self->{'task_data'}{'name'})
|
'Discovery task (host&devices) \''.safe_output($self->{'task_data'}{'name'})
|
||||||
.'\' has been completed. Please review the results.'
|
.'\' has been completed. Please review the results.'
|
||||||
|
|
|
@ -33,8 +33,8 @@ use base 'Exporter';
|
||||||
our @ISA = qw(Exporter);
|
our @ISA = qw(Exporter);
|
||||||
|
|
||||||
# version: Defines actual version of Pandora Server for this module only
|
# version: Defines actual version of Pandora Server for this module only
|
||||||
my $pandora_version = "7.0NG.773";
|
my $pandora_version = "7.0NG.773.1";
|
||||||
my $pandora_build = "230821";
|
my $pandora_build = "230822";
|
||||||
our $VERSION = $pandora_version." ".$pandora_build;
|
our $VERSION = $pandora_version." ".$pandora_build;
|
||||||
|
|
||||||
our %EXPORT_TAGS = ( 'all' => [ qw() ] );
|
our %EXPORT_TAGS = ( 'all' => [ qw() ] );
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
#
|
#
|
||||||
%global __os_install_post %{nil}
|
%global __os_install_post %{nil}
|
||||||
%define name pandorafms_server
|
%define name pandorafms_server
|
||||||
%define version 7.0NG.773
|
%define version 7.0NG.773.1
|
||||||
%define release 230821
|
%define release 230822
|
||||||
|
|
||||||
Summary: Pandora FMS Server
|
Summary: Pandora FMS Server
|
||||||
Name: %{name}
|
Name: %{name}
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
# This code is licensed under GPL 2.0 license.
|
# This code is licensed under GPL 2.0 license.
|
||||||
# **********************************************************************
|
# **********************************************************************
|
||||||
|
|
||||||
PI_VERSION="7.0NG.773"
|
PI_VERSION="7.0NG.773.1"
|
||||||
PI_BUILD="230821"
|
PI_BUILD="230822"
|
||||||
|
|
||||||
MODE=$1
|
MODE=$1
|
||||||
if [ $# -gt 1 ]; then
|
if [ $# -gt 1 ]; then
|
||||||
|
|
|
@ -35,7 +35,7 @@ use PandoraFMS::Config;
|
||||||
use PandoraFMS::DB;
|
use PandoraFMS::DB;
|
||||||
|
|
||||||
# version: define current version
|
# version: define current version
|
||||||
my $version = "7.0NG.773 Build 230821";
|
my $version = "7.0NG.773.1 Build 230822";
|
||||||
|
|
||||||
# Pandora server configuration
|
# Pandora server configuration
|
||||||
my %conf;
|
my %conf;
|
||||||
|
@ -769,8 +769,8 @@ sub pandora_checkdb_integrity {
|
||||||
|
|
||||||
# Delete orphan data from visual console.
|
# Delete orphan data from visual console.
|
||||||
log_message ('INTEGRITY', "Deleting orphan visual console items.");
|
log_message ('INTEGRITY', "Deleting orphan visual console items.");
|
||||||
db_do ($dbh, 'DELETE FROM tlayout_data WHERE id_agent NOT IN (SELECT id_agente FROM tagente)');
|
db_do ($dbh, 'DELETE FROM tlayout_data WHERE id_agent <> 0 AND id_agent NOT IN (SELECT id_agente FROM tagente)');
|
||||||
db_do ($dbh, 'DELETE FROM tlayout_data WHERE id_agente_modulo NOT IN (SELECT id_agente_modulo FROM tagente_modulo)');
|
db_do ($dbh, 'DELETE FROM tlayout_data WHERE id_agente_modulo <> 0 AND id_agente_modulo NOT IN (SELECT id_agente_modulo FROM tagente_modulo)');
|
||||||
|
|
||||||
# Delete orphan data form deleted agents.
|
# Delete orphan data form deleted agents.
|
||||||
# Clearl orphan data from dashboards
|
# Clearl orphan data from dashboards
|
||||||
|
|
|
@ -36,7 +36,7 @@ use Encode::Locale;
|
||||||
Encode::Locale::decode_argv;
|
Encode::Locale::decode_argv;
|
||||||
|
|
||||||
# version: define current version
|
# version: define current version
|
||||||
my $version = "7.0NG.773 Build 230821";
|
my $version = "7.0NG.773.1 Build 230822";
|
||||||
|
|
||||||
# save program name for logging
|
# save program name for logging
|
||||||
my $progname = basename($0);
|
my $progname = basename($0);
|
||||||
|
|
Loading…
Reference in New Issue