Skip to content
This repository has been archived by the owner on Jan 26, 2022. It is now read-only.

Commit

Permalink
Add pingdom decider to can_i_bump
Browse files Browse the repository at this point in the history
Signed-off-by: Kris Kelly <kkelly@pivotallabs.com>
  • Loading branch information
mariash authored and Kris Kelly committed Jan 29, 2014
1 parent ce3666b commit ed580a7
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 14 deletions.
1 change: 0 additions & 1 deletion sinatra/can_i_bump/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@ source "https://rubygems.org"
gem "sinatra"
gem "rspec"
gem "rest-client"
gem "vcr"
gem "webmock", "1.15"
2 changes: 0 additions & 2 deletions sinatra/can_i_bump/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ GEM
rack-protection (~> 1.4)
tilt (~> 1.3, >= 1.3.4)
tilt (1.4.1)
vcr (2.8.0)
webmock (1.15.0)
addressable (>= 2.2.7)
crack (>= 0.3.2)
Expand All @@ -37,5 +36,4 @@ DEPENDENCIES
rest-client
rspec
sinatra
vcr
webmock (= 1.15)
67 changes: 67 additions & 0 deletions sinatra/can_i_bump/lib/deciders/pingdom.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
require "rest-client"

module Decider
class Pingdom
PINGDOM_API_ENDPOINT = "https://api.pingdom.com/api/2.0"
UPDATE_INTERVAL = 30

attr_reader :reason

def initialize app_key, username, password, hostname
@app_key = app_key
@username = username
@password = password
@hostname = hostname
@can_i_bump = false
@reason = "No data yet"

message = "Invalid argument, cannot be nil"
[@app_key, @username, @password, @hostname].each {|param| raise ArgumentError, message if param.nil?}
end

def can_i_bump?
verify_pingdom
@can_i_bump
end

private

def verify_pingdom
checks = pingdom_checks
return set_can_i_bump(false, "No data from pingdom") if checks.empty?
failed_checks = checks.select { |c| c["status"] != "up" && c["status"] != "paused" }

unless failed_checks.empty?
return set_can_i_bump(
false,
"Pingdom failed to connect to #{failed_checks.map {|c| c["hostname"]}.join(", ")}")
end

return set_can_i_bump(true, nil)
rescue => e
return set_can_i_bump(false, "Can't connect to pingdom: #{e.message}")
end

def set_can_i_bump(value, reason)
@can_i_bump = value
@reason = reason
end

def pingdom_checks
response = RestClient::Request.new(
:method => :get,
:url => "#{Pingdom::PINGDOM_API_ENDPOINT}/checks",
:user => @username,
:password => @password,
:headers => {
"App-Key" => @app_key
}
).execute
filter_checks(JSON.parse(response.body)["checks"])
end

def filter_checks(checks)
checks.select { |c| c["hostname"] =~ /#{@hostname}/ }
end
end
end
79 changes: 79 additions & 0 deletions sinatra/can_i_bump/spec/deciders/pingdom_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
require "spec_helper"
require "deciders/pingdom"

describe Decider::Pingdom do
describe "initialize" do
context "invalid parameters" do

it "any parameter is nil" do
expect { Decider::Pingdom.new(nil, 'foo', 'bar', 'foo') }.to raise_error(ArgumentError)
expect { Decider::Pingdom.new('foo', nil, 'bar', 'foo') }.to raise_error(ArgumentError)
expect { Decider::Pingdom.new('foo', 'bar', nil, 'foo') }.to raise_error(ArgumentError)
expect { Decider::Pingdom.new('foo', 'bar', 'baz', nil) }.to raise_error(ArgumentError)
end
end
end

describe "#can_i_bump?" do
subject(:decider) { Decider::Pingdom.new('foobar', 'fake_user', 'fake_password', 'target_hostname') }

context "when pingdom is unreachable" do
before do
stub_request(:get, "https://fake_user:fake_password@api.pingdom.com/api/2.0/checks").to_return(:status => 500)
end

it "says NO" do
expect(decider.can_i_bump?).to be_false
expect(decider.reason).to match /500 Internal Server Error/
end
end

context "when pingdom does not return any checks" do
before do
stub_request(:get, "https://fake_user:fake_password@api.pingdom.com/api/2.0/checks").
to_return(:body => JSON.dump({"checks" => []}))
end

it "says NO" do
expect(decider.can_i_bump?).to be_false
expect(decider.reason).to match /No data/
end
end

context "when some matching checks are DOWN" do
before do
stub_request(:get, "https://fake_user:fake_password@api.pingdom.com/api/2.0/checks").
to_return(:body => JSON.dump(
{
"checks" => [
{"id" => 123, "status" => "down", "hostname" => "a.target_hostname"},
{"id" => 456, "status" => "up", "hostname" => "b.target_hostname"},
{"id" => 789, "status" => "down", "hostname" => "c.target_hostname"}
]
}))
end

it "says NO" do
expect(decider.can_i_bump?).to be_false
expect(decider.reason).to match /Pingdom failed to connect to a.target_hostname, c.target_hostname/
end
end

context "when all matching checks are UP" do
before do
stub_request(:get, "https://fake_user:fake_password@api.pingdom.com/api/2.0/checks").
to_return(:body => JSON.dump(
{
"checks" => [
{"id" => 123, "status" => "down", "hostname" => "a.bar"},
{"id" => 456, "status" => "up", "hostname" => "b.target_hostname"}
]
}))
end

it "ignores checks not matching the hostname" do
expect(decider.can_i_bump?).to be_true
end
end
end
end
13 changes: 2 additions & 11 deletions sinatra/can_i_bump/spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
require "vcr"
require "webmock/rspec"
require "support/can_i_bump_runner"

$:.unshift(File.expand_path("../lib", __FILE__))

RSpec.configure do |rspec_config|
rspec_config.include(CanIBumpRunner)
end


VCR.configure do |c|
c.cassette_library_dir = File.expand_path("../fixtures/vcr_cassettes", __FILE__)
c.hook_into :webmock
c.ignore_localhost = true
c.default_cassette_options = {
:serialize_with => :syck,
:decode_compressed_response => true
}
WebMock.disable_net_connect!(:allow => /127.0.0.1/)
end

0 comments on commit ed580a7

Please sign in to comment.