from pvl.verkko import web, db, table
from pvl.verkko.utils import parse_timedelta, format_timedelta
from pvl.web import html
import datetime
import logging; log = logging.getLogger('pvl.verkko.leases')
class DHCPLease (object) :
"""
A DHCP lease with ip/mac and starts/ends
"""
DATE_FMT = '%Y%m%d %H:%M'
TIME_FMT = '%H:%M:%S'
@classmethod
def format_datetime (cls, dt) :
if dt.date() == datetime.date.today() :
return dt.strftime(cls.TIME_FMT)
else :
return dt.strftime(cls.DATE_FMT)
def render_starts (self) :
return self.format_datetime(self.starts)
def render_ends (self) :
if self.ends :
return self.format_datetime(self.ends)
else :
return None
def ends_class (self) :
if self.ends and self.ends > datetime.datetime.now() :
return 'active'
else :
return None
@property
def length (self) :
if self.ends :
return self.ends - self.starts
else :
return datetime.datetime.now() - self.starts
def render_length (self) :
return format_timedelta(self.length)
db.mapper(DHCPLease, db.dhcp_leases, properties=dict(
))
class LeasesTable (table.Table) :
"""
<table> of leases.
"""
ITEMS = "Leases"
COLUMNS = (
table.Column('ip', "IP", DHCPLease.ip,
rowfilter = True,
),
table.Column('mac', "MAC", DHCPLease.mac,
rowfilter = True,
),
table.Column('hostname', "Hostname", DHCPLease.hostname),
table.Column('starts', "Starts", DHCPLease.starts, DHCPLease.render_starts),
table.Column('ends', "Ends", DHCPLease.ends, DHCPLease.render_ends,
rowcss = DHCPLease.ends_class
),
table.Column('length', "Lease", DHCPLease.ends - DHCPLease.starts, DHCPLease.render_length),
)
# XXX: have to set again
ATTRS = dict((col.attr, col) for col in COLUMNS)
# default
SORT = DHCPLease.starts.desc()
PAGE = 20
class LeasesHandler (table.TableHandler, web.DatabaseHandler) :
"""
Combined database + <table>
"""
CSS = web.DatabaseHandler.CSS + table.TableHandler.CSS + (
"/static/dhcp/hosts.css",
)
# view
TABLE = LeasesTable
def query (self) :
"""
Database SELECT query.
"""
return self.db.query(DHCPLease)
def filter_starts (self, value) :
return ((db.func.now() - DHCPLease.starts) < parse_timedelta(value))
def filter_ends (self, value) :
return ((DHCPLease.ends - db.func.now()) > parse_timedelta(value))
def filter_length (self, value) :
"""
Filter by leases valid on given date.
"""
dt = datetime.datetime.strptime(value, DHCPLease.DATE_FMT)
return db.between(dt, DHCPLease.starts, DHCPLease.ends)
def filter_ip (self, value) :
# column is IPv4 string literal format...
if '/' in value :
return (db.func.inet(DHCPLease.ip).op('<<')(db.func.cidr(value)))
else :
return (db.func.inet(DHCPLease.ip) == db.func.inet(value))
class ListHandler (LeasesHandler) :
"""
List of DHCP leases, using table.TableHandler -> LeasesTable.
"""
#TABLE_ITEM_URL = ItemHandler
def process (self) :
# super
table.TableHandler.process(self)
def title (self) :
if self.filters :
return "DHCP Leases: {filters}".format(filters=self.filters_title())
else :
return "DHCP Leases"
def render (self) :
return (
self.render_table(self.query, filters=self.filters, sort=self.sorts, page=self.page),
#html.a(href=self.url())(html('«'), 'Back') if self.filters else None,
)