123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- package database
- import (
- "fmt"
- "strconv"
- "sync"
- "time"
- "github.com/crowdsecurity/crowdsec/pkg/types"
- log "github.com/sirupsen/logrus"
- "github.com/jinzhu/gorm"
- _ "github.com/jinzhu/gorm/dialects/mysql"
- _ "github.com/jinzhu/gorm/dialects/sqlite"
- _ "github.com/mattn/go-sqlite3"
- "gopkg.in/tomb.v2"
- )
- type Context struct {
- Db *gorm.DB //Pointer to database
- lastCommit time.Time
- flush bool
- count int32
- lock sync.Mutex //booboo
- PusherTomb tomb.Tomb
- //to manage auto cleanup : max number of records *or* oldest
- maxEventRetention int
- maxDurationRetention time.Duration
- }
- func checkConfig(cfg map[string]string) error {
- switch dbType, _ := cfg["type"]; dbType {
- case "sqlite":
- if val, ok := cfg["db_path"]; !ok || val == "" {
- return fmt.Errorf("please specify a 'db_path' to SQLite db in the configuration")
- }
- case "mysql":
- if val, ok := cfg["db_host"]; !ok || val == "" {
- return fmt.Errorf("please specify a 'db_host' to MySQL db in the configuration")
- }
- if val, ok := cfg["db_username"]; !ok || val == "" {
- return fmt.Errorf("please specify a 'db_username' to MySQL db in the configuration")
- }
- if val, ok := cfg["db_password"]; !ok || val == "" {
- return fmt.Errorf("please specify a 'db_password' to MySQL db in the configuration")
- }
- if val, ok := cfg["db_name"]; !ok || val == "" {
- return fmt.Errorf("please specify a 'db_name' to MySQL db in the configuration")
- }
- default:
- return fmt.Errorf("please specify a proper 'type' to the database configuration ")
- }
- return nil
- }
- func NewDatabase(cfg map[string]string) (*Context, error) {
- var err error
- c := &Context{}
- if err = checkConfig(cfg); err != nil {
- return nil, fmt.Errorf("bad database configuration : %v", err)
- }
- if cfg["type"] == "sqlite" {
- c.Db, err = gorm.Open("sqlite3", cfg["db_path"]+"?_busy_timeout=10000")
- if err != nil {
- return nil, fmt.Errorf("failed to open %s : %s", cfg["db_path"], err)
- }
- }
- if cfg["type"] == "mysql" {
- gormArg := cfg["db_username"] + ":" + cfg["db_password"] + "@(" + cfg["db_host"] + ")/" + cfg["db_name"] + "?charset=utf8&parseTime=True&loc=Local"
- c.Db, err = gorm.Open("mysql", gormArg)
- if err != nil {
- return nil, fmt.Errorf("failed to open %s database : %s", cfg["db_name"], err)
- }
- }
- if v, ok := cfg["max_records"]; ok {
- c.maxEventRetention, err = strconv.Atoi(v)
- if err != nil {
- log.Errorf("Ignoring invalid max_records '%s' : %s", v, err)
- }
- }
- if v, ok := cfg["max_records_age"]; ok {
- c.maxDurationRetention, err = time.ParseDuration(v)
- if err != nil {
- log.Errorf("Ignoring invalid duration '%s' : %s", v, err)
- }
- }
- if val, ok := cfg["debug"]; ok && val == "true" {
- log.Infof("Enabling debug for %s", cfg["type"])
- c.Db.LogMode(true)
- }
- c.flush, err = strconv.ParseBool(cfg["flush"])
- if err != nil {
- return nil, fmt.Errorf("failed to parse 'flush' value %s : %s", cfg["flush"], err)
- }
- // Migrate the schema
- c.Db.AutoMigrate(&types.EventSequence{}, &types.SignalOccurence{}, &types.BanApplication{})
- c.Db.Model(&types.SignalOccurence{}).Related(&types.EventSequence{})
- c.Db.Model(&types.SignalOccurence{}).Related(&types.BanApplication{})
- c.lastCommit = time.Now()
- return c, nil
- }
|