dogapi 1.8.1 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/.rspec +2 -0
  2. data/.tailor +106 -0
  3. data/CHANGELOG.md +3 -0
  4. data/Gemfile +7 -0
  5. data/README.rdoc +4 -1
  6. data/Rakefile +31 -2
  7. data/lib/capistrano/datadog.rb +6 -10
  8. data/lib/dogapi/common.rb +1 -1
  9. data/lib/dogapi/event.rb +6 -6
  10. data/lib/dogapi/facade.rb +34 -45
  11. data/lib/dogapi/v1/alert.rb +1 -1
  12. data/lib/dogapi/v1/comment.rb +3 -3
  13. data/lib/dogapi/v1/dash.rb +1 -2
  14. data/lib/dogapi/v1/event.rb +1 -1
  15. data/lib/dogapi/v1/metric.rb +3 -3
  16. data/lib/dogapi/v1/user.rb +1 -1
  17. data/lib/dogapi/version.rb +1 -1
  18. data/spec/alerts_spec.rb +33 -0
  19. data/spec/common_spec.rb +16 -0
  20. data/spec/facade_spec.rb +122 -0
  21. data/spec/spec_helper.rb +28 -0
  22. data/spec/support/cassettes/Alerts/create/returns_HTTP_code_201.yml +90 -0
  23. data/spec/support/cassettes/Alerts/create/returns_a_valid_event_ID.yml +90 -0
  24. data/spec/support/cassettes/Alerts/create/returns_the_same_query_as_sent.yml +90 -0
  25. data/spec/support/cassettes/Facade/Client/emit_point_can_pass_nil_host.yml +32 -0
  26. data/spec/support/cassettes/Facade/Client/emit_point_passes_data.yml +32 -0
  27. data/spec/support/cassettes/Facade/Client/emit_point_uses_localhost_default.yml +32 -0
  28. data/spec/support/cassettes/Facade/Client/emits_point_with_localhost.yml +32 -0
  29. data/spec/support/cassettes/Facade/Events/emits_aggregate_events.yml +131 -0
  30. data/spec/support/cassettes/Facade/Events/emits_events_and_retrieves_them.yml +67 -0
  31. data/spec/support/cassettes/Facade/Events/emits_events_with_specified_priority.yml +67 -0
  32. data/spec/support/cassettes/Facade/Tags/adds_updates_and_detaches_tags.yml +352 -0
  33. data/tests/test_alerts.rb +3 -3
  34. data/tests/test_client.rb +0 -114
  35. data/tests/test_dashes.rb +3 -2
  36. metadata +38 -7
@@ -7,7 +7,7 @@ module Dogapi
7
7
 
8
8
  API_VERSION = "v1"
9
9
 
10
- def alert(query, options={})
10
+ def alert(query, options = {})
11
11
  begin
12
12
  params = {
13
13
  :api_key => @api_key,
@@ -8,7 +8,7 @@ module Dogapi
8
8
  API_VERSION = "v1"
9
9
 
10
10
  # Submit a comment.
11
- def comment(message, options={})
11
+ def comment(message, options = {})
12
12
  begin
13
13
  params = {
14
14
  :api_key => @api_key,
@@ -16,7 +16,7 @@ module Dogapi
16
16
  }
17
17
 
18
18
  body = {
19
- 'message' => message,
19
+ 'message' => message,
20
20
  }.merge options
21
21
 
22
22
  request(Net::HTTP::Post, "/api/#{API_VERSION}/comments", params, body, true)
@@ -26,7 +26,7 @@ module Dogapi
26
26
  end
27
27
 
28
28
  # Update a comment.
29
- def update_comment(comment_id, options={})
29
+ def update_comment(comment_id, options = {})
30
30
  begin
31
31
  params = {
32
32
  :api_key => @api_key,
@@ -7,7 +7,7 @@ module Dogapi
7
7
 
8
8
  API_VERSION = "v1"
9
9
 
10
- def create_dashboard(title, description, graphs, template_variables=nil)
10
+ def create_dashboard(title, description, graphs, template_variables = nil)
11
11
 
12
12
  begin
13
13
  params = {
@@ -75,7 +75,6 @@ module Dogapi
75
75
  end
76
76
  end
77
77
 
78
-
79
78
  def delete_dashboard(dash_id)
80
79
  begin
81
80
  params = {
@@ -54,7 +54,7 @@ module Dogapi
54
54
  end
55
55
  end
56
56
 
57
- def stream(start, stop, options={})
57
+ def stream(start, stop, options = {})
58
58
  begin
59
59
  defaults = {
60
60
  :priority => nil,
@@ -9,7 +9,7 @@ module Dogapi
9
9
  API_VERSION = "v1"
10
10
 
11
11
  # Records an Event with no duration
12
- def submit(metric, points, scope, options={})
12
+ def submit(metric, points, scope, options = {})
13
13
  begin
14
14
  params = {
15
15
  :api_key => @api_key
@@ -20,7 +20,8 @@ module Dogapi
20
20
  raise ArgumentError, "metric type must be gauge or counter"
21
21
  end
22
22
 
23
- body = { :series => [
23
+ body = {
24
+ :series => [
24
25
  {
25
26
  :metric => metric,
26
27
  :points => points,
@@ -31,7 +32,6 @@ module Dogapi
31
32
  ]
32
33
  }
33
34
 
34
-
35
35
  # Add tags if there are any
36
36
  if not options[:tags].nil?
37
37
  body[:series][0][:tags] = options[:tags]
@@ -7,7 +7,7 @@ module Dogapi
7
7
 
8
8
  API_VERSION = "v1"
9
9
 
10
- def invite(emails, options={})
10
+ def invite(emails, options = {})
11
11
  begin
12
12
  params = {
13
13
  :api_key => @api_key,
@@ -1,3 +1,3 @@
1
1
  module Dogapi
2
- VERSION = "1.8.1"
2
+ VERSION = "1.9.0"
3
3
  end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Alerts", :vcr => true do
4
+
5
+ before(:all) do
6
+ @api_key = ENV["DATADOG_API_KEY"]
7
+ @app_key = ENV["DATADOG_APP_KEY"]
8
+ @dog = Dogapi::Client.new(@api_key, @app_key)
9
+ @query = 'avg(last_10m):avg:test.metric.metric{host:test.metric.host} > 5'
10
+ end
11
+
12
+ context "create" do
13
+ before(:each) do
14
+ @new_alert = @dog.alert(@query)
15
+ end
16
+ after(:each) do
17
+ @dog.delete_alert(@new_alert[1]['id'])
18
+ end
19
+
20
+ it "returns HTTP code 201" do
21
+ expect(@new_alert[0]).to eq '201'
22
+ end
23
+
24
+ it "returns a valid event ID" do
25
+ expect(@new_alert[1]['id']).to be_a(Fixnum)
26
+ end
27
+
28
+ it "returns the same query as sent" do
29
+ expect(@new_alert[1]['query']).to eq @query
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Common" do
4
+
5
+ context "Scope" do
6
+
7
+ it "validates the Scope class" do
8
+ obj = Dogapi::Scope.new("somehost", "somedevice")
9
+
10
+ expect(obj.host).to eq "somehost"
11
+ expect(obj.device).to eq "somedevice"
12
+ end
13
+
14
+ end # end Scope
15
+
16
+ end # end Common
@@ -0,0 +1,122 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Facade", :vcr => true do
4
+
5
+ before(:all) do
6
+ @api_key = ENV["DATADOG_API_KEY"]
7
+ @app_key = ENV["DATADOG_APP_KEY"]
8
+ @job_number = ENV['TRAVIS_JOB_NUMBER'] || '1'
9
+ @dog = Dogapi::Client.new(@api_key, @app_key)
10
+ end
11
+
12
+ context "Client" do
13
+
14
+ before(:each) do
15
+ @dogmock = Dogapi::Client.new(@api_key, @app_key)
16
+ @metric_svc = double
17
+ @dogmock.instance_variable_set("@metric_svc", @metric_svc)
18
+ end
19
+
20
+ it "emit_point passes data" do
21
+ expect(@metric_svc).to receive(:submit) do |metric, points, scope, options|
22
+ expect(metric).to eq "metric.name"
23
+ expect(points[0][1]).to eq 0
24
+ expect(scope.host).to eq "myhost"
25
+ end
26
+ @dogmock.emit_point("metric.name", 0, :host => "myhost")
27
+ end
28
+
29
+ it "emit_point uses localhost default" do
30
+ expect(@metric_svc).to receive(:submit) do |metric, points, scope, options|
31
+ expect(scope.host).to eq Dogapi.find_localhost
32
+ end
33
+ @dogmock.emit_point("metric.name", 0)
34
+ end
35
+
36
+ it "emit_point can pass nil host" do
37
+ expect(@metric_svc).to receive(:submit) do |metric, points, scope, options|
38
+ expect(scope.host).to be_nil
39
+ end
40
+ @dogmock.emit_point("metric.name", 0, :host => nil)
41
+ end
42
+
43
+ end
44
+
45
+ context "Events" do
46
+
47
+ it "emits events and retrieves them" do
48
+ now = Time.now()
49
+
50
+ # Tag the events with the build number, because Travis parallel testing
51
+ # can cause problems with the event stream
52
+ tags = ["test-run:#{@job_number}"]
53
+
54
+ now_ts = now
55
+ now_title = 'dogapi-rb end test title ' + now_ts.to_i.to_s
56
+ now_message = 'test message'
57
+
58
+
59
+ event = Dogapi::Event.new(now_message, :msg_title => now_title,
60
+ :date_happened => now_ts, :tags => tags)
61
+
62
+ code, resp = @dog.emit_event(event)
63
+ now_event_id = resp["event"]["id"]
64
+
65
+ code, resp = @dog.get_event(now_event_id)
66
+ expect(resp['event']).not_to be_nil
67
+ expect(resp['event']['text']).to eq(now_message)
68
+ end
69
+
70
+ it "emits events with specified priority" do
71
+ event = Dogapi::Event.new('test message', :msg_title => 'title', :date_happened => Time.now(), :priority => "low")
72
+ code, resp = @dog.emit_event(event)
73
+ low_event_id = resp["event"]["id"]
74
+
75
+ code, resp = @dog.get_event(low_event_id)
76
+ expect(resp['event']).not_to be_nil
77
+ low_event = resp['event']
78
+ expect(low_event['priority']).to eq("low")
79
+ end
80
+
81
+ it "emits aggregate events" do
82
+ now = Time.now()
83
+ code, resp = @dog.emit_event(Dogapi::Event.new("Testing Aggregation (first)", :aggregation_key => now.to_i))
84
+ first = resp["event"]["id"]
85
+ code, resp = @dog.emit_event(Dogapi::Event.new("Testing Aggregation (second)", :aggregation_key => now.to_i))
86
+ second = resp["event"]["id"]
87
+
88
+ code, resp = @dog.get_event(first)
89
+ expect(resp["event"]).not_to be_nil
90
+ code, resp = @dog.get_event(second)
91
+ expect(resp["event"]).not_to be_nil
92
+ end
93
+
94
+ end
95
+
96
+ context "Tags" do
97
+ it "adds, updates and detaches tags" do
98
+ hostname = "test.tag.host"
99
+
100
+ @dog.emit_point('test.tag.metric', 1, :host => hostname)
101
+
102
+ @dog.detach_tags(hostname)
103
+ code, resp = @dog.host_tags(hostname)
104
+ expect(resp["tags"]).to be_empty
105
+
106
+ @dog.add_tags(hostname, ['test.tag.1', 'test.tag.2'])
107
+ code, resp = @dog.host_tags(hostname)
108
+ new_tags = resp["tags"]
109
+ expect(new_tags).to match_array(['test.tag.1', 'test.tag.2'])
110
+
111
+ @dog.add_tags(hostname, ['test.tag.3'])
112
+ code, resp = @dog.host_tags(hostname)
113
+ new_tags = resp["tags"]
114
+ expect(new_tags).to match_array(['test.tag.1', 'test.tag.2', 'test.tag.3'])
115
+
116
+ @dog.detach_tags(hostname)
117
+ code, resp = @dog.host_tags(hostname)
118
+ expect(resp["tags"]).to be_empty
119
+ end
120
+ end
121
+
122
+ end
@@ -0,0 +1,28 @@
1
+ require 'rspec'
2
+ require 'vcr'
3
+
4
+ # include our code and methods
5
+ require 'dogapi'
6
+
7
+ # Load any custom matchers
8
+ Dir[File.join(File.dirname(__FILE__), "/support/**/*.rb")].each { |f| require f }
9
+
10
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
11
+ RSpec.configure do |config|
12
+ config.treat_symbols_as_metadata_keys_with_true_values = true
13
+ config.run_all_when_everything_filtered = true
14
+ config.filter_run :focus
15
+
16
+ # Run specs in random order to surface order dependencies. If you find an
17
+ # order dependency and want to debug it, you can fix the order by providing
18
+ # the seed, which is printed after each run.
19
+ # --seed 1234
20
+ config.order = 'random'
21
+ end
22
+
23
+ VCR.configure do |c|
24
+ c.cassette_library_dir = 'spec/support/cassettes'
25
+ c.configure_rspec_metadata!
26
+ c.default_cassette_options = { :record => :new_episodes, :re_record_interval => 2592000 } # 30 days, in seconds
27
+ c.hook_into :webmock
28
+ end
@@ -0,0 +1,90 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://app.datadoghq.com/api/v1/alert?api_key=9775a026f1ca7d1c6c5af9d94d9595a4&application_key=87ce4a24b5553d2e482ea8a8500e71b8ad4554ff
6
+ body:
7
+ encoding: UTF-8
8
+ string: ! '{"query":"avg(last_10m):avg:test.metric.metric{host:test.metric.host}
9
+ > 5"}'
10
+ headers:
11
+ Accept:
12
+ - ! '*/*'
13
+ User-Agent:
14
+ - Ruby
15
+ Content-Type:
16
+ - application/json
17
+ response:
18
+ status:
19
+ code: 201
20
+ message: Created
21
+ headers:
22
+ Cache-Control:
23
+ - no-cache
24
+ Content-Type:
25
+ - application/json
26
+ Date:
27
+ - Tue, 27 Aug 2013 16:13:42 GMT
28
+ Pragma:
29
+ - no-cache
30
+ Server:
31
+ - gunicorn/0.17.4
32
+ Set-Cookie:
33
+ - user={"org":{"id":1499},"_type":"User","id":3658}; Path=/
34
+ X-Dd-Version:
35
+ - 31.153-293-3859d5c
36
+ Content-Length:
37
+ - '328'
38
+ Connection:
39
+ - keep-alive
40
+ body:
41
+ encoding: US-ASCII
42
+ string: ! '{"notify_no_data": false, "event_object": "6bc5a22ffc9d267c3cd6eb3ad79623e0",
43
+ "state": "OK", "name": "avg(last_10m):avg:test.metric.metric{host:test.metric.host}
44
+ > 5", "silenced": false, "query": "avg(last_10m):avg:test.metric.metric{host:test.metric.host}
45
+ > 5", "message": null, "creator": 3658, "id": 37498, "timeout_h": null}'
46
+ http_version:
47
+ recorded_at: Tue, 27 Aug 2013 16:13:42 GMT
48
+ - request:
49
+ method: delete
50
+ uri: https://app.datadoghq.com/api/v1/alert/37498?api_key=9775a026f1ca7d1c6c5af9d94d9595a4&application_key=87ce4a24b5553d2e482ea8a8500e71b8ad4554ff
51
+ body:
52
+ encoding: US-ASCII
53
+ string: ''
54
+ headers:
55
+ Accept:
56
+ - ! '*/*'
57
+ User-Agent:
58
+ - Ruby
59
+ response:
60
+ status:
61
+ code: 200
62
+ message: OK
63
+ headers:
64
+ Cache-Control:
65
+ - no-cache
66
+ Content-Type:
67
+ - application/json
68
+ Date:
69
+ - Tue, 27 Aug 2013 16:13:42 GMT
70
+ Pragma:
71
+ - no-cache
72
+ Server:
73
+ - gunicorn/0.17.4
74
+ Set-Cookie:
75
+ - user={"org":{"id":1499},"_type":"User","id":3658}; Path=/
76
+ X-Dd-Version:
77
+ - 31.153-293-3859d5c
78
+ Content-Length:
79
+ - '315'
80
+ Connection:
81
+ - keep-alive
82
+ body:
83
+ encoding: US-ASCII
84
+ string: ! '{"notify_no_data": false, "event_object": "6bc5a22ffc9d267c3cd6eb3ad79623e0",
85
+ "state": "OK", "name": "avg(last_10m):avg:test.metric.metric{host:test.metric.host}
86
+ > 5", "silenced": false, "query": "avg(last_10m):avg:test.metric.metric{host:test.metric.host}
87
+ > 5", "message": null, "creator": 3658, "timeout_h": null}'
88
+ http_version:
89
+ recorded_at: Tue, 27 Aug 2013 16:13:42 GMT
90
+ recorded_with: VCR 2.5.0
@@ -0,0 +1,90 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://app.datadoghq.com/api/v1/alert?api_key=9775a026f1ca7d1c6c5af9d94d9595a4&application_key=87ce4a24b5553d2e482ea8a8500e71b8ad4554ff
6
+ body:
7
+ encoding: UTF-8
8
+ string: ! '{"query":"avg(last_10m):avg:test.metric.metric{host:test.metric.host}
9
+ > 5"}'
10
+ headers:
11
+ Accept:
12
+ - ! '*/*'
13
+ User-Agent:
14
+ - Ruby
15
+ Content-Type:
16
+ - application/json
17
+ response:
18
+ status:
19
+ code: 201
20
+ message: Created
21
+ headers:
22
+ Cache-Control:
23
+ - no-cache
24
+ Content-Type:
25
+ - application/json
26
+ Date:
27
+ - Tue, 27 Aug 2013 16:13:42 GMT
28
+ Pragma:
29
+ - no-cache
30
+ Server:
31
+ - gunicorn/0.17.4
32
+ Set-Cookie:
33
+ - user={"org":{"id":1499},"_type":"User","id":3658}; Path=/
34
+ X-Dd-Version:
35
+ - 31.153-293-3859d5c
36
+ Content-Length:
37
+ - '328'
38
+ Connection:
39
+ - keep-alive
40
+ body:
41
+ encoding: US-ASCII
42
+ string: ! '{"notify_no_data": false, "event_object": "6bc5a22ffc9d267c3cd6eb3ad79623e0",
43
+ "state": "OK", "name": "avg(last_10m):avg:test.metric.metric{host:test.metric.host}
44
+ > 5", "silenced": false, "query": "avg(last_10m):avg:test.metric.metric{host:test.metric.host}
45
+ > 5", "message": null, "creator": 3658, "id": 37497, "timeout_h": null}'
46
+ http_version:
47
+ recorded_at: Tue, 27 Aug 2013 16:13:41 GMT
48
+ - request:
49
+ method: delete
50
+ uri: https://app.datadoghq.com/api/v1/alert/37497?api_key=9775a026f1ca7d1c6c5af9d94d9595a4&application_key=87ce4a24b5553d2e482ea8a8500e71b8ad4554ff
51
+ body:
52
+ encoding: US-ASCII
53
+ string: ''
54
+ headers:
55
+ Accept:
56
+ - ! '*/*'
57
+ User-Agent:
58
+ - Ruby
59
+ response:
60
+ status:
61
+ code: 200
62
+ message: OK
63
+ headers:
64
+ Cache-Control:
65
+ - no-cache
66
+ Content-Type:
67
+ - application/json
68
+ Date:
69
+ - Tue, 27 Aug 2013 16:13:42 GMT
70
+ Pragma:
71
+ - no-cache
72
+ Server:
73
+ - gunicorn/0.17.4
74
+ Set-Cookie:
75
+ - user={"org":{"id":1499},"_type":"User","id":3658}; Path=/
76
+ X-Dd-Version:
77
+ - 31.153-293-3859d5c
78
+ Content-Length:
79
+ - '315'
80
+ Connection:
81
+ - keep-alive
82
+ body:
83
+ encoding: US-ASCII
84
+ string: ! '{"notify_no_data": false, "event_object": "6bc5a22ffc9d267c3cd6eb3ad79623e0",
85
+ "state": "OK", "name": "avg(last_10m):avg:test.metric.metric{host:test.metric.host}
86
+ > 5", "silenced": false, "query": "avg(last_10m):avg:test.metric.metric{host:test.metric.host}
87
+ > 5", "message": null, "creator": 3658, "timeout_h": null}'
88
+ http_version:
89
+ recorded_at: Tue, 27 Aug 2013 16:13:42 GMT
90
+ recorded_with: VCR 2.5.0