terom@187: #!/usr/bin/python terom@187: terom@187: """ terom@187: Setup symlinks for pvl.verkko-rrd -> collectd based on define host/interface names terom@187: """ terom@187: terom@187: __version__ = '0.1' terom@187: terom@187: import os terom@187: terom@187: import pvl.args terom@235: import pvl.rrd.hosts terom@235: from pvl.rrd.hosts import hostreverse terom@187: terom@187: import optparse terom@187: import logging; log = logging.getLogger('main') terom@187: terom@187: COLLECTD_RRD = '/var/lib/collectd/rrd' terom@187: COLLECTD_PLUGIN = 'interfaces' terom@187: COLLECTD_TYPE = 'if_octets' terom@187: terom@187: def parse_argv (argv, doc = __doc__) : terom@187: """ terom@187: Parse command-line argv, returning (options, args). terom@187: """ terom@187: terom@187: prog = argv.pop(0) terom@187: args = argv terom@187: terom@187: # optparse terom@187: parser = optparse.OptionParser( terom@187: prog = prog, terom@187: usage = '%prog: [options] [ [...]]', terom@187: version = __version__, terom@187: description = doc, terom@187: ) terom@187: terom@187: # common terom@187: parser.add_option_group(pvl.args.parser(parser)) terom@187: terom@187: # options terom@187: parser.add_option('--collectd-rrd', metavar='PATH', default=COLLECTD_RRD, terom@187: help="Path to collectd rrd: %default") terom@188: parser.add_option('--collectd-plugin', metavar='PLUGIN', default=None, terom@188: help="Collectd plugin to use: -.txt") terom@187: parser.add_option('--collectd-type', metavar='TYPE', default=COLLECTD_TYPE, terom@187: help="Collectd type to use: %default") terom@187: terom@195: # interface is by plugin, snmp is by type... terom@195: parser.add_option('--collectd-instance-plugin', action='store_const', dest='collectd_instance', const='plugin', terom@195: help="Collectd by plugin instance") terom@195: parser.add_option('--collectd-instance-type', action='store_const', dest='collectd_instance', const='type', terom@195: help="Collectd by type instance") terom@195: terom@187: # hostnames terom@187: parser.add_option('--reverse-host', action='store_true', terom@187: help="Flip host.domain -> domain.host (default)") terom@187: parser.add_option('--no-reverse-host', action='store_false', dest='reverse_host', terom@187: help="Keep host.domain as host.domain") terom@187: parser.add_option('--domain', metavar='DOMAIN', terom@187: help="Append domain to collectd hostnames: .txt -> ") terom@187: terom@187: # output terom@187: parser.add_option('--rrd', metavar='PATH', terom@187: help="Output directory for .rrd symlinks: .txt -> /") terom@187: parser.add_option('--noop', action='store_true', terom@187: help="Scan symlinks, but do not update") terom@187: terom@187: parser.set_defaults( terom@195: collectd_instance = 'type', terom@195: reverse_host = True, terom@187: ) terom@187: terom@187: # parse terom@187: options, args = parser.parse_args(args) terom@187: terom@187: # apply terom@187: pvl.args.apply(options) terom@187: terom@187: return options, args terom@187: terom@235: def sync_links (options, links, dir) : terom@235: """ terom@235: Sync given (collectd, name) symlinks in given dir. terom@235: """ terom@235: terom@235: log.info("%s", dir) terom@235: terom@235: for path, name in links : terom@235: link = os.path.join(dir, name) terom@235: terom@235: # sync terom@235: if os.path.exists(link) : terom@235: continue terom@235: terom@235: log.info("%s: %s: %s", dir, name, path) terom@235: terom@235: yield link, path terom@235: terom@235: def apply_links (options, links) : terom@235: """ terom@235: Apply given symlinks terom@235: """ terom@235: terom@235: for link, path in links : terom@235: linkdir = os.path.dirname(link) terom@235: terom@235: # do terom@235: if not os.path.exists(linkdir) : terom@235: log.warn("mkdir: %s", linkdir) terom@235: os.mkdir(linkdir) terom@235: terom@235: print path terom@235: terom@235: os.symlink(path, link) terom@235: terom@187: def main (argv) : terom@187: options, args = parse_argv(argv) terom@187: terom@187: for txt in args : terom@188: # /-.txt -> /- terom@188: basepath, _ = os.path.splitext(txt) terom@188: terom@188: # /- -> /, terom@188: if '-' in basepath : terom@188: basepath, collectd_plugin = basepath.rsplit('-', 1) terom@188: else : terom@188: collectd_plugin = None terom@188: terom@188: # / -> terom@188: _, basename = os.path.split(basepath) terom@189: terom@189: # domain? terom@187: if options.domain is None : terom@188: # reverse-order hostname terom@188: domain = hostreverse(basename) terom@187: else : terom@187: # may be '' terom@187: domain = options.domain terom@187: terom@189: # output dir? terom@189: if options.rrd : terom@189: rrd_domain = hostreverse(domain) if options.reverse_host else domain terom@189: rrd = os.path.join(options.rrd, rrd_domain) terom@189: else : terom@189: rrd = basepath terom@189: terom@187: # generate links from spec terom@235: links = list(pvl.rrd.hosts.collectd_interfaces(options, open(txt), terom@187: collectd_domain = domain, terom@188: collectd_plugin = options.collectd_plugin or collectd_plugin or COLLECTD_PLUGIN, terom@187: )) terom@189: terom@189: if not os.path.exists(rrd) : terom@189: log.warn("mkdir: %s", rrd) terom@189: terom@189: if not options.noop : terom@189: os.mkdir(rrd) terom@187: terom@187: # sync missing links terom@187: links = list(sync_links(options, links, terom@189: dir = rrd, terom@187: )) terom@187: terom@187: # verbose terom@187: if not options.quiet : terom@187: for link, path in links : terom@187: print link, '->', path terom@187: terom@187: # apply terom@187: if not options.noop : terom@187: apply_links(options, links) terom@187: terom@187: return 0 terom@187: terom@187: if __name__ == '__main__': terom@187: import sys terom@187: terom@187: sys.exit(main(sys.argv))