usps-support 0.2.44 → 0.2.46

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: b04ede6eeee252cd53b27f9d9938019e9f2a81d467ca077bab1b17087fce0bc6
4
- data.tar.gz: aef62058741366eee1794b4ebdee5031f91ec78ee46ef60df3e277ab7ddb04aa
3
+ metadata.gz: a1508e9abf6ef884c05e7201b52f3c328a81be47388319938e5a4b3ef8aa5e5a
4
+ data.tar.gz: '08de17c41c0489f4f0a6994a73ca193a25c8b1917ebc652c6788d6d6c69c72d2'
5
5
  SHA512:
6
- metadata.gz: 191a90199bdcf0509844d3e12f158e1cad908b1c8c8ad97167bc1d6c464e3ae9bc8984a094306274bcbf806bc815a8385ce849524d1bb372557d592e00f57e07
7
- data.tar.gz: 5660fd1df623ce3988efdc5c607743095100d7a18e3815ca233bf57bf0313f2a39b728d8b308dac69c8838457f626449f631cafcb6dc4369bdf64f95d49025b8
6
+ metadata.gz: 54e24451d92bed2cfb93bda006c78d2d311f9e3e5a1a283cebc7f66e3908c4c5977b81a87ce265a1389e16ef6b8759759ca0e7ac5f304ff35a682bb29e2d9a12
7
+ data.tar.gz: cd741d2ff564082916e9782408762d8117b17d45afae4e8d90e3ddb442c0d1e79e84b3e5beb492387d7f971b5ee15f7db679a9c8e2d2c6753eecfc5adc87ea55
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+
5
+ module Usps::Support
6
+ # Base controller for external synthetic health probes (see the infrastructure repo's
7
+ # doc/application_health_probes.md). Unlike Rails' /up (boot-only) and nginx's static
8
+ # /instance-health-check, this exercises an app's *critical dependencies* and returns the sentinel
9
+ # "HEALTHCHECK_OK <app>" only when every check passes — a Route 53 HTTPS_STR_MATCH probe asserts
10
+ # the "HEALTHCHECK_OK" prefix, so a quiet app-level failure flips the Statuspage component even
11
+ # with no organic traffic.
12
+ #
13
+ # Host apps subclass this and override #checks to pick which dependencies to probe, e.g.
14
+ #
15
+ # class HealthController < Usps::Support::HealthController
16
+ # private
17
+ # def checks = { database: check_database, redis: check_redis }
18
+ # end
19
+ #
20
+ # and route to it (`get 'health' => 'health#show'`). The check_* primitives below each return a
21
+ # boolean and never raise, so the action always responds. Apps run only the checks for the
22
+ # dependencies they actually configure — admin-console has no HQ connection, so it omits
23
+ # check_hq_database; an iMIS-backed app adds check_imis; a custom downstream is check_http(url).
24
+ #
25
+ # Inherits ActionController::Base directly — NOT the host's ApplicationController — to bypass
26
+ # Devise auth, Pundit authorization, PaperTrail, and especially `allow_browser`, whose
27
+ # modern-browser gate would 406 Route 53's non-browser prober and fail the probe for the wrong
28
+ # reason.
29
+ class HealthController < ActionController::Base # rubocop:disable Rails/ApplicationController
30
+ SENTINEL_PREFIX = 'HEALTHCHECK_OK'
31
+
32
+ def show
33
+ results = checks
34
+ healthy = results.values.all?
35
+
36
+ body = "#{healthy ? "#{SENTINEL_PREFIX} #{app_name}" : "HEALTHCHECK_FAIL #{app_name}"}\n"
37
+ results.each { |name, ok| body << "#{name}=#{ok ? 'ok' : 'fail'}\n" }
38
+
39
+ response.set_header('Cache-Control', 'no-store')
40
+ response.set_header('Retry-After', '30') unless healthy
41
+ render(plain: body, content_type: 'text/plain', status: healthy ? :ok : :service_unavailable)
42
+ end
43
+
44
+ private
45
+
46
+ # Dependencies to probe, as { label => boolean }.
47
+ #
48
+ # Override per app.
49
+ #
50
+ # Default is the primary database only, which presumably every app needs.
51
+ def checks = { database: check_database }
52
+
53
+ # Derives "admin-console" from the host application's module (e.g. AdminConsole), so the sentinel
54
+ # identifies which app answered without per-app configuration.
55
+ def app_name = Rails.application.class.module_parent_name.underscore.dasherize
56
+
57
+ # --- Check primitives. Each returns true/false and swallows its own errors, so a dead
58
+ # dependency reads as a failed check rather than a 500. ---
59
+
60
+ # Primary application database (RDS).
61
+ def check_database = check_connection(::ActiveRecord::Base)
62
+
63
+ # HQ database (using VHQAB), reached over the HQ VPN — a *different* host than RDS.
64
+ def check_hq_database = check_connection(Models::Hq::Members::BaseRecord)
65
+
66
+ # Redis / Sidekiq's configured connection pool.
67
+ def check_redis
68
+ ::Sidekiq.redis { it.call('PING') }
69
+ true
70
+ rescue StandardError
71
+ false
72
+ end
73
+
74
+ # iMIS API liveness — authenticating proves network + credentials + the token endpoint, against
75
+ # the environment-appropriate iMIS.
76
+ def check_imis
77
+ ::Usps::Imis::Api.new.auth_token
78
+ true
79
+ rescue StandardError
80
+ false
81
+ end
82
+
83
+ # Generic downstream HTTP liveness for a custom dependency.
84
+ def check_http(url)
85
+ ::Net::HTTP.get_response(URI(url)).is_a?(::Net::HTTPSuccess)
86
+ rescue StandardError
87
+ false
88
+ end
89
+
90
+ # Checks out a connection from the given model's pool and runs a trivial query — proves the
91
+ # connection is live, which a boot-time check skips.
92
+ def check_connection(model)
93
+ model.connection.execute('SELECT 1')
94
+ true
95
+ rescue StandardError
96
+ false
97
+ end
98
+ end
99
+ end
data/lib/usps/all.rb CHANGED
@@ -5,8 +5,5 @@ require 'usps/jwt_auth'
5
5
  require_relative 'support'
6
6
 
7
7
  # :nocov:
8
- if defined?(Rails)
9
- require 'usps/support/railtie'
10
- require 'usps/support/engine'
11
- end
8
+ require 'usps/support/engine' if defined?(Rails)
12
9
  # :nocov:
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Usps
4
4
  module Support
5
- VERSION = '0.2.44'
5
+ VERSION = '0.2.46'
6
6
  end
7
7
  end
data/lib/usps/support.rb CHANGED
@@ -18,7 +18,7 @@ require_relative 'support/helpers'
18
18
  require_relative 'support/models'
19
19
  require_relative 'support/lib'
20
20
 
21
- # The Railtie and Engine requires live in `usps/all`, not here. This file can
21
+ # The Engine require lives in `usps/all`, not here. This file can
22
22
  # legitimately be required before Rails is loaded (e.g. from .simplecov to pull
23
23
  # in Usps::Support::Lib helpers), and because Ruby caches loaded files, a
24
24
  # conditional `if defined?(Rails)` block here would be evaluated once with
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: usps-support
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.44
4
+ version: 0.2.46
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julian Fiander
@@ -73,14 +73,13 @@ files:
73
73
  - Readme.md
74
74
  - app/controllers/concerns/usps/support/admin_menu.rb
75
75
  - app/controllers/usps/support/admins_controller.rb
76
+ - app/controllers/usps/support/health_controller.rb
76
77
  - app/models/usps/support/policy/admin_context.rb
77
78
  - config/routes.rb
78
79
  - db/hq/members_schema.rb
79
80
  - db/hq/websites_schema.rb
80
- - lib/tasks/db.rake
81
81
  - lib/usps/all.rb
82
82
  - lib/usps/support.rb
83
- - lib/usps/support/db/auxiliary_stamper.rb
84
83
  - lib/usps/support/db/members_schema.rb
85
84
  - lib/usps/support/db/websites_schema.rb
86
85
  - lib/usps/support/engine.rb
@@ -120,7 +119,6 @@ files:
120
119
  - lib/usps/support/models/hq/squadrons/squadron.rb
121
120
  - lib/usps/support/models/hq/squadrons/website.rb
122
121
  - lib/usps/support/models/toast.rb
123
- - lib/usps/support/railtie.rb
124
122
  - lib/usps/support/sidekiq_auth.rb
125
123
  - lib/usps/support/version.rb
126
124
  homepage: https://github.com/unitedstatespowersquadrons/usps-support
data/lib/tasks/db.rake DELETED
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'usps/support/db/auxiliary_stamper'
4
-
5
- namespace :db do
6
- desc "Stamp auxiliary test databases with the primary database's schema_migrations rows"
7
- task stamp_auxiliary_test_schemas: :environment do
8
- Usps::Support::Db::AuxiliaryStamper.call
9
- end
10
- end
11
-
12
- %w[db:schema:load db:migrate db:test:prepare].each do |task|
13
- Rake::Task[task].enhance do
14
- Rake::Task['db:stamp_auxiliary_test_schemas'].invoke if Rails.env.test?
15
- end
16
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Usps
4
- module Support
5
- module Db
6
- # Copies the primary test database's schema_migrations rows into each
7
- # auxiliary test database, so Rails' pending-migration check doesn't see
8
- # the primary's migrations as pending against schemas that don't run them.
9
- #
10
- module AuxiliaryStamper
11
- class << self
12
- def call(io: $stdout)
13
- primary, auxiliary = test_configs
14
- return if auxiliary.empty?
15
-
16
- ActiveRecord::Base.connection_pool.with_connection do |connection|
17
- primary_versions = fetch_versions(connection, primary.database)
18
-
19
- auxiliary.each do |config|
20
- existing = fetch_versions(connection, config.database)
21
- (primary_versions - existing).each do |version|
22
- io.puts "Stamping #{version} for #{config.database}"
23
- connection.execute(
24
- "INSERT INTO #{config.database}.schema_migrations (version) VALUES (#{version.to_i})"
25
- )
26
- end
27
- end
28
- end
29
- end
30
-
31
- private
32
-
33
- def test_configs
34
- configs = ActiveRecord::Base.configurations.configs_for(env_name: 'test')
35
- primary = configs.find(&:primary?) || configs.first
36
- [primary, configs - [primary]]
37
- end
38
-
39
- def fetch_versions(connection, database)
40
- connection.execute("SELECT version FROM #{database}.schema_migrations").to_a.flatten
41
- end
42
- end
43
- end
44
- end
45
- end
46
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rails'
4
-
5
- module Usps
6
- module Support
7
- # Expose rake tasks to Rails and ensure auxiliary test schemas stay in
8
- # sync with the primary's schema_migrations before Rails runs its
9
- # pending-migration check.
10
- #
11
- class Railtie < Rails::Railtie
12
- railtie_name :usps_support
13
-
14
- rake_tasks do
15
- path = File.expand_path(__dir__)
16
- Dir.glob("#{path}/../../tasks/**/*.rake").each { |f| load f }
17
- end
18
-
19
- initializer 'usps_support.stamp_auxiliary_test_schemas' do
20
- next unless Rails.env.test?
21
-
22
- require 'usps/support/db/auxiliary_stamper'
23
-
24
- ActiveSupport.on_load(:active_record) do
25
- ActiveRecord::Migration.singleton_class.prepend(
26
- Module.new do
27
- def maintain_test_schema!
28
- Usps::Support::Db::AuxiliaryStamper.call(io: File.open(File::NULL, 'w'))
29
- super
30
- end
31
- end
32
- )
33
- end
34
- end
35
- end
36
- end
37
- end