etcd-discovery 1.1.0 → 1.2.0

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
  SHA256:
3
- metadata.gz: 3453532202e1683980506e000b3e4b6ec564f4d1da1aba5fe43e4ad6976b1658
4
- data.tar.gz: 4cdbc6f516d3419476f5fab91a42ceb0b8611c925edfad3843a7af8e3a48b89e
3
+ metadata.gz: ee7722bd7f4ac071e3867e8f375f8d409dcfd3b0fe348c948c4d0720b4bc968d
4
+ data.tar.gz: f165f293b2f512a626d272498a27cafc2e31881fa293f9066c2c60293d17b529
5
5
  SHA512:
6
- metadata.gz: 9474e53f69a98deb4b570c0f89c1811cb363bb2630430a02823833b61d72aafd01b084e5b7165b703483dd1a462d3eb365c7ec30ffec9745e741104c989dd3a1
7
- data.tar.gz: 11427a5f9737d2110d3e82dc5febcc33e5573f6f4bd7f0bc89367b4e450c43a668abcda881dea6435c8a1422102925b7107ceeb8dd0f841a1eea5c168ca8435b
6
+ metadata.gz: 190cc1df8b425c188f37a8f5630d7bb6f86861dab222403266233d75be8b842b64a1e582d410f03b0253e19d8ef32c9d742076c703bf58fb98350eb4ba5df89f
7
+ data.tar.gz: d72483c7cb1449997e30261b76754c8a5df7953f8a89d3a24465e013df6a859132c5841b21104269b5bafcafcb670d1c3e2198fd512145613e3547b9d76b658e
@@ -25,16 +25,16 @@ module EtcdDiscovery
25
25
  end
26
26
 
27
27
  def to_uri(schemes = ["https", "http"])
28
- a = attributes # Shorten name
29
- schemes = [schemes] if !schemes.is_a?(Array)
30
- scheme = schemes.find { |s|
31
- !a["ports"][s].nil?
32
- }
33
- if a["user"].empty?
34
- URI("#{scheme}://#{a["name"]}:#{a["ports"][scheme]}")
35
- else
36
- URI("#{scheme}://#{a["user"]}:#{a["password"]}@#{a["name"]}:#{a["ports"][scheme]}")
28
+ schemes = Array(schemes)
29
+
30
+ scheme = schemes.find { |s| attributes["ports"][s] }
31
+ raise "No valid scheme found" unless scheme
32
+
33
+ if attributes["user"].nil? || attributes["user"].empty?
34
+ return URI("#{scheme}://#{attributes["name"]}:#{attributes["ports"][scheme]}")
37
35
  end
36
+
37
+ URI("#{scheme}://#{attributes["user"]}:#{attributes["password"]}@#{attributes["name"]}:#{attributes["ports"][scheme]}")
38
38
  end
39
39
 
40
40
  def to_private_uri(schemes = ["https", "http"])
@@ -60,7 +60,12 @@ module EtcdDiscovery
60
60
  end
61
61
 
62
62
  def to_s
63
- to_uri.to_s
63
+ uri = to_uri
64
+ if uri.userinfo
65
+ user, _password = uri.userinfo.split(":", 2)
66
+ uri.userinfo = "#{user}:REDACTED"
67
+ end
68
+ uri.to_s
64
69
  end
65
70
  end
66
71
  end
@@ -3,9 +3,9 @@ module EtcdDiscovery
3
3
  end
4
4
 
5
5
  class Service
6
- attr_accessor :attributes
6
+ attr_accessor :attributes, :shard
7
7
 
8
- def initialize(arg)
8
+ def initialize(arg, shard = nil)
9
9
  if arg.is_a? Etcd::Node
10
10
  @attributes = JSON.parse arg.value
11
11
  elsif arg.is_a? Hash
@@ -13,52 +13,73 @@ module EtcdDiscovery
13
13
  else
14
14
  raise TypeError, "requires a Etcd::Node or a Hash, not a #{arg.class}"
15
15
  end
16
+ @shard = shard
16
17
  end
17
18
 
18
- def self.get(service)
19
+ def self.get(service, shard: nil)
19
20
  raise TypeError, "service should be a String, is a #{service.class}" unless service.is_a? String
20
21
 
21
22
  client = EtcdDiscovery.config.client
22
23
  begin
23
24
  service = client.get("/services_infos/#{service}")
24
- new service.node
25
+ new(service.node, shard)
25
26
  rescue Etcd::KeyNotFound
26
- new("name" => service)
27
+ new({"name" => service}, shard)
27
28
  end
28
29
  end
29
30
 
30
31
  def all
31
32
  client = EtcdDiscovery.config.client
33
+
32
34
  begin
33
35
  node = client.get("/services/#{attributes["name"]}", recursive: true).node
34
36
  rescue Etcd::KeyNotFound
35
37
  raise ServiceNotFound, attributes["name"]
36
38
  end
39
+
37
40
  raise ServiceNotFound, attributes["name"] if node.children.empty?
38
- node.children.map { |c| Host.new(c) }
41
+
42
+ hosts = node.children.map { |c| Host.new(c) }
43
+ return hosts if @shard.nil?
44
+
45
+ hosts = hosts.select { |host| host.attributes["shard"].to_s == @shard.to_s }
46
+ raise ServiceNotFound, attributes["name"] if hosts.empty?
47
+
48
+ hosts
39
49
  end
40
50
 
41
51
  def one
42
52
  all.sample
43
53
  end
44
54
 
45
- def to_uri(schemes = ["https", "http"])
46
- a = attributes
47
- return one.to_uri(schemes) unless a["public"]
55
+ def to_uri(schemes = ["https", "http"], **kwargs)
56
+ unless kwargs.empty?
57
+ raise TypeError, "to_uri does not accept keyword arguments; pass schemes as a String or an Array"
58
+ end
48
59
 
49
- schemes = [schemes] if !schemes.is_a?(Array)
50
- scheme = schemes.reject do |s|
51
- a["ports"][s].nil?
52
- end.first
53
- if a["user"].nil? || a["user"] == ""
54
- URI("#{scheme}://#{a["hostname"]}:#{a["ports"][scheme]}")
55
- else
56
- URI("#{scheme}://#{a["user"]}:#{a["password"]}@#{a["hostname"]}:#{a["ports"][scheme]}")
60
+ raise TypeError, "schemes should be a String or an Array" if schemes.is_a? Hash
61
+
62
+ schemes = Array(schemes)
63
+
64
+ return one.to_uri(schemes) if @shard || !attributes["public"]
65
+
66
+ scheme = schemes.find { |s| attributes["ports"][s] }
67
+ raise "No valid scheme found" unless scheme
68
+
69
+ if attributes["user"].nil? || attributes["user"].empty?
70
+ return URI("#{scheme}://#{attributes["hostname"]}:#{attributes["ports"][scheme]}")
57
71
  end
72
+
73
+ URI("#{scheme}://#{attributes["user"]}:#{attributes["password"]}@#{attributes["hostname"]}:#{attributes["ports"][scheme]}")
58
74
  end
59
75
 
60
76
  def to_s
61
- to_uri.to_s
77
+ uri = to_uri
78
+ if uri.userinfo
79
+ user, _password = uri.userinfo.split(":", 2)
80
+ uri.userinfo = "#{user}:REDACTED"
81
+ end
82
+ uri.to_s
62
83
  end
63
84
 
64
85
  def to_json
@@ -1,8 +1,8 @@
1
1
  ## Require files from etcd-discovery
2
2
 
3
+ require "logger"
3
4
  require "etcd"
4
5
  require "json"
5
- require "logger"
6
6
 
7
7
  dir = File.join File.dirname(__FILE__), "etcd-discovery"
8
8
  Dir["#{dir}/*.rb"].sort.each do |file|
@@ -22,8 +22,8 @@ module EtcdDiscovery
22
22
  end
23
23
 
24
24
  # For a cleaner API
25
- def self.get(service)
26
- Service.get(service)
25
+ def self.get(service, shard: nil)
26
+ Service.get(service, shard: shard)
27
27
  end
28
28
 
29
29
  def self.register(service, host)
@@ -10,6 +10,19 @@ RSpec.describe EtcdDiscovery::Registrar do
10
10
  end
11
11
  end
12
12
 
13
+ context "with a sharded Hash" do
14
+ subject do
15
+ EtcdDiscovery::Registrar.new(
16
+ "service",
17
+ {"name" => "example.com", "ports" => {"http" => 80}, "shard" => "shard-0"}
18
+ )
19
+ end
20
+
21
+ it "should keep the shard on the host payload" do
22
+ expect(subject.host.attributes["shard"]).to eq "shard-0"
23
+ end
24
+ end
25
+
13
26
  context "with a EtcdDiscovery::Host" do
14
27
  subject { EtcdDiscovery::Registrar.new "service", EtcdDiscovery::Host.new({"name" => "example.com", "ports" => {"http" => 80}}) }
15
28
  it "should defines the state to new" do
data/spec/spec_helper.rb CHANGED
@@ -2,14 +2,14 @@ require "etcd-discovery"
2
2
 
3
3
  require "rubygems"
4
4
  require "bundler/setup"
5
- Bundler.require(:default, :development, :test)
5
+ Bundler.require(:default, :test)
6
6
 
7
7
  EtcdDiscovery.config.register_renew = 0.1
8
8
 
9
9
  require "webmock/rspec"
10
10
  WebMock.disable_net_connect!(allow_localhost: false)
11
11
 
12
- require_relative "./etcd_helper"
12
+ require_relative "etcd_helper"
13
13
 
14
14
  RSpec.configure do |config|
15
15
  config.include(EtcdHelper)
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: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Léo Unbekandt
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-08-24 00:00:00.000000000 Z
11
+ date: 2026-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: etcd
@@ -43,7 +43,7 @@ homepage: http://github.com/Scalingo/etcd-discovery-ruby
43
43
  licenses:
44
44
  - BSD
45
45
  metadata: {}
46
- post_install_message:
46
+ post_install_message:
47
47
  rdoc_options: []
48
48
  require_paths:
49
49
  - lib
@@ -58,8 +58,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
58
58
  - !ruby/object:Gem::Version
59
59
  version: '0'
60
60
  requirements: []
61
- rubygems_version: 3.3.5
62
- signing_key:
61
+ rubygems_version: 3.5.22
62
+ signing_key:
63
63
  specification_version: 4
64
64
  summary: Service discovery based on etcd
65
65
  test_files: []