data_shifter 0.3.2 → 0.3.3
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 +8 -0
- data/README.md +7 -2
- data/lib/data_shifter/configuration.rb +6 -0
- data/lib/data_shifter/internal/side_effect_guards.rb +35 -3
- data/lib/data_shifter/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8f9ab924aaeb0638f2061907484bc7ba4f5e795a1ea58e96f1ae8b0a7542b150
|
|
4
|
+
data.tar.gz: 24a81ebe9a5e1f0d27d4cec1494fd26c4c8d1209ddca2aba6cd606dec14e4dda
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f5834ec7a2545de4342cc3f9205c8ce0f3a0b53fdfbebacd1452b7196c1b7cb606c4fa4d32e8e7d92532ff7e958f5537d2cba51e0176f9d760cdad9fa8b31498
|
|
7
|
+
data.tar.gz: cefd020aedd8a63f65f0bb507bcf8843a65fac12debfb78e47cd0e74b485e98746a8d3b805e0c2be6071254488308a1c10b47fb9e5280f13425d6eade6f4113d
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
* N/A
|
|
6
6
|
|
|
7
|
+
## [0.3.3]
|
|
8
|
+
|
|
9
|
+
* [Bugfix] Dry-run net guard now allows loopback hosts (`127.0.0.1`, `::1`, `localhost`) by default. Previously, any tracing/metrics sidecar listening on loopback (Datadog agent on 8126, statsd on 8125, OTLP collectors, etc.) would trip `WebMock::NetConnectNotAllowedError` from a background tracer thread and abort the rake task — even when the shift itself made no HTTP calls. Opt out with `DataShifter.config.allow_loopback_requests = false` for strict net blocking.
|
|
10
|
+
|
|
11
|
+
## [0.3.2.1]
|
|
12
|
+
|
|
13
|
+
* [Bugfix] Dry-run Sidekiq guard restores the previous `Sidekiq::Testing` mode (`fake!`, `inline!`, or `disable!`) instead of always calling `disable!`, which leaked global state and could leave later specs enqueueing work to real Redis.
|
|
14
|
+
|
|
7
15
|
## [0.3.2]
|
|
8
16
|
|
|
9
17
|
* [Bugfix] Rake tasks exit quietly after a failed shift run when the shift already printed its failure summary; failures before that summary are still reported on stderr. Replaces rescuing only `Axn::Failure`, which missed most re-raised exceptions from `run!`.
|
data/README.md
CHANGED
|
@@ -111,10 +111,10 @@ In **dry run** mode, DataShifter automatically blocks or fakes these side effect
|
|
|
111
111
|
|
|
112
112
|
| Service | Behavior in dry run |
|
|
113
113
|
|-------------|----------------------|
|
|
114
|
-
| **HTTP** | Blocked via WebMock (`disable_net_connect!`). Allow
|
|
114
|
+
| **HTTP** | Blocked via WebMock (`disable_net_connect!`). Loopback (`127.0.0.1`, `::1`, `localhost`) is allowed by default so tracing/metrics sidecars (Datadog agent, statsd, OTLP collector, etc.) keep working; opt out with `DataShifter.config.allow_loopback_requests = false`. Allow other hosts with `allow_external_requests [...]` or `DataShifter.config.allow_external_requests`. |
|
|
115
115
|
| **ActionMailer** | `perform_deliveries = false` (restored after run). |
|
|
116
116
|
| **ActiveJob** | Queue adapter set to `:test` (restored after run). |
|
|
117
|
-
| **Sidekiq** | `Sidekiq::Testing.fake!` (
|
|
117
|
+
| **Sidekiq** | `Sidekiq::Testing.fake!` for the run; previous mode (`fake!`, `inline!`, or `disable!`) is restored after. Only applied if `Sidekiq::Testing` is already loaded. |
|
|
118
118
|
|
|
119
119
|
**Guarding other side effects:** For anything we don't cover (e.g. another service, or allowed HTTP that mutates), use e.g. `return if dry_run?` in your shift. DB changes are always rolled back in dry run; only non-DB side effects need this.
|
|
120
120
|
|
|
@@ -222,6 +222,11 @@ DataShifter.configure do |config|
|
|
|
222
222
|
# Hosts allowed for HTTP during dry run only (no effect in commit mode)
|
|
223
223
|
config.allow_external_requests = ["api.readonly.example.com"]
|
|
224
224
|
|
|
225
|
+
# Allow loopback HTTP (127.0.0.1, ::1, localhost) during dry runs (default: true).
|
|
226
|
+
# Needed so tracing/metrics sidecars (Datadog agent on 8126, statsd on 8125, OTLP
|
|
227
|
+
# collector, etc.) keep working in dry-run mode.
|
|
228
|
+
config.allow_loopback_requests = true
|
|
229
|
+
|
|
225
230
|
# Suppress repeated log messages during a shift run (default: true)
|
|
226
231
|
config.suppress_repeated_logs = true
|
|
227
232
|
|
|
@@ -16,6 +16,11 @@ module DataShifter
|
|
|
16
16
|
# Has no effect in commit mode — HTTP is unrestricted when dry_run is false.
|
|
17
17
|
attr_accessor :allow_external_requests
|
|
18
18
|
|
|
19
|
+
# Whether to allow loopback HTTP (127.0.0.1, ::1, localhost) during dry runs. Default: true.
|
|
20
|
+
# Loopback is rarely "external" and is needed for tracing/metrics sidecars (Datadog agent on
|
|
21
|
+
# 8126, statsd on 8125, OTLP collector, etc.). Set to false if you want strict net blocking.
|
|
22
|
+
attr_accessor :allow_loopback_requests
|
|
23
|
+
|
|
19
24
|
# Whether to suppress repeated log messages during a shift run. Default: true.
|
|
20
25
|
# Can be overridden per shift with `suppress_repeated_logs true/false`.
|
|
21
26
|
attr_accessor :suppress_repeated_logs
|
|
@@ -33,6 +38,7 @@ module DataShifter
|
|
|
33
38
|
|
|
34
39
|
def initialize
|
|
35
40
|
@allow_external_requests = []
|
|
41
|
+
@allow_loopback_requests = true
|
|
36
42
|
@suppress_repeated_logs = true
|
|
37
43
|
@repeated_log_cap = 1000
|
|
38
44
|
@progress_enabled = true
|
|
@@ -12,8 +12,15 @@ module DataShifter
|
|
|
12
12
|
# production runs never load WebMock. On restore we revert to the previous state (enable!
|
|
13
13
|
# or disable!) so e.g. specs that had WebMock enabled are not left with it disabled.
|
|
14
14
|
# - ActionMailer / ActiveJob / Sidekiq: no extra loading; we only toggle existing config
|
|
15
|
-
# for the duration of the block and restore in ensure
|
|
15
|
+
# for the duration of the block and restore in ensure (Sidekiq restores prior fake/inline/disable).
|
|
16
16
|
module SideEffectGuards
|
|
17
|
+
# Loopback hosts allowed by default during dry-run net blocking (unless opted out via
|
|
18
|
+
# DataShifter.config.allow_loopback_requests = false). Localhost is by definition local —
|
|
19
|
+
# the guard's purpose is to prevent accidental *external* state mutations, not to fight
|
|
20
|
+
# tracing/metrics sidecars (Datadog agent on 8126, statsd on 8125, OTLP collector, etc.)
|
|
21
|
+
# which commonly listen on these hosts.
|
|
22
|
+
DEFAULT_LOOPBACK_HOSTS = %w[127.0.0.1 ::1 localhost].freeze
|
|
23
|
+
|
|
17
24
|
class << self
|
|
18
25
|
# Applies side-effect guards, yields, then restores. Call only when running in dry run.
|
|
19
26
|
def with_guards(shift_class:, &block)
|
|
@@ -62,7 +69,8 @@ module DataShifter
|
|
|
62
69
|
def allowed_net_hosts(shift_class)
|
|
63
70
|
per_shift = shift_class.respond_to?(:_allow_external_requests) ? shift_class._allow_external_requests : []
|
|
64
71
|
global = DataShifter.config.allow_external_requests
|
|
65
|
-
|
|
72
|
+
loopback = DataShifter.config.allow_loopback_requests ? DEFAULT_LOOPBACK_HOSTS : []
|
|
73
|
+
Array(per_shift) + Array(global) + loopback
|
|
66
74
|
end
|
|
67
75
|
|
|
68
76
|
def webmock_net_connect_error
|
|
@@ -97,10 +105,23 @@ module DataShifter
|
|
|
97
105
|
def apply_sidekiq(saved)
|
|
98
106
|
return unless Sidekiq::Testing.respond_to?(:fake!)
|
|
99
107
|
|
|
108
|
+
saved[:sidekiq_testing_mode] = capture_sidekiq_testing_mode
|
|
100
109
|
Sidekiq::Testing.fake!
|
|
101
110
|
saved[:sidekiq] = true
|
|
102
111
|
end
|
|
103
112
|
|
|
113
|
+
def capture_sidekiq_testing_mode
|
|
114
|
+
if Sidekiq::Testing.respond_to?(:__test_mode)
|
|
115
|
+
Sidekiq::Testing.__test_mode
|
|
116
|
+
elsif Sidekiq::Testing.fake?
|
|
117
|
+
:fake
|
|
118
|
+
elsif Sidekiq::Testing.inline?
|
|
119
|
+
:inline
|
|
120
|
+
else
|
|
121
|
+
:disable
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
104
125
|
def restore_guards(saved)
|
|
105
126
|
if saved.delete(:webmock)
|
|
106
127
|
(saved.delete(:webmock_was_enabled) ? WebMock.enable! : WebMock.disable!)
|
|
@@ -112,7 +133,18 @@ module DataShifter
|
|
|
112
133
|
|
|
113
134
|
return unless saved.delete(:sidekiq)
|
|
114
135
|
|
|
115
|
-
|
|
136
|
+
restore_sidekiq_testing_mode(saved.delete(:sidekiq_testing_mode))
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def restore_sidekiq_testing_mode(mode)
|
|
140
|
+
case mode
|
|
141
|
+
when :fake
|
|
142
|
+
Sidekiq::Testing.fake!
|
|
143
|
+
when :inline
|
|
144
|
+
Sidekiq::Testing.inline!
|
|
145
|
+
else
|
|
146
|
+
Sidekiq::Testing.disable!
|
|
147
|
+
end
|
|
116
148
|
end
|
|
117
149
|
end
|
|
118
150
|
end
|
data/lib/data_shifter/version.rb
CHANGED