From 40fecc1a15360b8717b2b715de2ec02048e42caa Mon Sep 17 00:00:00 2001 From: Derek Higgins Date: Wed, 20 Feb 2013 06:25:31 -0500 Subject: [PATCH] Adding Nagios Support This commit adds an option to install Nagios to monitor the openstack components. Initially we are only monitoring a small subset of what could eventually be monitored http://bugzilla.redhat.com/show_bug.cgi?id=912768 Change-Id: I176876e5ecc35e7c58ef49534341939fd7998701 --- packstack/plugins/nagios_910.py | 170 ++++++++++++++++++ packstack/plugins/prescript_000.py | 12 ++ .../packstack/templates/cinder-list.erb | 14 ++ .../packstack/templates/glance-index.erb | 13 ++ .../templates/keystone-user-list.erb | 13 ++ .../modules/packstack/templates/nova-list.erb | 13 ++ .../packstack/templates/swift-list.erb | 14 ++ packstack/puppet/templates/horizon.pp | 2 + packstack/puppet/templates/nagios_nrpe.pp | 41 +++++ packstack/puppet/templates/nagios_server.pp | 64 +++++++ 10 files changed, 356 insertions(+) create mode 100644 packstack/plugins/nagios_910.py create mode 100644 packstack/puppet/modules/packstack/templates/cinder-list.erb create mode 100644 packstack/puppet/modules/packstack/templates/glance-index.erb create mode 100644 packstack/puppet/modules/packstack/templates/keystone-user-list.erb create mode 100644 packstack/puppet/modules/packstack/templates/nova-list.erb create mode 100644 packstack/puppet/modules/packstack/templates/swift-list.erb create mode 100644 packstack/puppet/templates/nagios_nrpe.pp create mode 100644 packstack/puppet/templates/nagios_server.pp diff --git a/packstack/plugins/nagios_910.py b/packstack/plugins/nagios_910.py new file mode 100644 index 000000000..d405d2ab3 --- /dev/null +++ b/packstack/plugins/nagios_910.py @@ -0,0 +1,170 @@ +""" +Installs and configures Nagios +""" + +import uuid +import logging + +import packstack.installer.engine_validators as validate +from packstack.installer import basedefs, output_messages +import packstack.installer.common_utils as utils + +from packstack.modules.ospluginutils import gethostlist,\ + getManifestTemplate,\ + appendManifestFile + +# Controller object will be initialized from main flow +controller = None + +# Plugin name +PLUGIN_NAME = "OS-Nagios" +PLUGIN_NAME_COLORED = utils.getColoredText(PLUGIN_NAME, basedefs.BLUE) + +logging.debug("plugin %s loaded", __name__) + +def initConfig(controllerObject): + global controller + controller = controllerObject + logging.debug("Adding OpenStack Nagios configuration") + paramsList = [ + {"CMD_OPTION" : "nagios-host", + "USAGE" : "The IP address of the server on which to install the Nagios server", + "PROMPT" : "Enter the IP address of the Nagios server", + "OPTION_LIST" : [], + "VALIDATORS" : [validate.validate_ssh], + "DEFAULT_VALUE" : utils.getLocalhostIP(), + "MASK_INPUT" : False, + "LOOSE_VALIDATION": True, + "CONF_NAME" : "CONFIG_NAGIOS_HOST", + "USE_DEFAULT" : False, + "NEED_CONFIRM" : False, + "CONDITION" : False }, + {"CMD_OPTION" : "nagios-passwd", + "USAGE" : "The password of the nagiosadmin user on the Nagios server", + "PROMPT" : "Enter the password for the nagiosadmin user", + "OPTION_LIST" : [], + "VALIDATORS" : [validate.validate_not_empty], + "DEFAULT_VALUE" : uuid.uuid4().hex[:16], + "MASK_INPUT" : True, + "LOOSE_VALIDATION": True, + "CONF_NAME" : "CONFIG_NAGIOS_PW", + "USE_DEFAULT" : False, + "NEED_CONFIRM" : False, + "CONDITION" : False }, + ] + + groupDict = { "GROUP_NAME" : "NAGIOS", + "DESCRIPTION" : "Nagios Config parameters", + "PRE_CONDITION" : "CONFIG_NAGIOS_INSTALL", + "PRE_CONDITION_MATCH" : "y", + "POST_CONDITION" : False, + "POST_CONDITION_MATCH" : True} + + controller.addGroup(groupDict, paramsList) + + +def initSequences(controller): + conf = controller.CONF + if conf['CONFIG_NAGIOS_INSTALL'] != 'y': + return + + nagiossteps = [ + {'title': 'Adding Nagios server manifest entries', 'functions':[createmanifest]}, + {'title': 'Adding Nagios host manifest entries', 'functions':[createnrpemanifests]} + ] + controller.addSequence("Installing Nagios", [], [], nagiossteps) + +def _serviceentry(**kwargs): + s = 'define service {\n' + keys = kwargs.keys() + keys.sort() + for key in keys: + s += "\t%s\t%s\n"%(key, kwargs[key]) + s+= "\t}\n" + return s + +def _copy_script(**kwargs): + # TODO : Replace all these shell templates with with python + s = ('file{"/usr/lib64/nagios/plugins/%(name)s":' + 'mode => 755, owner => "nagios", seltype => "nagios_unconfined_plugin_exec_t",' + 'content => template("packstack/%(name)s.erb"),}\n' + 'nagios_command{"%(name)s": command_line => "/usr/lib64/nagios/plugins/%(name)s", }\n' % kwargs) + return s + +def createmanifest(): + manifest_entries = '' + # I should be adding service entries with nagios_service but it appears to be broken + # http://projects.puppetlabs.com/issues/3420 + service_entries = '' + for hostname in gethostlist(controller.CONF): + manifest_entries += "nagios_host{'%s': address => '%s', use => 'linux-server', }\n" % (hostname, hostname) + + service_entries += _serviceentry(name='load5-%s'%hostname, service_description='5 minute load average', + host_name=hostname, check_command="check_nrpe!load5", use="generic-service", + normal_check_interval='5') + + service_entries += _serviceentry(name='df_var-%s'%hostname, + service_description='Percent disk space used on /var', + host_name=hostname, + check_command="check_nrpe!df_var", use="generic-service") + + manifest_entries += _copy_script(name="keystone-user-list") + service_entries += _serviceentry(name='keystone-user-list', + service_description='number of keystone users', + host_name=controller.CONF['CONFIG_NAGIOS_HOST'], + check_command="keystone-user-list", use="generic-service", + normal_check_interval='5') + + if controller.CONF['CONFIG_GLANCE_INSTALL'] == 'y': + manifest_entries += _copy_script(name="glance-index") + service_entries += _serviceentry(name='glance-index', + service_description='number of glance images', + host_name=controller.CONF['CONFIG_NAGIOS_HOST'], + check_command="glance-index", use="generic-service", + normal_check_interval='5') + + if controller.CONF['CONFIG_NOVA_INSTALL'] == 'y': + manifest_entries += _copy_script(name="nova-list") + service_entries += _serviceentry(name='nova-list', + service_description='number of nova vm instances', + host_name=controller.CONF['CONFIG_NAGIOS_HOST'], + check_command="nova-list", use="generic-service", + normal_check_interval='5') + + if controller.CONF['CONFIG_CINDER_INSTALL'] == 'y': + manifest_entries += _copy_script(name="cinder-list") + service_entries += _serviceentry(name='cinder-list', + service_description='number of cinder volumes', + host_name=controller.CONF['CONFIG_NAGIOS_HOST'], + check_command="cinder-list", use="generic-service", + normal_check_interval='5') + + if controller.CONF['CONFIG_SWIFT_INSTALL'] == 'y': + manifest_entries += _copy_script(name="swift-list") + service_entries += _serviceentry(name='swift-list', + service_description='number of swift containers', + host_name=controller.CONF['CONFIG_NAGIOS_HOST'], + check_command="swift-list", use="generic-service", + normal_check_interval='5') + + manifest_entries+="file{'/etc/nagios/resource.d/nagios_service.cfg': \n" \ + "ensure => present, mode => 644,\n" \ + "content => '%s'}" % service_entries + + controller.CONF['CONFIG_NAGIOS_MANIFEST_CONFIG'] = manifest_entries + + manifestfile = "%s_nagios.pp" % controller.CONF['CONFIG_NAGIOS_HOST'] + manifestdata = getManifestTemplate("nagios_server.pp") + appendManifestFile(manifestfile, manifestdata) + +def createnrpemanifests(): + for hostname in gethostlist(controller.CONF): + controller.CONF['CONFIG_NRPE_HOST'] = hostname + manifestfile = "%s_nagios_nrpe.pp" % hostname + manifestdata = getManifestTemplate("nagios_nrpe.pp") + appendManifestFile(manifestfile, manifestdata) + + controller.MESSAGES.append("To use Nagios, browse to http://%s/nagios " + "username : nagiosadmin, password : %s" % + (controller.CONF['CONFIG_NAGIOS_HOST'], + controller.CONF['CONFIG_NAGIOS_PW'])) diff --git a/packstack/plugins/prescript_000.py b/packstack/plugins/prescript_000.py index 17e522986..23a584a76 100644 --- a/packstack/plugins/prescript_000.py +++ b/packstack/plugins/prescript_000.py @@ -108,6 +108,18 @@ def initConfig(controllerObject): "USE_DEFAULT" : False, "NEED_CONFIRM" : False, "CONDITION" : False }, + {"CMD_OPTION" : "nagios-install", + "USAGE" : "Set to 'y' if you would like Packstack to install Nagios to monitor openstack hosts", + "PROMPT" : "Should Packstack install Nagios to monitor openstack hosts", + "OPTION_LIST" : ["y", "n"], + "VALIDATORS" : [validate.validate_options], + "DEFAULT_VALUE" : 'n', + "MASK_INPUT" : False, + "LOOSE_VALIDATION": False, + "CONF_NAME" : "CONFIG_NAGIOS_INSTALL", + "USE_DEFAULT" : False, + "NEED_CONFIRM" : False, + "CONDITION" : False }, ] groupDict = { "GROUP_NAME" : "GLOBAL", "DESCRIPTION" : "Global Options", diff --git a/packstack/puppet/modules/packstack/templates/cinder-list.erb b/packstack/puppet/modules/packstack/templates/cinder-list.erb new file mode 100644 index 000000000..739b9d750 --- /dev/null +++ b/packstack/puppet/modules/packstack/templates/cinder-list.erb @@ -0,0 +1,14 @@ +#!/bin/env bash + +. /etc/nagios/keystonerc_admin + +data=$(cinder list 2>&1) +rv=$? + +if [ "$rv" != "0" ] ; then + echo $data + exit $rv +fi + +echo "$data" | grep -v -e '--------' -e ' Status ' | wc -l + diff --git a/packstack/puppet/modules/packstack/templates/glance-index.erb b/packstack/puppet/modules/packstack/templates/glance-index.erb new file mode 100644 index 000000000..5fbea5e48 --- /dev/null +++ b/packstack/puppet/modules/packstack/templates/glance-index.erb @@ -0,0 +1,13 @@ +#!/bin/env bash + +. /etc/nagios/keystonerc_admin + +data=$(glance index 2>&1) +rv=$? + +if [ "$rv" != "0" ] ; then + echo $data + exit $rv +fi + +echo "$data" | grep -v -e "^ID " -e "---------------" | wc -l diff --git a/packstack/puppet/modules/packstack/templates/keystone-user-list.erb b/packstack/puppet/modules/packstack/templates/keystone-user-list.erb new file mode 100644 index 000000000..b40641ce6 --- /dev/null +++ b/packstack/puppet/modules/packstack/templates/keystone-user-list.erb @@ -0,0 +1,13 @@ +#!/bin/env bash + +. /etc/nagios/keystonerc_admin + +data=$(keystone user-list 2>&1) +rv=$? + +if [ "$rv" != "0" ] ; then + echo $data + exit $rv +fi + +echo "$data" | grep -v -e " id " -e "---------------" | wc -l diff --git a/packstack/puppet/modules/packstack/templates/nova-list.erb b/packstack/puppet/modules/packstack/templates/nova-list.erb new file mode 100644 index 000000000..9d3491f26 --- /dev/null +++ b/packstack/puppet/modules/packstack/templates/nova-list.erb @@ -0,0 +1,13 @@ +#!/bin/env bash + +. /etc/nagios/keystonerc_admin + +data=$(nova list 2>&1) +rv=$? + +if [ "$rv" != "0" ] ; then + echo $data + exit $rv +fi + +echo "$data" | grep -v -e '--------' -e '| Status |' -e '^$' | wc -l diff --git a/packstack/puppet/modules/packstack/templates/swift-list.erb b/packstack/puppet/modules/packstack/templates/swift-list.erb new file mode 100644 index 000000000..770add64a --- /dev/null +++ b/packstack/puppet/modules/packstack/templates/swift-list.erb @@ -0,0 +1,14 @@ +#!/bin/env bash + +. /etc/nagios/keystonerc_admin + +data=$(swift list 2>&1) +rv=$? + +if [ "$rv" != "0" ] ; then + echo $data + exit $rv +fi + +echo "$data" |wc -l + diff --git a/packstack/puppet/templates/horizon.pp b/packstack/puppet/templates/horizon.pp index 4af865a7d..daaf3f220 100644 --- a/packstack/puppet/templates/horizon.pp +++ b/packstack/puppet/templates/horizon.pp @@ -20,6 +20,8 @@ class {'memcached':} class {'apache':} class {'apache::mod::wsgi':} file { '/etc/httpd/conf.d/openstack-dashboard.conf':} +file { '/etc/httpd/conf.d/nagios.conf':} +file { '/etc/httpd/conf.d/php.conf':} firewall { '001 horizon incoming': proto => 'tcp', diff --git a/packstack/puppet/templates/nagios_nrpe.pp b/packstack/puppet/templates/nagios_nrpe.pp new file mode 100644 index 000000000..62a482cf2 --- /dev/null +++ b/packstack/puppet/templates/nagios_nrpe.pp @@ -0,0 +1,41 @@ +package{'nrpe': + ensure => present, + before => Class['nagios_configs'] +} + +class nagios_configs(){ + + file_line{'allowed_hosts': + path => '/etc/nagios/nrpe.cfg', + match => 'allowed_hosts=', + line => 'allowed_hosts=%(CONFIG_NAGIOS_HOST)s', + } + + # 5 minute load average + file_line{'load5': + path => '/etc/nagios/nrpe.cfg', + match => 'command\[load5\]=', + line => 'command[load5]=cut /proc/loadavg -f 1 -d " "', + } + + # disk used on /var + file_line{'df_var': + path => '/etc/nagios/nrpe.cfg', + match => "command\[df_var\]=", + line => "command[df_var]=df /var/ | sed -re 's/.* ([0-9]+)%%.*/\\1/' | grep -E '^[0-9]'", + } +} +class{'nagios_configs': + notify => Service['nrpe'], +} + +service{'nrpe': + ensure => running, + hasstatus => true, +} + +firewall { '001 nrpe incoming': + proto => 'tcp', + dport => ['5666'], + action => 'accept', +} diff --git a/packstack/puppet/templates/nagios_server.pp b/packstack/puppet/templates/nagios_server.pp new file mode 100644 index 000000000..42f6b0d8a --- /dev/null +++ b/packstack/puppet/templates/nagios_server.pp @@ -0,0 +1,64 @@ +package{['nagios', 'nagios-plugins-nrpe', 'nagios-plugins-ping']: + ensure => present, + before => Class['nagios_configs'] +} + +file { 'resource-d': + path => '/etc/nagios/resource.d', + ensure => directory, + owner => 'nagios', + before => Class['nagios_configs'], + require => Package['nagios'] +} + +class nagios_configs(){ + file{['/etc/nagios/resource.d/nagios_command.cfg', '/etc/nagios/resource.d/nagios_host.cfg']: + ensure => 'present', + mode => '0644', + } + + # Remove the entry for localhost, it contains services we're not + # monitoring + file{['/etc/nagios/objects/localhost.cfg']: + ensure => 'present', + content => '', + } + + Nagios_command{ + target => '/etc/nagios/resource.d/nagios_command.cfg' + } + Nagios_host{ + target => '/etc/nagios/resource.d/nagios_host.cfg' + } + + file_line{'resource.d': + path => '/etc/nagios/nagios.cfg', + line => 'cfg_dir=/etc/nagios/resource.d', + } + + nagios_command{'check_nrpe': + command_line => '/usr/lib64/nagios/plugins/check_nrpe -H $HOSTADDRESS$ -c $ARG1$', + } + + exec{'nagiospasswd': + command => '/usr/bin/htpasswd -b /etc/nagios/passwd nagiosadmin %(CONFIG_NAGIOS_PW)s', + } + + file {"/etc/nagios/keystonerc_admin": + ensure => "present", owner => "nagios", mode => '0600', + content => "export OS_USERNAME=admin +export OS_TENANT_NAME=admin +export OS_PASSWORD=%(CONFIG_KEYSTONE_ADMIN_PW)s +export OS_AUTH_URL=http://%(CONFIG_KEYSTONE_HOST)s:35357/v2.0/ ",} + + %(CONFIG_NAGIOS_MANIFEST_CONFIG)s +} + +class{'nagios_configs': + notify => [Service['nagios'], Service['httpd']], +} + +service{['nagios', 'httpd']: + ensure => running, + hasstatus => true, +}