summaryrefslogtreecommitdiffstats
path: root/src/lib/Bcfg2/Server/Plugins/NagiosGen.py
blob: d3c38ef192d01a5082e1d254196aa38c06bd4e42 (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
'''This module implements a Nagios configuration generator'''

import os
import re
import sys
import glob
import socket
from Bcfg2.Server.Plugin import Plugin, Generator, StructFile, \
    PluginExecutionError


class NagiosGen(Plugin, Generator):
    """ NagiosGen is a Bcfg2 plugin that dynamically generates Nagios
    configuration file based on Bcfg2 data. """
    __author__ = 'bcfg-dev@mcs.anl.gov'
    line_fmt = '\t%-32s %s'

    def __init__(self, core):
        Plugin.__init__(self, core)
        Generator.__init__(self)
        self.config = \
            StructFile(os.path.join(self.data, 'config.xml'),
                       should_monitor=True, create=self.name)
        self.Entries = {
            'Path': {'/etc/nagiosgen.status': self.createhostconfig,
                     '/etc/nagios/conf.d/bcfg2.cfg': self.createserverconfig}}

        self.client_attrib = {'encoding': 'ascii',
                              'owner': 'root',
                              'group': 'root',
                              'type': 'file',
                              'mode': '0400'}
        self.server_attrib = {'encoding': 'ascii',
                              'owner': 'nagios',
                              'group': 'nagios',
                              'type': 'file',
                              'mode': '0440'}

    def createhostconfig(self, entry, metadata):
        """Build host specific configuration file."""
        try:
            host_address = socket.getaddrinfo(metadata.hostname, None)[0][4][0]
        except socket.error:
            self.logger.error()
            raise PluginExecutionError("Failed to find IP address for %s" %
                                       metadata.hostname)
        host_groups = [grp for grp in metadata.groups
                       if os.path.isfile('%s/%s-group.cfg' %
                                         (self.data, grp))] + \
                      [bundle for bundle in metadata.bundles
                       if os.path.isfile('%s/%s-bundle.cfg' %
                                         (self.data, bundle))]
        host_config = ['define host {',
                       self.line_fmt % ('host_name', metadata.hostname),
                       self.line_fmt % ('alias', metadata.hostname),
                       self.line_fmt % ('address', host_address)]

        if host_groups:
            host_config.append(self.line_fmt % ("hostgroups",
                                                ",".join(sorted(host_groups))))

        # read the config
        xtra = dict()
        for el in self.config.Match(metadata):
            if el.tag == 'Option':
                xtra[el.get("name")] = el.text

        if xtra:
            host_config.extend([self.line_fmt % (opt, val)
                                for opt, val in list(xtra.items())])
        if 'use' not in xtra:
            host_config.append(self.line_fmt % ('use', 'default'))

        host_config.append('}')
        entry.text = "%s\n" % "\n".join(host_config)
        for (key, value) in list(self.client_attrib.items()):
            entry.attrib.__setitem__(key, value)
        fname = os.path.join(self.data, metadata.hostname + "-host.cfg")
        try:
            open(fname, 'w').write(entry.text)
        except OSError:
            err = sys.exc_info()[1]
            self.logger.error("Failed to write %s: %s" % (fname, err))

    def createserverconfig(self, entry, _):
        """Build monolithic server configuration file."""
        host_configs = glob.glob(os.path.join(self.data, '*-host.cfg'))
        group_configs = glob.glob(os.path.join(self.data, '*-group.cfg')) + \
            glob.glob(os.path.join(self.data, '*-bundle.cfg'))
        host_data = []
        group_data = []
        for host in host_configs:
            host_data.append(open(host, 'r').read())

        group_list = []
        for line in "\n".join(host_data).splitlines():
            # only include those groups which are actually used
            if "hostgroup" in line:
                group_list += line.split()[1].split(',')

        group_list = list(set(group_list))

        for group in group_configs:
            group_name = re.sub("(-group.cfg|.*/(?=[^/]+))", "", group)
            if group_name in group_list:
                groupfile = open(group, 'r')
                group_data.append(groupfile.read())
                groupfile.close()

        entry.text = "%s\n\n%s" % ("\n".join(group_data), "\n".join(host_data))
        for (key, value) in list(self.server_attrib.items()):
            entry.attrib.__setitem__(key, value)
        fname = os.path.join(self.data, "nagiosgen.cfg")
        try:
            open(fname, 'w').write(entry.text)
        except OSError:
            err = sys.exc_info()[1]
            self.logger.error("Failed to write %s: %s" % (fname, err))