Can't execute external script from zabbix - python

I'm trying to execute script from zabbix ui. I put my script to '/usr/lib/zabbix/externalscripts' folder. The script's name is "check_ssl.py". When I connect to server and go to that folder and execute the script manually - it works, but when I try to execute it from zabbix's ui - it throws an error :
"Traceback (most recent call last):
File "/usr/lib/zabbix/externalscripts/check_ssl.py", line 14, in <module>
ACCESS_KEY = conf('ACCESS_KEY')
File "/usr/local/lib/python3.8/dist-packages/decouple.py", line 243, in __call__
return self.config(*args, **kwargs)
File "/usr/local/lib/python3.8/dist-packages/decouple.py", line 105, in __call__
return self.get(*args, **kwargs)
File "/usr/local/lib/python3.8/dist-packages/decouple.py", line 90, in get
raise UndefinedValueError('{} not found. Declare it as envvar or define a default value.'.format(option))
decouple.UndefinedValueError: ACCESS_KEY not found. Declare it as envvar or define a default value."
ACCESS_KEY variable is declared and set as env. variable. Does anyone know why it throws this error?

The service environment is different from other users' env, see https://serverfault.com/questions/413397/how-to-set-environment-variable-in-systemd-service
Edit the service with systemctl edit zabbix-server and add Environment="ACCESS_KEY=your_access_key" in the [Service] section.

Create the script with Scope: Action Operation, Type: Script, Execute on: Zabbix agent (i've done it like that and works fine)
On commands insert the command, example python3 /home/suppor/python_scripts/customer/restart_apache.py
On Actions create one, select the condition (may be the trigger when to run the script), on Operation tab add the operation to run the script created
It works fine. You must allow remote commands on the zabbix agent

Related

Backslash Problem when Running Script for Windows Scheduler (via a batch file)

So, up until about a year ago I had several scripts that I ran via Windows Task Scheduler then all of a sudden I started getting 0x1 "errors".
Fast forward to present and I decided to try to figure out what was going on (because I really need some stuff to run when I am away). I have one python script that imports several others to run. Based on numerous other posts about problems with Task Scheduler,: I decided to use a .bat file
SET logfile="C:\Reports\batch.log"
#echo off
#echo Starting Script at %date% %time% >> %logfile%
call C:\Users\Me\Anaconda3\condabin\conda.bat activate C:\Users\Me\Anaconda3
C:\Users\Me\Anaconda3\python.exe C:\Users\Me\RUN_daily_notifications.py
pause
#echo finished at %date% %time% >> %logfile%
In many of the scripts that are executed are paths to different files here and there and the command line execution crashes at the first one (so I would assume I would need to fix them all). For example, in the first script I am setting up an Excel file:
writer = pd.ExcelWriter(r'P:\1MatData\Query Output\Hold Report.xlsx')
I run this via the Task Scheduler, the command line opens up and gives me this error:
C:\WINDOWS\system32>SET logfile="C:\Reports\batch.log"
Running Eng_Que
Traceback (most recent call last):
File "C:\Users\Me\RUN_daily_notifications.py", line 13, in <module>
import Eng_Que #G8
File "C:\Users\Me\Eng_Que.py", line 140, in <module>
writer = pd.ExcelWriter(r'P:\1MatData\Query Output\Hold Report.xlsx')
File "C:\Users\Me\Anaconda3\lib\site-packages\pandas\io\excel\_xlsxwriter.py", line 182, in __init__
super().__init__(
File "C:\Users\Me\Anaconda3\lib\site-packages\pandas\io\excel\_base.py", line 810, in __init__
self.handles = get_handle(
File "C:\Users\Me\Anaconda3\lib\site-packages\pandas\io\common.py", line 651, in get_handle
handle = open(handle, ioargs.mode)
FileNotFoundError: [Errno 2] No such file or directory: 'P:\\1MatData\\Query Output\\Hold Report.xlsx'
I've tried rewriting the line with the path in the script numerous ways, but never can seen to get a single backslash to pass.
For example (changes to the script and command line error):
writer = pd.ExcelWriter('P:\\1MatData\\Query Output\\Hold Report.xlsx')
still passes double backslashes:
FileNotFoundError: [Errno 2] No such file or directory: 'P:\\1MatData\\Query Output\\Hold Report.xlsx'
This:
writer = pd.ExcelWriter('P:\1MatData\Query Output\Hold Report.xlsx')
Gives:
FileNotFoundError: [Errno 2] No such file or directory: 'P:\x01MatData\\Query Output\\Hold Report.xlsx'
All of these (except for the last one of course) work fine in my terminal (Sy
pder).
I've also tried os.path.normpath and .realpath and still can't get single backslashes. Any advice, wisdom or suggestions would be greatly appreciated.
Edit to provide additional info requested:
The P: drive is a network drive that I have read/write access to.
Task properties:
General--
Selected Run only when user is logged on and have Run with highest privileges checked.
Actions--
Program/script: C:\Users\Me\Desktop\BatchFiles\daily_reports.bat
Add arguments: blank
Start in: blank
Settings--
Allow task to be run on demand -- checked
Stop the task if it runs longer than: 3 days
If the running task does not end when requested force it to stop -- checked.

Paramiko failing due due to file permissions

I have been trying to automate SFTP transfer from a Windows client via a python script to a CentOS machine running an Apache server. I have created a user account on the CentOS server that can only access SFTP, similar to the instructions listed here: https://www.digitalocean.com/community/tutorials/how-to-enable-sftp-without-shell-access-on-centos-7
I then used the following code in an attempt to transfer the file
transport.connect(username = username, password = password)
sftp = paramiko.SFTPClient.from_transport(transport)
sftp.put(base_dir + '\\report', '/var/www/html/reports/' + host_name, confirm = False)
However this results in the following error:
Traceback (most recent call last):
File "noschedule_make_report.py", line 74, in <module>
main()
File "noschedule_make_report.py", line 62, in main
sftp.chdir('/var/www/html/reports')
File "C:\Python27\lib\site-packages\paramiko\sftp_client.py", line 626, in chdir
if not stat.S_ISDIR(self.stat(path).st_mode):
File "C:\Python27\lib\site-packages\paramiko\sftp_client.py", line 460, in stat
t, msg = self._request(CMD_STAT, path)
File "C:\Python27\lib\site-packages\paramiko\sftp_client.py", line 780, in _request
return self._read_response(num)
File "C:\Python27\lib\site-packages\paramiko\sftp_client.py", line 832, in _read_response
self._convert_status(msg)
File "C:\Python27\lib\site-packages\paramiko\sftp_client.py", line 861, in _convert_status
raise IOError(errno.ENOENT, text)
IOError: [Errno 2] No such file
This code worked when I didn't set the restrictions on the upload user account as described in the Digital Ocean post, and instead had much more liberal permissions and shell login. Is there a way for me to have both the locked out login for the upload user and to use the Paramiko funcitonality?
Please note that using a sftp.chdir('/var/www/html/reports') command before the put command produced the same error, occurring at the chdir line instead.
Also I understand that similar questions have been asked (IOError: [Errno 2] No such file - Paramiko put()), but I am specifically asking if I can relegate these two sets of functionality.
There is a concept I think you have perhaps overlooked when configuring the sftp part, This is ChrootDirectory.
A Chroot in Unix world is a way to execute a command or an environment inside a system directory, so this directory appears the root of the system you're into. This is primary used as security feature because there is no way to escape this chroot. For instance imagine you have a path /opt/server/ftp/users/ and a ftp daemon is chrooted in /opt/server/ftp/ a client will see the users directory when he will do a ls -al and it will be impossible to access files on the system like /etc/
So this problem has nothing to do with the Paramiko code per-se but with the sftp configuration you set and the comprehension of what is a Chroot environment.
ChrootDirectory in you setup define the sftp user will be dropped into this directory when connection it created AND that he'll be impossible to see the full path of the system when it is logged, so when you upload the files you don't have to chdir /var/www/html/reports because you can't see this directory. Considering you set ChrootDirectory /var/www/html/reports
Check first the ChrootDirectory value you set, if you put /var/sftp/ but you want to access the system path (not the chroot one) /var/www/html/reports/ this is wrong. Correct to /var/www/html/reports/ seems legit, then change your code to
sftp.put(base_dir + '\\report', '.' + host_name, confirm = False)
the character . as second parameter means the current directory

Salt's mine.get command works on CLI but not in a jinja template

I'm using SaltStack, and have pillar files for minions that match on grains.
When I run a mine.get command on a minions CLI, it works fine:
salt-call mine.get 'role:production-server' network.ip_addrs grain
Returns a list of hosts and their IPs.
However, using the same command in a jinja template on the same minion results in an error:
{% for host, ip in salt['mine.get']('role:production-server', 'network.ip_addrs', expr_form='grain').items() %}
local:
Data failed to compile:
----------
Pillar failed to render with the following messages:
----------
Rendering SLS 'role_settings.staging-server' failed, render error:
Jinja error: 'master_uri'
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/salt/utils/templates.py", line 265, in render_jinja_tmpl
output = template.render(**unicode_context)
File "/usr/lib/python2.7/dist-packages/jinja2/environment.py", line 894, in render
return self.environment.handle_exception(exc_info, True)
File "<template>", line 25, in top-level template code
File "/usr/lib/python2.7/dist-packages/salt/modules/mine.py", line 182, in get
auth = _auth()
File "/usr/lib/python2.7/dist-packages/salt/modules/mine.py", line 24, in _auth
__context__['auth'] = salt.crypt.SAuth(__opts__)
File "/usr/lib/python2.7/dist-packages/salt/crypt.py", line 498, in __init__
self.crypticle = self.__authenticate()
File "/usr/lib/python2.7/dist-packages/salt/crypt.py", line 510, in __authenticate
self.opts.get('_safe_auth', True)
File "/usr/lib/python2.7/dist-packages/salt/crypt.py", line 341, in sign_in
if self.opts['master_ip'] not in self.opts['master_uri']:
KeyError: 'master_uri'
I'm at a loss to what is causing this, as it works fine from the command line, which seems to rule out problems communication with the salt master etc.
I know this is an old post but ...
You appear to be calling a custom Python module to access the mine within your pillar files.This is fine in the context of formulas but does not work with pillar data by default as the custom modules are on the minion yet the pillar data is compiled on the master.To allow the master access to the minion modules, you will need to add something like this to your Salt master config:
module_dirs:
- /var/cache/salt/minion/extmods
Once you've added that, you will need to restart your Salt master:
sudo service salt-master restart
Note: I suspect the above setting will only work if you also have a Salt minion installed and configured on your Salt master with the custom module installed.For further information see the Salt docs here: https://docs.saltstack.com/en/latest/ref/configuration/master.html#module-dirs

ConfigParser Error when running python script from RoR app's controller

I am trying to trigger a python script from a controller.
I have defined the follwing function in the controller:
private
def update_product_count(skus, qty)
system "python2 /home/nish/stuff/repos/Untitled/voylla_staging_changes/app/models/ReviseItem.py
skus qty > output"
end
Calling this function in another method of the same controller:
def show
//some code
update_product_count(#skus, #qty)
end
When I run the script manually, from my console, it runs fine. But i get this error when run from the controller:
Traceback (most recent call last):
File "/home/nish/stuff/repos/Untitled/voylla_staging_changes/app/models/ReviseItem.py", line 24, in <module>
devID = config.get("Keys", "Developer")
File "/usr/lib/python2.7/ConfigParser.py", line 607, in get
raise NoSectionError(section)
ConfigParser.NoSectionError: No section: 'Keys'
The most likely cause is that you are opening the config file using a relative path, and the controller has a different current directory to your console.
You should either use an absolute path to the config file, or have the script work out the directory it is executing in, and prepend that to the file name.

stack dump in twisted app.py 'application' error when using twistd but works with python?

I am trying to use twisted but when i try to run some of the example code provided with the twisted package, it seems to always crash when i use "twistd" instead of "python"
for example, using the example code given with twisted,
if i run to command : twisted -ny echoserv.py
Unhandled Error
Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/twisted/application/app.py", line 652, in run
runApp(config)
File "/usr/lib/python2.7/site-packages/twisted/scripts/twistd.py", line 23, in runApp
_SomeApplicationRunner(config).run()
File "/usr/lib/python2.7/site-packages/twisted/application/app.py", line 386, in run
self.application = self.createOrGetApplication()
File "/usr/lib/python2.7/site-packages/twisted/application/app.py", line 451, in createOrGetApplication
application = getApplication(self.config, passphrase)
--- ---
File "/usr/lib/python2.7/site-packages/twisted/application/app.py", line 462, in getApplication
application = service.loadApplication(filename, style, passphrase)
File "/usr/lib/python2.7/site-packages/twisted/application/service.py", line 405, in loadApplication
application = sob.loadValueFromFile(filename, 'application', passphrase)
File "/usr/lib/python2.7/site-packages/twisted/persisted/sob.py", line 211, in loadValueFromFile
value = d[variable]
exceptions.KeyError: 'application'
Failed to load application: 'application'
Could not find 'application' in the file. To use 'twistd -y', your .tac
file must create a suitable object (e.g., by calling service.Application())
and store it in a variable named 'application'. twistd loads your .tac file
and scans the global variables for one of this name.
Please read the 'Using Application' HOWTO for details.
I was using Twisted version 11.0.0 but then i tried 12.0.0 but i have the same problem.
The version of python i am using is 2.7.2
Any ideas on what to do would be helpful. I have been trying to deal with this problem for a few days now. thanks!
twistd -y is meant to be used with a python file that contains a variable called application, there is none in this file, so it's not going to work.
You might want to spend some time reading twistd's documentation so you get a clearer idea of its role in the twisted ecosystem.
To use 'twistd -y', your .tac file must create a suitable object (e.g., by calling service.Application()) and store it in a variable named 'application'. twistd loads your .tac file and scans the global variables for one of this name.
Please read the 'Using Application' HOWTO for details.

Categories

Resources