lib/arborist/monitor/snmp.rb
author Mahlon E. Smith <mahlon@martini.nu>
Wed, 30 Aug 2017 13:55:02 -0700
changeset 7 4548e58c8c66
parent 4 e6eb11b1e00d
child 8 e0b7c95a154f
permissions -rw-r--r--
Use the new #node_properties method, convery from .rvmrc
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.
7
4548e58c8c66 Use the new #node_properties method, convery from .rvmrc
Mahlon E. Smith <mahlon@martini.nu>
parents: 4
diff changeset
    26
	VERSION = '0.3.1'
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
7
4548e58c8c66 Use the new #node_properties method, convery from .rvmrc
Mahlon E. Smith <mahlon@martini.nu>
parents: 4
diff changeset
    37
	# Always request the node addresses and any config.
4548e58c8c66 Use the new #node_properties method, convery from .rvmrc
Mahlon E. Smith <mahlon@martini.nu>
parents: 4
diff changeset
    38
	USED_PROPERTIES = [ :addresses, :config ].freeze
4548e58c8c66 Use the new #node_properties method, convery from .rvmrc
Mahlon E. Smith <mahlon@martini.nu>
parents: 4
diff changeset
    39
4548e58c8c66 Use the new #node_properties method, convery from .rvmrc
Mahlon E. Smith <mahlon@martini.nu>
parents: 4
diff changeset
    40
	### Return the properties used by this monitor.
4548e58c8c66 Use the new #node_properties method, convery from .rvmrc
Mahlon E. Smith <mahlon@martini.nu>
parents: 4
diff changeset
    41
	def self::node_properties
4548e58c8c66 Use the new #node_properties method, convery from .rvmrc
Mahlon E. Smith <mahlon@martini.nu>
parents: 4
diff changeset
    42
		return USED_PROPERTIES
4548e58c8c66 Use the new #node_properties method, convery from .rvmrc
Mahlon E. Smith <mahlon@martini.nu>
parents: 4
diff changeset
    43
	end
4548e58c8c66 Use the new #node_properties method, convery from .rvmrc
Mahlon E. Smith <mahlon@martini.nu>
parents: 4
diff changeset
    44
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    45
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    46
	### Connect to the SNMP daemon and yield.
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    47
	###
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    48
	def run( nodes )
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    49
		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
    50
		opts = Arborist::Monitor::SNMP::DEFAULT_OPTIONS
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    51
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
    52
		# 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
    53
		# and retain any custom (overrides) config per node.
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    54
		#
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
    55
		@identifiers = {}
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    56
		@results     = {}
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    57
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
    58
		nodes.each_pair do |(identifier, props)|
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    59
			next unless props.key?( 'addresses' )
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    60
			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
    61
			@identifiers[ address ] = [ identifier, props['config'] ]
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    62
		end
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    63
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    64
		# Perform the work!
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    65
		#
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    66
		threads = []
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    67
		@identifiers.keys.each do |host|
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    68
			thr = Thread.new do
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    69
				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
    70
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    71
				config = @identifiers[host].last || {}
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    72
				opts = {
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    73
					host:      host,
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    74
					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
    75
					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
    76
					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
    77
					retries:   config[ 'retries' ]   || opts[ :retries ]
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    78
				}
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
				begin
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    81
					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
    82
						yield( snmp, host )
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    83
					end
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    84
				rescue SNMP::RequestTimeout
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    85
					@results[ host ] = {
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    86
						error: "Host is not responding to SNMP requests."
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    87
					}
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    88
				rescue StandardError => err
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
    89
					@results[ host ] = {
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    90
						error: "Network is not accessible. (%s: %s)" % [ err.class.name, err.message ]
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
				end
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    93
			end
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    94
			threads << thr
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    95
		end
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    96
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    97
		# Wait for thread completion
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    98
		threads.map( &:join )
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    99
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   100
		# Map everything back to identifier -> attribute(s), and send to the manager.
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   101
		#
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
   102
		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
   103
			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
   104
			hash[ identifier.first ] = results
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   105
		end
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   106
		self.log.debug "Sending to manager: %p" % [ reply ]
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   107
		return reply
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   108
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
   109
	ensure
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
   110
		@identifiers = {}
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
   111
		@results     = {}
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   112
	end
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   113
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
   114
end # Arborist::Monitor::SNMP
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   115
4
e6eb11b1e00d Refactor. Move all SNMP "sections" to their own classes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 3
diff changeset
   116
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
   117
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
   118
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
   119
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
   120
require 'arborist/monitor/snmp/swap'
0
8547a1ce445e Initial commit.
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   121