dogapi 1.39.0 → 1.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 220b05feea1448dc86ed0be4b9efdc730ff56d561965d9e004de6c6c2daf8091
4
- data.tar.gz: 2d161a3452ad1e7fe0e4d0039bf10866f10fd868ac008fe6d0b17485395289fb
3
+ metadata.gz: c64317943c656727e705f3ba310961de9fa8b3fda8fbcb976095d634d7311ecd
4
+ data.tar.gz: bb3f1977f9bd6bcd6d22779e23e247803b7800a1a0770e266d461878b68d574c
5
5
  SHA512:
6
- metadata.gz: 5c835303762440f2e6293d308dfd7cc19585194572960fd4244e8ac84035733d5fa47622b28b74b61ca5356a0f87aeba97385ee6dd3108b4a24f0c307fc5761b
7
- data.tar.gz: b4ae214e6f20ae634e32492c87dd9c50010d0c9ef8e4635a1cd9e76ebef75992bc215e096673ad01052ea00a770b25e95e85ce8a4bd0ddfdb94f690738f1c6ce
6
+ metadata.gz: f2814b96964abfc35ade6827652aed52c0b2795aa71f47a4a8a9152d7f97a013bb18680060657df015aeb0cb925cce58a16780c67df56397256d9e4c10aa8fcc
7
+ data.tar.gz: f9b7cb7ec7486d40af67d12ad68e44787e3e890efb0a98a9a5093875eba00eb0c19556a6b4fd35246611ffdc4cfe3b1aa2750750d001f6e145a8fe52085aac46
@@ -9,10 +9,36 @@ pr:
9
9
  include:
10
10
  - master
11
11
 
12
+ resources:
13
+ containers:
14
+ - container: datadog-agent
15
+ image: datadog/agent:7
16
+ options: --health-cmd="exit 0" --health-interval=1s
17
+ ports:
18
+ - 8125:8125
19
+ - 8126:8126/tcp
20
+ env:
21
+ DD_API_KEY: $(ddAPIKey)
22
+ DD_APM_ENABLED: "true"
23
+ DD_APM_NON_LOCAL_TRAFFIC: "true"
24
+ DD_LOGS_ENABLED: "true"
25
+ DD_LOGS_CONFIG_CONTAINER_COLLECT_ALL: "true"
26
+ DD_AC_EXCLUDE: "name:datadog-agent"
27
+ volumes:
28
+ - /var/run/docker.sock:/var/run/docker.sock:ro
29
+ - /proc/:/host/proc/:ro
30
+ - /sys/fs/cgroup/:/host/sys/fs/cgroup:ro
31
+
12
32
  jobs:
13
33
  - job: UnitTests
14
34
  pool:
15
35
  vmImage: "Ubuntu-16.04"
36
+ container:
37
+ image: ruby:$(RUBY_VERSION)
38
+ options: >-
39
+ -l com.datadoghq.ad.logs="[{\"source\": \"Azure Pipeline\", \"service\": \"dogapi-rb\"}]"
40
+ services:
41
+ datadog-agent: datadog-agent
16
42
  strategy:
17
43
  matrix:
18
44
  Rb24:
@@ -31,17 +57,19 @@ jobs:
31
57
  RUBY_VERSION: '2.6'
32
58
  TASK: rubocop
33
59
  steps:
34
- - task: UseRubyVersion@0
35
- displayName: Use Ruby $(RUBY_VERSION)
36
- inputs:
37
- versionSpec: $(RUBY_VERSION)
38
- addToPath: true
39
- - script: |
40
- gem install bundler
41
- bundle install --retry=3 --jobs=4
60
+ - script: bundle install --retry=3 --jobs=4
42
61
  displayName: 'bundle install'
62
+ env:
63
+ GEM_HOME: '~/.gem'
43
64
  - script: bundle exec rake $(TASK)
44
65
  displayName: Run $(TASK) via bundle
66
+ env:
67
+ GEM_HOME: '~/.gem'
68
+ DD_AGENT_HOST: datadog-agent
69
+ DD_ENV: ci
70
+ DD_SERVICE: dogapi-rb
71
+ DD_TAGS: "team:integration-tools-and-libraries,runtime:ruby-$(RUBY_VERSION),ci.job.name:$(System.JobName),matrix:$(TASK)"
72
+ DD_TRACE_ANALYTICS_ENABLED: "true"
45
73
  - job: TestRuby19
46
74
  pool:
47
75
  vmImage: "Ubuntu-16.04"
@@ -14,4 +14,8 @@ Metrics/LineLength:
14
14
  Metrics/ModuleLength:
15
15
  Max: 200
16
16
 
17
+ # Our Client constructor has 8 arguments
18
+ Metrics/ParameterLists:
19
+ Enabled: false
20
+
17
21
  inherit_from: .rubocop_todo.yml
@@ -520,3 +520,6 @@ Style/YodaCondition:
520
520
  Style/ZeroLengthPredicate:
521
521
  Exclude:
522
522
  - 'lib/capistrano/datadog.rb'
523
+
524
+ Style/SymbolArray:
525
+ EnforcedStyle: brackets # Since ruby1.9 is supported
@@ -1,5 +1,26 @@
1
1
  # Changes
2
2
 
3
+ ## 1.44.0 / 2020-12-10
4
+
5
+ * [Added] Allow skipping SSL verification. See [#246](https://github.com/DataDog/dogapi-rb/pull/246).
6
+
7
+ ## 1.43.0 / 2020-12-07
8
+
9
+ * [Fixed] find_localhost: Try both `hostname` and `hostname -f` before raising. See [#242](https://github.com/DataDog/dogapi-rb/pull/242).
10
+
11
+ ## 1.42.0 / 2020-09-17
12
+
13
+ * [Added] Allow dashboard creation / updates using Template Variable Presets. See [#238](https://github.com/DataDog/dogapi-rb/pull/238).
14
+
15
+ ## 1.41.0 / 2020-07-27
16
+
17
+ * [Added] Improve user-agent header to include telemetry information. See [#235](https://github.com/DataDog/dogapi-rb/pull/235).
18
+ * [Added] Move setting hostname to end of method body in order to actually return it. See [#233](https://github.com/DataDog/dogapi-rb/pull/233).
19
+
20
+ ## 1.40.0 / 2020-04-06
21
+
22
+ * [Added] Re-add service level objectives support. See [#224](https://github.com/DataDog/dogapi-rb/pull/224).
23
+
3
24
  ## 1.39.0 / 2020-02-04
4
25
 
5
26
  * [Added] Allow Setting Proxy without Using HTTP_PROXY, etc.. See [#180](https://github.com/DataDog/dogapi-rb/pull/180). Thanks [KingAlex42](https://github.com/KingAlex42).
data/Gemfile CHANGED
@@ -3,8 +3,8 @@ source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  group :test do
6
+ gem 'ddtrace', git: 'https://github.com/datadog/dd-trace-rb'
6
7
  gem 'rubocop', "~> 0.49.0"
7
- gem 'rake', '>= 2.4.2'
8
8
  gem 'rspec'
9
9
  gem 'simplecov'
10
10
  gem 'webmock'
@@ -4,7 +4,6 @@ gemspec
4
4
 
5
5
  group :test do
6
6
  gem 'rubocop', "~> 0.41.0"
7
- gem 'rake', '>= 2.4.2'
8
7
  gem 'rspec'
9
8
  gem 'simplecov', "~> 0.11.2"
10
9
  gem 'webmock'
@@ -154,6 +154,13 @@ data point you will need to pass a list of +Time+, +float+ pairs, instead of a s
154
154
 
155
155
  dog.emit_points('some.metric.name', [[t1, val1], [t2, val2], [t3, val3]], :host => "my_host", :device => "my_device")
156
156
 
157
+ If you want to specify the metric type, using the example above you can pass in a symbol key with :type and a value of a metric type such as counter, gauge or rate.
158
+
159
+ dog.emit_points('some.metric.name', [[t1, val1], [t2, val2], [t3, val3]], :host => "my_host", :device => "my_device", :type => 'counter' )
160
+
161
+ If you want to add metric tags, using the example above you can pass in a symbol key with :tags and an array of tags.
162
+
163
+ dog.emit_points('some.metric.name', [[t1, val1], [t2, val2], [t3, val3]], :host => "my_host", :device => "my_device", :tags => ['frontend', 'app:webserver'] )
157
164
 
158
165
  == Get points from a Datadog metric
159
166
 
@@ -43,4 +43,4 @@ Install [bundler](https://bundler.io/) and setup your RubyGems credentials:
43
43
  1. Build the gem: `bundle exec gem build dogapi.gemspec`.
44
44
  1. Push the gem: `bundle exec gem push dogapi-x.x.x.gem`.
45
45
  1. Check that the [Ruby Gem is published](https://rubygems.org/gems/dogapi).
46
- 1. Bump the version again in `lib/dogapi/version.rb` to a dev version (e.g. `1.39.0` -> `1.40.0.dev`), open a PR and merge it to master.
46
+ 1. Bump the version again in `lib/dogapi/version.rb` to a dev version (e.g. `1.42.0` -> `1.42.1.dev`), open a PR and merge it to master.
@@ -33,6 +33,8 @@ Gem::Specification.new do |spec|
33
33
  spec.add_dependency 'multi_json'
34
34
 
35
35
  spec.add_development_dependency 'bundler', '>= 1.3'
36
+ # NOTE: rake < 12.3.3 is vulnerable to CVE-2020-8130, but we only use it as a test dependency
37
+ # and neither our users nor our CI is vulnerable in any way
36
38
  spec.add_development_dependency 'rake', '~> 10'
37
39
  spec.add_development_dependency 'rdoc'
38
40
  end
@@ -4,6 +4,7 @@
4
4
 
5
5
  require 'cgi'
6
6
  require 'net/https'
7
+ require 'rbconfig'
7
8
  require 'socket'
8
9
  require 'uri'
9
10
  require 'English'
@@ -13,7 +14,16 @@ require 'multi_json'
13
14
  require 'set'
14
15
  require 'open3'
15
16
 
17
+ require 'dogapi/version'
18
+
16
19
  module Dogapi
20
+ USER_AGENT = format(
21
+ 'dogapi-rb/%<version>s (ruby %<ruver>s; os %<os>s; arch %<arch>s)',
22
+ version: VERSION,
23
+ ruver: RUBY_VERSION,
24
+ os: RbConfig::CONFIG['host_os'].downcase,
25
+ arch: RbConfig::CONFIG['host_cpu']
26
+ )
17
27
 
18
28
  # Metadata class to hold the scope of an API call
19
29
  class Scope
@@ -76,11 +86,12 @@ module Dogapi
76
86
  # Superclass that deals with the details of communicating with the DataDog API
77
87
  class APIService
78
88
  attr_reader :api_key, :application_key
79
- def initialize(api_key, application_key, silent=true, timeout=nil, endpoint=nil)
89
+ def initialize(api_key, application_key, silent=true, timeout=nil, endpoint=nil, skip_ssl_validation=false)
80
90
  @api_key = api_key
81
91
  @application_key = application_key
82
92
  @api_host = endpoint || Dogapi.find_datadog_host()
83
93
  @silent = silent
94
+ @skip_ssl_validation = skip_ssl_validation
84
95
  @timeout = timeout || 5
85
96
  end
86
97
 
@@ -100,6 +111,9 @@ module Dogapi
100
111
  session = connection.new(uri.host, uri.port)
101
112
  session.open_timeout = @timeout
102
113
  session.use_ssl = uri.scheme == 'https'
114
+ if @skip_ssl_validation
115
+ session.verify_mode = OpenSSL::SSL::VERIFY_NONE
116
+ end
103
117
  session.start do |conn|
104
118
  conn.read_timeout = @timeout
105
119
  yield conn
@@ -138,11 +152,11 @@ module Dogapi
138
152
  def prepare_request(method, url, params, body, send_json, with_app_key)
139
153
  url_with_params = url + params
140
154
  req = method.new(url_with_params)
155
+ req['User-Agent'] = USER_AGENT
141
156
  unless should_set_api_and_app_keys_in_params?(url)
142
157
  req['DD-API-KEY'] = @api_key
143
158
  req['DD-APPLICATION-KEY'] = @application_key if with_app_key
144
159
  end
145
-
146
160
  if send_json
147
161
  req.content_type = 'application/json'
148
162
  req.body = MultiJson.dump(body)
@@ -200,14 +214,17 @@ module Dogapi
200
214
  @@hostname = nil
201
215
 
202
216
  def Dogapi.find_localhost
203
- unless @@hostname
204
- out, status = Open3.capture2('hostname', '-f', err: File::NULL)
205
- @@hostname = out.strip
206
- # Get status to check if the call was successful
207
- raise SystemCallError, 'Could not get hostname with `hostname -f`' unless status.exitstatus.zero?
208
- end
209
- rescue SystemCallError
210
- @@hostname = Addrinfo.getaddrinfo(Socket.gethostname, nil, nil, nil, nil, Socket::AI_CANONNAME).first.canonname
217
+ return @@hostname if @@hostname
218
+ out, status = Open3.capture2('hostname', '-f', err: File::NULL)
219
+ unless status.exitstatus.zero?
220
+ begin
221
+ out = Addrinfo.getaddrinfo(Socket.gethostname, nil, nil, nil, nil, Socket::AI_CANONNAME).first.canonname
222
+ rescue SocketError
223
+ out, status = Open3.capture2('hostname', err: File::NULL)
224
+ raise SystemCallError, 'Both `hostname` and `hostname -f` failed.' unless status.exitstatus.zero?
225
+ end
226
+ end
227
+ @@hostname = out.strip
211
228
  end
212
229
 
213
230
  def Dogapi.find_proxy
@@ -224,4 +241,14 @@ module Dogapi
224
241
  raise ArgumentError, "Each tag needs to be a string. Current value: #{tag}" unless tag.is_a? String
225
242
  end
226
243
  end
244
+
245
+ # Very simplified hash with indifferent access - access to string or symbol
246
+ # keys via symbols. E.g.:
247
+ # my_hash = { 'foo' => 1 }
248
+ # Dogapi.symbolized_access(my_hash)
249
+ # my_hash[:foo] # => 1
250
+ def Dogapi.symbolized_access(hash)
251
+ hash.default_proc = proc { |h, k| h.key?(k.to_s) ? h[k.to_s] : nil }
252
+ hash
253
+ end
227
254
  end
@@ -13,7 +13,8 @@ module Dogapi
13
13
  # See Dogapi::V2 for the thick underlying clients
14
14
  class ClientV2
15
15
  attr_accessor :datadog_host
16
- def initialize(api_key, application_key=nil, host=nil, device=nil, silent=true, timeout=nil, endpoint=nil)
16
+ def initialize(api_key, application_key=nil, host=nil, device=nil, silent=true,
17
+ timeout=nil, endpoint=nil, skip_ssl_validation=false)
17
18
 
18
19
  if api_key
19
20
  @api_key = api_key
@@ -27,7 +28,7 @@ module Dogapi
27
28
  @device = device
28
29
 
29
30
  @dashboard_list_service_v2 = Dogapi::V2::DashboardListService.new(
30
- @api_key, @application_key, silent, timeout, @datadog_host
31
+ @api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation
31
32
  )
32
33
 
33
34
  end
@@ -64,7 +65,7 @@ module Dogapi
64
65
  # Support for API version 2.
65
66
 
66
67
  # rubocop:disable Metrics/MethodLength, Metrics/LineLength
67
- def initialize(api_key, application_key=nil, host=nil, device=nil, silent=true, timeout=nil, endpoint=nil)
68
+ def initialize(api_key, application_key=nil, host=nil, device=nil, silent=true, timeout=nil, endpoint=nil, skip_ssl_validation=false)
68
69
 
69
70
  if api_key
70
71
  @api_key = api_key
@@ -78,35 +79,38 @@ module Dogapi
78
79
  @device = device
79
80
 
80
81
  # FIXME: refactor to avoid all this code duplication
81
- @metric_svc = Dogapi::V1::MetricService.new(@api_key, @application_key, silent, timeout, @datadog_host)
82
- @event_svc = Dogapi::V1::EventService.new(@api_key, @application_key, silent, timeout, @datadog_host)
83
- @tag_svc = Dogapi::V1::TagService.new(@api_key, @application_key, silent, timeout, @datadog_host)
84
- @comment_svc = Dogapi::V1::CommentService.new(@api_key, @application_key, silent, timeout, @datadog_host)
85
- @search_svc = Dogapi::V1::SearchService.new(@api_key, @application_key, silent, timeout, @datadog_host)
86
- @dash_service = Dogapi::V1::DashService.new(@api_key, @application_key, silent, timeout, @datadog_host)
87
- @dashboard_service = Dogapi::V1::DashboardService.new(@api_key, @application_key, silent, timeout, @datadog_host)
82
+ @metric_svc = Dogapi::V1::MetricService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
83
+ @event_svc = Dogapi::V1::EventService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
84
+ @tag_svc = Dogapi::V1::TagService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
85
+ @comment_svc = Dogapi::V1::CommentService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
86
+ @search_svc = Dogapi::V1::SearchService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
87
+ @dash_service = Dogapi::V1::DashService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
88
+ @dashboard_service = Dogapi::V1::DashboardService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
88
89
  @dashboard_list_service = Dogapi::V1::DashboardListService.new(
89
- @api_key, @application_key, silent, timeout, @datadog_host
90
+ @api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation
90
91
  )
91
- @alert_svc = Dogapi::V1::AlertService.new(@api_key, @application_key, silent, timeout, @datadog_host)
92
- @user_svc = Dogapi::V1::UserService.new(@api_key, @application_key, silent, timeout, @datadog_host)
93
- @snapshot_svc = Dogapi::V1::SnapshotService.new(@api_key, @application_key, silent, timeout, @datadog_host)
94
- @embed_svc = Dogapi::V1::EmbedService.new(@api_key, @application_key, silent, timeout, @datadog_host)
95
- @screenboard_svc = Dogapi::V1::ScreenboardService.new(@api_key, @application_key, silent, timeout, @datadog_host)
96
- @monitor_svc = Dogapi::V1::MonitorService.new(@api_key, @application_key, silent, timeout, @datadog_host)
97
- @synthetics_svc = Dogapi::V1::SyntheticsService.new(@api_key, @application_key, silent, timeout, @datadog_host)
98
- @service_check_svc = Dogapi::V1::ServiceCheckService.new(@api_key, @application_key, silent, timeout, @datadog_host)
99
- @metadata_svc = Dogapi::V1::MetadataService.new(@api_key, @application_key, silent, timeout, @datadog_host)
92
+ @alert_svc = Dogapi::V1::AlertService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
93
+ @user_svc = Dogapi::V1::UserService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
94
+ @snapshot_svc = Dogapi::V1::SnapshotService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
95
+ @embed_svc = Dogapi::V1::EmbedService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
96
+ @screenboard_svc = Dogapi::V1::ScreenboardService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
97
+ @monitor_svc = Dogapi::V1::MonitorService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
98
+ @synthetics_svc = Dogapi::V1::SyntheticsService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
99
+ @service_check_svc = Dogapi::V1::ServiceCheckService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
100
+ @metadata_svc = Dogapi::V1::MetadataService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
100
101
  @legacy_event_svc = Dogapi::EventService.new(@datadog_host)
101
- @hosts_svc = Dogapi::V1::HostsService.new(@api_key, @application_key, silent, timeout, @datadog_host)
102
- @integration_svc = Dogapi::V1::IntegrationService.new(@api_key, @application_key, silent, timeout, @datadog_host)
103
- @aws_integration_svc = Dogapi::V1::AwsIntegrationService.new(@api_key, @application_key, silent, timeout, @datadog_host)
104
- @aws_logs_svc = Dogapi::V1::AwsLogsService.new(@api_key, @application_key, silent, timeout, @datadog_host)
105
- @usage_svc = Dogapi::V1::UsageService.new(@api_key, @application_key, silent, timeout, @datadog_host)
106
- @azure_integration_svc = Dogapi::V1::AzureIntegrationService.new(@api_key, @application_key, silent, timeout, @datadog_host)
107
- @gcp_integration_svc = Dogapi::V1::GcpIntegrationService.new(@api_key, @application_key, silent, timeout, @datadog_host)
102
+ @hosts_svc = Dogapi::V1::HostsService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
103
+ @integration_svc = Dogapi::V1::IntegrationService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
104
+ @aws_integration_svc = Dogapi::V1::AwsIntegrationService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
105
+ @aws_logs_svc = Dogapi::V1::AwsLogsService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
106
+ @usage_svc = Dogapi::V1::UsageService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
107
+ @azure_integration_svc = Dogapi::V1::AzureIntegrationService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
108
+ @gcp_integration_svc = Dogapi::V1::GcpIntegrationService.new(@api_key, @application_key, silent, timeout, @datadog_host, skip_ssl_validation)
109
+ @service_level_objective_svc = Dogapi::V1::ServiceLevelObjectiveService.new(@api_key, @application_key, silent,
110
+ timeout, @datadog_host, skip_ssl_validation)
111
+
108
112
  # Support for Dashboard List API v2.
109
- @v2 = Dogapi::ClientV2.new(@api_key, @application_key, true, true, @datadog_host)
113
+ @v2 = Dogapi::ClientV2.new(@api_key, @application_key, true, true, @datadog_host, skip_ssl_validation)
110
114
 
111
115
  end
112
116
  # rubocop:enable Metrics/MethodLength, Metrics/LineLength
@@ -673,6 +677,46 @@ module Dogapi
673
677
  @monitor_svc.unmute_host(hostname)
674
678
  end
675
679
 
680
+ #
681
+ # SERVICE LEVEL OBJECTIVES
682
+ #
683
+
684
+ def create_service_level_objective(type, slo_name, thresholds, options = {})
685
+ @service_level_objective_svc.create_service_level_objective(type, slo_name, thresholds, options)
686
+ end
687
+
688
+ def update_service_level_objective(slo_id, type, options = {})
689
+ @service_level_objective_svc.update_service_level_objective(slo_id, type, options)
690
+ end
691
+
692
+ def get_service_level_objective(slo_id)
693
+ @service_level_objective_svc.get_service_level_objective(slo_id)
694
+ end
695
+
696
+ def get_service_level_objective_history(slo_id, from_ts, to_ts)
697
+ @service_level_objective_svc.get_service_level_objective_history(slo_id, from_ts, to_ts)
698
+ end
699
+
700
+ def search_service_level_objective(slo_ids = nil, query = nil, offset = nil, limit = nil)
701
+ @service_level_objective_svc.search_service_level_objective(slo_ids, query, offset, limit)
702
+ end
703
+
704
+ def can_delete_service_level_objective(slo_ids)
705
+ @service_level_objective_svc.can_delete_service_level_objective(slo_ids)
706
+ end
707
+
708
+ def delete_service_level_objective(slo_id)
709
+ @service_level_objective_svc.delete_service_level_objective(slo_id)
710
+ end
711
+
712
+ def delete_many_service_level_objective(slo_ids)
713
+ @service_level_objective_svc.delete_many_service_level_objective(slo_ids)
714
+ end
715
+
716
+ def delete_timeframes_service_level_objective(ops)
717
+ @service_level_objective_svc.delete_timeframes_service_level_objective(ops)
718
+ end
719
+
676
720
  #
677
721
  # SERVICE CHECKS
678
722
  #
@@ -15,6 +15,7 @@ require 'dogapi/v1/monitor'
15
15
  require 'dogapi/v1/screenboard'
16
16
  require 'dogapi/v1/search'
17
17
  require 'dogapi/v1/service_check'
18
+ require 'dogapi/v1/service_level_objective'
18
19
  require 'dogapi/v1/snapshot'
19
20
  require 'dogapi/v1/synthetics'
20
21
  require 'dogapi/v1/tag'
@@ -28,6 +28,11 @@ module Dogapi
28
28
  # e.g. '["user1@domain.com", "user2@domain.com"]'
29
29
  # :template_variables => JSON: List of template variables for this dashboard.
30
30
  # e.g. [{"name": "host", "prefix": "host", "default": "my-host"}]
31
+ # :template_variable_presets => JSON: List of template variables saved views
32
+ # e.g. {
33
+ # "name": "my_template_variable_preset",
34
+ # "template_variables": [{"name": "host", "prefix": "host", "default": "my-host"}]
35
+ # }
31
36
  def create_board(title, widgets, layout_type, options)
32
37
  # Required arguments
33
38
  body = {
@@ -40,6 +45,7 @@ module Dogapi
40
45
  body[:is_read_only] = options[:is_read_only] if options[:is_read_only]
41
46
  body[:notify_list] = options[:notify_list] if options[:notify_list]
42
47
  body[:template_variables] = options[:template_variables] if options[:template_variables]
48
+ body[:template_variable_presets] = options[:template_variable_presets] if options[:template_variable_presets]
43
49
 
44
50
  request(Net::HTTP::Post, "/api/#{API_VERSION}/#{RESOURCE_NAME}", nil, body, true)
45
51
  end
@@ -60,6 +66,11 @@ module Dogapi
60
66
  # e.g. '["user1@domain.com", "user2@domain.com"]'
61
67
  # :template_variables => JSON: List of template variables for this dashboard.
62
68
  # e.g. [{"name": "host", "prefix": "host", "default": "my-host"}]
69
+ # :template_variable_presets => JSON: List of template variables saved views
70
+ # e.g. {
71
+ # "name": "my_template_variable_preset",
72
+ # "template_variables": [{"name": "host", "prefix": "host", "default": "my-host"}]
73
+ # }
63
74
  def update_board(dashboard_id, title, widgets, layout_type, options)
64
75
  # Required arguments
65
76
  body = {
@@ -72,6 +83,7 @@ module Dogapi
72
83
  body[:is_read_only] = options[:is_read_only] if options[:is_read_only]
73
84
  body[:notify_list] = options[:notify_list] if options[:notify_list]
74
85
  body[:template_variables] = options[:template_variables] if options[:template_variables]
86
+ body[:template_variable_presets] = options[:template_variable_presets] if options[:template_variable_presets]
75
87
 
76
88
  request(Net::HTTP::Put, "/api/#{API_VERSION}/#{RESOURCE_NAME}/#{dashboard_id}", nil, body, true)
77
89
  end
@@ -0,0 +1,113 @@
1
+ require 'dogapi'
2
+
3
+ module Dogapi
4
+ class V1 # for namespacing
5
+
6
+ # Implements Service Level Objectives endpoints
7
+ class ServiceLevelObjectiveService < Dogapi::APIService
8
+
9
+ API_VERSION = 'v1'
10
+
11
+ def create_service_level_objective(type, slo_name, thresholds, options = {})
12
+ body = {
13
+ type: type,
14
+ name: slo_name,
15
+ thresholds: thresholds
16
+ }
17
+
18
+ symbolized_options = Dogapi.symbolized_access(options)
19
+ if type.to_s == 'metric'
20
+ body[:query] = {
21
+ numerator: symbolized_options[:numerator],
22
+ denominator: symbolized_options[:denominator]
23
+ }
24
+ else
25
+ body[:monitor_search] = symbolized_options[:monitor_search] if symbolized_options[:monitor_search]
26
+ body[:monitor_ids] = symbolized_options[:monitor_ids] if symbolized_options[:monitor_ids]
27
+ body[:groups] = symbolized_options[:groups] if symbolized_options[:groups]
28
+ end
29
+ body[:tags] = symbolized_options[:tags] if symbolized_options[:tags]
30
+ body[:description] = symbolized_options[:description] if symbolized_options[:description]
31
+
32
+ request(Net::HTTP::Post, "/api/#{API_VERSION}/slo", nil, body, true)
33
+ end
34
+
35
+ def update_service_level_objective(slo_id, type, options = {})
36
+ body = {
37
+ type: type
38
+ }
39
+
40
+ symbolized_options = Dogapi.symbolized_access(options)
41
+ if type == 'metric'
42
+ if symbolized_options[:numerator] && symbolized_options[:denominator]
43
+ body[:query] = {
44
+ numerator: symbolized_options[:numerator],
45
+ denominator: symbolized_options[:denominator]
46
+ }
47
+ end
48
+ else
49
+ body[:monitor_search] = symbolized_options[:monitor_search] if symbolized_options[:monitor_search]
50
+ body[:monitor_ids] = symbolized_options[:monitor_ids] if symbolized_options[:monitor_ids]
51
+ body[:groups] = symbolized_options[:groups] if symbolized_options[:groups]
52
+ end
53
+ [:name, :thresholds, :tags, :description].each do |a|
54
+ body[a] = symbolized_options[a] if symbolized_options[a]
55
+ end
56
+
57
+ request(Net::HTTP::Put, "/api/#{API_VERSION}/slo/#{slo_id}", nil, body, true)
58
+ end
59
+
60
+ def get_service_level_objective(slo_id)
61
+ request(Net::HTTP::Get, "/api/#{API_VERSION}/slo/#{slo_id}", nil, nil, false)
62
+ end
63
+
64
+ def search_service_level_objective(slo_ids, query, offset, limit)
65
+ params = {}
66
+ params[:offset] = offset unless offset.nil?
67
+ params[:limit] = limit unless limit.nil?
68
+ if !slo_ids.nil?
69
+ params[:ids] = slo_ids.join(',')
70
+ else
71
+ params[:query] = query
72
+ end
73
+
74
+ request(Net::HTTP::Get, "/api/#{API_VERSION}/slo/", params, nil, false)
75
+ end
76
+
77
+ def delete_service_level_objective(slo_id)
78
+ request(Net::HTTP::Delete, "/api/#{API_VERSION}/slo/#{slo_id}", nil, nil, false)
79
+ end
80
+
81
+ def delete_many_service_level_objective(slo_ids)
82
+ body = {
83
+ ids: slo_ids
84
+ }
85
+ request(Net::HTTP::Delete, "/api/#{API_VERSION}/slo/", nil, body, true)
86
+ end
87
+
88
+ def delete_timeframes_service_level_objective(ops)
89
+ # ops is a hash of slo_id: [<timeframe>] to delete
90
+ request(Net::HTTP::Post, "/api/#{API_VERSION}/slo/bulk_delete", nil, ops, true)
91
+ end
92
+
93
+ def get_service_level_objective_history(slo_id, from_ts, to_ts)
94
+ params = {
95
+ from_ts: from_ts,
96
+ to_ts: to_ts
97
+ }
98
+ request(Net::HTTP::Get, "/api/#{API_VERSION}/slo/#{slo_id}/history", params, nil, false)
99
+ end
100
+
101
+ def can_delete_service_level_objective(slo_ids)
102
+ params = {}
103
+ params[:ids] = if slo_ids.is_a? Array
104
+ slo_ids.join(',')
105
+ else
106
+ slo_ids
107
+ end
108
+ request(Net::HTTP::Get, "/api/#{API_VERSION}/slo/can_delete", params, nil, false)
109
+ end
110
+
111
+ end
112
+ end
113
+ end
@@ -3,5 +3,5 @@
3
3
  # Copyright 2011-Present Datadog, Inc.
4
4
 
5
5
  module Dogapi
6
- VERSION = '1.39.0'
6
+ VERSION = '1.44.0'
7
7
  end
@@ -26,6 +26,15 @@ describe Dogapi::Client do
26
26
  'prefix' => 'host',
27
27
  'default' => 'my-host'
28
28
  }].freeze
29
+ TEMPLATE_VARIABLE_PRESETS = [{
30
+ 'name' => 'preset1',
31
+ 'template_variables' => [
32
+ {
33
+ 'name' => 'host1',
34
+ 'value' => 'my-host'
35
+ }
36
+ ]
37
+ }].freeze
29
38
 
30
39
  REQUIRED_ARGS = {
31
40
  title: TITLE,
@@ -37,7 +46,8 @@ describe Dogapi::Client do
37
46
  description: DESCRIPTION,
38
47
  is_read_only: IS_READ_ONLY,
39
48
  notify_list: NOTIFY_LIST,
40
- template_variables: TEMPLATE_VARIABLES
49
+ template_variables: TEMPLATE_VARIABLES,
50
+ template_variable_presets: TEMPLATE_VARIABLE_PRESETS
41
51
  }
42
52
  DASHBOARD_ARGS = REQUIRED_ARGS.values + [OPTIONS]
43
53
  DASHBOARD_PAYLOAD = REQUIRED_ARGS.merge(OPTIONS)
@@ -0,0 +1,73 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe Dogapi::Client do
4
+ SLO_ID = '42424242424242424242424242424242'.freeze
5
+ SLO_TYPE = 'metric'.freeze
6
+ SLO_NAME = 'test slo'.freeze
7
+ SLO_DESCRIPTION = 'test slo description'.freeze
8
+ SLO_QUERY_NUMERATOR = 'sum:test.metric.metric{type:good}.as_count()'.freeze
9
+ SLO_QUERY_DENOMINATOR = 'sum:test.metric.metric{*}.as_count()'.freeze
10
+ SLO_TAGS = ['type:test'].freeze
11
+ SLO_THRESHOLDS = [{ timeframe: '7d', target: 90 }, { timeframe: '30d', target: 95 }].freeze
12
+
13
+ describe '#create_service_level_objective' do
14
+ it_behaves_like 'an api method',
15
+ :create_service_level_objective, [SLO_TYPE, SLO_NAME, SLO_THRESHOLDS, {
16
+ description: SLO_DESCRIPTION,
17
+ tags: SLO_TAGS,
18
+ numerator: SLO_QUERY_NUMERATOR,
19
+ denominator: SLO_QUERY_DENOMINATOR
20
+ }],
21
+ :post, '/slo', 'type' => SLO_TYPE, 'name' => SLO_NAME, 'thresholds' => SLO_THRESHOLDS,
22
+ 'query' => { numerator: SLO_QUERY_NUMERATOR, denominator: SLO_QUERY_DENOMINATOR },
23
+ 'tags' => SLO_TAGS, 'description' => SLO_DESCRIPTION
24
+ end
25
+
26
+ describe '#update_service_level_objective' do
27
+ it_behaves_like 'an api method',
28
+ :update_service_level_objective, [SLO_ID, SLO_TYPE, { name: SLO_NAME }],
29
+ :put, "/slo/#{SLO_ID}", 'type' => SLO_TYPE, 'name' => SLO_NAME
30
+ end
31
+
32
+ describe '#get_service_level_objective' do
33
+ it_behaves_like 'an api method',
34
+ :get_service_level_objective, [SLO_ID],
35
+ :get, "/slo/#{SLO_ID}"
36
+ end
37
+
38
+ describe '#get_service_level_objective_history' do
39
+ it_behaves_like 'an api method with params',
40
+ :get_service_level_objective_history, [SLO_ID],
41
+ :get, "/slo/#{SLO_ID}/history", 'from_ts' => 0, 'to_ts' => 1_000_000
42
+ end
43
+
44
+ describe '#can_delete_service_level_objective' do
45
+ it_behaves_like 'an api method with params',
46
+ :can_delete_service_level_objective, [],
47
+ :get, '/slo/can_delete', 'ids' => [SLO_ID]
48
+ end
49
+
50
+ describe '#search_service_level_objective' do
51
+ it_behaves_like 'an api method with optional params',
52
+ :search_service_level_objective, [[SLO_ID]],
53
+ :get, '/slo/', 'ids' => SLO_ID
54
+ end
55
+
56
+ describe '#delete_service_level_objective' do
57
+ it_behaves_like 'an api method',
58
+ :delete_service_level_objective, [SLO_ID],
59
+ :delete, "/slo/#{SLO_ID}"
60
+ end
61
+
62
+ describe '#delete_many_service_level_objective' do
63
+ it_behaves_like 'an api method',
64
+ :delete_many_service_level_objective, [[SLO_ID]],
65
+ :delete, '/slo/', 'ids' => [SLO_ID]
66
+ end
67
+
68
+ describe '#delete_timeframes_service_level_objective' do
69
+ it_behaves_like 'an api method',
70
+ :delete_timeframes_service_level_objective, [{ SLO_ID => ['7d'] }],
71
+ :post, '/slo/bulk_delete', SLO_ID => ['7d']
72
+ end
73
+ end
@@ -10,7 +10,19 @@ SimpleCov.start do
10
10
  add_filter 'spec'
11
11
  end
12
12
 
13
- WebMock.disable_net_connect!(allow_localhost: false)
13
+ webmock_allow = []
14
+
15
+ begin
16
+ require 'ddtrace'
17
+ Datadog.configure do |c|
18
+ c.use :rspec, service_name: 'dogapi-rb'
19
+ end
20
+ webmock_allow << "#{Datadog::Transport::HTTP.default_hostname}:#{Datadog::Transport::HTTP.default_port}"
21
+ rescue LoadError
22
+ puts 'ddtrace gem not found'
23
+ end
24
+
25
+ WebMock.disable_net_connect!(allow_localhost: false, allow: webmock_allow)
14
26
 
15
27
  # include our code and methods
16
28
  require 'dogapi'
@@ -134,6 +134,15 @@ describe 'Common' do
134
134
  expect(req['DD-APPLICATION-KEY']).to eq service.application_key
135
135
  end
136
136
  end
137
+
138
+ it 'properly sets User-Agent header' do
139
+ service = Dogapi::APIService.new('api_key', 'app_key', true, nil, 'https://app.example.com')
140
+ params = service.prepare_params(nil, '/api/v1/validate', true)
141
+ req = service.prepare_request(Net::HTTP::Get, '/api/v1/validate', params, nil, false, true)
142
+
143
+ expect(req.key?('User-Agent')).to be true
144
+ expect(req['User-Agent']).to match(%r{dogapi-rb\/[^\s]+ \(ruby [^\s]+; os [^\s]+; arch [^\s]+\)})
145
+ end
137
146
  end
138
147
  end
139
148
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dogapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.39.0
4
+ version: 1.44.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Datadog, Inc.
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-04 00:00:00.000000000 Z
11
+ date: 2020-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: multi_json
@@ -131,6 +131,7 @@ files:
131
131
  - lib/dogapi/v1/screenboard.rb
132
132
  - lib/dogapi/v1/search.rb
133
133
  - lib/dogapi/v1/service_check.rb
134
+ - lib/dogapi/v1/service_level_objective.rb
134
135
  - lib/dogapi/v1/snapshot.rb
135
136
  - lib/dogapi/v1/synthetics.rb
136
137
  - lib/dogapi/v1/tag.rb
@@ -158,6 +159,7 @@ files:
158
159
  - spec/integration/screenboard_spec.rb
159
160
  - spec/integration/search_spec.rb
160
161
  - spec/integration/service_check_spec.rb
162
+ - spec/integration/service_level_objective_spec.rb
161
163
  - spec/integration/snapshot_spec.rb
162
164
  - spec/integration/synthetics_spec.rb
163
165
  - spec/integration/tag_spec.rb
@@ -175,7 +177,7 @@ metadata:
175
177
  changelog_uri: https://github.com/DataDog/dogapi-rb/blob/master/CHANGELOG.md
176
178
  documentation_uri: https://docs.datadoghq.com/api/
177
179
  source_code_uri: https://github.com/DataDog/dogapi-rb
178
- post_install_message:
180
+ post_install_message:
179
181
  rdoc_options:
180
182
  - "--title"
181
183
  - DogAPI -- Datadog Client
@@ -197,7 +199,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
197
199
  version: '0'
198
200
  requirements: []
199
201
  rubygems_version: 3.0.6
200
- signing_key:
202
+ signing_key:
201
203
  specification_version: 4
202
204
  summary: Ruby bindings for Datadog's API
203
205
  test_files:
@@ -220,6 +222,7 @@ test_files:
220
222
  - spec/integration/screenboard_spec.rb
221
223
  - spec/integration/search_spec.rb
222
224
  - spec/integration/service_check_spec.rb
225
+ - spec/integration/service_level_objective_spec.rb
223
226
  - spec/integration/snapshot_spec.rb
224
227
  - spec/integration/synthetics_spec.rb
225
228
  - spec/integration/tag_spec.rb