pg_sql_triggers 1.0.0 → 1.1.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/.erb_lint.yml +47 -0
- data/.rubocop.yml +4 -1
- data/CHANGELOG.md +112 -1
- data/COVERAGE.md +58 -0
- data/Goal.md +450 -123
- data/README.md +53 -215
- data/app/controllers/pg_sql_triggers/application_controller.rb +46 -0
- data/app/controllers/pg_sql_triggers/dashboard_controller.rb +4 -1
- data/app/controllers/pg_sql_triggers/generator_controller.rb +76 -8
- data/app/controllers/pg_sql_triggers/migrations_controller.rb +18 -0
- data/app/models/pg_sql_triggers/trigger_registry.rb +93 -12
- data/app/views/layouts/pg_sql_triggers/application.html.erb +34 -1
- data/app/views/pg_sql_triggers/dashboard/index.html.erb +70 -30
- data/app/views/pg_sql_triggers/generator/new.html.erb +22 -4
- data/app/views/pg_sql_triggers/generator/preview.html.erb +244 -16
- data/app/views/pg_sql_triggers/shared/_confirmation_modal.html.erb +221 -0
- data/app/views/pg_sql_triggers/shared/_kill_switch_status.html.erb +40 -0
- data/app/views/pg_sql_triggers/tables/index.html.erb +0 -2
- data/app/views/pg_sql_triggers/tables/show.html.erb +3 -4
- data/config/initializers/pg_sql_triggers.rb +69 -0
- data/db/migrate/20251222000001_create_pg_sql_triggers_tables.rb +3 -1
- data/db/migrate/20251229071916_add_timing_to_pg_sql_triggers_registry.rb +8 -0
- data/docs/README.md +66 -0
- data/docs/api-reference.md +681 -0
- data/docs/configuration.md +541 -0
- data/docs/getting-started.md +135 -0
- data/docs/kill-switch.md +586 -0
- data/docs/screenshots/.gitkeep +1 -0
- data/docs/screenshots/Generate Trigger.png +0 -0
- data/docs/screenshots/Triggers Page.png +0 -0
- data/docs/screenshots/kill error.png +0 -0
- data/docs/screenshots/kill modal for migration down.png +0 -0
- data/docs/usage-guide.md +493 -0
- data/docs/web-ui.md +353 -0
- data/lib/generators/pg_sql_triggers/templates/create_pg_sql_triggers_tables.rb +3 -1
- data/lib/generators/pg_sql_triggers/templates/initializer.rb +44 -2
- data/lib/pg_sql_triggers/drift/db_queries.rb +116 -0
- data/lib/pg_sql_triggers/drift/detector.rb +187 -0
- data/lib/pg_sql_triggers/drift/reporter.rb +179 -0
- data/lib/pg_sql_triggers/drift.rb +14 -11
- data/lib/pg_sql_triggers/dsl/trigger_definition.rb +15 -1
- data/lib/pg_sql_triggers/generator/form.rb +3 -1
- data/lib/pg_sql_triggers/generator/service.rb +82 -26
- data/lib/pg_sql_triggers/migration.rb +1 -1
- data/lib/pg_sql_triggers/migrator/pre_apply_comparator.rb +344 -0
- data/lib/pg_sql_triggers/migrator/pre_apply_diff_reporter.rb +143 -0
- data/lib/pg_sql_triggers/migrator/safety_validator.rb +258 -0
- data/lib/pg_sql_triggers/migrator.rb +85 -3
- data/lib/pg_sql_triggers/registry/manager.rb +100 -13
- data/lib/pg_sql_triggers/sql/kill_switch.rb +300 -0
- data/lib/pg_sql_triggers/testing/dry_run.rb +5 -7
- data/lib/pg_sql_triggers/testing/function_tester.rb +66 -24
- data/lib/pg_sql_triggers/testing/safe_executor.rb +23 -11
- data/lib/pg_sql_triggers/testing/syntax_validator.rb +24 -1
- data/lib/pg_sql_triggers/version.rb +1 -1
- data/lib/pg_sql_triggers.rb +24 -0
- data/lib/tasks/trigger_migrations.rake +33 -0
- data/scripts/generate_coverage_report.rb +129 -0
- metadata +45 -5
data/docs/kill-switch.md
ADDED
|
@@ -0,0 +1,586 @@
|
|
|
1
|
+
# Kill Switch Documentation
|
|
2
|
+
|
|
3
|
+
The Kill Switch is a centralized safety mechanism that prevents accidental destructive operations in protected environments (production, staging, etc.).
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Overview](#overview)
|
|
8
|
+
- [How It Works](#how-it-works)
|
|
9
|
+
- [Configuration](#configuration)
|
|
10
|
+
- [CLI Usage](#cli-usage)
|
|
11
|
+
- [Console Usage](#console-usage)
|
|
12
|
+
- [Web UI Usage](#web-ui-usage)
|
|
13
|
+
- [Protected Operations](#protected-operations)
|
|
14
|
+
- [Logging and Auditing](#logging-and-auditing)
|
|
15
|
+
- [Customization](#customization)
|
|
16
|
+
|
|
17
|
+
## Overview
|
|
18
|
+
|
|
19
|
+
The Kill Switch provides multiple layers of protection for dangerous operations:
|
|
20
|
+
|
|
21
|
+
1. **Environment Detection**: Automatically identifies protected environments
|
|
22
|
+
2. **Operation Blocking**: Prevents destructive operations by default
|
|
23
|
+
3. **Explicit Confirmation**: Requires typed confirmation text for overrides
|
|
24
|
+
4. **Audit Logging**: Records all attempts and overrides
|
|
25
|
+
|
|
26
|
+
### Key Benefits
|
|
27
|
+
|
|
28
|
+
- **Prevents Accidents**: Stops unintended operations in production
|
|
29
|
+
- **Requires Intent**: Explicit confirmation proves deliberate action
|
|
30
|
+
- **Maintains Audit Trail**: All operations are logged for compliance
|
|
31
|
+
- **Flexible Control**: Can be configured per environment and operation
|
|
32
|
+
|
|
33
|
+
## How It Works
|
|
34
|
+
|
|
35
|
+
The Kill Switch operates on three levels:
|
|
36
|
+
|
|
37
|
+
### Level 1: Configuration
|
|
38
|
+
Environment-based activation via `kill_switch_enabled` and `kill_switch_environments`:
|
|
39
|
+
|
|
40
|
+
```ruby
|
|
41
|
+
config.kill_switch_enabled = true
|
|
42
|
+
config.kill_switch_environments = %i[production staging]
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Level 2: Runtime Override
|
|
46
|
+
ENV variable support for CI/CD and automation:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
KILL_SWITCH_OVERRIDE=true rake trigger:migrate
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Level 3: Explicit Confirmation
|
|
53
|
+
Typed confirmation text proves intentional action:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
KILL_SWITCH_OVERRIDE=true CONFIRMATION_TEXT="EXECUTE TRIGGER_MIGRATE" rake trigger:migrate
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Decision Flow
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
┌─────────────────────────────────────┐
|
|
63
|
+
│ Operation Requested │
|
|
64
|
+
└──────────────┬──────────────────────┘
|
|
65
|
+
│
|
|
66
|
+
▼
|
|
67
|
+
┌─────────────────────────────────────┐
|
|
68
|
+
│ Is Kill Switch Enabled? │
|
|
69
|
+
└──────────────┬──────────────────────┘
|
|
70
|
+
│ Yes
|
|
71
|
+
▼
|
|
72
|
+
┌─────────────────────────────────────┐
|
|
73
|
+
│ Is Environment Protected? │
|
|
74
|
+
└──────────────┬──────────────────────┘
|
|
75
|
+
│ Yes
|
|
76
|
+
▼
|
|
77
|
+
┌─────────────────────────────────────┐
|
|
78
|
+
│ Is Override Provided? │
|
|
79
|
+
└──────────────┬──────────────────────┘
|
|
80
|
+
│ Yes
|
|
81
|
+
▼
|
|
82
|
+
┌─────────────────────────────────────┐
|
|
83
|
+
│ Is Confirmation Valid? │
|
|
84
|
+
└──────────────┬──────────────────────┘
|
|
85
|
+
│ Yes
|
|
86
|
+
▼
|
|
87
|
+
┌─────────────────────────────────────┐
|
|
88
|
+
│ ✓ Operation Allowed │
|
|
89
|
+
│ (Logged as OVERRIDDEN) │
|
|
90
|
+
└─────────────────────────────────────┘
|
|
91
|
+
|
|
92
|
+
│ No at any step
|
|
93
|
+
▼
|
|
94
|
+
┌─────────────────────────────────────┐
|
|
95
|
+
│ ✗ Operation Blocked │
|
|
96
|
+
│ (Logged as BLOCKED) │
|
|
97
|
+
└─────────────────────────────────────┘
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Configuration
|
|
101
|
+
|
|
102
|
+
Configure the Kill Switch in your initializer:
|
|
103
|
+
|
|
104
|
+
```ruby
|
|
105
|
+
# config/initializers/pg_sql_triggers.rb
|
|
106
|
+
PgSqlTriggers.configure do |config|
|
|
107
|
+
# Enable or disable the kill switch globally (default: true)
|
|
108
|
+
config.kill_switch_enabled = true
|
|
109
|
+
|
|
110
|
+
# Specify which environments to protect (default: [:production, :staging])
|
|
111
|
+
config.kill_switch_environments = %i[production staging]
|
|
112
|
+
|
|
113
|
+
# Require confirmation text for overrides (default: true)
|
|
114
|
+
config.kill_switch_confirmation_required = true
|
|
115
|
+
|
|
116
|
+
# Custom confirmation pattern (default: "EXECUTE <OPERATION>")
|
|
117
|
+
config.kill_switch_confirmation_pattern = ->(operation) {
|
|
118
|
+
"EXECUTE #{operation.to_s.upcase}"
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
# Logger for kill switch events (default: Rails.logger)
|
|
122
|
+
config.kill_switch_logger = Rails.logger
|
|
123
|
+
end
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Configuration Options
|
|
127
|
+
|
|
128
|
+
#### `kill_switch_enabled`
|
|
129
|
+
- **Type**: Boolean
|
|
130
|
+
- **Default**: `true`
|
|
131
|
+
- **Description**: Master toggle for the entire kill switch system
|
|
132
|
+
|
|
133
|
+
```ruby
|
|
134
|
+
config.kill_switch_enabled = false # Disable kill switch completely
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
#### `kill_switch_environments`
|
|
138
|
+
- **Type**: Array of Symbols
|
|
139
|
+
- **Default**: `[:production, :staging]`
|
|
140
|
+
- **Description**: List of environments where kill switch is active
|
|
141
|
+
|
|
142
|
+
```ruby
|
|
143
|
+
config.kill_switch_environments = [:production] # Only protect production
|
|
144
|
+
config.kill_switch_environments = [:production, :staging, :demo] # Multiple environments
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
#### `kill_switch_confirmation_required`
|
|
148
|
+
- **Type**: Boolean
|
|
149
|
+
- **Default**: `true`
|
|
150
|
+
- **Description**: Whether confirmation text is required for overrides
|
|
151
|
+
|
|
152
|
+
```ruby
|
|
153
|
+
config.kill_switch_confirmation_required = false # Only ENV override needed
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
#### `kill_switch_confirmation_pattern`
|
|
157
|
+
- **Type**: Lambda/Proc
|
|
158
|
+
- **Default**: `->(operation) { "EXECUTE #{operation.to_s.upcase}" }`
|
|
159
|
+
- **Description**: Generates the required confirmation text
|
|
160
|
+
|
|
161
|
+
```ruby
|
|
162
|
+
config.kill_switch_confirmation_pattern = ->(operation) {
|
|
163
|
+
"CONFIRM-#{operation.to_s.upcase}-#{Date.today.strftime('%Y%m%d')}"
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
#### `kill_switch_logger`
|
|
168
|
+
- **Type**: Logger
|
|
169
|
+
- **Default**: `Rails.logger`
|
|
170
|
+
- **Description**: Logger for kill switch events
|
|
171
|
+
|
|
172
|
+
```ruby
|
|
173
|
+
config.kill_switch_logger = Logger.new('log/kill_switch.log')
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## CLI Usage
|
|
177
|
+
|
|
178
|
+
### Rake Tasks
|
|
179
|
+
|
|
180
|
+
When running dangerous operations via rake tasks in protected environments, you must provide confirmation.
|
|
181
|
+
|
|
182
|
+
#### Basic Migration
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
# Without override - operation will be blocked in production
|
|
186
|
+
rake trigger:migrate
|
|
187
|
+
# => Error: Kill switch is active for production environment
|
|
188
|
+
|
|
189
|
+
# With ENV override and confirmation text
|
|
190
|
+
KILL_SWITCH_OVERRIDE=true CONFIRMATION_TEXT="EXECUTE TRIGGER_MIGRATE" rake trigger:migrate
|
|
191
|
+
# => Success: Migration applied
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
#### Rollback
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
KILL_SWITCH_OVERRIDE=true CONFIRMATION_TEXT="EXECUTE TRIGGER_ROLLBACK" rake trigger:rollback
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
#### Specific Migration Operations
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
# Apply specific migration
|
|
204
|
+
KILL_SWITCH_OVERRIDE=true CONFIRMATION_TEXT="EXECUTE TRIGGER_MIGRATE_UP" \
|
|
205
|
+
rake trigger:migrate:up VERSION=20231215120000
|
|
206
|
+
|
|
207
|
+
# Rollback specific migration
|
|
208
|
+
KILL_SWITCH_OVERRIDE=true CONFIRMATION_TEXT="EXECUTE TRIGGER_MIGRATE_DOWN" \
|
|
209
|
+
rake trigger:migrate:down VERSION=20231215120000
|
|
210
|
+
|
|
211
|
+
# Redo migration
|
|
212
|
+
KILL_SWITCH_OVERRIDE=true CONFIRMATION_TEXT="EXECUTE TRIGGER_MIGRATE_REDO" \
|
|
213
|
+
rake trigger:migrate:redo
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
#### Combined Migrations
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
# Schema and trigger migrations
|
|
220
|
+
KILL_SWITCH_OVERRIDE=true CONFIRMATION_TEXT="EXECUTE DB_MIGRATE_WITH_TRIGGERS" \
|
|
221
|
+
rake db:migrate:with_triggers
|
|
222
|
+
|
|
223
|
+
# Combined rollback
|
|
224
|
+
KILL_SWITCH_OVERRIDE=true CONFIRMATION_TEXT="EXECUTE DB_ROLLBACK_WITH_TRIGGERS" \
|
|
225
|
+
rake db:rollback:with_triggers
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Expected Confirmation Texts
|
|
229
|
+
|
|
230
|
+
| Operation | Required Confirmation Text |
|
|
231
|
+
|-----------|---------------------------|
|
|
232
|
+
| `trigger:migrate` | `EXECUTE TRIGGER_MIGRATE` |
|
|
233
|
+
| `trigger:rollback` | `EXECUTE TRIGGER_ROLLBACK` |
|
|
234
|
+
| `trigger:migrate:up` | `EXECUTE TRIGGER_MIGRATE_UP` |
|
|
235
|
+
| `trigger:migrate:down` | `EXECUTE TRIGGER_MIGRATE_DOWN` |
|
|
236
|
+
| `trigger:migrate:redo` | `EXECUTE TRIGGER_MIGRATE_REDO` |
|
|
237
|
+
| `db:migrate:with_triggers` | `EXECUTE DB_MIGRATE_WITH_TRIGGERS` |
|
|
238
|
+
| `db:rollback:with_triggers` | `EXECUTE DB_ROLLBACK_WITH_TRIGGERS` |
|
|
239
|
+
|
|
240
|
+
## Console Usage
|
|
241
|
+
|
|
242
|
+
### Using the Override Block
|
|
243
|
+
|
|
244
|
+
The `override` method provides a safe way to execute protected operations:
|
|
245
|
+
|
|
246
|
+
```ruby
|
|
247
|
+
# Enable a trigger in production
|
|
248
|
+
PgSqlTriggers::SQL::KillSwitch.override(confirmation: "EXECUTE TRIGGER_ENABLE") do
|
|
249
|
+
trigger = PgSqlTriggers::TriggerRegistry.find_by(trigger_name: "users_email_validation")
|
|
250
|
+
trigger.enable!
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
# Disable a trigger
|
|
254
|
+
PgSqlTriggers::SQL::KillSwitch.override(confirmation: "EXECUTE TRIGGER_DISABLE") do
|
|
255
|
+
trigger = PgSqlTriggers::TriggerRegistry.find_by(trigger_name: "users_email_validation")
|
|
256
|
+
trigger.disable!
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# Run migrations programmatically
|
|
260
|
+
PgSqlTriggers::SQL::KillSwitch.override(confirmation: "EXECUTE MIGRATOR_RUN_UP") do
|
|
261
|
+
PgSqlTriggers::Migrator.run_up
|
|
262
|
+
end
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Direct Confirmation Parameter
|
|
266
|
+
|
|
267
|
+
Some methods accept confirmation directly:
|
|
268
|
+
|
|
269
|
+
```ruby
|
|
270
|
+
# Enable/disable with direct confirmation
|
|
271
|
+
trigger = PgSqlTriggers::TriggerRegistry.find_by(trigger_name: "users_email_validation")
|
|
272
|
+
trigger.enable!(confirmation: "EXECUTE TRIGGER_ENABLE")
|
|
273
|
+
trigger.disable!(confirmation: "EXECUTE TRIGGER_DISABLE")
|
|
274
|
+
|
|
275
|
+
# Migrator with direct confirmation
|
|
276
|
+
PgSqlTriggers::Migrator.run_up(nil, confirmation: "EXECUTE MIGRATOR_RUN_UP")
|
|
277
|
+
PgSqlTriggers::Migrator.run_down(nil, confirmation: "EXECUTE MIGRATOR_RUN_DOWN")
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Checking Kill Switch Status
|
|
281
|
+
|
|
282
|
+
```ruby
|
|
283
|
+
# Check if kill switch is active
|
|
284
|
+
PgSqlTriggers::SQL::KillSwitch.active?
|
|
285
|
+
# => true (in production)
|
|
286
|
+
|
|
287
|
+
# Check for specific operation
|
|
288
|
+
PgSqlTriggers::SQL::KillSwitch.check!(
|
|
289
|
+
operation: :trigger_migrate,
|
|
290
|
+
actor: { type: 'console', user: current_user.email }
|
|
291
|
+
)
|
|
292
|
+
# => Raises error if blocked, returns true if allowed
|
|
293
|
+
|
|
294
|
+
# Get current environment
|
|
295
|
+
PgSqlTriggers::SQL::KillSwitch.environment
|
|
296
|
+
# => "production"
|
|
297
|
+
|
|
298
|
+
# Check if environment is protected
|
|
299
|
+
PgSqlTriggers::SQL::KillSwitch.protected_environment?
|
|
300
|
+
# => true
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Console Examples
|
|
304
|
+
|
|
305
|
+
#### Safe Batch Operations
|
|
306
|
+
|
|
307
|
+
```ruby
|
|
308
|
+
# Enable multiple triggers safely
|
|
309
|
+
trigger_names = ["users_email_validation", "orders_billing_trigger"]
|
|
310
|
+
|
|
311
|
+
PgSqlTriggers::SQL::KillSwitch.override(confirmation: "EXECUTE BATCH_ENABLE") do
|
|
312
|
+
trigger_names.each do |name|
|
|
313
|
+
trigger = PgSqlTriggers::TriggerRegistry.find_by(trigger_name: name)
|
|
314
|
+
trigger.enable!
|
|
315
|
+
puts "Enabled: #{name}"
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
#### Migration with Validation
|
|
321
|
+
|
|
322
|
+
```ruby
|
|
323
|
+
PgSqlTriggers::SQL::KillSwitch.override(confirmation: "EXECUTE TRIGGER_MIGRATE") do
|
|
324
|
+
# Check pending migrations
|
|
325
|
+
pending = PgSqlTriggers::Migrator.pending_migrations
|
|
326
|
+
puts "Pending migrations: #{pending.count}"
|
|
327
|
+
|
|
328
|
+
# Apply migrations
|
|
329
|
+
PgSqlTriggers::Migrator.run_up
|
|
330
|
+
|
|
331
|
+
# Validate results
|
|
332
|
+
PgSqlTriggers::Registry.validate!
|
|
333
|
+
puts "All triggers validated successfully"
|
|
334
|
+
end
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
## Web UI Usage
|
|
338
|
+
|
|
339
|
+
When accessing the web UI in protected environments, dangerous operations require confirmation.
|
|
340
|
+
|
|
341
|
+
### Visual Indicators
|
|
342
|
+
|
|
343
|
+
1. **Kill Switch Badge**: Shows "Protected Environment" banner
|
|
344
|
+
2. **Warning Icons**: Yellow/red indicators on dangerous actions
|
|
345
|
+
3. **Confirmation Modals**: Pop-ups requiring exact confirmation text
|
|
346
|
+
|
|
347
|
+
### Workflow
|
|
348
|
+
|
|
349
|
+
1. Navigate to the desired operation (e.g., "Apply Migration")
|
|
350
|
+
2. Click the action button
|
|
351
|
+
3. A modal appears showing:
|
|
352
|
+
- Operation description
|
|
353
|
+
- Required confirmation text
|
|
354
|
+
- Warning message
|
|
355
|
+
4. Type the exact confirmation text (e.g., "EXECUTE UI_MIGRATION_UP")
|
|
356
|
+
5. Click "Confirm"
|
|
357
|
+
6. Operation executes if confirmation matches
|
|
358
|
+
|
|
359
|
+
### UI Confirmation Texts
|
|
360
|
+
|
|
361
|
+
| Operation | Required Confirmation Text |
|
|
362
|
+
|-----------|---------------------------|
|
|
363
|
+
| Apply Migration (Up) | `EXECUTE UI_MIGRATION_UP` |
|
|
364
|
+
| Rollback Migration (Down) | `EXECUTE UI_MIGRATION_DOWN` |
|
|
365
|
+
| Redo Migration | `EXECUTE UI_MIGRATION_REDO` |
|
|
366
|
+
| Generate Trigger | `EXECUTE UI_TRIGGER_GENERATE` |
|
|
367
|
+
| Enable Trigger | `EXECUTE UI_TRIGGER_ENABLE` |
|
|
368
|
+
| Disable Trigger | `EXECUTE UI_TRIGGER_DISABLE` |
|
|
369
|
+
| Execute SQL | `EXECUTE UI_SQL` |
|
|
370
|
+
|
|
371
|
+
### Screenshot Example
|
|
372
|
+
|
|
373
|
+

|
|
374
|
+
|
|
375
|
+
## Protected Operations
|
|
376
|
+
|
|
377
|
+
### CLI Operations
|
|
378
|
+
|
|
379
|
+
All rake tasks that modify triggers or migrations:
|
|
380
|
+
|
|
381
|
+
- `trigger:migrate`
|
|
382
|
+
- `trigger:rollback`
|
|
383
|
+
- `trigger:migrate:up`
|
|
384
|
+
- `trigger:migrate:down`
|
|
385
|
+
- `trigger:migrate:redo`
|
|
386
|
+
- `db:migrate:with_triggers`
|
|
387
|
+
- `db:rollback:with_triggers`
|
|
388
|
+
|
|
389
|
+
### Console Operations
|
|
390
|
+
|
|
391
|
+
Registry and migrator methods:
|
|
392
|
+
|
|
393
|
+
- `TriggerRegistry#enable!`
|
|
394
|
+
- `TriggerRegistry#disable!`
|
|
395
|
+
- `TriggerRegistry#drop!`
|
|
396
|
+
- `Migrator.run_up`
|
|
397
|
+
- `Migrator.run_down`
|
|
398
|
+
- `Migrator.redo`
|
|
399
|
+
|
|
400
|
+
### Web UI Operations
|
|
401
|
+
|
|
402
|
+
All destructive UI actions:
|
|
403
|
+
|
|
404
|
+
- Migration up/down/redo
|
|
405
|
+
- Trigger enable/disable
|
|
406
|
+
- Trigger generation and application
|
|
407
|
+
- SQL capsule execution
|
|
408
|
+
|
|
409
|
+
## Logging and Auditing
|
|
410
|
+
|
|
411
|
+
All kill switch events are logged with comprehensive information.
|
|
412
|
+
|
|
413
|
+
### Log Format
|
|
414
|
+
|
|
415
|
+
```
|
|
416
|
+
[KILL_SWITCH] STATUS: operation=<operation> environment=<env> actor=<actor> [additional_info]
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### Log Levels
|
|
420
|
+
|
|
421
|
+
#### BLOCKED
|
|
422
|
+
Operation was prevented:
|
|
423
|
+
|
|
424
|
+
```
|
|
425
|
+
[KILL_SWITCH] BLOCKED: operation=trigger_migrate environment=production actor=CLI:ashwin reason=no_override
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
#### OVERRIDDEN
|
|
429
|
+
Operation allowed with valid override:
|
|
430
|
+
|
|
431
|
+
```
|
|
432
|
+
[KILL_SWITCH] OVERRIDDEN: operation=trigger_migrate environment=production actor=CLI:ashwin source=env_with_confirmation confirmation=EXECUTE TRIGGER_MIGRATE
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
#### ALLOWED
|
|
436
|
+
Operation allowed (not in protected environment):
|
|
437
|
+
|
|
438
|
+
```
|
|
439
|
+
[KILL_SWITCH] ALLOWED: operation=trigger_migrate environment=development actor=CLI:ashwin reason=not_protected_environment
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### Audit Information
|
|
443
|
+
|
|
444
|
+
Each log entry includes:
|
|
445
|
+
|
|
446
|
+
- **Operation**: The action being performed
|
|
447
|
+
- **Environment**: Current Rails environment
|
|
448
|
+
- **Actor**: Who is performing the operation
|
|
449
|
+
- CLI: `CLI:username`
|
|
450
|
+
- Console: `Console:user_email`
|
|
451
|
+
- Web UI: `UI:user_id`
|
|
452
|
+
- **Status**: BLOCKED, OVERRIDDEN, or ALLOWED
|
|
453
|
+
- **Source**: How override was provided (if applicable)
|
|
454
|
+
- **Confirmation**: The confirmation text used (if applicable)
|
|
455
|
+
- **Reason**: Why it was blocked or allowed
|
|
456
|
+
|
|
457
|
+
### Custom Logging
|
|
458
|
+
|
|
459
|
+
Configure a separate log file for kill switch events:
|
|
460
|
+
|
|
461
|
+
```ruby
|
|
462
|
+
# config/initializers/pg_sql_triggers.rb
|
|
463
|
+
PgSqlTriggers.configure do |config|
|
|
464
|
+
kill_switch_logger = Logger.new(Rails.root.join('log', 'kill_switch.log'))
|
|
465
|
+
kill_switch_logger.formatter = proc do |severity, datetime, progname, msg|
|
|
466
|
+
"[#{datetime.strftime('%Y-%m-%d %H:%M:%S')}] [#{severity}] #{msg}\n"
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
config.kill_switch_logger = kill_switch_logger
|
|
470
|
+
end
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
## Customization
|
|
474
|
+
|
|
475
|
+
### Custom Confirmation Patterns
|
|
476
|
+
|
|
477
|
+
#### Date-Based Confirmation
|
|
478
|
+
|
|
479
|
+
```ruby
|
|
480
|
+
config.kill_switch_confirmation_pattern = ->(operation) {
|
|
481
|
+
"CONFIRM-#{operation.to_s.upcase}-#{Date.today.strftime('%Y%m%d')}"
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
# Usage:
|
|
485
|
+
# CONFIRMATION_TEXT="CONFIRM-TRIGGER_MIGRATE-20231215" rake trigger:migrate
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
#### Include Environment
|
|
489
|
+
|
|
490
|
+
```ruby
|
|
491
|
+
config.kill_switch_confirmation_pattern = ->(operation) {
|
|
492
|
+
env = Rails.env.upcase
|
|
493
|
+
"#{env}-EXECUTE-#{operation.to_s.upcase}"
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
# Usage:
|
|
497
|
+
# CONFIRMATION_TEXT="PRODUCTION-EXECUTE-TRIGGER_MIGRATE" rake trigger:migrate
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
#### Random Token (Not Recommended)
|
|
501
|
+
|
|
502
|
+
```ruby
|
|
503
|
+
# Generate a one-time token (store it somewhere accessible)
|
|
504
|
+
config.kill_switch_confirmation_pattern = ->(operation) {
|
|
505
|
+
token = SecureRandom.hex(4)
|
|
506
|
+
Rails.cache.write("kill_switch_token_#{operation}", token, expires_in: 5.minutes)
|
|
507
|
+
token
|
|
508
|
+
}
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
### Custom Protected Environments
|
|
512
|
+
|
|
513
|
+
```ruby
|
|
514
|
+
# Protect additional environments
|
|
515
|
+
config.kill_switch_environments = [:production, :staging, :demo, :qa]
|
|
516
|
+
|
|
517
|
+
# Protect all non-development environments
|
|
518
|
+
config.kill_switch_environments = [:production, :staging, :test, :qa, :uat]
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
### Environment-Specific Configuration
|
|
522
|
+
|
|
523
|
+
```ruby
|
|
524
|
+
PgSqlTriggers.configure do |config|
|
|
525
|
+
config.kill_switch_enabled = true
|
|
526
|
+
|
|
527
|
+
# Different rules for different environments
|
|
528
|
+
if Rails.env.production?
|
|
529
|
+
config.kill_switch_confirmation_required = true
|
|
530
|
+
config.kill_switch_confirmation_pattern = ->(op) {
|
|
531
|
+
"PRODUCTION-EXECUTE-#{op.to_s.upcase}-#{Date.today.strftime('%Y%m%d')}"
|
|
532
|
+
}
|
|
533
|
+
elsif Rails.env.staging?
|
|
534
|
+
config.kill_switch_confirmation_required = true
|
|
535
|
+
config.kill_switch_confirmation_pattern = ->(op) { "STAGING-#{op.to_s.upcase}" }
|
|
536
|
+
end
|
|
537
|
+
end
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
## Best Practices
|
|
541
|
+
|
|
542
|
+
1. **Never Disable in Production**: Keep kill switch enabled for production
|
|
543
|
+
2. **Use Descriptive Confirmations**: Make confirmation texts clear and intentional
|
|
544
|
+
3. **Document Overrides**: Log why you're overriding protection
|
|
545
|
+
4. **Review Logs Regularly**: Audit kill switch logs for unexpected activity
|
|
546
|
+
5. **Test in Lower Environments**: Verify operations work before production
|
|
547
|
+
6. **Automate Safely**: Use kill switch overrides in CI/CD with proper controls
|
|
548
|
+
7. **Train Your Team**: Ensure everyone understands the kill switch system
|
|
549
|
+
|
|
550
|
+
## Troubleshooting
|
|
551
|
+
|
|
552
|
+
### Error: "Kill switch is active"
|
|
553
|
+
|
|
554
|
+
**Cause**: Attempting a protected operation without proper override.
|
|
555
|
+
|
|
556
|
+
**Solution**:
|
|
557
|
+
```bash
|
|
558
|
+
# Provide both override and confirmation
|
|
559
|
+
KILL_SWITCH_OVERRIDE=true CONFIRMATION_TEXT="EXECUTE <OPERATION>" rake <task>
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### Error: "Invalid confirmation text"
|
|
563
|
+
|
|
564
|
+
**Cause**: Confirmation text doesn't match the expected pattern.
|
|
565
|
+
|
|
566
|
+
**Solution**: Check the error message for the exact required text and copy it exactly.
|
|
567
|
+
|
|
568
|
+
### Kill Switch Not Working
|
|
569
|
+
|
|
570
|
+
**Check**:
|
|
571
|
+
1. Is `kill_switch_enabled` set to `true`?
|
|
572
|
+
2. Is the current environment in `kill_switch_environments`?
|
|
573
|
+
3. Are you testing in a protected environment?
|
|
574
|
+
|
|
575
|
+
### Logs Not Appearing
|
|
576
|
+
|
|
577
|
+
**Check**:
|
|
578
|
+
1. Is `kill_switch_logger` configured correctly?
|
|
579
|
+
2. Does the log file have write permissions?
|
|
580
|
+
3. Is the log level appropriate?
|
|
581
|
+
|
|
582
|
+
## Next Steps
|
|
583
|
+
|
|
584
|
+
- [Configuration](configuration.md) - Full configuration reference
|
|
585
|
+
- [Web UI](web-ui.md) - Using kill switch in the web interface
|
|
586
|
+
- [API Reference](api-reference.md) - Programmatic access to kill switch
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# This directory is for storing screenshot images referenced in the documentation.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|