diplomatic_bag 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 641df0432390b52215d6063148e94b402ea200fa5a424ca2499c98aa8ba2d88a
4
+ data.tar.gz: 4a0ddc8cc86c54a6e52ed1a6b387a21ed206c1fc2743196b3e143cc06db169b7
5
+ SHA512:
6
+ metadata.gz: 0f1568f519ef9b7b685bd07905b60ba441051a928c3ec11e0a1b1ae5bae0c4ff15096749c6ac55a52d82a2d34640b99558b5a5bd1cd708e383dfbd59a19240a3
7
+ data.tar.gz: 34193eac2e23dff911c8c8845a0998102f0a88bafd5e4d9104c29c184d2d934bfd1bd376217a240cf76383efd25787a3779070f449045c0f73db998087ecf960
data/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ Copyright (c) 2014, Diplomat project contributors
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+ * Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ * Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+ * Neither the name of the Ruby FFI project nor the
12
+ names of its contributors may be used to endorse or promote products
13
+ derived from this software without specific prior written permission.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
19
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,356 @@
1
+ # Diplomat
2
+ [![Gem Version](https://badge.fury.io/rb/diplomat.svg)](https://rubygems.org/gems/diplomat) [![Gem](https://img.shields.io/gem/dt/diplomat.svg)](https://rubygems.org/gems/diplomat/versions/2.0.0) [![Build Status](https://travis-ci.org/WeAreFarmGeek/diplomat.svg?branch=master)](https://travis-ci.org/WeAreFarmGeek/diplomat) [![Code Climate](https://codeclimate.com/github/johnhamelink/diplomat.svg)](https://codeclimate.com/github/WeAreFarmGeek/diplomat) [![Inline docs](http://inch-ci.org/github/wearefarmgeek/diplomat.svg?branch=master)](http://inch-ci.org/github/wearefarmgeek/diplomat)
3
+ ### A HTTP Ruby API for [Consul](http://www.consul.io/)
4
+
5
+ ![Diplomacy Board Game](http://i.imgur.com/Nkuy4b7.jpg)
6
+
7
+
8
+ ## FAQ
9
+
10
+ #### What's Diplomat for?
11
+
12
+ Diplomat allows any ruby application to interact with [Consul's](http://www.consul.io/) distributed key value store, and also receive information about services currently available in the Consul cluster.
13
+
14
+ #### Does it work in rails?
15
+
16
+ Yup! In fact, we're using it in all of our rails production apps instead of any previous case where it'd be right to use environment variables according to [12Factor configuration principals](http://12factor.net/config). This gives us the ability to scale up without making any changes to the actual project codebase, and to move applications around the cluster with ease.
17
+
18
+ Here's what a production database.yml file might look like:
19
+
20
+ ```erb
21
+ <% if Rails.env.production? %>
22
+ production:
23
+ adapter: postgresql
24
+ encoding: unicode
25
+ host: <%= Diplomat::Service.get('postgres').Address %>
26
+ database: <%= Diplomat::Kv.get('project/db/name') %>
27
+ pool: 5
28
+ username: <%= Diplomat::Kv.get('project/db/user') %>
29
+ password: <%= Diplomat::Kv.get('project/db/pass') %>
30
+ port: <%= Diplomat::Service.get('postgres').ServicePort %>
31
+ <% end %>
32
+ ```
33
+
34
+ #### Why would I use Consul over ZooKeeper, Doozerd, etcd, Nagios, Sensu, SmartStack, SkyDNS, Chef, Puppet, Ansible, etc?
35
+
36
+ [Read up what makes Consul different here](http://www.consul.io/intro/vs/index.html)
37
+
38
+ #### How do I install Consul?
39
+
40
+ [See here](http://www.consul.io/intro/). I managed to roll it out on my production machines with the help of [Ansible](http://www.ansible.com/) in one working day.
41
+
42
+ ### Which versions of Ruby does Diplomat support? Where did my ruby 1.9 compatibility go?
43
+
44
+ Check out [Travis](https://travis-ci.org/WeAreFarmGeek/diplomat) to see which versions of ruby we currently test when we're making builds.
45
+
46
+ We've dropped ruby 1.9 support. You can still depend on Diplomat by directly using the `ruby-1.9-compatible` branch on github, although be advised it's not actively maintained anymore.
47
+
48
+ ## Usage
49
+
50
+ [The most up to date place to read about the API is here.](http://rubydoc.info/github/WeAreFarmGeek/diplomat)
51
+
52
+ Here's a few examples of how diplomat works:
53
+
54
+ ### Key Values
55
+
56
+ #### Setting
57
+
58
+ Setting the value of a key is easy as pie:
59
+
60
+ ```ruby
61
+ foo = Diplomat::Kv.put('foo', 'bar')
62
+ # => "bar"
63
+ ```
64
+
65
+ #### Getting
66
+
67
+ Getting the value of a key is just as simple:
68
+
69
+ ```ruby
70
+ foo = Diplomat::Kv.get('foo')
71
+ # => "bar"
72
+ ```
73
+
74
+ Or retrieve a value from another datacenter:
75
+
76
+ ```ruby
77
+ foo = Diplomat::Kv.get('foo', :dc => 'dc-west')
78
+ # => "baz"
79
+ ```
80
+
81
+ You can also retrieve values recursively:
82
+
83
+ ```ruby
84
+ Diplomat::Kv.put('foo/a', 'lorem')
85
+ Diplomat::Kv.put('foo/b', 'ipsum')
86
+ Diplomat::Kv.put('foo/c', 'dolor')
87
+
88
+ Diplomat::Kv.get('foo/', recurse: true)
89
+ # => [{:key=>"foo/a", :value=>"lorem"}, {:key=>"foo/b", :value=>"ipsum"}, {:key=>"foo/c", :value=>"dolor"}]
90
+ ```
91
+
92
+
93
+ Or list all available keys:
94
+
95
+ ```ruby
96
+ Diplomat::Kv.get('/', :keys => true) # => ['foo/a', 'foo/b']
97
+ ```
98
+ You can convert the consul data to a ruby hash
99
+
100
+ ```ruby
101
+ Diplomat::Kv.put('foo/a', 'lorem')
102
+ Diplomat::Kv.put('foo/b', 'ipsum')
103
+ Diplomat::Kv.put('foo/c', 'dolor')
104
+
105
+ Diplomat::Kv.get('foo/', recurse: true, convert_to_hash: true)
106
+ # => {"foo"=>{"a"=>"lorem", "b"=>"ipsum", "c"=>"dolor"}}
107
+ ```
108
+
109
+ ### Nodes
110
+
111
+ #### Getting
112
+
113
+ Look up a node:
114
+
115
+ ```ruby
116
+ foo_service = Diplomat::Node.get('foo')
117
+ # => {"Node"=>{"Node"=>"foobar", "Address"=>"10.1.10.12"}, "Services"=>{"consul"=>{"ID"=>"consul", "Service"=>"consul", "Tags"=>nil, "Port"=>8300}, "redis"=>{"ID"=>"redis", "Service"=>"redis", "Tags"=>["v1"], "Port"=>8000}}}
118
+ ```
119
+
120
+ Get all nodes:
121
+
122
+ ```ruby
123
+ nodes = Diplomat::Node.get_all
124
+ # => [#<OpenStruct Address="10.1.10.12", Node="foo">, #<OpenStruct Address="10.1.10.13", Node="bar">]
125
+ ```
126
+
127
+ Get all nodes for a particular datacenter
128
+
129
+ ```ruby
130
+ nodes = Diplomat::Node.get_all({ :dc => 'My_Datacenter' })
131
+ # => [#<OpenStruct Address="10.1.10.12", Node="foo">, #<OpenStruct Address="10.1.10.13", Node="bar">]
132
+ ```
133
+
134
+ Register a node:
135
+
136
+ ```ruby
137
+ Diplomat::Node.register({ :Node => "app1", :Address => "10.0.0.2" })
138
+ # => true
139
+ ```
140
+
141
+ De-register a node:
142
+
143
+ ```ruby
144
+ Diplomat::Node.deregister({ :Node => "app1", :Address => "10.0.0.2" })
145
+ # => true
146
+ ```
147
+
148
+ ### Services
149
+
150
+ #### Getting
151
+
152
+ Looking up a service is easy as pie:
153
+
154
+ ```ruby
155
+ foo_service = Diplomat::Service.get('foo')
156
+ # => #<OpenStruct Node="hotel", Address="1.2.3.4", ServiceID="hotel_foo", ServiceName="foo", ServiceTags=["foo"], ServicePort=5432>
157
+ ```
158
+ Or if you have multiple nodes per service:
159
+
160
+ ```ruby
161
+ foo_service = Diplomat::Service.get('foo', :all)
162
+ # => [#<OpenStruct Node="hotel", Address="1.2.3.4", ServiceID="hotel_foo", ServiceName="foo", ServiceTags=["foo"], ServicePort=5432>,#<OpenStruct Node="indigo", Address="1.2.3.5", ServiceID="indigo_foo", ServiceName="foo", ServiceTags=["foo"], ServicePort=5432>]
163
+ ```
164
+
165
+ Or if you want to find services for a particular datacenter
166
+
167
+ ```ruby
168
+ foo_service = Diplomat::Service.get('foo', :all, { :dc => 'My_Datacenter'})
169
+ # => [#<OpenStruct Node="hotel", Address="1.2.3.4", ServiceID="hotel_foo", ServiceName="foo", ServiceTags=["foo"], ServicePort=5432>,#<OpenStruct Node="indigo", Address="1.2.3.5", ServiceID="indigo_foo", ServiceName="foo", ServiceTags=["foo"], ServicePort=5432>]
170
+ ```
171
+
172
+ If you wish to list all the services on consul:
173
+
174
+ ```ruby
175
+ services = Diplomat::Service.get_all
176
+ # => #<OpenStruct consul=[], foo=[], bar=[]>
177
+ ```
178
+
179
+ If you wish to list all the services for a specific datacenter:
180
+
181
+ ```ruby
182
+ services = Diplomat::Service.get_all({ :dc => 'My_Datacenter' })
183
+ # => #<OpenStruct consul=[], foo=[], bar=[]>
184
+ ```
185
+
186
+ ### Datacenters
187
+
188
+ Getting a list of datacenters is quite simple and gives you the option to extract all services out of
189
+ all accessible datacenters if you need to.
190
+
191
+ ```ruby
192
+ datacenters = Diplomat::Datacenter.get()
193
+ # => ["DC1", "DC2"]
194
+ ```
195
+
196
+ ### Sessions
197
+
198
+ Creating a session:
199
+
200
+ ```ruby
201
+ sessionid = Diplomat::Session.create({:Node => "server1", :Name => "my-lock"})
202
+ # => "fc5ca01a-c317-39ea-05e8-221da00d3a12"
203
+ ```
204
+ Or destroying a session:
205
+
206
+ ```ruby
207
+ Diplomat::Session.destroy("fc5ca01a-c317-39ea-05e8-221da00d3a12")
208
+ ```
209
+
210
+ Renew a session:
211
+ ```ruby
212
+ Diplomat::Session.renew(sessionid)
213
+ ```
214
+
215
+ List sessions:
216
+ ```ruby
217
+ Diplomat::Session.list.each {|session| puts "#{session["ID"]} #{session["Name"]}"}
218
+ ```
219
+
220
+ ### Locks
221
+
222
+ Acquire a lock:
223
+
224
+ ```ruby
225
+ sessionid = Diplomat::Session.create({:Node => "server1", :Name => "my-lock"})
226
+ lock_acquired = Diplomat::Lock.acquire("/key/to/lock", sessionid)
227
+ # => true
228
+ ```
229
+ Or wait for a lock to be acquired:
230
+
231
+ ```ruby
232
+ sessionid = Diplomat::Session.create({:hostname => "server1", :ipaddress => "4.4.4.4"})
233
+ lock_acquired = Diplomat::Lock.wait_to_acquire("/key/to/lock", sessionid)
234
+ ```
235
+
236
+ Release a lock:
237
+
238
+ ```ruby
239
+ Diplomat::Lock.release("/key/to/lock", sessionid )
240
+ ```
241
+
242
+ ### Events
243
+
244
+ Fire an event:
245
+
246
+ ```ruby
247
+ Diplomat::Event.fire('do_something', 'payload')
248
+ ```
249
+
250
+ List all events with a certain name received by the local agent:
251
+
252
+ ```ruby
253
+ Diplomat::Event.get_all('do_something')
254
+ ```
255
+
256
+ Get the latest event with a certain name received by the local agent:
257
+
258
+ ```ruby
259
+ Diplomat::Event.get('do_something')
260
+ ```
261
+
262
+ Iterate through the events with a certain name received by the local agent:
263
+
264
+ ```ruby
265
+ events = Enumerator.new do |y|
266
+ ret = {token: :first}
267
+ while ret = begin Diplomat::Event.get('do_something', ret[:token], :reject) rescue nil end
268
+ y.yield(ret[:value])
269
+ end
270
+ end
271
+
272
+ events.each{ |e| puts e }
273
+ ```
274
+
275
+ ### Status
276
+
277
+ Returns information about the status of the Consul cluster.
278
+
279
+ Get the raft leader for the datacenter in which the local consul agent is running
280
+
281
+ ```ruby
282
+ Diplomat::Status.leader()
283
+ ```
284
+
285
+ Get an array of Raft peers for the datacenter in which the agent is running
286
+
287
+ ```ruby
288
+ Diplomat::Status.peers()
289
+ ```
290
+
291
+ ### Maintenance mode
292
+
293
+ Enable maintenance mode on a host, with optional reason and DC (requires access to local agent)
294
+
295
+ ```ruby
296
+ Diplomat::Maintenance.enable(true, 'doing stuff', :dc => 'abc')
297
+ ```
298
+
299
+ Determine if a host has maintenance mode enabled
300
+
301
+ ```ruby
302
+ Diplomat::Maintenance.enabled('foobar')
303
+ # => { :enabled => true, :reason => 'doing stuff' }
304
+ ```
305
+
306
+ ### Custom configuration
307
+
308
+ You can create a custom configuration using the following syntax:
309
+
310
+ ```ruby
311
+ Diplomat.configure do |config|
312
+ # Set up a custom Consul URL
313
+ config.url = "http://localhost:8888"
314
+ # Set up a custom Faraday Middleware
315
+ config.middleware = MyCustomMiddleware
316
+ # Set extra Faraday configuration options and custom access token (ACL)
317
+ config.options = {ssl: {version: :TLSv1_2}, headers: {"X-Consul-Token" => "xxxxxxxx-yyyy-zzzz-1111-222222222222"}}
318
+ end
319
+ ```
320
+
321
+ This is traditionally kept inside the `config/initializers` directory if you're using rails. The middleware allows you to customise what happens when faraday sends and receives data. This can be useful if you want to instrument your use of diplomat, for example. You can read more about Faraday's custom middleware [here](http://stackoverflow.com/a/20973008).
322
+
323
+ Alternatively, configuration settings can be overriden at each method call allowing for instance to address different consul agents, with some other token.
324
+
325
+ ```ruby
326
+ Diplomat::Service.get('foo', { http_addr: 'http://consu01:8500' })
327
+ Diplomat::Service.get('foo', { http_addr: 'http://consu02:8500' })
328
+ Diplomat::Kv.put('key/path', 'value', { http_addr: 'http://localhost:8500', dc: 'dc1', token: '111-222-333-444-555' })
329
+ ```
330
+
331
+ Most common options are:
332
+ * dc: target datacenter
333
+ * token: identity used to perform the corresponding action
334
+ * http_addr: to target a remote consul node
335
+ * stale: use consistency mode that allows any server to service the read regardless of whether it is the leader
336
+
337
+ ### Todo
338
+
339
+ - [ ] Updating Docs with latest changes
340
+ - [ ] Using custom objects for response objects (instead of openStruct)
341
+ - [ ] PUTing and DELETEing services
342
+ - [x] Custom SSL Cert Middleware for faraday
343
+ - [x] Allowing the custom configuration of the consul url to connect to
344
+ - [x] Deleting Keys
345
+ - [x] Listing available services
346
+ - [x] Health
347
+ - [x] Members
348
+ - [x] Status
349
+ - [x] Datacenter support for services
350
+ - [x] Ruby 1.8 support
351
+ - [x] Events
352
+
353
+
354
+ ## Enjoy!
355
+
356
+ ![Photo Copyright "merlinmann" https://www.flickr.com/photos/merlin/. All rights reserved.](http://i.imgur.com/3mBwzR9.jpg)
@@ -0,0 +1,9 @@
1
+ Feature: Configuration
2
+
3
+ Scenario: I'm Setting up Diplomat with a default config
4
+ Given I am setting up a default diplomat
5
+ Then I should be able to get and put keys
6
+
7
+ Scenario: I'm Setting up Diplomat with a custom config
8
+ Given I am setting up a custom diplomat
9
+ Then I should be able to get and put keys
@@ -0,0 +1,24 @@
1
+ require 'diplomat'
2
+
3
+ Given 'I am setting up a default diplomat' do
4
+ end
5
+
6
+ Given 'I am setting up a custom diplomat' do
7
+ class StubMiddleware # :nodoc:
8
+ def initialize(app, options = {})
9
+ @app = app
10
+ @options = options
11
+ end
12
+
13
+ def call(env)
14
+ @app.call(env)
15
+ end
16
+ end
17
+
18
+ expect do
19
+ Diplomat.configure do |config|
20
+ config.url = 'http://localhost:8500'
21
+ config.middleware = StubMiddleware
22
+ end
23
+ end.to_not raise_error
24
+ end
@@ -0,0 +1,9 @@
1
+ Then 'I should be able to get and put keys' do
2
+ # High-fructose Corn Syrup
3
+ Diplomat.put('drink', 'Irn Bru')
4
+ expect(Diplomat.get('drink')).to eq('Irn Bru')
5
+
6
+ # Sugar
7
+ Diplomat::Kv.put('cake', 'Sponge')
8
+ expect(Diplomat::Kv.get('cake')).to eq('Sponge')
9
+ end
@@ -0,0 +1,81 @@
1
+ module Diplomat
2
+ # Methods for interacting with the Consul ACL API endpoint
3
+ class Acl < Diplomat::RestClient
4
+ @access_methods = %i[list info create destroy update]
5
+ attr_reader :id, :type, :acl
6
+
7
+ # Get Acl info by ID
8
+ # @param id [String] ID of the Acl to get
9
+ # @param options [Hash] options parameter hash
10
+ # @return [Hash]
11
+ # rubocop:disable PerceivedComplexity
12
+ def info(id, options = {}, not_found = :reject, found = :return)
13
+ @id = id
14
+ @options = options
15
+ custom_params = []
16
+ custom_params << use_consistency(options)
17
+
18
+ raw = send_get_request(@conn_no_err, ["/v1/acl/info/#{id}"], options, custom_params)
19
+
20
+ if raw.status == 200 && raw.body.chomp != 'null'
21
+ case found
22
+ when :reject
23
+ raise Diplomat::AclAlreadyExists, id
24
+ when :return
25
+ @raw = raw
26
+ return parse_body
27
+ end
28
+ elsif raw.status == 200 && raw.body.chomp == 'null'
29
+ case not_found
30
+ when :reject
31
+ raise Diplomat::AclNotFound, id
32
+ when :return
33
+ return nil
34
+ end
35
+ else
36
+ raise Diplomat::UnknownStatus, "status #{raw.status}: #{raw.body}"
37
+ end
38
+ end
39
+ # rubocop:enable PerceivedComplexity
40
+
41
+ # List all Acls
42
+ # @param options [Hash] options parameter hash
43
+ # @return [List] list of [Hash] of Acls
44
+ def list(options = {})
45
+ @raw = send_get_request(@conn_no_err, ['/v1/acl/list'], options)
46
+ parse_body
47
+ end
48
+
49
+ # Update an Acl definition, create if not present
50
+ # @param value [Hash] Acl definition, ID field is mandatory
51
+ # @param options [Hash] options parameter hash
52
+ # @return [Hash] The result Acl
53
+ def update(value, options = {})
54
+ raise Diplomat::IdParameterRequired unless value['ID'] || value[:ID]
55
+
56
+ custom_params = use_cas(@options)
57
+ @raw = send_put_request(@conn, ['/v1/acl/update'], options, value, custom_params)
58
+ parse_body
59
+ end
60
+
61
+ # Create an Acl definition
62
+ # @param value [Hash] Acl definition, ID field is mandatory
63
+ # @param options [Hash] options parameter hash
64
+ # @return [Hash] The result Acl
65
+ def create(value, options = {})
66
+ custom_params = use_cas(@options)
67
+ @raw = send_put_request(@conn, ['/v1/acl/create'], options, value, custom_params)
68
+ parse_body
69
+ end
70
+
71
+ # Destroy an ACl token by its id
72
+ # @param ID [String] the Acl ID
73
+ # @param options [Hash] options parameter hash
74
+ # @return [Bool]
75
+ def destroy(id, options = {})
76
+ @id = id
77
+ @raw = send_put_request(@conn, ["/v1/acl/destroy/#{@id}"], options, nil)
78
+ @raw.body.chomp == 'true'
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,42 @@
1
+ require 'base64'
2
+ require 'faraday'
3
+
4
+ module Diplomat
5
+ # Agent API endpoint methods
6
+ # @see https://www.consul.io/docs/agent/http/agent.html
7
+ class Agent < Diplomat::RestClient
8
+ @access_methods = %i[self checks services members]
9
+
10
+ # Get agent configuration
11
+ # @param options [Hash] options parameter hash
12
+ # @return [OpenStruct] all data associated with the node
13
+ def self(options = {})
14
+ ret = send_get_request(@conn, ['/v1/agent/self'], options)
15
+ JSON.parse(ret.body).tap { |node| OpenStruct.new node }
16
+ end
17
+
18
+ # Get local agent checks
19
+ # @param options [Hash] options parameter hash
20
+ # @return [OpenStruct] all agent checks
21
+ def checks(options = {})
22
+ ret = send_get_request(@conn, ['/v1/agent/checks'], options)
23
+ JSON.parse(ret.body).tap { |node| OpenStruct.new node }
24
+ end
25
+
26
+ # Get local agent services
27
+ # @param options [Hash] options parameter hash
28
+ # @return [OpenStruct] all agent services
29
+ def services(options = {})
30
+ ret = send_get_request(@conn, ['/v1/agent/services'], options)
31
+ JSON.parse(ret.body).tap { |node| OpenStruct.new node }
32
+ end
33
+
34
+ # Get cluster members (as seen by the agent)
35
+ # @param options [Hash] options parameter hash
36
+ # @return [OpenStruct] all members
37
+ def members(options = {})
38
+ ret = send_get_request(@conn, ['/v1/agent/members'], options)
39
+ JSON.parse(ret.body).map { |node| OpenStruct.new node }
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,109 @@
1
+ module Diplomat
2
+ # Methods for interacting with the Consul check API endpoint
3
+ class Check < Diplomat::RestClient
4
+ @access_methods = %i[checks register_script register_ttl
5
+ deregister pass warn fail]
6
+
7
+ # Get registered checks
8
+ # @return [OpenStruct] all data associated with the service
9
+ def checks(options = {})
10
+ ret = send_get_request(@conn, ['/v1/agent/checks'], options)
11
+ JSON.parse(ret.body)
12
+ end
13
+
14
+ # Register a check
15
+ # @param check_id [String] the unique id of the check
16
+ # @param name [String] the name
17
+ # @param notes [String] notes about the check
18
+ # @param args [String[]] command to be run for check
19
+ # @param interval [String] frequency (with units) of the check execution
20
+ # @param options [Hash] options parameter hash
21
+ # @return [Integer] Status code
22
+ # rubocop:disable ParameterLists
23
+ def register_script(check_id, name, notes, args, interval, options = {})
24
+ unless args.is_a?(Array)
25
+ raise(Diplomat::DeprecatedArgument, 'Script usage is deprecated, replace by an array of args')
26
+ end
27
+
28
+ definition = JSON.generate(
29
+ 'ID' => check_id,
30
+ 'Name' => name,
31
+ 'Notes' => notes,
32
+ 'Args' => args,
33
+ 'Interval' => interval
34
+ )
35
+ ret = send_put_request(@conn, ['/v1/agent/check/register'], options, definition)
36
+ ret.status == 200
37
+ end
38
+ # rubocop:enable ParameterLists
39
+
40
+ # Register a TTL check
41
+ # @param check_id [String] the unique id of the check
42
+ # @param name [String] the name
43
+ # @param notes [String] notes about the check
44
+ # @param ttl [String] time (with units) to mark a check down
45
+ # @param options [Hash] options parameter hash
46
+ # @return [Boolean] Success
47
+ def register_ttl(check_id, name, notes, ttl, options = {})
48
+ definition = JSON.generate(
49
+ 'ID' => check_id,
50
+ 'Name' => name,
51
+ 'Notes' => notes,
52
+ 'TTL' => ttl
53
+ )
54
+ ret = send_put_request(@conn, ['/v1/agent/check/register'], options, definition)
55
+ ret.status == 200
56
+ end
57
+
58
+ # Deregister a check
59
+ # @param check_id [String] the unique id of the check
60
+ # @param options [Hash] options parameter hash
61
+ # @return [Integer] Status code
62
+ def deregister(check_id, options = {})
63
+ ret = send_put_request(@conn, ["/v1/agent/check/deregister/#{check_id}"], options, nil)
64
+ ret.status == 200
65
+ end
66
+
67
+ # Update a TTL check
68
+ # @param check_id [String] the unique id of the check
69
+ # @param status [String] status of the check. Valid values are "passing", "warning", and "critical"
70
+ # @param output [String] human-readable message will be passed through to the check's Output field
71
+ # @param options [Hash] options parameter hash
72
+ # @return [Integer] Status code
73
+ def update_ttl(check_id, status, output = nil, options = {})
74
+ definition = JSON.generate(
75
+ 'Status' => status,
76
+ 'Output' => output
77
+ )
78
+ ret = send_put_request(@conn, ["/v1/agent/check/update/#{check_id}"], options, definition)
79
+ ret.status == 200
80
+ end
81
+
82
+ # Pass a check
83
+ # @param check_id [String] the unique id of the check
84
+ # @param output [String] human-readable message will be passed through to the check's Output field
85
+ # @param options [Hash] options parameter hash
86
+ # @return [Integer] Status code
87
+ def pass(check_id, output = nil, options = {})
88
+ update_ttl(check_id, 'passing', output, options)
89
+ end
90
+
91
+ # Warn a check
92
+ # @param check_id [String] the unique id of the check
93
+ # @param output [String] human-readable message will be passed through to the check's Output field
94
+ # @param options [Hash] options parameter hash
95
+ # @return [Integer] Status code
96
+ def warn(check_id, output = nil, options = {})
97
+ update_ttl(check_id, 'warning', output, options)
98
+ end
99
+
100
+ # Fail a check
101
+ # @param check_id [String] the unique id of the check
102
+ # @param output [String] human-readable message will be passed through to the check's Output field
103
+ # @param options [Hash] options parameter hash
104
+ # @return [Integer] Status code
105
+ def fail(check_id, output = nil, options = {})
106
+ update_ttl(check_id, 'critical', output, options)
107
+ end
108
+ end
109
+ end