etcd-discovery 0.1.5 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e88aa106512adc7611e367d928d282c360340adc
4
- data.tar.gz: f0b5f71eee7989887cc20710958c156e6826b077
3
+ metadata.gz: 894c96cbadf49bdddf6f499c50be5f8bd68ef95f
4
+ data.tar.gz: 7df1a2709784aaaea0838d36186f75aec034875c
5
5
  SHA512:
6
- metadata.gz: dc991580a31c81665586b8e3b99e1118d3e3ace0c9002967fe3fd8723de61e0ed700a8eb0965e0ae7a0360e6810ed1b76e8ecf776ca331ca02b2f6377dfd14a9
7
- data.tar.gz: ed999908f71f93a9695cc73061bb6f4cdce2496bbf47a682cf4b6957636db9ab5c321af2f148c4637c4530bb2bd2565cb7d8995825c10e64d19267f8f767f908
6
+ metadata.gz: 6f67fd59fe7ecf4c7301d60f5263be4a2a1304be7b06d6716bd85e289d6a6c52e45b4fb385fd26e4163cc0b5ae1f6bc5a70a926077b34d582e457ee376a2c248
7
+ data.tar.gz: 1316ad6bf0935b9d9958017c1e3c8c3c16b32dd22067ff8daa4ca51db024b34f3fc7dd28d827c3e9b76e1290851b935b29232bf89a8b524a4babb0dea41cf686
@@ -27,6 +27,6 @@ module EtcdDiscovery
27
27
  end
28
28
 
29
29
  def self.register(service, host)
30
- Service.register(service, host)
30
+ Registration.register(service, host)
31
31
  end
32
32
  end
@@ -37,6 +37,28 @@ module EtcdDiscovery
37
37
  end
38
38
  end
39
39
 
40
+ def to_private_uri(schemes = ["https", "http"])
41
+ a = attributes
42
+ if a['private_hostname'].empty?
43
+ return self.to_uri(schemes)
44
+ end
45
+ schemes = [schemes] if !schemes.is_a?(Array)
46
+ scheme = schemes.select{ |s|
47
+ !a['private_ports'][s].nil?
48
+ }.first
49
+
50
+ if a['user'].empty?
51
+ URI("#{scheme}://#{a['private_hostname']}:#{a['private_ports'][scheme]}")
52
+ else
53
+ URI("#{scheme}://#{a['user']}:#{a['password']}@#{a['private_hostname']}:#{a['private_ports'][scheme]}")
54
+ end
55
+ end
56
+
57
+ def set_credentials(user, password)
58
+ @attributes['user'] = user
59
+ @attributes['password'] = password
60
+ end
61
+
40
62
  def to_s
41
63
  self.to_uri.to_s
42
64
  end
@@ -1,3 +1,5 @@
1
+ require 'securerandom'
2
+
1
3
  module EtcdDiscovery
2
4
  class InvalidStateError < StandardError
3
5
  def initialize(current, expected)
@@ -13,21 +15,27 @@ module EtcdDiscovery
13
15
  class Registrar
14
16
  attr_reader :state
15
17
  attr_reader :thread
18
+ attr_reader :watcher
16
19
  attr_reader :host
20
+ attr_reader :service
21
+ attr_reader :user
22
+ attr_reader :password
17
23
 
18
24
  def initialize(service, host)
19
25
  @logger = Logger.new($stdout)
20
26
 
21
27
  if host.is_a? Hash
22
- @host = Host.new host
28
+ @host = Host.new host.merge('service_name' => service, 'uuid' => SecureRandom.uuid)
23
29
  elsif host.is_a? EtcdDiscovery::Host
24
30
  @host = host
25
31
  else
26
32
  raise TypeError, "host should be a Hash or a Etcd::Host, is a #{host.class}"
27
33
  end
28
34
 
29
- @service = service
35
+ @service = EtcdDiscovery::Service.new service_params
30
36
  @state = :new
37
+ @user = @host.attributes['user']
38
+ @password = @host.attributes['password']
31
39
  end
32
40
 
33
41
  def register
@@ -37,13 +45,33 @@ module EtcdDiscovery
37
45
  end
38
46
 
39
47
  @state = :started
40
- value = @host.to_json
41
48
 
49
+ service_value = @service.to_json
50
+
51
+ # Do not start credentials synchro if the service is not public or has no credentials
52
+ if @service.attributes['public'] && (@service.attributes['user'].present? || @service.attributes['password'].present?)
53
+ @watcher = Thread.new {
54
+ @logger.warn "Watcher #{@service.attributes['name']} started"
55
+ index = 0
56
+ while @state == :started
57
+ resp = client.watch service_key, {index: index}
58
+ value = JSON.parse resp.node.value
59
+ @user = value['user']
60
+ @password = value['password']
61
+ @host.set_credentials user, password
62
+ @service.set_credentials user, password
63
+ index = resp.etcd_index
64
+ end
65
+ }
66
+ end
67
+
68
+ client.set(service_key, value: service_value)
42
69
  @thread = Thread.new {
43
70
  @logger.warn "Register '#{@service}' started"
44
71
  while @state == :started
72
+ value = @host.to_json
45
73
  begin
46
- client.set(key, value: value, ttl: config.register_ttl)
74
+ client.set(host_key, value: value, ttl: config.register_ttl)
47
75
  rescue => e
48
76
  @logger.warn "Fail to set #{key}: #{e}, #{e.message}, #{e.class}"
49
77
  end
@@ -51,7 +79,9 @@ module EtcdDiscovery
51
79
  end
52
80
  @logger.warn "Register '#{@service}' stopped"
53
81
  }
54
- self
82
+
83
+
84
+ return self
55
85
  end
56
86
 
57
87
  def stop
@@ -70,8 +100,25 @@ module EtcdDiscovery
70
100
  EtcdDiscovery.config
71
101
  end
72
102
 
73
- def key
74
- "/services/#{@service}/#{@host.attributes['name']}"
103
+ def host_key
104
+ "/services/#{@service.attributes['name']}/#{@host.attributes['uuid']}"
105
+ end
106
+
107
+ def service_key
108
+ "/services_infos/#{@service.attributes['name']}"
109
+ end
110
+
111
+ def service_params
112
+ params = {
113
+ 'name' => host.attributes['service_name'],
114
+ 'critical' => host.attributes['critical'],
115
+ 'user' => host.attributes['user'],
116
+ 'password' => host.attributes['password'],
117
+ 'public' => host.attributes['public']
118
+ }
119
+ params['hostname'] = host.attributes['name']if params['public']
120
+ params['ports'] = host.attributes['ports'] if params['public']
121
+ return params
75
122
  end
76
123
  end
77
124
  end
@@ -0,0 +1,7 @@
1
+ module EtcdDiscovery
2
+ class Registration
3
+ def self.register(service, host)
4
+ EtcdDiscovery::Registrar.new(service, host).register
5
+ end
6
+ end
7
+ end
@@ -3,19 +3,40 @@ module EtcdDiscovery
3
3
  end
4
4
 
5
5
  class Service
6
+ attr_accessor :attributes
7
+
8
+ def initialize(arg)
9
+ if arg.is_a? Etcd::Node
10
+ @attributes = JSON.parse arg.value
11
+ elsif arg.is_a? Hash
12
+ @attributes = arg
13
+ else
14
+ raise TypeError, "requires a Etcd::Node or a Hash, not a #{arg.class}"
15
+ end
16
+ end
17
+
6
18
  def self.get(service)
7
19
  raise TypeError, "service should be a String, is a #{service.class}" unless service.is_a? String
8
20
 
9
21
  client = EtcdDiscovery.config.client
10
22
  begin
11
- node = client.get("/services/#{service}", recursive: true)
23
+ service = client.get("/services_infos/#{service}")
24
+ return self.new service.node
25
+ rescue Etcd::KeyNotFound
26
+ return self.new name: 'service'
27
+ end
28
+ end
29
+
30
+ def all
31
+ client = EtcdDiscovery.config.client
32
+ begin
33
+ node = client.get("/services/#{attributes['name']}", recursive: true).node
12
34
  rescue Etcd::KeyNotFound
13
- raise ServiceNotFound, service
35
+ raise ServiceNotFound, attributes['name']
14
36
  end
15
37
  if node.children.length == 0
16
- raise ServiceNotFound, service
38
+ raise ServiceNotFound, attributes['name']
17
39
  end
18
-
19
40
  hosts = []
20
41
  node.children.each do |c|
21
42
  hosts << Host.new(c)
@@ -23,8 +44,32 @@ module EtcdDiscovery
23
44
  return hosts
24
45
  end
25
46
 
26
- def self.register(service, host)
27
- EtcdDiscovery::Registrar.new(service, host).register
47
+ def one
48
+ all.sample
49
+ end
50
+
51
+ def to_uri(schemes = ["https", "http"])
52
+ a = attributes
53
+ return one.to_uri(schemes) unless a['public']
54
+
55
+ schemes = [schemes] if !schemes.is_a?(Array)
56
+ scheme = schemes.select{|s|
57
+ !a['ports'][s].nil?
58
+ }.first
59
+ if a['user'].empty?
60
+ URI("#{scheme}://#{a['hostname']}:#{a['ports'][scheme]}")
61
+ else
62
+ URI("#{scheme}://#{a['user']}:#{a['password']}@#{a['hostname']}:#{a['ports'][scheme]}")
63
+ end
64
+ end
65
+
66
+ def to_json
67
+ attributes.to_json
68
+ end
69
+
70
+ def set_credentials(user, password)
71
+ @attributes['user'] = user
72
+ @attributes['password'] = password
28
73
  end
29
74
  end
30
75
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: etcd-discovery
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Léo Unbekandt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-02 00:00:00.000000000 Z
11
+ date: 2017-06-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: etcd
@@ -35,6 +35,7 @@ files:
35
35
  - lib/etcd-discovery/config.rb
36
36
  - lib/etcd-discovery/host.rb
37
37
  - lib/etcd-discovery/registrar.rb
38
+ - lib/etcd-discovery/registration.rb
38
39
  - lib/etcd-discovery/service.rb
39
40
  - spec/etcd-discovery/registrar_spec.rb
40
41
  - spec/spec_helper.rb
@@ -58,9 +59,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
58
59
  version: '0'
59
60
  requirements: []
60
61
  rubyforge_project:
61
- rubygems_version: 2.5.1
62
+ rubygems_version: 2.5.2
62
63
  signing_key:
63
64
  specification_version: 4
64
65
  summary: Service discovery based on etcd
65
66
  test_files: []
66
- has_rdoc: