summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: c929feb)
raw | patch | inline | side by side (parent: c929feb)
author | Sebastian Harl <sh@tokkee.org> | |
Thu, 4 Dec 2014 19:55:00 +0000 (20:55 +0100) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Thu, 4 Dec 2014 19:55:00 +0000 (20:55 +0100) |
The plugin uses libfacter from the cfacter project. libfacter is a C++
library, so the plugin is implemented in C++ as well using a small shim to
talk to SysDB.
library, so the plugin is implemented in C++ as well using a small shim to
talk to SysDB.
configure.ac | patch | blob | history | |
src/Makefile.am | patch | blob | history | |
src/plugins/backend/facter.cc | [new file with mode: 0644] | patch | blob |
diff --git a/configure.ac b/configure.ac
index 10c18c9add8aa80b8e2ff60fb132958722242d50..088a4b59fc994ad313dbd9540b1fc70901808b6d 100644 (file)
--- a/configure.ac
+++ b/configure.ac
done
fi
+dnl We need C++11 for facter.
+AC_MSG_CHECKING([whether $CXX accepts -std=c++11])
+if test_cxx_flags -std=c++11; then
+ CXXFLAGS="$CXXFLAGS -std=c++11"
+ AC_MSG_RESULT([yes])
+else
+ # Oh well, the header check will determine if it works anyway.
+ AC_MSG_RESULT([no])
+fi
+
dnl Hardening (see e.g. http://wiki.debian.org/Hardening for a motivation).
AC_DEFINE([_FORTIFY_SOURCE], 2,
[Define to enable protection against static sized buffer overflows.])
AC_SUBST([READLINE_CFLAGS])
AM_CONDITIONAL([BUILD_CLIENT], test "x$readline_support" != "no")
+AC_LANG_PUSH(C++)
+AC_ARG_WITH([libfacter],
+ [AS_HELP_STRING([--with-libfacter], [libfacter support (default: auto)])],
+ [with_libfacter="$withval"],
+ [with_libfacter="yes"])
+if test "x$with_libfacter" = "xyes" || test "x$with_libfacter" = "xauto"; then
+ AC_CHECK_HEADERS([facter/facts/collection.hpp],
+ [have_libfacter="yes"],
+ [have_libfacter="no (facter/facts/collection.hpp not found)"])
+else if test "x$with_libfacter" = "xno"; then
+ have_libfacter="$with_libfacter (disabled on command-line)"
+else
+ AC_MSG_ERROR([Invalid value for option --with-libfacter=$with_libfacter (expected "yes", "no", or "auto")])
+fi; fi
+if test "x$have_libfacter" = "xyes"; then
+ AC_MSG_CHECKING([for facter::facts::collection in -lfacter])
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[[ #include <facter/facts/collection.hpp> ]]],
+ [[[
+ facter::facts::collection facts;
+ facts.add_default_facts();
+ ]]]
+ )],
+ [TEST_LIBS=$TEST_LIBS -lfacter],
+ [have_libfacter="yes"],
+ [have_libfacter="no (libfacter not found)"])
+ AC_MSG_RESULT([$have_libfacter])
+fi
+AC_LANG_POP(C++)
+
AC_ARG_WITH([librrd],
[AS_HELP_STRING([--with-librrd], [librrd support (default: auto)])],
[with_librrd="$withval"],
AM_CONDITIONAL([INTEGRATION_TESTING], test "x$integration_tests" = "xyes")
dnl Plugin checks.
+facter_default=$have_libfacter
+if test "x$facter_default" != "xyes"; then
+ facter_default="no (requires libfacter)"
+fi
puppet_storeconfigs_default=$with_libdbi
if test "x$puppet_storeconfigs_default" != "xyes"; then
puppet_storeconfigs_default="no (requires libdbi)"
AC_SDB_PLUGIN_INIT
AC_SDB_PLUGIN([collectd-unixsock], [yes],
[backend accessing the system statistics collection daemon])
+AC_SDB_PLUGIN([facter], [$facter_default],
+ [backend retrieving local facter facts])
AC_SDB_PLUGIN([mk-livestatus], [yes],
[backend accessing Nagios/Icinga/Shinken using MK Livestatus])
AC_SDB_PLUGIN([puppet-storeconfigs], [$puppet_storeconfigs_default],
AC_MSG_RESULT()
AC_MSG_RESULT([ Backends:])
AC_MSG_RESULT([ collectd::unixsock: . . . . $enable_collectd_unixsock])
+AC_MSG_RESULT([ facter . . . . . . . . . . $enable_facter])
AC_MSG_RESULT([ mk-livestatus: . . . . . . $enable_mk_livestatus])
AC_MSG_RESULT([ puppet::storeconfigs: . . . $enable_puppet_storeconfigs])
AC_MSG_RESULT()
diff --git a/src/Makefile.am b/src/Makefile.am
index 1583217d9d79c8ca0c61827be20daf6449922da6..3472b6f527ed55068670db2cd99069e2f40ef0c7 100644 (file)
--- a/src/Makefile.am
+++ b/src/Makefile.am
sysdbd_DEPENDENCIES += plugins/backend/collectd/unixsock.la
endif
+if BUILD_PLUGIN_FACTER
+pkgbackendlib_LTLIBRARIES += plugins/backend/facter.la
+plugins_backend_facter_la_SOURCES = plugins/backend/facter.cc
+plugins_backend_facter_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version -lfacter
+sysdbd_LDADD += -dlopen plugins/backend/facter.la
+sysdbd_DEPENDENCIES += plugins/backend/facter.la
+endif
+
if BUILD_PLUGIN_MKLIVESTATUS
pkgbackendlib_LTLIBRARIES += plugins/backend/mk-livestatus.la
plugins_backend_mk_livestatus_la_SOURCES = plugins/backend/mk-livestatus.c
diff --git a/src/plugins/backend/facter.cc b/src/plugins/backend/facter.cc
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * SysDB - src/plugins/backend/facter.cc
+ * Copyright (C) 2014 Sebastian 'tokkee' Harl <sh@tokkee.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "sysdb.h"
+#include "core/plugin.h"
+#include "core/store.h"
+#include "utils/error.h"
+
+#include <facter/facts/collection.hpp>
+#include <iostream>
+#include <sstream>
+
+static const char *hostname;
+static sdb_time_t now;
+
+static bool
+fact_iter(std::string const &k, facter::facts::value const *v)
+{
+ /* Don't ignore hidden values for now; they also provide the old,
+ * non-structured facts. */
+
+ std::stringstream ss;
+ v->write(ss, false);
+ std::string s = ss.str();
+ char *str = const_cast<char *>(s.c_str());
+
+ /* Ignore non-structured facts for now. */
+ if (str[0] == '{')
+ return true;
+
+ sdb_data_t value = { SDB_TYPE_STRING, { .string = str } };
+ sdb_store_attribute(hostname, k.c_str(), &value, now);
+ return true;
+} /* fact_iter */
+
+/* SysDB interface */
+extern "C" {
+
+ SDB_PLUGIN_MAGIC;
+
+ static int
+ facter_collect(sdb_object_t __attribute__((unused)) *user_data)
+ {
+ facter::facts::collection facts;
+
+ /* XXX: this may execute other programs; can we be sure that works
+ * reasonably well in a multi-threaded program? */
+ facts.add_default_facts();
+ facts.add_external_facts();
+
+ now = sdb_gettime();
+ facter::facts::value const *v = facts["fqdn"];
+ std::stringstream ss;
+ v->write(ss, false);
+ std::string s = ss.str();
+ hostname = s.c_str();
+
+ sdb_store_host(hostname, now);
+ facts.each(fact_iter);
+ sdb_log(SDB_LOG_DEBUG, "facter backend: Processed %zu facts "
+ "for host '%s'", facts.size(), hostname);
+ return 0;
+ } /* main */
+
+ int
+ sdb_module_init(sdb_plugin_info_t *info)
+ {
+ sdb_plugin_set_info(info, SDB_PLUGIN_INFO_DESC,
+ "backend retrieving local facter facts");
+ sdb_plugin_set_info(info, SDB_PLUGIN_INFO_COPYRIGHT,
+ "Copyright (C) 2014 Sebastian 'tokkee' Harl <sh@tokkee.org>");
+ sdb_plugin_set_info(info, SDB_PLUGIN_INFO_LICENSE, "BSD");
+ sdb_plugin_set_info(info, SDB_PLUGIN_INFO_VERSION, SDB_VERSION);
+ sdb_plugin_set_info(info, SDB_PLUGIN_INFO_PLUGIN_VERSION, SDB_VERSION);
+
+ sdb_plugin_register_collector("main", facter_collect,
+ /* interval */ NULL, /* user_data */ NULL);
+ return 0;
+ } /* sdb_module_init */
+
+} /* extern C */
+
+/* vim: set tw=78 sw=4 ts=4 noexpandtab : */
+