summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Kemp <steve@steve.org.uk>2012-11-24 18:15:20 +0000
committerSteve Kemp <steve@steve.org.uk>2012-11-24 18:15:20 +0000
commitcda123f8d716c943e0e3f0f72f35ebd542430a53 (patch)
treed61e5163d45b482d96acdf6525dd792a69fff5b5
parent4ba3a2ae8b2abb3f758e974eaca596e111704285 (diff)
Replaced Custodian::Alerter with a full mauve-specific notifier.
-rw-r--r--lib/custodian/alerter.rb267
-rw-r--r--lib/custodian/alerts/mauve.rb221
2 files changed, 220 insertions, 268 deletions
diff --git a/lib/custodian/alerter.rb b/lib/custodian/alerter.rb
deleted file mode 100644
index ac38da8..0000000
--- a/lib/custodian/alerter.rb
+++ /dev/null
@@ -1,267 +0,0 @@
-
-require 'custodian/util/bytemark'
-require 'custodian/util/dns'
-
-
-####
-#### NOTE: This class will go away, once I've moved the implementation
-#### over to alerts/mauve.rb
-####
-####
-
-#
-# This class encapsulates the raising and clearing of alerts via Mauve.
-#
-# There is a helper method to update any alerts with details of whether the
-# affected host is inside/outside the Bytemark network.
-#
-#
-module Custodian
-
- class Alerter
-
- #
- # Details of the test case which we're going to raise/clear.
- #
- attr_reader :test
-
- #
- # Is this alerter available?
- #
- attr_reader :available
-
-
- #
- # Constructor.
- #
- # Save the details away.
- #
- def initialize( test_class )
- @test = test_class
-
-
- @available = true
-
- begin
- require 'mauve/sender'
- require 'mauve/proto'
- rescue LoadError
- @available = false
- end
-
- puts "ALERTER DISABLED: Steve"
- @available = false
- end
-
-
-
-
- #
- # Expand to a message indicating whether a hostname is inside the Bytemark network.
- # or not.
- #
- #
- def expand_inside_bytemark( host )
-
- #
- # If the host is a URL then we need to work with the hostname component alone.
- #
- # We'll also make the host a link that can be clicked in the alert we raise.
- #
- target = host
- if ( target =~ /https?:\/\/([^\/]+)/ )
- target = $1.dup
- host = "<a href=\"#{host}\">#{host}</a>"
- end
-
-
- #
- # Resolved IP of the target
- #
- resolved = nil
-
- #
- # Resolve the target to an IP, unless it is already an address.
- #
- if ( ( target =~ /^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$/ ) ||
- ( target =~ /^([0-9a-f:]+)$/ ) )
- resolved = target
- else
- resolved = Custodian::Util::DNS.hostname_to_ip( target )
- end
-
-
- #
- # Did we get an error?
- #
- return "" unless ( !resolved.nil? )
-
-
- #
- # Return the formatted message
- #
- if ( Custodian::Util::Bytemark.inside?( resolved.to_s ) )
- if ( resolved == target )
- return "<p>#{host} is inside the Bytemark network.</p>"
- else
- return "<p>#{host} resolves to #{resolved} which is inside the Bytemark network.</p>"
- end
- else
- if ( resolved == target )
- return "<p>#{host} is OUTSIDE the Bytemark network.</p>"
- else
- return "<p>#{host} resolves to #{resolved} which is OUTSIDE the Bytemark network.</p>"
- end
- end
-
- end
-
-
-
-
-
- #
- # Generate an alert-message which will be raised via mauve.
- #
- def raise( detail )
-
- if ( !@available )
- puts "Should raise alert for test: #{test}"
- exit(3)
- return
- end
-
- #
- # Get ready to send to mauve.
- #
- update = Mauve::Proto::AlertUpdate.new
- update.alert = []
- update.source = "custodian"
- update.replace = false
-
- #
- # Construct an alert with our test details.
- #
- alert = get_alert(detail)
-
- #
- # We're raising this alert.
- #
- alert.raise_time = Time.now.to_i
-
- #
- # Update it and send it
- #
- update.alert << alert
- Mauve::Sender.new("alert.bytemark.co.uk").send(update)
- end
-
-
-
- #
- # Generate an alert-message which will be cleared via mauve.
- #
- def clear
-
- if ( !@available )
- puts "Should clear alert for test: #{test}"
- return
- end
-
- #
- # Get ready to send to mauve.
- #
- update = Mauve::Proto::AlertUpdate.new
- update.alert = []
- update.source = "custodian"
- update.replace = false
-
-
- #
- # Construct an alert with our test details.
- #
- alert = get_alert( "" )
-
- #
- # We're clearing this alert.
- #
- alert.clear_time = Time.now.to_i
-
- #
- # Update it and send it
- #
- update.alert << alert
- Mauve::Sender.new("alert.bytemark.co.uk").send(update)
- end
-
-
-
-
- #
- # Using the test-data-hash which was set in the constructor
- # generate a useful alert that can be fired off to mauve.
- #
- # Most of the mess of this method is ensuring there is some
- # "helpful" data in the detail-field of the alert.
- #
- def get_alert( detail )
-
- #
- # Is this alert affecting a machine inside/outside our network?
- #
- inside = expand_inside_bytemark( @details["target_host"] )
-
-
- #
- # The subject of an alert should be one of:
- #
- # 1. Hostname.
- #
- # 2. IP address
- #
- # 3. A URL.
- #
- #
- # We attempt to resolve the alert to the hostname, as that is readable.
- #
- #
- subject = @details['target_host']
- if ( ( subject =~ /^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$/ ) ||
- ( subject =~ /^([0-9a-f:]+)$/ ) )
- res = Custodian::Util::DNS.ip_to_hostname( subject )
- if ( res )
- subject = res
- end
- end
-
- #
- # Document the hostname if the alert relates to an IP address.
- #
- resolved = ""
- if ( ( @details["target_host"] =~ /^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$/ ) ||
- ( @details["target_host"] =~ /^([0-9a-f:]+)$/ ) )
-
- resolved = Custodian::Util::DNS.ip_to_hostname( @details["target_host"] )
- if ( resolved.nil? )
- resolved = ""
- else
- resolved = "The IP address #{@details["target_host"]} resolves to #{resolved}."
- end
- end
-
-
- alert = Mauve::Proto::Alert.new
- alert.id = "#{@details['test_type']}-#{@details['target_host']}"
- alert.subject = subject
- alert.summary = "#{@details['test_alert']} to #{subject} failed #{detail}"
- alert.detail = "#{inside} <p>The #{@details['test_type']} test failed against #{@details['target_host']}: #{detail}</p><p>#{resolved}</p>"
-
- #
- # Return the alert to the caller.
- #
- alert
- end
-
- end
-
-end
diff --git a/lib/custodian/alerts/mauve.rb b/lib/custodian/alerts/mauve.rb
index c3e8a76..64b6982 100644
--- a/lib/custodian/alerts/mauve.rb
+++ b/lib/custodian/alerts/mauve.rb
@@ -1,8 +1,21 @@
+require 'custodian/util/bytemark'
+require 'custodian/util/dns'
+
+
+#
+# This class encapsulates the raising and clearing of alerts via Mauve.
+#
+# There is a helper method to update any alerts with details of whether the
+# affected host is inside/outside the Bytemark network.
+#
+# This is almost Bytemark-specific, although the server it talks to is
+# indeed Open Source:
+#
+# https://projects.bytemark.co.uk/projects/mauvealert
#
-# The Mauve-alerter.
#
module Custodian
@@ -10,20 +23,226 @@ module Custodian
class Mauve < AlertFactory
+
#
# The test this alerter cares about
#
attr_reader :test
+
+
+
#
# Constructor
#
def initialize( obj )
@test = obj
+
+ begin
+ require 'mauve/sender'
+ require 'mauve/proto'
+ rescue LoadError
+ puts "ERROR Loading mauvealert libraries"
+ end
+ end
+
+
+
+
+ #
+ # Generate an alert-message which will be raised via mauve.
+ #
+ def raise()
+
+
+ #
+ # Get ready to send to mauve.
+ #
+ update = Mauve::Proto::AlertUpdate.new
+ update.alert = []
+ update.source = "custodian"
+ update.replace = false
+
+ #
+ # Construct a new alert structure.
+ #
+ alert = _get_alert( true )
+
+ #
+ # We're raising this alert.
+ #
+ alert.raise_time = Time.now.to_i
+
+ #
+ # Update it and send it
+ #
+ update.alert << alert
+ Mauve::Sender.new( @target ).send(update)
+ end
+
+
+
+ #
+ # Generate an alert-message which will be cleared via mauve.
+ #
+ def clear
+
+ #
+ # Get ready to send to mauve.
+ #
+ update = Mauve::Proto::AlertUpdate.new
+ update.alert = []
+ update.source = "custodian"
+ update.replace = false
+
+ #
+ # Construct a new alert structure.
+ #
+ alert = _get_alert( false )
+
+ #
+ # We're clearing this alert.
+ #
+ alert.clear_time = Time.now.to_i
+
+ #
+ # Update it and send it
+ #
+ update.alert << alert
+ Mauve::Sender.new( @target ).send(update)
end
+
+
+
+ #
+ # Using the test object, which was set in the constructor,
+ # generate a useful alert that can be fired off to mauve.
+ #
+ # Most of the mess of this method is ensuring there is some
+ # "helpful" data in the detail-field of the alert.
+ #
+ def _get_alert( failure )
+
+ #
+ # The subject of an alert MUST be one of:
+ #
+ # 1. Hostname.
+ # 2. IP address
+ # 3. A URL.
+ #
+ # We attempt to resolve the alert to the hostname, as that is more
+ # readable, if we have been given an IP address.
+ #
+ subject = @test.target
+
+ if ( ( subject =~ /^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$/ ) ||
+ ( subject =~ /^([0-9a-f:]+)$/ ) )
+ res = Custodian::Util::DNS.ip_to_hostname( subject )
+ if ( res )
+ subject = res
+ end
+ end
+
+
+ #
+ # The test type
+ #
+ test_host = test.target
+ test_type = test.get_type
+
+
+ alert = Mauve::Proto::Alert.new
+ alert.id = "#{test_type}-#{test_host}"
+ alert.subject = subject
+ alert.summary = "#{test_type}-#{test_host}"
+ alert.detail = "<p>The #{test_type} test failed against #{test_host}.</p>"
+
+ #
+ # If we're raising then add the error
+ #
+ if ( failure )
+ alert.detail = "#{alert.detail}\n#{test.error()}"
+ end
+
+ #
+ # Determine if this is inside/outside the bytemark network
+ #
+ location = expand_inside_bytemark( test_host )
+ if ( !location.nil? && location.length )
+ alert.detail = "#{alert.detail}\n#{location}"
+ end
+
+ #
+ # Return the alert to the caller.
+ #
+ alert
+ end
+
+
+ #
+ # Expand to a message indicating whether a hostname is inside the Bytemark network.
+ # or not.
+ #
+ #
+ def expand_inside_bytemark( host )
+
+ #
+ # If the host is a URL then we need to work with the hostname component alone.
+ #
+ # We'll also make the host a link that can be clicked in the alert we raise.
+ #
+ target = host
+ if ( target =~ /^([a-z]+):\/\/([^\/]+)/ )
+ target = $2.dup
+ host = "<a href=\"#{host}\">#{host}</a>"
+ end
+
+
+ #
+ # Resolved IP of the target
+ #
+ resolved = nil
+
+ #
+ # Resolve the target to an IP, unless it is already an address.
+ #
+ if ( ( target =~ /^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$/ ) ||
+ ( target =~ /^([0-9a-f:]+)$/ ) )
+ resolved = target
+ else
+ resolved = Custodian::Util::DNS.hostname_to_ip( target )
+ end
+
+
+ #
+ # Did we get an error?
+ #
+ return "" unless ( !resolved.nil? )
+
+
+ #
+ # Return the formatted message
+ #
+ if ( Custodian::Util::Bytemark.inside?( resolved.to_s ) )
+ if ( resolved == target )
+ return "<p>#{host} is inside the Bytemark network.</p>"
+ else
+ return "<p>#{host} resolves to #{resolved} which is inside the Bytemark network.</p>"
+ end
+ else
+ if ( resolved == target )
+ return "<p>#{host} is OUTSIDE the Bytemark network.</p>"
+ else
+ return "<p>#{host} resolves to #{resolved} which is OUTSIDE the Bytemark network.</p>"
+ end
+ end
+
+ end
+
+
register_alert_type "mauve"