lib/flapjack/api.rb in flapjack-0.6.39 vs lib/flapjack/api.rb in flapjack-0.6.40

- old
+ new

@@ -10,13 +10,17 @@ require 'rack/fiber_pool' require 'sinatra/base' require 'flapjack/pikelet' +require 'flapjack/redis_pool' require 'flapjack/api/entity_presenter' +require 'async-rack' +require 'flapjack/rack_logger' + require 'flapjack/data/contact' require 'flapjack/data/entity' require 'flapjack/data/entity_check' # from https://github.com/sinatra/sinatra/issues/501 @@ -47,11 +51,11 @@ class API < Sinatra::Base set :show_exceptions, false - if 'test'.eql?(FLAPJACK_ENV) + if defined?(FLAPJACK_ENV) && 'test'.eql?(FLAPJACK_ENV) # expose test errors properly set :raise_errors, true else # doesn't work with Rack::Test unless we wrap tests in EM.synchrony blocks rescue_exception = Proc.new { |env, exception| @@ -63,20 +67,44 @@ use Rack::FiberPool, :size => 25, :rescue_exception => rescue_exception end use Rack::MethodOverride use Rack::JsonParamsParser - extend Flapjack::Pikelet + api_logger = Flapjack::RackLogger.new('log/api_access.log') + use Rack::CommonLogger, api_logger - before do - # will only initialise the first time it's run - Flapjack::API.bootstrap + class << self + include Flapjack::ThinPikelet + + attr_accessor :redis + + alias_method :thin_bootstrap, :bootstrap + alias_method :thin_cleanup, :cleanup + + def bootstrap(opts = {}) + thin_bootstrap(opts) + @redis = Flapjack::RedisPool.new(:config => opts[:redis_config], :size => 1) + end + + def cleanup + @redis.empty! if @redis + thin_cleanup + end + end + def redis + self.class.instance_variable_get('@redis') + end + + def logger + self.class.instance_variable_get('@logger') + end + get '/entities' do content_type :json - ret = Flapjack::Data::Entity.all(:redis => @@redis).sort_by(&:name).collect {|e| + ret = Flapjack::Data::Entity.all(:redis => redis).sort_by(&:name).collect {|e| {'id' => e.id, 'name' => e.name, 'checks' => e.check_list.sort.collect {|c| entity_check_status(e, c) } } @@ -84,11 +112,11 @@ ret.to_json end get '/checks/:entity' do content_type :json - entity = Flapjack::Data::Entity.find_by_name(params[:entity], :redis => @@redis) + entity = Flapjack::Data::Entity.find_by_name(params[:entity], :redis => redis) if entity.nil? status 404 return end entity.check_list.to_json @@ -98,11 +126,11 @@ content_type :json entity_name = params[:captures][0] check = params[:captures][1] - entity = Flapjack::Data::Entity.find_by_name(entity_name, :redis => @@redis) + entity = Flapjack::Data::Entity.find_by_name(entity_name, :redis => redis) if entity.nil? status 404 return end @@ -123,25 +151,25 @@ content_type :json entity_name = params[:captures][0] check = params[:captures][1] - entity = entity = Flapjack::Data::Entity.find_by_name(entity_name, :redis => @@redis) + entity = entity = Flapjack::Data::Entity.find_by_name(entity_name, :redis => redis) if entity.nil? status 404 return end start_time = validate_and_parsetime(params[:start_time]) end_time = validate_and_parsetime(params[:end_time]) presenter = if check entity_check = Flapjack::Data::EntityCheck.for_entity(entity, - check, :redis => @@redis) + check, :redis => redis) Flapjack::API::EntityCheckPresenter.new(entity_check) else - Flapjack::API::EntityPresenter.new(entity, :redis => @@redis) + Flapjack::API::EntityPresenter.new(entity, :redis => redis) end presenter.outages(start_time, end_time).to_json end @@ -149,25 +177,25 @@ content_type :json entity_name = params[:captures][0] check = params[:captures][1] - entity = Flapjack::Data::Entity.find_by_name(entity_name, :redis => @@redis) + entity = Flapjack::Data::Entity.find_by_name(entity_name, :redis => redis) if entity.nil? status 404 return end start_time = validate_and_parsetime(params[:start_time]) end_time = validate_and_parsetime(params[:end_time]) presenter = if check entity_check = Flapjack::Data::EntityCheck.for_entity(entity, - check, :redis => @@redis) + check, :redis => redis) Flapjack::API::EntityCheckPresenter.new(entity_check) else - Flapjack::API::EntityPresenter.new(entity, :redis => @@redis) + Flapjack::API::EntityPresenter.new(entity, :redis => redis) end presenter.unscheduled_maintenance(start_time, end_time).to_json end @@ -175,91 +203,107 @@ content_type :json entity_name = params[:captures][0] check = params[:captures][1] - entity = Flapjack::Data::Entity.find_by_name(entity_name, :redis => @@redis) + entity = Flapjack::Data::Entity.find_by_name(entity_name, :redis => redis) if entity.nil? status 404 return end start_time = validate_and_parsetime(params[:start_time]) end_time = validate_and_parsetime(params[:end_time]) presenter = if check entity_check = Flapjack::Data::EntityCheck.for_entity(entity, - check, :redis => @@redis) + check, :redis => redis) Flapjack::API::EntityCheckPresenter.new(entity_check) else - Flapjack::API::EntityPresenter.new(entity, :redis => @@redis) + Flapjack::API::EntityPresenter.new(entity, :redis => redis) end presenter.scheduled_maintenance(start_time, end_time).to_json end get %r{/downtime/([a-zA-Z0-9][a-zA-Z0-9\.\-]*[a-zA-Z0-9])(?:/(\w+))?} do content_type :json entity_name = params[:captures][0] check = params[:captures][1] - entity = Flapjack::Data::Entity.find_by_name(entity_name, :redis => @@redis) + entity = Flapjack::Data::Entity.find_by_name(entity_name, :redis => redis) if entity.nil? status 404 return end start_time = validate_and_parsetime(params[:start_time]) end_time = validate_and_parsetime(params[:end_time]) presenter = if check entity_check = Flapjack::Data::EntityCheck.for_entity(entity, - check, :redis => @@redis) + check, :redis => redis) Flapjack::API::EntityCheckPresenter.new(entity_check) else - Flapjack::API::EntityPresenter.new(entity, :redis => @@redis) + Flapjack::API::EntityPresenter.new(entity, :redis => redis) end presenter.downtime(start_time, end_time).to_json end # create a scheduled maintenance period for a service on an entity post '/scheduled_maintenances/:entity/:check' do content_type :json - entity = Flapjack::Data::Entity.find_by_name(params[:entity], :redis => @@redis) + entity = Flapjack::Data::Entity.find_by_name(params[:entity], :redis => redis) if entity.nil? status 404 return end entity_check = Flapjack::Data::EntityCheck.for_entity(entity, - params[:check], :redis => @@redis) + params[:check], :redis => redis) entity_check.create_scheduled_maintenance(:start_time => params[:start_time], :duration => params[:duration], :summary => params[:summary]) status 204 end # create an acknowledgement for a service on an entity # NB currently, this does not acknowledge a specific failure event, just # the entity-check as a whole post '/acknowledgements/:entity/:check' do content_type :json - entity = Flapjack::Data::Entity.find_by_name(params[:entity], :redis => @@redis) + entity = Flapjack::Data::Entity.find_by_name(params[:entity], :redis => redis) if entity.nil? status 404 return end dur = params[:duration] ? params[:duration].to_i : nil duration = (dur.nil? || (dur <= 0)) ? (4 * 60 * 60) : dur entity_check = Flapjack::Data::EntityCheck.for_entity(entity, - params[:check], :redis => @@redis) + params[:check], :redis => redis) entity_check.create_acknowledgement('summary' => params[:summary], 'duration' => duration) status 204 end + post '/test_notifications/:entity/:check' do + content_type :json + entity = Flapjack::Data::Entity.find_by_name(params[:entity], :redis => redis) + if entity.nil? + status 404 + return + end + + summary = params[:summary] || "Testing notifications to all contacts interested in entity #{entity.name}" + + entity_check = Flapjack::Data::EntityCheck.for_entity(entity, + params[:check], :redis => redis) + entity_check.test_notifications('summary' => summary) + status 204 + end + post '/entities' do pass unless 'application/json'.eql?(request.content_type) content_type :json errors = [] @@ -270,11 +314,11 @@ entities.each do |entity| unless entity['id'] errors << "Entity not imported as it has no id: #{entity.inspect}" next end - Flapjack::Data::Entity.add(entity, :redis => @@redis) + Flapjack::Data::Entity.add(entity, :redis => redis) end ret = 200 else ret = 403 errors << "No valid entities were submitted" @@ -289,17 +333,17 @@ errors = [] ret = nil contacts = params[:contacts] if contacts && contacts.is_a?(Enumerable) && contacts.any? {|c| !c['id'].nil?} - Flapjack::Data::Contact.delete_all(:redis => @@redis) + Flapjack::Data::Contact.delete_all(:redis => redis) contacts.each do |contact| unless contact['id'] logger.warn "Contact not imported as it has no id: #{contact.inspect}" next end - Flapjack::Data::Contact.add(contact, :redis => @@redis) + Flapjack::Data::Contact.add(contact, :redis => redis) end ret = 200 else ret = 403 errors << "No valid contacts were submitted" @@ -313,10 +357,10 @@ private def entity_check_status(entity, check) entity_check = Flapjack::Data::EntityCheck.for_entity(entity, - check, :redis => @@redis) + check, :redis => redis) return if entity_check.nil? { 'name' => check, 'state' => entity_check.state, 'in_unscheduled_maintenance' => entity_check.in_unscheduled_maintenance?, 'in_scheduled_maintenance' => entity_check.in_scheduled_maintenance?,