From ef7f471d58315311af61924c8af8a63b08fac554 Mon Sep 17 00:00:00 2001 From: "Nicholas St. Germain" Date: Sun, 9 Dec 2018 21:41:38 -0600 Subject: [PATCH] added asa module. fixes #44. Version Bump 1.0!!! --- Varken.py | 9 +++++- data/varken.example.ini | 7 +++-- requirements.txt | 1 + varken/__init__.py | 2 +- varken/cisco.py | 62 +++++++++++++++++++++++++++++++++++++++++ varken/helpers.py | 8 +++++- varken/iniparser.py | 37 ++++++++++++++---------- varken/structures.py | 8 ++++++ 8 files changed, 113 insertions(+), 21 deletions(-) create mode 100644 varken/cisco.py diff --git a/Varken.py b/Varken.py index f904846..6fe4ec3 100644 --- a/Varken.py +++ b/Varken.py @@ -20,6 +20,7 @@ from varken.sonarr import SonarrAPI from varken.tautulli import TautulliAPI from varken.radarr import RadarrAPI from varken.ombi import OmbiAPI +from varken.cisco import CiscoAPI from varken.dbmanager import DBManager from varken.varkenlogger import VarkenLogger @@ -98,8 +99,14 @@ if __name__ == "__main__": if server.request_total_counts: schedule.every(server.request_total_run_seconds).seconds.do(threaded, OMBI.get_total_requests) + if CONFIG.ciscoasa_enabled: + for firewall in CONFIG.ciscoasa_firewalls: + ASA = CiscoAPI(firewall, DBMANAGER) + schedule.every(firewall.get_bandwidth_run_seconds).seconds.do(threaded, ASA.get_bandwidth) + # Run all on startup - SERVICES_ENABLED = [CONFIG.ombi_enabled, CONFIG.radarr_enabled, CONFIG.tautulli_enabled, CONFIG.sonarr_enabled] + SERVICES_ENABLED = [CONFIG.ombi_enabled, CONFIG.radarr_enabled, CONFIG.tautulli_enabled, + CONFIG.sonarr_enabled, CONFIG.ciscoasa_enabled] if not [enabled for enabled in SERVICES_ENABLED if enabled]: exit("All services disabled. Exiting") schedule.run_all() diff --git a/data/varken.example.ini b/data/varken.example.ini index f38217f..392ed80 100644 --- a/data/varken.example.ini +++ b/data/varken.example.ini @@ -10,7 +10,7 @@ sonarr_server_ids = 1,2 radarr_server_ids = 1,2 tautulli_server_ids = 1 ombi_server_ids = 1 -asa = false +ciscoasa_firewall_ids = false [influxdb] url = influxdb.domain.tld @@ -81,10 +81,11 @@ request_type_run_seconds = 300 get_request_total_counts = true request_total_run_seconds = 300 -[asa] +[ciscoasa-1] url = firewall.domain.tld username = cisco password = cisco -influx_db = asa +outside_interface = WAN ssl = false verify_ssl = true +get_bandwidth_run_seconds = 300 diff --git a/requirements.txt b/requirements.txt index 8fdd006..bab1e82 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,4 @@ geoip2>=2.9.0 influxdb>=5.2.0 schedule>=0.5.0 distro>=1.3.0 +urllib3>=1.22 \ No newline at end of file diff --git a/varken/__init__.py b/varken/__init__.py index cd46408..341988c 100644 --- a/varken/__init__.py +++ b/varken/__init__.py @@ -1 +1 @@ -VERSION = 0.2 +VERSION = 1.0 diff --git a/varken/cisco.py b/varken/cisco.py new file mode 100644 index 0000000..6ce3392 --- /dev/null +++ b/varken/cisco.py @@ -0,0 +1,62 @@ +import logging +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 = logging.getLogger() + + self.get_token() + + def __repr__(self): + return "".format(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)) + print(req.headers) + 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) diff --git a/varken/helpers.py b/varken/helpers.py index 00ca318..25f99d9 100644 --- a/varken/helpers.py +++ b/varken/helpers.py @@ -2,10 +2,10 @@ import os import time import tarfile import hashlib +import urllib3 import geoip2.database import logging -from functools import update_wrapper from json.decoder import JSONDecodeError from os.path import abspath, join from requests.exceptions import InvalidSchema, SSLError @@ -58,6 +58,8 @@ def connection_handler(session, request, verify): v = verify return_json = False + urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + try: get = s.send(r, verify=v) if get.status_code == 401: @@ -69,6 +71,10 @@ def connection_handler(session, request, verify): return_json = get.json() except JSONDecodeError: logger.error('No JSON response... BORKED! Let us know in discord') + # 204 No Content is for ASA only + elif get.status_code == 204: + if get.headers['X-Auth-Token']: + return get.headers['X-Auth-Token'] except InvalidSchema: logger.error('You added http(s):// in the config file. Don\'t do that.') diff --git a/varken/iniparser.py b/varken/iniparser.py index 0c361f0..30629a0 100644 --- a/varken/iniparser.py +++ b/varken/iniparser.py @@ -2,14 +2,14 @@ import configparser import logging from sys import exit from os.path import join, exists -from varken.structures import SonarrServer, RadarrServer, OmbiServer, TautulliServer, InfluxServer +from varken.structures import SonarrServer, RadarrServer, OmbiServer, TautulliServer, InfluxServer, CiscoASAFirewall logger = logging.getLogger() class INIParser(object): def __init__(self, data_folder): - self.config = configparser.ConfigParser() + self.config = configparser.ConfigParser(interpolation=None) self.data_folder = data_folder self.influx_server = InfluxServer() @@ -26,8 +26,8 @@ class INIParser(object): self.tautulli_enabled = False self.tautulli_servers = [] - self.asa_enabled = False - self.asa = None + self.ciscoasa_enabled = False + self.ciscoasa_firewalls = [] self.parse_opts() @@ -172,15 +172,22 @@ class INIParser(object): self.ombi_servers.append(server) # Parse ASA opts - if self.config.getboolean('global', 'asa'): - self.asa_enabled = True - url = self.config.get('asa', 'url') - username = self.config.get('asa', 'username') - password = self.config.get('asa', 'password') - scheme = 'https://' if self.config.getboolean('asa', 'ssl') else 'http://' - verify_ssl = self.config.getboolean('asa', 'verify_ssl') - if scheme != 'https://': - verify_ssl = False - db_name = self.config.get('asa', 'influx_db') + self.ciscoasa_enabled = self.enable_check('ciscoasa_firewall_ids') - self.asa = (scheme + url, username, password, verify_ssl, db_name) + if self.ciscoasa_enabled: + fids = self.config.get('global', 'ciscoasa_firewall_ids').strip(' ').split(',') + for firewall_id in fids: + ciscoasa_section = 'ciscoasa-' + firewall_id + url = self.config.get(ciscoasa_section, 'url') + username = self.config.get(ciscoasa_section, 'username') + password = self.config.get(ciscoasa_section, 'password') + scheme = 'https://' if self.config.getboolean(ciscoasa_section, 'ssl') else 'http://' + verify_ssl = self.config.getboolean(ciscoasa_section, 'verify_ssl') + if scheme != 'https://': + verify_ssl = False + outside_interface = self.config.get(ciscoasa_section, 'outside_interface') + get_bandwidth_run_seconds = self.config.getint(ciscoasa_section, 'get_bandwidth_run_seconds') + + firewall = CiscoASAFirewall(firewall_id, scheme + url, username, password, outside_interface, + verify_ssl, get_bandwidth_run_seconds) + self.ciscoasa_firewalls.append(firewall) diff --git a/varken/structures.py b/varken/structures.py index d934ece..44c202a 100644 --- a/varken/structures.py +++ b/varken/structures.py @@ -70,6 +70,14 @@ class InfluxServer(NamedTuple): username: str = 'root' password: str = 'root' +class CiscoASAFirewall(NamedTuple): + id: int = None + url: str = '192.168.1.1' + username: str = 'cisco' + password: str = 'cisco' + outside_interface: str = None + verify_ssl: bool = False + get_bandwidth_run_seconds: int = 30 class OmbiRequestCounts(NamedTuple): pending: int = 0