152 lines
5.2 KiB
Ruby
152 lines
5.2 KiB
Ruby
class AlignWafActionEnums < ActiveRecord::Migration[8.1]
|
|
def up
|
|
# Current enum mapping (BEFORE):
|
|
# allow: 0, deny: 1, rate_limit: 2, redirect: 3, log: 4, challenge: 5
|
|
#
|
|
# Target enum mapping (AFTER):
|
|
# deny: 0, allow: 1, redirect: 2, challenge: 3, log: 4
|
|
#
|
|
# Strategy: Use temporary values to avoid conflicts during swap
|
|
|
|
say "Aligning WAF action enums to canonical order (deny:0, allow:1, redirect:2, challenge:3, log:4)"
|
|
|
|
# === Rules Table ===
|
|
say_with_time "Updating rules table..." do
|
|
# Temporarily disable triggers to avoid FK constraint issues during enum swap
|
|
execute "SET session_replication_role = replica;"
|
|
|
|
# Step 1: Move existing values to temporary range (100+)
|
|
execute <<-SQL
|
|
UPDATE rules
|
|
SET waf_action = CASE
|
|
WHEN waf_action = 0 THEN 100 -- allow -> temp(100)
|
|
WHEN waf_action = 1 THEN 101 -- deny -> temp(101)
|
|
WHEN waf_action = 2 THEN 102 -- rate_limit -> temp(102)
|
|
WHEN waf_action = 3 THEN 103 -- redirect -> temp(103)
|
|
WHEN waf_action = 4 THEN 104 -- log -> temp(104)
|
|
WHEN waf_action = 5 THEN 105 -- challenge -> temp(105)
|
|
ELSE waf_action
|
|
END
|
|
SQL
|
|
|
|
# Step 2: Move from temporary to final positions
|
|
execute <<-SQL
|
|
UPDATE rules
|
|
SET waf_action = CASE
|
|
WHEN waf_action = 101 THEN 0 -- deny -> 0
|
|
WHEN waf_action = 100 THEN 1 -- allow -> 1
|
|
WHEN waf_action = 103 THEN 2 -- redirect -> 2
|
|
WHEN waf_action = 105 THEN 3 -- challenge -> 3
|
|
WHEN waf_action = 104 THEN 4 -- log -> 4
|
|
WHEN waf_action = 102 THEN 0 -- rate_limit -> deny (rate_limit is a rule_type, not action)
|
|
ELSE waf_action
|
|
END
|
|
SQL
|
|
|
|
# Re-enable triggers
|
|
execute "SET session_replication_role = DEFAULT;"
|
|
|
|
# Return count without triggering model validations
|
|
connection.execute("SELECT COUNT(*) FROM rules").first["count"]
|
|
end
|
|
|
|
# === Events Table ===
|
|
say_with_time "Updating events table..." do
|
|
# Step 1: Move existing values to temporary range (100+)
|
|
execute <<-SQL
|
|
UPDATE events
|
|
SET waf_action = CASE
|
|
WHEN waf_action = 0 THEN 100 -- allow -> temp(100)
|
|
WHEN waf_action = 1 THEN 101 -- deny -> temp(101)
|
|
WHEN waf_action = 2 THEN 102 -- redirect -> temp(102)
|
|
WHEN waf_action = 3 THEN 103 -- challenge -> temp(103)
|
|
ELSE waf_action
|
|
END
|
|
SQL
|
|
|
|
# Step 2: Move from temporary to final positions
|
|
execute <<-SQL
|
|
UPDATE events
|
|
SET waf_action = CASE
|
|
WHEN waf_action = 101 THEN 0 -- deny -> 0
|
|
WHEN waf_action = 100 THEN 1 -- allow -> 1
|
|
WHEN waf_action = 102 THEN 2 -- redirect -> 2
|
|
WHEN waf_action = 103 THEN 3 -- challenge -> 3
|
|
ELSE waf_action
|
|
END
|
|
SQL
|
|
|
|
# Return count without triggering model validations
|
|
connection.execute("SELECT COUNT(*) FROM events").first["count"]
|
|
end
|
|
|
|
say "Enum alignment complete!", true
|
|
end
|
|
|
|
def down
|
|
# Reverse the migration - swap back to old order
|
|
say "Reverting WAF action enums to original order"
|
|
|
|
# === Rules Table ===
|
|
say_with_time "Reverting rules table..." do
|
|
execute <<-SQL
|
|
UPDATE rules
|
|
SET waf_action = CASE
|
|
WHEN waf_action = 0 THEN 100 -- deny -> temp(100)
|
|
WHEN waf_action = 1 THEN 101 -- allow -> temp(101)
|
|
WHEN waf_action = 2 THEN 102 -- redirect -> temp(102)
|
|
WHEN waf_action = 3 THEN 103 -- challenge -> temp(103)
|
|
WHEN waf_action = 4 THEN 104 -- log -> temp(104)
|
|
ELSE waf_action
|
|
END
|
|
SQL
|
|
|
|
execute <<-SQL
|
|
UPDATE rules
|
|
SET waf_action = CASE
|
|
WHEN waf_action = 101 THEN 0 -- allow -> 0
|
|
WHEN waf_action = 100 THEN 1 -- deny -> 1
|
|
WHEN waf_action = 104 THEN 4 -- log -> 4
|
|
WHEN waf_action = 103 THEN 3 -- redirect -> 3
|
|
WHEN waf_action = 102 THEN 2 -- rate_limit -> 2 (restore even though deprecated)
|
|
WHEN waf_action = 105 THEN 5 -- challenge -> 5
|
|
ELSE waf_action
|
|
END
|
|
SQL
|
|
|
|
# Return count without triggering model validations
|
|
connection.execute("SELECT COUNT(*) FROM rules").first["count"]
|
|
end
|
|
|
|
# === Events Table ===
|
|
say_with_time "Reverting events table..." do
|
|
execute <<-SQL
|
|
UPDATE events
|
|
SET waf_action = CASE
|
|
WHEN waf_action = 0 THEN 100 -- deny -> temp(100)
|
|
WHEN waf_action = 1 THEN 101 -- allow -> temp(101)
|
|
WHEN waf_action = 2 THEN 102 -- redirect -> temp(102)
|
|
WHEN waf_action = 3 THEN 103 -- challenge -> temp(103)
|
|
ELSE waf_action
|
|
END
|
|
SQL
|
|
|
|
execute <<-SQL
|
|
UPDATE events
|
|
SET waf_action = CASE
|
|
WHEN waf_action = 101 THEN 0 -- allow -> 0
|
|
WHEN waf_action = 100 THEN 1 -- deny -> 1
|
|
WHEN waf_action = 102 THEN 2 -- redirect -> 2
|
|
WHEN waf_action = 103 THEN 3 -- challenge -> 3
|
|
ELSE waf_action
|
|
END
|
|
SQL
|
|
|
|
# Return count without triggering model validations
|
|
connection.execute("SELECT COUNT(*) FROM events").first["count"]
|
|
end
|
|
|
|
say "Revert complete!", true
|
|
end
|
|
end
|