etcd-discovery 0.1.5 → 1.0.1

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
  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: