Nagios check giving error and not the output I expect - python

I have a python code which when run locally gives correct output but when I run it with Nagios check locally it gives errors.
Code :
#!/usr/bin/env python
import pandas as pd
df = pd.read_csv("...")
print(df)
Nagios configuration :
inside localhost.cfg
define service {
use local-service
host_name localhost
service_description active edges
check_command. check_edges
}
inside commands.cfg
define command {
command_name check_edges
command_line $USER1$/check_edges.py $HOSTADDRESS$
}
Error :
(No output on stdout) stderr : Traceback File "/usr/local/nagios/libexec/check_edges.py" line 3, in <module> import pandas as pd
ImportError: No module named pandas
Please give as much details as possible to solve this problem
****pip show python gives :
Location: /usr/lib/python2.7/lib-dynload
pip show pandas gives :
Location : /home/nwvepops01/.local/lib/python2.7/site-packages****

As user, from the shell, check the istance of python.
For example with this command:
env python
Modify the script and on the first line replace this
#!/usr/bin/env python
with the absolute path of the python executable.

Related

Environment variable not visible in Python application started from pm2

I'm using a server for the first time. It has Ubuntu 18.04.
I've never worked with that OS, but after some guides I managed to get my code working, except for the environment variable.
In ~/.bashrc at the end of file I added export KEY="123asd".
Then I reloaded the terminal.
I checked if my environment variable is loaded via printenv KEY and it shows the correct value.
In my main.py there's:
import os
import telebot
API_KEY = os.getenv("KEY")
bot = telebot.TeleBot(API_KEY)
When I run it with pm2 start main.py --interpreter=python3 there's an error in logs:
raise Exception('Bot token is not defined')
Exception: Bot token is not defined
If I understand correctly it means that API_KEY is None so there's a problem with the environment variable.
I tried giving API_KEY an actual value, not an environment variable, and it worked fine.
So what else do I need to do to use an environment variable properly?
I was looking in the wrong place.
If I want to use pm2 then I need to create a ecosystem.config.js file and give it my variable. Like this:
module.exports = {
apps : [{
name: "main.py",
env: {
KEY: "123asd"
}
}]
}
It works, only I'm not sure if it's correct since there are more than 1 processes of my main.py (1 online, others are erorred)

Run Python app (script on PATH) from Java

I'm facing quite simple problem, yet still not able to figure out what in particular causes that, and - more importantly - how to solve it.
I'm currently on Linux, and I would like to run an python app (script) from a Java application. The script is on PATH, thus I really would like to utilise that (avoid using absolute path to the script), if possible.
However, all I tried resulted in various forms of "File does not exist".
Sample
As a demonstration, I've tried to run one python3-based app (meld)
and one binary-built app (ls) for comparison:
$ which ls
/usr/bin/ls
$ file /usr/bin/ls
/usr/bin/ls: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=[...], for GNU/Linux 3.2.0, stripped
$ which meld
/usr/bin/meld
$ file /usr/bin/meld
/usr/bin/meld: Python script, UTF-8 Unicode text executable
$ head -n1 /usr/bin/meld
#!/usr/bin/python3
Nextly, I've created simple Java main, which tries several ways how to start theese:
package cz.martlin.processes;
import java.io.File;
import java.io.IOException;
import java.lang.ProcessBuilder.Redirect;
import java.util.List;
import java.util.stream.Collectors;
public class ProcessPlaying {
public static void main(String[] args) {
List<List<String>> commands = List.of(
List.of("ls"),
List.of("/usr/bin/ls"),
List.of("meld"),
List.of("/usr/bin/meld"),
List.of("python3", "/usr/bin/meld"),
List.of("/usr/bin/python3", "/usr/bin/meld"),
List.of("sh", "-c", "meld"),
List.of("sh", "-c", "/usr/bin/meld"),
List.of("sh", "-c", "python3 /usr/bin/meld")
);
for (List<String> command : commands) {
run(command);
}
}
private static void run(List<String> command) {
System.out.println("Running: " + command);
//String executable = command.get(0);
//boolean exists = new File(executable).exists();
//System.out.println("Exists the " + executable + " ? " + exists);
try {
ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectError(Redirect.INHERIT);
Process proc = pb.start();
// Process proc = Runtime.getRuntime().exec(command.stream().collect(Collectors.joining(" ")));
int code = proc.waitFor();
System.out.println("OK, return code: " + code);
} catch (IOException e) {
System.out.println("Failed to start: " + e.toString());
} catch (InterruptedException e) {
System.out.println("Failed to await: " + e.toString());
}
System.out.println();
}
}
Here are the results:
Running: [ls]
OK, return code: 0
Running: [/usr/bin/ls]
OK, return code: 0
Running: [meld]
Failed to start: java.io.IOException: Cannot run program "meld": error=2, Directory or file doesn't exist
Running: [/usr/bin/meld]
Failed to start: java.io.IOException: Cannot run program "/usr/bin/meld": error=2, Directory or file doesn't exist
Running: [python3, /usr/bin/meld]
python3: can't open file '/usr/bin/meld': [Errno 2] No such file or directory
OK, return code: 2
Running: [/usr/bin/python3, /usr/bin/meld]
/usr/bin/python3: can't open file '/usr/bin/meld': [Errno 2] No such file or directory
OK, return code: 2
Running: [sh, -c, meld]
sh: line 1: meld: command not found
OK, return code: 127
Running: [sh, -c, /usr/bin/meld]
sh: line 1: /usr/bin/meld: Directory or file doesn't exist
OK, return code: 127
Running: [sh, -c, python3 /usr/bin/meld]
python3: can't open file '/usr/bin/meld': [Errno 2] No such file or directory
OK, return code: 2
To sum it up:
all of the commands tried works when executed directly from the shell (either sh or bash)
executing the binary works either by the full path (/usr/bin/ls) or by just the name (ls)
executing the python script the same way doesn't work neither way
when trying to run the python3 interpreter and populate the script path as an argument to the python, now the python yields the script file doesn't exist
trying to populate it as a command to the brand new shell didn't help either
I've tried to use the Runtime#exec (based on this comment: https://stackoverflow.com/a/36783743/3797793) to start the process (both the exec(String) and exec(String[] forms), but no sucess (none of the listed commands did actually execute).
Thus, my question is/are:
What do I understand wrong?
How to start the Python script from Java?
Would some small (ba)sh script wrapper do the job?
Since it's python3-based, Jython wouldn't help here (because the latest one is 2.7.*), would it?
Further requirements:
As mentioned, I would like to be able to avoid using full path to the Python script
Also, I would like to have platform independant solution (at least Linux and Windows compatible)
Thanks in advance

Python inputs from another python file

I have a python file(file1.py) where i have written a script. Now, my friend asked me to keep the inputs in another python file(file2.py) and import the file in file1.py so that its becomes easy to modify the inputs if we keep it seperate file. So i created file2.py, copied the inputs there and saved it. Then i wrote the following line in file1.py: from file2 import * but its throwing error:
TASK [Run the python script]
********************************************************************************************************************************************************************************************************************************* fatal: [automation_server]: FAILED! => {"changed": true, "msg":
"non-zero return code", "rc": 1, "stderr": "Shared connection to
10.242.174.192 closed.\r\n", "stderr_lines": ["Shared connection to 10.242.174.192 closed."], "stdout": "/etc/profile.d/lang.sh: line 19: warning: setlocale: LC_CTYPE: cannot change locale (UTF-8): No such
file or directory\r\nTraceback (most recent call last):\r\n File
\"/home/bgnanasekaran/.ansible/tmp/ansible-tmp-1591957555.760499-407
182191177023663/download_RI_build.py\", line 8, in \r\n
from file2 import
*\r\nModuleNotFoundError: No module named 'file2'\r\n", "stdout_lines": ["/etc/profile.d/lang.sh: line 19: warning: setlocale:
LC_CTYPE: cannot change locale (UTF-8): No such file or directory",
"Traceback (most recent call last):", " File
\"/home/bgnanasekaran/.ansible/tmp/ansible-tmp-1591957555.760499-407
182191177023663/download_RI_build.py\", line 8, in ", "
from file2 import *", "ModuleNotFoundError: No module named 'file2'"]}
Note: I'll give some example of inputs in file2.py -
name="Suresh"
college="VIT"
Also note: I wrote all these python scripts to make it run with ansible playbook. This script is a part of play in my ansible playbook.
Please help me do this. I want a python file where i can store my python script inputs and use the same file in python script. This is not so related to ansible but more related to python.
you need a configuration file this post might help you or you can create a class and all required variable as a class variable and import the class into your script.
import is for python files only.
If you want to read content of a file you need to open it.
with open('filename', 'r') as handler:
print(handler.readlines())
Is a minimal example
You could also try to use environment varibales, which is a much more common practice when dealing with deployment strategies
import os
VARIABLE = os.getenv('VARIBALE', 'default_value')
Then you run the script with:
VARIABLE=this ./pythonscript.py
Or export the variable into the environment in another way

Jinja not imported when executing script from another one

I have a web server with CGI script calling python scripts.
When i try to execute in a main file (test1.py) another script called via
os.system('/var/www/cgi-bin/readIRtemp.py '+arg1+' '+arg2+' '+arg3)
I get his error message in /var/log/apache2/error.log :
import: not found
from: can't read /var/mail/jinja2
this is understandable for me since when called directly from the python console my script works !
its content is:
import sys, os
from jinja2 import Environment, FileSystemLoader, select_autoescape
last20values=sys.argv[1]
currTempInDegreesCelcius=sys.argv[2]
print('test '+last20values+' '+currTempInDegreesCelcius)
env = Environment(
loader=FileSystemLoader('/var/www/html/templates'),
autoescape=select_autoescape(['html', 'xml'])
)
template = env.get_template('IR.html')
updatedTemplate=template.render( arrayOfTemp = last20values, currTemp=currTempInDegreesCelcius)
Html_file=open("/var/www/html/IR.html","w")
Html_file.write(updatedTemplate)
Html_file.close()
I read somewhere something like maybe when calling os.system() the script is running with a different user account or some crazy things like that ... please help!
of course i chmod 777 * everything but that doesnt help ...

ansible: local test new module with Error:Module unable to decode valid JSON on stdin. Unable to figure out what parameters were passed

I'm new to Python. This is my first Ansible module in order to delete the SimpleDB domain from ChaosMonkey deletion.
When tested in my local venv with my Mac OS X, it keeps saying
Module unable to decode valid JSON on stdin. Unable to figure out
what parameters were passed.
Here is the code:
#!/usr/bin/python
# Delete SimpleDB Domain
from ansible.module_utils.basic import *
import boto3
def delete_sdb_domain():
fields = dict(
sdb_domain_name=dict(required=True, type='str')
)
module = AnsibleModule(argument_spec=fields)
client = boto3.client('sdb')
response = client.delete_domain(DomainName='module.params['sdb_domain_name']')
module.exit_json(changed = False, meta = response)
def main():
delete_sdb_domain()
if __name__ == '__main__':
main()
And I'm trying to pass in parameters from this file: /tmp/args.json.
and run the following command to make the local test:
$ python ./delete_sdb_domain.py /tmp/args.json
please note I'm using venv test environment on my Mac.
If you find any syntax error in my module, please also point it out.
This is not how you should test your modules.
AnsibleModule expects to have specific JSON as stdin data.
So the closest thing you can try is:
python ./delete_sdb_domain.py < /tmp/args.json
But I bet you have your json file in wrong format (no ANSIBLE_MODULE_ARGS, etc.).
To debug your modules you can use test-module script from Ansible hacking pack:
./hacking/test-module -m delete_sdb_domain.py -a "sdb_domain_name=zzz"

Categories