pvl.hosts: support foo:bar = ... extension fields
#!/usr/bin/python
"""
Setup symlinks for pvl.verkko-rrd -> collectd based on define host/interface names
"""
__version__ = '0.1'
import os
import pvl.args
import pvl.rrd.hosts
from pvl.rrd.hosts import hostreverse
import optparse
import logging; log = logging.getLogger('main')
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 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)
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(pvl.rrd.hosts.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))