Added a simple data model class to be more flexible. SQLAlchemy will not be included. uplink is to small for this... maybe later. Lot of housekeeping where done too.

This commit is contained in:
Johannes Findeisen 2022-08-28 04:17:53 +02:00
commit d2f3484ca9
8 changed files with 279 additions and 62 deletions

View file

@ -25,8 +25,6 @@
# TODO: Implement a speedtest/ping that will also run regularly but in an individual interval
# TODO: become more verbose in each log level and log only to error when it really is an error
# else log to info and even add debug messages in DEBUG level
# TODO: Maybe make path to pid_file an arg to use /var/run/user/$uid/uplink.pid instead of
# /tmp/uplink.pid or check user id and write it to /var/run or var/run/user/$uid automatically
# TODO: make all args consistent and clean... there is some stuff to do!
import argparse
@ -113,7 +111,7 @@ def main():
args = parse_args()
root_logger = logging.getLogger()
logger.error("TEST")
if args.logfile:
logfile = os.path.expanduser(args.logfile)
if not os.path.exists(os.path.dirname(logfile)):
@ -143,7 +141,7 @@ def main():
configuration.set_env_var('_start_date', time.strftime('%Y-%m-%d %H:%M:%S',
time.localtime(
calendar.timegm(time.gmtime()))))
calendar.timegm(time.gmtime()))))
# interval set in args is overriding configuration and default
if args.interval:
@ -177,17 +175,17 @@ def main():
if configuration.get_httpserver_framework() == 'bottle':
from uplink.server_bottle import Server
s = Server(configuration)
st = Thread(target=s.run, daemon=True)
st = Thread(target=s.run_server, daemon=True)
st.start()
elif configuration.get_httpserver_framework() == 'cherrypy':
from uplink.server_cherrypy import Server
s = Server(configuration)
st = Thread(target=s.run, daemon=True)
st = Thread(target=s.run_server, daemon=True)
st.start()
elif configuration.get_httpserver_framework() == 'pyramid':
from uplink.server_pyramid import Server
s = Server(configuration)
st = Thread(target=s.run, daemon=True)
st = Thread(target=s.run_server, daemon=True)
st.start()
else:
logger.error('[uplink] no http framework configured! '

32
uplink/csv.py Normal file
View file

@ -0,0 +1,32 @@
# Copyright (c) 2022 Johannes Findeisen <you@hanez.org>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is furnished
# to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
# OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
from logging import getLogger
logger = getLogger(__name__)
class Csv:
def __init__(self, configuration):
self.configuration = configuration
def write_model_to_csv(self):
return

View file

@ -18,13 +18,9 @@
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import calendar
import pymysql
import socket
import time
from logging import getLogger
from sqlalchemy import create_engine
logger = getLogger(__name__)
@ -32,35 +28,57 @@ logger = getLogger(__name__)
class Database:
def __init__(self, configuration):
self.configuration = configuration
self.date = None
self.time = None
self.status = None
def write_to_db(self, fc, ip, provider, status):
timestamp = calendar.timegm(time.gmtime())
local_time = time.localtime(timestamp)
self.date = time.strftime('%Y-%m-%d', local_time)
self.time = time.strftime('%H:%M:%S', local_time)
self.__configuration = configuration
def write_model_to_db(self, model):
try:
con = pymysql.connect(host=self.configuration.get_database_host(),
user=self.configuration.get_database_user(),
password=self.configuration.get_database_password(),
database=self.configuration.get_database_name())
con = pymysql.connect(host=self.__configuration.get_database_host(),
user=self.__configuration.get_database_user(),
password=self.__configuration.get_database_password(),
database=self.__configuration.get_database_name())
sql = 'INSERT INTO log (timestamp, date, time, uptime, internal_ip, external_ip, external_ipv6, is_linked, ' \
'is_connected, str_transmission_rate_up, str_transmission_rate_down, str_max_bit_rate_up, ' \
'str_max_bit_rate_down, str_max_linked_bit_rate_up, str_max_linked_bit_rate_down, model_name, ' \
'system_version, provider, message, source_host) VALUES (\"' + str(timestamp) + '\",\"' + str(self.date) + '\",\"' + \
str(self.time) + '\",\"' + str(fc.connection_uptime) + '\",\"' + str(ip) + '\",\"' + \
str(fc.external_ip) + '\",\"' + str(fc.external_ipv6) + '\",\"' + str(int(fc.is_linked)) + '\",\"' + \
str(int(fc.is_connected)) + '\",\"' + str(fc.str_transmission_rate[0]) + '\",\"' + \
str(fc.str_transmission_rate[1]) + '\",\"' + str(fc.str_max_bit_rate[0]) + '\",\"' + \
str(fc.str_max_bit_rate[1]) + '\",\"' + str(fc.str_max_linked_bit_rate[0]) + '\",\"' + \
str(fc.str_max_linked_bit_rate[1]) + '\",\"' + str(fc.modelname) + '\",\"' + \
str(fc.fc.system_version) + '\",\"' + str(provider) + '\",\"' + str(status) + '\",\"' + \
socket.gethostname() + '\")'
sql = 'INSERT INTO log (' \
'timestamp, ' \
'date, ' \
'time, ' \
'uptime, ' \
'internal_ip, ' \
'external_ip, ' \
'external_ipv6, ' \
'is_linked, ' \
'is_connected, ' \
'str_transmission_rate_up, ' \
'str_transmission_rate_down, ' \
'str_max_bit_rate_up, ' \
'str_max_bit_rate_down, ' \
'str_max_linked_bit_rate_up, ' \
'str_max_linked_bit_rate_down, ' \
'model_name, ' \
'system_version, ' \
'provider, ' \
'message, ' \
'source_host '\
') VALUES (\"' + \
str(model.get_timestamp()) + '\",\"' + \
str(model.get_date()) + '\",\"' + \
str(model.get_time()) + '\",\"' + \
str(model.get_uptime()) + '\",\"' + \
str(model.get_internal_ip()) + '\",\"' + \
str(model.get_external_ip()) + '\",\"' + \
str(model.get_external_ipv6()) + '\",\"' + \
str(int(model.get_is_linked())) + '\",\"' + \
str(int(model.get_is_connected())) + '\",\"' + \
str(model.get_str_transmission_rate_up()) + '\",\"' + \
str(model.get_str_transmission_rate_down()) + '\",\"' + \
str(model.get_str_max_bit_rate_up()) + '\",\"' + \
str(model.get_str_max_bit_rate_down()) + '\",\"' + \
str(model.get_str_max_linked_bit_rate_up()) + '\",\"' + \
str(model.get_str_max_linked_bit_rate_down()) + '\",\"' + \
str(model.get_model_name()) + '\",\"' + \
str(model.get_system_version()) + '\",\"' + \
str(model.get_provider()) + '\",\"' + \
str(model.get_message()) + '\",\"' + \
str(model.get_source_host() + '\")')
with con.cursor() as cur:
cur.execute(sql)

View file

@ -26,4 +26,152 @@ logger = getLogger(__name__)
class Model:
def __init__(self, configuration):
self.configuration = configuration
self.__configuration = configuration
self.__date = None
self.__external_ip = None
self.__external_ipv6 = None
# no set method for id; it is auto incrementing in the database
self.__id = None
self.__internal_ip = None
self.__is_connected = None
self.__is_linked = None
self.__message = None
self.__model_name = None
self.__provider = None
self.__source_host = None
self.__str_max_bit_rate_down = None
self.__str_max_bit_rate_up = None
self.__str_max_linked_bit_rate_down = None
self.__str_max_linked_bit_rate_up = None
self.__str_transmission_rate_down = None
self.__str_transmission_rate_up = None
self.__system_version = None
self.__time = None
self.__timestamp = None
self.__uptime = None
# set methods:
def set_date(self, date):
self.__date = date
def set_external_ip(self, external_ip):
self.__external_ip = external_ip
def set_external_ipv6(self, external_ipv6):
self.__external_ipv6 = external_ipv6
def set_internal_ip(self, internal_ip):
self.__internal_ip = internal_ip
def set_is_connected(self, is_connected):
self.__is_connected = is_connected
def set_is_linked(self, is_linked):
self.__is_linked = is_linked
def set_message(self, message):
self.__message = message
def set_model_name (self, model_name):
self.__model_name = model_name
def set_provider(self, provider):
self.__provider = provider
def set_source_host(self, source_host):
self.__source_host = source_host
def set_str_max_bit_rate_down(self, str_max_bit_rate_down):
self.__str_max_bit_rate_down = str_max_bit_rate_down
def set_str_max_bit_rate_up(self, str_max_bit_rate_up):
self.__str_max_bit_rate_up = str_max_bit_rate_up
def set_str_max_linked_bit_rate_down(self, str_max_linked_bit_rate_down):
self.__str_max_linked_bit_rate_down = str_max_linked_bit_rate_down
def set_str_max_linked_bit_rate_up(self, str_max_linked_bit_rate_up):
self.__str_max_linked_bit_rate_up = str_max_linked_bit_rate_up
def set_str_transmission_rate_down(self, str_transmission_rate_down):
self.__str_transmission_rate_down = str_transmission_rate_down
def set_str_transmission_rate_up(self, str_transmission_rate_up):
self.__str_transmission_rate_up = str_transmission_rate_up
def set_system_version(self, system_version):
self.__system_version = system_version
def set_time(self, time):
self.__time = time
def set_timestamp(self, timestamp):
self.__timestamp = timestamp
def set_uptime(self, uptime):
self.__uptime = uptime
# get methods:
def get_date(self):
return self.__date
def get_external_ip(self):
return self.__external_ip
def get_external_ipv6(self):
return self.__external_ipv6
def get_id(self):
return self.__id
def get_internal_ip(self):
return self.__internal_ip
def get_is_connected(self):
return self.__is_connected
def get_is_linked(self):
return self.__is_linked
def get_message(self):
return self.__message
def get_model_name(self):
return self.__model_name
def get_provider(self):
return self.__provider
def get_source_host(self):
return self.__source_host
def get_str_max_bit_rate_down(self):
return self.__str_max_bit_rate_down
def get_str_max_bit_rate_up(self):
return self.__str_max_bit_rate_up
def get_str_max_linked_bit_rate_down(self):
return self.__str_max_linked_bit_rate_down
def get_str_max_linked_bit_rate_up(self):
return self.__str_max_linked_bit_rate_up
def get_str_transmission_rate_down(self):
return self.__str_transmission_rate_down
def get_str_transmission_rate_up(self):
return self.__str_transmission_rate_up
def get_system_version(self):
return self.__system_version
def get_time(self):
return self.__time
def get_timestamp(self):
return self.__timestamp
def get_uptime(self):
return self.__uptime

View file

@ -31,17 +31,17 @@ logger = getLogger(__name__)
class Server:
def __init__(self, configuration):
self.configuration = configuration
self.__configuration = configuration
@route('/hello/<name>')
def index(self, name):
return template('<b>Hello {{name}}</b>!', name=name)
@route('/config')
def configuration(self):
return template('<pre>{{config}}</pre>!', config=json.dumps(vars(self.configuration),
def config(self):
return template('<pre>{{config}}</pre>!', config=json.dumps(vars(self.__configuration),
sort_keys=True, indent=4))
def run(self):
run(host=self.configuration.get_httpserver_host(),
port=self.configuration.get_httpserver_port())
def run_server(self):
run(host=self.__configuration.get_httpserver_host(),
port=self.__configuration.get_httpserver_port())

View file

@ -32,23 +32,23 @@ logger = getLogger(__name__)
class Server:
def __init__(self, configuration):
self.configuration = configuration
self.__configuration = configuration
@cherrypy.expose
def index(self):
return "Hello world!"
return 'Hello world!'
@cherrypy.expose
def config(self):
return '<pre style="border:2px solid black;background:#1d2021;color:#f0751a;">' + \
json.dumps(vars(self.configuration), sort_keys=True, indent=4) + \
json.dumps(vars(self.__configuration), sort_keys=True, indent=4) + \
'</pre>'
@cherrypy.expose
def playground(self):
return "My Playground!"
return 'My Playground!'
def run(self):
def run_server(self):
conf = {
'/': {
# 'tools.sessions.on': True,
@ -73,8 +73,8 @@ class Server:
#})
cherrypy.config.update({
'global': {
'server.socket_host': self.configuration.get_httpserver_host(),
'server.socket_port': self.configuration.get_httpserver_port(),
'server.socket_host': self.__configuration.get_httpserver_host(),
'server.socket_port': self.__configuration.get_httpserver_port(),
'environment': 'production'
}
})

View file

@ -31,16 +31,16 @@ logger = getLogger(__name__)
class Server:
def __init__(self, configuration):
self.configuration = configuration
self.__configuration = configuration
def config(self, request):
return Response(config=json.dumps(vars(self.configuration), sort_keys=True, indent=4))
return Response(config=json.dumps(vars(self.__configuration), sort_keys=True, indent=4))
def run(self):
def run_server(self):
with Configurator() as config:
config.add_route('config', '/')
config.add_view(self.config, route_name='config')
app = config.make_wsgi_app()
server = make_server(self.configuration.get_httpserver_host(),
self.configuration.get_httpserver_port(), app)
server = make_server(self.__configuration.get_httpserver_host(),
self.__configuration.get_httpserver_port(), app)
server.serve_forever()

View file

@ -24,6 +24,7 @@
# be optional too.
import calendar
import socket
import time
from fritzconnection.lib.fritzstatus import FritzStatus
@ -60,13 +61,33 @@ class Uplink(Daemon):
else:
self.status = 'DOWN'
logger.info(str(uplink['provider'] + ' ' + self.status + ' (ip: ' +
fc.external_ip + ')'))
logger.info(str(uplink['provider'] + ' (uplink IP: ' + fc.external_ip + ') ' +
self.status))
model = Model(self.configuration)
model.set_date(self.date)
model.set_external_ip(fc.external_ip)
model.set_external_ipv6(fc.external_ipv6)
model.set_internal_ip(uplink['ip'])
model.set_is_connected(fc.is_connected)
model.set_is_linked(fc.is_linked)
model.set_message(self.status)
model.set_model_name(fc.modelname)
model.set_provider(uplink['provider'])
model.set_source_host(socket.gethostname())
model.set_str_max_bit_rate_down(fc.str_max_bit_rate[1])
model.set_str_max_bit_rate_up(fc.str_max_bit_rate[0])
model.set_str_max_linked_bit_rate_down(fc.str_max_linked_bit_rate[1])
model.set_str_max_linked_bit_rate_up(fc.str_max_linked_bit_rate[0])
model.set_str_transmission_rate_down(fc.str_transmission_rate[1])
model.set_str_transmission_rate_up (fc.str_transmission_rate[0])
model.set_system_version(fc.fc.system_version)
model.set_time(self.time)
model.set_timestamp(timestamp)
model.set_uptime(fc.connection_uptime)
database = Database(self.configuration)
database.write_to_db(fc, uplink['ip'], uplink['provider'], self.status)
database.write_model_to_db(model)
except Exception as err:
message = str('error when getting data from ' + uplink['ip'] + ': {0}')
@ -77,17 +98,17 @@ class Uplink(Daemon):
if self.configuration.get_httpserver_framework() == 'bottle':
from uplink.server_bottle import Server
s = Server(self.configuration)
st = Thread(target=s.run, daemon=True)
st = Thread(target=s.run_server, daemon=True)
st.start()
elif self.configuration.get_httpserver_framework() == 'cherrypy':
from uplink.server_cherrypy import Server
s = Server(self.configuration)
st = Thread(target=s.run, daemon=True)
st = Thread(target=s.run_server, daemon=True)
st.start()
elif self.configuration.get_httpserver_framework() == 'pyramid':
from uplink.server_pyramid import Server
s = Server(self.configuration)
st = Thread(target=s.run, daemon=True)
st = Thread(target=s.run_server, daemon=True)
st.start()
while True:
for i in range(len(self.configuration.get_uplinks())):