pg_rails 7.6.46 → 7.6.47
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/pg_engine/app/controllers/pg_engine/health_controller.rb +12 -69
- data/pg_engine/lib/pg_engine/configuracion.rb +18 -1
- data/pg_engine/lib/pg_engine/health_checker.rb +101 -0
- data/pg_engine/lib/pg_engine/utils/ssl_verifier.rb +4 -0
- data/pg_engine/lib/pg_engine.rb +1 -0
- data/pg_engine/spec/lib/pg_engine/health_checker_spec.rb +32 -0
- data/pg_rails/lib/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 591319e8a54f63a347c80ff17ee90834b5b85421beefe137661390b40199a5b5
|
|
4
|
+
data.tar.gz: 0e4b70de53c11f4c3484f462fa48b193fd988f2112f7f44347ae62c60b297d72
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bebfda4fcd522f32f070e8690d033690936ffbfe29f6c0771592278c0a87bfdbf0ca9ee2593d277e601296ccc6c1a9ec874651bb3311bb317f94b002cdee329f
|
|
7
|
+
data.tar.gz: 8f9bdac3e190a317fd1377e5161d6988223a2cb726b072fe174b7f437ebe9b3021b62107bb4f51c94e480101067bccde9a4b00c5899e77792d46134e201c89c4
|
|
@@ -6,83 +6,26 @@ module PgEngine
|
|
|
6
6
|
render_down
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
+
# Examples:
|
|
10
|
+
# ?except=["good_job", "ssl", "websocket"]
|
|
11
|
+
# ?only=["redis"]
|
|
9
12
|
def show
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
check_good_job unless ENV.fetch("HEALTH_CHECK_SKIP_GOOD_JOB", nil) == "1"
|
|
13
|
+
HealthChecker.new.run_checks(
|
|
14
|
+
only: parse_ary(params[:only]),
|
|
15
|
+
except: parse_ary(params[:except])
|
|
16
|
+
)
|
|
17
|
+
|
|
16
18
|
render_up
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
private
|
|
20
22
|
|
|
21
|
-
def
|
|
22
|
-
return if
|
|
23
|
-
|
|
24
|
-
raise PgEngine::Error, 'good_job is down'
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def check_postgres
|
|
28
|
-
return if User.count.is_a? Integer
|
|
29
|
-
|
|
30
|
-
raise PgEngine::Error, 'postgres is down'
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def check_redis
|
|
34
|
-
return if Kredis.counter('healthcheck').increment.is_a? Integer
|
|
35
|
-
|
|
36
|
-
raise PgEngine::Error, 'redis is down'
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def check_websocket
|
|
40
|
-
result = nil
|
|
41
|
-
begin
|
|
42
|
-
Timeout.timeout(5) do
|
|
43
|
-
EM.run do
|
|
44
|
-
url = Rails.application.config.action_cable.url
|
|
45
|
-
ws = Faye::WebSocket::Client.new(url)
|
|
46
|
-
|
|
47
|
-
ws.on :message do |event|
|
|
48
|
-
type = JSON.parse(event.data)['type']
|
|
49
|
-
if type == 'welcome'
|
|
50
|
-
result = :success
|
|
51
|
-
ws.close
|
|
52
|
-
EM.stop
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
rescue Timeout::Error
|
|
58
|
-
raise PgEngine::Error, 'websocket server is down'
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
return if result == :success
|
|
62
|
-
|
|
63
|
-
raise PgEngine::Error, 'websocket server is down'
|
|
64
|
-
end
|
|
65
|
-
# rubocop:enable Metrics/MethodLength
|
|
66
|
-
|
|
67
|
-
def check_ssl
|
|
68
|
-
raise PgEngine::Error, 'no ssl log file' unless File.exist?(PgEngine::SslVerifier::OUTPUT_PATH)
|
|
69
|
-
|
|
70
|
-
sites = JSON.parse(File.read(PgEngine::SslVerifier::OUTPUT_PATH))
|
|
71
|
-
PgEngine.config.health_ssl_urls.each do |url|
|
|
72
|
-
check_site_ssl(sites, url)
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def check_site_ssl(sites, url)
|
|
77
|
-
raise PgEngine::Error, "SSL record not present: #{url}. Forgot to run PgEngine::SslVerifier ?" if sites[url].blank?
|
|
78
|
-
|
|
79
|
-
if Time.zone.parse(sites[url]['verified_at']) < 2.days.ago
|
|
80
|
-
raise PgEngine::Error, "The SSL info is outdated: #{url}. PgEngine::SslVerifier is down?"
|
|
81
|
-
end
|
|
23
|
+
def parse_ary(param)
|
|
24
|
+
return if param.blank?
|
|
82
25
|
|
|
83
|
-
|
|
26
|
+
ary = JSON.parse(param)
|
|
84
27
|
|
|
85
|
-
|
|
28
|
+
ary.is_a?(Array) ? ary : [ary]
|
|
86
29
|
end
|
|
87
30
|
|
|
88
31
|
def render_up
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
module PgEngine
|
|
6
6
|
class Configuracion
|
|
7
|
-
attr_accessor :users_controller, :global_domains, :navigators,
|
|
7
|
+
attr_accessor :users_controller, :global_domains, :navigators,
|
|
8
|
+
:user_profiles, :health_ssl_urls, :health_checks
|
|
8
9
|
|
|
9
10
|
# attr_accessor :profile_groups
|
|
10
11
|
|
|
@@ -12,6 +13,7 @@ module PgEngine
|
|
|
12
13
|
@global_domains = ['app.localhost.com', 'test.host', 'localhost']
|
|
13
14
|
@navigators = [PgEngine::Navigator.new]
|
|
14
15
|
@health_ssl_urls = []
|
|
16
|
+
@health_checks = []
|
|
15
17
|
# @profile_groups = [:account]
|
|
16
18
|
@user_profiles = {
|
|
17
19
|
account__owner: 0
|
|
@@ -55,5 +57,20 @@ module PgEngine
|
|
|
55
57
|
{ name: group, options: }
|
|
56
58
|
end
|
|
57
59
|
end
|
|
60
|
+
|
|
61
|
+
# @param [String] name
|
|
62
|
+
# description for the check
|
|
63
|
+
#
|
|
64
|
+
# @param [Duration] frequency
|
|
65
|
+
# interval to wait between check runs, if left blank, check will run
|
|
66
|
+
# every time
|
|
67
|
+
#
|
|
68
|
+
# @param [Proc] block
|
|
69
|
+
# a function that raises error if sth is wrong
|
|
70
|
+
def add_health_check(name, only_explicit: false, &block)
|
|
71
|
+
@health_checks.push(
|
|
72
|
+
{ name:, only_explicit:, block: }
|
|
73
|
+
)
|
|
74
|
+
end
|
|
58
75
|
end
|
|
59
76
|
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
module PgEngine
|
|
2
|
+
class HealthChecker
|
|
3
|
+
def run_checks(only: nil, except: nil)
|
|
4
|
+
ary = [default_checks, PgEngine.config.health_checks].flatten
|
|
5
|
+
ary.each do |health_check|
|
|
6
|
+
included = only.present? && only.include?(health_check[:name].to_s)
|
|
7
|
+
excluded = except.present? && except.include?(health_check[:name].to_s)
|
|
8
|
+
|
|
9
|
+
if included || (only.blank? && !health_check[:only_explicit] && !excluded)
|
|
10
|
+
Rails.logger.info "Running health check: #{health_check[:name]}"
|
|
11
|
+
|
|
12
|
+
health_check[:block].call
|
|
13
|
+
else
|
|
14
|
+
Rails.logger.info "Skipping health check: #{health_check[:name]}"
|
|
15
|
+
end
|
|
16
|
+
rescue StandardError => e
|
|
17
|
+
raise "Health check failed: #{health_check[:name]}. With: #{e.message}", cause: e
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def default_checks
|
|
24
|
+
ary = []
|
|
25
|
+
ary << {
|
|
26
|
+
name: :redis,
|
|
27
|
+
block: lambda do
|
|
28
|
+
return if Kredis.counter('healthcheck').increment.is_a? Integer
|
|
29
|
+
|
|
30
|
+
raise PgEngine::Error, 'redis is down'
|
|
31
|
+
end
|
|
32
|
+
}
|
|
33
|
+
ary << {
|
|
34
|
+
name: :postgres,
|
|
35
|
+
block: lambda do
|
|
36
|
+
return if User.count.is_a? Integer
|
|
37
|
+
|
|
38
|
+
raise PgEngine::Error, 'postgres is down'
|
|
39
|
+
end
|
|
40
|
+
}
|
|
41
|
+
ary << {
|
|
42
|
+
name: :websocket,
|
|
43
|
+
block: lambda do
|
|
44
|
+
result = nil
|
|
45
|
+
begin
|
|
46
|
+
Timeout.timeout(5) do
|
|
47
|
+
EM.run do
|
|
48
|
+
url = Rails.application.config.action_cable.url
|
|
49
|
+
ws = Faye::WebSocket::Client.new(url)
|
|
50
|
+
|
|
51
|
+
ws.on :message do |event|
|
|
52
|
+
type = JSON.parse(event.data)['type']
|
|
53
|
+
if type == 'welcome'
|
|
54
|
+
result = :success
|
|
55
|
+
ws.close
|
|
56
|
+
EM.stop
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
rescue Timeout::Error
|
|
62
|
+
raise PgEngine::Error, 'websocket server is down'
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
return if result == :success
|
|
66
|
+
|
|
67
|
+
raise PgEngine::Error, 'websocket server is down'
|
|
68
|
+
end
|
|
69
|
+
}
|
|
70
|
+
ary << {
|
|
71
|
+
name: :ssl,
|
|
72
|
+
block: lambda do
|
|
73
|
+
SslChecker.new.check_ssl
|
|
74
|
+
end
|
|
75
|
+
}
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
class SslChecker
|
|
79
|
+
def check_ssl
|
|
80
|
+
raise PgEngine::Error, 'no ssl log file' unless File.exist?(PgEngine::SslVerifier::OUTPUT_PATH)
|
|
81
|
+
|
|
82
|
+
sites = JSON.parse(File.read(PgEngine::SslVerifier::OUTPUT_PATH))
|
|
83
|
+
PgEngine.config.health_ssl_urls.each do |url|
|
|
84
|
+
check_site_ssl(sites, url)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def check_site_ssl(sites, url)
|
|
89
|
+
raise PgEngine::Error, "SSL record not present: #{url}. Forgot to run PgEngine::SslVerifier ?" if sites[url].blank?
|
|
90
|
+
|
|
91
|
+
if Time.zone.parse(sites[url]['verified_at']) < 2.days.ago
|
|
92
|
+
raise PgEngine::Error, "The SSL info is outdated: #{url}. PgEngine::SslVerifier is down?"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
return unless Time.zone.parse(sites[url]['expires_at']) < 7.days.from_now
|
|
96
|
+
|
|
97
|
+
raise PgEngine::Error, "The SSL certificate is expired (or about to expire): #{url}"
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -39,6 +39,10 @@ module PgEngine
|
|
|
39
39
|
raise PgEngine::Error, "#{url}: The SSL certificate is expired (or about to expire)."
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
# FIXME: ensure domain is included in certificate domains
|
|
43
|
+
# for example, if domain is example.com and certificate is issued for
|
|
44
|
+
# *.example.com, it fails.
|
|
45
|
+
|
|
42
46
|
log_output(url, cert.not_after)
|
|
43
47
|
end
|
|
44
48
|
rescue OpenSSL::SSL::SSLError => e
|
data/pg_engine/lib/pg_engine.rb
CHANGED
|
@@ -4,6 +4,7 @@ require_relative 'pg_engine/engine'
|
|
|
4
4
|
require_relative 'pg_engine/core_ext'
|
|
5
5
|
require_relative 'pg_engine/error'
|
|
6
6
|
require_relative 'pg_engine/configuracion'
|
|
7
|
+
require_relative 'pg_engine/health_checker'
|
|
7
8
|
require_relative 'pg_engine/site_brand'
|
|
8
9
|
require_relative 'pg_engine/navigator'
|
|
9
10
|
require_relative 'pg_engine/active_job_extensions'
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require 'rails_helper'
|
|
2
|
+
|
|
3
|
+
describe PgEngine::HealthChecker do
|
|
4
|
+
let(:health_checker) { described_class.new }
|
|
5
|
+
let(:doub) { double }
|
|
6
|
+
|
|
7
|
+
before do
|
|
8
|
+
PgEngine.config.health_checks = []
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "checks the extras" do
|
|
12
|
+
allow(doub).to receive(:bla)
|
|
13
|
+
PgEngine.configurar do |config|
|
|
14
|
+
config.add_health_check(:dummy_check) do
|
|
15
|
+
doub.bla
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
health_checker.run_checks(only: ["dummy_check"])
|
|
19
|
+
expect(doub).to have_received(:bla)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "error is descriptive" do
|
|
23
|
+
PgEngine.configurar do |config|
|
|
24
|
+
config.add_health_check(:dummy_check) do
|
|
25
|
+
raise "sth went wrong"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
expect {
|
|
29
|
+
health_checker.run_checks(only: ["dummy_check"])
|
|
30
|
+
}.to raise_error(/Health check failed: dummy_check/)
|
|
31
|
+
end
|
|
32
|
+
end
|
data/pg_rails/lib/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pg_rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 7.6.
|
|
4
|
+
version: 7.6.47
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Martín Rosso
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-03-
|
|
11
|
+
date: 2026-03-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -890,6 +890,7 @@ files:
|
|
|
890
890
|
- pg_engine/lib/pg_engine/email_observer.rb
|
|
891
891
|
- pg_engine/lib/pg_engine/engine.rb
|
|
892
892
|
- pg_engine/lib/pg_engine/error.rb
|
|
893
|
+
- pg_engine/lib/pg_engine/health_checker.rb
|
|
893
894
|
- pg_engine/lib/pg_engine/mailgun/log_sync.rb
|
|
894
895
|
- pg_engine/lib/pg_engine/navigator.rb
|
|
895
896
|
- pg_engine/lib/pg_engine/route_helpers.rb
|
|
@@ -935,6 +936,7 @@ files:
|
|
|
935
936
|
- pg_engine/spec/lib/pg_engine/date_jumper_spec.rb
|
|
936
937
|
- pg_engine/spec/lib/pg_engine/error_helper_spec.rb
|
|
937
938
|
- pg_engine/spec/lib/pg_engine/form_helper_spec.rb
|
|
939
|
+
- pg_engine/spec/lib/pg_engine/health_checker_spec.rb
|
|
938
940
|
- pg_engine/spec/lib/pg_engine/mailgun/log_sync_spec.rb
|
|
939
941
|
- pg_engine/spec/lib/pg_engine/utils/pg_engine/pg_logger_spec.rb
|
|
940
942
|
- pg_engine/spec/lib/pg_engine/utils/ssl_verifier_spec.rb
|