captive.whump.shanti-portal/tools/storage.py

122 lines
3.2 KiB
Python
Raw Normal View History

2017-03-03 00:04:12 +00:00
"""
Database storage backends for client.py.
"""
import json
from datetime import datetime
2017-03-06 09:26:35 +00:00
import psycopg2
2017-03-06 15:03:57 +00:00
from psycopg2.extras import DictCursor, register_ipaddress, Inet
2017-03-03 00:04:12 +00:00
from redis import Redis
2017-03-06 15:03:57 +00:00
from client import Client
2017-03-03 00:04:12 +00:00
2017-03-06 09:26:35 +00:00
class StoragePostgres(object):
2017-03-06 15:03:57 +00:00
"""
This requires python 3 for inet data type.
"""
2017-03-06 09:26:35 +00:00
def __init__(self, **kw):
config = kw.pop('config')
self.conn = psycopg2.connect(
host=config.get('postgres', 'hostname'),
user=config.get('postgres', 'username'),
password=config.get('postgres', 'password'),
dbname=config.get('postgres', 'database'),
2017-03-06 15:03:57 +00:00
port=config.getint('postgres', 'port'),
sslmode='disable',
cursor_factory=DictCursor
)
self.cur = self.conn.cursor()
register_ipaddress()
2017-09-29 16:37:30 +00:00
def client_ids(self):
self.cur.execute(
'select client_id from client'
)
return self.cur
2017-03-06 15:03:57 +00:00
def get_client_by_id(self, client_id):
self.cur.execute(
'select * from client where client_id=%s',
(client_id,)
2017-03-06 09:26:35 +00:00
)
2017-03-06 15:03:57 +00:00
return self.cur.fetchone()
def get_client(self, ip_address, protocol):
"""
Expects an ipaddress.IPv4Interface as ip_address argument.
"""
2017-03-06 15:03:57 +00:00
self.cur.execute(
'select * from client where ip_address=%s and protocol=%s',
(ip_address, protocol, )
2017-03-06 15:03:57 +00:00
)
return self.cur.fetchone()
def write_client(self, client):
query = (
'insert into client (client_id, created, ip_address, protocol, '
2017-09-29 15:44:40 +00:00
'enabled, last_packets, last_activity, expires) values '
'(%s, %s, %s, %s, %s, %s, %s, %s) on conflict (client_id, '
'ip_address, protocol) do update set (enabled, last_packets, '
'last_activity) = (EXCLUDED.enabled, EXCLUDED.last_packets, '
2017-03-06 15:03:57 +00:00
'EXCLUDED.last_activity)'
)
self.cur.execute(
query,
(
client.client_id,
client.created,
client._ip_address,
2017-03-06 15:03:57 +00:00
client.protocol,
client.enabled,
client.last_packets,
2017-09-29 15:44:40 +00:00
client.last_activity,
client.expires
2017-03-06 15:03:57 +00:00
)
)
self.conn.commit()
def remove_client(self, client):
query = 'delete from client where client_id=%s'
self.cur.execute(query, (client.client_id,))
self.conn.commit()
2017-03-06 09:26:35 +00:00
2017-03-03 00:04:12 +00:00
class DateTimeEncoder(json.JSONEncoder):
"""
json.JSONEncoder sub-class that converts all datetime objects to
epoch timestamp integer values.
"""
def default(self, o):
if isinstance(o, datetime):
return int(o.strftime('%s'))
return json.JSONEncoder.default(self, o)
class StorageRedis(object):
2017-03-06 09:26:35 +00:00
"""
Note: Abandoned this storage backend for Postgres.
"""
2017-03-03 00:04:12 +00:00
def __init__(self, **kw):
config = kw.pop('config')
self.r = Redis(
host=config.get('redis', 'hostname'),
port=config.getint('redis', 'port'),
db=config.getint('redis', 'db')
)
def add_client(self, client_id, **kw):
2017-03-06 09:26:35 +00:00
raise NotImplemented