summaryrefslogtreecommitdiff
path: root/parser
diff options
context:
space:
mode:
authorSteve Kemp <steve@steve.org.uk>2012-11-13 16:16:18 +0000
committerSteve Kemp <steve@steve.org.uk>2012-11-13 16:16:18 +0000
commit723f2d471679d4f2081b8cca82346f93f906fc26 (patch)
treee978d5ac404e5686d22bdc8717ba24de4a95ed7b /parser
parentaffe98261e29ec044066c36cf625772eb0f48154 (diff)
added test-case to cover basic file-parsing.
Diffstat (limited to 'parser')
-rwxr-xr-xparser/parser.rb360
1 files changed, 185 insertions, 175 deletions
diff --git a/parser/parser.rb b/parser/parser.rb
index a3f7246..4612001 100755
--- a/parser/parser.rb
+++ b/parser/parser.rb
@@ -29,15 +29,13 @@ require 'json'
#
# TODO:
#
-# 1. Break parse_file down into repeated calls to parse_line, to allow test
-# cases to be written.
+# 1. Explicitly abort and panic on malformed lines.
#
-# 2. Explicitly abort and panic on malformed lines.
+# 2. Implement HTTP-fetching for macro-bodies.
#
-# 3. Implement HTTP-fetching for macro-bodies.
#
# Steve
-# --
+# --
#
class MonitorConfig
@@ -65,8 +63,7 @@ class MonitorConfig
@file = filename
if ( @file.nil? || ( ! File.exists?( @file) ) )
- puts "Missing configuration file"
- exit( 0 )
+ raise ArgumentError, "Missing configuration file!"
end
end
@@ -112,6 +109,10 @@ class MonitorConfig
+ def macros
+ @MACROS
+ end
+
#
# Is the given string of text a macro?
#
@@ -129,208 +130,217 @@ class MonitorConfig
end
-
-
-
#
- # Parse the configuration file, named in our constructor.
+ # Parse a single line from the configuration file.
#
- def parse_file()
+ def parse_line( line )
+
#
- # Parse the configuration file on the command line
+ # A blank line, or a comment may be skipped.
#
- File.open( @file, "r").each_line do |line|
-
- #
- # A blank line, or a comment may be skipped.
- #
- next if ( ( line =~ /^#/ ) || ( line.length < 1 ) )
+ return if ( ( line =~ /^#/ ) || ( line.length < 1 ) )
- # specification of mauve-server to which we should raise our alerts to.
- next if ( line =~ /Mauve\s+server(.*)source/ )
-
-
- #
- # Look for macro definitions, inline
- #
- if ( line =~ /^([A-Z]_+)\s+are\s+fetched\s+from\s+([^\s]+)\.?/ )
- define_macro( line )
+ #
+ # The specification of mauve-server to which we should raise our alerts to.
+ #
+ return if ( line =~ /Mauve\s+server(.*)source/ )
- elsif ( line =~ /^([0-9A-Z_]+)\s+(is|are)\s+/ )
- define_macro( line )
- elsif ( line =~ /\s+must\s+ping/ )
+ #
+ # Look for macro definitions, inline
+ #
+ if ( line =~ /^([A-Z]_+)\s+are\s+fetched\s+from\s+([^\s]+)\.?/ )
+ define_macro( line )
- #
- # Target
- #
- targets = Array.new
+ elsif ( line =~ /^([0-9A-Z_]+)\s+(is|are)\s+/ )
+ define_macro( line )
- #
- # Fallback target is the first token on the line
- #
- target = line.split( /\s+/)[0]
+ elsif ( line =~ /\s+must\s+ping/ )
+ #
+ # Target
+ #
+ targets = Array.new
- #
- # If the target is a macro
- #
- if ( is_macro?( target ) )
- targets = get_macro_targets(target)
+ #
+ # Fallback target is the first token on the line
+ #
+ target = line.split( /\s+/)[0]
+
+
+ #
+ # If the target is a macro
+ #
+ if ( is_macro?( target ) )
+ targets = get_macro_targets(target)
+ else
+ targets.push( target )
+ end
+
+ #
+ # The alert-failure message
+ #
+ alert = "Ping failed"
+ if ( line =~ /otherwise '([^']+)'/ )
+ alert=$1.dup
+ end
+
+ #
+ # Store the test(s)
+ #
+ targets.each do |host|
+ test = {
+ :target_host => host,
+ :test_type => "ping",
+ :test_alert => alert
+ }
+
+ if ( !ENV['DUMP'].nil? )
+ puts ( test.to_json )
else
- targets.push( target )
+ @queue.put( test.to_json )
end
-
- #
- # The alert-failure message
- #
- alert = "Ping failed"
- if ( line =~ /otherwise '([^']+)'/ )
- alert=$1.dup
- end
-
+ end
+
+ elsif ( line =~ /\s+must\s+run\s+([^\s]+)\s+/i )
+
+ #
+ # Get the service we're testing, and remove any trailing "."
+ #
+ # This handles the case of:
+ #
+ # LINN_HOSTS must run ssh.
+ #
+ service = $1.dup
+ service.chomp!(".")
+
+ #
+ # Target of the service-test.
+ #
+ targets = Array.new
+ target = line.split( /\s+/)[0]
+
+ #
+ # If the target is a macro
+ #
+ if ( is_macro?( target ) )
+ targets = get_macro_targets( target )
+ else
+ targets.push( target )
+ end
+
+ #
+ # Alert text
+ #
+ alert = "#{service} failed"
+ if ( line =~ /otherwise '([^']+)'/ )
+ alert=$1.dup
+ end
+
+ #
+ # All our service tests require a port - we setup the defaults here,
+ # but the configuration file will allow users to specify an alternative
+ # via " on XXX ".
+ #
+ case service
+ when /ssh/ then
+ port=22
+ when /jabber/ then
+ port=5222
+ when /ldap/ then
+ port=389
+ when /^https$/ then
+ port=443
+ when /^http$/ then
+ port=80
+ when /rsync/i then
+ port=873
+ when /ftp/i then
+ port=21
+ when /telnet/i then
+ port=23
+ when /smtp/i then
+ port=25
+ end
+
+ #
+ # But allow that to be changed
+ #
+ # e.g.
+ #
+ # must run ssh on 33 otherwise ..
+ # must run ftp on 44 otherwise ..
+ # must run http on 8000 otherwise ..
+ #
+ if ( line =~ /\s+on\s+([0-9]+)/ )
+ port = $1.dup
+ end
+
+ targets.each do |host|
+
+ test = {
+ :target_host => host,
+ :test_type => service,
+ :test_port => port,
+ :test_alert => alert
+ }
+
#
- # Store the test(s)
+ # HTTP-tests will include the expected result in one of two
+ # forms:
#
- targets.each do |host|
- test = {
- :target_host => host,
- :test_type => "ping",
- :test_alert => alert
- }
-
- if ( !ENV['DUMP'].nil? )
- puts ( test.to_json )
- else
- @queue.put( test.to_json )
- end
- end
-
- elsif ( line =~ /\s+must\s+run\s+([^\s]+)\s+/i )
-
+ # must run http with status 200
#
- # Get the service we're testing, and remove any trailing "."
+ # must run http with content 'text'
#
- # This handles the case of:
+ # If those are sepcified then include them here.
#
- # LINN_HOSTS must run ssh.
+ # Note we're deliberately fast and loose here - which allows both to be specified
#
- service = $1.dup
- service.chomp!(".")
-
+ # http://example.vm/ must run http with status 200 and content 'OK' otherwise 'boo!'.
#
- # Target of the service-test.
#
- targets = Array.new
- target = line.split( /\s+/)[0]
+ if ( line =~ /\s+with\s+status\s+([0-9]+)\s+/ )
+ test[:http_status]=$1.dup
+ end
+ if ( line =~ /\s+with\s+content\s+'([^']+)'/ )
+ test[:http_text]=$1.dup
+ end
#
- # If the target is a macro
+ # We've parsed(!) the line. Either output the JSON to the console
+ # or add to the queue.
#
- if ( is_macro?( target ) )
- targets = get_macro_targets( target )
+ if ( !ENV['DUMP'].nil? )
+ puts ( test.to_json )
else
- targets.push( target )
+ @queue.put( test.to_json )
end
+ end
+ else
+ puts "Unknown line: #{line}" if ( line.length > 2 )
+ end
+ end
- #
- # Alert text
- #
- alert = "#{service} failed"
- if ( line =~ /otherwise '([^']+)'/ )
- alert=$1.dup
- end
- #
- # All our service tests require a port - we setup the defaults here,
- # but the configuration file will allow users to specify an alternative
- # via " on XXX ".
- #
- case service
- when /ssh/ then
- port=22
- when /jabber/ then
- port=5222
- when /ldap/ then
- port=389
- when /^https$/ then
- port=443
- when /^http$/ then
- port=80
- when /rsync/i then
- port=873
- when /ftp/i then
- port=21
- when /telnet/i then
- port=23
- when /smtp/i then
- port=25
- end
+ #
+ # Parse the configuration file, named in our constructor.
+ #
+ def parse_file()
+ #
+ # Parse the configuration file on the command line
+ #
+ File.open( @file, "r").each_line do |line|
+ parse_line( line)
+ end
+ end
- #
- # But allow that to be changed
- #
- # e.g.
- #
- # must run ssh on 33 otherwise ..
- # must run ftp on 44 otherwise ..
- # must run http on 8000 otherwise ..
- #
- if ( line =~ /\s+on\s+([0-9]+)/ )
- port = $1.dup
- end
- targets.each do |host|
-
- test = {
- :target_host => host,
- :test_type => service,
- :test_port => port,
- :test_alert => alert
- }
-
- #
- # HTTP-tests will include the expected result in one of two
- # forms:
- #
- # must run http with status 200
- #
- # must run http with content 'text'
- #
- # If those are sepcified then include them here.
- #
- # Note we're deliberately fast and loose here - which allows both to be specified
- #
- # http://example.vm/ must run http with status 200 and content 'OK' otherwise 'boo!'.
- #
- #
- if ( line =~ /\s+with\s+status\s+([0-9]+)\s+/ )
- test[:http_status]=$1.dup
- end
- if ( line =~ /\s+with\s+content\s+'([^']+)'/ )
- test[:http_text]=$1.dup
- end
-
- #
- # We've parsed(!) the line. Either output the JSON to the console
- # or add to the queue.
- #
- if ( !ENV['DUMP'].nil? )
- puts ( test.to_json )
- else
- @queue.put( test.to_json )
- end
- end
+end
- else
- puts "Unknown line: #{line}" if ( line.length > 2 )
- end
- end
- end
-end
#
# Entry-point to our code.