WeAreFarmGeek/diplomat: A HTTP Ruby API for Consul

A HTTP Ruby API for Consul
FAQ
What’s Diplomat for?
Diplomat permits any ruby software to work together with Consul’s distributed key worth retailer, and in addition obtain details about companies at the moment accessible within the Consul cluster.
Does it work in rails?
Yup! In actual fact, we’re utilizing it in all of our rails manufacturing apps as a substitute of any earlier case the place it would be proper to make use of atmosphere variables in line with 12Issue configuration principals. This offers us the power to scale up with out making any modifications to the precise venture codebase, and to maneuver purposes across the cluster with ease.
This is what a manufacturing database.yml file would possibly appear to be:
<% if Rails.env.manufacturing? %>
manufacturing:
adapter: postgresql
encoding: unicode
host: <%= Diplomat::Service.get('postgres').Handle %>
database: <%= Diplomat::Kv.get('venture/db/identify') %>
pool: 5
username: <%= Diplomat::Kv.get('venture/db/person') %>
password: <%= Diplomat::Kv.get('venture/db/cross') %>
port: <%= Diplomat::Service.get('postgres').ServicePort %>
<% finish %>
Why would I exploit Consul over ZooKeeper, Doozerd, etcd, Nagios, Sensu, SmartStack, SkyDNS, Chef, Puppet, Ansible, and so on?
Learn up what makes Consul completely different right here
How do I set up Consul?
See right here. I managed to roll it out on my manufacturing machines with the assistance of Ansible in a single working day.
Which variations of Ruby does Diplomat assist? The place did my ruby 1.9 compatibility go?
Try GitHub Actions to see which variations of ruby we at the moment check after we’re making builds.
We have dropped ruby 1.9 assist. You’ll be able to nonetheless rely on Diplomat by instantly utilizing the ruby-1.9-compatible
department on github, though be suggested it is not actively maintained anymore.
ERB templating
It’s attainable to inject diplomat information into .erb
information (comparable to in chef), however you would additionally take a look at
consul-templaterb that’s extremely optimized for ERB templating
with very hello parallelism and good optimized efficiency for big clusters.
Utilization
The hottest place to learn concerning the API is right here.
This is a number of examples of how diplomat works:
Key Values
Setting
Setting the worth of a key’s straightforward as pie:
foo = Diplomat::Kv.put('foo', 'bar')
# => "bar"
Getting
Getting the worth of a key’s simply as easy:
foo = Diplomat::Kv.get('foo')
# => "bar"
Or retrieve a price from one other datacenter:
foo = Diplomat::Kv.get('foo', :dc => 'dc-west')
# => "baz"
You may as well retrieve values recursively:
Diplomat::Kv.put('foo/a', 'lorem')
Diplomat::Kv.put('foo/b', 'ipsum')
Diplomat::Kv.put('foo/c', 'dolor')
Diplomat::Kv.get('foo/', recurse: true)
# => [{:key=>"foo/a", :value=>"lorem"}, {:key=>"foo/b", :value=>"ipsum"}, {:key=>"foo/c", :value=>"dolor"}]
You may as well use get_all
to retrieve values recursively with a constant return sort:
Diplomat::Kv.put('foo/a', 'lorem')
Diplomat::Kv.put('foo/b', 'ipsum')
Diplomat::Kv.put('foo/c', 'dolor')
Diplomat::Kv.get('foo/', recurse: true)
# => [{:key=>"foo/a", :value=>"lorem"}, {:key=>"foo/b", :value=>"ipsum"}, {:key=>"foo/c", :value=>"dolor"}]
Diplomat::Kv.get_all('foo/')
# => [{:key=>"foo/a", :value=>"lorem"}, {:key=>"foo/b", :value=>"ipsum"}, {:key=>"foo/c", :value=>"dolor"}]
Diplomat::Kv.put('bar/a', 'lorem')
Diplomat::Kv.get('bar/', recurse: true)
# => "lorem"
Diplomat::Kv.get_all('bar/')
# => [{:key=>"bar/a", :value=>"lorem"}]
Or record all accessible keys:
Diplomat::Kv.get('/', :keys => true) # => ['foo/a', 'foo/b']
You’ll be able to convert the consul information to a ruby hash
Diplomat::Kv.put('foo/a', 'lorem')
Diplomat::Kv.put('foo/b', 'ipsum')
Diplomat::Kv.put('foo/c', 'dolor')
Diplomat::Kv.get('foo/', recurse: true, convert_to_hash: true)
# => {"foo"=>{"a"=>"lorem", "b"=>"ipsum", "c"=>"dolor"}}
Nodes
Getting
Lookup a node:
foo_service = Diplomat::Node.get('foo')
# => {"Node"=>{"Node"=>"foobar", "Handle"=>"10.1.10.12"}, "Providers"=>{"consul"=>{"ID"=>"consul", "Service"=>"consul", "Tags"=>nil, "Port"=>8300}, "redis"=>{"ID"=>"redis", "Service"=>"redis", "Tags"=>["v1"], "Port"=>8000}}}
Get all nodes:
nodes = Diplomat::Node.get_all
# => [#, #]
Get all nodes for a specific datacenter
nodes = Diplomat::Node.get_all({ :dc => 'My_Datacenter' })
# => [#, #]
Register a node:
Diplomat::Node.register({ :Node => "app1", :Handle => "10.0.0.2" })
# => true
De-register a node:
Diplomat::Node.deregister({ :Node => "app1", :Handle => "10.0.0.2" })
# => true
Providers
Getting
Wanting up a service is simple as pie:
foo_service = Diplomat::Service.get('foo')
# => #
Or in case you have a number of nodes per service:
foo_service = Diplomat::Service.get('foo', :all)
# => [#,#]
Or if you wish to discover companies for a specific datacenter
foo_service = Diplomat::Service.get('foo', :all, { :dc => 'My_Datacenter'})
# => [#,#]
In case you want to record all of the companies on consul:
companies = Diplomat::Service.get_all
# => #
In case you want to record all of the companies for a particular datacenter:
companies = Diplomat::Service.get_all({ :dc => 'My_Datacenter' })
# => #
Datacenters
Getting a listing of datacenters is kind of easy and offers you the choice to extract all companies out of
all accessible datacenters if it’s essential.
datacenters = Diplomat::Datacenter.get()
# => ["DC1", "DC2"]
Periods
Making a session:
sessionid = Diplomat::Session.create({:Node => "server1", :Title => "my-lock"})
# => "fc5ca01a-c317-39ea-05e8-221da00d3a12"
Or destroying a session:
Diplomat::Session.destroy("fc5ca01a-c317-39ea-05e8-221da00d3a12")
Renew a session:
Diplomat::Session.renew(sessionid)
Record periods:
Diplomat::Session.record.every {|session| places "#{session["ID"]} #{session["Name"]}"}
Locks
Purchase a lock:
sessionid = Diplomat::Session.create({:Node => "server1", :Title => "my-lock"})
lock_acquired = Diplomat::Lock.purchase("/key/to/lock", sessionid)
# => true
Or look ahead to a lock to be acquired:
sessionid = Diplomat::Session.create({:hostname => "server1", :ipaddress => "4.4.4.4"})
lock_acquired = Diplomat::Lock.wait_to_acquire("/key/to/lock", sessionid)
Launch a lock:
Diplomat::Lock.launch("/key/to/lock", sessionid )
Occasions
Fireplace an occasion:
Diplomat::Occasion.fireplace('do_something', 'payload')
Record all occasions with a sure identify obtained by the native agent:
Diplomat::Occasion.get_all('do_something')
Get the newest occasion with a sure identify obtained by the native agent:
Diplomat::Occasion.get('do_something')
Iterate by way of the occasions with a sure identify obtained by the native agent:
occasions = Enumerator.new do |y|
ret = {token: :first}
whereas ret = start Diplomat::Occasion.get('do_something', ret[:token], :reject) rescue nil finish
y.yield(ret[:value])
finish
finish
occasions.every places e
Standing
Returns details about the standing of the Consul cluster.
Get the raft chief for the datacenter wherein the native consul agent is working
Diplomat::Standing.chief()
Get an array of Raft friends for the datacenter wherein the agent is working
Autopilot
Returns details about the autopilot configuration of the Consul cluster
Get the present autopilot configuration
Diplomat::Autopilot.get_configuration()
Get the well being standing from autopilot
Diplomat::Autopilot.get_health()
Upkeep mode
Allow upkeep mode on a bunch, with non-obligatory cause and DC (requires entry to native agent)
Diplomat::Upkeep.allow(true, 'doing stuff', :dc => 'abc')
Decide if a bunch has upkeep mode enabled
Diplomat::Upkeep.enabled('foobar')
# => { :enabled => true, :cause => 'doing stuff' }
Customized configuration
You’ll be able to create a customized configuration utilizing the next syntax:
Diplomat.configure do |config|
# Arrange a customized Consul URL
config.url = "http://localhost:8888"
# Arrange a customized Faraday Middleware
config.middleware = MyCustomMiddleware
# Set additional Faraday configuration choices and customized entry token (ACL)
config.choices = {ssl: {model: :TLSv1_2}, headers: {"X-Consul-Token" => "xxxxxxxx-yyyy-zzzz-1111-222222222222"}}
finish
That is historically saved contained in the config/initializers
listing for those who’re utilizing rails. The middleware means that you can customise what occurs when faraday sends and receives information. This may be helpful if you wish to instrument your use of diplomat, for instance. You’ll be able to learn extra about Faraday’s customized middleware right here.
Alternatively, configuration settings might be overriden at every methodology name permitting as an example to handle completely different consul brokers, with another token.
Diplomat::Service.get('foo', { http_addr: 'http://consu01:8500' })
Diplomat::Service.get('foo', { http_addr: 'http://consu02:8500' })
Diplomat::Kv.put('key/path', 'worth', { http_addr: 'http://localhost:8500', dc: 'dc1', token: '111-222-333-444-555' })
Commonest choices are:
- dc: goal datacenter
- token: id used to carry out the corresponding motion
- http_addr: to focus on a distant consul node
- stale: use consistency mode that enables any server to service the learn no matter whether or not it’s the chief