pg_rails 7.6.45 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b524111b45e87b104a8c0f6b72556dd1517c4e647178461750e183419a23146c
4
- data.tar.gz: 0c6dd6725ed14b94e5717cc6a2281aa00b763460570c637f6053f470f5a8eb18
3
+ metadata.gz: 591319e8a54f63a347c80ff17ee90834b5b85421beefe137661390b40199a5b5
4
+ data.tar.gz: 0e4b70de53c11f4c3484f462fa48b193fd988f2112f7f44347ae62c60b297d72
5
5
  SHA512:
6
- metadata.gz: 46084cbce13b300ab53a7e9f742ac80a802a7410dd4759c3a2600fbc714747da28ce95d3659167e18ee2c76313fa300e5f4ee29f23f39f8d39caa376a05bd4dd
7
- data.tar.gz: 72e0c9c7a81a1ce708a46987f8dfc0a042056bc22e61ee800781f65151caaa80c565ef65f1b209154d95eb35ec2454b3bc62a446b9b9c6c9f33bfba974df17d4
6
+ metadata.gz: bebfda4fcd522f32f070e8690d033690936ffbfe29f6c0771592278c0a87bfdbf0ca9ee2593d277e601296ccc6c1a9ec874651bb3311bb317f94b002cdee329f
7
+ data.tar.gz: 8f9bdac3e190a317fd1377e5161d6988223a2cb726b072fe174b7f437ebe9b3021b62107bb4f51c94e480101067bccde9a4b00c5899e77792d46134e201c89c4
@@ -121,14 +121,12 @@ input[type=datetime-local], input[type=datetime] {
121
121
  .filter label {
122
122
  font-size: 0.8em;
123
123
  font-weight: bold;
124
- max-width: 5em;
125
124
  text-align: right;
126
125
  line-height: 1.2em;
127
126
  vertical-align: middle;
128
127
  opacity: 0.5;
129
128
  min-width: 1em!important;
130
129
  padding-left: 0.5em;
131
- width: min-content;
132
130
  }
133
131
 
134
132
  // Popover
@@ -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
- check_redis
11
- check_postgres
12
- check_websocket
13
- check_ssl
14
- # FIXME: make configurable
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 check_good_job
22
- return if GoodJob::Process.active.count.positive?
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
- return unless Time.zone.parse(sites[url]['expires_at']) < 7.days.from_now
26
+ ary = JSON.parse(param)
84
27
 
85
- raise PgEngine::Error, "The SSL certificate is expired (or about to expire): #{url}"
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, :user_profiles, :health_ssl_urls
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
@@ -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
@@ -2,6 +2,6 @@
2
2
 
3
3
  # :nocov:
4
4
  module PgRails
5
- VERSION = '7.6.45'
5
+ VERSION = '7.6.47'
6
6
  end
7
7
  # :nocov:
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.45
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-13 00:00:00.000000000 Z
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