diff --git a/icinga2.spec b/icinga2.spec index cd55ea3ad..09eb78d9a 100644 --- a/icinga2.spec +++ b/icinga2.spec @@ -419,6 +419,7 @@ exit 0 %config(noreplace) %{_sysconfdir}/%{name}/scripts/* %{_sbindir}/%{name} %{_bindir}/%{name}-migrate-config +%{_bindir}/%{name}-discover-agent %{_bindir}/%{name}-build-ca %{_bindir}/%{name}-build-key %{_bindir}/%{name}-sign-key diff --git a/pki/icinga2-setup-agent.cmake b/pki/icinga2-setup-agent.cmake index 2833e7dc0..50c8dfab4 100644 --- a/pki/icinga2-setup-agent.cmake +++ b/pki/icinga2-setup-agent.cmake @@ -27,6 +27,7 @@ if [ -n "$1" ]; then echo "Installing the certificate bundle..." tar -C $ICINGA2CONFIG/pki/agent/ -xf "$1" + chown @ICINGA2_USER@:@ICINGA2_GROUP@ $ICINGA2CONFIG/pki/agent/* || exit 1 echo "Setting up agent configuration..." cat >$ICINGA2CONFIG/features-available/agent.conf <>> parser = NetstringParser() + >>> parser.feed('3:456,') + >>> parser.results + ['456'] + >>> NetstringParser.parse('3:abc,4:defg,') + ['abc', 'defg'] + """ + + def __init__(self): + self.results = [] + self.reset() + return + + def reset(self): + self._data = '' + self._length = 0 + self._parse = self._parse_len + return + + def feed(self, s): + i = 0 + while i < len(s): + i = self._parse(s, i) + return + + def _parse_len(self, s, i): + while i < len(s): + c = s[i] + if c < '0' or '9' < c: + self._parse = self._parse_sep + break + self._length *= 10 + self._length += ord(c)-48 + i += 1 + return i + + def _parse_sep(self, s, i): + if s[i] != ':': raise SyntaxError(i) + self._parse = self._parse_data + return i+1 + + def _parse_data(self, s, i): + n = min(self._length, len(s)-i) + self._data += s[i:i+n] + self._length -= n + if self._length == 0: + self._parse = self._parse_end + return i+n + + def _parse_end(self, s, i): + if s[i] != ',': raise SyntaxError(i) + self.add_data(self._data) + self.reset() + return i+1 + + def add_data(self, data): + self.results.append(data) + return + + @classmethod + def parse(klass, s): + self = klass() + self.feed(s) + return self.results + +# Icinga 2 +# Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +import socket, ssl, pprint, sys, json + +def warning(*objs): + print(*objs, file=sys.stderr) + +if len(sys.argv) < 6: + warning("Syntax: %s " % (sys.argv[0])) + sys.exit(1) + +host = sys.argv[1] +port = int(sys.argv[2]) +certfile = sys.argv[3] +keyfile = sys.argv[4] +cafile = sys.argv[5] + +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + +# require a certificate from the server +ssl_sock = ssl.wrap_socket(s, + keyfile=keyfile, + certfile=certfile, + ca_certs=cafile, + cert_reqs=ssl.CERT_REQUIRED) + +ssl_sock.connect((host, port)) + +cn = None + +for rdn in ssl_sock.getpeercert()["subject"][0]: + if rdn[0] == "commonName": + cn = rdn[1] + +if cn == None: + warning("Agent certificate does not have a commonName.") + sys.exit(1) + +ssl_sock.write('20:{"method":"get_crs"},') + +nsp = NetstringParser() +while True: + data = ssl_sock.read() + if not data: + break + nsp.feed(data) + +if len(nsp.results) != 1: + warning("Agent returned invalid response: ", repr(nsp.results)) + sys.exit(1) + +response = json.loads(nsp.results[0]) +method = response['method'] + +if method != "push_crs": + warning("Agent did not return any check results. Make sure you're using the master certificate.") + sys.exit(1) + +params = response['params'] + +for service in params['services']: + print(\ +"""apply Service "%s" { + import "agent-service" + + assign where host.name == "%s" +} +""" % (service, cn)) + +# note that closing the SSLSocket will also close the underlying socket +ssl_sock.close()