Merge branch 'ent-10178-14839-plugin-autodiscover-de-agente-perjudica-al-agente' into 'develop'
changed the way of getting data out of windows to make it faster See merge request artica/pandorafms!5590
This commit is contained in:
commit
8278c9c4e5
|
@ -6,21 +6,22 @@
|
||||||
#
|
#
|
||||||
# (c) A. Kevin Rojas <kevin.rojas@pandorafms.com>
|
# (c) A. Kevin Rojas <kevin.rojas@pandorafms.com>
|
||||||
#
|
#
|
||||||
|
# Edited in 2023 by Alejandro Sánchez <alejandro.sanchez@pandorafms.com>
|
||||||
|
#
|
||||||
# TO DO LIST:
|
# TO DO LIST:
|
||||||
# - Enable child services detection (Windows)
|
# - Enable child services detection (Windows)
|
||||||
# - Make CPU/Memory usage available for child services (Windows)
|
# - Make CPU/Memory usage available for child services (Windows)
|
||||||
#
|
#
|
||||||
###################################################
|
###################################################
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from sys import argv
|
from sys import argv
|
||||||
from sys import stderr
|
from sys import stderr
|
||||||
from sys import exit
|
from sys import exit
|
||||||
|
import psutil
|
||||||
from subprocess import Popen
|
from subprocess import Popen
|
||||||
from subprocess import PIPE
|
from subprocess import PIPE
|
||||||
from subprocess import DEVNULL
|
from subprocess import DEVNULL
|
||||||
from subprocess import getstatusoutput
|
from subprocess import getstatusoutput
|
||||||
import psutil
|
|
||||||
except ModuleNotFoundError as err:
|
except ModuleNotFoundError as err:
|
||||||
print("{} error: {}. Exiting...".format(argv[0], err), file=stderr)
|
print("{} error: {}. Exiting...".format(argv[0], err), file=stderr)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
@ -28,99 +29,100 @@ except ModuleNotFoundError as err:
|
||||||
module_list = []
|
module_list = []
|
||||||
VERSION = "1.2"
|
VERSION = "1.2"
|
||||||
|
|
||||||
|
def win_service(servicelist, option=False, memcpu=False):
|
||||||
|
|
||||||
#########################################################################################
|
modules_default = []
|
||||||
# Powershell class
|
modules_percentage=[]
|
||||||
#########################################################################################
|
## take all services
|
||||||
class PSCheck:
|
services=psutil.win_service_iter()
|
||||||
@staticmethod
|
for service in services:
|
||||||
def check_service(servicename, option=False, memcpu=False):
|
if service.name() in servicelist:
|
||||||
"""Check services with powershell by parsing their DisplayName. Returns a dict\
|
serv=service.as_dict()
|
||||||
list with the name of the service and a boolean with its status.\n
|
if serv['status']=='running':
|
||||||
Requires service name (case insensitive)."""
|
value=1
|
||||||
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 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:
|
|
||||||
children = PSCheck.getchildren(element, memcpu)
|
|
||||||
if isinstance(children, list) and len(children) > 1:
|
|
||||||
for child in children:
|
|
||||||
output += child
|
|
||||||
else:
|
else:
|
||||||
output += children
|
value=0
|
||||||
else:
|
|
||||||
next
|
|
||||||
|
|
||||||
if output and element and procname:
|
## create module for each service
|
||||||
return ({"name" : element, "process" : procname, "modules": output})
|
parent = build_module("Service " + str(serv['name']) + " - Status", value,"generic_proc")
|
||||||
else:
|
modules_default +=parent
|
||||||
return (None)
|
|
||||||
|
|
||||||
@staticmethod
|
# memory and cpu percentage
|
||||||
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:
|
if memcpu:
|
||||||
kidsusage = get_memcpu(str(child))
|
## process
|
||||||
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()
|
srv_pid = service.pid()
|
||||||
process = psutil.Process(srv_pid)
|
process = psutil.Process(srv_pid)
|
||||||
proc_name = process.name()
|
proc_name = process.name()
|
||||||
return proc_name
|
##cpu
|
||||||
|
value_cpu=process.cpu_percent(interval=0.5)
|
||||||
|
parent = build_module("Service " + str(proc_name) + " - CPU usage", value_cpu,"generic_data")
|
||||||
|
parent[0].update([("unit","%"),("module_parent",str(serv['name']))])
|
||||||
|
modules_percentage +=parent
|
||||||
|
##mem
|
||||||
|
value_mem=process.memory_percent()
|
||||||
|
parent = build_module("Service " + str(proc_name) + " - Memory usage", value_mem,"generic_data")
|
||||||
|
parent[0].update([("unit","%"),("module_parent",str(serv['name']))])
|
||||||
|
modules_percentage +=parent
|
||||||
|
|
||||||
|
|
||||||
#########################################################################################
|
for module in modules_default:
|
||||||
# Services creation
|
print_module(module, 1)
|
||||||
#########################################################################################
|
if memcpu:
|
||||||
|
for module in modules_percentage:
|
||||||
|
print_module(module, 1)
|
||||||
|
|
||||||
def service_module(name, value, parent=None):
|
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", "show", "-pLoadState", "-pActiveState", srvc], stdout=PIPE,
|
||||||
|
stdin=DEVNULL, universal_newlines=True)
|
||||||
|
result = syscall.communicate()
|
||||||
|
srvstatus = result[0].strip().lower().split("\n")
|
||||||
|
if srvstatus[0] == "loadstate=not-found":
|
||||||
|
next
|
||||||
|
else:
|
||||||
|
if srvstatus[1] == "activestate=active":
|
||||||
|
modules += build_module("Service " + srvc + " - Status", 1, "generic_proc")
|
||||||
|
status = 1
|
||||||
|
elif srvstatus[1] == "activestate=inactive":
|
||||||
|
modules += build_module("Service " +srvc+ " - Status", 0, "generic_proc")
|
||||||
|
status = 0
|
||||||
|
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 += build_module("Service " + srvc + " - Status", 1, "generic_proc")
|
||||||
|
status = 1
|
||||||
|
elif "is stopped" in result:
|
||||||
|
modules += build_module("Service " +srvc+ " - Status", 0, "generic_proc")
|
||||||
|
status = 0
|
||||||
|
else:
|
||||||
|
next
|
||||||
|
else:
|
||||||
|
print("No systemd or service commands available. Exiting...", file=stderr)
|
||||||
|
exit()
|
||||||
|
if status:
|
||||||
|
module_list.append(srvc)
|
||||||
|
if memcpu:
|
||||||
|
modules += get_memcpu(srvc, None)
|
||||||
|
|
||||||
|
for m in modules:
|
||||||
|
print_module(m, 1)
|
||||||
|
|
||||||
|
|
||||||
|
def build_module(name, value, module_type, parent=None):
|
||||||
#print ("service_module BEGIN "+str(now(0,1)))
|
#print ("service_module BEGIN "+str(now(0,1)))
|
||||||
module = [{
|
module = [{
|
||||||
"name" : "Service "+ name + " - Status",
|
"name" : name ,
|
||||||
"type" : "generic_proc",
|
"type" : module_type,
|
||||||
"value" : value,
|
"value" : value,
|
||||||
"module_parent" : parent,
|
"module_parent" : parent,
|
||||||
}]
|
}]
|
||||||
|
@ -167,74 +169,6 @@ def proc_percentbyname(procname): ############# 03/03/2020
|
||||||
next
|
next
|
||||||
#print ("proc_percentbyname END "+str(now(0,1)))
|
#print ("proc_percentbyname END "+str(now(0,1)))
|
||||||
return [sum(memory),sum(cpu)]
|
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 is not 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", "show", "-pLoadState", "-pActiveState", srvc], stdout=PIPE,
|
|
||||||
stdin=DEVNULL, universal_newlines=True)
|
|
||||||
result = syscall.communicate()
|
|
||||||
srvstatus = result[0].strip().lower().split("\n")
|
|
||||||
if srvstatus[0] == "loadstate=not-found":
|
|
||||||
next
|
|
||||||
else:
|
|
||||||
if srvstatus[1] == "activestate=active":
|
|
||||||
modules += service_module(srvc, 1)
|
|
||||||
status = 1
|
|
||||||
elif srvstatus[1] == "activestate=inactive":
|
|
||||||
modules += service_module(srvc, 0)
|
|
||||||
status = 0
|
|
||||||
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:
|
|
||||||
modules += get_memcpu(srvc, None)
|
|
||||||
|
|
||||||
for m in modules:
|
|
||||||
print_module(m, 1)
|
|
||||||
|
|
||||||
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
# print_module function
|
# print_module function
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
|
@ -356,6 +290,7 @@ def main():
|
||||||
service_list = ["MySQL", "postgresql", "pgsql", "oracle", "MSSQL", "IISADMIN",
|
service_list = ["MySQL", "postgresql", "pgsql", "oracle", "MSSQL", "IISADMIN",
|
||||||
"apache", "nginx", "W3svc", "NTDS", "Netlogon", "DNS", "MSExchangeADTopology",
|
"apache", "nginx", "W3svc", "NTDS", "Netlogon", "DNS", "MSExchangeADTopology",
|
||||||
"MSExchangeServiceHost", "MSExchangeSA", "MSExchangeTransport"]
|
"MSExchangeServiceHost", "MSExchangeSA", "MSExchangeTransport"]
|
||||||
|
|
||||||
discover(OS, service_list)
|
discover(OS, service_list)
|
||||||
elif psutil.LINUX:
|
elif psutil.LINUX:
|
||||||
OS = "Linux"
|
OS = "Linux"
|
||||||
|
|
Loading…
Reference in New Issue