
pallet.crate.nagios.clj Maven / Gradle / Ivy
The newest version!
(ns pallet.crate.nagios
"Crate to install and configure nagios 3.
`nagios` installs nagios from packages. Functions are provided for generating
the nagios configuration files.
See the `nagios-config` crate for configuring nodes to be monitored by nagios.
It is intended that the nagios server node and all montiored nodes are
specified in any `lift` or `converge` operation used to configure any of these
nodes.
Tested on ubuntu 10.04"
(:require
[pallet.action :as action]
[pallet.action.package :as package]
[pallet.action.remote-file :as remote-file]
[pallet.action.user :as user]
[pallet.argument :as argument]
[pallet.compute :as compute]
[pallet.parameter :as parameter]
[pallet.phase :as phase]
[pallet.session :as session]
[clojure.string :as string]))
;; slingshot version compatibility
(try
(use '[slingshot.slingshot :only [throw+]])
(catch Exception _
(use '[slingshot.core :only [throw+]])))
(defn nagios-hostname
"Return the nagios hostname for a node"
[node]
;; this should match (session/safe-name session)
;; for things to work well
(format
"%s%s" (compute/group-name node) (session/safe-id (compute/id node))))
(def hostgroup-fmt "
define hostgroup {
hostgroup_name %s
alias %s
members %s
}
")
(def host-fmt "
define host {
use %s
host_name %s
alias %s
address %s
}
")
(def service-fmt "
define service {
use %s
hostgroup_name %s
service_description %s
check_command %s
notification_interval %s
}
")
(def servicegroup-fmt "
define servicegroup {
servicegroup_name %s
}
")
(def host-service-fmt "
define service {
use %s
host_name %s
service_description %s
check_command %s
notification_interval %s
servicegroups %s
}
")
(def command-fmt "
define command {
command_name %s
command_line %s
}
")
(defmulti property-fmt
(fn [value]
(cond
(string? value) :default
(seq? value) :seq
(vector? value) :seq
:else :default)))
(defmethod property-fmt :seq
[value]
(string/join "," (map name value)))
(defmethod property-fmt :default
[value]
(str value))
(defn define
"Define a nagios object"
[object-type properties]
(format
"define %s{\n%s\n}\n"
object-type
(string/join
\newline
(map
#(format " %s %s" (name (first %)) (property-fmt (second %)))
properties))))
(defn define-contact [properties]
(define "contact"
(select-keys
properties
[:contact_name :alias :service_notification_period
:host_notification_period :service_notification_options
:host_notification_options :service_notification_commands
:host_notification_commands :email :contactgroups])))
(defn define-contactgroup [properties]
(define "contactgroup"
(select-keys
properties
[:contactgroup_name :alias :members :contactgroup_members])))
(def ^{:private true}
remote-file* (action/action-fn remote-file/remote-file-action))
(action/def-collected-action contact
"Define a contact for nagios"
[session options]
(str
(remote-file*
session
"/etc/nagios3/conf.d/pallet-contacts.cfg" :action :delete :force true)
(remote-file*
session
"/etc/nagios3/conf.d/pallet-contacts.cfg"
:owner "root"
:content (string/join
\newline
(concat
(map (comp define-contact first) options)
(map (comp
define-contactgroup
#(hash-map :contactgroup_name %))
(distinct
(map
name
(apply
concat
(map (comp :contactgroups first) options))))))))))
(defn hostgroup
[name alias members]
(format hostgroup-fmt name alias (string/join "," members)))
(defn host
([ip hostname] (host ip hostname "generic-host"))
([ip hostname template]
(format host-fmt template hostname hostname ip)))
(defn define-servicegroup
"Define a nagios servicegroup"
[properties]
(when-not
(every? properties #{:servicegroup_name})
(throw+
{:type :invalid-servicegroup-definiton
:message (format "Invalid servicegroup definition : %s" properties)}))
(define "servicegroup"
(select-keys
properties
[:servicegroup_name :alias :members :servicegroup_members :notes
:notes_url :action_url])))
(defn define-service
"Define a nagios service"
[properties]
(when-not
(every? properties #{:service_description :host_name :check_command})
(throw+
{:type :invalid-service-definiton
:message (format "Invalid service definition : %s" properties)}))
(define "service"
(select-keys
properties
[:use :host_name :hostgroup_name :service_description :display_name
:servicegroups :is_volatile :check_command :initial_state
:max_check_attempts :check_interval :retry_interval :active_checks_enabled
:passive_checks_enabled :check_period :obsess_over_service
:check_freshness :freshness_threshold :event_handler
:event_handler_enabled :low_flap_threshold :high_flap_threshold
:flap_detection_enabled :flap_detection_options :process_perf_data
:retain_status_information :retain_nonstatus_information
:notification_interval :first_notification_delay :notification_period
:notification_options :notifications_enabled :contacts :contact_groups
:stalking_options :notes :notes_url :action_url :icon_image
:icon_image_alt])))
(defn host-service
[hostname {:keys [template check_command service_description
notification_interval service_group]
:as options}]
(define-service
(-> (merge
{:use "generic-service"
:notification_interval 0}
options)
(assoc :host_name hostname))))
(defn config-for-node
[session node]
(parameter/get-for session
[:nagios :host-services (keyword (nagios-hostname node))] nil))
(defn config-for-unmanaged-node
[session unmanaged-node]
(parameter/get-for session
[:nagios :host-services (keyword (:name unmanaged-node))] nil))
(defn unmanaged-host
"Add an unmanaged host to a nagios server. Beware name conflicts between
managed and unmanged servers are not detected."
[session ip name]
(parameter/update-for
session [:nagios :hosts]
(fn [m]
(distinct (conj (or m []) {:ip ip :name name})))))
(action/def-bash-action hosts
"Define nagios hosts"
[session]
(str
(remote-file*
session
"/etc/nagios3/conf.d/pallet-host-*.cfg" :action :delete :force true)
(string/join
\newline
(for [node (filter #(config-for-node session %) (:all-nodes session))
:let [hostname (nagios-hostname node)]]
(remote-file*
session
(format "/etc/nagios3/conf.d/pallet-host-%s.cfg" hostname)
:owner "root"
:content (str
(host
(compute/primary-ip node) hostname)
(string/join
\newline
(map
(partial host-service hostname)
(config-for-node session node)))))))
(string/join
\newline
(for [node (filter
#(config-for-unmanaged-node session %)
(parameter/get-for session [:nagios :hosts] nil))
:let [hostname (:name node)]]
(remote-file*
session
(format "/etc/nagios3/conf.d/pallet-host-%s.cfg" hostname)
:owner "root"
:content (str
(host (:ip node) hostname)
(string/join
\newline
(map
(partial host-service hostname)
(config-for-unmanaged-node session node)))))))))
(defn servicegroup
"Configure nagios servicegroup monitoring.
:servicegroup_name servicegroup name
:alias alias
:members services
:servicegroup_members servicegroups
:notes note string
:notes_url url
:action_url url"
[session options]
(parameter/update-for
session [:nagios :servicegroups (keyword (:servicegroup_name options))]
(fn [x]
(merge-with
conj
(merge (or x {}) (dissoc options :members :servicegroup_members))
(select-keys options [:members :servicegroup_members])))))
(action/def-bash-action servicegroups
[session]
(str
(remote-file*
session
"/etc/nagios3/conf.d/pallet-servicegroups.cfg"
:owner "root"
:content
(string/join
\newline
(map
(comp
define-servicegroup
#(parameter/get-for
session
[:nagios :servicegroups %]
{:servicegroup_name (name %)}))
(distinct
(map
keyword
(filter
identity
(apply
concat
(apply
concat
(map
#(map :servicegroups %)
(concat
(map #(config-for-node session %) (:all-nodes session))
(map #(config-for-unmanaged-node session %)
(parameter/get-for
session [:nagios :hosts] nil))))))))))))))
(defn command*
[session [command-name command-line]]
(remote-file*
session
(format "/etc/nagios3/conf.d/pallet-command-%s.cfg" (name command-name))
:owner "root"
:content (format command-fmt (name command-name) command-line)
:literal true))
(defn command
"Define nagios command"
[session command-name command-line]
(remote-file/remote-file
session
(format "/etc/nagios3/conf.d/pallet-command-%s.cfg" (name command-name))
:owner "root"
:content (format command-fmt (name command-name) command-line)
:literal true))
(action/def-bash-action commands
"Define nagios commands"
[session]
(string/join
"\n"
(map
#(command* session %)
(parameter/get-for session [:nagios :commands] nil))))
(defn nrpe-command
"Define an nrpe command"
[session]
(command
session
"check_nrpe"
"$USER1$/check_nrpe -H $HOSTADDRESS$ -c $ARG1$"))
(defn record-nagios-server
"Record nagios server details"
[session]
(parameter/update-for
session [:nagios :server :ip]
(fn [x]
(compute/primary-ip (session/target-node session)))))
(defn hostgroups
"Create host groups for each tag, and one for all managed machines."
[session]
(let [nodes (filter #(config-for-node session %) (:all-nodes session))]
(str
(hostgroup "all-managed" "Managed Servers" (map nagios-hostname nodes))
(when-let [unmanaged (parameter/get-for
session [:nagios :hosts] nil)]
(hostgroup
"all-unmanaged" "Unmanaged Servers"
(map :name unmanaged)))
(reduce
#(str
%1 " "
(hostgroup
(first %2) (first %2)
(map (fn [n] (nagios-hostname n)) (second %2))))
""
(group-by (fn [n] (compute/tag n)) nodes)))))
(defn nagios
"Install nagios. Depends on a MTA and a webserver. Note that you will
need all target node groups in the lift/converge command."
[session admin-password]
(->
session
(package/package-manager
:debconf
(str "nagios3-cgi nagios3/adminpassword password " admin-password)
(str "nagios3-cgi nagios3/adminpassword-repeat password " admin-password)
(str "nagios3-cgi nagios3/httpd multiselect " "apache2"))
(package/packages
:yum ["httpd" "gcc" "glib" "glibc-common" "gd" "gd-devel" "nagios"]
:aptitude ["build-essential" "libgd2-xpm-dev" "apache2"
"php5-common" "php5" "libapache2-mod-php5"
"nagios3" "nagios-plugins-extra nagios-nrpe-plugin"])
;; remove any botched configuration files
(remote-file/remote-file
"/etc/nagios3/conf.d/pallet-hostgroups.cfg" :action :delete :force true)
(remote-file/remote-file
"/etc/nagios3/conf.d/pallet-servicegroups.cfg" :action :delete :force true)
(phase/schedule-in-pre-phase
(record-nagios-server))
;; Generate hostgroups defintion for each tag
(phase/schedule-in-post-phase
(commands)
(remote-file/remote-file
"/etc/nagios3/conf.d/pallet-hostgroups.cfg"
:owner "root"
:content (argument/delayed-fn hostgroups))
;; generate host configurations for each node
(hosts)
(servicegroups))))
© 2015 - 2025 Weber Informatics LLC | Privacy Policy