lib/arborist/monitor/snmp.rb
author Mahlon E. Smith <mahlon@martini.nu>
Wed, 07 Sep 2016 15:23:42 -0700
changeset 4 e6eb11b1e00d
parent 3 d46ca2b52efe
child 7 4548e58c8c66
permissions -rw-r--r--
Refactor. Move all SNMP "sections" to their own classes.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     1
# -*- ruby -*-
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     2
# vim: set noet nosta sw=4 ts=4 :
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     3
#encoding: utf-8
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     4
#
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     5
# SNMP checks for Arborist.  Requires an SNMP agent to be installed
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     6
# on target machine, and the various "pieces" enabled.  For your platform.
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     7
#
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     8
# For example, for disk monitoring with Net-SNMP, you'll want to set
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     9
# 'includeAllDisks' in the snmpd.conf. bsnmpd on FreeBSD benefits from
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    10
# the 'bsnmp-ucd' package.  Etc.
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    11
#
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    12
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    13
require 'loggability'
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    14
require 'arborist/monitor' unless defined?( Arborist::Monitor )
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    15
require 'snmp'
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    16
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    17
using Arborist::TimeRefinements
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    18
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    19
# Shared SNMP monitor logic.
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    20
#
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    21
module Arborist::Monitor::SNMP
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    22
	extend Loggability
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    23
	log_to :arborist
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    24
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    25
	# The version of this library.
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    26
	VERSION = '0.3.0'
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    27
1
8446f55f7e58 Allow local node "config" to override SNMP instanced globals. Add mount point includes and excludes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
    28
	# Global defaults for instances of this monitor
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    29
	#
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    30
	DEFAULT_OPTIONS = {
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    31
		timeout:   2,
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    32
		retries:   1,
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    33
		community: 'public',
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    34
		port:      161
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    35
	}
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    36
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    37
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    38
	### Connect to the SNMP daemon and yield.
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    39
	###
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    40
	def run( nodes )
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    41
		self.log.debug "Got nodes to SNMP check: %p" % [ nodes ]
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    42
		opts = Arborist::Monitor::SNMP::DEFAULT_OPTIONS
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    43
1
8446f55f7e58 Allow local node "config" to override SNMP instanced globals. Add mount point includes and excludes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
    44
		# Create mapping of addresses back to node identifiers,
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    45
		# and retain any custom (overrides) config per node.
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    46
		#
1
8446f55f7e58 Allow local node "config" to override SNMP instanced globals. Add mount point includes and excludes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
    47
		@identifiers = {}
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    48
		@results     = {}
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    49
1
8446f55f7e58 Allow local node "config" to override SNMP instanced globals. Add mount point includes and excludes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
    50
		nodes.each_pair do |(identifier, props)|
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    51
			next unless props.key?( 'addresses' )
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    52
			address = props[ 'addresses' ].first
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    53
			@identifiers[ address ] = [ identifier, props['config'] ]
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    54
		end
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    55
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    56
		# Perform the work!
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    57
		#
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    58
		threads = []
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    59
		@identifiers.keys.each do |host|
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    60
			thr = Thread.new do
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    61
				Thread.current.abort_on_exception = true
1
8446f55f7e58 Allow local node "config" to override SNMP instanced globals. Add mount point includes and excludes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
    62
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    63
				config = @identifiers[host].last || {}
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    64
				opts = {
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    65
					host:      host,
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    66
					port:      config[ 'port' ]      || opts[ :port ],
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    67
					community: config[ 'community' ] || opts[ :community ],
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    68
					timeout:   config[ 'timeout' ]   || opts[ :timeout ],
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    69
					retries:   config[ 'retries' ]   || opts[ :retries ]
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    70
				}
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    71
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    72
				begin
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    73
					SNMP::Manager.open( opts ) do |snmp|
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    74
						yield( snmp, host )
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    75
					end
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    76
				rescue SNMP::RequestTimeout
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    77
					@results[ host ] = {
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    78
						error: "Host is not responding to SNMP requests."
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    79
					}
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    80
				rescue StandardError => err
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    81
					@results[ host ] = {
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    82
						error: "Network is not accessible. (%s: %s)" % [ err.class.name, err.message ]
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    83
					}
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    84
				end
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    85
			end
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    86
			threads << thr
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    87
		end
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    88
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    89
		# Wait for thread completion
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    90
		threads.map( &:join )
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    91
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    92
		# Map everything back to identifier -> attribute(s), and send to the manager.
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    93
		#
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    94
		reply = @results.each_with_object({}) do |(address, results), hash|
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    95
			identifier = @identifiers[ address ] or next
3
d46ca2b52efe Put the nil check back when building the results hash.
Mahlon E. Smith <mahlon@martini.nu>
parents: 1
diff changeset
    96
			hash[ identifier.first ] = results
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    97
		end
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    98
		self.log.debug "Sending to manager: %p" % [ reply ]
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    99
		return reply
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   100
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
   101
	ensure
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
   102
		@identifiers = {}
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
   103
		@results     = {}
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   104
	end
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   105
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
   106
end # Arborist::Monitor::SNMP
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   107
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
   108
require 'arborist/monitor/snmp/disk'
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
   109
require 'arborist/monitor/snmp/load'
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
   110
require 'arborist/monitor/snmp/memory'
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
   111
require 'arborist/monitor/snmp/process'
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
   112
require 'arborist/monitor/snmp/swap'
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   113