Standarized globals and functions

This commit is contained in:
Enrique Martin 2023-08-16 08:12:14 +02:00
parent 0fed9f8749
commit 6159f285fd
7 changed files with 254 additions and 100 deletions

View File

@ -6,7 +6,7 @@ import os
# Its values can be changed.
#########################################################################################
GLOBAL_VARIABLES = {
_GLOBAL_VARIABLES = {
'agents_group_name' : '',
'interval' : 300
}
@ -15,17 +15,16 @@ GLOBAL_VARIABLES = {
# Define some global variables
#########################################################################################
POSIX = os.name == "posix"
WINDOWS = os.name == "nt"
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")
_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
@ -49,7 +48,7 @@ def set_global_variable(
value = None
):
"""
Sets the value of a global variable in the 'GLOBAL_VARIABLES' dictionary.
Sets the value of a global variable in the '_GLOBAL_VARIABLES' dictionary.
Args:
variable_name (str): Name of the variable to set.
@ -57,7 +56,23 @@ def set_global_variable(
"""
from .general import set_dict_key_value
set_dict_key_value(GLOBAL_VARIABLES, variable_name, 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 = ""
):
"""
Gets the value of a global variable in the '_GLOBAL_VARIABLES' dictionary.
Args:
variable_name (str): Name of the variable to set.
"""
from .general import get_dict_key_value
get_dict_key_value(_GLOBAL_VARIABLES, variable_name)
####
# Agent class
@ -70,18 +85,22 @@ class Agent:
"""
def __init__(
self,
config: dict = None,
config: dict = {},
modules_def: list = [],
log_modules_def: list = []
):
if config is None:
config = init_agent()
self.config = config
self.modules_def = modules_def
self.log_modules_def = log_modules_def
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,
@ -211,6 +230,38 @@ class 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
#########################################################################################
@ -235,8 +286,8 @@ def init_agent(
"os_version" : "",
"timestamp" : now(),
"address" : "",
"group" : GLOBAL_VARIABLES['agents_group_name'],
"interval" : GLOBAL_VARIABLES['interval'],
"group" : _GLOBAL_VARIABLES['agents_group_name'],
"interval" : _GLOBAL_VARIABLES['interval'],
"agent_mode" : "1"
}

View File

@ -5,10 +5,10 @@ import json
# Define some global variables
#########################################################################################
ERROR_LEVEL = 0
SUMMARY = {}
INFO = ""
MONITORING_DATA = []
_ERROR_LEVEL = 0
_SUMMARY = {}
_INFO = ""
_MONITORING_DATA = []
####
# Internal: Alias for output.print_debug function
@ -36,9 +36,22 @@ def set_disco_error_level(
Args:
value (int, optional): The error level value. Default is 0.
"""
global ERROR_LEVEL
global _ERROR_LEVEL
ERROR_LEVEL = value
_ERROR_LEVEL = value
####
# Set fixed value to summary dict
#########################################################################################
def set_disco_summary(
data: dict = {}
):
"""
TODO: Add comments
"""
global _SUMMARY
_SUMMARY = {}
####
# Set fixed value to summary key
@ -48,15 +61,15 @@ def set_disco_summary_value(
value = None
):
"""
Sets a fixed value for a key in the 'SUMMARY' dictionary.
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.
"""
global SUMMARY
global _SUMMARY
SUMMARY[key] = value
_SUMMARY[key] = value
####
# Add value to summary key
@ -74,10 +87,10 @@ def add_disco_summary_value(
key (str): Key to add the value to.
value (any): Value to add to the key.
"""
global SUMMARY
global _SUMMARY
if key in SUMMARY:
SUMMARY[key] += value
if key in _SUMMARY:
_SUMMARY[key] += value
else:
set_summary_value(key, value)
@ -88,14 +101,14 @@ def set_disco_info_value(
value: str = ""
):
"""
Sets a fixed value to the 'INFO' variable.
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.
data (str, optional): The value to set in the '_INFO' variable. Default is an empty string.
"""
global INFO
global _INFO
INFO = value
_INFO = value
####
# Add data to info
@ -104,14 +117,14 @@ def add_disco_info_value(
value: str = ""
):
"""
Adds data to the 'INFO' variable.
Adds data to the '_INFO' variable.
Args:
data (str, optional): The data to add to the 'INFO' variable. Default is an empty string.
data (str, optional): The data to add to the '_INFO' variable. Default is an empty string.
"""
global INFO
global _INFO
INFO += value
_INFO += value
####
# Set fixed value to monitoring data
@ -122,9 +135,9 @@ def set_disco_monitoring_data(
"""
TODO: Add comments
"""
global MONITORING_DATA
global _MONITORING_DATA
MONITORING_DATA = data
_MONITORING_DATA = data
####
# Add value to monitoring data
@ -135,9 +148,9 @@ def add_disco_monitoring_data(
"""
TODO: Add comments
"""
global MONITORING_DATA
global _MONITORING_DATA
MONITORING_DATA.append(data)
_MONITORING_DATA.append(data)
####
# Print JSON output and exit script
@ -146,28 +159,28 @@ def disco_output():
"""
Prints the JSON output and exits the script.
The function uses the global variables 'ERROR_LEVEL', 'SUMMARY', and 'info'
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.
the '_ERROR_LEVEL' as the exit code.
"""
from .output import print_stdout
global ERROR_LEVEL
global SUMMARY
global INFO
global MONITORING_DATA
global _ERROR_LEVEL
global _SUMMARY
global _INFO
global _MONITORING_DATA
OUTPUT={}
if SUMMARY:
OUTPUT["summary"] = SUMMARY
output={}
if _SUMMARY:
output["summary"] = _SUMMARY
if INFO:
OUTPUT["info"] = INFO
if _INFO:
output["info"] = _INFO
if MONITORING_DATA:
OUTPUT["monitoring_data"] = MONITORING_DATA
if _MONITORING_DATA:
output["monitoring_data"] = _MONITORING_DATA
json_string = json.dumps(OUTPUT)
json_string = json.dumps(output)
print_stdout(json_string)
sys.exit(ERROR_LEVEL)
sys.exit(_ERROR_LEVEL)

View File

@ -54,7 +54,7 @@ def _get_cipher(
####
# Return encrypted string
#########################################################################################
def encrypt(
def encrypt_AES(
str_to_encrypt: str = "",
password: str = _PASSWORD
) -> str:
@ -75,7 +75,7 @@ def encrypt(
####
# Return decrypted string
#########################################################################################
def decrypt(
def decrypt_AES(
str_to_decrypt: str = "",
password: str = _PASSWORD
) -> str:

View File

@ -353,6 +353,24 @@ def set_dict_key_value(
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 = ""
):
"""
Return the value of a key in a given dict.
"""
key = input_key.strip()
if key in input_dict:
return input_dict[key]
else:
return None
####
# Return MD5 hash string.
#########################################################################################

View File

@ -1,7 +1,9 @@
import urllib3
import warnings
from requests.sessions import Session
from requests_ntlm import HttpNtlmAuth
from requests.auth import HTTPBasicAuth
from requests.auth import HTTPDigestAuth
from requests.sessions import Session
####
# Internal: Alias for output.print_debug function
@ -18,10 +20,10 @@ def _print_debug(
print_debug(var, print_errors)
####
# Auth URL session
# Internal: Auth URL session
#########################################################################################
def auth_call(
def _auth_call(
session = None,
authtype: str = "basic",
user: str = "",
@ -54,6 +56,7 @@ def call_url(
user: str = "",
passw: str = "",
timeout: int = 1,
verify: bool = True,
print_errors: bool = False
) -> str:
"""
@ -71,20 +74,32 @@ def call_url(
"""
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 != None:
auth_call(session, authtype, user, passw)
if authtype is not None:
_auth_call(session, authtype, user, passw)
output = ""
try:
output = session.get(url, timeout=timeout, verify=False)
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)")
except Exception as e:
if print_errors:
print_stderr(f"{type(e).__name__}:\t{str(e)}")
return output
return None

View File

@ -120,86 +120,127 @@ def print_module(
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:

View File

@ -10,7 +10,7 @@ import sys
# Its values can be changed.
#########################################################################################
GLOBAL_VARIABLES = {
_GLOBAL_VARIABLES = {
'transfer_mode' : 'tentacle',
'temporal' : '/tmp',
'data_dir' : '/var/spool/pandora/data_in/',
@ -42,7 +42,7 @@ def set_global_variable(
value = None
):
"""
Sets the value of a global variable in the 'GLOBAL_VARIABLES' dictionary.
Sets the value of a global variable in the '_GLOBAL_VARIABLES' dictionary.
Args:
variable_name (str): Name of the variable to set.
@ -50,7 +50,23 @@ def set_global_variable(
"""
from .general import set_dict_key_value
set_dict_key_value(GLOBAL_VARIABLES, variable_name, 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 = ""
):
"""
Gets the value of a global variable in the '_GLOBAL_VARIABLES' dictionary.
Args:
variable_name (str): Name of the variable to set.
"""
from .general import get_dict_key_value
get_dict_key_value(_GLOBAL_VARIABLES, variable_name)
####
# Sends file using tentacle protocol
@ -58,7 +74,7 @@ def set_global_variable(
def tentacle_xml(
data_file: str = "",
tentacle_ops: dict = {},
tentacle_path: str = GLOBAL_VARIABLES['tentacle_client'],
tentacle_path: str = _GLOBAL_VARIABLES['tentacle_client'],
debug: int = 0,
print_errors: bool = True
) -> bool:
@ -78,11 +94,11 @@ def tentacle_xml(
if data_file is not None :
if not 'address' in tentacle_ops:
tentacle_ops['address'] = GLOBAL_VARIABLES['tentacle_ip']
tentacle_ops['address'] = _GLOBAL_VARIABLES['tentacle_ip']
if not 'port' in tentacle_ops:
tentacle_ops['port'] = GLOBAL_VARIABLES['tentacle_port']
tentacle_ops['port'] = _GLOBAL_VARIABLES['tentacle_port']
if not 'extra_opts' in tentacle_ops:
tentacle_ops['extra_opts'] = GLOBAL_VARIABLES['tentacle_extra_opts']
tentacle_ops['extra_opts'] = _GLOBAL_VARIABLES['tentacle_extra_opts']
if tentacle_ops['address'] is None :
if print_errors:
@ -123,11 +139,11 @@ def tentacle_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']
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']
):
"""
@ -135,10 +151,10 @@ def transfer_xml(
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'].
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'].
"""
if file is not None:
if transfer_mode != "local":
@ -157,7 +173,7 @@ def transfer_xml(
def write_xml(
xml: str = "",
agent_name: str = "",
data_dir: str = GLOBAL_VARIABLES['temporal'],
data_dir: str = _GLOBAL_VARIABLES['temporal'],
print_errors: bool = False
) -> str:
"""