standard_health 0.1.0 → 0.2.0
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/CHANGELOG.md +10 -0
- data/README.md +41 -0
- data/app/controllers/standard_health/application_controller.rb +7 -17
- data/app/controllers/standard_health/diagnostics_application_controller.rb +11 -0
- data/app/controllers/standard_health/diagnostics_controller.rb +9 -3
- data/lib/standard_health/configuration.rb +13 -0
- data/lib/standard_health/version.rb +1 -1
- data/lib/standard_health.rb +36 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8542efb5b2511d31b4c9b3ef2a10f650ed342c1eeadc4aecaadef1476b82bc59
|
|
4
|
+
data.tar.gz: 8996c9e8f67904d842f589e60d880127680afa55365cb3be835260db9d36b3c1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b528859586bf219cab6b76902a230f3e660d36e4c108db6489ad1c4643fc19455c868bfa1fbe2b5fdc5291173aa04bfaa516ff322f44cecea41cd3cf5381b474
|
|
7
|
+
data.tar.gz: fe062a3ab494d205e3d436037a4ea42fbe3802043a7d8b3ee873ff4d5b6dd1ae7d1a7bd4659a3e4c533d92cfc035fa47d7c582801a418e4ba24b8943163ae5d5
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.0] - 2026-04-29
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `c.diagnostics_parent_controller` config option. When set, only `StandardHealth::DiagnosticsController` inherits from it; `HealthController` still uses `parent_controller`. Lets consuming apps put auth (e.g. HTTP Basic) on the diagnostics endpoint without needing `raise_on_missing_callback_actions = false` — the workaround three rarebit-one web apps applied when adopting v0.1.0.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- `StandardHealth::DiagnosticsController` now inherits from a new `StandardHealth::DiagnosticsApplicationController` that resolves to `diagnostics_parent_controller || parent_controller`. Backward-compatible — when the new option isn't set, behavior is identical to v0.1.0.
|
|
19
|
+
|
|
10
20
|
## [0.1.0] - 2026-04-28
|
|
11
21
|
|
|
12
22
|
### Added
|
data/README.md
CHANGED
|
@@ -125,8 +125,49 @@ StandardHealth.configure do |c|
|
|
|
125
125
|
end
|
|
126
126
|
```
|
|
127
127
|
|
|
128
|
+
> **Note (Rails 7.1+):** the `only: :env` filter above raises `AbstractController::ActionNotFound` because `HealthController` (alive/ready) shares this parent and has no `:env` action. Use [Splitting auth between health and diagnostics](#splitting-auth-between-health-and-diagnostics) instead — that's why v0.2.0 added `diagnostics_parent_controller`.
|
|
129
|
+
|
|
128
130
|
For a more granular setup, mount the engine inside an authenticated route block in your host app's `routes.rb`.
|
|
129
131
|
|
|
132
|
+
### Splitting auth between health and diagnostics
|
|
133
|
+
|
|
134
|
+
The pattern above hits a snag on Rails 7.1+ when you want to protect *only* `/diagnostics/env`. Both `HealthController` and `DiagnosticsController` inherit from `parent_controller`, so a `before_action :authenticate, only: :env` on that single parent applies to both — and Rails raises `AbstractController::ActionNotFound` because `:env` doesn't exist on `HealthController`.
|
|
135
|
+
|
|
136
|
+
Pre-v0.2.0 the workaround was to disable the check on the host controller:
|
|
137
|
+
|
|
138
|
+
```ruby
|
|
139
|
+
class StandardHealthHostController < ActionController::API
|
|
140
|
+
self.raise_on_missing_callback_actions = false # workaround
|
|
141
|
+
http_basic_authenticate_with(name: ..., password: ..., only: :env)
|
|
142
|
+
end
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
From v0.2.0 onwards, point `diagnostics_parent_controller` at a separate base class instead. Only `DiagnosticsController` inherits from it, so the `only: :env` callback no longer leaks onto `HealthController`:
|
|
146
|
+
|
|
147
|
+
```ruby
|
|
148
|
+
# app/controllers/health_base_controller.rb
|
|
149
|
+
class HealthBaseController < ActionController::API
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# app/controllers/diagnostics_base_controller.rb
|
|
153
|
+
class DiagnosticsBaseController < ActionController::API
|
|
154
|
+
http_basic_authenticate_with(
|
|
155
|
+
name: ENV.fetch("HEALTH_USER"),
|
|
156
|
+
password: ENV.fetch("HEALTH_PASS")
|
|
157
|
+
)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# config/initializers/standard_health.rb
|
|
161
|
+
StandardHealth.configure do |c|
|
|
162
|
+
c.parent_controller = "HealthBaseController"
|
|
163
|
+
c.diagnostics_parent_controller = "DiagnosticsBaseController"
|
|
164
|
+
end
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Now `/health/alive` and `/health/ready` are unauthenticated (probe-friendly) while `/health/diagnostics/env` requires HTTP Basic — no `raise_on_missing_callback_actions` flag needed.
|
|
168
|
+
|
|
169
|
+
When `diagnostics_parent_controller` is unset, `DiagnosticsController` falls back to `parent_controller`, matching v0.1.0 behavior exactly.
|
|
170
|
+
|
|
130
171
|
## Status semantics
|
|
131
172
|
|
|
132
173
|
`/ready` returns:
|
|
@@ -3,26 +3,16 @@
|
|
|
3
3
|
module StandardHealth
|
|
4
4
|
# Base controller for all StandardHealth endpoints.
|
|
5
5
|
#
|
|
6
|
-
# Lazily inherits from `StandardHealth.config.parent_controller`
|
|
6
|
+
# Lazily inherits from `StandardHealth.config.parent_controller` (resolved
|
|
7
|
+
# by `StandardHealth.parent_controller` in lib/standard_health.rb) so host
|
|
7
8
|
# apps can wire their own auth/rate-limiting/before_actions in once and
|
|
8
|
-
# have them apply to /alive
|
|
9
|
-
#
|
|
9
|
+
# have them apply to /alive and /ready. The default is
|
|
10
|
+
# `ActionController::API` so the engine works in API-only host apps
|
|
10
11
|
# without configuration.
|
|
11
12
|
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
# singleton avoids re-running `constantize` per request.
|
|
16
|
-
def self.parent_controller
|
|
17
|
-
@parent_controller ||= config.parent_controller.constantize
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# Allow tests/host apps to bust the cached parent controller (e.g. when
|
|
21
|
-
# toggling config between examples).
|
|
22
|
-
def self.reset_parent_controller!
|
|
23
|
-
@parent_controller = nil
|
|
24
|
-
end
|
|
25
|
-
|
|
13
|
+
# `DiagnosticsController` has its own base class
|
|
14
|
+
# (`DiagnosticsApplicationController`) with its own resolver — see
|
|
15
|
+
# `config.diagnostics_parent_controller`.
|
|
26
16
|
class ApplicationController < parent_controller
|
|
27
17
|
end
|
|
28
18
|
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module StandardHealth
|
|
4
|
+
# Separate base class for `DiagnosticsController` so host apps can target
|
|
5
|
+
# diagnostics-only auth at this class via `diagnostics_parent_controller`.
|
|
6
|
+
# When `diagnostics_parent_controller` is unset, this resolves to the same
|
|
7
|
+
# class as `parent_controller`, so the inheritance chain is behaviorally
|
|
8
|
+
# identical to v0.1.0.
|
|
9
|
+
class DiagnosticsApplicationController < diagnostics_parent_controller
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -3,9 +3,15 @@
|
|
|
3
3
|
module StandardHealth
|
|
4
4
|
# Diagnostics endpoints. Output here is potentially sensitive (it
|
|
5
5
|
# enumerates which env vars are missing), so host apps are responsible
|
|
6
|
-
# for wrapping these routes with authentication
|
|
7
|
-
#
|
|
8
|
-
|
|
6
|
+
# for wrapping these routes with authentication.
|
|
7
|
+
#
|
|
8
|
+
# Inherits from `DiagnosticsApplicationController`, which resolves to
|
|
9
|
+
# `config.diagnostics_parent_controller || config.parent_controller`.
|
|
10
|
+
# This lets host apps put auth on diagnostics only — e.g. an HTTP Basic
|
|
11
|
+
# `before_action :auth, only: :env` on a dedicated diagnostics parent —
|
|
12
|
+
# without that callback leaking onto `HealthController` and tripping
|
|
13
|
+
# Rails 7.1's `raise_on_missing_callback_actions`.
|
|
14
|
+
class DiagnosticsController < DiagnosticsApplicationController
|
|
9
15
|
# Audits the configured EnvSpec against the current process ENV and
|
|
10
16
|
# returns the result as JSON. When no EnvSpec is configured the
|
|
11
17
|
# endpoint returns an empty audit rather than a 404 so callers don't
|
|
@@ -25,6 +25,18 @@ module StandardHealth
|
|
|
25
25
|
# engine works in API-only host apps without configuration.
|
|
26
26
|
attr_accessor :parent_controller
|
|
27
27
|
|
|
28
|
+
# Optional class name of a controller that ONLY `DiagnosticsController`
|
|
29
|
+
# should inherit from. When set, `HealthController` continues to use
|
|
30
|
+
# `parent_controller` while `DiagnosticsController` uses this one. Lets
|
|
31
|
+
# host apps put auth (e.g. HTTP Basic) on the diagnostics endpoint
|
|
32
|
+
# without needing to set `raise_on_missing_callback_actions = false`
|
|
33
|
+
# to suppress Rails 7.1's missing-action error caused by a single
|
|
34
|
+
# parent declaring `before_action :auth, only: :env` for both controllers.
|
|
35
|
+
#
|
|
36
|
+
# When unset (the default), `DiagnosticsController` falls back to
|
|
37
|
+
# `parent_controller` — fully backward-compatible with v0.1.0.
|
|
38
|
+
attr_accessor :diagnostics_parent_controller
|
|
39
|
+
|
|
28
40
|
# An optional `StandardHealth::EnvSpec` instance describing required and
|
|
29
41
|
# recommended environment variables for the host app. Audited via the
|
|
30
42
|
# /diagnostics/env endpoint.
|
|
@@ -32,6 +44,7 @@ module StandardHealth
|
|
|
32
44
|
|
|
33
45
|
def initialize
|
|
34
46
|
@parent_controller = "ActionController::API"
|
|
47
|
+
@diagnostics_parent_controller = nil
|
|
35
48
|
@env_spec = nil
|
|
36
49
|
@checks = []
|
|
37
50
|
end
|
data/lib/standard_health.rb
CHANGED
|
@@ -32,5 +32,41 @@ module StandardHealth
|
|
|
32
32
|
def reset_config!
|
|
33
33
|
@config = Configuration.new
|
|
34
34
|
end
|
|
35
|
+
|
|
36
|
+
# Resolves `config.parent_controller` to an actual class lazily — at
|
|
37
|
+
# the moment the engine's `ApplicationController` is first referenced
|
|
38
|
+
# (request time), by which point the host app's controllers are
|
|
39
|
+
# loaded. Caching avoids re-running `constantize` per request, and
|
|
40
|
+
# the name-mismatch reset lets tests swap config between examples.
|
|
41
|
+
def parent_controller
|
|
42
|
+
expected = config.parent_controller
|
|
43
|
+
if @parent_controller && @parent_controller.name != expected
|
|
44
|
+
@parent_controller = nil
|
|
45
|
+
end
|
|
46
|
+
@parent_controller ||= expected.constantize
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def reset_parent_controller!
|
|
50
|
+
@parent_controller = nil
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Resolves the parent class for `DiagnosticsController` only. Falls
|
|
54
|
+
# back to `config.parent_controller` when no diagnostics-specific
|
|
55
|
+
# parent is configured, preserving v0.1.0 behavior. When set, lets
|
|
56
|
+
# host apps apply `before_action :auth, only: :env` to the diagnostics
|
|
57
|
+
# endpoint without that callback leaking onto `HealthController`
|
|
58
|
+
# (which would otherwise trip Rails 7.1's
|
|
59
|
+
# `raise_on_missing_callback_actions`).
|
|
60
|
+
def diagnostics_parent_controller
|
|
61
|
+
expected = config.diagnostics_parent_controller || config.parent_controller
|
|
62
|
+
if @diagnostics_parent_controller && @diagnostics_parent_controller.name != expected
|
|
63
|
+
@diagnostics_parent_controller = nil
|
|
64
|
+
end
|
|
65
|
+
@diagnostics_parent_controller ||= expected.constantize
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def reset_diagnostics_parent_controller!
|
|
69
|
+
@diagnostics_parent_controller = nil
|
|
70
|
+
end
|
|
35
71
|
end
|
|
36
72
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: standard_health
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jaryl Sim
|
|
@@ -37,6 +37,7 @@ files:
|
|
|
37
37
|
- README.md
|
|
38
38
|
- Rakefile
|
|
39
39
|
- app/controllers/standard_health/application_controller.rb
|
|
40
|
+
- app/controllers/standard_health/diagnostics_application_controller.rb
|
|
40
41
|
- app/controllers/standard_health/diagnostics_controller.rb
|
|
41
42
|
- app/controllers/standard_health/health_controller.rb
|
|
42
43
|
- config/routes.rb
|