# -*- coding: utf-8 -*- # vim: set et sts=4: import collections import ConfigParser from optparse import OptionParser, Option import sys import lxml.etree import sqlite3 from slapos.proxy.db_version import DB_VERSION class Parser(OptionParser): """ Parse all arguments. """ def __init__(self, usage=None, version=None): """ Initialize all options possibles. """ OptionParser.__init__(self, usage=usage, version=version, option_list=[ Option("-u", "--database-uri", type=str, help="URI for sqlite database"), Option('--show-instances', help="View instance information", default=False, action="store_true"), Option('--show-params', help="View published parameters", default=False, action="store_true"), Option('--show-network', help="View network information", default=False, action="store_true"), Option('--show-all', help="View all information", default=False, action="store_true"), ]) def check_args(self): """ Check arguments """ (options, args) = self.parse_args() if len(args) < 1: self.error("Incorrect number of arguments") return options, args[0] class Config: def setConfig(self, option_dict, configuration_file_path): """ Set options given by parameters. """ # Set options parameters for option, value in option_dict.__dict__.items(): setattr(self, option, value) # Load configuration file configuration_parser = ConfigParser.SafeConfigParser() configuration_parser.read(configuration_file_path) # Merges the arguments and configuration for section in ("slapproxy", "slapos"): configuration_dict = dict(configuration_parser.items(section)) for key in configuration_dict: if not getattr(self, key, None): setattr(self, key, configuration_dict[key]) if not self.database_uri: raise ValueError('database-uri is required.') tbl_computer = 'computer' + DB_VERSION tbl_software = 'software' + DB_VERSION tbl_partition = 'partition' + DB_VERSION tbl_partition_network = 'partition_network' + DB_VERSION tbl_slave = 'slave' + DB_VERSION null_str = u"-" def print_table(qry, tablename, skip=None): if skip is None: skip = set() columns = [c[0] for c in qry.description if c[0] not in skip] rows = [] for row in qry.fetchall(): line = {} for col in columns: val = row[col] if val is None: val = null_str line[col] = val.strip() rows.append(line) max_width = {col: len(col) for col in columns} for row in rows: for col in columns: val = row[col] max_width[col] = max(max_width[col], len(val) if val else 0) hdr = [col.center(max_width[col]) for col in columns] print if rows: print 'table %s:' % tablename, else: print 'table %s: empty' % tablename return if skip: print 'skipping %s' % ', '.join(skip) else: print print ' | '.join(hdr) print '-+-'.join('-'*len(h) for h in hdr) for row in rows: cells = [row[col].ljust(max_width[col]) for col in columns] print ' | '.join(cells) def print_params(conn): cur = conn.cursor() print qry = cur.execute("SELECT reference, partition_reference, software_type, connection_xml FROM %s" % tbl_partition) for row in qry.fetchall(): if not row['connection_xml']: continue xml = str(row['connection_xml']) print '%s: %s (type %s)' % (row['reference'], row['partition_reference'], row['software_type']) instance = lxml.etree.fromstring(xml) for parameter in list(instance): name = parameter.get('id') text = parameter.text if text and name in ('ssh-key', 'ssh-public-key'): text = text[:20] + '...' + text[-20:] print ' %s = %s' % (name, text) print def print_computer_table(conn): cur = conn.cursor() qry = cur.execute("SELECT * FROM %s" % tbl_computer) print_table(qry, tbl_computer) def print_software_table(conn): cur = conn.cursor() qry = cur.execute("SELECT * FROM %s" % tbl_software) print_table(qry, tbl_software) def print_partition_table(conn): cur = conn.cursor() qry = cur.execute("SELECT * FROM %s WHERE slap_state<>'free'" % tbl_partition) print_table(qry, tbl_partition, skip=['xml', 'connection_xml', 'slave_instance_list']) def print_slave_table(conn): cur = conn.cursor() qry = cur.execute("SELECT * FROM %s" % tbl_slave) print_table(qry, tbl_slave, skip=['connection_xml']) def print_tables(conn): print_computer_table(conn) print_software_table(conn) print_partition_table(conn) print_slave_table(conn) def print_network(conn): print cur = conn.cursor() addr = collections.defaultdict(list) qry = cur.execute(""" SELECT * FROM %s WHERE partition_reference NOT IN ( SELECT reference FROM %s WHERE slap_state='free') """ % (tbl_partition_network, tbl_partition)) for row in qry: addr[row['partition_reference']].append(row['address']) for partition_reference in sorted(addr.keys()): addresses = addr[partition_reference] print '%s: %s' % (partition_reference, ', '.join(addresses)) def run(config): conn = sqlite3.connect(config.database_uri) conn.row_factory = sqlite3.Row fn = [] if config.show_all or config.show_instances: fn.append(print_tables) if config.show_all or config.show_params: fn.append(print_params) if config.show_all or config.show_network: fn.append(print_network) if fn: for f in fn: f(conn) else: print 'usage: %s [ --show-params | --show-network | --show-instances | --show-all ]' % sys.argv[0] def main(): "Run default configuration." usage = "usage: %s [options] CONFIGURATION_FILE" % sys.argv[0] try: # Parse arguments config = Config() config.setConfig(*Parser(usage=usage).check_args()) run(config) return_code = 0 except SystemExit, err: # Catch exception raise by optparse return_code = err sys.exit(return_code)