summaryrefslogtreecommitdiffstats
path: root/src/lib/Server/Admin/__init__.py
blob: 41c485d6cd56c0a7243c3a13b2d78286c8909577 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
__revision__ = '$Revision$'

__all__ = [
        'Backup',
        'Bundle',
        'Client',
        'Compare',
        'Group',
        'Init',
        'Minestruct',
        'Mode',
        'Perf',
        'Pull',
        'Query',
        'Reports',
        'Snapshots',
        'Tidy',
        'Viz',
        'Xcmd'
        ]

import logging
import lxml.etree
import sys

import Bcfg2.Server.Core
import Bcfg2.Options
# Compatibility import
from Bcfg2.Bcfg2Py3k import ConfigParser


class ModeOperationError(Exception):
    pass


class Mode(object):
    """Help message has not yet been added for mode."""
    __shorthelp__ = 'Shorthelp not defined yet'
    __longhelp__ = 'Longhelp not defined yet'
    __args__ = []

    def __init__(self, configfile):
        self.configfile = configfile
        self.__cfp = False
        self.log = logging.getLogger('Bcfg2.Server.Admin.Mode')

    def getCFP(self):
        if not self.__cfp:
            self.__cfp = ConfigParser.ConfigParser()
            self.__cfp.read(self.configfile)
        return self.__cfp

    cfp = property(getCFP)

    def __call__(self, args):
        pass

    def errExit(self, emsg):
        print(emsg)
        raise SystemExit(1)

    def get_repo_path(self):
        """Return repository path"""
        return self.cfp.get('server', 'repository')

    def load_stats(self, client):
        stats = lxml.etree.parse("%s/etc/statistics.xml" %
                                (self.get_repo_path()))
        hostent = stats.xpath('//Node[@name="%s"]' % client)
        if not hostent:
            self.errExit("Could not find stats for client %s" % (client))
        return hostent[0]

    def print_table(self, rows, justify='left', hdr=True, vdelim=" ", padding=1):
        """Pretty print a table

        rows - list of rows ([[row 1], [row 2], ..., [row n]])
        hdr - if True the first row is treated as a table header
        vdelim - vertical delimiter between columns
        padding - # of spaces around the longest element in the column
        justify - may be left,center,right

        """
        hdelim = "="
        justify = {'left': str.ljust,
                   'center': str.center,
                   'right': str.rjust}[justify.lower()]

        """
        Calculate column widths (longest item in each column
        plus padding on both sides)

        """
        cols = list(zip(*rows))
        colWidths = [max([len(str(item)) + 2 * padding for \
                          item in col]) for col in cols]
        borderline = vdelim.join([w * hdelim for w in colWidths])

        # Print out the table
        print(borderline)
        for row in rows:
            print(vdelim.join([justify(str(item), width) for \
                               (item, width) in zip(row, colWidths)]))
            if hdr:
                print(borderline)
                hdr = False


class MetadataCore(Mode):
    """Base class for admin-modes that handle metadata."""
    def __init__(self, configfile, usage, pwhitelist=None, pblacklist=None):
        Mode.__init__(self, configfile)
        options = {'plugins': Bcfg2.Options.SERVER_PLUGINS,
                   'configfile': Bcfg2.Options.CFILE,
                   'encoding': Bcfg2.Options.ENCODING}
        setup = Bcfg2.Options.OptionParser(options)
        setup.hm = usage
        setup.parse(sys.argv[1:])
        if pwhitelist is not None:
            setup['plugins'] = [x for x in setup['plugins']
                                if x in pwhitelist]
        elif pblacklist is not None:
            setup['plugins'] = [x for x in setup['plugins']
                                if x not in pblacklist]
        try:
            self.bcore = Bcfg2.Server.Core.Core(self.get_repo_path(),
                                                setup['plugins'],
                                                'foo', setup['encoding'])
        except Bcfg2.Server.Core.CoreInitError:
            msg = sys.exc_info()[1]
            self.errExit("Core load failed because %s" % msg)
        self.bcore.fam.handle_events_in_interval(5)
        self.metadata = self.bcore.metadata


class StructureMode(MetadataCore):
    pass