philae 0.2.12 → 0.4.0

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
  SHA256:
3
- metadata.gz: 98c6b24b9ffa3987fffbb4a47f404e8d20e728663be1dd3a6953972bfab2a7d6
4
- data.tar.gz: f646a2b162c96cf3eced95b894f75ab74e64a13fb9dc40618ebf6757a721a068
3
+ metadata.gz: 30d73e3e0425c11acc1fb1f03291b6d922b9141b077d5df15c82fd1bb654be9a
4
+ data.tar.gz: f2296b07a57836132bc39c34de390d54a19cf91b31fe91420629fac920ff1a5b
5
5
  SHA512:
6
- metadata.gz: c0a665aee100b59fa4057f1cb688aebf8fcf52282408142b3186d53da9e236522ad74c2945c26f0be66e38a377329cfb494863e24a85acde4f7ac72b4a7102e8
7
- data.tar.gz: 8316c82012b480bb5cd6b43b2992a5b6e3712a78337031c51760903cc9d79a6962f71aeef5e1ed3a426a33c4d4ede4ddc0c99218c47835a5f881363cd4afd417
6
+ metadata.gz: 80374b372327ad433cfe231df3cba1e555af3225b4bc0747c66fa304885f08242058666a8d7853e64751666d15cd419d2d72a805ca8a71be1b32779f532de46e
7
+ data.tar.gz: 68507be35885a378a305df2172a718c331e8b51b1bd7b2b5630228d10a4d1cc21ddb82c5eb28b4e59f167fea9d8847905140b0c566f065ef5b26597f1d10efe6
@@ -0,0 +1,54 @@
1
+ module Philae
2
+ class CollectionProbe
3
+ def initialize(*args)
4
+ raise ArgumentError, "can't be instantiate, use specialized class"
5
+ end
6
+
7
+ def probes
8
+ raise ArgumentError, 'specialized class should implement :probes'
9
+ end
10
+
11
+ def check
12
+ results = []
13
+ result_queue = Queue.new
14
+ probes.each do |probe|
15
+ Thread.new do
16
+ begin
17
+ result = probe.check
18
+ rescue StandardError => e
19
+ result = {
20
+ healthy: false,
21
+ error: "probe #{probe.name} check failed: #{e.class} - #{e.message}",
22
+ }
23
+ end
24
+ result[:probe] = probe
25
+ result_queue.push result
26
+ end
27
+ end
28
+
29
+ loop do
30
+ results.push result_queue.pop
31
+ break if results.count == probes.length
32
+ end
33
+
34
+ failed_results = results.select do |result|
35
+ result[:healthy] == false
36
+ end
37
+
38
+ error = failed_results.map do |result|
39
+ msg = "#{result[:probe].name}: #{result[:comment]} "
40
+ msg += result[:code] if result[:code]
41
+ msg += result[:error] if result[:error]
42
+ next msg
43
+ end.join(', ')
44
+
45
+ if failed_results.count == probes.count
46
+ return { healthy: false, comment: "All #{name} nodes are down", error: error }
47
+ elsif failed_results.count > 0
48
+ return { healthy: true, comment: "#{failed_results.count} #{name} nodes are down: #{error}" }
49
+ else
50
+ return { healthy: true, comment: '' }
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,30 @@
1
+ require_relative 'collection_probe'
2
+ require_relative 'etcd_probe'
3
+
4
+ module Philae
5
+ class EtcdClusterProbe < CollectionProbe
6
+ attr_reader :name, :etcd_probes
7
+
8
+ # @param [Integer] read_timeout Timeout in second for the HTTP request
9
+ def initialize(name, endpoints, read_timeout: 1, cacert: nil, ssl_cert: nil, ssl_key: nil)
10
+ raise ArgumentError, 'empty endpoints' if endpoints.nil? || endpoints.empty?
11
+
12
+ @etcd_probes = endpoints.map do |endpoint|
13
+ endpoint_uri = URI(endpoint)
14
+ next EtcdProbe.new(
15
+ "#{name}-#{endpoint_uri.host}-#{endpoint_uri.port}",
16
+ endpoint_uri.host,
17
+ endpoint_uri.port,
18
+ read_timeout: read_timeout, cacert: cacert,
19
+ ssl_cert: ssl_cert, ssl_key: ssl_key,
20
+ )
21
+ end
22
+
23
+ @name = name
24
+ end
25
+
26
+ def probes
27
+ return @etcd_probes
28
+ end
29
+ end
30
+ end
@@ -14,15 +14,12 @@ module Philae
14
14
 
15
15
  # @param [Integer] read_timeout Timeout in second for the HTTP request
16
16
  def initialize(name, host, port, read_timeout: 1, cacert: nil, ssl_cert: nil, ssl_key: nil)
17
- if not cacert.nil?
18
- if !File.exists? cacert
19
- raise InvalidSSLConfig, "cacert"
20
- elsif ssl_cert.nil? or !File.exists? ssl_cert
21
- raise InvalidSSLConfig, "ssl_cert"
22
- elsif ssl_key.nil? or !File.exists? ssl_key
23
- raise InvalidSSLConfig, "ssl_key"
24
- end
17
+ if !cacert.nil?
18
+ raise InvalidSSLConfig, 'cacert' if !File.exist?(cacert)
19
+ raise InvalidSSLConfig, 'ssl_cert' if ssl_cert.nil? || !File.exist?(ssl_cert)
20
+ raise InvalidSSLConfig, 'ssl_key' if ssl_key.nil? || !File.exist?(ssl_key)
25
21
  end
22
+
26
23
  @name = name
27
24
  @host = host
28
25
  @port = port
@@ -34,22 +31,25 @@ module Philae
34
31
 
35
32
  def check
36
33
  begin
37
- if not @cacert.nil?
38
- client = Etcd.client host: @host, port: @port, read_timeout: @read_timeout do |c|
39
- c.use_ssl = true
40
- c.ca_file = @cacert
41
- c.ssl_cert = OpenSSL::X509::Certificate.new(File.read(@ssl_cert))
42
- c.ssl_key = OpenSSL::PKey::RSA.new(File.read(@ssl_key))
43
- end
44
- else
45
- client = Etcd.client host: @host, port: @port, read_timeout: @read_timeout
46
- end
47
- client.get '/'
48
- rescue Exception => e
34
+ etcd_client.get '/'
35
+ rescue StandardError => e
49
36
  return { healthy: false, comment: "Unable to contact etcd (#{e.message})" }
50
37
  end
51
38
 
52
39
  return { healthy: true, comment: '' }
53
40
  end
41
+
42
+ protected
43
+
44
+ def etcd_client
45
+ return Etcd.client host: @host, port: @port, read_timeout: @read_timeout do |c|
46
+ next if @cacert.nil?
47
+
48
+ c.use_ssl = true
49
+ c.ca_file = @cacert
50
+ c.ssl_cert = OpenSSL::X509::Certificate.new(File.read(@ssl_cert))
51
+ c.ssl_key = OpenSSL::PKey::RSA.new(File.read(@ssl_key))
52
+ end
53
+ end
54
54
  end
55
55
  end
@@ -11,12 +11,13 @@ module Philae
11
11
  # key: "path/to/key",
12
12
  # ca: "path/to/ca"
13
13
  # }
14
- def initialize(name, uri, username = nil, password = nil, tls_context = nil)
14
+ def initialize(name, uri, username = nil, password = nil, tls_context = nil, timeout = nil)
15
15
  @name = name
16
16
  @uri = uri
17
17
  @username = username
18
18
  @password = password
19
19
  @tls_context = tls_context
20
+ @timeout = timeout
20
21
  end
21
22
 
22
23
  def check
@@ -32,6 +33,14 @@ module Philae
32
33
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
33
34
  end
34
35
  end
36
+
37
+ if !@timeout.nil?
38
+ http.read_timeout = @timeout
39
+ http.open_timeout = @timeout
40
+ http.write_timeout = @timeout
41
+ http.ssl_timeout = @timeout
42
+ end
43
+
35
44
  req = Net::HTTP::Get.new(uri)
36
45
  req.basic_auth @username, @password if !@username.nil? || !@password.nil?
37
46
  resp = http.start do |httpconn|
@@ -0,0 +1,46 @@
1
+ require_relative 'collection_probe.rb'
2
+ require_relative 'nsq_probe.rb'
3
+
4
+ module Philae
5
+ class NSQClusterProbe < CollectionProbe
6
+ DEFAULT_HTTP_PORT = 4152
7
+
8
+ attr_reader :name, :nsq_probes
9
+
10
+ def self.new_from_env(name, opts = {})
11
+ if ENV['NSQD_HOSTS'].nil? || ENV['NSQD_HTTP_PORT'].nil?
12
+ raise ArgumentError, 'no NSQD_HOSTS and NSQD_HTTP_PORT defined'
13
+ end
14
+
15
+ tls_context = nil
16
+ if ENV['NSQD_TLS'] == 'true'
17
+ tls_context = {
18
+ cert: ENV['NSQD_TLS_CERT'],
19
+ key: ENV['NSQD_TLS_KEY'],
20
+ ca: ENV['NSQD_TLS_CACERT'],
21
+ }
22
+ end
23
+
24
+ http_hosts = ENV['NSQD_HOSTS'].split(',').map do |host|
25
+ host.split(':')[0] + ":#{ENV['NSQD_HTTP_PORT']}"
26
+ end
27
+
28
+ new(name, http_hosts, tls_context, opts)
29
+ end
30
+
31
+ def initialize(name, hosts, tls_context = nil, opts = {})
32
+ raise ArgumentError, 'should have at least one host' if hosts.nil? || hosts.empty?
33
+
34
+ @name = name
35
+ @nsq_probes = hosts.map do |hostport|
36
+ host, port = hostport.split(':')
37
+ port = DEFAULT_HTTP_PORT if port.nil?
38
+ next Philae::NSQProbe.new("#{name}-#{host}-#{port}", host, port, tls_context, opts)
39
+ end
40
+ end
41
+
42
+ def probes
43
+ @nsq_probes
44
+ end
45
+ end
46
+ end
@@ -2,19 +2,19 @@ require File.join File.dirname(__FILE__), 'http_probe.rb'
2
2
 
3
3
  module Philae
4
4
  class NSQProbe < HttpProbe
5
- def self.new_from_env(name)
5
+ def self.new_from_env(name, opts = {})
6
6
  if ENV["NSQD_TLS"] == "true"
7
7
  return self.new(name, ENV["NSQD_HOST"], ENV["NSQD_HTTP_PORT"], {
8
8
  cert: ENV["NSQD_TLS_CERT"],
9
9
  key: ENV["NSQD_TLS_KEY"],
10
10
  ca: ENV["NSQD_TLS_CACERT"],
11
- })
11
+ }, opts)
12
12
  else
13
13
  return self.new(name, ENV["NSQD_HOST"], ENV["NSQD_HTTP_PORT"])
14
14
  end
15
15
  end
16
16
 
17
- def initialize(name, host, port = 4151, tls_context = nil)
17
+ def initialize(name, host, port = 4151, tls_context = nil, opts = {})
18
18
  @name = name
19
19
  scheme = "http"
20
20
  if !tls_context.nil?
@@ -22,6 +22,7 @@ module Philae
22
22
  end
23
23
  @uri = "#{scheme}://#{host}:#{port}/ping"
24
24
  @tls_context = tls_context
25
+ @timeout = opts.fetch(:timeout, 5)
25
26
  end
26
27
  end
27
28
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: philae
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.12
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - leo@scalingo.com
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2019-08-30 00:00:00.000000000 Z
13
+ date: 2021-08-23 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: docker-api
@@ -68,6 +68,20 @@ dependencies:
68
68
  - - "~>"
69
69
  - !ruby/object:Gem::Version
70
70
  version: '2.4'
71
+ - !ruby/object:Gem::Dependency
72
+ name: pg
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - "~>"
76
+ - !ruby/object:Gem::Version
77
+ version: '0.18'
78
+ type: :runtime
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - "~>"
83
+ - !ruby/object:Gem::Version
84
+ version: '0.18'
71
85
  description:
72
86
  email: hello@scalingo.com
73
87
  executables: []
@@ -75,10 +89,13 @@ extensions: []
75
89
  extra_rdoc_files: []
76
90
  files:
77
91
  - lib/philae.rb
92
+ - lib/philae/collection_probe.rb
78
93
  - lib/philae/docker_probe.rb
94
+ - lib/philae/etcd_cluster_probe.rb
79
95
  - lib/philae/etcd_probe.rb
80
96
  - lib/philae/http_probe.rb
81
97
  - lib/philae/mongo_probe.rb
98
+ - lib/philae/nsq_cluster_probe.rb
82
99
  - lib/philae/nsq_probe.rb
83
100
  - lib/philae/pgsql_probe.rb
84
101
  - lib/philae/philae_probe.rb
@@ -103,7 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
120
  - !ruby/object:Gem::Version
104
121
  version: '0'
105
122
  requirements: []
106
- rubygems_version: 3.0.3
123
+ rubygems_version: 3.1.4
107
124
  signing_key:
108
125
  specification_version: 4
109
126
  summary: Provide an health check API