diplomat-blsk 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c646a06af39073c8504079328bee82d458cff79fa8fbaa2a53b9f70f85e722dd
4
+ data.tar.gz: f3fe8d726dda350c3e9ec5378bc53bea75b0d018d3bc0b6419702fe0c5dc6092
5
+ SHA512:
6
+ metadata.gz: 4b81139172f1656bddae22c4ebd80d7b2338d9bce4cb353e79cb2b0ad69eb5c0a9d6fe54ea0f1c194f4d23f26956c986e4f9fc9b0f2968a0460c76add3b29af8
7
+ data.tar.gz: 50ca257850a4a798a114cf981f95cbbd1275f002b86c633eb8e372afae07005f14d3ead16bb968d1d65a43130ffb1ac37afdec78d4c739cf5abc842ea4038d59
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.
@@ -0,0 +1,341 @@
1
+ # Diplomat
2
+ [![Gem Version](https://badge.fury.io/rb/diplomat.svg)](http://badge.fury.io/rb/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.png)](https://codeclimate.com/github/WeAreFarmGeek/diplomat) [![Dependency Status](https://gemnasium.com/WeAreFarmGeek/diplomat.svg)](https://gemnasium.com/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 Boad 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
+ ```ruby
76
+ foo = Diplomat::Kv.get('foo', :dc => 'dc-west')
77
+ # => "baz"
78
+ ```
79
+
80
+ You can also retrieve values recursively:
81
+ ```ruby
82
+ Diplomat::Kv.put('foo/a', 'lorem')
83
+ Diplomat::Kv.put('foo/b', 'ipsum')
84
+ Diplomat::Kv.put('foo/c', 'dolor')
85
+
86
+ Diplomat::Kv.get('foo/', recurse: true)
87
+ # => [{:key=>"foo/a", :value=>"lorem"}, {:key=>"foo/b", :value=>"ipsum"}, {:key=>"foo/c", :value=>"dolor"}]
88
+ ```
89
+
90
+
91
+ Or list all available keys:
92
+
93
+ ```ruby
94
+ Diplomat::Kv.get('/', :keys => true) # => ['foo/a', 'foo/b']
95
+ ```
96
+ You can convert the consul data to a ruby hash
97
+ ```ruby
98
+ Diplomat::Kv.put('foo/a', 'lorem')
99
+ Diplomat::Kv.put('foo/b', 'ipsum')
100
+ Diplomat::Kv.put('foo/c', 'dolor')
101
+
102
+ Diplomat::Kv.get('foo/', recurse: true, convert_to_hash: true)
103
+ # => {"foo"=>{"a"=>"lorem", "b"=>"ipsum", "c"=>"dolor"}}
104
+ ```
105
+
106
+ ### Nodes
107
+
108
+ #### Getting
109
+
110
+ Look up a node:
111
+
112
+ ```ruby
113
+ foo_service = Diplomat::Node.get('foo')
114
+ # => {"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}}}
115
+ ```
116
+
117
+ Get all nodes:
118
+
119
+ ```ruby
120
+ nodes = Diplomat::Node.get_all
121
+ # => [#<OpenStruct Address="10.1.10.12", Node="foo">, #<OpenStruct Address="10.1.10.13", Node="bar">]
122
+ ```
123
+
124
+ Get all nodes for a particular datacenter
125
+
126
+ ```ruby
127
+ nodes = Diplomat::Node.get_all({ :dc => 'My_Datacenter' })
128
+ # => [#<OpenStruct Address="10.1.10.12", Node="foo">, #<OpenStruct Address="10.1.10.13", Node="bar">]
129
+ ```
130
+
131
+ Register a node:
132
+
133
+ ```ruby
134
+ Diplomat::Node.register({ :Node => "app1", :Address => "10.0.0.2" })
135
+ # => true
136
+ ```
137
+
138
+ De-register a node:
139
+
140
+ ```ruby
141
+ Diplomat::Node.deregister({ :Node => "app1", :Address => "10.0.0.2" })
142
+ # => true
143
+ ```
144
+
145
+ ### Services
146
+
147
+ #### Getting
148
+
149
+ Looking up a service is easy as pie:
150
+
151
+ ```ruby
152
+ foo_service = Diplomat::Service.get('foo')
153
+ # => #<OpenStruct Node="hotel", Address="1.2.3.4", ServiceID="hotel_foo", ServiceName="foo", ServiceTags=["foo"], ServicePort=5432>
154
+ ```
155
+ Or if you have multiple nodes per service:
156
+
157
+ ```ruby
158
+ foo_service = Diplomat::Service.get('foo', :all)
159
+ # => [#<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>]
160
+ ```
161
+
162
+ Or if you want to find services for a particular datacenter
163
+
164
+ ```ruby
165
+ foo_service = Diplomat::Service.get('foo', :all, { :dc => 'My_Datacenter'})
166
+ # => [#<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>]
167
+ ```
168
+
169
+ If you wish to list all the services on consul:
170
+
171
+ ```ruby
172
+ services = Diplomat::Service.get_all
173
+ # => #<OpenStruct consul=[], foo=[], bar=[]>
174
+ ```
175
+
176
+ If you wish to list all the services for a specific datacenter:
177
+
178
+ ```ruby
179
+ services = Diplomat::Service.get_all({ :dc => 'My_Datacenter' })
180
+ # => #<OpenStruct consul=[], foo=[], bar=[]>
181
+ ```
182
+
183
+ ### Datacenters
184
+
185
+ Getting a list of datacenters is quite simple and gives you the option to extract all services out of
186
+ all accessible datacenters if you need to.
187
+
188
+ ```ruby
189
+ datacenters = Diplomat::Datacenter.get()
190
+ # => ["DC1", "DC2"]
191
+ ```
192
+
193
+ ### Sessions
194
+
195
+ Creating a session:
196
+
197
+ ```ruby
198
+ sessionid = Diplomat::Session.create({:Node => "server1", :Name => "my-lock"})
199
+ # => "fc5ca01a-c317-39ea-05e8-221da00d3a12"
200
+ ```
201
+ Or destroying a session:
202
+
203
+ ```ruby
204
+ Diplomat::Session.destroy("fc5ca01a-c317-39ea-05e8-221da00d3a12")
205
+ ```
206
+
207
+ Renew a session:
208
+ ```ruby
209
+ Diplomat::Session.renew(sessionid)
210
+ ```
211
+
212
+ List sessions:
213
+ ```ruby
214
+ Diplomat::Session.list.each {|session| puts "#{session["ID"]} #{session["Name"]}"}
215
+ ```
216
+
217
+ ### Locks
218
+
219
+ Acquire a lock:
220
+
221
+ ```ruby
222
+ sessionid = Diplomat::Session.create({:Node => "server1", :Name => "my-lock"})
223
+ lock_acquired = Diplomat::Lock.acquire("/key/to/lock", sessionid)
224
+ # => true
225
+ ```
226
+ Or wait for a lock to be acquired:
227
+
228
+ ```ruby
229
+ sessionid = Diplomat::Session.create({:hostname => "server1", :ipaddress => "4.4.4.4"})
230
+ lock_acquired = Diplomat::Lock.wait_to_acquire("/key/to/lock", sessionid)
231
+ ```
232
+
233
+ Release a lock:
234
+
235
+ ```ruby
236
+ Diplomat::Lock.release("/key/to/lock", sessionid )
237
+ ```
238
+
239
+ ### Events
240
+
241
+ Fire an event:
242
+
243
+ ```ruby
244
+ Diplomat::Event.fire('do_something', 'payload')
245
+ ```
246
+
247
+ List all events with a certain name received by the local agent:
248
+
249
+ ```ruby
250
+ Diplomat::Event.get_all('do_something')
251
+ ```
252
+
253
+ Get the latest event with a certain name received by the local agent:
254
+
255
+ ```ruby
256
+ Diplomat::Event.get('do_something')
257
+ ```
258
+
259
+ Iterate through the events with a certain name received by the local agent:
260
+
261
+ ```ruby
262
+ events = Enumerator.new do |y|
263
+ ret = {token: :first}
264
+ while ret = begin Diplomat::Event.get('do_something', ret[:token], :reject) rescue nil end
265
+ y.yield(ret[:value])
266
+ end
267
+ end
268
+
269
+ events.each{ |e| puts e }
270
+ ```
271
+
272
+ ### Status
273
+
274
+ Returns information about the status of the Consul cluster.
275
+
276
+ Get the raft leader for the datacenter in which the local consul agent is running
277
+
278
+ ```ruby
279
+ Diplomat::Status.leader()
280
+ ```
281
+
282
+ Get an array of Raft peers for the datacenter in which the agent is running
283
+
284
+ ```ruby
285
+ Diplomat::Status.peers()
286
+ ```
287
+
288
+ ### Maintenance mode
289
+
290
+ Enable maintenance mode on a host, with optional reason and DC (requires access to local agent)
291
+
292
+ ```ruby
293
+ Diplomat::Maintenance.enable(true, 'doing stuff', :dc => 'abc')
294
+ ```
295
+
296
+ Determine if a host has maintenance mode enabled
297
+
298
+ ```ruby
299
+ Diplomat::Maintenance.enabled('foobar')
300
+ # => { :enabled => true, :reason => 'doing stuff' }
301
+ ```
302
+
303
+ ### Custom configuration
304
+
305
+ You can create a custom configuration using the following syntax:
306
+
307
+ ```ruby
308
+ Diplomat.configure do |config|
309
+ # Set up a custom Consul URL
310
+ config.url = "http://localhost:8888"
311
+ # Set up a custom Faraday Middleware
312
+ config.middleware = MyCustomMiddleware
313
+ # Connect into consul with custom access token (ACL)
314
+ config.acl_token = "xxxxxxxx-yyyy-zzzz-1111-222222222222"
315
+ # Set extra Faraday configuration options
316
+ config.options = {ssl: { version: :TLSv1_2 }}
317
+ end
318
+ ```
319
+
320
+ 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).
321
+
322
+ ### Todo
323
+
324
+ - [ ] Updating Docs with latest changes
325
+ - [ ] Using custom objects for response objects (instead of openStruct)
326
+ - [ ] PUTing and DELETEing services
327
+ - [x] Custom SSL Cert Middleware for faraday
328
+ - [x] Allowing the custom configuration of the consul url to connect to
329
+ - [x] Deleting Keys
330
+ - [x] Listing available services
331
+ - [x] Health
332
+ - [x] Members
333
+ - [x] Status
334
+ - [x] Datacenter support for services
335
+ - [x] Ruby 1.8 support
336
+ - [x] Events
337
+
338
+
339
+ ## Enjoy!
340
+
341
+ ![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,62 @@
1
+ require 'json'
2
+ require 'base64'
3
+ require 'faraday'
4
+
5
+ # Top level namespace ensures all required libraries are included and initializes the gem configration.
6
+ module Diplomat
7
+ class << self
8
+ attr_accessor :root_path
9
+ attr_accessor :lib_path
10
+ attr_accessor :configuration
11
+
12
+ # Internal: Requires internal Faraday libraries.
13
+ # @param *libs One or more relative String names to Faraday classes.
14
+ # @return [nil]
15
+ def require_libs(*libs)
16
+ libs.each do |lib|
17
+ require "#{lib_path}/#{lib}"
18
+ end
19
+ end
20
+
21
+ alias require_lib require_libs
22
+ end
23
+
24
+ raise 'Diplomat only supports ruby >= 2.0.0' unless RUBY_VERSION.to_f >= 2.0
25
+
26
+ self.root_path = File.expand_path '..', __FILE__
27
+ self.lib_path = File.expand_path '../diplomat', __FILE__
28
+
29
+ require_libs 'configuration', 'rest_client', 'api_options', 'kv', 'datacenter',
30
+ 'service', 'members', 'node', 'nodes', 'check', 'health', 'session', 'lock',
31
+ 'error', 'event', 'acl', 'maintenance', 'query', 'agent', 'status'
32
+ self.configuration ||= Diplomat::Configuration.new
33
+
34
+ class << self
35
+ # Build optional configuration by yielding a block to configure
36
+ # @yield [Diplomat::Configuration]
37
+ def configure
38
+ self.configuration ||= Diplomat::Configuration.new
39
+ yield(configuration)
40
+ end
41
+
42
+ private
43
+
44
+ # Send all other unknown commands to Diplomat::Kv
45
+ # @deprecated Please use Diplomat::Kv instead.
46
+ # @param name [Symbol] Method to send to Kv
47
+ # @param *args List of arguments to send to Kv
48
+ # @param &block block to send to Kv
49
+ # @return [Object]
50
+ def method_missing(name, *args, &block)
51
+ Diplomat::Kv.new.send(name, *args, &block) || super
52
+ end
53
+
54
+ # Make `respond_to_missing?` fall back to super
55
+ #
56
+ # @param meth_id [Symbol] the tested method
57
+ # @oaram with_private if private methods should be tested too
58
+ def respond_to_missing?(meth_id, with_private = false)
59
+ access_method?(meth_id) || super
60
+ end
61
+ end
62
+ end