MegaRAID nagios monitoring - python

I have been beating my head against the wall, trying to figure out what is wrong with the following nagios plugin I wrote. When I run the following code:
#!/usr/bin/env python3
import paramiko
import os.path
import sys
OK = 0
WARNING = 1
CRITICAL = 2
DEPENDENT = 3
UNKNOWN = 4
active = str("Active")
online = str("Online")
optimal = str("Optimal")
k = str("OK")
degrade = str("Degraded")
fail = str("Failed")
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(
hostname='<hostname>',
username='<service account>',
key_filename=os.path.join(os.path.expanduser('~'), ".ssh", "id_rsa.pub")
)
stdin,stdout,stderr = client.exec_command("sudo /opt/MegaRAID/MegaCli/MegaCli64 -ShowSummary -a0")
check = str(stdout.read().decode('ascii'))
client.close()
OK_STR = str("RAID is OK!")
WARN_STR = str("Warning! Something is wrong with the RAID!")
CRIT_STR = str("CRITICAL! THE RAID IS BROKEN")
UNK_STR = str("Uh oh! Something ain't right?")
print(check)
if (degrade) in (check):
print(WARN_STR) and sys.exit(WARNING)
elif (fail) in (check):
print(CRIT_STR) and sys.exit(CRITICAL)
elif str('Exit Code: 0x00') in (check):
print(OK_STR) and sys.exit(OK)
else:
sys.exit(UNKNOWN) and print(UNK_STR)
I recieve the output that I expect running it from CLI. If I change my logic on the if statement, the exit code changes and I have verified using 'echo $?'.
However, in my LibreNMS front end, I receive no stdout message and an exit code of 1, which is not how my code outputs in the terminal. If anybody can find something wrong with my code, I really need the help.

Related

Cloning volume using Libvirt Python createXMLFrom causes End of file while reading data: Input/output error

I am trying to clone a volume using:
libvirt_conn = libvirt.openAuth(<qemu_addr>, <auth>, 0)
pool = libvirt_conn.storagePoolLookupByName(<pool_name>)
original_volume = pool.storageVolLookupByName(<original_volume_name>)
new_volume_xml = <xml_string>
new_volume = pool.createXMLFrom(new_volume_xml, original_volume)
When I run this I get the following error:
End of file while reading data: Input/output error
When I try:
libvirt_conn = libvirt.openAuth(<qemu_addr>, <auth>, 0)
pool = libvirt_conn.storagePoolLookupByName(<pool_name>)
original_volume = pool.storageVolLookupByName(<original_volume_name>)
new_volume_xml = <xml_string>
try:
new_volume = pool.createXMLFrom(new_volume_xml, original_volume)
except:
<next libvirt command>
I get a client socket is closed error. I have tried editing /etc/libvirt/libvirtd.conf with:
min_workers = 5
max_workers = 20
log_level = 1
log_filters="1:libvirt 1:util 1:qemu"
log_outputs="1:file:/var/log/libvirt/libvirtd.log"
keepalive_interval = -1
When I restart libvirtd and tail /var/log/libvirt/libvirtd.log I don't see anything useful. My feeling is the socket is closing because the cloning of the volume takes a longtime, but I am not sure how to keep the libvirt/qemu socket open longer. Is this possible?

How do I fix "sh: 1: title: not found" error in python3?

I want to make a twitch token generator for a discord bot, but when i run it, I get the error
sh: 1: title: not found
I think the part of the code that went wrong is
success = 0
fail = 0
created = 0
def count():
while True:
os.system(f'title S = {success}/ F = {fail} / C = {created}')
time.sleep(1)
full source code here
Does anybody have any ideas? Any help would be appreciated
os.system(f'title S = {success}/ F = {fail} / C = {created}')
Why are you trying to execute a string (which is what os.system() does) that you probably should just be printing out? Something like:
print(f'title S = {success}/ F = {fail} / C = {created}')
Your shell is unlikely to respond well to that.

Find USB serial port with Python script

I am trying to write a script in python so I can find in 1 sec the COM number of the USB serial adapter I have plugged to my laptop.
What I need is to isolate the COMx port so I can display the result and open putty with that specific port. Can you help me with that?
Until now I have already written a script in batch/powershell and I am getting this information but I havent been able to separate the text of the COMx port so I can call the putty program with the serial parameter.
I have also been able to find the port via Python but I cant isolate it from the string.
import re # Used for regular expressions (unused)
import os # To check that the path of the files defined in the config file exist (unused)
import sys # To leave the script if (unused)
import numpy as np
from infi.devicemanager import DeviceManager
dm = DeviceManager()
dm.root.rescan()
devs = dm.all_devices
print ('Size of Devs: ',len(devs))
print ('Type of Devs: ',type(devs))
myarray = ([])
myarray =np.array(devs)
print ('Type of thing: ',type(myarray))
match = '<USB Serial Port (COM6)>' (custom match. the ideal would be "USB Serial Port")
i=0
#print (myarray, '\n')
while i != len(devs):
if match == myarray[i]:
print ('Found it!')
break
print ('array: ',i," : ", myarray[i])
i = i+1
print ('array 49: ', myarray[49]) (here I was checking what is the difference of the "element" inside the array)
print ('match : ', match) (and what is the difference of what I submitted)
print ('end')
I was expecting the if match == myarray[i] to find the two elements but for some reason it doesnt. Its returning me that those two are not the same.
Thank you for any help in advance!
=== UPDATE ===
Full script can be found here
https://github.com/elessargr/k9-serial
this is a follow up answer from #MacrosG
i tried a minimal example with properties from Device
from infi.devicemanager import DeviceManager
dm = DeviceManager()
dm.root.rescan()
devs = dm.all_devices
print ('Size of Devs: ',len(devs))
for d in devs:
if "USB" in d.description :
print(d.description)
If Python says the strings are not the same I dare say it's quite likely they are not.
You can compare with:
if "USB Serial Port" in devs[i]:
Then you should be able to find not a complete letter by letter match but one that contains a USB port.
There is no need to use numpy, devs is already a list and hence iterable.
If you want to do this with regular-expressions:
def main():
from infi.devicemanager import DeviceManager
import re
device_manager = DeviceManager()
device_manager.root.rescan()
pattern = r"USB Serial Port \(COM(\d)\)"
for device in device_manager.all_devices:
try:
match = re.fullmatch(pattern, device.friendly_name)
except KeyError:
continue
if match is None:
continue
com_number = match.group(1)
print(f"Found device \"{device.friendly_name}\" -> com_number: {com_number}")
return 0
if __name__ == "__main__":
import sys
sys.exit(main())
Output:
Found device "USB Serial Port (COM3)" -> com_number: 3
Huge thanks to everyone and especially to bigdataolddriver since I went with his solution
Last thing!
for d in devs:
if "USB Serial Port" in d.description :
str = d.__str__()
COMport = str.split('(', 1)[1].split(')')[0]
i=1
break
else:
i=0
if i == 1:
print ("I found it!")
print(d.description, "found on : ", COMport)
subprocess.Popen(r'"C:\Tools\putty.exe" -serial ', COMport)
elif i ==0:
print ("USB Serial Not found \nPlease check physical connection.")
else:
print("Error")
Any ideas how to pass the COMport to the putty.exe as a parameter?
===== UPDATE =====
if i == 1:
print ("I found it!")
print(d.description, "found on : ", COMport)
command = '"C:\MyTools\putty.exe" -serial ' + COMport
#print (command)
subprocess.Popen(command)
Thank you everyone!

Python on Crontab does not execute bash script

import subprocess as sub
import re
import os
from datetime import datetime as influx_timestap
from influxdb import InfluxDBClient
from collections import OrderedDict
insert_json = []
hostname = str(sub.check_output('hostname')).strip()
location = str(sub.check_output(['ps -ef | grep mgr'], shell=True)).split()
current_dir = os.getcwd()
print("script executed")
gg_location_pattern = re.compile(r'mgr\.prm$')
gg_process_pattertn = re.compile(r'^REPLICAT|^EXTRACT')
for index in location:
if gg_location_pattern.search(index) != None:
gg_location = index[:-14]
os.chdir(gg_location)
print("checkpoint1")
get_lag = sub.check_output(str(current_dir) + '/ggsci_test.sh', shell=True)
print("checkpoint2")
processes = get_lag.split("\n")
for process in processes:
if gg_process_pattertn.search(process) != None:
lag_at_chkpnt = int((process.split()[3]).split(":")[0]) * 3600 + int((process.split()[3]).split(":")[1]) *60 + int((process.split()[3]).split(":")[2])
time_since_chkpnt = int((process.split()[4]).split(":")[0]) * 3600 + int((process.split()[4]).split(":")[1]) *60 + int((process.split()[4]).split(":")[2]
)
process_dict = OrderedDict({"measurement": "GoldenGate_Mon_" + str(hostname) + "_Graph",
"tags": {"hostname": hostname, "process_name": process.split()[2]},
"time": influx_timestap.now().isoformat('T'),
"fields": {"process_type": process.split()[0], "process_status": process.split()[1],
"lag_at_chkpnt": lag_at_chkpnt, "time_since_chkpnt": time_since_chkpnt}})
insert_json.append(process_dict)
host = 'xxxxxxxx'
port = 'x'
user = 'x'
password = 'x'
dbname = 'x'
print("before client")
client = InfluxDBClient(host, port, user, password, dbname)
client.write_points(insert_json)
print("after client")
This code works manually perfect, but on the crontab it is not working. After searching on the internet I found that they say change or set your "PATH" variable on the crontab. I changed my "PATH" variable and it is still not working.
Crontab log file write "checkpoint1" after that there is nothing. So, line not working is "get_lag = sub.check_output(str(current_dir) + '/ggsci_test.sh', shell=True)"
What can I do here afterwards?
Take care,
it looks like your external script (ggsci_test.sh) has some issues with the paths / general failure.
From the Python subprocess documentation about subprocess.check_output:
If the return code was non-zero it raises a CalledProcessError. The
CalledProcessError object will have the return code in the returncode
attribute and any output in the output attribute.
So thats the reason why you see the error when catching it, but not being able to continue.
You should check therefore if your shell script has any issues that need to be solved before.

Get Windows Process/File Description in Python

I have the following code so far that tells me every time a new process is created.
import wmi
c = wmi.WMI()
process_watcher = c.Win32_Process.watch_for("creation")
while True:
new_process = process_watcher()
print(new_process.Caption)
print(new_process.ExecutablePath)
This works fine, but what I'm really trying to do is get at the Processes Description because while the filename of what I'm looking for might change, the description does not. I can't find anything in Win32_Process or win32file that gets me the file description though. Does anybody know how to do this?
Thanks!
while True:
try:
new_process = process_watcher()
proc_owner = new_process.GetOwner()
proc_owner = "%s\\%s" % (proc_owner[0],proc_owner[2])
create_date = new_process.CreationDate
executable = new_process.ExecutablePath
cmdline = new_process.CommandLine
pid = new_process.ProcessId
parent_pid = new_process.parentProcessId
privileges = "N/A"
process_log_message = "%s,%s,%s,%s,%s,%s,%s,\r\n" % (create_date,proc_owner,executable,cmdline,pid,parent_pid,privileges)
print "1"
print process_log_message
log_to_file(process_log_message)
except:
print "2"
pass
Hope this helps :)

Categories

Resources