#11206 Resolve conflicts
This commit is contained in:
commit
384fb8d115
|
@ -1,5 +1,5 @@
|
|||
# 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,
|
||||
# Copyright (c) 2003-2023 Pandora FMS
|
||||
# http://www.pandorafms.com
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# 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,
|
||||
# Copyright (c) 2003-2023 Pandora FMS
|
||||
# http://www.pandorafms.com
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# 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,
|
||||
# Copyright (c) 2003-2023 Pandora FMS
|
||||
# http://www.pandorafms.com
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# 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,
|
||||
# Copyright (c) 2003-2023 Pandora FMS
|
||||
# http://www.pandorafms.com
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# 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,
|
||||
# Copyright (c) 2003-2023 Pandora FMS
|
||||
# http://www.pandorafms.com
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# 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,
|
||||
# Copyright (c) 2003-2023 Pandora FMS
|
||||
# http://www.pandorafms.com
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Base config file for Pandora FMS Windows Agent
|
||||
# (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
|
||||
# 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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Fichero de configuracion base de agentes de Pandora
|
||||
# Base config file for Pandora agents
|
||||
# Version 7.0NG.773, AIX version
|
||||
# Version 7.0NG.773.1, AIX version
|
||||
|
||||
# General Parameters
|
||||
# ==================
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Fichero de configuracion base de agentes de Pandora
|
||||
# Base config file for Pandora agents
|
||||
# Version 7.0NG.773
|
||||
# Version 7.0NG.773.1
|
||||
# FreeBSD/IPSO version
|
||||
# Licenced under GPL licence, 2003-2007 Sancho Lerena
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Fichero de configuracion base de agentes de Pandora
|
||||
# Base config file for Pandora agents
|
||||
# Version 7.0NG.773, HPUX Version
|
||||
# Version 7.0NG.773.1, HPUX Version
|
||||
|
||||
# General Parameters
|
||||
# ==================
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Base config file for Pandora FMS agents
|
||||
# Version 7.0NG.773
|
||||
# Version 7.0NG.773.1
|
||||
# Licensed under GPL license v2,
|
||||
# (c) 2003-2023 Pandora FMS
|
||||
# please visit http://pandora.sourceforge.net
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Base config file for Pandora FMS agents
|
||||
# Version 7.0NG.773
|
||||
# Version 7.0NG.773.1
|
||||
# Licensed under GPL license v2,
|
||||
# (c) 2003-2023 Pandora FMS
|
||||
# please visit http://pandora.sourceforge.net
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Base config file for Pandora FMS agents
|
||||
# Version 7.0NG.773
|
||||
# Version 7.0NG.773.1
|
||||
# Licensed under GPL license v2,
|
||||
# please visit http://pandora.sourceforge.net
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Fichero de configuracion base de agentes de Pandora
|
||||
# Base config file for Pandora agents
|
||||
# Version 7.0NG.773, Solaris version
|
||||
# Version 7.0NG.773.1, Solaris version
|
||||
|
||||
# General Parameters
|
||||
# ==================
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# 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,
|
||||
# Copyright (c) 2003-2023 Pandora FMS
|
||||
# http://www.pandorafms.com
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
package: pandorafms-agent-unix
|
||||
Version: 7.0NG.773-230821
|
||||
Version: 7.0NG.773.1-230822
|
||||
Architecture: all
|
||||
Priority: optional
|
||||
Section: admin
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# 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."
|
||||
whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null
|
||||
|
|
|
@ -31,7 +31,7 @@ fi
|
|||
if [ "$#" -ge 2 ]; then
|
||||
VERSION="$2"
|
||||
else
|
||||
VERSION="7.0NG.773"
|
||||
VERSION="7.0NG.773.1"
|
||||
fi
|
||||
|
||||
# Path for the generated DMG file
|
||||
|
|
|
@ -19,11 +19,11 @@
|
|||
<choice id="com.pandorafms.pandorafms_src" visible="false">
|
||||
<pkg-ref id="com.pandorafms.pandorafms_src"/>
|
||||
</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">
|
||||
<pkg-ref id="com.pandorafms.pandorafms_uninstall"/>
|
||||
</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()" />
|
||||
<script>
|
||||
<![CDATA[
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
<key>CFBundleIconFile</key> <string>pandorafms.icns</string>
|
||||
<key>CFBundleIdentifier</key> <string>com.pandorafms.pandorafms_uninstall</string>
|
||||
|
||||
<key>CFBundleVersion</key> <string>7.0NG.773</string>
|
||||
<key>CFBundleGetInfoString</key> <string>7.0NG.773 Pandora FMS on Aug 2020</string>
|
||||
<key>CFBundleShortVersionString</key> <string>7.0NG.773</string>
|
||||
<key>CFBundleVersion</key> <string>7.0NG.773.1</string>
|
||||
<key>CFBundleGetInfoString</key> <string>7.0NG.773.1 Pandora FMS on Aug 2020</string>
|
||||
<key>CFBundleShortVersionString</key> <string>7.0NG.773.1</string>
|
||||
|
||||
<key>NSPrincipalClass</key><string>NSApplication</string>
|
||||
<key>NSMainNibFile</key><string>MainMenu</string>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# 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,
|
||||
# Copyright (c) 2003-2023 Pandora FMS
|
||||
# http://www.pandorafms.com
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# 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,
|
||||
# Copyright (c) 2003-2023 Pandora FMS
|
||||
# http://www.pandorafms.com
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# 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,
|
||||
# Copyright (c) 2003-2023 Pandora FMS
|
||||
# http://www.pandorafms.com
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Base config file for Pandora FMS agents
|
||||
# Version 7.0NG.773
|
||||
# Version 7.0NG.773.1
|
||||
# Licensed under GPL license v2,
|
||||
# Copyright (c) 2004-2023 Pandora FMS
|
||||
# https://pandorafms.com
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# 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,
|
||||
# Copyright (c) 2003-2023 Pandora FMS
|
||||
# http://www.pandorafms.com
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# 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,
|
||||
# Copyright (c) 2003-2023 Pandora FMS
|
||||
# http://www.pandorafms.com
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# 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,
|
||||
# Copyright (c) 2003-2023 Pandora FMS
|
||||
# http://www.pandorafms.com
|
||||
|
|
|
@ -1030,8 +1030,8 @@ my $Sem = undef;
|
|||
# Semaphore used to control the number of threads
|
||||
my $ThreadSem = undef;
|
||||
|
||||
use constant AGENT_VERSION => '7.0NG.773';
|
||||
use constant AGENT_BUILD => '230821';
|
||||
use constant AGENT_VERSION => '7.0NG.773.1';
|
||||
use constant AGENT_BUILD => '230822';
|
||||
|
||||
# Agent log default file size maximum and instances
|
||||
use constant DEFAULT_MAX_LOG_SIZE => 600000;
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
#
|
||||
%global __os_install_post %{nil}
|
||||
%define name pandorafms_agent_linux
|
||||
%define version 7.0NG.773
|
||||
%define release 230821
|
||||
%define version 7.0NG.773.1
|
||||
%define release 230822
|
||||
|
||||
Summary: Pandora FMS Linux agent, PERL version
|
||||
Name: %{name}
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
#
|
||||
%global __os_install_post %{nil}
|
||||
%define name pandorafms_agent_linux
|
||||
%define version 7.0NG.773
|
||||
%define release 230821
|
||||
%define version 7.0NG.773.1
|
||||
%define release 230822
|
||||
|
||||
Summary: Pandora FMS Linux agent, PERL version
|
||||
Name: %{name}
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
# Please see http://www.pandorafms.org. This code is licensed under GPL 2.0 license.
|
||||
# **********************************************************************
|
||||
|
||||
PI_VERSION="7.0NG.773"
|
||||
PI_BUILD="230821"
|
||||
PI_VERSION="7.0NG.773.1"
|
||||
PI_BUILD="230822"
|
||||
OS_NAME=`uname -s`
|
||||
|
||||
FORCE=0
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Base config file for Pandora FMS Windows Agent
|
||||
# (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
|
||||
# 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
|
||||
|
|
|
@ -3,7 +3,7 @@ AllowLanguageSelection
|
|||
{Yes}
|
||||
|
||||
AppName
|
||||
{Pandora FMS Windows Agent v7.0NG.773}
|
||||
{Pandora FMS Windows Agent v7.0NG.773.1}
|
||||
|
||||
ApplicationID
|
||||
{17E3D2CF-CA02-406B-8A80-9D31C17BD08F}
|
||||
|
@ -186,7 +186,7 @@ UpgradeApplicationID
|
|||
{}
|
||||
|
||||
Version
|
||||
{230821}
|
||||
{230822}
|
||||
|
||||
ViewReadme
|
||||
{Yes}
|
||||
|
|
|
@ -30,7 +30,7 @@ using namespace Pandora;
|
|||
using namespace Pandora_Strutils;
|
||||
|
||||
#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_dir;
|
||||
|
|
|
@ -11,7 +11,7 @@ BEGIN
|
|||
VALUE "LegalCopyright", "Pandora FMS"
|
||||
VALUE "OriginalFilename", "PandoraAgent.exe"
|
||||
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"
|
||||
END
|
||||
END
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
package: pandorafms-console
|
||||
Version: 7.0NG.773-230821
|
||||
Version: 7.0NG.773.1-230822
|
||||
Architecture: all
|
||||
Priority: optional
|
||||
Section: admin
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
pandora_version="7.0NG.773-230821"
|
||||
pandora_version="7.0NG.773.1-230822"
|
||||
|
||||
package_pear=0
|
||||
package_pandora=1
|
||||
|
|
|
@ -261,12 +261,27 @@ function agents_modules_load_js()
|
|||
}
|
||||
|
||||
function select_selected () {
|
||||
// $('#id_agents2 option').each(function(){
|
||||
// if($(this).attr('selected') === 'selected'){
|
||||
// $(this).prop('selected', true);
|
||||
// }
|
||||
// });
|
||||
var f = document.forms.filter_form;
|
||||
f.action = "index.php?sec=view&sec2=extensions/agents_modules";
|
||||
$('#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>
|
||||
<?php
|
||||
}
|
||||
|
@ -653,7 +668,7 @@ function mainAgentsModules()
|
|||
}
|
||||
|
||||
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 .= '<tr>';
|
||||
$show_filters .= '<td width="33%">'.$filter_type.'</td>';
|
||||
|
@ -679,6 +694,13 @@ function mainAgentsModules()
|
|||
'onclick' => 'select_selected()',
|
||||
],
|
||||
true
|
||||
).html_print_button(
|
||||
__('Export to CSV'),
|
||||
'srcbutton_csv',
|
||||
false,
|
||||
'export_csv()',
|
||||
['class' => 'secondary mini'],
|
||||
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"
|
||||
}
|
||||
|
||||
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) {
|
||||
var match = /notification-(.*)-id-([0-9]+)/.exec(event.target.id);
|
||||
if (!match) {
|
||||
|
|
|
@ -187,6 +187,27 @@ if (get_parameter('mark_notification_as_read', 0)) {
|
|||
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)) {
|
||||
echo notifications_print_dropdown();
|
||||
return;
|
||||
|
|
|
@ -169,6 +169,7 @@ class ConsoleSupervisor
|
|||
* NOTIF.PHP.DISABLE_FUNCTIONS
|
||||
* NOTIF.PHP.CHROMIUM
|
||||
* NOTIF.PHP.VERSION
|
||||
* NOTIF.PHP.VERSION.SUPPORT
|
||||
*/
|
||||
|
||||
$this->checkPHPSettings();
|
||||
|
@ -383,6 +384,7 @@ class ConsoleSupervisor
|
|||
* NOTIF.PHP.DISABLE_FUNCTIONS
|
||||
* NOTIF.PHP.CHROMIUM
|
||||
* NOTIF.PHP.VERSION
|
||||
* NOTIF.PHP.VERSION.SUPPORT
|
||||
*/
|
||||
|
||||
$this->checkPHPSettings();
|
||||
|
@ -874,6 +876,7 @@ class ConsoleSupervisor
|
|||
case 'NOTIF.PHP.DISABLE_FUNCTIONS':
|
||||
case 'NOTIF.PHP.CHROMIUM':
|
||||
case 'NOTIF.PHP.VERSION':
|
||||
case 'NOTIF.PHP.VERSION.SUPPORT':
|
||||
case 'NOTIF.HISTORYDB':
|
||||
case 'NOTIF.PANDORADB':
|
||||
case 'NOTIF.PANDORADB.HISTORICAL':
|
||||
|
@ -1830,14 +1833,14 @@ class ConsoleSupervisor
|
|||
$url = 'https://www.php.net/supported-versions.php';
|
||||
$this->notify(
|
||||
[
|
||||
'type' => 'NOTIF.PHP.VERSION',
|
||||
'type' => 'NOTIF.PHP.VERSION.SUPPORT',
|
||||
'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,
|
||||
'url' => $url,
|
||||
]
|
||||
);
|
||||
} else {
|
||||
$this->cleanNotifications('NOTIF.PHP.VERSION');
|
||||
$this->cleanNotifications('NOTIF.PHP.VERSION.SUPPORT');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
/**
|
||||
* Pandora build version and version
|
||||
*/
|
||||
$build_version = 'PC230821';
|
||||
$pandora_version = 'v7.0NG.773';
|
||||
$build_version = 'PC230822';
|
||||
$pandora_version = 'v7.0NG.773.1';
|
||||
|
||||
// Do not overwrite default timezone set if defined.
|
||||
$script_tz = @date_default_timezone_get();
|
||||
|
|
|
@ -2904,6 +2904,8 @@ function html_print_anchor(
|
|||
|
||||
$output .= '>';
|
||||
|
||||
$output .= (isset($options['text']) === true) ? $options['text'] : '';
|
||||
|
||||
$output .= (isset($options['content']) === true) ? io_safe_input_html($options['content']) : '';
|
||||
|
||||
$output .= '</a>';
|
||||
|
@ -7118,6 +7120,7 @@ function html_print_menu_button(array $options, bool $return=false)
|
|||
'class' => ($options['class'] ?? ''),
|
||||
'style' => ($options['style'] ?? ''),
|
||||
'onClick' => ($options['onClick'] ?? ''),
|
||||
'text' => ($options['text'] ?? ''),
|
||||
'content' => $content,
|
||||
],
|
||||
$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.CHROMIUM',
|
||||
'NOTIF.PHP.VERSION',
|
||||
'NOTIF.PHP.VERSION.SUPPORT',
|
||||
'NOTIF.HISTORYDB',
|
||||
'NOTIF.PANDORADB',
|
||||
'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.
|
||||
*
|
||||
|
@ -1022,9 +1123,24 @@ function notifications_print_dropdown()
|
|||
$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(
|
||||
"<div id='notification-wrapper'>
|
||||
<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
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1034,6 +1150,8 @@ function notifications_print_dropdown()
|
|||
>
|
||||
</div>
|
||||
",
|
||||
$notification_filter,
|
||||
$notification_menu,
|
||||
array_reduce(
|
||||
$mess,
|
||||
function ($carry, $message) {
|
||||
|
@ -1093,6 +1211,8 @@ function notifications_print_dropdown_element($message_info)
|
|||
$message_info['subject'] = io_safe_input($img);
|
||||
}
|
||||
|
||||
$type = explode('.', $message_info['subtype'])[1];
|
||||
|
||||
if (strlen($body_preview) >= 170) {
|
||||
$body_preview = substr($body_preview, 0, 150);
|
||||
$body_preview .= __('. Read More...');
|
||||
|
@ -1103,6 +1223,7 @@ function notifications_print_dropdown_element($message_info)
|
|||
class='notification-item'
|
||||
onclick='%s'
|
||||
id='notification-item-id-%s'
|
||||
value='%s'
|
||||
href='%s'
|
||||
target='%s'
|
||||
>
|
||||
|
@ -1116,8 +1237,9 @@ function notifications_print_dropdown_element($message_info)
|
|||
</p>
|
||||
</div>
|
||||
</a>",
|
||||
$action.';click_on_notification_toast(event)',
|
||||
$action.'; click_on_notification_toast(event)',
|
||||
$message_info['id_mensaje'],
|
||||
$type,
|
||||
messages_get_url($message_info['id_mensaje']),
|
||||
$target,
|
||||
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: "✓ ";
|
||||
}
|
||||
|
||||
.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_layout {
|
||||
margin-top: 15px;
|
||||
|
|
|
@ -130,8 +130,8 @@
|
|||
</div>
|
||||
<div style='padding-bottom: 50px'>
|
||||
<?php
|
||||
$version = '7.0NG.773';
|
||||
$build = '230821';
|
||||
$version = '7.0NG.773.1';
|
||||
$build = '230822';
|
||||
$banner = "v$version Build $build";
|
||||
error_reporting(0);
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
# Pandora FMS Console
|
||||
#
|
||||
%define name pandorafms_console
|
||||
%define version 7.0NG.773
|
||||
%define release 230821
|
||||
%define version 7.0NG.773.1
|
||||
%define release 230822
|
||||
|
||||
# User and Group under which Apache is running
|
||||
%define httpd_name httpd
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
# Pandora FMS Console
|
||||
#
|
||||
%define name pandorafms_console
|
||||
%define version 7.0NG.773
|
||||
%define release 230821
|
||||
%define version 7.0NG.773.1
|
||||
%define release 230822
|
||||
|
||||
# User and Group under which Apache is running
|
||||
%define httpd_name httpd
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
# Pandora FMS Console
|
||||
#
|
||||
%define name pandorafms_console
|
||||
%define version 7.0NG.773
|
||||
%define release 230821
|
||||
%define version 7.0NG.773.1
|
||||
%define release 230822
|
||||
%define httpd_name httpd
|
||||
# User and Group under which Apache is running
|
||||
%define httpd_name apache2
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
# This code is licensed under GPL 2.0 license.
|
||||
# **********************************************************************
|
||||
|
||||
PI_VERSION="7.0NG.773"
|
||||
PI_VERSION="7.0NG.773.1"
|
||||
FORCE=0
|
||||
DESTDIR=""
|
||||
LOG_TIMESTAMP=`date +"%Y/%m/%d %H:%M:%S"`
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
package: pandorafms-server
|
||||
Version: 7.0NG.773-230821
|
||||
Version: 7.0NG.773.1-230822
|
||||
Architecture: all
|
||||
Priority: optional
|
||||
Section: admin
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
pandora_version="7.0NG.773-230821"
|
||||
pandora_version="7.0NG.773.1-230822"
|
||||
|
||||
package_cpan=0
|
||||
package_pandora=1
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#############################################################################
|
||||
# Pandora FMS Server Parameters
|
||||
# Pandora FMS, the Flexible Monitoring System.
|
||||
# Version 7.0NG.773
|
||||
# Version 7.0NG.773.1
|
||||
# Licensed under GPL license v2,
|
||||
# (c) 2003-2023 Pandora FMS
|
||||
# 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
|
||||
my $pandora_version = "7.0NG.773";
|
||||
my $pandora_build = "230821";
|
||||
my $pandora_version = "7.0NG.773.1";
|
||||
my $pandora_build = "230822";
|
||||
our $VERSION = $pandora_version." ".$pandora_build;
|
||||
|
||||
# Setup hash
|
||||
|
|
|
@ -2058,6 +2058,8 @@ sub PandoraFMS::Recon::Base::report_scanned_agents($;$) {
|
|||
'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz=tasklist#'
|
||||
);
|
||||
|
||||
$notification->{'subtype'} .= safe_input('NOTIF.DISCOVERYTASK.REVIEW');
|
||||
|
||||
$notification->{'mensaje'} = safe_input(
|
||||
'Discovery task (host&devices) \''.safe_output($self->{'task_data'}{'name'})
|
||||
.'\' has been completed. Please review the results.'
|
||||
|
|
|
@ -33,8 +33,8 @@ use base 'Exporter';
|
|||
our @ISA = qw(Exporter);
|
||||
|
||||
# version: Defines actual version of Pandora Server for this module only
|
||||
my $pandora_version = "7.0NG.773";
|
||||
my $pandora_build = "230821";
|
||||
my $pandora_version = "7.0NG.773.1";
|
||||
my $pandora_build = "230822";
|
||||
our $VERSION = $pandora_version." ".$pandora_build;
|
||||
|
||||
our %EXPORT_TAGS = ( 'all' => [ qw() ] );
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
#
|
||||
%global __os_install_post %{nil}
|
||||
%define name pandorafms_server
|
||||
%define version 7.0NG.773
|
||||
%define release 230821
|
||||
%define version 7.0NG.773.1
|
||||
%define release 230822
|
||||
|
||||
Summary: Pandora FMS Server
|
||||
Name: %{name}
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
# This code is licensed under GPL 2.0 license.
|
||||
# **********************************************************************
|
||||
|
||||
PI_VERSION="7.0NG.773"
|
||||
PI_BUILD="230821"
|
||||
PI_VERSION="7.0NG.773.1"
|
||||
PI_BUILD="230822"
|
||||
|
||||
MODE=$1
|
||||
if [ $# -gt 1 ]; then
|
||||
|
|
|
@ -35,7 +35,7 @@ use PandoraFMS::Config;
|
|||
use PandoraFMS::DB;
|
||||
|
||||
# version: define current version
|
||||
my $version = "7.0NG.773 Build 230821";
|
||||
my $version = "7.0NG.773.1 Build 230822";
|
||||
|
||||
# Pandora server configuration
|
||||
my %conf;
|
||||
|
@ -769,8 +769,8 @@ sub pandora_checkdb_integrity {
|
|||
|
||||
# Delete orphan data from visual console.
|
||||
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_agente_modulo NOT IN (SELECT id_agente_modulo FROM tagente_modulo)');
|
||||
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 <> 0 AND id_agente_modulo NOT IN (SELECT id_agente_modulo FROM tagente_modulo)');
|
||||
|
||||
# Delete orphan data form deleted agents.
|
||||
# Clearl orphan data from dashboards
|
||||
|
|
|
@ -36,7 +36,7 @@ use Encode::Locale;
|
|||
Encode::Locale::decode_argv;
|
||||
|
||||
# version: define current version
|
||||
my $version = "7.0NG.773 Build 230821";
|
||||
my $version = "7.0NG.773.1 Build 230822";
|
||||
|
||||
# save program name for logging
|
||||
my $progname = basename($0);
|
||||
|
|
Loading…
Reference in New Issue