GORM SQLChaos manipulates DML at program runtime based on gorm callbacks
In Financial Business distributed system, account imbalance problems caused by unstable networks or human mistakes may cause serious impacts. We built Imbalance Monitor&Analysis System, so we want to create data imbalance situations between our business systems to verify if our monitor reports these imbalances timely. Also, we want this situation to be controllable and runs periodically to ensure the system works fine.
Yep, Chaos Engineering ;).
So I developed SQLChaos and embedded it into our business systems.
NOTE: if you're looking for SQL injection attack or any related tools, SQLChaos is not what you want.
- Easy to embed into your code;
- Modify DML SQL values at program runtime;
- Support
INSERT
,UPDATE
SQL;
SQLChaos registers hooks on gorm Before("gorm:update")
and Before("gorm:create")
callbacks.
It will fetch values from *Statement.Dest pointer, which is a staging store before the real operation is performed,
and try to match user defined conditions and apply assigments.
Embed SQLChaos where your gorm.DB setupped.
db, err := gorm.Open(mysql.Open(DSN), &gorm.Config{}, &sqlchaos.Config{
DBName: "dummy",
RuleProvider: sqlchaos.WithSimpleHTTPRuleProvider(),
})
if err != nil {
fmt.Fprintf(os.Stderr, "connect db failed:%v", err)
return
}
SQLChaos provides a simple HTTP server for implementing RuleProvider
to enable/disable
chaos rules at program runtime. You can implement yours and replace it as your need.
SimpleHTTPRuleProvider listens at SQLCHAOS_HTTP
.
> SQLCHAOS_HTTP=127.0.0.1:8081 ./your-program
After your program started, you will see SQLChaos enabled
. And SQLChaos listens at port 8081
.
Try to enable a rule,
export DBNAME=dummy;export TABLE=users;
# For dabase dummy table users, before INSERT Statement evaluated,
# set balance to 1024 and age to 40 for every record
# which age is greater then or equals to 1 and less then 50.
> curl -XPOST "http://127.0.0.1:8081/$DBNAME/$TABLE" -H'Content-Type: application/json' \
-d'{"dml":"INSERT","when":"age>=1 AND age<50","then":"balance=1024,age=40"}'
After enabled, every record you created using gorm which matches age>=1
and age<50
condition,
the balance
will be set to 1024
and age
will be 40
before it inserted into database.
To disable the table chaos rule,
> curl -XDELETE "http://127.0.0.1:8081/$DBNAME/$TABLE"
For more practical examples, please check ./example
.
- gorm
Save
may not envoke hooks, so SQLChaos only be called inCreate
,Update
,Updates
; when
condition supportsAND
only, and operators like= < <= > >=
are supported;- Only read values from gorm Statement.Dest which is basically same as
the argument you pass to
Create
Update
Updates
functions. Ensure values whichwhen
needed are present where you call onCreate
,Update
,Updates
. Record will not be matched if valueswhen
required are absent.