2020-11-30 09:37:17 +00:00
|
|
|
package database
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/go-openapi/strfmt"
|
2023-06-22 09:31:41 +00:00
|
|
|
"github.com/pkg/errors"
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
2020-11-30 09:37:17 +00:00
|
|
|
|
|
|
|
"github.com/crowdsecurity/crowdsec/pkg/database/ent"
|
|
|
|
"github.com/crowdsecurity/crowdsec/pkg/database/ent/machine"
|
2023-01-31 13:47:44 +00:00
|
|
|
"github.com/crowdsecurity/crowdsec/pkg/types"
|
2020-11-30 09:37:17 +00:00
|
|
|
)
|
|
|
|
|
2023-01-31 13:47:44 +00:00
|
|
|
const CapiMachineID = types.CAPIOrigin
|
|
|
|
const CapiListsMachineID = types.ListOrigin
|
2021-08-25 09:45:29 +00:00
|
|
|
|
2022-06-08 14:05:52 +00:00
|
|
|
func (c *Client) CreateMachine(machineID *string, password *strfmt.Password, ipAddress string, isValidated bool, force bool, authType string) (*ent.Machine, error) {
|
2020-11-30 09:37:17 +00:00
|
|
|
hashPassword, err := bcrypt.GenerateFromPassword([]byte(*password), bcrypt.DefaultCost)
|
|
|
|
if err != nil {
|
2023-12-04 22:06:01 +00:00
|
|
|
c.Log.Warningf("CreateMachine: %s", err)
|
|
|
|
return nil, HashError
|
2020-11-30 09:37:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
machineExist, err := c.Ent.Machine.
|
|
|
|
Query().
|
|
|
|
Where(machine.MachineIdEQ(*machineID)).
|
|
|
|
Select(machine.FieldMachineId).Strings(c.CTX)
|
|
|
|
if err != nil {
|
2022-06-08 14:05:52 +00:00
|
|
|
return nil, errors.Wrapf(QueryFail, "machine '%s': %s", *machineID, err)
|
2020-11-30 09:37:17 +00:00
|
|
|
}
|
|
|
|
if len(machineExist) > 0 {
|
|
|
|
if force {
|
|
|
|
_, err := c.Ent.Machine.Update().Where(machine.MachineIdEQ(*machineID)).SetPassword(string(hashPassword)).Save(c.CTX)
|
|
|
|
if err != nil {
|
2021-03-12 14:10:56 +00:00
|
|
|
c.Log.Warningf("CreateMachine : %s", err)
|
2022-06-08 14:05:52 +00:00
|
|
|
return nil, errors.Wrapf(UpdateFail, "machine '%s'", *machineID)
|
2020-11-30 09:37:17 +00:00
|
|
|
}
|
2022-06-08 14:05:52 +00:00
|
|
|
machine, err := c.QueryMachineByID(*machineID)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrapf(QueryFail, "machine '%s': %s", *machineID, err)
|
|
|
|
}
|
|
|
|
return machine, nil
|
2020-11-30 09:37:17 +00:00
|
|
|
}
|
2022-06-08 14:05:52 +00:00
|
|
|
return nil, errors.Wrapf(UserExists, "user '%s'", *machineID)
|
2020-11-30 09:37:17 +00:00
|
|
|
}
|
|
|
|
|
2022-06-08 14:05:52 +00:00
|
|
|
machine, err := c.Ent.Machine.
|
2020-11-30 09:37:17 +00:00
|
|
|
Create().
|
|
|
|
SetMachineId(*machineID).
|
|
|
|
SetPassword(string(hashPassword)).
|
|
|
|
SetIpAddress(ipAddress).
|
|
|
|
SetIsValidated(isValidated).
|
2022-06-08 14:05:52 +00:00
|
|
|
SetAuthType(authType).
|
2020-11-30 09:37:17 +00:00
|
|
|
Save(c.CTX)
|
|
|
|
|
|
|
|
if err != nil {
|
2021-03-12 14:10:56 +00:00
|
|
|
c.Log.Warningf("CreateMachine : %s", err)
|
2022-06-08 14:05:52 +00:00
|
|
|
return nil, errors.Wrapf(InsertFail, "creating machine '%s'", *machineID)
|
2020-11-30 09:37:17 +00:00
|
|
|
}
|
|
|
|
|
2022-06-08 14:05:52 +00:00
|
|
|
return machine, nil
|
2020-11-30 09:37:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) QueryMachineByID(machineID string) (*ent.Machine, error) {
|
|
|
|
machine, err := c.Ent.Machine.
|
|
|
|
Query().
|
|
|
|
Where(machine.MachineIdEQ(machineID)).
|
|
|
|
Only(c.CTX)
|
|
|
|
if err != nil {
|
2021-03-12 14:10:56 +00:00
|
|
|
c.Log.Warningf("QueryMachineByID : %s", err)
|
2020-11-30 09:37:17 +00:00
|
|
|
return &ent.Machine{}, errors.Wrapf(UserNotExists, "user '%s'", machineID)
|
|
|
|
}
|
|
|
|
return machine, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) ListMachines() ([]*ent.Machine, error) {
|
|
|
|
machines, err := c.Ent.Machine.Query().All(c.CTX)
|
|
|
|
if err != nil {
|
2023-12-04 22:06:01 +00:00
|
|
|
return nil, errors.Wrapf(QueryFail, "listing machines: %s", err)
|
2020-11-30 09:37:17 +00:00
|
|
|
}
|
|
|
|
return machines, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) ValidateMachine(machineID string) error {
|
2022-01-05 12:50:04 +00:00
|
|
|
rets, err := c.Ent.Machine.Update().Where(machine.MachineIdEQ(machineID)).SetIsValidated(true).Save(c.CTX)
|
2020-11-30 09:37:17 +00:00
|
|
|
if err != nil {
|
2021-03-11 10:18:09 +00:00
|
|
|
return errors.Wrapf(UpdateFail, "validating machine: %s", err)
|
2020-11-30 09:37:17 +00:00
|
|
|
}
|
2022-01-05 12:50:04 +00:00
|
|
|
if rets == 0 {
|
|
|
|
return fmt.Errorf("machine not found")
|
|
|
|
}
|
2020-11-30 09:37:17 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) QueryPendingMachine() ([]*ent.Machine, error) {
|
|
|
|
var machines []*ent.Machine
|
|
|
|
var err error
|
|
|
|
|
|
|
|
machines, err = c.Ent.Machine.Query().Where(machine.IsValidatedEQ(false)).All(c.CTX)
|
|
|
|
if err != nil {
|
2021-03-12 14:10:56 +00:00
|
|
|
c.Log.Warningf("QueryPendingMachine : %s", err)
|
2023-12-04 22:06:01 +00:00
|
|
|
return nil, errors.Wrapf(QueryFail, "querying pending machines: %s", err)
|
2020-11-30 09:37:17 +00:00
|
|
|
}
|
|
|
|
return machines, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) DeleteWatcher(name string) error {
|
2022-07-28 15:32:12 +00:00
|
|
|
nbDeleted, err := c.Ent.Machine.
|
2020-11-30 09:37:17 +00:00
|
|
|
Delete().
|
|
|
|
Where(machine.MachineIdEQ(name)).
|
|
|
|
Exec(c.CTX)
|
|
|
|
if err != nil {
|
2022-07-28 15:32:12 +00:00
|
|
|
return err
|
2020-11-30 09:37:17 +00:00
|
|
|
}
|
2022-07-28 15:32:12 +00:00
|
|
|
|
|
|
|
if nbDeleted == 0 {
|
|
|
|
return fmt.Errorf("machine doesn't exist")
|
|
|
|
}
|
|
|
|
|
2020-11-30 09:37:17 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-07-28 14:23:47 +00:00
|
|
|
func (c *Client) BulkDeleteWatchers(machines []*ent.Machine) (int, error) {
|
|
|
|
ids := make([]int, len(machines))
|
|
|
|
for i, b := range machines {
|
|
|
|
ids[i] = b.ID
|
|
|
|
}
|
|
|
|
nbDeleted, err := c.Ent.Machine.Delete().Where(machine.IDIn(ids...)).Exec(c.CTX)
|
|
|
|
if err != nil {
|
|
|
|
return nbDeleted, err
|
|
|
|
}
|
|
|
|
return nbDeleted, nil
|
|
|
|
}
|
|
|
|
|
2022-01-13 15:46:16 +00:00
|
|
|
func (c *Client) UpdateMachineLastPush(machineID string) error {
|
2022-01-19 13:56:05 +00:00
|
|
|
_, err := c.Ent.Machine.Update().Where(machine.MachineIdEQ(machineID)).SetLastPush(time.Now().UTC()).Save(c.CTX)
|
2022-01-13 15:46:16 +00:00
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(UpdateFail, "updating machine last_push: %s", err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-05-19 13:47:27 +00:00
|
|
|
func (c *Client) UpdateMachineLastHeartBeat(machineID string) error {
|
|
|
|
_, err := c.Ent.Machine.Update().Where(machine.MachineIdEQ(machineID)).SetLastHeartbeat(time.Now().UTC()).Save(c.CTX)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(UpdateFail, "updating machine last_heartbeat: %s", err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-11-30 09:37:17 +00:00
|
|
|
func (c *Client) UpdateMachineScenarios(scenarios string, ID int) error {
|
|
|
|
_, err := c.Ent.Machine.UpdateOneID(ID).
|
2022-01-19 13:56:05 +00:00
|
|
|
SetUpdatedAt(time.Now().UTC()).
|
2020-11-30 09:37:17 +00:00
|
|
|
SetScenarios(scenarios).
|
|
|
|
Save(c.CTX)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("unable to update machine in database: %s", err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) UpdateMachineIP(ipAddr string, ID int) error {
|
|
|
|
_, err := c.Ent.Machine.UpdateOneID(ID).
|
|
|
|
SetIpAddress(ipAddr).
|
|
|
|
Save(c.CTX)
|
|
|
|
if err != nil {
|
2022-07-28 15:32:12 +00:00
|
|
|
return fmt.Errorf("unable to update machine IP in database: %s", err)
|
2020-11-30 09:37:17 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) UpdateMachineVersion(ipAddr string, ID int) error {
|
|
|
|
_, err := c.Ent.Machine.UpdateOneID(ID).
|
|
|
|
SetVersion(ipAddr).
|
|
|
|
Save(c.CTX)
|
|
|
|
if err != nil {
|
2022-07-28 15:32:12 +00:00
|
|
|
return fmt.Errorf("unable to update machine version in database: %s", err)
|
2020-11-30 09:37:17 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) IsMachineRegistered(machineID string) (bool, error) {
|
|
|
|
exist, err := c.Ent.Machine.Query().Where().Select(machine.FieldMachineId).Strings(c.CTX)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
if len(exist) == 1 {
|
|
|
|
return true, nil
|
|
|
|
}
|
|
|
|
if len(exist) > 1 {
|
2023-12-04 22:06:01 +00:00
|
|
|
return false, fmt.Errorf("more than one item with the same machineID in database")
|
2020-11-30 09:37:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return false, nil
|
|
|
|
|
|
|
|
}
|
2023-12-04 22:06:01 +00:00
|
|
|
|
2023-07-28 14:23:47 +00:00
|
|
|
func (c *Client) QueryLastValidatedHeartbeatLT(t time.Time) ([]*ent.Machine, error) {
|
|
|
|
return c.Ent.Machine.Query().Where(machine.LastHeartbeatLT(t), machine.IsValidatedEQ(true)).All(c.CTX)
|
|
|
|
}
|