pingdom-client 0.0.0.alpha

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source :rubygems
2
+
3
+ gem "faraday", "~> 0.5.6"
4
+
5
+ gem "excon", "~> 0.5.6"
6
+ gem "yajl-ruby", "~> 0.8.1", :require => "yajl"
7
+
8
+ gem "activesupport", "~> 3.0.4"
9
+ gem "i18n", "~> 0.5.0" # ActiveSupport dependency
10
+
11
+ group :development do
12
+ gem "bundler", "~> 1.0.0"
13
+ gem "rake", "~> 0.8.7"
14
+ gem "rspec", "2.1.0"
15
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,37 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activesupport (3.0.4)
5
+ addressable (2.2.4)
6
+ diff-lcs (1.1.2)
7
+ excon (0.5.6)
8
+ faraday (0.5.6)
9
+ addressable (~> 2.2.4)
10
+ multipart-post (~> 1.1.0)
11
+ rack (>= 1.1.0, < 2)
12
+ i18n (0.5.0)
13
+ multipart-post (1.1.0)
14
+ rack (1.2.1)
15
+ rake (0.8.7)
16
+ rspec (2.1.0)
17
+ rspec-core (~> 2.1.0)
18
+ rspec-expectations (~> 2.1.0)
19
+ rspec-mocks (~> 2.1.0)
20
+ rspec-core (2.1.0)
21
+ rspec-expectations (2.1.0)
22
+ diff-lcs (~> 1.1.2)
23
+ rspec-mocks (2.1.0)
24
+ yajl-ruby (0.8.1)
25
+
26
+ PLATFORMS
27
+ ruby
28
+
29
+ DEPENDENCIES
30
+ activesupport (~> 3.0.4)
31
+ bundler (~> 1.0.0)
32
+ excon (~> 0.5.6)
33
+ faraday (~> 0.5.6)
34
+ i18n (~> 0.5.0)
35
+ rake (~> 0.8.7)
36
+ rspec (= 2.1.0)
37
+ yajl-ruby (~> 0.8.1)
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ require "rubygems"
2
+ require "bundler"
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+
11
+ require 'rspec/core/rake_task'
12
+ RSpec::Core::RakeTask.new do |t|
13
+ t.rspec_opts = ["-c", "-f progress", "-r ./spec/spec_helper.rb"]
14
+ t.pattern = 'spec/**/*_spec.rb'
15
+ end
16
+
17
+ task :console do
18
+ exec %(ruby -rirb -rubygems -r bundler/setup -r lib/pingdom-client -e '$credentials = YAML.load_file("credentials.yml").with_indifferent_access; $client = Pingdom::Client.new($credentials); IRB.start')
19
+ end
20
+
21
+ task :default => :spec
data/Readme.md ADDED
@@ -0,0 +1,47 @@
1
+ # Pingdom RESTful API Client
2
+
3
+ Pingdom now offers a RESTful API, which gives us no reason not to make a decent,
4
+ non-SOAP API client for their services.
5
+
6
+ ## Usage
7
+
8
+ client = Pingdom::Client.new :username => u, :password => p
9
+ check = client.checks.first #=> #<Pingdom::Check>
10
+ check.lastresponsetime #=> 200 (ms)
11
+ check.status #=> :up
12
+ check.up? #=> true
13
+
14
+ result = check.results.first(:probes => [1,2,3], :status => [:up, :down])
15
+ #=> #<Pingdom::Result>
16
+ result.status #=> :up
17
+ result.up? #=> true
18
+ result.responsetime #=> 200 (ms)
19
+
20
+ avg = check.average(:from => 1.month.ago,
21
+ :probes => [1,2,3])
22
+ #=> #<Pingdom::Summary::Average>
23
+ avg.responsetime.avgresponse
24
+
25
+ ## License
26
+
27
+ The MIT License
28
+
29
+ Copyright (c) 2011 Matt Todd.
30
+
31
+ Permission is hereby granted, free of charge, to any person obtaining a copy
32
+ of this software and associated documentation files (the "Software"), to deal
33
+ in the Software without restriction, including without limitation the rights
34
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
35
+ copies of the Software, and to permit persons to whom the Software is
36
+ furnished to do so, subject to the following conditions:
37
+
38
+ The above copyright notice and this permission notice shall be included in
39
+ all copies or substantial portions of the Software.
40
+
41
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
44
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
46
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
47
+ THE SOFTWARE.
@@ -0,0 +1,435 @@
1
+ require 'faraday'
2
+
3
+ require 'active_support/core_ext/numeric/time'
4
+ require 'active_support/core_ext/time/acts_like'
5
+ require 'active_support/core_ext/time/calculations'
6
+ require 'active_support/core_ext/hash/indifferent_access'
7
+ require 'active_support/core_ext/hash/reverse_merge'
8
+ require 'active_support/core_ext/array/wrap'
9
+ require 'active_support/core_ext/hash/slice'
10
+
11
+ LOGGER = lambda do |app|
12
+ lambda do |env|
13
+ puts "Request: %s %s" % [env[:method], env[:url].to_s]
14
+ app.call(env)
15
+ end
16
+ end
17
+
18
+ module Pingdom
19
+ class Client
20
+
21
+ attr_accessor :limit
22
+
23
+ def initialize(credentials = {})
24
+ @connection = Faraday::Connection.new(:url => "https://api/pingdom.com/api/2.0/") do |builder|
25
+ builder.url_prefix = "https://api.pingdom.com/api/2.0"
26
+
27
+ builder.builder.run LOGGER
28
+
29
+ builder.adapter :excon
30
+
31
+ # builder.use Gzip # TODO: write GZip response handler, add Accept-Encoding: gzip header
32
+ builder.response :yajl
33
+ builder.use Tinder::FaradayResponse::WithIndifferentAccess
34
+
35
+ builder.basic_auth credentials[:username], credentials[:password]
36
+ end
37
+ end
38
+
39
+ # probes => [1,2,3] #=> probes => "1,2,3"
40
+ def prepare_params(options)
41
+ options.each do |(key, value)|
42
+ options[key] = Array.wrap(value).map(&:to_s).join(',')
43
+ options[key] = value.to_i if value.acts_like?(:time)
44
+ end
45
+
46
+ options
47
+ end
48
+
49
+ def get(uri, params = {}, &block)
50
+ response = @connection.get(@connection.build_url(uri, prepare_params(params)), &block)
51
+ update_limits!(response.headers['req-limit-short'], response.headers['req-limit-long'])
52
+ response
53
+ end
54
+
55
+ def update_limits!(short, long)
56
+ @limit ||= {}
57
+ @limit[:short] = parse_limit(short)
58
+ @limit[:long] = parse_limit(long)
59
+ @limit
60
+ end
61
+
62
+ # "Remaining: 394 Time until reset: 3589"
63
+ def parse_limit(limit)
64
+ if limit.to_s =~ /Remaining: (\d+) Time until reset: (\d+)/
65
+ { :remaining => $1.to_i,
66
+ :resets_at => $2.to_i.seconds.from_now }
67
+ end
68
+ end
69
+
70
+ def test!(options = {})
71
+ Result.parse(self, get("single", options)).first
72
+ end
73
+
74
+ def checks(options = {})
75
+ Check.parse(self, get("checks", options))
76
+ end
77
+ def check(id)
78
+ Check.parse(self, get("checks/#{id}"))
79
+ end
80
+
81
+ # Check ID
82
+ def results(id, options = {})
83
+ options.reverse_merge!(:includeanalysis => true)
84
+ Result.parse(self, get("results/#{id}", options))
85
+ end
86
+
87
+ def probes(options = {})
88
+ Probe.parse(self, get("probes", options))
89
+ end
90
+
91
+ def contacts(options = {})
92
+ Contact.parse(self, get("contacts", options))
93
+ end
94
+
95
+ def summary(id)
96
+ Summary.proxy(self, id)
97
+ end
98
+
99
+ end
100
+
101
+ class Base
102
+ def initialize(client, response, attributes = {})
103
+ @client = client
104
+ @response = response
105
+ @attributes = attributes
106
+ end
107
+
108
+ def self.attributes(hash)
109
+ hash.each do |(attribute, aliases)|
110
+ class_eval <<-"end;" unless instance_methods.include?(attribute.to_s)
111
+ def #{attribute}
112
+ @attributes[:#{attribute}]
113
+ end
114
+ end;
115
+
116
+ Array.wrap(aliases).each do |aliased|
117
+ alias_method aliased, attribute
118
+ end
119
+ end
120
+ end
121
+
122
+ def method_missing(name, *args, &block)
123
+ @attributes[name] or super
124
+ end
125
+
126
+ def respond_to?(name)
127
+ super(name) || @attributes.key?(name)
128
+ end
129
+
130
+ def id
131
+ @attributes[:id]
132
+ end
133
+
134
+ def inspect
135
+ "#<%s %s>" % [self.class.to_s, @attributes.inject([]){ |a, (k,v)| a << "%s: %s" % [k,v.inspect]; a }.join(' ')]
136
+ end
137
+
138
+ def self.check_error!(response)
139
+ if response.body.key?(:error)
140
+ raise Error, "%s (%s %s)" % [ response.body[:error][:errormessage],
141
+ response.body[:error][:statuscode],
142
+ response.body[:error][:statusdesc] ]
143
+ end
144
+ end
145
+
146
+ def self.parse(client, response)
147
+ check_error!(response)
148
+ response.body
149
+ end
150
+ end
151
+
152
+ # {"statusdesclong"=>"OK", "probeid"=>28, "responsetime"=>221, "statusdesc"=>"OK", "status"=>"up", "probedesc"=>"Amsterdam 2, Netherlands"}
153
+ class Result < Base
154
+ def self.parse(client, response)
155
+ results = super
156
+ Array.wrap(results[:results] || results[:result]).map do |result|
157
+ new(client, response, result)
158
+ end
159
+ end
160
+
161
+ attributes :responsetime => :response_time,
162
+ :probeid => :probe_id
163
+
164
+ def probe
165
+ @client.probes.detect{ |probe| probe.id == probe_id }
166
+ end
167
+ end
168
+
169
+ # {"name"=>"Autocomplete", "id"=>259103, "type"=>"http", "lastresponsetime"=>203173, "status"=>"up", "lasttesttime"=>1298102416}
170
+ class Check < Base
171
+ def self.parse(client, response)
172
+ super[:checks].map do |check|
173
+ new(client, response, check)
174
+ end
175
+ end
176
+
177
+ attributes :lastresponsetime => :last_response_time,
178
+ :lasttesttime => :last_test_time,
179
+ :lasterrortime => :last_error_time
180
+
181
+ def results(options = {})
182
+ @client.results(id, options)
183
+ end
184
+
185
+ def summary
186
+ @client.summary(id)
187
+ end
188
+
189
+ def lasttesttime
190
+ Time.at(super)
191
+ end
192
+
193
+ def lasterrortime
194
+ Time.at(super)
195
+ end
196
+
197
+ end
198
+
199
+ # {"city"=>"Manchester", "name"=>"Manchester, UK", "country"=>"United Kingdom",
200
+ # "countryiso"=>"GB", "id"=>46, "ip"=>"212.84.74.156", "hostname"=>"s424.pingdom.com", "active"=>true}
201
+ class Probe < Base
202
+ def self.parse(client, response)
203
+ super[:probes].map do |probe|
204
+ new(client, response, probe)
205
+ end
206
+ end
207
+
208
+ attributes :countryiso => [:country_iso, :country_code]
209
+
210
+ def test!(options)
211
+ @client.test!(options.merge(:probeid => id))
212
+ end
213
+
214
+ end
215
+
216
+ # {"name"=>"Larry Bernstein", "directtwitter"=>false, "id"=>142762, "cellphone"=>"1-510-501-7401",
217
+ # "paused"=>false, "defaultsmsprovider"=>"clickatell", "email"=>"lbernstein@demandbase.com"}
218
+ class Contact < Base
219
+ def self.parse(client, response)
220
+ super[:contacts].map do |contact|
221
+ new(client, response, contact)
222
+ end
223
+ end
224
+
225
+ attributes :cellphone => :phone
226
+
227
+ end
228
+
229
+ class Summary < Base
230
+
231
+ class Proxy < Struct.new(:client, :check_id)
232
+ def average(options = {})
233
+ options.reverse_merge!(:byprobe => true, :includeuptime => true)
234
+ Average.parse(client, client.get("summary.average/#{check_id}", options))
235
+ end
236
+ alias_method :averages, :average
237
+
238
+ def outage(options = {})
239
+ options.reverse_merge!(:byprobe => true, :includeuptime => true)
240
+ Outage.parse(client, client.get("summary.outage/#{check_id}", options))
241
+ end
242
+ alias_method :outages, :outage
243
+
244
+ def performance(options = {})
245
+ options.reverse_merge!(:resolution => :day, :includeuptime => true)
246
+ Performance.parse(client, client.get("summary.performance/#{check_id}", options))
247
+ end
248
+ end
249
+
250
+ def self.proxy(client, check)
251
+ Proxy.new(client, check)
252
+ end
253
+
254
+ def from
255
+ Time.at(@attributes[:from])
256
+ end
257
+
258
+ def to
259
+ Time.at(@attributes[:to])
260
+ end
261
+
262
+ attributes :responsetime => :response_time
263
+
264
+ # summary.average includeuptime probes=34,35 byprobe
265
+ # { "responsetime"=>{
266
+ # "from"=>0, "to"=>1298110456, "probes"=>"34, 35", "avgresponse"=>[
267
+ # {"probeid"=>35, "avgresponse"=>94},
268
+ # {"probeid"=>34, "avgresponse"=>125} ]},
269
+ # "status"=>{"totalup"=>5035757, "totalunknown"=>1293069551, "totaldown"=>5078}}
270
+ class Average < Base
271
+ def self.parse(client, response)
272
+ body = super[:summary]
273
+ sum = body[:responsetime]
274
+ attrs = sum.slice(:from, :to)
275
+ attrs[:probes] = (attrs[:probes] || "").gsub(/\w+/, '').split(',').map{|e| e.to_i }
276
+
277
+ sum[:status] = Status.new(client, response, body[:status]) if body.key?(:status)
278
+
279
+ case sum[:avgresponse]
280
+ when Array
281
+ sum[:responsetime] = 0
282
+ sum[:averages] =
283
+ sum.delete(:avgresponse).map do |avg|
284
+ sum[:responsetime] += avg[:avgresponse]
285
+ new(client, response, avg)
286
+ end
287
+ sum[:responsetime] = sum[:responsetime] / sum[:averages].size if sum[:averages].size > 0
288
+
289
+ when Integer
290
+ sum[:responsetime] = sum.delete(:avgresponse)
291
+
292
+ end
293
+
294
+ sum = Summary.new(client, response, sum)
295
+ end
296
+
297
+ attributes :probeid => :probe_id
298
+
299
+ def probe
300
+ @client.probes.detect{ |probe| probe.id == probe_id }
301
+ end
302
+
303
+ end
304
+
305
+ # summary.outage
306
+ # {"states"=>[{"timeto"=>1297587576, "timefrom"=>1297475316, "status"=>"up"},
307
+ # {"timeto"=>1297587906, "timefrom"=>1297587576, "status"=>"down"},
308
+ # {"timeto"=>1298110749, "timefrom"=>1297587906, "status"=>"up"}]}
309
+ class Outage < Base
310
+ def self.parse(client, response)
311
+ super[:summary][:states].
312
+ select{ |s| s[:status] == "down" }.
313
+ map do |outage|
314
+ new(client, response, outage)
315
+ end
316
+ end
317
+
318
+ def downtime
319
+ (@attributes[:timeto] - @attributes[:timefrom]).seconds
320
+ end
321
+
322
+ def timefrom
323
+ Time.at(@attributes[:timefrom])
324
+ end
325
+
326
+ def timeto
327
+ Time.at(@attributes[:timeto])
328
+ end
329
+
330
+ attributes :timefrom => [:time_from, :from],
331
+ :timeto => [:time_to, :to,]
332
+
333
+ end
334
+
335
+ # summary.performance includeuptime resolution=day
336
+ # {"days"=>[{"unmonitored"=>0, "downtime"=>0, "starttime"=>1297238400, "uptime"=>86400, "avgresponse"=>234},
337
+ # {"unmonitored"=>0, "downtime"=>0, "starttime"=>1297324800, "uptime"=>86400, "avgresponse"=>215},
338
+ # {"unmonitored"=>0, "downtime"=>2648, "starttime"=>1297411200, "uptime"=>83752, "avgresponse"=>211},
339
+ # {"unmonitored"=>0, "downtime"=>0, "starttime"=>1297497600, "uptime"=>86400, "avgresponse"=>207},
340
+ # {"unmonitored"=>0, "downtime"=>330, "starttime"=>1297584000, "uptime"=>86070, "avgresponse"=>228},
341
+ # {"unmonitored"=>0, "downtime"=>0, "starttime"=>1297670400, "uptime"=>86400, "avgresponse"=>236},
342
+ # {"unmonitored"=>0, "downtime"=>0, "starttime"=>1297756800, "uptime"=>86400, "avgresponse"=>230},
343
+ # {"unmonitored"=>0, "downtime"=>0, "starttime"=>1297843200, "uptime"=>86400, "avgresponse"=>256},
344
+ # {"unmonitored"=>0, "downtime"=>0, "starttime"=>1297929600, "uptime"=>86400, "avgresponse"=>216},
345
+ # {"unmonitored"=>0, "downtime"=>0, "starttime"=>1298016000, "uptime"=>86400, "avgresponse"=>251},
346
+ # {"unmonitored"=>0, "downtime"=>0, "starttime"=>1298102400, "uptime"=>8646, "avgresponse"=>223}]}
347
+ class Performance < Base
348
+ INTERVALS = {
349
+ "hour" => 1.hour,
350
+ "day" => 1.day,
351
+ "week" => 1.week
352
+ }
353
+
354
+ def self.parse(client, response)
355
+ body = super
356
+ interval = body.keys.detect{ |k| INTERVALS.keys.include?(k.to_s) }.to_sym
357
+ intervals = body[interval]
358
+
359
+ intervals.map do |perf|
360
+ perf[:interval] = interval
361
+ new(client, response, perf)
362
+ end
363
+ end
364
+
365
+ def starttime
366
+ Time.at(@attributes[:starttime])
367
+ end
368
+
369
+ def endtime
370
+ starttime + INTERVALS[interval.to_s].to_i
371
+ end
372
+ alias_method :end_at, :endtime
373
+
374
+ def uptime
375
+ @attributes[:uptime].seconds
376
+ end
377
+ def downtime
378
+ @attributes[:downtime].seconds
379
+ end
380
+ def unmonitored
381
+ @attributes[:unmonitored].seconds
382
+ end
383
+ def monitored
384
+ uptime + downtime
385
+ end
386
+ def period
387
+ monitored + unmonitored
388
+ end
389
+
390
+ end
391
+
392
+ # {"status"=>{"totalup"=>5035757, "totalunknown"=>1293069551, "totaldown"=>5078}}
393
+ class Status < Base
394
+ end
395
+
396
+ end
397
+
398
+ class Error < RuntimeError
399
+ end
400
+ end
401
+
402
+ # Taken from:
403
+ # https://github.com/collectiveidea/tinder/raw/master/lib/tinder/middleware.rb
404
+ # See:
405
+ # https://github.com/collectiveidea/tinder/blob/master/MIT-LICENSE
406
+ module Tinder
407
+ module FaradayResponse
408
+ class WithIndifferentAccess < ::Faraday::Response::Middleware
409
+ begin
410
+ require 'active_support/core_ext/hash/indifferent_access'
411
+ rescue LoadError, NameError => error
412
+ self.load_error = error
413
+ end
414
+
415
+ def self.register_on_complete(env)
416
+ env[:response].on_complete do |response|
417
+ json = response[:body]
418
+ if json.is_a?(Hash)
419
+ response[:body] = ::HashWithIndifferentAccess.new(json)
420
+ elsif json.is_a?(Array) and json.first.is_a?(Hash)
421
+ response[:body] = json.map{|item| ::HashWithIndifferentAccess.new(item) }
422
+ end
423
+ end
424
+ end
425
+ end
426
+
427
+ class RaiseOnAuthenticationFailure < ::Faraday::Response::Middleware
428
+ def self.register_on_complete(env)
429
+ env[:response].on_complete do |response|
430
+ raise AuthenticationFailed if response[:status] == 401
431
+ end
432
+ end
433
+ end
434
+ end
435
+ end
@@ -0,0 +1,66 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = %q{pingdom-client}
3
+ s.version = "0.0.0.alpha"
4
+
5
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
6
+ s.authors = ["Matt Todd"]
7
+ s.date = %q{2011-02-24}
8
+ s.description = %q{Pingdom Ruby Client}
9
+ s.email = %q{chiology@gmail.com}
10
+ s.files = [
11
+ "pingdom-client.gemspec",
12
+ "Gemfile",
13
+ "Gemfile.lock",
14
+ "lib/pingdom-client.rb",
15
+ "Rakefile",
16
+ "Readme.md",
17
+ "spec/pingdom-client_spec.rb",
18
+ "spec/spec_helper.rb"
19
+ ]
20
+ s.homepage = %q{http://github.com/mtodd/pingdom-client}
21
+ s.licenses = ["MIT"]
22
+ s.require_paths = ["lib"]
23
+ s.rubygems_version = %q{1.3.7}
24
+ s.summary = %q{Pingdom Ruby Client}
25
+ s.test_files = [
26
+ "spec/spec_helper.rb",
27
+ "spec/pingdom-client_spec.rb"
28
+ ]
29
+
30
+ if s.respond_to? :specification_version then
31
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
32
+ s.specification_version = 3
33
+
34
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
35
+ s.add_runtime_dependency("faraday", ["~> 0.5.6"])
36
+ s.add_runtime_dependency("excon", ["~> 0.5.6"])
37
+ s.add_runtime_dependency("yajl-ruby", ["~> 0.8.1"])
38
+ s.add_runtime_dependency("activesupport", ["~> 3.0.4"])
39
+ s.add_runtime_dependency("i18n", ["~> 0.5.0"])
40
+
41
+ s.add_development_dependency("bundler", ["~> 1.0.0"])
42
+ s.add_development_dependency("rake", ["~> 0.8.7"])
43
+ s.add_development_dependency("rspec", ["= 2.1.0"])
44
+ else
45
+ s.add_dependency("faraday", ["~> 0.5.6"])
46
+ s.add_dependency("excon", ["~> 0.5.6"])
47
+ s.add_dependency("yajl-ruby", ["~> 0.8.1"])
48
+ s.add_dependency("activesupport", ["~> 3.0.4"])
49
+ s.add_dependency("i18n", ["~> 0.5.0"])
50
+
51
+ s.add_dependency("bundler", ["~> 1.0.0"])
52
+ s.add_dependency("rake", ["~> 0.8.7"])
53
+ s.add_dependency("rspec", ["= 2.1.0"])
54
+ end
55
+ else
56
+ s.add_dependency("faraday", ["~> 0.5.6"])
57
+ s.add_dependency("excon", ["~> 0.5.6"])
58
+ s.add_dependency("yajl-ruby", ["~> 0.8.1"])
59
+ s.add_dependency("activesupport", ["~> 3.0.4"])
60
+ s.add_dependency("i18n", ["~> 0.5.0"])
61
+
62
+ s.add_dependency("bundler", ["~> 1.0.0"])
63
+ s.add_dependency("rake", ["~> 0.8.7"])
64
+ s.add_dependency("rspec", ["= 2.1.0"])
65
+ end
66
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe Pingdom::Client do
4
+ let(:client){ Pingdom::Client.new(CREDENTIALS) }
5
+
6
+ describe "#test!" do
7
+ it "should test a single endpoint" do
8
+ response = client.test!(:host => "pingdom.com", :type => "http")
9
+
10
+ response.status.should == "up"
11
+ response.responsetime.should be_a(Numeric)
12
+ end
13
+ end
14
+
15
+ describe "#checks" do
16
+ it "should get a list of checks" do
17
+ checks = client.checks
18
+
19
+ first = checks.first
20
+ first.should be_a(Pingdom::Check)
21
+ first.last_response_time.should be_a(Numeric)
22
+ end
23
+ end
24
+
25
+ describe "#limit" do
26
+ { :short => "short term",
27
+ :long => "long term" }.each do |(key, label)|
28
+ describe label do
29
+ let(:limit){ client.test!(:host => "pingdom.com", :type => "http"); client.limit[key] }
30
+
31
+ it "should indicate how many requests can be made" do
32
+ limit[:remaining].should be_a(Numeric)
33
+ end
34
+
35
+ it "should indicate when the current limit will be reset" do
36
+ limit[:resets_at].acts_like?(:time).should be_true
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ end
@@ -0,0 +1,8 @@
1
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
2
+ require 'rubygems'
3
+ require 'bundler/setup'
4
+ require 'pingdom-client'
5
+
6
+ require 'rspec'
7
+
8
+ CREDENTIALS = YAML.load_file(File.join(File.dirname(__FILE__), '..', 'credentials.yml')).inject({}){ |h,(k,v)| h[k.to_sym] = v; h }
metadata ADDED
@@ -0,0 +1,203 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pingdom-client
3
+ version: !ruby/object:Gem::Version
4
+ hash: -1851332162
5
+ prerelease: true
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 0
10
+ - alpha
11
+ version: 0.0.0.alpha
12
+ platform: ruby
13
+ authors:
14
+ - Matt Todd
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2011-02-24 00:00:00 -05:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: faraday
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ hash: 7
31
+ segments:
32
+ - 0
33
+ - 5
34
+ - 6
35
+ version: 0.5.6
36
+ type: :runtime
37
+ version_requirements: *id001
38
+ - !ruby/object:Gem::Dependency
39
+ name: excon
40
+ prerelease: false
41
+ requirement: &id002 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ hash: 7
47
+ segments:
48
+ - 0
49
+ - 5
50
+ - 6
51
+ version: 0.5.6
52
+ type: :runtime
53
+ version_requirements: *id002
54
+ - !ruby/object:Gem::Dependency
55
+ name: yajl-ruby
56
+ prerelease: false
57
+ requirement: &id003 !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ hash: 61
63
+ segments:
64
+ - 0
65
+ - 8
66
+ - 1
67
+ version: 0.8.1
68
+ type: :runtime
69
+ version_requirements: *id003
70
+ - !ruby/object:Gem::Dependency
71
+ name: activesupport
72
+ prerelease: false
73
+ requirement: &id004 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ~>
77
+ - !ruby/object:Gem::Version
78
+ hash: 15
79
+ segments:
80
+ - 3
81
+ - 0
82
+ - 4
83
+ version: 3.0.4
84
+ type: :runtime
85
+ version_requirements: *id004
86
+ - !ruby/object:Gem::Dependency
87
+ name: i18n
88
+ prerelease: false
89
+ requirement: &id005 !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ~>
93
+ - !ruby/object:Gem::Version
94
+ hash: 11
95
+ segments:
96
+ - 0
97
+ - 5
98
+ - 0
99
+ version: 0.5.0
100
+ type: :runtime
101
+ version_requirements: *id005
102
+ - !ruby/object:Gem::Dependency
103
+ name: bundler
104
+ prerelease: false
105
+ requirement: &id006 !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ hash: 23
111
+ segments:
112
+ - 1
113
+ - 0
114
+ - 0
115
+ version: 1.0.0
116
+ type: :development
117
+ version_requirements: *id006
118
+ - !ruby/object:Gem::Dependency
119
+ name: rake
120
+ prerelease: false
121
+ requirement: &id007 !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ~>
125
+ - !ruby/object:Gem::Version
126
+ hash: 49
127
+ segments:
128
+ - 0
129
+ - 8
130
+ - 7
131
+ version: 0.8.7
132
+ type: :development
133
+ version_requirements: *id007
134
+ - !ruby/object:Gem::Dependency
135
+ name: rspec
136
+ prerelease: false
137
+ requirement: &id008 !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - "="
141
+ - !ruby/object:Gem::Version
142
+ hash: 11
143
+ segments:
144
+ - 2
145
+ - 1
146
+ - 0
147
+ version: 2.1.0
148
+ type: :development
149
+ version_requirements: *id008
150
+ description: Pingdom Ruby Client
151
+ email: chiology@gmail.com
152
+ executables: []
153
+
154
+ extensions: []
155
+
156
+ extra_rdoc_files: []
157
+
158
+ files:
159
+ - pingdom-client.gemspec
160
+ - Gemfile
161
+ - Gemfile.lock
162
+ - lib/pingdom-client.rb
163
+ - Rakefile
164
+ - Readme.md
165
+ - spec/pingdom-client_spec.rb
166
+ - spec/spec_helper.rb
167
+ has_rdoc: true
168
+ homepage: http://github.com/mtodd/pingdom-client
169
+ licenses:
170
+ - MIT
171
+ post_install_message:
172
+ rdoc_options: []
173
+
174
+ require_paths:
175
+ - lib
176
+ required_ruby_version: !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ hash: 3
182
+ segments:
183
+ - 0
184
+ version: "0"
185
+ required_rubygems_version: !ruby/object:Gem::Requirement
186
+ none: false
187
+ requirements:
188
+ - - ">="
189
+ - !ruby/object:Gem::Version
190
+ hash: 3
191
+ segments:
192
+ - 0
193
+ version: "0"
194
+ requirements: []
195
+
196
+ rubyforge_project:
197
+ rubygems_version: 1.3.7
198
+ signing_key:
199
+ specification_version: 3
200
+ summary: Pingdom Ruby Client
201
+ test_files:
202
+ - spec/spec_helper.rb
203
+ - spec/pingdom-client_spec.rb