pvl/verkko/hosts.py
changeset 8 f64c44640b15
parent 6 0f243c59d5d1
child 9 3334d8ddf2f1
equal deleted inserted replaced
7:7baf4cccb4a9 8:f64c44640b15
     1 from pvl.verkko import db, web
     1 from pvl.verkko import db, web
     2 
     2 
     3 from pvl.html import tags as html
     3 from pvl.html import tags as html
     4 
     4 
       
     5 import re
     5 import socket # dns
     6 import socket # dns
     6 
     7 
     7 import logging; log = logging.getLogger('pvl.verkko.hosts')
     8 import logging; log = logging.getLogger('pvl.verkko.hosts')
     8 
     9 
     9 # XXX: this should actually be DHCPHost
    10 # XXX: this should actually be DHCPHost
    10 class Host (object) :
    11 class Host (object) :
    11     DATE_FMT = '%Y%m%d'
    12     DATE_FMT = '%Y%m%d'
       
    13     
       
    14     MAC_HEX = r'([A-Za-z0-9]{2})'
       
    15     MAC_SEP = r'[-:.]?'
       
    16     MAC_RE = re.compile(MAC_SEP.join([MAC_HEX] * 6))
       
    17 
       
    18     @classmethod
       
    19     def normalize_mac (cls, mac) :
       
    20         match = cls.MAC_RE.search(mac)
       
    21 
       
    22         if not match :
       
    23             raise ValueError(mac)
       
    24 
       
    25         else :
       
    26             return ':'.join(hh.lower() for hh in match.groups())
    12 
    27 
    13     def __init__ (self, ip, mac, name=None) :
    28     def __init__ (self, ip, mac, name=None) :
    14         self.ip = ip
    29         self.ip = ip
    15         self.mac = mac
    30         self.mac = mac
    16         self.name = name
    31         self.name = name
    89         log.debug("sort: %s", sort)
   104         log.debug("sort: %s", sort)
    90 
   105 
    91         hosts = hosts.order_by(sort)
   106         hosts = hosts.order_by(sort)
    92 
   107 
    93         # k
   108         # k
       
   109         self.sort = sort
       
   110 
    94         return hosts
   111         return hosts
    95     
   112     
    96     def render_hosts (self, hosts, title=None) :
   113     def render_hosts (self, hosts, title=None) :
    97         COLS = (
   114         COLS = (
    98             #title          sort
   115             #title          sort
   118                         html.a(href=self.url(ItemHandler, id=host.id))(
   135                         html.a(href=self.url(ItemHandler, id=host.id))(
   119                             '#' #host['rowid'])
   136                             '#' #host['rowid'])
   120                         )
   137                         )
   121                     ),
   138                     ),
   122                     html.td(class_='ip')(
   139                     html.td(class_='ip')(
   123                         html.a(href=self.url(ListHandler, attr='ip', value=host.ip))(
   140                         html.a(href=self.url(ListHandler, ip=host.ip))(
   124                             host.ip
   141                             host.ip
   125                         )
   142                         )
   126                     ),
   143                     ),
   127                     html.td(class_='mac')(
   144                     html.td(class_='mac')(
   128                         html.a(href=self.url(ListHandler, attr='mac', value=host.mac))(
   145                         html.a(href=self.url(ListHandler, mac=host.mac))(
   129                             host.render_mac()
   146                             host.render_mac()
   130                         )
   147                         )
   131                     ),
   148                     ),
   132                     html.td(host.render_name()),
   149                     html.td(host.render_name()),
   133                     html.td(host.when()),
   150                     html.td(host.when()),
   139         attrs = (
   156         attrs = (
   140                 ('IP',          host.ip),
   157                 ('IP',          host.ip),
   141                 ('MAC',         host.mac),
   158                 ('MAC',         host.mac),
   142                 ('Hostname',    host.name),
   159                 ('Hostname',    host.name),
   143                 ('DNS',         host.dns()),
   160                 ('DNS',         host.dns()),
       
   161                 ('First seen',  host.first_seen),
       
   162                 ('Last seen',   host.last_seen),
   144         )
   163         )
   145 
   164 
   146         return (
   165         return (
   147             html.h2('Host'),
   166             html.h2('Host'),
   148             html.dl(
   167             html.dl(
   150             ),
   169             ),
   151 
   170 
   152             html.h2('Related'),
   171             html.h2('Related'),
   153             self.render_hosts(hosts),
   172             self.render_hosts(hosts),
   154 
   173 
   155             html.a(href=self.url(IndexHandler))(html('«'), 'Back'),
   174             html.a(href=self.url(ListHandler))(html('«'), 'Back'),
   156         )
   175         )
   157 
   176 
   158 class IndexHandler (BaseHandler) :
   177 class IndexHandler (BaseHandler) :
   159     def process (self) :
   178     def process (self) :
   160         self.hosts = self.query()
   179         self.hosts = self.query()
   180 
   199 
   181     def render (self) :
   200     def render (self) :
   182         return self.render_host(self.host, self.hosts)
   201         return self.render_host(self.host, self.hosts)
   183 
   202 
   184 class ListHandler (BaseHandler) :
   203 class ListHandler (BaseHandler) :
   185     def process (self, attr, value) :
   204     def process (self) :
   186         # fake host
   205         hosts = self.query()
   187         _host = { 'ip': None, 'mac': None, 'name': None }
   206         self.filters = {}
   188 
   207 
   189         if attr not in self.HOST_ATTRS :
   208         for attr in self.HOST_ATTRS :
   190             raise web.BadRequest("Invalid attribute: {attr}".format(attr=attr))
   209             value = self.request.args.get(attr)
   191 
   210 
   192         _host[attr] = value
   211             if not value :
   193 
   212                 continue
   194         self.host = Host(**_host)
   213 
   195         self.expression = "{attr}: {value}".format(attr=attr, value=value)
   214             # preprocess
   196 
   215             if attr == 'mac' :
   197         # query
   216                 value = Host.normalize_mac(value)
   198         attr = self.HOST_ATTRS[attr]
   217 
   199         log.debug("%s == %s", attr, value)
   218             # filter
       
   219             hosts = hosts.filter(self.HOST_ATTRS[attr] == value)
       
   220             self.filters[attr] = value
   200         
   221         
   201         self.hosts = self.query().filter(attr == value)
   222         self.hosts = hosts
   202 
   223 
   203     def title (self) :
   224     def title (self) :
   204         return "DHCP Hosts: {self.expression}".format(self=self)
   225         if self.filters :
       
   226             return "DHCP Hosts: {filters}".format(filters=', '.join(self.filters.itervalues()))
       
   227         else :
       
   228             return "DHCP Hosts"
   205     
   229     
   206     def render (self) :
   230     def render (self) :
   207         return self.render_host(self.host, self.hosts)
   231         return (
   208     
   232             self.render_hosts(self.hosts),
       
   233 
       
   234             html.a(href=self.url())(html('«'), 'Back') if self.filters else None,
       
   235         )