v1.6.1 Merge
v1.6.1 Merge
This commit is contained in:
commit
345ce141ec
14 changed files with 221 additions and 163 deletions
21
CHANGELOG.md
21
CHANGELOG.md
|
@ -1,5 +1,24 @@
|
||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## [v1.6.1](https://github.com/Boerderij/Varken/tree/v1.6.1) (2019-01-11)
|
||||||
|
[Full Changelog](https://github.com/Boerderij/Varken/compare/v1.6...v1.6.1)
|
||||||
|
|
||||||
|
**Implemented enhancements:**
|
||||||
|
|
||||||
|
- \[Feature Request\] Unifi Integration [\#79](https://github.com/Boerderij/Varken/issues/79)
|
||||||
|
|
||||||
|
**Fixed bugs:**
|
||||||
|
|
||||||
|
- \[BUG\] Unexpected keyword argument 'langCode' while creating OmbiMovieRequest structure [\#88](https://github.com/Boerderij/Varken/issues/88)
|
||||||
|
|
||||||
|
**Closed issues:**
|
||||||
|
|
||||||
|
- Remove Cisco ASA since Telegraf + SNMP can do the same [\#86](https://github.com/Boerderij/Varken/issues/86)
|
||||||
|
|
||||||
|
**Merged pull requests:**
|
||||||
|
|
||||||
|
- v1.6 Merge [\#90](https://github.com/Boerderij/Varken/pull/85) ([DirtyCajunRice](https://github.com/DirtyCajunRice))
|
||||||
|
|
||||||
## [v1.6](https://github.com/Boerderij/Varken/tree/v1.6) (2019-01-04)
|
## [v1.6](https://github.com/Boerderij/Varken/tree/v1.6) (2019-01-04)
|
||||||
[Full Changelog](https://github.com/Boerderij/Varken/compare/v1.5...v1.6)
|
[Full Changelog](https://github.com/Boerderij/Varken/compare/v1.5...v1.6)
|
||||||
|
|
||||||
|
@ -15,7 +34,7 @@
|
||||||
|
|
||||||
**Merged pull requests:**
|
**Merged pull requests:**
|
||||||
|
|
||||||
- v1.6 Merge [\#75](https://github.com/Boerderij/Varken/pull/85) ([DirtyCajunRice](https://github.com/DirtyCajunRice))
|
- v1.6 Merge [\#85](https://github.com/Boerderij/Varken/pull/85) ([DirtyCajunRice](https://github.com/DirtyCajunRice))
|
||||||
|
|
||||||
## [v1.5](https://github.com/Boerderij/Varken/tree/v1.5) (2018-12-30)
|
## [v1.5](https://github.com/Boerderij/Varken/tree/v1.5) (2018-12-30)
|
||||||
[Full Changelog](https://github.com/Boerderij/Varken/compare/v1.4...v1.5)
|
[Full Changelog](https://github.com/Boerderij/Varken/compare/v1.4...v1.5)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
FROM lsiobase/alpine.python3
|
FROM lsiobase/alpine.python3
|
||||||
|
|
||||||
LABEL maintainer="dirtycajunrice"
|
LABEL maintainers="dirtycajunrice,samwiseg0"
|
||||||
|
|
||||||
ENV DEBUG="False"
|
ENV DEBUG="False"
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
[](https://microbadger.com/images/boerderij/varken)
|
[](https://microbadger.com/images/boerderij/varken)
|
||||||
[](https://microbadger.com/images/boerderij/varken)
|
[](https://microbadger.com/images/boerderij/varken)
|
||||||
[](https://hub.docker.com/r/boerderij/varken/)
|
[](https://hub.docker.com/r/boerderij/varken/)
|
||||||
[](https://hub.docker.com/r/boerderij/varken/)
|
|
||||||
|
|
||||||
Dutch for PIG. PIG is an Acronym for Plex/InfluxDB/Grafana
|
Dutch for PIG. PIG is an Acronym for Plex/InfluxDB/Grafana
|
||||||
|
|
||||||
|
@ -30,7 +29,7 @@ Supported Modules:
|
||||||
* [Radarr](https://radarr.video/) - A fork of Sonarr to work with movies à la Couchpotato.
|
* [Radarr](https://radarr.video/) - A fork of Sonarr to work with movies à la Couchpotato.
|
||||||
* [Tautulli](https://tautulli.com/) - A Python based monitoring and tracking tool for Plex Media Server.
|
* [Tautulli](https://tautulli.com/) - A Python based monitoring and tracking tool for Plex Media Server.
|
||||||
* [Ombi](https://ombi.io/) - Want a Movie or TV Show on Plex or Emby? Use Ombi!
|
* [Ombi](https://ombi.io/) - Want a Movie or TV Show on Plex or Emby? Use Ombi!
|
||||||
* Cisco ASA
|
* [Unifi](https://unifi-sdn.ubnt.com/) - The Global Leader in Managed Wi-Fi Systems
|
||||||
|
|
||||||
Key features:
|
Key features:
|
||||||
* Multiple server support for all modules
|
* Multiple server support for all modules
|
||||||
|
|
71
Varken.py
71
Varken.py
|
@ -1,7 +1,7 @@
|
||||||
import platform
|
import platform
|
||||||
import schedule
|
import schedule
|
||||||
|
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
from queue import Queue
|
||||||
from sys import version
|
from sys import version
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from os import access, R_OK, getenv
|
from os import access, R_OK, getenv
|
||||||
|
@ -10,8 +10,9 @@ from os.path import isdir, abspath, dirname, join
|
||||||
from argparse import ArgumentParser, RawTextHelpFormatter
|
from argparse import ArgumentParser, RawTextHelpFormatter
|
||||||
from logging import getLogger, StreamHandler, Formatter, DEBUG
|
from logging import getLogger, StreamHandler, Formatter, DEBUG
|
||||||
|
|
||||||
|
from varken import structures # Needed to check version of python
|
||||||
from varken.ombi import OmbiAPI
|
from varken.ombi import OmbiAPI
|
||||||
from varken.cisco import CiscoAPI
|
from varken.unifi import UniFiAPI
|
||||||
from varken import VERSION, BRANCH
|
from varken import VERSION, BRANCH
|
||||||
from varken.sonarr import SonarrAPI
|
from varken.sonarr import SonarrAPI
|
||||||
from varken.radarr import RadarrAPI
|
from varken.radarr import RadarrAPI
|
||||||
|
@ -26,9 +27,14 @@ from varken.varkenlogger import VarkenLogger
|
||||||
PLATFORM_LINUX_DISTRO = ' '.join(x for x in linux_distribution() if x)
|
PLATFORM_LINUX_DISTRO = ' '.join(x for x in linux_distribution() if x)
|
||||||
|
|
||||||
|
|
||||||
def threaded(job):
|
def thread():
|
||||||
thread = Thread(target=job)
|
while schedule.jobs:
|
||||||
thread.start()
|
job = QUEUE.get()
|
||||||
|
a = job()
|
||||||
|
print(a)
|
||||||
|
if a is not None:
|
||||||
|
schedule.clear(a)
|
||||||
|
QUEUE.task_done()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -85,64 +91,81 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
CONFIG = INIParser(DATA_FOLDER)
|
CONFIG = INIParser(DATA_FOLDER)
|
||||||
DBMANAGER = DBManager(CONFIG.influx_server)
|
DBMANAGER = DBManager(CONFIG.influx_server)
|
||||||
|
QUEUE = Queue()
|
||||||
|
|
||||||
if CONFIG.sonarr_enabled:
|
if CONFIG.sonarr_enabled:
|
||||||
for server in CONFIG.sonarr_servers:
|
for server in CONFIG.sonarr_servers:
|
||||||
SONARR = SonarrAPI(server, DBMANAGER)
|
SONARR = SonarrAPI(server, DBMANAGER)
|
||||||
if server.queue:
|
if server.queue:
|
||||||
schedule.every(server.queue_run_seconds).seconds.do(threaded, SONARR.get_queue)
|
at_time = schedule.every(server.queue_run_seconds).seconds
|
||||||
|
at_time.do(QUEUE.put, SONARR.get_queue).tag(f"sonarr-{server.id}-get_queue")
|
||||||
if server.missing_days > 0:
|
if server.missing_days > 0:
|
||||||
schedule.every(server.missing_days_run_seconds).seconds.do(threaded, SONARR.get_missing)
|
at_time = schedule.every(server.missing_days_run_seconds).seconds
|
||||||
|
at_time.do(QUEUE.put, SONARR.get_missing).tag(f"sonarr-{server.id}-get_missing")
|
||||||
if server.future_days > 0:
|
if server.future_days > 0:
|
||||||
schedule.every(server.future_days_run_seconds).seconds.do(threaded, SONARR.get_future)
|
at_time = schedule.every(server.future_days_run_seconds).seconds
|
||||||
|
at_time.do(QUEUE.put, SONARR.get_future).tag(f"sonarr-{server.id}-get_future")
|
||||||
|
|
||||||
if CONFIG.tautulli_enabled:
|
if CONFIG.tautulli_enabled:
|
||||||
GEOIPHANDLER = GeoIPHandler(DATA_FOLDER)
|
GEOIPHANDLER = GeoIPHandler(DATA_FOLDER)
|
||||||
schedule.every(12).to(24).hours.do(threaded, GEOIPHANDLER.update)
|
schedule.every(12).to(24).hours.do(QUEUE.put, GEOIPHANDLER.update)
|
||||||
for server in CONFIG.tautulli_servers:
|
for server in CONFIG.tautulli_servers:
|
||||||
TAUTULLI = TautulliAPI(server, DBMANAGER, GEOIPHANDLER)
|
TAUTULLI = TautulliAPI(server, DBMANAGER, GEOIPHANDLER)
|
||||||
if server.get_activity:
|
if server.get_activity:
|
||||||
schedule.every(server.get_activity_run_seconds).seconds.do(threaded, TAUTULLI.get_activity)
|
at_time = schedule.every(server.get_activity_run_seconds).seconds
|
||||||
|
at_time.do(QUEUE.put, TAUTULLI.get_activity).tag(f"tautulli-{server.id}-get_activity")
|
||||||
if server.get_stats:
|
if server.get_stats:
|
||||||
schedule.every(server.get_stats_run_seconds).seconds.do(threaded, TAUTULLI.get_stats)
|
at_time = schedule.every(server.get_stats_run_seconds).seconds
|
||||||
|
at_time.do(QUEUE.put, TAUTULLI.get_stats).tag(f"tautulli-{server.id}-get_stats")
|
||||||
|
|
||||||
if CONFIG.radarr_enabled:
|
if CONFIG.radarr_enabled:
|
||||||
for server in CONFIG.radarr_servers:
|
for server in CONFIG.radarr_servers:
|
||||||
RADARR = RadarrAPI(server, DBMANAGER)
|
RADARR = RadarrAPI(server, DBMANAGER)
|
||||||
if server.get_missing:
|
if server.get_missing:
|
||||||
schedule.every(server.get_missing_run_seconds).seconds.do(threaded, RADARR.get_missing)
|
at_time = schedule.every(server.get_missing_run_seconds).seconds
|
||||||
|
at_time.do(QUEUE.put, RADARR.get_missing).tag(f"radarr-{server.id}-get_missing")
|
||||||
if server.queue:
|
if server.queue:
|
||||||
schedule.every(server.queue_run_seconds).seconds.do(threaded, RADARR.get_queue)
|
at_time = schedule.every(server.queue_run_seconds).seconds
|
||||||
|
at_time.do(QUEUE.put, RADARR.get_queue).tag(f"radarr-{server.id}-get_queue")
|
||||||
|
|
||||||
if CONFIG.ombi_enabled:
|
if CONFIG.ombi_enabled:
|
||||||
for server in CONFIG.ombi_servers:
|
for server in CONFIG.ombi_servers:
|
||||||
OMBI = OmbiAPI(server, DBMANAGER)
|
OMBI = OmbiAPI(server, DBMANAGER)
|
||||||
if server.request_type_counts:
|
if server.request_type_counts:
|
||||||
schedule.every(server.request_type_run_seconds).seconds.do(threaded, OMBI.get_request_counts)
|
at_time = schedule.every(server.request_type_run_seconds).seconds
|
||||||
|
at_time.do(QUEUE.put, OMBI.get_request_counts).tag(f"ombi-{server.id}-get_request_counts")
|
||||||
if server.request_total_counts:
|
if server.request_total_counts:
|
||||||
schedule.every(server.request_total_run_seconds).seconds.do(threaded, OMBI.get_all_requests)
|
at_time = schedule.every(server.request_total_run_seconds).seconds
|
||||||
|
at_time.do(QUEUE.put, OMBI.get_all_requests).tag(f"ombi-{server.id}-get_all_requests")
|
||||||
if server.issue_status_counts:
|
if server.issue_status_counts:
|
||||||
schedule.every(server.issue_status_run_seconds).seconds.do(threaded, OMBI.get_issue_counts)
|
at_time = schedule.every(server.issue_status_run_seconds).seconds
|
||||||
|
at_time.do(QUEUE.put, OMBI.get_issue_counts).tag(f"ombi-{server.id}-get_issue_counts")
|
||||||
|
|
||||||
if CONFIG.sickchill_enabled:
|
if CONFIG.sickchill_enabled:
|
||||||
for server in CONFIG.sickchill_servers:
|
for server in CONFIG.sickchill_servers:
|
||||||
SICKCHILL = SickChillAPI(server, DBMANAGER)
|
SICKCHILL = SickChillAPI(server, DBMANAGER)
|
||||||
if server.get_missing:
|
if server.get_missing:
|
||||||
schedule.every(server.get_missing_run_seconds).seconds.do(threaded, SICKCHILL.get_missing)
|
at_time = schedule.every(server.get_missing_run_seconds).seconds
|
||||||
|
at_time.do(QUEUE.put, SICKCHILL.get_missing).tag(f"sickchill-{server.id}-get_missing")
|
||||||
|
|
||||||
if CONFIG.ciscoasa_enabled:
|
if CONFIG.unifi_enabled:
|
||||||
for firewall in CONFIG.ciscoasa_servers:
|
for server in CONFIG.unifi_servers:
|
||||||
ASA = CiscoAPI(firewall, DBMANAGER)
|
UNIFI = UniFiAPI(server, DBMANAGER)
|
||||||
schedule.every(firewall.get_bandwidth_run_seconds).seconds.do(threaded, ASA.get_bandwidth)
|
at_time = schedule.every(server.get_usg_stats_run_seconds).seconds
|
||||||
|
at_time.do(QUEUE.put, UNIFI.get_usg_stats).tag(f"unifi-{server.id}-get_usg_stats")
|
||||||
|
|
||||||
# Run all on startup
|
# Run all on startup
|
||||||
SERVICES_ENABLED = [CONFIG.ombi_enabled, CONFIG.radarr_enabled, CONFIG.tautulli_enabled,
|
SERVICES_ENABLED = [CONFIG.ombi_enabled, CONFIG.radarr_enabled, CONFIG.tautulli_enabled, CONFIG.unifi_enabled,
|
||||||
CONFIG.sonarr_enabled, CONFIG.ciscoasa_enabled, CONFIG.sickchill_enabled]
|
CONFIG.sonarr_enabled, CONFIG.sickchill_enabled]
|
||||||
if not [enabled for enabled in SERVICES_ENABLED if enabled]:
|
if not [enabled for enabled in SERVICES_ENABLED if enabled]:
|
||||||
vl.logger.error("All services disabled. Exiting")
|
vl.logger.error("All services disabled. Exiting")
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
WORKER = Thread(target=thread)
|
||||||
|
WORKER.start()
|
||||||
|
|
||||||
schedule.run_all()
|
schedule.run_all()
|
||||||
|
|
||||||
while True:
|
while schedule.jobs:
|
||||||
schedule.run_pending()
|
schedule.run_pending()
|
||||||
sleep(1)
|
sleep(1)
|
||||||
|
|
|
@ -3,12 +3,14 @@ sonarr_server_ids = 1,2
|
||||||
radarr_server_ids = 1,2
|
radarr_server_ids = 1,2
|
||||||
tautulli_server_ids = 1
|
tautulli_server_ids = 1
|
||||||
ombi_server_ids = 1
|
ombi_server_ids = 1
|
||||||
ciscoasa_server_ids = false
|
|
||||||
sickchill_server_ids = false
|
sickchill_server_ids = false
|
||||||
|
unifi_server_ids = false
|
||||||
|
|
||||||
[influxdb]
|
[influxdb]
|
||||||
url = influxdb.domain.tld
|
url = influxdb.domain.tld
|
||||||
port = 8086
|
port = 8086
|
||||||
|
ssl = false
|
||||||
|
verify_ssl = false
|
||||||
username = root
|
username = root
|
||||||
password = root
|
password = root
|
||||||
|
|
||||||
|
@ -87,11 +89,12 @@ verify_ssl = false
|
||||||
get_missing = true
|
get_missing = true
|
||||||
get_missing_run_seconds = 300
|
get_missing_run_seconds = 300
|
||||||
|
|
||||||
[ciscoasa-1]
|
[unifi-1]
|
||||||
url = firewall.domain.tld
|
url = unifi.domain.tld:8443
|
||||||
username = cisco
|
username = ubnt
|
||||||
password = cisco
|
password = ubnt
|
||||||
outside_interface = WAN
|
site = default
|
||||||
|
usg_name = MyRouter
|
||||||
ssl = false
|
ssl = false
|
||||||
verify_ssl = false
|
verify_ssl = false
|
||||||
get_bandwidth_run_seconds = 300
|
get_usg_stats_run_seconds = 300
|
|
@ -40,6 +40,7 @@ services:
|
||||||
- GF_PATHS_DATA=/config/data
|
- GF_PATHS_DATA=/config/data
|
||||||
- GF_PATHS_LOGS=/config/logs
|
- GF_PATHS_LOGS=/config/logs
|
||||||
- GF_PATHS_PLUGINS=/config/plugins
|
- GF_PATHS_PLUGINS=/config/plugins
|
||||||
|
- GF_PATHS_CONFIG=/config/grafana.ini
|
||||||
- GF_INSTALL_PLUGINS=grafana-piechart-panel,grafana-worldmap-panel
|
- GF_INSTALL_PLUGINS=grafana-piechart-panel,grafana-worldmap-panel
|
||||||
depends_on:
|
depends_on:
|
||||||
- influxdb
|
- influxdb
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
VERSION = 1.7
|
VERSION = "1.6.1"
|
||||||
BRANCH = 'pre-nightly'
|
BRANCH = 'master'
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
from logging import getLogger
|
|
||||||
from requests import Session, Request
|
|
||||||
from datetime import datetime, timezone
|
|
||||||
|
|
||||||
from varken.helpers import connection_handler
|
|
||||||
|
|
||||||
|
|
||||||
class CiscoAPI(object):
|
|
||||||
def __init__(self, firewall, dbmanager):
|
|
||||||
self.now = datetime.now(timezone.utc).astimezone().isoformat()
|
|
||||||
self.dbmanager = dbmanager
|
|
||||||
self.firewall = firewall
|
|
||||||
# Create session to reduce server web thread load, and globally define pageSize for all requests
|
|
||||||
self.session = Session()
|
|
||||||
self.session.auth = (self.firewall.username, self.firewall.password)
|
|
||||||
self.logger = getLogger()
|
|
||||||
|
|
||||||
self.get_token()
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return f"<ciscoasa-{self.firewall.id}>"
|
|
||||||
|
|
||||||
def get_token(self):
|
|
||||||
endpoint = '/api/tokenservices'
|
|
||||||
|
|
||||||
req = self.session.prepare_request(Request('POST', self.firewall.url + endpoint))
|
|
||||||
post = connection_handler(self.session, req, self.firewall.verify_ssl)
|
|
||||||
|
|
||||||
if not post:
|
|
||||||
return
|
|
||||||
|
|
||||||
self.session.headers = {'X-Auth-Token': post}
|
|
||||||
|
|
||||||
def get_bandwidth(self):
|
|
||||||
self.now = datetime.now(timezone.utc).astimezone().isoformat()
|
|
||||||
endpoint = '/api/monitoring/device/interfaces/' + self.firewall.outside_interface
|
|
||||||
|
|
||||||
if not self.session.headers:
|
|
||||||
return
|
|
||||||
|
|
||||||
req = self.session.prepare_request(Request('GET', self.firewall.url + endpoint))
|
|
||||||
get = connection_handler(self.session, req, self.firewall.verify_ssl)
|
|
||||||
|
|
||||||
if not get:
|
|
||||||
return
|
|
||||||
|
|
||||||
influx_payload = [
|
|
||||||
{
|
|
||||||
"measurement": "Cisco ASA",
|
|
||||||
"tags": {
|
|
||||||
"interface": self.firewall.outside_interface
|
|
||||||
},
|
|
||||||
"time": self.now,
|
|
||||||
"fields": {
|
|
||||||
"upload_bitrate": get['outputBitRate'],
|
|
||||||
"download_bitrate": get['inputBitRate']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
self.dbmanager.write_points(influx_payload)
|
|
|
@ -5,8 +5,9 @@ from influxdb import InfluxDBClient
|
||||||
class DBManager(object):
|
class DBManager(object):
|
||||||
def __init__(self, server):
|
def __init__(self, server):
|
||||||
self.server = server
|
self.server = server
|
||||||
self.influx = InfluxDBClient(self.server.url, self.server.port, self.server.username, self.server.password,
|
self.influx = InfluxDBClient(host=self.server.url, port=self.server.port, username=self.server.username,
|
||||||
'varken')
|
password=self.server.password, ssl=self.server.ssl, database='varken',
|
||||||
|
verify_ssl=self.server.verify_ssl)
|
||||||
databases = [db['name'] for db in self.influx.get_list_database()]
|
databases = [db['name'] for db in self.influx.get_list_database()]
|
||||||
self.logger = getLogger()
|
self.logger = getLogger()
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
|
from ipaddress import IPv4Address
|
||||||
from calendar import monthcalendar
|
from calendar import monthcalendar
|
||||||
from geoip2.database import Reader
|
from geoip2.database import Reader
|
||||||
from tarfile import open as taropen
|
from tarfile import open as taropen
|
||||||
|
@ -11,7 +12,6 @@ from json.decoder import JSONDecodeError
|
||||||
from os.path import abspath, join, basename, isdir
|
from os.path import abspath, join, basename, isdir
|
||||||
from urllib3.exceptions import InsecureRequestWarning
|
from urllib3.exceptions import InsecureRequestWarning
|
||||||
from requests.exceptions import InvalidSchema, SSLError, ConnectionError
|
from requests.exceptions import InvalidSchema, SSLError, ConnectionError
|
||||||
from ipaddress import IPv4Address
|
|
||||||
|
|
||||||
logger = getLogger()
|
logger = getLogger()
|
||||||
|
|
||||||
|
@ -36,11 +36,11 @@ class GeoIPHandler(object):
|
||||||
today = date.today()
|
today = date.today()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
dbdate = date.fromtimestamp(stat(self.dbfile).st_ctime)
|
dbdate = date.fromtimestamp(stat(self.dbfile).st_mtime)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
self.logger.error("Could not find GeoLite2 DB as: %s", self.dbfile)
|
self.logger.error("Could not find GeoLite2 DB as: %s", self.dbfile)
|
||||||
self.download()
|
self.download()
|
||||||
dbdate = date.fromtimestamp(stat(self.dbfile).st_ctime)
|
dbdate = date.fromtimestamp(stat(self.dbfile).st_mtime)
|
||||||
|
|
||||||
first_wednesday_day = [week[2:3][0] for week in monthcalendar(today.year, today.month) if week[2:3][0] != 0][0]
|
first_wednesday_day = [week[2:3][0] for week in monthcalendar(today.year, today.month) if week[2:3][0] != 0][0]
|
||||||
first_wednesday_date = date(today.year, today.month, first_wednesday_day)
|
first_wednesday_date = date(today.year, today.month, first_wednesday_day)
|
||||||
|
@ -90,7 +90,8 @@ def rfc1918_ip_check(ip):
|
||||||
return rfc1918_ip
|
return rfc1918_ip
|
||||||
|
|
||||||
|
|
||||||
def connection_handler(session, request, verify):
|
def connection_handler(session, request, verify, as_is_reply=False):
|
||||||
|
air = as_is_reply
|
||||||
s = session
|
s = session
|
||||||
r = request
|
r = request
|
||||||
v = verify
|
v = verify
|
||||||
|
@ -109,11 +110,9 @@ def connection_handler(session, request, verify):
|
||||||
return_json = get.json()
|
return_json = get.json()
|
||||||
except JSONDecodeError:
|
except JSONDecodeError:
|
||||||
logger.error('No JSON response. Response is: %s', get.text)
|
logger.error('No JSON response. Response is: %s', get.text)
|
||||||
# 204 No Content is for ASA only
|
|
||||||
elif get.status_code == 204:
|
|
||||||
if get.headers['X-Auth-Token']:
|
|
||||||
return get.headers['X-Auth-Token']
|
|
||||||
|
|
||||||
|
if air:
|
||||||
|
return get
|
||||||
except InvalidSchema:
|
except InvalidSchema:
|
||||||
logger.error("You added http(s):// in the config file. Don't do that.")
|
logger.error("You added http(s):// in the config file. Don't do that.")
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,10 @@ from os.path import join, exists
|
||||||
from re import match, compile, IGNORECASE
|
from re import match, compile, IGNORECASE
|
||||||
from configparser import ConfigParser, NoOptionError, NoSectionError
|
from configparser import ConfigParser, NoOptionError, NoSectionError
|
||||||
|
|
||||||
from varken.helpers import clean_sid_check, rfc1918_ip_check
|
|
||||||
from varken.structures import SickChillServer
|
|
||||||
from varken.varkenlogger import BlacklistFilter
|
from varken.varkenlogger import BlacklistFilter
|
||||||
from varken.structures import SonarrServer, RadarrServer, OmbiServer, TautulliServer, InfluxServer, CiscoASAFirewall
|
from varken.structures import SickChillServer, UniFiServer
|
||||||
|
from varken.helpers import clean_sid_check, rfc1918_ip_check
|
||||||
|
from varken.structures import SonarrServer, RadarrServer, OmbiServer, TautulliServer, InfluxServer
|
||||||
|
|
||||||
|
|
||||||
class INIParser(object):
|
class INIParser(object):
|
||||||
|
@ -15,7 +15,7 @@ class INIParser(object):
|
||||||
self.config = None
|
self.config = None
|
||||||
self.data_folder = data_folder
|
self.data_folder = data_folder
|
||||||
self.filtered_strings = None
|
self.filtered_strings = None
|
||||||
self.services = ['sonarr', 'radarr', 'ombi', 'tautulli', 'sickchill', 'ciscoasa']
|
self.services = ['sonarr', 'radarr', 'ombi', 'tautulli', 'sickchill', 'unifi']
|
||||||
|
|
||||||
self.logger = getLogger()
|
self.logger = getLogger()
|
||||||
self.influx_server = InfluxServer()
|
self.influx_server = InfluxServer()
|
||||||
|
@ -141,13 +141,15 @@ class INIParser(object):
|
||||||
self.config_blacklist()
|
self.config_blacklist()
|
||||||
# Parse InfluxDB options
|
# Parse InfluxDB options
|
||||||
url = self.url_check(self.config.get('influxdb', 'url'), include_port=False, section='influxdb')
|
url = self.url_check(self.config.get('influxdb', 'url'), include_port=False, section='influxdb')
|
||||||
|
|
||||||
port = self.config.getint('influxdb', 'port')
|
port = self.config.getint('influxdb', 'port')
|
||||||
|
ssl = self.config.getboolean('influxdb', 'ssl')
|
||||||
|
verify_ssl = self.config.getboolean('influxdb', 'verify_ssl')
|
||||||
|
|
||||||
username = self.config.get('influxdb', 'username')
|
username = self.config.get('influxdb', 'username')
|
||||||
|
|
||||||
password = self.config.get('influxdb', 'password')
|
password = self.config.get('influxdb', 'password')
|
||||||
self.influx_server = InfluxServer(url=url, port=port, username=username, password=password)
|
|
||||||
|
self.influx_server = InfluxServer(url=url, port=port, username=username, password=password, ssl=ssl,
|
||||||
|
verify_ssl=verify_ssl)
|
||||||
|
|
||||||
# Check for all enabled services
|
# Check for all enabled services
|
||||||
for service in self.services:
|
for service in self.services:
|
||||||
|
@ -167,29 +169,26 @@ class INIParser(object):
|
||||||
url = self.url_check(self.config.get(section, 'url'), section=section)
|
url = self.url_check(self.config.get(section, 'url'), section=section)
|
||||||
|
|
||||||
apikey = None
|
apikey = None
|
||||||
if service != 'ciscoasa':
|
if service not in ['ciscoasa', 'unifi']:
|
||||||
apikey = self.config.get(section, 'apikey')
|
apikey = self.config.get(section, 'apikey')
|
||||||
|
|
||||||
scheme = 'https://' if self.config.getboolean(section, 'ssl') else 'http://'
|
scheme = 'https://' if self.config.getboolean(section, 'ssl') else 'http://'
|
||||||
|
|
||||||
verify_ssl = self.config.getboolean(section, 'verify_ssl')
|
verify_ssl = self.config.getboolean(section, 'verify_ssl')
|
||||||
|
|
||||||
if scheme != 'https://':
|
if scheme != 'https://':
|
||||||
verify_ssl = False
|
verify_ssl = False
|
||||||
|
|
||||||
if service == 'sonarr':
|
if service in ['sonarr', 'radarr']:
|
||||||
queue = self.config.getboolean(section, 'queue')
|
queue = self.config.getboolean(section, 'queue')
|
||||||
|
queue_run_seconds = self.config.getint(section, 'queue_run_seconds')
|
||||||
|
|
||||||
|
if service == 'sonarr':
|
||||||
missing_days = self.config.getint(section, 'missing_days')
|
missing_days = self.config.getint(section, 'missing_days')
|
||||||
|
|
||||||
future_days = self.config.getint(section, 'future_days')
|
future_days = self.config.getint(section, 'future_days')
|
||||||
|
|
||||||
missing_days_run_seconds = self.config.getint(section, 'missing_days_run_seconds')
|
missing_days_run_seconds = self.config.getint(section, 'missing_days_run_seconds')
|
||||||
|
|
||||||
future_days_run_seconds = self.config.getint(section, 'future_days_run_seconds')
|
future_days_run_seconds = self.config.getint(section, 'future_days_run_seconds')
|
||||||
|
|
||||||
queue_run_seconds = self.config.getint(section, 'queue_run_seconds')
|
|
||||||
|
|
||||||
server = SonarrServer(id=server_id, url=scheme + url, api_key=apikey, verify_ssl=verify_ssl,
|
server = SonarrServer(id=server_id, url=scheme + url, api_key=apikey, verify_ssl=verify_ssl,
|
||||||
missing_days=missing_days, future_days=future_days,
|
missing_days=missing_days, future_days=future_days,
|
||||||
missing_days_run_seconds=missing_days_run_seconds,
|
missing_days_run_seconds=missing_days_run_seconds,
|
||||||
|
@ -197,12 +196,7 @@ class INIParser(object):
|
||||||
queue=queue, queue_run_seconds=queue_run_seconds)
|
queue=queue, queue_run_seconds=queue_run_seconds)
|
||||||
|
|
||||||
if service == 'radarr':
|
if service == 'radarr':
|
||||||
queue = self.config.getboolean(section, 'queue')
|
|
||||||
|
|
||||||
queue_run_seconds = self.config.getint(section, 'queue_run_seconds')
|
|
||||||
|
|
||||||
get_missing = self.config.getboolean(section, 'get_missing')
|
get_missing = self.config.getboolean(section, 'get_missing')
|
||||||
|
|
||||||
get_missing_run_seconds = self.config.getint(section, 'get_missing_run_seconds')
|
get_missing_run_seconds = self.config.getint(section, 'get_missing_run_seconds')
|
||||||
|
|
||||||
server = RadarrServer(id=server_id, url=scheme + url, api_key=apikey, verify_ssl=verify_ssl,
|
server = RadarrServer(id=server_id, url=scheme + url, api_key=apikey, verify_ssl=verify_ssl,
|
||||||
|
@ -212,18 +206,17 @@ class INIParser(object):
|
||||||
if service == 'tautulli':
|
if service == 'tautulli':
|
||||||
fallback_ip = self.config.get(section, 'fallback_ip')
|
fallback_ip = self.config.get(section, 'fallback_ip')
|
||||||
|
|
||||||
|
get_stats = self.config.getboolean(section, 'get_stats')
|
||||||
get_activity = self.config.getboolean(section, 'get_activity')
|
get_activity = self.config.getboolean(section, 'get_activity')
|
||||||
|
|
||||||
get_activity_run_seconds = self.config.getint(section, 'get_activity_run_seconds')
|
get_activity_run_seconds = self.config.getint(section, 'get_activity_run_seconds')
|
||||||
|
|
||||||
get_stats = self.config.getboolean(section, 'get_stats')
|
|
||||||
|
|
||||||
get_stats_run_seconds = self.config.getint(section, 'get_stats_run_seconds')
|
get_stats_run_seconds = self.config.getint(section, 'get_stats_run_seconds')
|
||||||
|
|
||||||
invalid_wan_ip = rfc1918_ip_check(fallback_ip)
|
invalid_wan_ip = rfc1918_ip_check(fallback_ip)
|
||||||
|
|
||||||
if invalid_wan_ip:
|
if invalid_wan_ip:
|
||||||
self.logger.error('Invalid failback_ip [%s] set for %s-%s!', fallback_ip, service, server_id)
|
self.logger.error('Invalid fallback_ip [%s] set for %s-%s!', fallback_ip, service,
|
||||||
|
server_id)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
server = TautulliServer(id=server_id, url=scheme + url, api_key=apikey,
|
server = TautulliServer(id=server_id, url=scheme + url, api_key=apikey,
|
||||||
|
@ -233,17 +226,13 @@ class INIParser(object):
|
||||||
get_stats_run_seconds=get_stats_run_seconds)
|
get_stats_run_seconds=get_stats_run_seconds)
|
||||||
|
|
||||||
if service == 'ombi':
|
if service == 'ombi':
|
||||||
|
issue_status_counts = self.config.getboolean(section, 'get_issue_status_counts')
|
||||||
request_type_counts = self.config.getboolean(section, 'get_request_type_counts')
|
request_type_counts = self.config.getboolean(section, 'get_request_type_counts')
|
||||||
|
|
||||||
request_type_run_seconds = self.config.getint(section, 'request_type_run_seconds')
|
|
||||||
|
|
||||||
request_total_counts = self.config.getboolean(section, 'get_request_total_counts')
|
request_total_counts = self.config.getboolean(section, 'get_request_total_counts')
|
||||||
|
|
||||||
request_total_run_seconds = self.config.getint(section, 'request_total_run_seconds')
|
|
||||||
|
|
||||||
issue_status_counts = self.config.getboolean(section, 'get_issue_status_counts')
|
|
||||||
|
|
||||||
issue_status_run_seconds = self.config.getint(section, 'issue_status_run_seconds')
|
issue_status_run_seconds = self.config.getint(section, 'issue_status_run_seconds')
|
||||||
|
request_type_run_seconds = self.config.getint(section, 'request_type_run_seconds')
|
||||||
|
request_total_run_seconds = self.config.getint(section, 'request_total_run_seconds')
|
||||||
|
|
||||||
server = OmbiServer(id=server_id, url=scheme + url, api_key=apikey, verify_ssl=verify_ssl,
|
server = OmbiServer(id=server_id, url=scheme + url, api_key=apikey, verify_ssl=verify_ssl,
|
||||||
request_type_counts=request_type_counts,
|
request_type_counts=request_type_counts,
|
||||||
|
@ -255,29 +244,24 @@ class INIParser(object):
|
||||||
|
|
||||||
if service == 'sickchill':
|
if service == 'sickchill':
|
||||||
get_missing = self.config.getboolean(section, 'get_missing')
|
get_missing = self.config.getboolean(section, 'get_missing')
|
||||||
|
|
||||||
get_missing_run_seconds = self.config.getint(section, 'get_missing_run_seconds')
|
get_missing_run_seconds = self.config.getint(section, 'get_missing_run_seconds')
|
||||||
|
|
||||||
server = SickChillServer(id=server_id, url=scheme + url, api_key=apikey,
|
server = SickChillServer(id=server_id, url=scheme + url, api_key=apikey,
|
||||||
verify_ssl=verify_ssl, get_missing=get_missing,
|
verify_ssl=verify_ssl, get_missing=get_missing,
|
||||||
get_missing_run_seconds=get_missing_run_seconds)
|
get_missing_run_seconds=get_missing_run_seconds)
|
||||||
|
|
||||||
if service == 'ciscoasa':
|
if service == 'unifi':
|
||||||
username = self.config.get(section, 'username')
|
username = self.config.get(section, 'username')
|
||||||
|
|
||||||
password = self.config.get(section, 'password')
|
password = self.config.get(section, 'password')
|
||||||
|
site = self.config.get(section, 'site').lower()
|
||||||
|
usg_name = self.config.get(section, 'usg_name')
|
||||||
|
get_usg_stats_run_seconds = self.config.getint(section, 'get_usg_stats_run_seconds')
|
||||||
|
|
||||||
outside_interface = self.config.get(section, 'outside_interface')
|
server = UniFiServer(id=server_id, url=scheme + url, verify_ssl=verify_ssl, site=site,
|
||||||
|
username=username, password=password, usg_name=usg_name,
|
||||||
get_bandwidth_run_seconds = self.config.getint(section, 'get_bandwidth_run_seconds')
|
get_usg_stats_run_seconds=get_usg_stats_run_seconds)
|
||||||
|
|
||||||
server = CiscoASAFirewall(id=server_id, url=scheme + url, verify_ssl=verify_ssl,
|
|
||||||
username=username, password=password,
|
|
||||||
outside_interface=outside_interface,
|
|
||||||
get_bandwidth_run_seconds=get_bandwidth_run_seconds)
|
|
||||||
|
|
||||||
getattr(self, f'{service}_servers').append(server)
|
getattr(self, f'{service}_servers').append(server)
|
||||||
|
|
||||||
except NoOptionError as e:
|
except NoOptionError as e:
|
||||||
self.logger.error('Missing key in %s. Error: %s', section, e)
|
self.logger.error('Missing key in %s. Error: %s', section, e)
|
||||||
self.rectify_ini()
|
self.rectify_ini()
|
||||||
|
|
|
@ -14,8 +14,10 @@ if version_info < (3, 6, 2):
|
||||||
class InfluxServer(NamedTuple):
|
class InfluxServer(NamedTuple):
|
||||||
password: str = 'root'
|
password: str = 'root'
|
||||||
port: int = 8086
|
port: int = 8086
|
||||||
|
ssl: bool = False
|
||||||
url: str = 'localhost'
|
url: str = 'localhost'
|
||||||
username: str = 'root'
|
username: str = 'root'
|
||||||
|
verify_ssl: bool = False
|
||||||
|
|
||||||
|
|
||||||
class SonarrServer(NamedTuple):
|
class SonarrServer(NamedTuple):
|
||||||
|
@ -76,13 +78,14 @@ class SickChillServer(NamedTuple):
|
||||||
verify_ssl: bool = False
|
verify_ssl: bool = False
|
||||||
|
|
||||||
|
|
||||||
class CiscoASAFirewall(NamedTuple):
|
class UniFiServer(NamedTuple):
|
||||||
get_bandwidth_run_seconds: int = 30
|
get_usg_stats_run_seconds: int = 30
|
||||||
id: int = None
|
id: int = None
|
||||||
outside_interface: str = None
|
password: str = 'ubnt'
|
||||||
password: str = 'cisco'
|
site: str = None
|
||||||
url: str = '192.168.1.1'
|
url: str = 'unifi.domain.tld:8443'
|
||||||
username: str = 'cisco'
|
username: str = 'ubnt'
|
||||||
|
usg_name: str = None
|
||||||
verify_ssl: bool = False
|
verify_ssl: bool = False
|
||||||
|
|
||||||
|
|
||||||
|
@ -168,6 +171,8 @@ class OmbiMovieRequest(NamedTuple):
|
||||||
subscribed: bool = None
|
subscribed: bool = None
|
||||||
theMovieDbId: int = None
|
theMovieDbId: int = None
|
||||||
title: str = None
|
title: str = None
|
||||||
|
langCode: str = None
|
||||||
|
languageCode: str = None
|
||||||
|
|
||||||
|
|
||||||
# Sonarr
|
# Sonarr
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
from os import _exit
|
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
from requests import Session, Request
|
from requests import Session, Request
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
|
@ -17,6 +16,7 @@ class TautulliAPI(object):
|
||||||
self.session.params = {'apikey': self.server.api_key}
|
self.session.params = {'apikey': self.server.api_key}
|
||||||
self.endpoint = '/api/v2'
|
self.endpoint = '/api/v2'
|
||||||
self.logger = getLogger()
|
self.logger = getLogger()
|
||||||
|
self.my_ip = None
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<tautulli-{self.server.id}>"
|
return f"<tautulli-{self.server.id}>"
|
||||||
|
@ -34,6 +34,11 @@ class TautulliAPI(object):
|
||||||
|
|
||||||
get = g['response']['data']
|
get = g['response']['data']
|
||||||
|
|
||||||
|
# Remove erroneous key from sessions
|
||||||
|
for session in get['sessions']:
|
||||||
|
if session.get('_cache_time'):
|
||||||
|
del session['_cache_time']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sessions = [TautulliStream(**session) for session in get['sessions']]
|
sessions = [TautulliStream(**session) for session in get['sessions']]
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
|
@ -46,22 +51,27 @@ class TautulliAPI(object):
|
||||||
getattr(session, 'ip_address_public')
|
getattr(session, 'ip_address_public')
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
self.logger.error('Public IP attribute missing!!! Do you have an old version of Tautulli (v1)?')
|
self.logger.error('Public IP attribute missing!!! Do you have an old version of Tautulli (v1)?')
|
||||||
_exit(1)
|
exit(1)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
geodata = self.geoiphandler.lookup(session.ip_address_public)
|
geodata = self.geoiphandler.lookup(session.ip_address_public)
|
||||||
except (ValueError, AddressNotFoundError):
|
except (ValueError, AddressNotFoundError):
|
||||||
if self.server.fallback_ip:
|
self.logger.debug('Public IP missing for Tautulli session...')
|
||||||
# Try the failback ip in the config file
|
if not self.my_ip:
|
||||||
|
# Try the fallback ip in the config file
|
||||||
try:
|
try:
|
||||||
|
self.logger.debug('Atempting to use the failback IP...')
|
||||||
geodata = self.geoiphandler.lookup(self.server.fallback_ip)
|
geodata = self.geoiphandler.lookup(self.server.fallback_ip)
|
||||||
except AddressNotFoundError as e:
|
except AddressNotFoundError as e:
|
||||||
self.logger.error('%s', e)
|
self.logger.error('%s', e)
|
||||||
_exit(1)
|
|
||||||
|
self.my_ip = self.session.get('http://ip.42.pl/raw').text
|
||||||
|
self.logger.debug('Looked the public IP and set it to %s', self.my_ip)
|
||||||
|
|
||||||
|
geodata = self.geoiphandler.lookup(self.my_ip)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
my_ip = self.session.get('http://ip.42.pl/raw').text
|
geodata = self.geoiphandler.lookup(self.my_ip)
|
||||||
geodata = self.geoiphandler.lookup(my_ip)
|
|
||||||
|
|
||||||
if not all([geodata.location.latitude, geodata.location.longitude]):
|
if not all([geodata.location.latitude, geodata.location.longitude]):
|
||||||
latitude = 37.234332396
|
latitude = 37.234332396
|
||||||
|
|
75
varken/unifi.py
Normal file
75
varken/unifi.py
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
from logging import getLogger
|
||||||
|
from requests import Session, Request
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
|
from varken.helpers import connection_handler
|
||||||
|
|
||||||
|
|
||||||
|
class UniFiAPI(object):
|
||||||
|
def __init__(self, server, dbmanager):
|
||||||
|
self.dbmanager = dbmanager
|
||||||
|
self.server = server
|
||||||
|
# Create session to reduce server web thread load, and globally define pageSize for all requests
|
||||||
|
self.session = Session()
|
||||||
|
self.logger = getLogger()
|
||||||
|
|
||||||
|
self.get_cookie()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<unifi-{self.server.id}>"
|
||||||
|
|
||||||
|
def get_cookie(self):
|
||||||
|
endpoint = '/api/login'
|
||||||
|
pre_cookies = {'username': self.server.username, 'password': self.server.password, 'remember': True}
|
||||||
|
req = self.session.prepare_request(Request('POST', self.server.url + endpoint, json=pre_cookies))
|
||||||
|
post = connection_handler(self.session, req, self.server.verify_ssl, as_is_reply=True)
|
||||||
|
|
||||||
|
if not post.cookies.get('unifises'):
|
||||||
|
return
|
||||||
|
|
||||||
|
cookies = {'unifises': post.cookies.get('unifises')}
|
||||||
|
self.session.cookies.update(cookies)
|
||||||
|
|
||||||
|
def get_usg_stats(self):
|
||||||
|
now = datetime.now(timezone.utc).astimezone().isoformat()
|
||||||
|
endpoint = f'/api/s/{self.server.site}/stat/device'
|
||||||
|
req = self.session.prepare_request(Request('GET', self.server.url + endpoint))
|
||||||
|
get = connection_handler(self.session, req, self.server.verify_ssl)
|
||||||
|
|
||||||
|
if not get:
|
||||||
|
self.logger.error("Canceling Job get_usg_stats for unifi-%s", self.server.id)
|
||||||
|
return f"unifi-{self.server.id}-get_usg_stats"
|
||||||
|
|
||||||
|
devices = {device['name']: device for device in get['data']}
|
||||||
|
if devices.get(self.server.usg_name):
|
||||||
|
device = devices[self.server.usg_name]
|
||||||
|
else:
|
||||||
|
self.logger.error("Could not find a USG named %s from your UniFi Controller", self.server.usg_name)
|
||||||
|
return
|
||||||
|
|
||||||
|
influx_payload = [
|
||||||
|
{
|
||||||
|
"measurement": "UniFi",
|
||||||
|
"tags": {
|
||||||
|
"model": device['model'],
|
||||||
|
"name": device['name']
|
||||||
|
},
|
||||||
|
"time": now,
|
||||||
|
"fields": {
|
||||||
|
"bytes_current": device['wan1']['bytes-r'],
|
||||||
|
"rx_bytes_total": device['wan1']['rx_bytes'],
|
||||||
|
"rx_bytes_current": device['wan1']['rx_bytes-r'],
|
||||||
|
"tx_bytes_total": device['wan1']['tx_bytes'],
|
||||||
|
"tx_bytes_current": device['wan1']['tx_bytes-r'],
|
||||||
|
"speedtest_latency": device['speedtest-status']['latency'],
|
||||||
|
"speedtest_download": device['speedtest-status']['xput_download'],
|
||||||
|
"speedtest_upload": device['speedtest-status']['xput_upload'],
|
||||||
|
"cpu_loadavg_1": device['sys_stats']['loadavg_1'],
|
||||||
|
"cpu_loadavg_5": device['sys_stats']['loadavg_5'],
|
||||||
|
"cpu_loadavg_15": device['sys_stats']['loadavg_15'],
|
||||||
|
"cpu_util": device['system-stats']['cpu'],
|
||||||
|
"mem_util": device['system-stats']['mem'],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
self.dbmanager.write_points(influx_payload)
|
Loading…
Add table
Add a link
Reference in a new issue