1#!/usr/local/bin/ruby 2# 3# Xymon server script 4# Check a dokuwiki installation for any update or error 5# Require the associated plugin to be installed on the target wikis 6# Erwan Martin <public@fzwte.net> 7# 8# Runs on FreeBSD and certainly elsewhere since it's ruby 9# 10# License: Public Domain 11# 12 13require 'cgi' 14require 'pp' 15require "xmlrpc/client" 16require 'openssl' 17 18xymon = ENV['XYMON'] 19xymonsrv = ENV['XYMSRV'] 20xymonhome = ENV['XYMONHOME'] 21xymongrep = xymonhome+'/bin/xymongrep' 22column = 'dokuwikicheck DOKUWIKI*' 23 24wikis_to_check = []; 25 26#extract the list of dokuwiki installations to check from the xymon config files 27host_lines = %x{#{xymongrep} #{column}} 28hosts = host_lines.split(/\n/) 29hosts.each do |ahost| 30 if ahost =~ /^[\d\.]+\s+([a-zA-Z0-9\-\.\:]+?)\s*\#/ 31 xymon_name = $1 32 else 33 next 34 end 35 36 wiki_information = { 37 :xymon_name => xymon_name, 38 :url => '', 39 :user => '', 40 :password => '', 41 :sslcert => '', 42 :sslkey => '', 43 :sslcacert => '' 44 } 45 46 if ahost =~ /DOKUWIKIURL:([^\s]*?)(?:\s|$)/ 47 wiki_information[:url] = $1 48 end 49 if ahost =~ /DOKUWIKIUSER:([^\s]*?)(?:\s|$)/ 50 wiki_information[:user] = $1 51 end 52 if ahost =~ /DOKUWIKIPASSWORD:([^\s]*?)(?:\s|$)/ 53 wiki_information[:password] = $1 54 end 55 if ahost =~ /DOKUWIKISSLCERT:([^\s]*?)(?:\s|$)/ 56 wiki_information[:sslcert] = $1 57 end 58 if ahost =~ /DOKUWIKISSLKEY:([^\s]*?)(?:\s|$)/ 59 wiki_information[:sslkey] = $1 60 end 61 if ahost =~ /DOKUWIKISSLCACERT:([^\s]*?)(?:\s|$)/ 62 wiki_information[:sslcacert] = $1 63 end 64 65 wikis_to_check << wiki_information 66end 67 68#we need to be able to set param to the http client of the ruby xmlrpc client 69module SELF_SSL 70 class Net_HTTP < Net::HTTP 71 def set_sslcontext(value) 72 @ssl_context = value 73 end 74 end 75 76 class XMLRPC_Client < XMLRPC::Client 77 def initialize(*args) 78 super 79 @http = SELF_SSL::Net_HTTP.new( @host, @port, 80 @proxy_host,@proxy_port ) 81 @http.use_ssl = @use_ssl if @use_ssl 82 @http.read_timeout = @timeout 83 @http.open_timeout = @timeout 84 end 85 86 def get_http() 87 return @http 88 end 89 end 90end 91 92#main loop 93wikis_to_check.each do |wiki_information| 94 xymon_color = 'clear' 95 xymon_message = '' 96 begin 97 #url, user and password 98 raise "No url was provided" if wiki_information[:url].strip.empty? 99 endpoint_url = wiki_information[:url] + '/lib/exe/xmlrpc.php' 100 server = SELF_SSL::XMLRPC_Client.new2(endpoint_url) 101 server.user = wiki_information[:user] 102 server.password = wiki_information[:password] 103 http=server.get_http() 104 object_to_decorate = http 105 if RUBY_VERSION < "1.9" 106 ssl_context = OpenSSL::SSL::SSLContext.new 107 http.set_sslcontext(ssl_context) 108 object_to_decorate = ssl_context 109 end 110 111 #ssl (if provided) 112 # the equivalent line is: 113 # openssl s_client -connect host:port -servername host -cert :sslcert -key :sslkey -verify 12 -CAfile :sslcacert 114 if not wiki_information[:sslcert].empty? 115 certificate = OpenSSL::X509::Certificate.new(File.read(wiki_information[:sslcert])) 116 object_to_decorate.cert = certificate 117 end 118 if not wiki_information[:sslkey].empty? 119 key = OpenSSL::PKey::RSA.new(File.read(wiki_information[:sslkey])) 120 object_to_decorate.key=key 121 end 122 if not wiki_information[:sslcacert].empty? 123 object_to_decorate.ca_file=wiki_information[:sslcacert] 124 end 125 if http.use_ssl? 126 object_to_decorate.verify_mode = OpenSSL::SSL::VERIFY_PEER 127 object_to_decorate.verify_depth = 12 128 end 129 ##Uncomment this to see the chain verification in details and to override it 130 #object_to_decorate.verify_callback = Proc.new do |ok, store_context| 131 # puts ok 132 # puts store_context 133 # true 134 #end 135 136 137 #call 138 status_page = server.call("wiki.getPage", "xymon:xymonstatus") 139 140 #find the color in the response 141 if status_page =~ /^xymon_color: (.*?)$/ 142 xymon_color = $1 143 xymon_message = status_page 144 else 145 raise "Could not find xymon color in status page\n\n %s" % status_page 146 end 147 rescue Exception => e 148 xymon_message = "Error!\n%s\n\n%s" % [e.message, e.backtrace] 149 xymon_color = "clear" 150 end 151 152 #send the color and message to xymon 153 xymon_message.gsub!(/([\"`])/, "\\\\\\1") 154 xymon_host = wiki_information[:xymon_name] 155 command = "#{xymon} \"#{xymonsrv}\" \"status+90000 #{xymon_host}.dokuwikicheck #{xymon_color} #{xymon_message}\"" 156 #puts command 157 %x{#{command}} 158end 159 160 161