philae 0.3.1 → 0.3.2
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 +4 -4
- data/lib/philae/collection_probe.rb +54 -0
- data/lib/philae/etcd_cluster_probe.rb +30 -0
- data/lib/philae/nsq_cluster_probe.rb +46 -0
- metadata +4 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a72261c385f330a6ca14c7ddaccd3774aa4e0e0918eb754bf757ccf16627b0db
|
4
|
+
data.tar.gz: f38b28573ee5829bcd41c9a772c074c43dff746a44b18842aab6c4cd7059bc21
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 270fd5405071f9f12369bafe35693eda220a29180107ae32c5e4aeb0ac16f8d34ad3e069c5f886695b84707512a84054fa51e94fcbfce1bcb904df85f9c78e3c
|
7
|
+
data.tar.gz: 80543e2c7e06be18b3569c50ba373fe5c071d290f1f7ad51ba65af41033c32b62f324b05cffdadd230f8f87ca342888e61218cb1df3d5dd58ff70377a5d66827
|
@@ -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
|
@@ -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)
|
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)
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize(name, hosts, tls_context = nil)
|
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)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def probes
|
43
|
+
@nsq_probes
|
44
|
+
end
|
45
|
+
end
|
46
|
+
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.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- leo@scalingo.com
|
@@ -89,10 +89,13 @@ extensions: []
|
|
89
89
|
extra_rdoc_files: []
|
90
90
|
files:
|
91
91
|
- lib/philae.rb
|
92
|
+
- lib/philae/collection_probe.rb
|
92
93
|
- lib/philae/docker_probe.rb
|
94
|
+
- lib/philae/etcd_cluster_probe.rb
|
93
95
|
- lib/philae/etcd_probe.rb
|
94
96
|
- lib/philae/http_probe.rb
|
95
97
|
- lib/philae/mongo_probe.rb
|
98
|
+
- lib/philae/nsq_cluster_probe.rb
|
96
99
|
- lib/philae/nsq_probe.rb
|
97
100
|
- lib/philae/pgsql_probe.rb
|
98
101
|
- lib/philae/philae_probe.rb
|