diff --git a/pandora_agents/unix/Linux/pandora_agent.conf b/pandora_agents/unix/Linux/pandora_agent.conf index 52ca10f17b..34f9d8e02b 100644 --- a/pandora_agents/unix/Linux/pandora_agent.conf +++ b/pandora_agents/unix/Linux/pandora_agent.conf @@ -254,9 +254,6 @@ module_plugin pandora_mem_used module_plugin pandora_netusage -# Service autodiscovery plugin -module_plugin autodiscover --default - # Plugin for inventory on the agent (Only Enterprise) #module_plugin inventory 1 cpu ram video nic hd cdrom software init_services filesystem users route diff --git a/pandora_agents/unix/plugins/autodiscover b/pandora_agents/unix/plugins/autodiscover deleted file mode 100644 index cbe4de677e..0000000000 Binary files a/pandora_agents/unix/plugins/autodiscover and /dev/null differ diff --git a/pandora_agents/win32/bin/pandora_agent.conf b/pandora_agents/win32/bin/pandora_agent.conf index 774797aa4b..ba1e0b6444 100644 --- a/pandora_agents/win32/bin/pandora_agent.conf +++ b/pandora_agents/win32/bin/pandora_agent.conf @@ -245,10 +245,6 @@ module_plugin cscript.exe //B "%ProgramFiles%\Pandora_Agent\util\network.vbs" #module_crontab * 12-15 * * 1 #module_end -# Service autodiscovery plugin -module_plugin "%PROGRAMFILES%\Pandora_Agent\util\autodiscover.exe" --default - - ######################################### # EXAMPLES # ######################################### diff --git a/pandora_agents/win32/bin/util/autodiscover.exe b/pandora_agents/win32/bin/util/autodiscover.exe deleted file mode 100644 index 41b7bf3629..0000000000 Binary files a/pandora_agents/win32/bin/util/autodiscover.exe and /dev/null differ diff --git a/pandora_plugins/Autodiscover services/autodiscover b/pandora_plugins/Autodiscover services/autodiscover deleted file mode 100644 index cbe4de677e..0000000000 Binary files a/pandora_plugins/Autodiscover services/autodiscover and /dev/null differ diff --git a/pandora_plugins/Autodiscover services/autodiscover.exe b/pandora_plugins/Autodiscover services/autodiscover.exe deleted file mode 100644 index 41b7bf3629..0000000000 Binary files a/pandora_plugins/Autodiscover services/autodiscover.exe and /dev/null differ diff --git a/pandora_plugins/Autodiscover services/autodiscover.py b/pandora_plugins/Autodiscover services/autodiscover.py deleted file mode 100644 index 78a70cddba..0000000000 --- a/pandora_plugins/Autodiscover services/autodiscover.py +++ /dev/null @@ -1,398 +0,0 @@ -#!/usr/bin/env python3 -################################################### -# -# Pandora FMS Autodiscovery plugin. -# Checks the status of the services in list and monitors CPU and Memory for each of them. -# -# (c) A. Kevin Rojas -# -# TO DO LIST: -# - Enable child services detection (Windows) -# - Make CPU/Memory usage available for child services (Windows) -# -################################################### - -from sys import argv, path, stderr, exit -import psutil -from subprocess import * - -global module_list -module_list = [] - - -######################################################################################### -# Powershell class -######################################################################################### -class PSCheck: - @staticmethod - def check_service(servicename, option=False, memcpu=False): - """Check services with powershell by parsing their DisplayName. Returns a dict\ - list with the name of the service and a boolean with its status.\n - Requires service name (case insensitive).""" - pscall = Popen(["powershell", "Get-Service", "-Name", "'*"+ str(servicename) + "*'", - "|", "Select-Object", "-ExpandProperty", "Name"], - stdout=PIPE, stdin=DEVNULL, stderr=DEVNULL, universal_newlines=True) - result = pscall.communicate() - result = str(result[0]).strip().split("\n") - procname = '' - if result != '': - output = [] - for element in result: - if element != '': - # Get process name - procname = PSCheck.get_serviceprocess(element) - # Get process status - parstatus = PSCheck.getstatus(element) - if memcpu == True and parstatus == 1: - usage = get_memcpu(str(procname), str(element)) - output += usage - # Generate module with name and status - parent = service_module(str(element), parstatus) - output += parent - if option == True: - children = PSCheck.getchildren(element, memcpu) - if type(children) == list and len(children) > 1: - for child in children: - output += child - else: - output += children - else: - next - - #if output != '': - if output and element and procname: - return ({"name" : element, "process" : procname, "modules": output}) - else: - return (None) - - @staticmethod - def getchildren(servicename, memcpu=False): - """Gets Dependent services of a given Windows service""" - pschild = Popen(["powershell", "Get-Service", "-Name '" + str(servicename) + - "' -DS", "|", "Select-Object", "-ExpandProperty", "Name"], - stdout=PIPE, stdin=DEVNULL, stderr=DEVNULL, universal_newlines=True) - children = pschild.communicate()[0].strip() - kids = [] - for child in (children.split("\n") if children != "" else []): - status = PSCheck.getstatus(child) - kids += service_module(str(child), status, "Service " + str(servicename) + " - Status") - if status: - if memcpu == True: - kidsusage = get_memcpu(str(child)) - for usage in kidsusage: - kids += usage - else: - next - return (kids) - - @staticmethod - def getstatus(servicename): - """Gets the status of a given Windows service""" - running = Popen(["powershell", "Get-Service", "-Name '" + str(servicename) + - "' |", "Select-Object", "-ExpandProperty", "Status"], - stdout=PIPE, stdin=DEVNULL, stderr=DEVNULL, universal_newlines=True) - status = running.communicate()[0].strip() - return (int(status == "Running")) - - @staticmethod - def get_serviceprocess(servicename): - """Gets name of the process of the service""" - service = psutil.win_service_get(servicename) - srv_pid = service.pid() - process = psutil.Process(srv_pid) - proc_name = process.name() - return (proc_name) - - -######################################################################################### -# Services creation -######################################################################################### - -def service_module(name, value, parent=None): - #print ("service_module BEGIN "+str(now(0,1))) - module = [{ - "name" : "Service "+ name + " - Status", - "type" : "generic_proc", - "value" : value, - "module_parent" : parent, - }] - #print ("service_module END "+str(now(0,1))) - return (module) - -def get_memcpu (process, servicename): - """Creates a module for Memory and CPU for a given process. Returns a list of dictionaries.""" - modules = [] - if process: - if servicename != None: - parentname = servicename - else: - parentname = process - modules += [{ - "name" : "Service "+ process + " - Memory usage", - "type" : "generic_data", - "value" : proc_percentbyname(process)[0], - "unit" : "%", - "module_parent" : "Service "+ parentname + " - Status", - }, - {"name" : "Service "+ process + " - CPU usage", - "type" : "generic_data", - "value" : proc_percentbyname(process)[1], - "unit" : "%", - "module_parent" : "Service "+ parentname + " - Status", - }] - return (modules) - -def proc_percentbyname(procname): ############# 03/03/2020 - """Gets Memory and CPU usage for a given process. Returns a list.""" - #print ("proc_percentbyname BEGIN "+str(now(0,1))) - procs = [p for p in psutil.process_iter() if procname in p.name().lower()] - memory = [] - cpu = [] - try: - for proc in procs: - if proc.name() == procname: - cpu.append(proc.cpu_percent(interval=0.5)) - memory.append(proc.memory_percent()) - else: - next - except psutil.NoSuchProcess: - next - #print ("proc_percentbyname END "+str(now(0,1))) - return ([sum(memory),sum(cpu)]) - -def win_service(servicelist, option=False, memcpu=False): - """Creates modules for Windows servers.""" - modules = [] - for srvc in servicelist: - if srvc and len(srvc) > 2: - output = PSCheck.check_service(srvc, option, memcpu) - if output != None and output["modules"]: - modules += PSCheck.check_service(srvc.strip(), option, memcpu)["modules"] - module_list.append(srvc) - winprocess = output["name"] - #if memcpu == True: - # modules += get_memcpu(winprocess) ## Only available for parent service ATM. - else: - next - else: - next - for module in modules: - print_module(module, 1) - - -def lnx_service(services_list, memcpu=False): - """Creates modules for Linux servers""" - modules = [] - sysctl = getstatusoutput("command -v systemctl")[0] - servic = getstatusoutput("command -v service")[0] - for srvc in services_list: - status = None - if sysctl == 0: - ### Systemd available - syscall = Popen(["systemctl", "is-active", srvc], stdout=PIPE, - stdin=DEVNULL, universal_newlines=True) - result = syscall.communicate() - result = result[0].strip().lower() - if result == "active": - modules += service_module(srvc, 1) - status = 1 - elif result == "inactive": - modules += service_module(srvc, 0) - status = 0 - elif result == "unknown": - next - elif sysctl != 0 and servic == 0: - ### Systemd not available, switch to service command - syscall = Popen(["service", srvc, "status"], stdout=PIPE, - stdin=DEVNULL, stderr=DEVNULL, universal_newlines=True) - result = syscall.communicate()[0].lower() - if "is running" in result: - modules += service_module(srvc, 1) - status = 1 - elif "is stopped" in result: - modules += service_module(srvc, 0) - status = 0 - else: - next - else: - print ("No systemd or service commands available. Exiting...", file=stderr) - exit() - if status: - module_list.append(srvc) - if memcpu == True: - modules += get_memcpu(srvc, None) - - for m in modules: - print_module (m, 1) - - -######################################################################################### -# print_module function -######################################################################################### -def print_module(module, str_flag=False): - """Returns module in XML format. Accepts only {dict}.\n - + Only works with one module at a time: otherwise iteration is needed. - + Module "value" field accepts str type or [list] for datalists. - + Use not_print_flag to avoid printing the XML (only populates variables). - """ - data = dict(module) - module_xml = ("\n" - "\t\n" - "\t" + str(data["type"]) + "\n" - ) - #### Strip spaces if module not generic_data_string - if type(data["type"]) is not str and "string" not in data["type"]: - data["value"] = data["value"].strip() - if isinstance(data["value"], list): # Checks if value is a list - module_xml += "\t\n" - for value in data["value"]: - if type(value) is dict and "value" in value: - module_xml += "\t\n" - module_xml += "\t\t\n" - if "timestamp" in value: - module_xml += "\t\t\n" - module_xml += "\t\n" - else: - module_xml += "\t\n" - if "desc" in data: - module_xml += "\t\n" - if "unit" in data: - module_xml += "\t\n" - if "interval" in data: - module_xml += "\t\n" - if "tags" in data: - module_xml += "\t" + str(data["tags"]) + "\n" - if "module_group" in data: - module_xml += "\t" + str(data["module_group"]) + "\n" - if "module_parent" in data and data["module_parent"] != None: - module_xml += "\t" + str(data["module_parent"]) + "\n" - if "min_warning" in data: - module_xml += "\t\n" - if "max_warning" in data: - module_xml += "\t\n" - if "min_critical" in data: - module_xml += "\t\n" - if "max_critical" in data: - module_xml += "\t\n" - if "str_warning" in data: - module_xml += "\t\n" - if "str_critical" in data: - module_xml += "\t\n" - if "critical_inverse" in data: - module_xml += "\t\n" - if "warning_inverse" in data: - module_xml += "\t\n" - if "max" in data: - module_xml += "\t\n" - if "min" in data: - module_xml += "\t\n" - if "post_process" in data: - module_xml += "\t\n" - if "disabled" in data: - module_xml += "\t\n" - if "min_ff_event" in data: - module_xml += "\t\n" - if "status" in data: - module_xml += "\t\n" - if "timestamp" in data: - module_xml += "\t\n" - if "custom_id" in data: - module_xml += "\t\n" - if "critical_instructions" in data: - module_xml += "\t\n" - if "warning_instructions" in data: - module_xml += "\t\n" - if "unknown_instructions" in data: - module_xml += "\t\n" - if "quiet" in data: - module_xml += "\t\n" - if "module_ff_interval" in data: - module_xml += "\t\n" - if "crontab" in data: - module_xml += "\t\n" - if "min_ff_event_normal" in data: - module_xml += "\t\n" - if "min_ff_event_warning" in data: - module_xml += "\t\n" - if "min_ff_event_critical" in data: - module_xml += "\t\n" - if "ff_type" in data: - module_xml += "\t\n" - if "ff_timeout" in data: - module_xml += "\t\n" - if "each_ff" in data: - module_xml += "\t\n" - if "module_parent_unlink" in data: - module_xml += "\t\n" - if "global_alerts" in data: - for alert in data["alert"]: - module_xml += "\t\n" - module_xml += "\n" - - #### Print flag - if str_flag is not False: - print (module_xml) - - return (module_xml) - - -######################################################################################### -# MAIN -######################################################################################### - -def main(): - """Checks OS and calls the discover function.""" - if psutil.WINDOWS: - OS = "Windows" - service_list = ["MySQL", "postgresql", "pgsql", "oracle", "MSSQL", "IISADMIN", - "apache", "nginx", "W3svc", "NTDS", "Netlogon", "DNS", "MSExchangeADTopology", - "MSExchangeServiceHost", "MSExchangeSA", "MSExchangeTransport"] - discover(OS, service_list) - elif psutil.LINUX: - OS = "Linux" - service_list = ["httpd", "apache2", "nginx", "ldap", "docker", - "postfix", "mysqld", "postgres", "oracle", "mongod"] - discover(OS, service_list) - else: - print ("OS not recognized. Exiting...", file=stderr) - exit() - -def discover(osyst, servicelist): - """Shows help and triggers the creation of service modules""" - if "--usage" in argv: - memcpu = True - else: - memcpu = False - if len(argv) > 2 and argv[1] == "--list": - servicelist = argv[2].split(",") - if osyst == "Windows": - win_service(servicelist, False, memcpu) ## False won't get children - elif osyst == "Linux": - lnx_service(servicelist, memcpu) - elif len(argv) > 1 and argv[1] == "--default": - if osyst == "Windows": - win_service(servicelist, False, memcpu) ## False won't get children - elif osyst == "Linux": - lnx_service(servicelist, memcpu) - else: - print ("\nPandora FMS Autodiscovery plugin.") - print ("Checks the status of the services in list and monitors CPU and Memory for each of them.\n") - print ("Usage:") - print ("{} [options] [--usage]".format(argv[0])) - print ("--help") - print ("\tPrints this help screen") - print ("--default") - print ("\tRuns this tool with default monitoring.".format(argv[0])) - print ("\tServices monitored by default for {}:".format(osyst)) - print ("\t",", ".join(servicelist)) - print ("--list \"\"") - print ("\tReplaces default services for a given list (comma-separated)") - if osyst == "Windows": - print ("\tEach element of the list will be treated as a regexp, but they must be over 2 characters.") - print ("\tElements under 2 characters will be discarded.") - print ("--usage") - print ("\tAdds modules for CPU and Memory usage per service/process (optional, can take some time).\n") - - -##### RUN #### -main() \ No newline at end of file