2016-11-16 13:47:49 +00:00
|
|
|
package mysql
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
2018-01-10 19:38:20 +00:00
|
|
|
"fmt"
|
2016-11-16 13:47:49 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/jmoiron/sqlx"
|
2017-06-22 19:50:45 +00:00
|
|
|
"github.com/kolide/fleet/server/kolide"
|
2017-01-13 18:35:25 +00:00
|
|
|
"github.com/pkg/errors"
|
2016-11-16 13:47:49 +00:00
|
|
|
)
|
|
|
|
|
2018-01-10 19:38:20 +00:00
|
|
|
func (d *Datastore) ApplyLabelSpecs(specs []*kolide.LabelSpec) (err error) {
|
|
|
|
tx, err := d.db.Beginx()
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "begin ApplyLabelSpecs transaction")
|
|
|
|
}
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
if err != nil {
|
|
|
|
rbErr := tx.Rollback()
|
|
|
|
// It seems possible that there might be a case in
|
|
|
|
// which the error we are dealing with here was thrown
|
|
|
|
// by the call to tx.Commit(), and the docs suggest
|
|
|
|
// this call would then result in sql.ErrTxDone.
|
|
|
|
if rbErr != nil && rbErr != sql.ErrTxDone {
|
|
|
|
panic(fmt.Sprintf("got err '%s' rolling back after err '%s'", rbErr, err))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
sql := `
|
2016-11-16 13:47:49 +00:00
|
|
|
INSERT INTO labels (
|
|
|
|
name,
|
|
|
|
description,
|
|
|
|
query,
|
2016-11-25 18:08:22 +00:00
|
|
|
platform,
|
|
|
|
label_type
|
2018-01-10 19:38:20 +00:00
|
|
|
) VALUES ( ?, ?, ?, ?, ? )
|
|
|
|
ON DUPLICATE KEY UPDATE
|
|
|
|
name = VALUES(name),
|
|
|
|
description = VALUES(description),
|
|
|
|
query = VALUES(query),
|
|
|
|
platform = VALUES(platform),
|
|
|
|
label_type = VALUES(label_type),
|
|
|
|
deleted = false
|
2016-11-16 13:47:49 +00:00
|
|
|
`
|
2018-01-10 19:38:20 +00:00
|
|
|
stmt, err := tx.Prepare(sql)
|
2016-11-16 13:47:49 +00:00
|
|
|
if err != nil {
|
2018-01-10 19:38:20 +00:00
|
|
|
return errors.Wrap(err, "prepare ApplyLabelSpecs insert")
|
2016-11-16 13:47:49 +00:00
|
|
|
}
|
|
|
|
|
2018-01-10 19:38:20 +00:00
|
|
|
for _, s := range specs {
|
2018-05-14 18:23:38 +00:00
|
|
|
if s.Name == "" {
|
|
|
|
return errors.New("label name must not be empty")
|
|
|
|
}
|
2018-01-10 19:38:20 +00:00
|
|
|
_, err := stmt.Exec(s.Name, s.Description, s.Query, s.Platform, s.LabelType)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "exec ApplyLabelSpecs insert")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
err = tx.Commit()
|
|
|
|
return errors.Wrap(err, "commit ApplyLabelSpecs transaction")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *Datastore) GetLabelSpecs() ([]*kolide.LabelSpec, error) {
|
|
|
|
var specs []*kolide.LabelSpec
|
|
|
|
// Get basic specs
|
|
|
|
query := "SELECT name, description, query, platform, label_type FROM labels"
|
|
|
|
if err := d.db.Select(&specs, query); err != nil {
|
|
|
|
return nil, errors.Wrap(err, "get labels")
|
|
|
|
}
|
2016-11-16 13:47:49 +00:00
|
|
|
|
2018-01-10 19:38:20 +00:00
|
|
|
return specs, nil
|
2016-11-16 13:47:49 +00:00
|
|
|
}
|
|
|
|
|
2018-05-08 01:54:29 +00:00
|
|
|
func (d *Datastore) GetLabelSpec(name string) (*kolide.LabelSpec, error) {
|
|
|
|
var specs []*kolide.LabelSpec
|
|
|
|
query := `
|
|
|
|
SELECT name, description, query, platform, label_type
|
|
|
|
FROM labels
|
|
|
|
WHERE name = ?
|
|
|
|
`
|
|
|
|
if err := d.db.Select(&specs, query, name); err != nil {
|
|
|
|
return nil, errors.Wrap(err, "get label")
|
|
|
|
}
|
2018-05-09 23:54:42 +00:00
|
|
|
if len(specs) == 0 {
|
|
|
|
return nil, notFound("Label").WithName(name)
|
|
|
|
}
|
|
|
|
if len(specs) > 1 {
|
2018-05-08 01:54:29 +00:00
|
|
|
return nil, errors.Errorf("expected 1 label row, got %d", len(specs))
|
|
|
|
}
|
|
|
|
|
|
|
|
return specs[0], nil
|
|
|
|
}
|
|
|
|
|
2018-06-18 17:09:08 +00:00
|
|
|
// NewLabel creates a new kolide.Label
|
|
|
|
func (d *Datastore) NewLabel(label *kolide.Label, opts ...kolide.OptionalArg) (*kolide.Label, error) {
|
|
|
|
db := d.getTransaction(opts)
|
|
|
|
var (
|
|
|
|
deletedLabel kolide.Label
|
|
|
|
query string
|
|
|
|
)
|
|
|
|
err := db.Get(&deletedLabel,
|
|
|
|
"SELECT * FROM labels WHERE name = ? AND deleted", label.Name)
|
|
|
|
switch err {
|
|
|
|
case nil:
|
|
|
|
query = `
|
|
|
|
REPLACE INTO labels (
|
|
|
|
name,
|
|
|
|
description,
|
|
|
|
query,
|
|
|
|
platform,
|
|
|
|
label_type
|
|
|
|
) VALUES ( ?, ?, ?, ?, ?)
|
|
|
|
`
|
|
|
|
case sql.ErrNoRows:
|
|
|
|
query = `
|
|
|
|
INSERT INTO labels (
|
|
|
|
name,
|
|
|
|
description,
|
|
|
|
query,
|
|
|
|
platform,
|
|
|
|
label_type
|
|
|
|
) VALUES ( ?, ?, ?, ?, ?)
|
|
|
|
`
|
|
|
|
default:
|
|
|
|
return nil, errors.Wrap(err, "check for existing label")
|
|
|
|
}
|
|
|
|
result, err := db.Exec(query, label.Name, label.Description, label.Query, label.Platform, label.LabelType)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "inserting label")
|
|
|
|
}
|
|
|
|
|
|
|
|
id, _ := result.LastInsertId()
|
|
|
|
label.ID = uint(id)
|
|
|
|
return label, nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *Datastore) SaveLabel(label *kolide.Label) (*kolide.Label, error) {
|
|
|
|
query := `
|
|
|
|
UPDATE labels SET
|
|
|
|
name = ?,
|
|
|
|
description = ?
|
|
|
|
WHERE id = ?
|
|
|
|
`
|
|
|
|
_, err := d.db.Exec(query, label.Name, label.Description, label.ID)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "saving label")
|
|
|
|
}
|
|
|
|
return label, nil
|
|
|
|
}
|
|
|
|
|
2018-05-04 18:05:55 +00:00
|
|
|
// DeleteLabel deletes a kolide.Label
|
|
|
|
func (d *Datastore) DeleteLabel(name string) error {
|
|
|
|
return d.deleteEntityByName("labels", name)
|
2016-11-16 13:47:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Label returns a kolide.Label identified by lid if one exists
|
|
|
|
func (d *Datastore) Label(lid uint) (*kolide.Label, error) {
|
|
|
|
sql := `
|
|
|
|
SELECT * FROM labels
|
|
|
|
WHERE id = ? AND NOT deleted
|
|
|
|
`
|
|
|
|
label := &kolide.Label{}
|
|
|
|
|
|
|
|
if err := d.db.Get(label, sql, lid); err != nil {
|
2017-01-13 18:35:25 +00:00
|
|
|
return nil, errors.Wrap(err, "selecting label")
|
2016-11-16 13:47:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return label, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ListLabels returns all labels limited or sorted by kolide.ListOptions
|
|
|
|
func (d *Datastore) ListLabels(opt kolide.ListOptions) ([]*kolide.Label, error) {
|
2017-01-16 22:57:05 +00:00
|
|
|
query := `
|
2016-11-16 13:47:49 +00:00
|
|
|
SELECT * FROM labels WHERE NOT deleted
|
|
|
|
`
|
2017-01-16 22:57:05 +00:00
|
|
|
query = appendListOptionsToSQL(query, opt)
|
2016-11-16 13:47:49 +00:00
|
|
|
labels := []*kolide.Label{}
|
|
|
|
|
2017-01-16 22:57:05 +00:00
|
|
|
if err := d.db.Select(&labels, query); err != nil {
|
|
|
|
// it's ok if no labels exist
|
|
|
|
if err == sql.ErrNoRows {
|
|
|
|
return labels, nil
|
|
|
|
}
|
2017-01-13 18:35:25 +00:00
|
|
|
return nil, errors.Wrap(err, "selecting labels")
|
2016-11-16 13:47:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return labels, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *Datastore) LabelQueriesForHost(host *kolide.Host, cutoff time.Time) (map[string]string, error) {
|
|
|
|
sqlStatment := `
|
|
|
|
SELECT l.id, l.query
|
|
|
|
FROM labels l
|
2016-12-29 20:11:26 +00:00
|
|
|
WHERE (l.platform = ? OR l.platform = '')
|
2016-11-16 13:47:49 +00:00
|
|
|
AND NOT l.deleted
|
|
|
|
AND l.id NOT IN /* subtract the set of executions that are recent enough */
|
|
|
|
(
|
|
|
|
SELECT l.id
|
|
|
|
FROM labels l
|
|
|
|
JOIN label_query_executions lqe
|
|
|
|
ON lqe.label_id = l.id
|
|
|
|
WHERE lqe.host_id = ? AND lqe.updated_at > ?
|
|
|
|
)
|
|
|
|
`
|
|
|
|
rows, err := d.db.Query(sqlStatment, host.Platform, host.ID, cutoff)
|
|
|
|
if err != nil && err != sql.ErrNoRows {
|
2017-01-13 18:35:25 +00:00
|
|
|
return nil, errors.Wrap(err, "selecting label queries for host")
|
2016-11-16 13:47:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
defer rows.Close()
|
|
|
|
results := map[string]string{}
|
|
|
|
|
|
|
|
for rows.Next() {
|
|
|
|
var id, query string
|
|
|
|
|
|
|
|
if err = rows.Scan(&id, &query); err != nil {
|
2017-01-13 18:35:25 +00:00
|
|
|
return nil, errors.Wrap(err, "scanning label queries for host")
|
2016-11-16 13:47:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
results[id] = query
|
|
|
|
}
|
|
|
|
|
|
|
|
return results, nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-01-17 06:03:51 +00:00
|
|
|
func (d *Datastore) RecordLabelQueryExecutions(host *kolide.Host, results map[uint]bool, updated time.Time) error {
|
2016-11-16 13:47:49 +00:00
|
|
|
sqlStatement := `
|
|
|
|
INSERT INTO label_query_executions (updated_at, matches, label_id, host_id) VALUES
|
|
|
|
|
|
|
|
`
|
|
|
|
vals := []interface{}{}
|
|
|
|
bindvars := ""
|
|
|
|
|
|
|
|
for labelID, result := range results {
|
|
|
|
if bindvars != "" {
|
|
|
|
bindvars += ","
|
|
|
|
}
|
|
|
|
bindvars += "(?,?,?,?)"
|
|
|
|
vals = append(vals, updated, result, labelID, host.ID)
|
|
|
|
}
|
|
|
|
|
|
|
|
sqlStatement += bindvars
|
|
|
|
sqlStatement += `
|
|
|
|
ON DUPLICATE KEY UPDATE
|
|
|
|
updated_at = VALUES(updated_at),
|
|
|
|
matches = VALUES(matches)
|
|
|
|
`
|
|
|
|
|
|
|
|
_, err := d.db.Exec(sqlStatement, vals...)
|
|
|
|
if err != nil {
|
2017-01-13 18:35:25 +00:00
|
|
|
return errors.Wrap(err, "inserting label query execution")
|
2016-11-16 13:47:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ListLabelsForHost returns a list of kolide.Label for a given host id.
|
|
|
|
func (d *Datastore) ListLabelsForHost(hid uint) ([]kolide.Label, error) {
|
|
|
|
sqlStatement := `
|
|
|
|
SELECT labels.* from labels, label_query_executions lqe
|
|
|
|
WHERE lqe.host_id = ?
|
|
|
|
AND lqe.label_id = labels.id
|
|
|
|
AND lqe.matches
|
|
|
|
AND NOT labels.deleted
|
|
|
|
`
|
|
|
|
|
|
|
|
labels := []kolide.Label{}
|
|
|
|
err := d.db.Select(&labels, sqlStatement, hid)
|
|
|
|
if err != nil {
|
2017-01-13 18:35:25 +00:00
|
|
|
return nil, errors.Wrap(err, "selecting host labels")
|
2016-11-16 13:47:49 +00:00
|
|
|
}
|
2017-01-16 22:57:05 +00:00
|
|
|
|
2016-11-16 13:47:49 +00:00
|
|
|
return labels, nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// ListHostsInLabel returns a list of kolide.Host that are associated
|
|
|
|
// with kolide.Label referened by Label ID
|
|
|
|
func (d *Datastore) ListHostsInLabel(lid uint) ([]kolide.Host, error) {
|
|
|
|
sqlStatement := `
|
|
|
|
SELECT h.*
|
|
|
|
FROM label_query_executions lqe
|
|
|
|
JOIN hosts h
|
|
|
|
ON lqe.host_id = h.id
|
|
|
|
WHERE lqe.label_id = ?
|
|
|
|
AND lqe.matches = 1
|
|
|
|
AND NOT h.deleted
|
|
|
|
`
|
|
|
|
hosts := []kolide.Host{}
|
|
|
|
err := d.db.Select(&hosts, sqlStatement, lid)
|
|
|
|
if err != nil {
|
2017-01-13 18:35:25 +00:00
|
|
|
return nil, errors.Wrap(err, "selecting label query executions")
|
2016-11-16 13:47:49 +00:00
|
|
|
}
|
|
|
|
return hosts, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *Datastore) ListUniqueHostsInLabels(labels []uint) ([]kolide.Host, error) {
|
2016-11-16 23:12:59 +00:00
|
|
|
if len(labels) == 0 {
|
|
|
|
return []kolide.Host{}, nil
|
|
|
|
}
|
|
|
|
|
2016-11-16 13:47:49 +00:00
|
|
|
sqlStatement := `
|
2017-02-17 19:19:27 +00:00
|
|
|
SELECT DISTINCT h.*
|
2016-11-16 13:47:49 +00:00
|
|
|
FROM label_query_executions lqe
|
|
|
|
JOIN hosts h
|
|
|
|
ON lqe.host_id = h.id
|
|
|
|
WHERE lqe.label_id IN (?)
|
|
|
|
AND lqe.matches = 1
|
|
|
|
AND NOT h.deleted
|
|
|
|
`
|
|
|
|
query, args, err := sqlx.In(sqlStatement, labels)
|
|
|
|
if err != nil {
|
2017-01-13 18:35:25 +00:00
|
|
|
return nil, errors.Wrap(err, "building query listing unique hosts in labels")
|
2016-11-16 13:47:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
query = d.db.Rebind(query)
|
|
|
|
hosts := []kolide.Host{}
|
|
|
|
err = d.db.Select(&hosts, query, args...)
|
|
|
|
if err != nil {
|
2017-01-13 18:35:25 +00:00
|
|
|
return nil, errors.Wrap(err, "listing unique hosts in labels")
|
2016-11-16 13:47:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return hosts, nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *Datastore) searchLabelsWithOmits(query string, omit ...uint) ([]kolide.Label, error) {
|
2019-07-03 17:47:43 +00:00
|
|
|
transformedQuery := transformQuery(query)
|
|
|
|
|
2016-11-16 13:47:49 +00:00
|
|
|
sqlStatement := `
|
|
|
|
SELECT *
|
|
|
|
FROM labels
|
2016-12-15 02:27:22 +00:00
|
|
|
WHERE (
|
2017-02-24 00:41:12 +00:00
|
|
|
MATCH(name) AGAINST(? IN BOOLEAN MODE)
|
|
|
|
AND NOT deleted
|
2016-12-15 02:27:22 +00:00
|
|
|
)
|
2016-11-16 13:47:49 +00:00
|
|
|
AND id NOT IN (?)
|
2017-03-02 23:40:50 +00:00
|
|
|
ORDER BY label_type DESC, id ASC
|
2016-11-16 13:47:49 +00:00
|
|
|
LIMIT 10
|
|
|
|
`
|
2016-12-15 02:27:22 +00:00
|
|
|
|
2019-07-03 17:47:43 +00:00
|
|
|
sql, args, err := sqlx.In(sqlStatement, transformedQuery, omit)
|
2016-11-16 13:47:49 +00:00
|
|
|
if err != nil {
|
2017-01-13 18:35:25 +00:00
|
|
|
return nil, errors.Wrap(err, "building query for labels with omits")
|
2016-11-16 13:47:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sql = d.db.Rebind(sql)
|
|
|
|
|
|
|
|
matches := []kolide.Label{}
|
|
|
|
err = d.db.Select(&matches, sql, args...)
|
|
|
|
if err != nil {
|
2017-01-13 18:35:25 +00:00
|
|
|
return nil, errors.Wrap(err, "selecting labels with omits")
|
2016-11-16 13:47:49 +00:00
|
|
|
}
|
|
|
|
|
2017-02-24 00:41:12 +00:00
|
|
|
matches, err = d.addAllHostsLabelToList(matches, omit...)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "adding all hosts label to matches")
|
|
|
|
}
|
|
|
|
|
2016-11-16 13:47:49 +00:00
|
|
|
return matches, nil
|
|
|
|
}
|
|
|
|
|
2017-02-24 00:41:12 +00:00
|
|
|
// When we search labels, we always want to make sure that the All Hosts label
|
|
|
|
// is included in the results set. Sometimes it already is and we don't need to
|
|
|
|
// add it, sometimes it's not so we explicitly add it.
|
|
|
|
func (d *Datastore) addAllHostsLabelToList(labels []kolide.Label, omit ...uint) ([]kolide.Label, error) {
|
|
|
|
sqlStatement := `
|
|
|
|
SELECT *
|
|
|
|
FROM labels
|
|
|
|
WHERE
|
|
|
|
label_type=?
|
|
|
|
AND name = 'All Hosts'
|
|
|
|
LIMIT 1
|
|
|
|
`
|
|
|
|
|
|
|
|
var allHosts kolide.Label
|
|
|
|
err := d.db.Get(&allHosts, sqlStatement, kolide.LabelTypeBuiltIn)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "getting all hosts label")
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, omission := range omit {
|
|
|
|
if omission == allHosts.ID {
|
|
|
|
return labels, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, label := range labels {
|
|
|
|
if label.ID == allHosts.ID {
|
|
|
|
return labels, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return append(labels, allHosts), nil
|
|
|
|
}
|
|
|
|
|
2017-01-17 14:51:04 +00:00
|
|
|
func (d *Datastore) searchLabelsDefault(omit ...uint) ([]kolide.Label, error) {
|
|
|
|
sqlStatement := `
|
|
|
|
SELECT *
|
|
|
|
FROM labels
|
|
|
|
WHERE NOT deleted
|
|
|
|
AND id NOT IN (?)
|
2017-03-02 23:40:50 +00:00
|
|
|
ORDER BY label_type DESC, id ASC
|
2017-01-17 14:51:04 +00:00
|
|
|
LIMIT 5
|
|
|
|
`
|
|
|
|
|
|
|
|
var in interface{}
|
|
|
|
{
|
|
|
|
// use -1 if there are no values to omit.
|
|
|
|
//Avoids empty args error for `sqlx.In`
|
|
|
|
in = omit
|
|
|
|
if len(omit) == 0 {
|
|
|
|
in = -1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var labels []kolide.Label
|
|
|
|
sql, args, err := sqlx.In(sqlStatement, in)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "searching default labels")
|
|
|
|
}
|
|
|
|
sql = d.db.Rebind(sql)
|
|
|
|
err = d.db.Select(&labels, sql, args...)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "searching default labels rebound")
|
|
|
|
}
|
2017-02-24 00:41:12 +00:00
|
|
|
|
|
|
|
labels, err = d.addAllHostsLabelToList(labels, omit...)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "getting all host label")
|
|
|
|
}
|
|
|
|
|
2017-01-17 14:51:04 +00:00
|
|
|
return labels, nil
|
|
|
|
}
|
|
|
|
|
2016-11-16 13:47:49 +00:00
|
|
|
// SearchLabels performs wildcard searches on kolide.Label name
|
|
|
|
func (d *Datastore) SearchLabels(query string, omit ...uint) ([]kolide.Label, error) {
|
2019-07-03 17:47:43 +00:00
|
|
|
transformedQuery := transformQuery(query)
|
|
|
|
if !queryMinLength(transformedQuery) {
|
2017-01-17 14:51:04 +00:00
|
|
|
return d.searchLabelsDefault(omit...)
|
|
|
|
}
|
2016-11-16 13:47:49 +00:00
|
|
|
if len(omit) > 0 {
|
|
|
|
return d.searchLabelsWithOmits(query, omit...)
|
|
|
|
}
|
|
|
|
|
2017-03-02 23:40:50 +00:00
|
|
|
// Ordering first by label_type ensures that built-in labels come
|
|
|
|
// first. We will probably need to make a custom ordering function here
|
|
|
|
// if additional label types are added. Ordering next by ID ensures
|
|
|
|
// that the order is always consistent.
|
2016-11-16 13:47:49 +00:00
|
|
|
sqlStatement := `
|
|
|
|
SELECT *
|
|
|
|
FROM labels
|
2016-12-15 02:27:22 +00:00
|
|
|
WHERE (
|
2017-02-24 00:41:12 +00:00
|
|
|
MATCH(name) AGAINST(? IN BOOLEAN MODE)
|
|
|
|
AND NOT deleted
|
2016-12-15 02:27:22 +00:00
|
|
|
)
|
2017-03-02 23:40:50 +00:00
|
|
|
ORDER BY label_type DESC, id ASC
|
2016-11-16 13:47:49 +00:00
|
|
|
LIMIT 10
|
|
|
|
`
|
|
|
|
matches := []kolide.Label{}
|
2019-07-03 17:47:43 +00:00
|
|
|
err := d.db.Select(&matches, sqlStatement, transformedQuery)
|
2016-11-16 13:47:49 +00:00
|
|
|
if err != nil {
|
2017-01-13 18:35:25 +00:00
|
|
|
return nil, errors.Wrap(err, "selecting labels for search")
|
2016-11-16 13:47:49 +00:00
|
|
|
}
|
2017-02-24 00:41:12 +00:00
|
|
|
|
|
|
|
matches, err = d.addAllHostsLabelToList(matches, omit...)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "adding all hosts label to matches")
|
|
|
|
}
|
|
|
|
|
2016-11-16 13:47:49 +00:00
|
|
|
return matches, nil
|
|
|
|
}
|
2018-05-17 22:54:34 +00:00
|
|
|
|
|
|
|
func (d *Datastore) LabelIDsByName(labels []string) ([]uint, error) {
|
|
|
|
sqlStatement := `
|
|
|
|
SELECT id FROM labels
|
|
|
|
WHERE name IN (?)
|
|
|
|
`
|
|
|
|
|
|
|
|
sql, args, err := sqlx.In(sqlStatement, labels)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "building query to get host IDs")
|
|
|
|
}
|
|
|
|
|
|
|
|
var hostIDs []uint
|
|
|
|
if err := d.db.Select(&hostIDs, sql, args...); err != nil {
|
|
|
|
return nil, errors.Wrap(err, "get host IDs")
|
|
|
|
}
|
|
|
|
|
|
|
|
return hostIDs, nil
|
|
|
|
|
|
|
|
}
|