#!/usr/local/bin/ruby

##    This program is free software: you can redistribute it and/or modify
##    it under the terms of the GNU General Public License as published by
##    the Free Software Foundation, either version 3 of the License, or
##    (at your option) any later version. For further details see:
##    <http://www.gnu.org/licenses/>.
##
##    This program is distributed in the hope that it will be useful,
##    but WITHOUT ANY WARRANTY; without even the implied warranty of
##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##    GNU General Public License for more details.

# ==============
# check_arcconf
# ==============
# * written by Silver Salonen, Estonia

# version 1.0.1 (18.Nov.2013)
# - bugfix: variable #{arcconf_bin} was not used properly

# version 1.0 (22.Mar.2011)

# plugin return codes:
# 0	OK
# 1	Warning
# 2	Critical
# 3	Unknown

require 'getoptlong'

opts = GetoptLong.new(
	[ "--help", "-h", GetoptLong::OPTIONAL_ARGUMENT],
	[ "--controller", "-c", GetoptLong::REQUIRED_ARGUMENT],
	[ "--disk", "-d", GetoptLong::REQUIRED_ARGUMENT],
	[ "--raid", "-r", GetoptLong::REQUIRED_ARGUMENT]
)

optHelp = nil
optController = nil
optDisk = nil
optRaid = nil

opts.each {|opt, arg|
	case opt
		when "--help", "-h"
			optHelp = true
			break 2
		when "--controller", "-c"
			optController = arg
		when "--disk", "-d"
			optDisk = arg
		when "--raid", "-r"
			optRaid = arg
	end
}

def printUsage()
	print "Usage: #{0} [-h] [-c <controller-number>] (-d <disk-number>|-r <RAID-number>)\n\n"
	print "Examples:	#{0} -d 2\n"
	print "		#{0} -r 1\n"
end

def printHelp()
	printUsage
	print "\nThis plugin checks healt of logical and physical units of Adaptec RAID controller.\n\n"
	print "For more details, see inside the script ;)\n"
	exit 3
end

if (optHelp)
	printHelp
	exit 3
end

if (!optDisk && !optRaid)
	printUsage
	exit 3
end

arcconf_bin = `which arcconf`
if (arcconf_bin == "")
	print "arcconf: command not found!\n"
	exit 3
end

controller = optController ? optController : 1

arcconf=`#{arcconf_bin} getconfig #{controller}`

if (arcconf.include?("Invalid controller number"))
	print "Invalid controller number: #{controller}\n"
	exit 3
end

def getParam(what, number, param, arcconf)
	correctSection = false
	if (what == "disk")
		lineCheck = "Device ##{number}"
	elsif (what == "raid")
		lineCheck = "Logical device number #{number}"
	else
		return false
	end
	arcconf.each_line do |line|
		line = line.strip
		if (!correctSection)
			if (line == lineCheck)
				correctSection = true
			end
			next
		end
		# else
		if (!line.include?(':'))
			next
		end
		aParam = line.split(':')
		if (aParam[0].strip == param)
			return aParam[1].strip
		end
	end
	return false
end

retDisk = 0
if (optDisk)
	aParams = ["State", "S.M.A.R.T. warnings"]
	aParams.each do |param|
		paramValue = getParam("disk", optDisk, param, arcconf)
		if (paramValue == false)
			print "Could not get parameter #{param} for disk #{optDisk}!\n"
			retDisk = 3
			next
		end
		if (param == "State" && paramValue != "Online" || param == "S.M.A.R.T. warnings" && paramValue != "0")
			print "Disk #{optDisk} #{param}: #{paramValue}\n"
			retDisk = 2
		end
	end
	if (retDisk == 0)
		print "Disk #{optDisk} OK!\n"
	end
end

retRaid = 0
if (optRaid)
	aParams = ["Status of logical device", "Failed stripes"]
	aParams.each do |param|
		paramValue = getParam("raid", optRaid, param, arcconf)
		if (paramValue == false)
			print "Could not get parameter #{param} for RAID #{optRaid}!\n"
			retRaid = 3
			next
		end
		if (param == "Status of logical device" && paramValue != "Optimal" || param == "Failed stripes" && paramValue != "No")
			print "RAID #{optRaid} '#{param}': #{paramValue}\n"
			retRaid = 2
		end
	end
	if (retRaid == 0)
		print "RAID #{optRaid} OK!\n"
	end
end

exit retDisk > retRaid ? retDisk : retRaid
