mirror of
https://github.com/pandorafms/pandorafms.git
synced 2025-07-29 16:55:05 +02:00
Organization and new functions for pandoraPluginTools
This commit is contained in:
parent
b526b10200
commit
2ca114f844
@ -1,52 +1,31 @@
|
|||||||
# Python: module plugintools for PandoraFMS Developers
|
# Python: module plugintools for PandoraFMS Developers
|
||||||
|
|
||||||
pandoraPluginTools is a library that aims to help the creation of scripts and their integration in PandoraFMS.
|
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)
|
[PluginTools Reference Documentation](https://pandorafms.com/guides/public/books/plugintools)
|
||||||
|
|
||||||
The package includes the following modules: agents, modules, transfer, general, discovery and http. Each one has different requirements and functions that facilitate and automate the data integration in PandoraFMS. They have the following dependencies :
|
The package includes the following modules. Each one has different functions that facilitate and automate the data integration in Pandora FMS:
|
||||||
|
|
||||||
**agents**
|
|
||||||
Module that contains functions oriented to the creation of agents.
|
|
||||||
- datetime.datetime
|
|
||||||
- subprocess.Popen
|
|
||||||
- Hashlib
|
|
||||||
- sys
|
|
||||||
- os
|
|
||||||
- print_module
|
|
||||||
- print_log_module
|
|
||||||
|
|
||||||
**modules**
|
|
||||||
Module that contains functions oriented to the creation of modules.
|
|
||||||
|
|
||||||
**transfer**
|
|
||||||
Module containing functions oriented to file transfer and data sending.
|
|
||||||
- datetime.datetime
|
|
||||||
- subprocess.Popen
|
|
||||||
- shutil
|
|
||||||
- sys
|
|
||||||
- os
|
|
||||||
- print_agent
|
|
||||||
|
|
||||||
**general**
|
**general**
|
||||||
Module containing general purpose functions, useful in the creation of plugins for PandoraFMS.
|
Module containing general purpose functions, useful in the creation of plugins for PandoraFMS
|
||||||
- datetime.datetime
|
|
||||||
- hashlib
|
**threads**
|
||||||
- json
|
Module containing threading purpose functions, useful to run parallel functions.
|
||||||
- sys
|
|
||||||
|
**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**
|
**discovery**
|
||||||
Module that contains general purpose functions, useful in the creation of plugins for PandoraFMS discovery.
|
Module containing functions oriented to the creation of Pandora FMS discovery plugins
|
||||||
- json
|
|
||||||
- sys
|
|
||||||
|
|
||||||
**http**
|
**http**
|
||||||
Module that contains general purpose functions, useful in the creation of plugins for PandoraFMS discovery.
|
Module containing functions oriented to HTTP API calls
|
||||||
- requests_ntlm.HttpNtlmAuth
|
|
||||||
- requests.auth.HTTPBasicAuth
|
|
||||||
- requests.auth.HTTPDigestAuth
|
|
||||||
- requests.sessions.Session
|
|
||||||
|
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
@ -56,7 +35,7 @@ import pandoraPluginTools as ppt
|
|||||||
## Define agent
|
## Define agent
|
||||||
server_name = "WIN-SERV"
|
server_name = "WIN-SERV"
|
||||||
|
|
||||||
agent=ppt.agents.init_agent()
|
agent=ppt.init_agent()
|
||||||
agent.update(
|
agent.update(
|
||||||
agent_name = ppt.generate_md5(server_name),
|
agent_name = ppt.generate_md5(server_name),
|
||||||
agent_alias = server_name,
|
agent_alias = server_name,
|
||||||
@ -86,3 +65,21 @@ ppt.transfer_xml(
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
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
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
from .general import *
|
||||||
|
from .threads import *
|
||||||
from .agents import *
|
from .agents import *
|
||||||
from .modules import *
|
from .modules import *
|
||||||
from .transfer import *
|
from .transfer import *
|
||||||
from .discovery import *
|
from .discovery import *
|
||||||
from .http import *
|
from .http import *
|
||||||
from .general import *
|
|
||||||
|
@ -3,15 +3,22 @@ from subprocess import *
|
|||||||
import hashlib
|
import hashlib
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
from .general import now,set_dict_key_value
|
||||||
from .modules import print_module,print_log_module
|
from .modules import print_module,print_log_module
|
||||||
|
from .transfer import write_xml
|
||||||
|
|
||||||
|
####
|
||||||
|
# Define global variables dict, used in functions as default values.
|
||||||
|
# Its values can be changed.
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
global_variables = {
|
global_variables = {
|
||||||
'temporal' : '/tmp',
|
'agents_group_name' : '',
|
||||||
'agents_group_name': '',
|
'interval' : 300
|
||||||
'interval' : 300
|
|
||||||
}
|
}
|
||||||
#########################################################################################
|
|
||||||
# OS check
|
####
|
||||||
|
# Define some global variables
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
|
|
||||||
POSIX = os.name == "posix"
|
POSIX = os.name == "posix"
|
||||||
@ -28,9 +35,9 @@ AIX = sys.platform.startswith("aix")
|
|||||||
|
|
||||||
####
|
####
|
||||||
# Set a global variable with the specified name and assigns a value to it.
|
# Set a global variable with the specified name and assigns a value to it.
|
||||||
###########################################
|
#########################################################################################
|
||||||
def set_global_variable(
|
def set_global_variable(
|
||||||
variable_name,
|
variable_name: str = "",
|
||||||
value
|
value
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
@ -40,79 +47,33 @@ def set_global_variable(
|
|||||||
variable_name (str): Name of the variable to set.
|
variable_name (str): Name of the variable to set.
|
||||||
value (any): Value to assign to the variable.
|
value (any): Value to assign to the variable.
|
||||||
"""
|
"""
|
||||||
|
set_dict_key_value(global_variables, variable_name, value)
|
||||||
global_variables[variable_name] = value
|
|
||||||
|
|
||||||
####
|
####
|
||||||
# Prints agent XML. Requires agent conf
|
# Agent class
|
||||||
# (dict) and modules (list) as arguments.
|
#########################################################################################
|
||||||
###########################################
|
|
||||||
def print_agent(
|
class Agent:
|
||||||
agent,
|
|
||||||
modules,
|
|
||||||
temp_dir=global_variables['temporal'],
|
|
||||||
log_modules= None,
|
|
||||||
print_flag = None
|
|
||||||
):
|
|
||||||
"""Prints agent XML. Requires agent conf (dict) and modules (list) as arguments.
|
|
||||||
- Use print_flag to show modules' XML in STDOUT.
|
|
||||||
- Returns a tuple (xml, data_file).
|
|
||||||
"""
|
"""
|
||||||
data_file=None
|
Basic agent class. Requires agent parameters (config {dictionary})
|
||||||
|
and module definition (modules_def [list of dictionaries])
|
||||||
|
"""
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
config: dict = None,
|
||||||
|
modules_def: list = []
|
||||||
|
):
|
||||||
|
|
||||||
header = "<?xml version='1.0' encoding='UTF-8'?>\n"
|
if config is None:
|
||||||
header += "<agent_data"
|
config = init_agent()
|
||||||
for dato in agent:
|
|
||||||
header += " " + str(dato) + "='" + str(agent[dato]) + "'"
|
|
||||||
header += ">\n"
|
|
||||||
xml = header
|
|
||||||
if modules :
|
|
||||||
for module in modules:
|
|
||||||
modules_xml = print_module(module)
|
|
||||||
xml += str(modules_xml)
|
|
||||||
if log_modules :
|
|
||||||
for log_module in log_modules:
|
|
||||||
modules_xml = print_log_module(log_module)
|
|
||||||
xml += str(modules_xml)
|
|
||||||
xml += "</agent_data>"
|
|
||||||
if not print_flag:
|
|
||||||
data_file = write_xml(xml, agent["agent_name"], temp_dir)
|
|
||||||
else:
|
|
||||||
print(xml)
|
|
||||||
|
|
||||||
return (xml,data_file)
|
|
||||||
|
|
||||||
####
|
self.config = config
|
||||||
# Creates a agent .data file in the
|
self.modules_def = modules_def
|
||||||
# specified data_dir folder
|
|
||||||
###########################################
|
|
||||||
def write_xml(
|
|
||||||
xml,
|
|
||||||
agent_name,
|
|
||||||
data_dir=global_variables['temporal']
|
|
||||||
):
|
|
||||||
"""Creates a agent .data file in the specified data_dir folder\n
|
|
||||||
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."""
|
|
||||||
|
|
||||||
Utime = datetime.now().strftime('%s')
|
|
||||||
agent_name_md5 = (hashlib.md5(agent_name.encode()).hexdigest())
|
|
||||||
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:
|
|
||||||
print(f"ERROR - Could not write file: {o}, please check directory permissions", file=sys.stderr)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"{type(e).__name__}: {e}", file=sys.stderr)
|
|
||||||
return (data_file)
|
|
||||||
|
|
||||||
####
|
####
|
||||||
# Init agent template
|
# Init agent template
|
||||||
###########################################
|
#########################################################################################
|
||||||
def init_agent() :
|
def init_agent() -> dict:
|
||||||
"""
|
"""
|
||||||
Initializes an agent template with default values.
|
Initializes an agent template with default values.
|
||||||
|
|
||||||
@ -120,33 +81,58 @@ def init_agent() :
|
|||||||
dict: Dictionary representing the agent template with default values.
|
dict: Dictionary representing the agent template with default values.
|
||||||
"""
|
"""
|
||||||
agent = {
|
agent = {
|
||||||
"agent_name" : "",
|
"agent_name" : "",
|
||||||
"agent_alias" : "",
|
"agent_alias" : "",
|
||||||
"parent_agent_name" : "",
|
"parent_agent_name" : "",
|
||||||
"description" : "",
|
"description" : "",
|
||||||
"version" : "",
|
"version" : "",
|
||||||
"os_name" : "",
|
"os_name" : "",
|
||||||
"os_version" : "",
|
"os_version" : "",
|
||||||
"timestamp" : datetime.today().strftime('%Y/%m/%d %H:%M:%S'),
|
"timestamp" : now(),
|
||||||
"address" : "",
|
"address" : "",
|
||||||
"group" : global_variables['agents_group_name'],
|
"group" : global_variables['agents_group_name'],
|
||||||
"interval" : global_variables['interval'],
|
"interval" : global_variables['interval'],
|
||||||
"agent_mode" : "1",
|
"agent_mode" : "1",
|
||||||
}
|
}
|
||||||
|
|
||||||
return agent
|
return agent
|
||||||
|
|
||||||
|
####
|
||||||
#########################################################################################
|
# Prints agent XML. Requires agent conf (dict) and modules (list) as arguments.
|
||||||
# Agent class
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
|
def print_agent(
|
||||||
|
agent: dict = None,
|
||||||
|
modules: list = [],
|
||||||
|
log_modules: list = [],
|
||||||
|
print_flag: bool = False
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
Prints agent XML. Requires agent conf (dict) and modules (list) as arguments.
|
||||||
|
- Use print_flag to show modules' XML in STDOUT.
|
||||||
|
- Returns xml (str).
|
||||||
|
"""
|
||||||
|
xml = ""
|
||||||
|
data_file = None
|
||||||
|
|
||||||
class Agent:
|
if agent is not None:
|
||||||
"""Basic agent class. Requires agent parameters (config {dictionary})
|
header = "<?xml version='1.0' encoding='UTF-8'?>\n"
|
||||||
and module definition (modules_def [list of dictionaries]) """
|
header += "<agent_data"
|
||||||
def __init__(
|
for dato in agent:
|
||||||
self,
|
header += " " + str(dato) + "='" + str(agent[dato]) + "'"
|
||||||
config,
|
header += ">\n"
|
||||||
modules_def
|
xml = header
|
||||||
):
|
|
||||||
self.config = config
|
for module in modules:
|
||||||
self.modules_def = modules_def
|
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(xml)
|
||||||
|
|
||||||
|
return xml
|
||||||
|
@ -1,194 +0,0 @@
|
|||||||
import sys
|
|
||||||
import json
|
|
||||||
|
|
||||||
####
|
|
||||||
# Set fixed value to summary key
|
|
||||||
###########################################
|
|
||||||
def set_summary_value(
|
|
||||||
key="",
|
|
||||||
value=""
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
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
|
|
||||||
|
|
||||||
summary[key] = value
|
|
||||||
|
|
||||||
####
|
|
||||||
# Add value to summary key
|
|
||||||
###########################################
|
|
||||||
def add_summary_value(
|
|
||||||
key="",
|
|
||||||
value=""
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
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.
|
|
||||||
"""
|
|
||||||
global summary
|
|
||||||
|
|
||||||
if key in summary:
|
|
||||||
summary[key] += value
|
|
||||||
else:
|
|
||||||
set_summary_value(key, value)
|
|
||||||
|
|
||||||
####
|
|
||||||
# Set error level to value
|
|
||||||
###########################################
|
|
||||||
def set_error_level(
|
|
||||||
value=0
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
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
|
|
||||||
|
|
||||||
####
|
|
||||||
# Add data to info
|
|
||||||
###########################################
|
|
||||||
def add_info_value(
|
|
||||||
data=""
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Adds data to the 'info' variable.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
data (str, optional): The data to add to the 'info' variable. Default is an empty string.
|
|
||||||
"""
|
|
||||||
global info
|
|
||||||
|
|
||||||
info += data
|
|
||||||
|
|
||||||
####
|
|
||||||
# Set fixed value to info
|
|
||||||
###########################################
|
|
||||||
def set_info_value(
|
|
||||||
data=""
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
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.
|
|
||||||
"""
|
|
||||||
global info
|
|
||||||
|
|
||||||
info = data
|
|
||||||
|
|
||||||
####
|
|
||||||
# Parse parameters from configuration file
|
|
||||||
###########################################
|
|
||||||
def parse_parameter(
|
|
||||||
config=None,
|
|
||||||
default="",
|
|
||||||
key=""
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Parses a parameter from the configuration file.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
config (ConfigParser, optional): The ConfigParser object representing the configuration file. Default is None.
|
|
||||||
default (any, optional): The default value to return if the parameter is not found. Default is an empty string.
|
|
||||||
key (str): The key of the parameter to parse.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
any: The parsed value of the parameter, or the default value if the parameter is not found.
|
|
||||||
"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
return config.get("CONF", key)
|
|
||||||
except Exception as e:
|
|
||||||
return default
|
|
||||||
|
|
||||||
####
|
|
||||||
# Parse configuration file credentials
|
|
||||||
###########################################
|
|
||||||
def parse_conf_entities(
|
|
||||||
entities=""
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Parses the configuration file credentials.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
entities (str): A JSON string representing the entities.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
list: A list of entities parsed from the JSON string. If parsing fails, an empty list is returned.
|
|
||||||
"""
|
|
||||||
entities_list = []
|
|
||||||
|
|
||||||
try:
|
|
||||||
parsed_entities = json.loads(entities)
|
|
||||||
if isinstance(parsed_entities, list):
|
|
||||||
entities_list = parsed_entities
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
set_error_level(1)
|
|
||||||
add_info_value("Error while parsing configuration zones or instances: "+str(e)+"\n")
|
|
||||||
|
|
||||||
return entities_list
|
|
||||||
|
|
||||||
|
|
||||||
####
|
|
||||||
# Parse parameter input (int)
|
|
||||||
###########################################
|
|
||||||
def param_int(
|
|
||||||
param=""
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Parses a parameter as an integer.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
param (any): The parameter to be parsed as an integer.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
int: The parsed integer value. If parsing fails, returns 0.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
return int(param)
|
|
||||||
except:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
####
|
|
||||||
# Print JSON output and exit script
|
|
||||||
###########################################
|
|
||||||
def print_output():
|
|
||||||
"""
|
|
||||||
Prints the JSON output and exits the script.
|
|
||||||
|
|
||||||
The function uses the global variables 'output', 'error_level', 'summary', and 'info'
|
|
||||||
to create the JSON output. It then prints the JSON string and exits the script with
|
|
||||||
the 'error_level' as the exit code.
|
|
||||||
"""
|
|
||||||
|
|
||||||
global output
|
|
||||||
global error_level
|
|
||||||
global summary
|
|
||||||
global info
|
|
||||||
|
|
||||||
output={}
|
|
||||||
if summary:
|
|
||||||
output["summary"] = summary
|
|
||||||
|
|
||||||
if info:
|
|
||||||
output["info"] = info
|
|
||||||
|
|
||||||
json_string = json.dumps(output)
|
|
||||||
|
|
||||||
print(json_string)
|
|
||||||
sys.exit(error_level)
|
|
130
pandora_server/extras/pandoraPlugintools/discovery.py
Normal file
130
pandora_server/extras/pandoraPlugintools/discovery.py
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
import sys
|
||||||
|
import json
|
||||||
|
|
||||||
|
####
|
||||||
|
# Define some global variables
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
output = {}
|
||||||
|
error_level = 0
|
||||||
|
summary = {}
|
||||||
|
info = ""
|
||||||
|
monitoring_data = []
|
||||||
|
|
||||||
|
####
|
||||||
|
# Set fixed value to summary key
|
||||||
|
#########################################################################################
|
||||||
|
def set_summary_value(
|
||||||
|
key: str = "",
|
||||||
|
value = ""
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
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
|
||||||
|
|
||||||
|
summary[key] = value
|
||||||
|
|
||||||
|
####
|
||||||
|
# Add value to summary key
|
||||||
|
#########################################################################################
|
||||||
|
def add_summary_value(
|
||||||
|
key: str = "",
|
||||||
|
value = ""
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
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.
|
||||||
|
"""
|
||||||
|
global summary
|
||||||
|
|
||||||
|
if key in summary:
|
||||||
|
summary[key] += value
|
||||||
|
else:
|
||||||
|
set_summary_value(key, value)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Set error level to value
|
||||||
|
#########################################################################################
|
||||||
|
def set_error_level(
|
||||||
|
value: int = 0
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
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
|
||||||
|
|
||||||
|
####
|
||||||
|
# Add data to info
|
||||||
|
#########################################################################################
|
||||||
|
def add_info_value(
|
||||||
|
data: str = ""
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Adds data to the 'info' variable.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data (str, optional): The data to add to the 'info' variable. Default is an empty string.
|
||||||
|
"""
|
||||||
|
global info
|
||||||
|
|
||||||
|
info += data
|
||||||
|
|
||||||
|
####
|
||||||
|
# Set fixed value to info
|
||||||
|
#########################################################################################
|
||||||
|
def set_info_value(
|
||||||
|
data: str = ""
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
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.
|
||||||
|
"""
|
||||||
|
global info
|
||||||
|
|
||||||
|
info = data
|
||||||
|
|
||||||
|
####
|
||||||
|
# Print JSON output and exit script
|
||||||
|
#########################################################################################
|
||||||
|
def print_output():
|
||||||
|
"""
|
||||||
|
Prints the JSON output and exits the script.
|
||||||
|
|
||||||
|
The function uses the global variables 'output', 'error_level', 'summary', and 'info'
|
||||||
|
to create the JSON output. It then prints the JSON string and exits the script with
|
||||||
|
the 'error_level' as the exit code.
|
||||||
|
"""
|
||||||
|
|
||||||
|
global output
|
||||||
|
global error_level
|
||||||
|
global summary
|
||||||
|
global info
|
||||||
|
|
||||||
|
output={}
|
||||||
|
if summary:
|
||||||
|
output["summary"] = summary
|
||||||
|
|
||||||
|
if info:
|
||||||
|
output["info"] = info
|
||||||
|
|
||||||
|
json_string = json.dumps(output)
|
||||||
|
|
||||||
|
print(json_string)
|
||||||
|
sys.exit(error_level)
|
@ -5,47 +5,99 @@ from datetime import datetime
|
|||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
|
|
||||||
#########################################################################################
|
####
|
||||||
# Debug_dict: prints dictionary in formatted json string.
|
# Prints dictionary in formatted json string.
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
|
|
||||||
class debug_dict:
|
def debug_dict(
|
||||||
def __init__ (
|
jsontxt = ""
|
||||||
self,
|
|
||||||
jsontxt
|
|
||||||
):
|
|
||||||
self.debug_json = json.dumps (jsontxt, indent=4)
|
|
||||||
print (self.debug_json)
|
|
||||||
|
|
||||||
#########################################################################################
|
|
||||||
# Timedate class
|
|
||||||
#########################################################################################
|
|
||||||
|
|
||||||
#class Timedate:
|
|
||||||
def now(
|
|
||||||
print_flag=None,
|
|
||||||
utimestamp=None
|
|
||||||
):
|
):
|
||||||
"""Returns time in yyyy/mm/dd HH:MM:SS format by default. Use 1 as an argument
|
"""
|
||||||
to get epoch time (utimestamp)"""
|
Prints any list, dict, string, float or integer as a json
|
||||||
if utimestamp:
|
"""
|
||||||
time = datetime.timestamp(datetime.today())
|
try:
|
||||||
else:
|
debug_json = json.dumps(jsontxt, indent=4)
|
||||||
time = datetime.today().strftime('%Y/%m/%d %H:%M:%S')
|
print (debug_json)
|
||||||
if print_flag:
|
except json.JSONDecodeError as e:
|
||||||
print (time)
|
print(f"debug_dict: Failed to dump. Error: {e}")
|
||||||
else:
|
except Exception as e:
|
||||||
return (time)
|
print(f"debug_dict: Unexpected error: {e}")
|
||||||
|
|
||||||
|
####
|
||||||
|
# Assign to a key in a dict a given value.
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
# Translate macro
|
|
||||||
|
def set_dict_key_value(
|
||||||
|
input_dict: dict = {},
|
||||||
|
input_key: str = "",
|
||||||
|
input_value
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Assign to a key in a dict a given value
|
||||||
|
"""
|
||||||
|
key = input_key.strip()
|
||||||
|
|
||||||
|
if len(key) > 0:
|
||||||
|
input_dict[key] = input_value
|
||||||
|
|
||||||
|
####
|
||||||
|
# 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(
|
||||||
|
print_flag: int = 0,
|
||||||
|
utimestamp: int = 0
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
Returns time in yyyy/mm/dd HH:MM:SS format by default. Use 1 as an argument
|
||||||
|
to get epoch time (utimestamp)
|
||||||
|
"""
|
||||||
|
today = datetime.today()
|
||||||
|
|
||||||
|
if utimestamp:
|
||||||
|
time = datetime.timestamp(today)
|
||||||
|
else:
|
||||||
|
time = today.strftime('%Y/%m/%d %H:%M:%S')
|
||||||
|
|
||||||
|
if print_flag:
|
||||||
|
print(time)
|
||||||
|
|
||||||
|
return time
|
||||||
|
|
||||||
|
####
|
||||||
|
# Translate macros in string from a dict.
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
def translate_macros(
|
def translate_macros(
|
||||||
macro_dic: dict,
|
macro_dic: dict = {},
|
||||||
data: str
|
data: str = ""
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Expects a macro dictionary key:value (macro_name:macro_value)
|
"""
|
||||||
and a string to replace macro. \n
|
Expects a macro dictionary key:value (macro_name:macro_value)
|
||||||
|
and a string to replace macro.
|
||||||
|
|
||||||
It will replace the macro_name for the macro_value in any string.
|
It will replace the macro_name for the macro_value in any string.
|
||||||
"""
|
"""
|
||||||
for macro_name, macro_value in macro_dic.items():
|
for macro_name, macro_value in macro_dic.items():
|
||||||
@ -54,14 +106,15 @@ def translate_macros(
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
#########################################################################################
|
####
|
||||||
# Configuration file parser
|
# Parse configuration file line by line based on separator and return dict.
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
|
|
||||||
def parse_configuration(
|
def parse_configuration(
|
||||||
file="/etc/pandora/pandora_server.conf",
|
file: str = "/etc/pandora/pandora_server.conf",
|
||||||
separator=" "
|
separator: str = " ",
|
||||||
):
|
default_values: dict = {}
|
||||||
|
) -> dict:
|
||||||
"""
|
"""
|
||||||
Parse configuration. Reads configuration file and stores its data as dict.
|
Parse configuration. Reads configuration file and stores its data as dict.
|
||||||
|
|
||||||
@ -73,72 +126,148 @@ def parse_configuration(
|
|||||||
- dict: containing all keys and values from file.
|
- dict: containing all keys and values from file.
|
||||||
"""
|
"""
|
||||||
config = {}
|
config = {}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open (file, "r") as conf:
|
with open (file, "r") as conf:
|
||||||
lines = conf.read().splitlines()
|
lines = conf.read().splitlines()
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if line.startswith("#") or len(line) < 1 :
|
if line.strip().startswith("#") or len(line.strip()) < 1 :
|
||||||
pass
|
continue
|
||||||
else:
|
else:
|
||||||
option, value = line.strip().split(separator)
|
option, value = line.strip().split(separator, maxsplit=1)
|
||||||
config[option.strip()] = value.strip()
|
config[option.strip()] = value.strip()
|
||||||
|
|
||||||
return config
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print (f"{type(e).__name__}: {e}")
|
print (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.
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
# csv file parser
|
|
||||||
#########################################################################################
|
|
||||||
def parse_csv_file(
|
def parse_csv_file(
|
||||||
file, separator=';',
|
file: str = "",
|
||||||
count_parameters=None,
|
separator: str = ';',
|
||||||
debug=False
|
count_parameters: int = 0,
|
||||||
|
debug: bool = False
|
||||||
) -> list:
|
) -> list:
|
||||||
"""
|
"""
|
||||||
Parse csv configuration. Reads configuration file and stores its data in an array.
|
Parse csv configuration. Reads configuration file and stores its data in a list.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
- file (str): configuration csv file path. \n
|
- file (str): configuration csv file path. \n
|
||||||
- separator (str, optional): Separator for option and value. Defaults to ";".
|
- separator (str, optional): Separator for option and value. Defaults to ";".
|
||||||
- coun_parameters (int): min number of parameters each line shold have. Default None
|
- coun_parameters (int): min number of parameters each line shold have. Default None
|
||||||
- debug: print errors on lines
|
- debug (bool): print errors on lines
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
- List: containing a list for of values for each csv line.
|
- List: containing a list for of values for each csv line.
|
||||||
"""
|
"""
|
||||||
csv_arr = []
|
csv_arr = []
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open (file, "r") as conf:
|
with open (file, "r") as csv:
|
||||||
lines = conf.read().splitlines()
|
lines = csv.read().splitlines()
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if line.startswith("#") or len(line) < 1 :
|
if line.strip().startswith("#") or len(line.strip()) < 1 :
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
value = line.strip().split(separator)
|
value = line.strip().split(separator)
|
||||||
if count_parameters is None or len(value) >= count_parameters:
|
if len(value) >= count_parameters:
|
||||||
csv_arr.append(value)
|
csv_arr.append(value)
|
||||||
elif debug==True:
|
elif debug==True:
|
||||||
print(f'Csv line: {line} doesnt match minimun parameter defined: {count_parameters}',file=sys.stderr)
|
print(f'Csv line: {line} does not match minimun parameter defined: {count_parameters}',file=sys.stderr)
|
||||||
|
|
||||||
return csv_arr
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print (f"{type(e).__name__}: {e}")
|
print (f"{type(e).__name__}: {e}")
|
||||||
return 1
|
|
||||||
|
|
||||||
|
return csv_arr
|
||||||
|
|
||||||
|
####
|
||||||
|
# Parse given variable to integer.
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
# md5 generator
|
|
||||||
#########################################################################################
|
def parse_int(
|
||||||
def generate_md5(input_string):
|
var=""
|
||||||
|
) -> int:
|
||||||
"""
|
"""
|
||||||
Generates an MD5 hash for the given input string.
|
Parse given variable to integer.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
input_string (str): The string for which the MD5 hash will be generated.
|
var (any): The variable to be parsed as an integer.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str: The MD5 hash of the input string as a hexadecimal string.
|
int: The parsed integer value. If parsing fails, returns 0.
|
||||||
"""
|
"""
|
||||||
md5_hash = hashlib.md5(input_string.encode()).hexdigest()
|
try:
|
||||||
return md5_hash
|
return int(var)
|
||||||
|
except:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
####
|
||||||
|
# Parse given variable to float.
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
def parse_float(
|
||||||
|
var=""
|
||||||
|
) -> 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=""
|
||||||
|
) -> 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=""
|
||||||
|
) -> 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
|
@ -3,17 +3,18 @@ from requests.auth import HTTPBasicAuth
|
|||||||
from requests.auth import HTTPDigestAuth
|
from requests.auth import HTTPDigestAuth
|
||||||
from requests.sessions import Session
|
from requests.sessions import Session
|
||||||
|
|
||||||
#########################################################################################
|
####
|
||||||
# URL calls
|
# Auth URL session
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
|
|
||||||
def auth_call(
|
def auth_call(
|
||||||
session,
|
session = None,
|
||||||
authtype,
|
authtype: str = "basic",
|
||||||
user,
|
user: str = "",
|
||||||
passw
|
passw: str = ""
|
||||||
):
|
):
|
||||||
"""Authentication for url request. Requires request.sessions.Session() object.
|
"""
|
||||||
|
Authentication for url request. Requires request.sessions.Session() object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
- session (object): request Session() object.
|
- session (object): request Session() object.
|
||||||
@ -21,27 +22,34 @@ def auth_call(
|
|||||||
- user (str): auth user.
|
- user (str): auth user.
|
||||||
- passw (str): auth password.
|
- passw (str): auth password.
|
||||||
"""
|
"""
|
||||||
if authtype == 'ntlm':
|
if session is not None:
|
||||||
session.auth = HttpNtlmAuth(user, passw)
|
if authtype == 'ntlm':
|
||||||
elif authtype == 'basic':
|
session.auth = HttpNtlmAuth(user, passw)
|
||||||
session.auth = HTTPBasicAuth(user, passw)
|
elif authtype == 'basic':
|
||||||
elif authtype == 'digest':
|
session.auth = HTTPBasicAuth(user, passw)
|
||||||
session.auth = HTTPDigestAuth(user, passw)
|
elif authtype == 'digest':
|
||||||
|
session.auth = HTTPDigestAuth(user, passw)
|
||||||
|
|
||||||
|
####
|
||||||
|
# Call URL and return output
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
def call_url(
|
def call_url(
|
||||||
url,
|
url: str = "",
|
||||||
authtype,
|
authtype: str = "basic",
|
||||||
user,
|
user: str = "",
|
||||||
passw,
|
passw: str = "",
|
||||||
time_out
|
timeout: int = 1
|
||||||
):
|
) -> str:
|
||||||
"""Call URL. Uses request module to get url contents.
|
"""
|
||||||
|
Call URL. Uses request module to get url contents.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
- url (str): URL
|
- url (str): URL
|
||||||
- authtype (str): ntlm', 'basic', 'digest'. Optional.
|
- authtype (str): ntlm', 'basic', 'digest'. Optional.
|
||||||
- user (str): auth user. Optional.
|
- user (str): auth user. Optional.
|
||||||
- passw (str): auth password. Optional.
|
- passw (str): auth password. Optional.
|
||||||
|
- timeout (int): session timeout seconds. Optional.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
- str: call output
|
- str: call output
|
||||||
@ -50,11 +58,14 @@ def call_url(
|
|||||||
with Session() as session:
|
with Session() as session:
|
||||||
if authtype != None:
|
if authtype != None:
|
||||||
auth_call(session, authtype, user, passw)
|
auth_call(session, authtype, user, passw)
|
||||||
|
|
||||||
|
output = ""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
output = session.get(url, timeout=time_out, verify=False)
|
output = session.get(url, timeout=timeout, verify=False)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
exit("Error: URL format not valid (example http://myserver/page.php)")
|
output = "Error: URL format not valid (example http://myserver/page.php)"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
exit(f"{type(e).__name__}:\t{str(e)}")
|
output = f"{type(e).__name__}:\t{str(e)}"
|
||||||
else:
|
|
||||||
return output
|
return output
|
||||||
|
@ -1,151 +1,160 @@
|
|||||||
####
|
####
|
||||||
# Returns module in XML format.
|
# Returns module in XML format. Accepts only {dict}
|
||||||
# Accepts only {dict}
|
#########################################################################################
|
||||||
###########################################
|
|
||||||
def print_module(
|
def print_module(
|
||||||
module,
|
module: dict = None,
|
||||||
print_flag=None
|
print_flag: bool = False
|
||||||
):
|
) -> str:
|
||||||
"""Returns module in XML format. Accepts only {dict}.\n
|
"""
|
||||||
|
Returns module in XML format. Accepts only {dict}.
|
||||||
- Only works with one module at a time: otherwise iteration is needed.
|
- Only works with one module at a time: otherwise iteration is needed.
|
||||||
- Module "value" field accepts str type or [list] for datalists.
|
- Module "value" field accepts str type or [list] for datalists.
|
||||||
- Use print_flag to show modules' XML in STDOUT.
|
- Use print_flag to show modules' XML in STDOUT.
|
||||||
"""
|
"""
|
||||||
data = dict(module)
|
module_xml = ""
|
||||||
module_xml = ("<module>\n"
|
|
||||||
"\t<name><![CDATA[" + str(data["name"]) + "]]></name>\n"
|
if module is not None:
|
||||||
"\t<type>" + str(data["type"]) + "</type>\n"
|
data = dict(module)
|
||||||
)
|
module_xml = ("<module>\n"
|
||||||
|
"\t<name><![CDATA[" + str(data["name"]) + "]]></name>\n"
|
||||||
if type(data["type"]) is not str and "string" not in data["type"]: #### Strip spaces if module not generic_data_string
|
"\t<type>" + str(data["type"]) + "</type>\n"
|
||||||
data["value"] = data["value"].strip()
|
)
|
||||||
if isinstance(data["value"], list): # Checks if value is a list
|
|
||||||
module_xml += "\t<datalist>\n"
|
if type(data["type"]) is not str and "string" not in data["type"]: #### Strip spaces if module not generic_data_string
|
||||||
for value in data["value"]:
|
data["value"] = data["value"].strip()
|
||||||
if type(value) is dict and "value" in value:
|
|
||||||
module_xml += "\t<data>\n"
|
if isinstance(data["value"], list): # Checks if value is a list
|
||||||
module_xml += "\t\t<value><![CDATA[" + str(value["value"]) + "]]></value>\n"
|
module_xml += "\t<datalist>\n"
|
||||||
if "timestamp" in value:
|
for value in data["value"]:
|
||||||
module_xml += "\t\t<timestamp><![CDATA[" + str(value["timestamp"]) + "]]></timestamp>\n"
|
if type(value) is dict and "value" in value:
|
||||||
module_xml += "\t</data>\n"
|
module_xml += "\t<data>\n"
|
||||||
module_xml += "\t</datalist>\n"
|
module_xml += "\t\t<value><![CDATA[" + str(value["value"]) + "]]></value>\n"
|
||||||
else:
|
if "timestamp" in value:
|
||||||
module_xml += "\t<data><![CDATA[" + str(data["value"]) + "]]></data>\n"
|
module_xml += "\t\t<timestamp><![CDATA[" + str(value["timestamp"]) + "]]></timestamp>\n"
|
||||||
if "desc" in data:
|
module_xml += "\t</data>\n"
|
||||||
module_xml += "\t<description><![CDATA[" + str(data["desc"]) + "]]></description>\n"
|
module_xml += "\t</datalist>\n"
|
||||||
if "unit" in data:
|
else:
|
||||||
module_xml += "\t<unit><![CDATA[" + str(data["unit"]) + "]]></unit>\n"
|
module_xml += "\t<data><![CDATA[" + str(data["value"]) + "]]></data>\n"
|
||||||
if "interval" in data:
|
|
||||||
module_xml += "\t<module_interval><![CDATA[" + str(data["interval"]) + "]]></module_interval>\n"
|
if "desc" in data:
|
||||||
if "tags" in data:
|
module_xml += "\t<description><![CDATA[" + str(data["desc"]) + "]]></description>\n"
|
||||||
module_xml += "\t<tags>" + str(data["tags"]) + "</tags>\n"
|
if "unit" in data:
|
||||||
if "module_group" in data:
|
module_xml += "\t<unit><![CDATA[" + str(data["unit"]) + "]]></unit>\n"
|
||||||
module_xml += "\t<module_group>" + str(data["module_group"]) + "</module_group>\n"
|
if "interval" in data:
|
||||||
if "module_parent" in data:
|
module_xml += "\t<module_interval><![CDATA[" + str(data["interval"]) + "]]></module_interval>\n"
|
||||||
module_xml += "\t<module_parent>" + str(data["module_parent"]) + "</module_parent>\n"
|
if "tags" in data:
|
||||||
if "min_warning" in data:
|
module_xml += "\t<tags>" + str(data["tags"]) + "</tags>\n"
|
||||||
module_xml += "\t<min_warning><![CDATA[" + str(data["min_warning"]) + "]]></min_warning>\n"
|
if "module_group" in data:
|
||||||
if "min_warning_forced" in data:
|
module_xml += "\t<module_group>" + str(data["module_group"]) + "</module_group>\n"
|
||||||
module_xml += "\t<min_warning_forced><![CDATA[" + str(data["min_warning_forced"]) + "]]></min_warning_forced>\n"
|
if "module_parent" in data:
|
||||||
if "max_warning" in data:
|
module_xml += "\t<module_parent>" + str(data["module_parent"]) + "</module_parent>\n"
|
||||||
module_xml += "\t<max_warning><![CDATA[" + str(data["max_warning"]) + "]]></max_warning>\n"
|
if "min_warning" in data:
|
||||||
if "max_warning_forced" in data:
|
module_xml += "\t<min_warning><![CDATA[" + str(data["min_warning"]) + "]]></min_warning>\n"
|
||||||
module_xml += "\t<max_warning_forced><![CDATA[" + str(data["max_warning_forced"]) + "]]></max_warning_forced>\n"
|
if "min_warning_forced" in data:
|
||||||
if "min_critical" in data:
|
module_xml += "\t<min_warning_forced><![CDATA[" + str(data["min_warning_forced"]) + "]]></min_warning_forced>\n"
|
||||||
module_xml += "\t<min_critical><![CDATA[" + str(data["min_critical"]) + "]]></min_critical>\n"
|
if "max_warning" in data:
|
||||||
if "min_critical_forced" in data:
|
module_xml += "\t<max_warning><![CDATA[" + str(data["max_warning"]) + "]]></max_warning>\n"
|
||||||
module_xml += "\t<min_critical_forced><![CDATA[" + str(data["min_critical_forced"]) + "]]></min_critical_forced>\n"
|
if "max_warning_forced" in data:
|
||||||
if "max_critical" in data:
|
module_xml += "\t<max_warning_forced><![CDATA[" + str(data["max_warning_forced"]) + "]]></max_warning_forced>\n"
|
||||||
module_xml += "\t<max_critical><![CDATA[" + str(data["max_critical"]) + "]]></max_critical>\n"
|
if "min_critical" in data:
|
||||||
if "max_critical_forced" in data:
|
module_xml += "\t<min_critical><![CDATA[" + str(data["min_critical"]) + "]]></min_critical>\n"
|
||||||
module_xml += "\t<max_critical_forced><![CDATA[" + str(data["max_critical_forced"]) + "]]></max_critical_forced>\n"
|
if "min_critical_forced" in data:
|
||||||
if "str_warning" in data:
|
module_xml += "\t<min_critical_forced><![CDATA[" + str(data["min_critical_forced"]) + "]]></min_critical_forced>\n"
|
||||||
module_xml += "\t<str_warning><![CDATA[" + str(data["str_warning"]) + "]]></str_warning>\n"
|
if "max_critical" in data:
|
||||||
if "str_warning_forced" in data:
|
module_xml += "\t<max_critical><![CDATA[" + str(data["max_critical"]) + "]]></max_critical>\n"
|
||||||
module_xml += "\t<str_warning_forced><![CDATA[" + str(data["str_warning_forced"]) + "]]></str_warning_forced>\n"
|
if "max_critical_forced" in data:
|
||||||
if "str_critical" in data:
|
module_xml += "\t<max_critical_forced><![CDATA[" + str(data["max_critical_forced"]) + "]]></max_critical_forced>\n"
|
||||||
module_xml += "\t<str_critical><![CDATA[" + str(data["str_critical"]) + "]]></str_critical>\n"
|
if "str_warning" in data:
|
||||||
if "str_critical_forced" in data:
|
module_xml += "\t<str_warning><![CDATA[" + str(data["str_warning"]) + "]]></str_warning>\n"
|
||||||
module_xml += "\t<str_critical_forced><![CDATA[" + str(data["str_critical_forced"]) + "]]></str_critical_forced>\n"
|
if "str_warning_forced" in data:
|
||||||
if "critical_inverse" in data:
|
module_xml += "\t<str_warning_forced><![CDATA[" + str(data["str_warning_forced"]) + "]]></str_warning_forced>\n"
|
||||||
module_xml += "\t<critical_inverse><![CDATA[" + str(data["critical_inverse"]) + "]]></critical_inverse>\n"
|
if "str_critical" in data:
|
||||||
if "warning_inverse" in data:
|
module_xml += "\t<str_critical><![CDATA[" + str(data["str_critical"]) + "]]></str_critical>\n"
|
||||||
module_xml += "\t<warning_inverse><![CDATA[" + str(data["warning_inverse"]) + "]]></warning_inverse>\n"
|
if "str_critical_forced" in data:
|
||||||
if "max" in data:
|
module_xml += "\t<str_critical_forced><![CDATA[" + str(data["str_critical_forced"]) + "]]></str_critical_forced>\n"
|
||||||
module_xml += "\t<max><![CDATA[" + str(data["max"]) + "]]></max>\n"
|
if "critical_inverse" in data:
|
||||||
if "min" in data:
|
module_xml += "\t<critical_inverse><![CDATA[" + str(data["critical_inverse"]) + "]]></critical_inverse>\n"
|
||||||
module_xml += "\t<min><![CDATA[" + str(data["min"]) + "]]></min>\n"
|
if "warning_inverse" in data:
|
||||||
if "post_process" in data:
|
module_xml += "\t<warning_inverse><![CDATA[" + str(data["warning_inverse"]) + "]]></warning_inverse>\n"
|
||||||
module_xml += "\t<post_process><![CDATA[" + str(data["post_process"]) + "]]></post_process>\n"
|
if "max" in data:
|
||||||
if "disabled" in data:
|
module_xml += "\t<max><![CDATA[" + str(data["max"]) + "]]></max>\n"
|
||||||
module_xml += "\t<disabled><![CDATA[" + str(data["disabled"]) + "]]></disabled>\n"
|
if "min" in data:
|
||||||
if "min_ff_event" in data:
|
module_xml += "\t<min><![CDATA[" + str(data["min"]) + "]]></min>\n"
|
||||||
module_xml += "\t<min_ff_event><![CDATA[" + str(data["min_ff_event"]) + "]]></min_ff_event>\n"
|
if "post_process" in data:
|
||||||
if "status" in data:
|
module_xml += "\t<post_process><![CDATA[" + str(data["post_process"]) + "]]></post_process>\n"
|
||||||
module_xml += "\t<status><![CDATA[" + str(data["status"]) + "]]></status>\n"
|
if "disabled" in data:
|
||||||
if "timestamp" in data:
|
module_xml += "\t<disabled><![CDATA[" + str(data["disabled"]) + "]]></disabled>\n"
|
||||||
module_xml += "\t<timestamp><![CDATA[" + str(data["timestamp"]) + "]]></timestamp>\n"
|
if "min_ff_event" in data:
|
||||||
if "custom_id" in data:
|
module_xml += "\t<min_ff_event><![CDATA[" + str(data["min_ff_event"]) + "]]></min_ff_event>\n"
|
||||||
module_xml += "\t<custom_id><![CDATA[" + str(data["custom_id"]) + "]]></custom_id>\n"
|
if "status" in data:
|
||||||
if "critical_instructions" in data:
|
module_xml += "\t<status><![CDATA[" + str(data["status"]) + "]]></status>\n"
|
||||||
module_xml += "\t<critical_instructions><![CDATA[" + str(data["critical_instructions"]) + "]]></critical_instructions>\n"
|
if "timestamp" in data:
|
||||||
if "warning_instructions" in data:
|
module_xml += "\t<timestamp><![CDATA[" + str(data["timestamp"]) + "]]></timestamp>\n"
|
||||||
module_xml += "\t<warning_instructions><![CDATA[" + str(data["warning_instructions"]) + "]]></warning_instructions>\n"
|
if "custom_id" in data:
|
||||||
if "unknown_instructions" in data:
|
module_xml += "\t<custom_id><![CDATA[" + str(data["custom_id"]) + "]]></custom_id>\n"
|
||||||
module_xml += "\t<unknown_instructions><![CDATA[" + str(data["unknown_instructions"]) + "]]></unknown_instructions>\n"
|
if "critical_instructions" in data:
|
||||||
if "quiet" in data:
|
module_xml += "\t<critical_instructions><![CDATA[" + str(data["critical_instructions"]) + "]]></critical_instructions>\n"
|
||||||
module_xml += "\t<quiet><![CDATA[" + str(data["quiet"]) + "]]></quiet>\n"
|
if "warning_instructions" in data:
|
||||||
if "module_ff_interval" in data:
|
module_xml += "\t<warning_instructions><![CDATA[" + str(data["warning_instructions"]) + "]]></warning_instructions>\n"
|
||||||
module_xml += "\t<module_ff_interval><![CDATA[" + str(data["module_ff_interval"]) + "]]></module_ff_interval>\n"
|
if "unknown_instructions" in data:
|
||||||
if "crontab" in data:
|
module_xml += "\t<unknown_instructions><![CDATA[" + str(data["unknown_instructions"]) + "]]></unknown_instructions>\n"
|
||||||
module_xml += "\t<crontab><![CDATA[" + str(data["crontab"]) + "]]></crontab>\n"
|
if "quiet" in data:
|
||||||
if "min_ff_event_normal" in data:
|
module_xml += "\t<quiet><![CDATA[" + str(data["quiet"]) + "]]></quiet>\n"
|
||||||
module_xml += "\t<min_ff_event_normal><![CDATA[" + str(data["min_ff_event_normal"]) + "]]></min_ff_event_normal>\n"
|
if "module_ff_interval" in data:
|
||||||
if "min_ff_event_warning" in data:
|
module_xml += "\t<module_ff_interval><![CDATA[" + str(data["module_ff_interval"]) + "]]></module_ff_interval>\n"
|
||||||
module_xml += "\t<min_ff_event_warning><![CDATA[" + str(data["min_ff_event_warning"]) + "]]></min_ff_event_warning>\n"
|
if "crontab" in data:
|
||||||
if "min_ff_event_critical" in data:
|
module_xml += "\t<crontab><![CDATA[" + str(data["crontab"]) + "]]></crontab>\n"
|
||||||
module_xml += "\t<min_ff_event_critical><![CDATA[" + str(data["min_ff_event_critical"]) + "]]></min_ff_event_critical>\n"
|
if "min_ff_event_normal" in data:
|
||||||
if "ff_type" in data:
|
module_xml += "\t<min_ff_event_normal><![CDATA[" + str(data["min_ff_event_normal"]) + "]]></min_ff_event_normal>\n"
|
||||||
module_xml += "\t<ff_type><![CDATA[" + str(data["ff_type"]) + "]]></ff_type>\n"
|
if "min_ff_event_warning" in data:
|
||||||
if "ff_timeout" in data:
|
module_xml += "\t<min_ff_event_warning><![CDATA[" + str(data["min_ff_event_warning"]) + "]]></min_ff_event_warning>\n"
|
||||||
module_xml += "\t<ff_timeout><![CDATA[" + str(data["ff_timeout"]) + "]]></ff_timeout>\n"
|
if "min_ff_event_critical" in data:
|
||||||
if "each_ff" in data:
|
module_xml += "\t<min_ff_event_critical><![CDATA[" + str(data["min_ff_event_critical"]) + "]]></min_ff_event_critical>\n"
|
||||||
module_xml += "\t<each_ff><![CDATA[" + str(data["each_ff"]) + "]]></each_ff>\n"
|
if "ff_type" in data:
|
||||||
if "module_parent_unlink" in data:
|
module_xml += "\t<ff_type><![CDATA[" + str(data["ff_type"]) + "]]></ff_type>\n"
|
||||||
module_xml += "\t<module_parent_unlink><![CDATA[" + str(data["parent_unlink"]) + "]]></module_parent_unlink>\n"
|
if "ff_timeout" in data:
|
||||||
if "global_alerts" in data:
|
module_xml += "\t<ff_timeout><![CDATA[" + str(data["ff_timeout"]) + "]]></ff_timeout>\n"
|
||||||
for alert in data["alert"]:
|
if "each_ff" in data:
|
||||||
module_xml += "\t<alert_template><![CDATA[" + alert + "]]></alert_template>\n"
|
module_xml += "\t<each_ff><![CDATA[" + str(data["each_ff"]) + "]]></each_ff>\n"
|
||||||
module_xml += "</module>\n"
|
if "module_parent_unlink" in data:
|
||||||
|
module_xml += "\t<module_parent_unlink><![CDATA[" + str(data["parent_unlink"]) + "]]></module_parent_unlink>\n"
|
||||||
|
if "alert" in data:
|
||||||
|
for alert in data["alert"]:
|
||||||
|
module_xml += "\t<alert_template><![CDATA[" + alert + "]]></alert_template>\n"
|
||||||
|
module_xml += "</module>\n"
|
||||||
|
|
||||||
if print_flag:
|
if print_flag:
|
||||||
print (module_xml)
|
print(module_xml)
|
||||||
|
|
||||||
return (module_xml)
|
return module_xml
|
||||||
|
|
||||||
|
|
||||||
#########################################################################################
|
####
|
||||||
# print_module
|
# Returns log module in XML format. Accepts only {dict}
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
|
|
||||||
def print_log_module(
|
def print_log_module(
|
||||||
module,
|
module: dict = None,
|
||||||
print_flag = None
|
print_flag: bool = False
|
||||||
):
|
) -> str:
|
||||||
"""Returns log module in XML format. Accepts only {dict}.\n
|
"""
|
||||||
|
Returns log module in XML format. Accepts only {dict}.
|
||||||
- Only works with one module at a time: otherwise iteration is needed.
|
- Only works with one module at a time: otherwise iteration is needed.
|
||||||
- Module "value" field accepts str type.
|
- Module "value" field accepts str type.
|
||||||
- Use not_print_flag to avoid printing the XML (only populates variables).
|
- Use not_print_flag to avoid printing the XML (only populates variables).
|
||||||
"""
|
"""
|
||||||
data = dict(module)
|
module_xml = ""
|
||||||
module_xml = ("<log_module>\n"
|
|
||||||
"\t<source><![CDATA[" + str(data["source"]) + "]]></source>\n"
|
if module is not None:
|
||||||
"\t<data>\"" + str(data["value"]) + "\"</data>\n"
|
data = dict(module)
|
||||||
)
|
module_xml = ("<log_module>\n"
|
||||||
|
"\t<source><![CDATA[" + str(data["source"]) + "]]></source>\n"
|
||||||
module_xml += "</log_module>\n"
|
"\t<data>\"" + str(data["value"]) + "\"</data>\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
module_xml += "</log_module>\n"
|
||||||
|
|
||||||
if print_flag:
|
if print_flag:
|
||||||
print (module_xml)
|
print(module_xml)
|
||||||
|
|
||||||
return (module_xml)
|
return module_xml
|
||||||
|
87
pandora_server/extras/pandoraPlugintools/threads.py
Normal file
87
pandora_server/extras/pandoraPlugintools/threads.py
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import sys
|
||||||
|
from queue import Queue
|
||||||
|
from threading import Thread
|
||||||
|
|
||||||
|
####
|
||||||
|
# Internal use only: Run a given function in a thread
|
||||||
|
#########################################################################################
|
||||||
|
def _single_thread(
|
||||||
|
q = None,
|
||||||
|
function: callable = None,
|
||||||
|
errors: list = []
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Internal use only: Run a given function in a thread
|
||||||
|
"""
|
||||||
|
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 = []
|
||||||
|
) -> bool:
|
||||||
|
"""
|
||||||
|
Run a given function for given items list in a given number of threads
|
||||||
|
"""
|
||||||
|
|
||||||
|
# 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()
|
||||||
|
|
||||||
|
for error in errors:
|
||||||
|
print(error,file=sys.stderr)
|
||||||
|
|
||||||
|
if len(errors) > 0:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print("Error while running threads: "+str(e)+"\n",file=sys.stderr)
|
||||||
|
return False
|
@ -4,22 +4,29 @@ import shutil
|
|||||||
import subprocess
|
import subprocess
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from .general import generate_md5,set_dict_key_value
|
||||||
from .agents import print_agent
|
from .agents import print_agent
|
||||||
|
|
||||||
|
####
|
||||||
|
# Define global variables dict, used in functions as default values.
|
||||||
|
# Its values can be changed.
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
global_variables = {
|
global_variables = {
|
||||||
'transfer_mode' : 'tentacle',
|
'transfer_mode' : 'tentacle',
|
||||||
'temporal' : '/tmp',
|
'temporal' : '/tmp',
|
||||||
'data_dir' : '/var/spool/pandora/data_in/',
|
'data_dir' : '/var/spool/pandora/data_in/',
|
||||||
'tentacle_client' : 'tentacle_client',
|
'tentacle_client' : 'tentacle_client',
|
||||||
'tentacle_ip' : '127.0.0.1',
|
'tentacle_ip' : '127.0.0.1',
|
||||||
'tentacle_port' : 41121
|
'tentacle_port' : 41121,
|
||||||
|
'tentacle_extra_opts' : ''
|
||||||
}
|
}
|
||||||
|
|
||||||
####
|
####
|
||||||
# Set a global variable with the specified name and assigns a value to it.
|
# Set a global variable with the specified name and assigns a value to it.
|
||||||
###########################################
|
#########################################################################################
|
||||||
def set_global_variable(
|
def set_global_variable(
|
||||||
variable_name,
|
variable_name: str = "",
|
||||||
value
|
value
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
@ -29,123 +36,131 @@ def set_global_variable(
|
|||||||
variable_name (str): Name of the variable to set.
|
variable_name (str): Name of the variable to set.
|
||||||
value (any): Value to assign to the variable.
|
value (any): Value to assign to the variable.
|
||||||
"""
|
"""
|
||||||
|
set_dict_key_value(global_variables, variable_name, value)
|
||||||
global_variables[variable_name] = value
|
|
||||||
|
|
||||||
####
|
####
|
||||||
# Sends file using tentacle protocol
|
# Sends file using tentacle protocol
|
||||||
###########################################
|
#########################################################################################
|
||||||
def tentacle_xml(
|
def tentacle_xml(
|
||||||
file,
|
data_file: str = "",
|
||||||
tentacle_ops,
|
tentacle_ops: dict = {},
|
||||||
tentacle_path='',
|
tentacle_path: str = global_variables['tentacle_client'],
|
||||||
debug=0
|
debug: int = 0,
|
||||||
):
|
print_errors: bool = True
|
||||||
"""Sends file using tentacle protocol\n
|
) -> bool:
|
||||||
|
"""
|
||||||
|
Sends file using tentacle protocol
|
||||||
- Only works with one file at time.
|
- Only works with one file at time.
|
||||||
- file variable needs full file path.
|
- file variable needs full file path.
|
||||||
- tentacle_opts should be a dict with tentacle options (address [password] [port]).
|
- tentacle_opts should be a dict with tentacle options (address [password] [port]).
|
||||||
- tentacle_path allows to define a custom path for tentacle client in case is not in sys path).
|
- tentacle_path allows to define a custom path for tentacle client in case is not in sys path).
|
||||||
- if debug is enabled, the data file will not be removed after being sent.
|
- if debug is enabled, the data file will not be removed after being sent.
|
||||||
|
- if print_errors is enabled, function will print all error messages
|
||||||
|
|
||||||
Returns 0 for OK and 1 for errors.
|
Returns True for OK and False for errors.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if file is None :
|
if data_file is not None :
|
||||||
msg="Tentacle error: file path is required."
|
|
||||||
print(str(datetime.today().strftime('%Y-%m-%d %H:%M')) + msg, file=sys.stderr)
|
|
||||||
else :
|
|
||||||
data_file = file
|
|
||||||
|
|
||||||
if tentacle_ops['address'] is None :
|
if not 'address' in tentacle_ops:
|
||||||
msg="Tentacle error: No address defined"
|
tentacle_ops['address'] = global_variables['tentacle_ip']
|
||||||
print(str(datetime.today().strftime('%Y-%m-%d %H:%M')) + msg, file=sys.stderr)
|
if not 'port' in tentacle_ops:
|
||||||
return 1
|
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:
|
||||||
|
sys.stderr.write("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:
|
||||||
|
sys.stderr.write(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=Popen(tentacle_cmd, stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True)
|
||||||
|
rc=tentacle_exe.wait()
|
||||||
|
|
||||||
|
if debug == 0 :
|
||||||
|
os.remove(data_file.strip())
|
||||||
|
|
||||||
|
if rc != 0 :
|
||||||
|
if print_errors:
|
||||||
|
stderr = tentacle_exe.stderr.read().decode()
|
||||||
|
msg="Tentacle error:" + str(stderr)
|
||||||
|
print(str(datetime.today().strftime('%Y-%m-%d %H:%M')) + msg , file=sys.stderr)
|
||||||
|
return False
|
||||||
|
|
||||||
try :
|
else:
|
||||||
with open(data_file, 'r') as data:
|
if print_errors:
|
||||||
data.read()
|
sys.stderr.write("Tentacle error: file path is required.")
|
||||||
data.close()
|
return False
|
||||||
except Exception as e :
|
|
||||||
msg=f"Tentacle error: {type(e).__name__} {e}"
|
|
||||||
print(str(datetime.today().strftime('%Y-%m-%d %H:%M')) + msg , file=sys.stderr)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
tentacle_cmd = f"{tentacle_path}{global_variables['tentacle_client']} -v -a {tentacle_ops['address']} {global_variables['tentacle_opts']}"
|
|
||||||
if "port" in tentacle_ops:
|
|
||||||
tentacle_cmd += f"-p {tentacle_ops['port']} "
|
|
||||||
if "password" in tentacle_ops:
|
|
||||||
tentacle_cmd += f"-x {tentacle_ops['password']} "
|
|
||||||
tentacle_cmd += f"{data_file.strip()} "
|
|
||||||
|
|
||||||
tentacle_exe=Popen(tentacle_cmd, stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True)
|
|
||||||
rc=tentacle_exe.wait()
|
|
||||||
|
|
||||||
if rc != 0 :
|
|
||||||
stderr = tentacle_exe.stderr.read().decode()
|
|
||||||
msg="Tentacle error:" + str(stderr)
|
|
||||||
print(str(datetime.today().strftime('%Y-%m-%d %H:%M')) + msg , file=sys.stderr)
|
|
||||||
next
|
|
||||||
return 1
|
|
||||||
elif debug == 0 :
|
|
||||||
os.remove(file)
|
|
||||||
|
|
||||||
return 0
|
|
||||||
|
|
||||||
####
|
####
|
||||||
# Detect transfer mode and execute
|
# Detect transfer mode and send XML.
|
||||||
###########################################
|
#########################################################################################
|
||||||
def agentplugin(
|
|
||||||
modules,
|
|
||||||
agent,
|
|
||||||
temp_dir=global_variables['temporal'],
|
|
||||||
tentacle=False,
|
|
||||||
tentacle_conf=None
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Detects the transfer mode and executes the corresponding action.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
modules (list): List of modules.
|
|
||||||
agent (dict): Dictionary with agent configuration.
|
|
||||||
temp_dir (str, optional): Temporary directory. Default is global_variables['temporal'].
|
|
||||||
tentacle (bool, optional): Indicates whether to use the Tentacle protocol. Default is False.
|
|
||||||
tentacle_conf (dict, optional): Dictionary with Tentacle protocol configuration. Default is None.
|
|
||||||
"""
|
|
||||||
agent_file=print_agent(agent,modules,temp_dir)
|
|
||||||
|
|
||||||
if agent_file[1] is not None:
|
|
||||||
if tentacle == True and tentacle_conf is not None:
|
|
||||||
tentacle_xml(agent_file[1],tentacle_conf)
|
|
||||||
else:
|
|
||||||
shutil.move(agent_file[1], global_variables['data_dir'])
|
|
||||||
|
|
||||||
####
|
|
||||||
# Detect transfer mode and execute (call agentplugin())
|
|
||||||
###########################################
|
|
||||||
def transfer_xml(
|
def transfer_xml(
|
||||||
agent,
|
file: str = "",
|
||||||
modules,
|
transfer_mode: str = global_variables['transfer_mode'],
|
||||||
transfer_mode=global_variables['transfer_mode'],
|
tentacle_ip: str = global_variables['tentacle_ip'],
|
||||||
tentacle_ip=global_variables['tentacle_ip'],
|
tentacle_port: int = global_variables['tentacle_port'],
|
||||||
tentacle_port=global_variables['tentacle_port'],
|
tentacle_extra_opts: str = global_variables['tentacle_extra_opts'],
|
||||||
temporal=global_variables['temporal']
|
data_dir: str = global_variables['data_dir']
|
||||||
):
|
):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Detects the transfer mode and calls the agentplugin() function to perform the transfer.
|
Detects the transfer mode and calls the agentplugin() function to perform the transfer.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
agent (dict): Dictionary with agent configuration.
|
file (str): Path to file to send.
|
||||||
modules (list): List of modules.
|
|
||||||
transfer_mode (str, optional): Transfer mode. Default is global_variables['transfer_mode'].
|
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_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'].
|
tentacle_port (str, optional): Port for Tentacle. Default is global_variables['tentacle_port'].
|
||||||
temporal (str, optional): Temporary directory. Default is global_variables['temporal'].
|
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":
|
||||||
|
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']
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
Creates a 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.
|
||||||
|
"""
|
||||||
|
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))
|
||||||
|
|
||||||
if transfer_mode != "local" and tentacle_ip is not None:
|
try:
|
||||||
tentacle_conf={"address":tentacle_ip,"port":tentacle_port}
|
with open(data_file, 'x') as data:
|
||||||
agentplugin(modules,agent,temporal,True,tentacle_conf)
|
data.write(xml)
|
||||||
else:
|
except OSError as o:
|
||||||
agentplugin(modules,agent,temporal)
|
print(f"ERROR - Could not write file: {o}, please check directory permissions", file=sys.stderr)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"{type(e).__name__}: {e}", file=sys.stderr)
|
||||||
|
|
||||||
|
return data_file
|
||||||
|
Loading…
x
Reference in New Issue
Block a user