Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
rodjek committed Jun 26, 2010
1 parent 5c81dbc commit 3bfd8e4
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 0 deletions.
8 changes: 8 additions & 0 deletions lib/bluster.rb
@@ -0,0 +1,8 @@
# stdlib

# external
require 'redis'

# internal
require 'bluster/bluster'
require 'bluster/errors'
117 changes: 117 additions & 0 deletions lib/bluster/bluster.rb
@@ -0,0 +1,117 @@
class Bluster
attr_accessor :objects_path, :redis_host, :redis_port, :last_update_timestamp, :redis

# Instantiate a new Bluster object.
#
# objects_path - path to the Nagios objects.cache file
#
# Returns a configured Bluster instance.
def initialize(objects_path, server)
self.objects_path = objects_path
self.redis_host = server.split(':').first
self.redis_port = server.split(':').last.to_i
self.last_update_timestamp = 0

ensure_object_cache_exists
ensure_redis_connection
end

# The list of contact object names.
#
# Returns an Array of String contact names.
def contacts
ensure_cache_up_to_date
contacts = self.redis.keys("bluster:objects:contact:*")
contacts.map! { |r| r.split(":")[3] }
contacts.uniq
end

# The configuration details of a contact.
#
# Returns a Hash of Strings.
def get_contact(contact)
ensure_cache_up_to_date
namespace = "bluster:objects:contact:#{contact}"
keys = self.redis.keys("#{namespace}:*")
data = {}
keys.each { |key|
short_key = key.split(":")[4]
data[short_key] = self.redis.get("#{namespace}:#{short_key}")
}
data
end

private

# Checks that the provided object cache path exists.
#
# Returns nothing.
def ensure_object_cache_exists
if not File.exist? self.objects_path
raise ObjectCacheNotFound.new(self.objects_path)
end
end

# Ensure that the cache in Redis is up to date
#
# Returns nothing.
def ensure_cache_up_to_date
self.last_update_timestamp = self.redis.get("bluster:last_update_timestamp").to_i
if self.last_update_timestamp.nil?
update_object_cache
elsif self.last_update_timestamp != File.new(self.objects_path).mtime.to_i
update_object_cache
end
end

# Ensure that a working connection to Redis has been established and that
# the object cache is up to date.
#
# Returns nothing.
def ensure_redis_connection
self.redis = Redis.new(:host => self.redis_host, :port => self.redis_port)
ensure_cache_up_to_date
rescue Errno::ECONNREFUSED
raise RedisConnectionError.new("Unable to connect to redis")
end

# Read the object cache file and store the contents in redis.
#
# Returns nothing.
def update_object_cache
in_object = false
objects = {}
data = {}
type = ""
File.open(self.objects_path, "r").readlines.each { |line|
line = line.strip
if line =~ %r{^define (\w+) .*}
type = $1
in_object = true
data = {}
if objects[type].nil?
objects[type] = []
end
else
if in_object == true
if line == "}"
in_object = false
objects[type] << data
else
chunks = line.squeeze(' ').split(' ')
data[chunks.first] = chunks.last
end
end
end
}

objects["contact"].each { |contact|
namespace = "bluster:objects:contact:#{contact['contact_name']}"
contact.keys.each { |key|
self.redis.set("#{namespace}:#{key}", contact[key]) if key != "contact_name"
}
}

self.redis.set("bluster:last_update_timestamp", File.new(self.objects_path).mtime.to_i)
end
end
7 changes: 7 additions & 0 deletions lib/bluster/errors.rb
@@ -0,0 +1,7 @@
class Bluster
class ObjectCacheNotFound < StandardError
end

class RedisConnectionError < StandardError
end
end

0 comments on commit 3bfd8e4

Please sign in to comment.