github.com/crowdsecurity/crowdsec@v1.6.1/pkg/metabase/database.go (about)

     1  package metabase
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"path/filepath"
     7  	"strings"
     8  
     9  	"github.com/crowdsecurity/crowdsec/pkg/csconfig"
    10  )
    11  
    12  type Database struct {
    13  	DBUrl   string
    14  	Model   *Model
    15  	Config  *csconfig.DatabaseCfg
    16  	Client  *MBClient
    17  	Details *Details
    18  	// in case mysql host is 127.0.0.1 the ip address of mysql/pgsql host will be the docker gateway since metabase run in a container
    19  }
    20  
    21  type Details struct {
    22  	Db                string      `json:"db"`
    23  	Host              string      `json:"host"`
    24  	Port              int         `json:"port"`
    25  	Dbname            string      `json:"dbname"`
    26  	User              string      `json:"user"`
    27  	Password          string      `json:"password"`
    28  	Ssl               bool        `json:"ssl"`
    29  	AdditionalOptions interface{} `json:"additional-options"`
    30  	TunnelEnabled     bool        `json:"tunnel-enabled"`
    31  }
    32  
    33  type Model struct {
    34  	Engine         string                 `json:"engine"`
    35  	Name           string                 `json:"name"`
    36  	Details        *Details               `json:"details"`
    37  	AutoRunQueries bool                   `json:"auto_run_queries"`
    38  	IsFullSync     bool                   `json:"is_full_sync"`
    39  	IsOnDemand     bool                   `json:"is_on_demand"`
    40  	Schedules      map[string]interface{} `json:"schedules"`
    41  }
    42  
    43  func NewDatabase(config *csconfig.DatabaseCfg, client *MBClient, remoteDBAddr string) (*Database, error) {
    44  	var details *Details
    45  
    46  	database := Database{}
    47  
    48  	switch config.Type {
    49  	case "mysql":
    50  		return nil, fmt.Errorf("database '%s' is not supported yet", config.Type)
    51  	case "sqlite":
    52  		database.DBUrl = metabaseSQLiteDBURL
    53  		localFolder := filepath.Dir(config.DbPath)
    54  		// replace /var/lib/crowdsec/data/ with /metabase-data/
    55  		dbPath := strings.Replace(config.DbPath, localFolder, containerSharedFolder, 1)
    56  		details = &Details{
    57  			Db: dbPath,
    58  		}
    59  	case "postgresql", "postgres", "pgsql":
    60  		return nil, fmt.Errorf("database '%s' is not supported yet", config.Type)
    61  	default:
    62  		return nil, fmt.Errorf("database '%s' not supported", config.Type)
    63  	}
    64  	database.Details = details
    65  	database.Client = client
    66  	database.Config = config
    67  
    68  	return &database, nil
    69  }
    70  
    71  func (d *Database) Update() error {
    72  	success, errormsg, err := d.Client.Do("GET", routes[databaseEndpoint], nil)
    73  	if err != nil {
    74  		return err
    75  	}
    76  	if errormsg != nil {
    77  		return fmt.Errorf("update sqlite db http error: %+v", errormsg)
    78  	}
    79  
    80  	data, err := json.Marshal(success)
    81  	if err != nil {
    82  		return fmt.Errorf("update sqlite db response (marshal): %w", err)
    83  	}
    84  
    85  	model := Model{}
    86  
    87  	if err := json.Unmarshal(data, &model); err != nil {
    88  		return fmt.Errorf("update sqlite db response (unmarshal): %w", err)
    89  	}
    90  	model.Details = d.Details
    91  	_, errormsg, err = d.Client.Do("PUT", routes[databaseEndpoint], model)
    92  	if err != nil {
    93  		return err
    94  	}
    95  	if errormsg != nil {
    96  		return fmt.Errorf("update sqlite db http error: %+v", errormsg)
    97  	}
    98  
    99  	return nil
   100  }