FanaticalHelp / freebox-monitoring

Scripts to monitor Freebox with Zabbix (expose Freebox metrics by json)
BSD 3-Clause "New" or "Revised" License
3 stars 4 forks source link

Zabbix in a Truenas jail doesn't find the config.ini file. #5

Closed DiWa51 closed 2 years ago

DiWa51 commented 2 years ago

I've freshly installed the Zabbix plugin (v5.0.17) on Truenas 12.0-U6. I'd like to thanks the author for sharing this script to the zabbix community!

I had hard time to run freebox.py from Zabbix itself. So this is both an How To install Zabbix freebox-monitoring in a Truenas Plugin to make it work (for future generations) & an issue as it doesn't behave as I would expect it to (jump to the bottom TL;DR;).

Disclaimer: I'm totally new to Zabbix and a little bit more experienced with Truenas.

1st from root user in the zabbix jail, I installed python3, pip3 & required packages as explained in the README.md, placed the script fbx_monitor.py under /usr/local/etc/zabbix5/zabbix/externalscripts and renamed it to freebox.py

root@zabbix% cp fbx_monitor.py /usr/local/etc/zabbix5/zabbix/externalscripts/freebox.py
root@zabbix% chown zabbix:wheel /usr/local/etc/zabbix5/zabbix/externalscripts/freebox.py

Originally, with this Truenas plugin setup, the zabbix user running the server process doesn't have a home to save the .cache/fbx-Zabbox/config.ini

In the jail I changed the user to use a /home/zabbix home folder:

root@zabbix% mkdir -p /home/zabbix
root@zabbix% chown zabbix:wheel /home/zabbix
root@zabbix% pw user mod zabbix -d /home/zabbix

I enabled new application request on the Freebox webUI itself.

as zabbix user, I ran the script from the shell to authorize the app

root@zabbix% su zabbix
zabbix@zabbix% /usr/local/etc/zabbix5/zabbix/externalscripts/freebox.py authorize
you need to press YES on the box

File has finally been created on the filesystem

zabbix@zabbix% ls /home/zabbix/.cache/fbx-Zabbox/config.ini
/home/zabbix/.cache/fbx-Zabbox/config.ini

This is working in the shell and I have data from the freebox

zabbix@zabbix% freebox.py connection
{"type"= [...]}

Back to the Zabbix WebUI, things are still not yet working.

From the hosts list, I selected the freebox and then its items list. There, I opened the "Template Freebox: Freebox connection" entry. From this page I use the Test button at the bottom; Make sure to "get value from host" (1st tick box)

1st, for some unknown reasons, the script returns an unknown Python3 error (it is working in the shell!).

... env: python3: No such file or directory

I fixed it by changing the shebang in freebox.py header to hardcoded absolute path to python3

#!/usr/local/bin/python3

2nd, another error is thrown stating the app is not authorized (even though it was from the shell...) I worked it around by running the authorize step from the UI, using again the Test feature:

Finally the script is running, hooray, I have data from my Freebox into Zabbix.

Now comes the remaining issues:

Why does it need to create the .cache under / directly? Why doesn't it use the /home/zabbix/.cache folder? i.e. the user running the zabbix processes Why can't it use the env setup for python3 in the shebang? All in all it seems the zabbix user in the shell is not behaving as the zabbix user from the WebUI. WHY?

Thanks a lot for your lights

DiWa51 commented 2 years ago

An update on my issue. After further testing in Zabbix and Python, it turns out one of the lib used in the Python script doesn't return the right path AppDirs(appname="fbx-Zabbox", appauthor="Webcentric")

For some unknown reasons in Zabbix, app_dir.user_cache_dir refers to the wrong path, as it returns /.cache and not /home/zabbix/.cache

So in the class Settings I've added a workaround that'll keep only here given I'm not sure anybody else will face this issue:

@@ -1,10 +1,12 @@
-#!/usr/bin/env python3
+#!/usr/local/bin/python3

 """Get Foreebox metrics for monitoring"""

 import requests

+import getpass
 import logging
+import os
 from appdirs import AppDirs
 from os.path import exists, join as path_join
 from configparser import ConfigParser
@@ -271,7 +273,14 @@ class MonitoringAgent:
 class Settings:
     config = ConfigParser()
     app_dir = AppDirs(appname="fbx-Zabbox", appauthor="Webcentric")
-    file_path_cache = path_join(app_dir.user_cache_dir, "config.ini")
+    # 20220930: harcoding the path if it starts with /.cache
+    #            For some unknown reasons in Zabbixi, app_dir.user_cache_dir refers to the wrong path
+    #            as it returns /.cache and not /home/zabbix/.cache
+    app_user_cache_dir = app_dir.user_cache_dir
+    if app_user_cache_dir.startswith("/.cache"):
+        app_user_cache_dir = '/home/'+getpass.getuser()+'/'+app_user_cache_dir[1:]
+    file_path_cache = path_join(app_user_cache_dir, "config.ini")
+
     instances = []

     def __init__(self):
@@ -279,9 +288,9 @@ class Settings:
         self.config.read([self.file_path_cache])

     def save(self):
-        if not exists(self.app_dir.user_cache_dir):
+        if not exists(self.app_user_cache_dir):
             from os import makedirs
-            makedirs(self.app_dir.user_cache_dir)
+            makedirs(self.app_user_cache_dir)

         for i in self.instances:
             self.save_object(i)
@@ -335,7 +344,6 @@ if __name__ == "__main__":

     if args.action == "authorize":
         monitoring.authorize()
-
     else:
         try:
             import json

I hope this could help (at least me in the future...)