mirror of
https://github.com/fleetdm/fleet
synced 2026-05-24 09:28:54 +00:00
238 lines
6 KiB
Go
238 lines
6 KiB
Go
package mysql
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
|
|
"github.com/kolide/kolide-ose/server/kolide"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
func (d *Datastore) PackByName(name string) (*kolide.Pack, bool, error) {
|
|
sqlStatement := `
|
|
SELECT *
|
|
FROM packs
|
|
WHERE name = ? AND NOT deleted
|
|
`
|
|
var pack kolide.Pack
|
|
err := d.db.Get(&pack, sqlStatement, name)
|
|
if err != nil {
|
|
if err == sql.ErrNoRows {
|
|
return nil, false, nil
|
|
}
|
|
return nil, false, errors.Wrap(err, "fetching packs by name")
|
|
}
|
|
|
|
return &pack, true, nil
|
|
}
|
|
|
|
// NewPack creates a new Pack
|
|
func (d *Datastore) NewPack(pack *kolide.Pack) (*kolide.Pack, error) {
|
|
|
|
query := `
|
|
INSERT INTO packs ( name, description, platform, created_by, disabled )
|
|
VALUES ( ?, ?, ?, ?, ?)
|
|
`
|
|
|
|
result, err := d.db.Exec(query, pack.Name, pack.Description, pack.Platform, pack.CreatedBy, pack.Disabled)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "creating new pack")
|
|
}
|
|
|
|
id, _ := result.LastInsertId()
|
|
pack.ID = uint(id)
|
|
return pack, nil
|
|
}
|
|
|
|
// SavePack stores changes to pack
|
|
func (d *Datastore) SavePack(pack *kolide.Pack) error {
|
|
query := `
|
|
UPDATE packs
|
|
SET name = ?, platform = ?, disabled = ?, description = ?
|
|
WHERE id = ? AND NOT deleted
|
|
`
|
|
|
|
_, err := d.db.Exec(query, pack.Name, pack.Platform, pack.Disabled, pack.Description, pack.ID)
|
|
if err == sql.ErrNoRows {
|
|
return notFound("Pack").WithID(pack.ID)
|
|
} else if err != nil {
|
|
return errors.Wrap(err, "update pack")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// DeletePack soft deletes a kolide.Pack so that it won't show up in results
|
|
func (d *Datastore) DeletePack(pid uint) error {
|
|
err := d.deleteEntity("packs", pid)
|
|
if err == sql.ErrNoRows {
|
|
return notFound("Pack").WithID(pid)
|
|
} else if err != nil {
|
|
return errors.Wrap(err, "delete pack")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Pack fetch kolide.Pack with matching ID
|
|
func (d *Datastore) Pack(pid uint) (*kolide.Pack, error) {
|
|
query := `SELECT * FROM packs WHERE id = ? AND NOT deleted`
|
|
pack := &kolide.Pack{}
|
|
err := d.db.Get(pack, query, pid)
|
|
if err == sql.ErrNoRows {
|
|
return nil, notFound("Pack").WithID(pid)
|
|
} else if err != nil {
|
|
return nil, errors.Wrap(err, "getting pack")
|
|
}
|
|
|
|
return pack, nil
|
|
}
|
|
|
|
// ListPacks returns all kolide.Pack records limited and sorted by kolide.ListOptions
|
|
func (d *Datastore) ListPacks(opt kolide.ListOptions) ([]*kolide.Pack, error) {
|
|
query := `SELECT * FROM packs WHERE NOT deleted`
|
|
packs := []*kolide.Pack{}
|
|
err := d.db.Select(&packs, appendListOptionsToSQL(query, opt))
|
|
if err != nil && err != sql.ErrNoRows {
|
|
return nil, errors.Wrap(err, "listing packs")
|
|
}
|
|
return packs, nil
|
|
}
|
|
|
|
// AddLabelToPack associates a kolide.Label with a kolide.Pack
|
|
func (d *Datastore) AddLabelToPack(lid uint, pid uint) error {
|
|
query := `
|
|
INSERT INTO pack_targets ( pack_id, type, target_id )
|
|
VALUES ( ?, ?, ? )
|
|
ON DUPLICATE KEY UPDATE id=id
|
|
`
|
|
_, err := d.db.Exec(query, pid, kolide.TargetLabel, lid)
|
|
if err != nil {
|
|
return errors.Wrap(err, "adding label to pack")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// AddHostToPack associates a kolide.Host with a kolide.Pack
|
|
func (d *Datastore) AddHostToPack(hid, pid uint) error {
|
|
query := `
|
|
INSERT INTO pack_targets ( pack_id, type, target_id )
|
|
VALUES ( ?, ?, ? )
|
|
ON DUPLICATE KEY UPDATE id=id
|
|
`
|
|
_, err := d.db.Exec(query, pid, kolide.TargetHost, hid)
|
|
if err != nil {
|
|
return errors.Wrap(err, "adding host to pack")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ListLabelsForPack will return a list of kolide.Label records associated with kolide.Pack
|
|
func (d *Datastore) ListLabelsForPack(pid uint) ([]*kolide.Label, error) {
|
|
query := `
|
|
SELECT
|
|
l.id,
|
|
l.created_at,
|
|
l.updated_at,
|
|
l.name
|
|
FROM
|
|
labels l
|
|
JOIN
|
|
pack_targets pt
|
|
ON
|
|
pt.target_id = l.id
|
|
WHERE
|
|
pt.type = ?
|
|
AND
|
|
pt.pack_id = ?
|
|
AND NOT l.deleted
|
|
`
|
|
|
|
labels := []*kolide.Label{}
|
|
|
|
if err := d.db.Select(&labels, query, kolide.TargetLabel, pid); err != nil && err != sql.ErrNoRows {
|
|
return nil, errors.Wrap(err, "listing labels for pack")
|
|
}
|
|
|
|
return labels, nil
|
|
}
|
|
|
|
// RemoreLabelFromPack will remove the association between a kolide.Label and
|
|
// a kolide.Pack
|
|
func (d *Datastore) RemoveLabelFromPack(lid, pid uint) error {
|
|
query := `
|
|
DELETE FROM pack_targets
|
|
WHERE target_id = ? AND pack_id = ? AND type = ?
|
|
`
|
|
_, err := d.db.Exec(query, lid, pid, kolide.TargetLabel)
|
|
if err == sql.ErrNoRows {
|
|
return notFound("PackTarget").WithMessage(fmt.Sprintf("label ID: %d, pack ID: %d", lid, pid))
|
|
} else if err != nil {
|
|
return errors.Wrap(err, "removing label from pack")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// RemoveHostFromPack will remove the association between a kolide.Host and a
|
|
// kolide.Pack
|
|
func (d *Datastore) RemoveHostFromPack(hid, pid uint) error {
|
|
query := `
|
|
DELETE FROM pack_targets
|
|
WHERE target_id = ? AND pack_id = ? AND type = ?
|
|
`
|
|
_, err := d.db.Exec(query, hid, pid, kolide.TargetHost)
|
|
if err == sql.ErrNoRows {
|
|
return notFound("PackTarget").WithMessage(fmt.Sprintf("host ID: %d, pack ID: %d", hid, pid))
|
|
} else if err != nil {
|
|
return errors.Wrap(err, "removing host from pack")
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
func (d *Datastore) ListHostsInPack(pid uint, opt kolide.ListOptions) ([]*kolide.Host, error) {
|
|
query := `
|
|
SELECT DISTINCT h.*
|
|
FROM hosts h
|
|
JOIN pack_targets pt
|
|
JOIN label_query_executions lqe
|
|
ON (
|
|
pt.target_id = lqe.label_id
|
|
AND lqe.host_id = h.id
|
|
AND lqe.matches
|
|
AND pt.type = ?
|
|
) OR (
|
|
pt.target_id = h.id
|
|
AND pt.type = ?
|
|
)
|
|
WHERE pt.pack_id = ?
|
|
`
|
|
|
|
hosts := []*kolide.Host{}
|
|
if err := d.db.Select(&hosts, appendListOptionsToSQL(query, opt), kolide.TargetLabel, kolide.TargetHost, pid); err != nil && err != sql.ErrNoRows {
|
|
return nil, errors.Wrap(err, "listing hosts in pack")
|
|
}
|
|
return hosts, nil
|
|
}
|
|
|
|
func (d *Datastore) ListExplicitHostsInPack(pid uint, opt kolide.ListOptions) ([]*kolide.Host, error) {
|
|
query := `
|
|
SELECT DISTINCT h.*
|
|
FROM hosts h
|
|
JOIN pack_targets pt
|
|
ON (
|
|
pt.target_id = h.id
|
|
AND pt.type = ?
|
|
)
|
|
WHERE pt.pack_id = ?
|
|
`
|
|
hosts := []*kolide.Host{}
|
|
if err := d.db.Select(&hosts, appendListOptionsToSQL(query, opt), kolide.TargetHost, pid); err != nil && err != sql.ErrNoRows {
|
|
return nil, errors.Wrap(err, "listing explicit hosts in pack")
|
|
}
|
|
return hosts, nil
|
|
|
|
}
|