rename pvl.syslog-dhcp as pvl.dhcp-syslog, and pvl.verkko-rrd-interfaces as pvl.rrd-interfaces
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/pvl.dhcp-syslog Tue Feb 19 22:07:40 2013 +0200
@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+
+"""
+ Monitor DHCP use.
+"""
+
+__version__ = '0.1'
+
+import pvl.args
+import pvl.syslog.args
+
+import pvl.verkko.db as db
+import pvl.dhcp.syslog
+import pvl.dhcp.hosts
+
+import logging, optparse
+
+log = logging.getLogger('main')
+
+# name of process in syslog
+DHCP_SYSLOG_PROG = 'dhcpd'
+
+def parse_options (argv) :
+ """
+ Parse command-line arguments.
+ """
+
+ prog = argv[0]
+
+ parser = optparse.OptionParser(
+ prog = prog,
+ usage = '%prog: [options]',
+ version = __version__,
+
+ # module docstring
+ description = __doc__,
+ )
+
+ # options
+ parser.add_option_group(pvl.args.parser(parser))
+
+ ## syslog
+ parser.add_option_group(pvl.syslog.args.parser(parser, prog=DHCP_SYSLOG_PROG))
+
+ ## XXX: networks
+ parser.add_option('--network', metavar='NET', action='append',
+ help="Filter leases by network prefix as plugin instance")
+
+ parser.add_option('--gateway', metavar='GW/IFACE', action='append',
+ help="Filter messages by gateway/interface as plugin instance")
+
+ ## hosts
+ parser.add_option('--database', metavar='URI',
+ help="Track hosts in given database")
+
+ parser.add_option('--create', action='store_true',
+ help="Initialize database")
+
+ # defaults
+ parser.set_defaults(
+
+ )
+
+ # parse
+ options, args = parser.parse_args(argv[1:])
+
+ # apply
+ pvl.args.apply(options, prog)
+
+ if not options.database :
+ parser.error("Missing required option: --database")
+
+ return options, args
+
+def main (argv) :
+ options, args = parse_options(argv)
+
+ # db
+ if not options.database :
+ log.error("No database given")
+ return 1
+
+ log.info("Open up database: %s", options.database)
+ db = pvl.verkko.db.Database(options.database)
+ hosts_db = pvl.dhcp.hosts.DHCPHostsDatabase(db)
+
+ if options.create :
+ hosts_db.create()
+
+ # syslog
+ log.info("Open up syslog...")
+ syslog = pvl.syslog.args.apply(options)
+ parser = pvl.dhcp.syslog.DHCPSyslogParser()
+
+ log.info("Enter mainloop...")
+ for source in syslog.main() :
+ # parse dhcp messages from syslog
+ for host in parser(source) :
+ log.debug("%s: %s", source, host)
+
+ hosts_db(host)
+
+ # done
+ return 0
+
+if __name__ == '__main__':
+ import sys
+
+ sys.exit(main(sys.argv))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/pvl.rrd-interfaces Tue Feb 19 22:07:40 2013 +0200
@@ -0,0 +1,266 @@
+#!/usr/bin/python
+
+"""
+ Setup symlinks for pvl.verkko-rrd -> collectd based on define host/interface names
+"""
+
+__version__ = '0.1'
+
+import shlex
+import os
+
+import pvl.args
+
+import optparse
+import logging; log = logging.getLogger('main')
+
+def hostjoin (*hosts) :
+ """
+ DNS hostname join.
+ """
+
+ return '.'.join(hosts)
+
+def hostreverse (host) :
+ """
+ Reverse hostname.
+ """
+
+ return '.'.join(reversed(host.split('.')))
+
+def collectd_interfaces (options, file, collectd_domain, collectd_plugin) :
+ """
+ Read collectd (host, type-instance, name) items, and yield (collectd-rrd, out-rrd) tuples.
+
+ file - read host/ports from file
+ collectd_domain - append given domain to collectd hostname
+ collectd_plugin - use given collectd plugin's type-instances
+ """
+
+ host = None
+
+ log.info("scanning %s/<host>.%s/%s/%s-<port>.rrd", options.collectd_rrd, collectd_domain, collectd_plugin, options.collectd_type)
+
+ for idx, line in enumerate(file, 1) :
+ line = line.rstrip()
+
+ if not line :
+ continue
+
+ # comment?
+ if line.startswith('#') :
+ continue
+
+ # line
+ parts = shlex.split(line)
+
+ if not line[0].isspace() :
+ host = parts.pop(0)
+
+ # host-spec?
+ if '=' in host :
+ collectd_host, interface_host = host.split('=')
+ else :
+ collectd_host = interface_host = host
+
+ # flip from DNS-ordering -> path-ordering
+ if options.reverse_host :
+ interface_host = hostreverse(interface_host)
+
+ # host has domain in collectd?
+ if collectd_domain :
+ collectd_host = hostjoin(collectd_host, collectd_domain)
+
+ if not parts :
+ # keep host for following lines
+ continue
+
+ port = parts.pop(0)
+
+ # possibly multiple tags..
+ for tag in parts :
+ if options.collectd_instance == 'type' :
+ type = options.collectd_type + '-' + port
+ else :
+ type = options.collectd_type
+
+ if options.collectd_instance == 'plugin' :
+ plugin = collectd_plugin + '-' + port
+ else :
+ plugin = collectd_plugin
+
+ collectd_rrd = os.path.join(options.collectd_rrd, collectd_host, plugin, type) + '.rrd'
+
+ if not os.path.exists(collectd_rrd) :
+ log.warn("%s: missing collectd rrd: %s", idx, collectd_rrd)
+ continue
+
+ # out
+ interface_rrd = os.path.join(interface_host, tag + '.rrd')
+
+ log.debug("%s: %s", interface_rrd, collectd_rrd)
+
+ yield collectd_rrd, interface_rrd
+
+def sync_links (options, links, dir) :
+ """
+ Sync given (collectd, name) symlinks in given dir.
+ """
+
+ log.info("%s", dir)
+
+ for path, name in links :
+ link = os.path.join(dir, name)
+
+ # sync
+ if os.path.exists(link) :
+ continue
+
+ log.info("%s: %s: %s", dir, name, path)
+
+ yield link, path
+
+def apply_links (options, links) :
+ """
+ Apply given symlinks
+ """
+
+ for link, path in links :
+ linkdir = os.path.dirname(link)
+
+ # do
+ if not os.path.exists(linkdir) :
+ log.warn("mkdir: %s", linkdir)
+ os.mkdir(linkdir)
+
+ print path
+
+ os.symlink(path, link)
+
+COLLECTD_RRD = '/var/lib/collectd/rrd'
+COLLECTD_PLUGIN = 'interfaces'
+COLLECTD_TYPE = 'if_octets'
+
+def parse_argv (argv, doc = __doc__) :
+ """
+ Parse command-line argv, returning (options, args).
+ """
+
+ prog = argv.pop(0)
+ args = argv
+
+ # optparse
+ parser = optparse.OptionParser(
+ prog = prog,
+ usage = '%prog: [options] [<input.txt> [...]]',
+ version = __version__,
+ description = doc,
+ )
+
+ # common
+ parser.add_option_group(pvl.args.parser(parser))
+
+ # options
+ parser.add_option('--collectd-rrd', metavar='PATH', default=COLLECTD_RRD,
+ help="Path to collectd rrd: %default")
+ parser.add_option('--collectd-plugin', metavar='PLUGIN', default=None,
+ help="Collectd plugin to use: <input>-<plugin>.txt")
+ parser.add_option('--collectd-type', metavar='TYPE', default=COLLECTD_TYPE,
+ help="Collectd type to use: %default")
+
+ # interface is by plugin, snmp is by type...
+ parser.add_option('--collectd-instance-plugin', action='store_const', dest='collectd_instance', const='plugin',
+ help="Collectd by plugin instance")
+ parser.add_option('--collectd-instance-type', action='store_const', dest='collectd_instance', const='type',
+ help="Collectd by type instance")
+
+ # hostnames
+ parser.add_option('--reverse-host', action='store_true',
+ help="Flip host.domain -> domain.host (default)")
+ parser.add_option('--no-reverse-host', action='store_false', dest='reverse_host',
+ help="Keep host.domain as host.domain")
+ parser.add_option('--domain', metavar='DOMAIN',
+ help="Append domain to collectd hostnames: <input>.txt -> <input>")
+
+ # output
+ parser.add_option('--rrd', metavar='PATH',
+ help="Output directory for .rrd symlinks: <input>.txt -> <input>/")
+ parser.add_option('--noop', action='store_true',
+ help="Scan symlinks, but do not update")
+
+ parser.set_defaults(
+ collectd_instance = 'type',
+ reverse_host = True,
+ )
+
+ # parse
+ options, args = parser.parse_args(args)
+
+ # apply
+ pvl.args.apply(options)
+
+ return options, args
+
+def main (argv) :
+ options, args = parse_argv(argv)
+
+ for txt in args :
+ # <path>/<domain>-<plugin>.txt -> <path>/<domain>-<plugin>
+ basepath, _ = os.path.splitext(txt)
+
+ # <path>/<domain>-<plugin> -> <path>/<domain>, <plugin>
+ if '-' in basepath :
+ basepath, collectd_plugin = basepath.rsplit('-', 1)
+ else :
+ collectd_plugin = None
+
+ # <path>/<domain> -> <domain>
+ _, basename = os.path.split(basepath)
+
+ # domain?
+ if options.domain is None :
+ # reverse-order hostname
+ domain = hostreverse(basename)
+ else :
+ # may be ''
+ domain = options.domain
+
+ # output dir?
+ if options.rrd :
+ rrd_domain = hostreverse(domain) if options.reverse_host else domain
+ rrd = os.path.join(options.rrd, rrd_domain)
+ else :
+ rrd = basepath
+
+ # generate links from spec
+ links = list(collectd_interfaces(options, open(txt),
+ collectd_domain = domain,
+ collectd_plugin = options.collectd_plugin or collectd_plugin or COLLECTD_PLUGIN,
+ ))
+
+ if not os.path.exists(rrd) :
+ log.warn("mkdir: %s", rrd)
+
+ if not options.noop :
+ os.mkdir(rrd)
+
+ # sync missing links
+ links = list(sync_links(options, links,
+ dir = rrd,
+ ))
+
+ # verbose
+ if not options.quiet :
+ for link, path in links :
+ print link, '->', path
+
+ # apply
+ if not options.noop :
+ apply_links(options, links)
+
+ return 0
+
+if __name__ == '__main__':
+ import sys
+
+ sys.exit(main(sys.argv))
--- a/bin/pvl.syslog-dhcp Tue Feb 19 21:50:27 2013 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-#!/usr/bin/env python
-
-"""
- Monitor DHCP use.
-"""
-
-__version__ = '0.1'
-
-import pvl.args
-import pvl.syslog.args
-
-import pvl.verkko.db as db
-import pvl.dhcp.syslog
-import pvl.dhcp.hosts
-
-import logging, optparse
-
-log = logging.getLogger('main')
-
-# name of process in syslog
-DHCP_SYSLOG_PROG = 'dhcpd'
-
-def parse_options (argv) :
- """
- Parse command-line arguments.
- """
-
- prog = argv[0]
-
- parser = optparse.OptionParser(
- prog = prog,
- usage = '%prog: [options]',
- version = __version__,
-
- # module docstring
- description = __doc__,
- )
-
- # options
- parser.add_option_group(pvl.args.parser(parser))
-
- ## syslog
- parser.add_option_group(pvl.syslog.args.parser(parser, prog=DHCP_SYSLOG_PROG))
-
- ## XXX: networks
- parser.add_option('--network', metavar='NET', action='append',
- help="Filter leases by network prefix as plugin instance")
-
- parser.add_option('--gateway', metavar='GW/IFACE', action='append',
- help="Filter messages by gateway/interface as plugin instance")
-
- ## hosts
- parser.add_option('--database', metavar='URI',
- help="Track hosts in given database")
-
- parser.add_option('--create', action='store_true',
- help="Initialize database")
-
- # defaults
- parser.set_defaults(
-
- )
-
- # parse
- options, args = parser.parse_args(argv[1:])
-
- # apply
- pvl.args.apply(options, prog)
-
- if not options.database :
- parser.error("Missing required option: --database")
-
- return options, args
-
-def main (argv) :
- options, args = parse_options(argv)
-
- # db
- if not options.database :
- log.error("No database given")
- return 1
-
- log.info("Open up database: %s", options.database)
- db = pvl.verkko.db.Database(options.database)
- hosts_db = pvl.dhcp.hosts.DHCPHostsDatabase(db)
-
- if options.create :
- hosts_db.create()
-
- # syslog
- log.info("Open up syslog...")
- syslog = pvl.syslog.args.apply(options)
- parser = pvl.dhcp.syslog.DHCPSyslogParser()
-
- log.info("Enter mainloop...")
- for source in syslog.main() :
- # parse dhcp messages from syslog
- for host in parser(source) :
- log.debug("%s: %s", source, host)
-
- hosts_db(host)
-
- # done
- return 0
-
-if __name__ == '__main__':
- import sys
-
- sys.exit(main(sys.argv))
--- a/bin/pvl.verkko-rrd-interfaces Tue Feb 19 21:50:27 2013 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,266 +0,0 @@
-#!/usr/bin/python
-
-"""
- Setup symlinks for pvl.verkko-rrd -> collectd based on define host/interface names
-"""
-
-__version__ = '0.1'
-
-import shlex
-import os
-
-import pvl.args
-
-import optparse
-import logging; log = logging.getLogger('main')
-
-def hostjoin (*hosts) :
- """
- DNS hostname join.
- """
-
- return '.'.join(hosts)
-
-def hostreverse (host) :
- """
- Reverse hostname.
- """
-
- return '.'.join(reversed(host.split('.')))
-
-def collectd_interfaces (options, file, collectd_domain, collectd_plugin) :
- """
- Read collectd (host, type-instance, name) items, and yield (collectd-rrd, out-rrd) tuples.
-
- file - read host/ports from file
- collectd_domain - append given domain to collectd hostname
- collectd_plugin - use given collectd plugin's type-instances
- """
-
- host = None
-
- log.info("scanning %s/<host>.%s/%s/%s-<port>.rrd", options.collectd_rrd, collectd_domain, collectd_plugin, options.collectd_type)
-
- for idx, line in enumerate(file, 1) :
- line = line.rstrip()
-
- if not line :
- continue
-
- # comment?
- if line.startswith('#') :
- continue
-
- # line
- parts = shlex.split(line)
-
- if not line[0].isspace() :
- host = parts.pop(0)
-
- # host-spec?
- if '=' in host :
- collectd_host, interface_host = host.split('=')
- else :
- collectd_host = interface_host = host
-
- # flip from DNS-ordering -> path-ordering
- if options.reverse_host :
- interface_host = hostreverse(interface_host)
-
- # host has domain in collectd?
- if collectd_domain :
- collectd_host = hostjoin(collectd_host, collectd_domain)
-
- if not parts :
- # keep host for following lines
- continue
-
- port = parts.pop(0)
-
- # possibly multiple tags..
- for tag in parts :
- if options.collectd_instance == 'type' :
- type = options.collectd_type + '-' + port
- else :
- type = options.collectd_type
-
- if options.collectd_instance == 'plugin' :
- plugin = collectd_plugin + '-' + port
- else :
- plugin = collectd_plugin
-
- collectd_rrd = os.path.join(options.collectd_rrd, collectd_host, plugin, type) + '.rrd'
-
- if not os.path.exists(collectd_rrd) :
- log.warn("%s: missing collectd rrd: %s", idx, collectd_rrd)
- continue
-
- # out
- interface_rrd = os.path.join(interface_host, tag + '.rrd')
-
- log.debug("%s: %s", interface_rrd, collectd_rrd)
-
- yield collectd_rrd, interface_rrd
-
-def sync_links (options, links, dir) :
- """
- Sync given (collectd, name) symlinks in given dir.
- """
-
- log.info("%s", dir)
-
- for path, name in links :
- link = os.path.join(dir, name)
-
- # sync
- if os.path.exists(link) :
- continue
-
- log.info("%s: %s: %s", dir, name, path)
-
- yield link, path
-
-def apply_links (options, links) :
- """
- Apply given symlinks
- """
-
- for link, path in links :
- linkdir = os.path.dirname(link)
-
- # do
- if not os.path.exists(linkdir) :
- log.warn("mkdir: %s", linkdir)
- os.mkdir(linkdir)
-
- print path
-
- os.symlink(path, link)
-
-COLLECTD_RRD = '/var/lib/collectd/rrd'
-COLLECTD_PLUGIN = 'interfaces'
-COLLECTD_TYPE = 'if_octets'
-
-def parse_argv (argv, doc = __doc__) :
- """
- Parse command-line argv, returning (options, args).
- """
-
- prog = argv.pop(0)
- args = argv
-
- # optparse
- parser = optparse.OptionParser(
- prog = prog,
- usage = '%prog: [options] [<input.txt> [...]]',
- version = __version__,
- description = doc,
- )
-
- # common
- parser.add_option_group(pvl.args.parser(parser))
-
- # options
- parser.add_option('--collectd-rrd', metavar='PATH', default=COLLECTD_RRD,
- help="Path to collectd rrd: %default")
- parser.add_option('--collectd-plugin', metavar='PLUGIN', default=None,
- help="Collectd plugin to use: <input>-<plugin>.txt")
- parser.add_option('--collectd-type', metavar='TYPE', default=COLLECTD_TYPE,
- help="Collectd type to use: %default")
-
- # interface is by plugin, snmp is by type...
- parser.add_option('--collectd-instance-plugin', action='store_const', dest='collectd_instance', const='plugin',
- help="Collectd by plugin instance")
- parser.add_option('--collectd-instance-type', action='store_const', dest='collectd_instance', const='type',
- help="Collectd by type instance")
-
- # hostnames
- parser.add_option('--reverse-host', action='store_true',
- help="Flip host.domain -> domain.host (default)")
- parser.add_option('--no-reverse-host', action='store_false', dest='reverse_host',
- help="Keep host.domain as host.domain")
- parser.add_option('--domain', metavar='DOMAIN',
- help="Append domain to collectd hostnames: <input>.txt -> <input>")
-
- # output
- parser.add_option('--rrd', metavar='PATH',
- help="Output directory for .rrd symlinks: <input>.txt -> <input>/")
- parser.add_option('--noop', action='store_true',
- help="Scan symlinks, but do not update")
-
- parser.set_defaults(
- collectd_instance = 'type',
- reverse_host = True,
- )
-
- # parse
- options, args = parser.parse_args(args)
-
- # apply
- pvl.args.apply(options)
-
- return options, args
-
-def main (argv) :
- options, args = parse_argv(argv)
-
- for txt in args :
- # <path>/<domain>-<plugin>.txt -> <path>/<domain>-<plugin>
- basepath, _ = os.path.splitext(txt)
-
- # <path>/<domain>-<plugin> -> <path>/<domain>, <plugin>
- if '-' in basepath :
- basepath, collectd_plugin = basepath.rsplit('-', 1)
- else :
- collectd_plugin = None
-
- # <path>/<domain> -> <domain>
- _, basename = os.path.split(basepath)
-
- # domain?
- if options.domain is None :
- # reverse-order hostname
- domain = hostreverse(basename)
- else :
- # may be ''
- domain = options.domain
-
- # output dir?
- if options.rrd :
- rrd_domain = hostreverse(domain) if options.reverse_host else domain
- rrd = os.path.join(options.rrd, rrd_domain)
- else :
- rrd = basepath
-
- # generate links from spec
- links = list(collectd_interfaces(options, open(txt),
- collectd_domain = domain,
- collectd_plugin = options.collectd_plugin or collectd_plugin or COLLECTD_PLUGIN,
- ))
-
- if not os.path.exists(rrd) :
- log.warn("mkdir: %s", rrd)
-
- if not options.noop :
- os.mkdir(rrd)
-
- # sync missing links
- links = list(sync_links(options, links,
- dir = rrd,
- ))
-
- # verbose
- if not options.quiet :
- for link, path in links :
- print link, '->', path
-
- # apply
- if not options.noop :
- apply_links(options, links)
-
- return 0
-
-if __name__ == '__main__':
- import sys
-
- sys.exit(main(sys.argv))
--- a/pvl/verkko/__init__.py Tue Feb 19 21:50:27 2013 +0200
+++ b/pvl/verkko/__init__.py Tue Feb 19 22:07:40 2013 +0200
@@ -2,4 +2,4 @@
from pvl.verkko import db
from pvl.verkko.db import Database
-__version__ = '0.5.0-dev1'
+__version__ = '0.5.0-dev2'
--- a/setup.py Tue Feb 19 21:50:27 2013 +0200
+++ b/setup.py Tue Feb 19 22:07:40 2013 +0200
@@ -6,6 +6,14 @@
from distutils.core import setup
from glob import glob
+def _globs (*pats) :
+ for pat in pats :
+ for file in glob(pat) :
+ yield file
+
+def globs (*pats) :
+ return list(_globs(*pats))
+
setup(
name = 'pvl-verkko',
version = __version__,
@@ -36,19 +44,13 @@
],
# bin
- scripts = [
- 'bin/pvl.dhcp-leases',
- 'bin/pvl.syslog-dhcp',
- 'bin/pvl.verkko-dhcp',
- 'bin/pvl.verkko-rrd',
- 'bin/pvl.verkko-rrd-interfaces',
- ],
+ scripts = globs('bin/pvl.dhcp-*', 'bin/pvl.rrd-*', 'bin/pvl.verkko-*'),
# etc, static
data_files = [
( 'etc/pvl/verkko', [ ] ),
- ( 'share/pvl/verkko/static/dhcp', glob('static/dhcp/*.css') + glob('static/dhcp/*.js')),
- ( 'share/pvl/verkko/static/rrd', glob('static/rrd/*.css') + glob('static/rrd/*.js')),
+ ( 'share/pvl/verkko/static/dhcp', globs('static/dhcp/*.css', 'static/dhcp/*.js')),
+ ( 'share/pvl/verkko/static/rrd', globs('static/rrd/*.css', 'static/rrd/*.js')),
],
)