2016-11-16 13:47:49 +00:00
package mysql
import (
"database/sql"
2016-12-01 17:00:00 +00:00
"fmt"
2016-11-16 13:47:49 +00:00
"time"
"github.com/jmoiron/sqlx"
2020-11-11 17:59:12 +00:00
"github.com/fleetdm/fleet/server/kolide"
2017-01-04 21:16:17 +00:00
"github.com/pkg/errors"
2016-11-16 13:47:49 +00:00
)
func ( d * Datastore ) NewHost ( host * kolide . Host ) ( * kolide . Host , error ) {
sqlStatement := `
INSERT INTO hosts (
2016-12-06 19:51:11 +00:00
osquery_host_id ,
2016-11-16 13:47:49 +00:00
detail_update_time ,
2020-04-07 01:10:20 +00:00
label_update_time ,
2016-11-16 13:47:49 +00:00
node_key ,
host_name ,
uuid ,
platform ,
osquery_version ,
os_version ,
uptime ,
2017-01-04 21:16:17 +00:00
physical_memory ,
seen_time
2016-11-16 13:47:49 +00:00
)
2020-04-07 01:10:20 +00:00
VALUES ( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? )
2016-11-16 13:47:49 +00:00
`
2020-04-07 01:10:20 +00:00
result , err := d . db . Exec (
sqlStatement ,
host . OsqueryHostID ,
host . DetailUpdateTime ,
host . LabelUpdateTime ,
host . NodeKey ,
host . HostName ,
host . UUID ,
host . Platform ,
host . OsqueryVersion ,
host . OSVersion ,
host . Uptime ,
host . PhysicalMemory ,
host . SeenTime ,
)
2016-11-16 13:47:49 +00:00
if err != nil {
2017-01-04 21:16:17 +00:00
return nil , errors . Wrap ( err , "new host" )
2016-11-16 13:47:49 +00:00
}
id , _ := result . LastInsertId ( )
host . ID = uint ( id )
return host , nil
}
// TODO needs test
func ( d * Datastore ) SaveHost ( host * kolide . Host ) error {
sqlStatement := `
UPDATE hosts SET
detail_update_time = ? ,
2020-04-07 01:10:20 +00:00
label_update_time = ? ,
2016-11-16 13:47:49 +00:00
node_key = ? ,
host_name = ? ,
uuid = ? ,
platform = ? ,
osquery_version = ? ,
os_version = ? ,
uptime = ? ,
physical_memory = ? ,
2016-12-01 17:00:00 +00:00
cpu_type = ? ,
cpu_subtype = ? ,
cpu_brand = ? ,
cpu_physical_cores = ? ,
hardware_vendor = ? ,
hardware_model = ? ,
hardware_version = ? ,
hardware_serial = ? ,
computer_name = ? ,
build = ? ,
platform_like = ? ,
code_name = ? ,
2017-01-04 21:16:17 +00:00
cpu_logical_cores = ? ,
2017-04-06 18:55:24 +00:00
seen_time = ? ,
distributed_interval = ? ,
config_tls_refresh = ? ,
2020-05-21 15:36:00 +00:00
logger_tls_period = ? ,
2020-05-29 16:12:39 +00:00
additional = COALESCE ( ? , additional ) ,
2020-03-11 20:38:44 +00:00
enroll_secret_name = ? ,
primary_ip = ? ,
primary_mac = ?
2016-11-16 13:47:49 +00:00
WHERE id = ?
`
2020-03-11 20:38:44 +00:00
_ , err := d . db . Exec ( sqlStatement ,
host . DetailUpdateTime ,
2020-04-07 01:10:20 +00:00
host . LabelUpdateTime ,
2020-03-11 20:38:44 +00:00
host . NodeKey ,
host . HostName ,
host . UUID ,
host . Platform ,
host . OsqueryVersion ,
host . OSVersion ,
host . Uptime ,
host . PhysicalMemory ,
host . CPUType ,
host . CPUSubtype ,
host . CPUBrand ,
host . CPUPhysicalCores ,
host . HardwareVendor ,
host . HardwareModel ,
host . HardwareVersion ,
host . HardwareSerial ,
host . ComputerName ,
host . Build ,
host . PlatformLike ,
host . CodeName ,
host . CPULogicalCores ,
host . SeenTime ,
host . DistributedInterval ,
host . ConfigTLSRefresh ,
host . LoggerTLSPeriod ,
host . Additional ,
host . EnrollSecretName ,
host . PrimaryIP ,
host . PrimaryMac ,
host . ID ,
)
if err != nil {
return errors . Wrapf ( err , "save host with id %d" , host . ID )
}
2020-03-11 01:14:02 +00:00
2020-03-11 20:38:44 +00:00
return nil
2016-11-16 13:47:49 +00:00
}
2017-01-04 18:18:21 +00:00
func ( d * Datastore ) DeleteHost ( hid uint ) error {
2020-10-22 17:51:26 +00:00
err := d . deleteEntity ( "hosts" , hid )
2017-01-20 17:22:33 +00:00
if err != nil {
return errors . Wrapf ( err , "deleting host with id %d" , hid )
}
return nil
2016-11-16 13:47:49 +00:00
}
func ( d * Datastore ) Host ( id uint ) ( * kolide . Host , error ) {
sqlStatement := `
SELECT * FROM hosts
2020-10-22 17:51:26 +00:00
WHERE id = ? LIMIT 1
2016-11-16 13:47:49 +00:00
`
host := & kolide . Host { }
err := d . db . Get ( host , sqlStatement , id )
if err != nil {
2017-01-04 21:16:17 +00:00
return nil , errors . Wrap ( err , "getting host by id" )
2016-11-16 13:47:49 +00:00
}
return host , nil
}
2020-03-30 02:19:54 +00:00
func ( d * Datastore ) ListHosts ( opt kolide . HostListOptions ) ( [ ] * kolide . Host , error ) {
Add host additional info filters (#28)
This change adds the ability to filter additional host info via the list hosts endpoint; a continuation from [here](https://github.com/kolide/fleet/pull/2330), but now filtering is accomplished via SQL.
Additional object without filter:
```
curl 'https://localhost:8080/api/v1/kolide/hosts'
...
"additional": {
"macs": [
{
"mac": "00:00:00:00:00:00"
},
{
"mac": "02:42:c0:a8:10:05"
}
],
"time": [
{
"day": "13",
"hour": "3",
"year": "2020",
"month": "10",
"minutes": "43",
"seconds": "11",
"weekday": "Tuesday",
"datetime": "2020-10-13T03:43:11Z",
"iso_8601": "2020-10-13T03:43:11Z",
"timezone": "GMT",
"timestamp": "Tue Oct 13 03:43:11 2020 UTC",
"unix_time": "1602560591",
"local_time": "1602560591",
"local_timezone": "UTC"
}
},
...
```
Additional object with filter:
```
curl 'https://localhost:8080/api/v1/kolide/hosts?additional_info_filters=macs,notreal'
...
"additional": {
"macs": [
{
"mac": "00:00:00:00:00:00"
},
{
"mac": "02:42:c0:a8:10:05"
}
],
"notreal": null
},
...
```
2020-11-14 00:33:25 +00:00
sql := ` SELECT id ,
osquery_host_id ,
created_at ,
updated_at ,
detail_update_time ,
node_key ,
host_name ,
uuid ,
platform ,
osquery_version ,
os_version ,
build ,
platform_like ,
code_name ,
uptime ,
physical_memory ,
cpu_type ,
cpu_subtype ,
cpu_brand ,
cpu_physical_cores ,
cpu_logical_cores ,
hardware_vendor ,
hardware_model ,
hardware_version ,
hardware_serial ,
computer_name ,
primary_ip_id ,
seen_time ,
distributed_interval ,
logger_tls_period ,
config_tls_refresh ,
primary_ip ,
primary_mac ,
label_update_time ,
enroll_secret_name ,
`
2020-03-30 02:19:54 +00:00
var params [ ] interface { }
Add host additional info filters (#28)
This change adds the ability to filter additional host info via the list hosts endpoint; a continuation from [here](https://github.com/kolide/fleet/pull/2330), but now filtering is accomplished via SQL.
Additional object without filter:
```
curl 'https://localhost:8080/api/v1/kolide/hosts'
...
"additional": {
"macs": [
{
"mac": "00:00:00:00:00:00"
},
{
"mac": "02:42:c0:a8:10:05"
}
],
"time": [
{
"day": "13",
"hour": "3",
"year": "2020",
"month": "10",
"minutes": "43",
"seconds": "11",
"weekday": "Tuesday",
"datetime": "2020-10-13T03:43:11Z",
"iso_8601": "2020-10-13T03:43:11Z",
"timezone": "GMT",
"timestamp": "Tue Oct 13 03:43:11 2020 UTC",
"unix_time": "1602560591",
"local_time": "1602560591",
"local_timezone": "UTC"
}
},
...
```
Additional object with filter:
```
curl 'https://localhost:8080/api/v1/kolide/hosts?additional_info_filters=macs,notreal'
...
"additional": {
"macs": [
{
"mac": "00:00:00:00:00:00"
},
{
"mac": "02:42:c0:a8:10:05"
}
],
"notreal": null
},
...
```
2020-11-14 00:33:25 +00:00
// Filter additional info by extracting into a new json object.
if len ( opt . AdditionalFilters ) > 0 {
sql += ` JSON_OBJECT (
`
for _ , field := range opt . AdditionalFilters {
sql += fmt . Sprintf ( ` ?, JSON_EXTRACT(additional, ?), ` )
params = append ( params , field , fmt . Sprintf ( ` $."%s" ` , field ) )
}
sql = sql [ : len ( sql ) - 2 ]
sql += `
) AS additional
`
} else {
sql += `
additional
`
}
sql += ` FROM hosts
`
2020-03-30 02:19:54 +00:00
switch opt . StatusFilter {
case "new" :
2020-11-04 20:03:06 +00:00
sql += "WHERE DATE_ADD(created_at, INTERVAL 1 DAY) >= ?"
2020-03-30 02:19:54 +00:00
params = append ( params , time . Now ( ) )
case "online" :
2020-11-04 20:03:06 +00:00
sql += fmt . Sprintf ( "WHERE DATE_ADD(seen_time, INTERVAL LEAST(distributed_interval, config_tls_refresh) + %d SECOND) > ?" , kolide . OnlineIntervalBuffer )
2020-03-30 02:19:54 +00:00
params = append ( params , time . Now ( ) )
case "offline" :
2020-11-04 20:03:06 +00:00
sql += fmt . Sprintf ( "WHERE DATE_ADD(seen_time, INTERVAL LEAST(distributed_interval, config_tls_refresh) + %d SECOND) <= ? AND DATE_ADD(seen_time, INTERVAL 30 DAY) >= ?" , kolide . OnlineIntervalBuffer )
2020-03-30 02:19:54 +00:00
params = append ( params , time . Now ( ) , time . Now ( ) )
case "mia" :
2020-11-04 20:03:06 +00:00
sql += "WHERE DATE_ADD(seen_time, INTERVAL 30 DAY) <= ?"
2020-03-30 02:19:54 +00:00
params = append ( params , time . Now ( ) )
}
sql = appendListOptionsToSQL ( sql , opt . ListOptions )
2016-11-16 13:47:49 +00:00
hosts := [ ] * kolide . Host { }
2020-03-30 02:19:54 +00:00
if err := d . db . Select ( & hosts , sql , params ... ) ; err != nil {
2017-01-04 21:16:17 +00:00
return nil , errors . Wrap ( err , "list hosts" )
2016-11-16 13:47:49 +00:00
}
2016-12-06 19:51:11 +00:00
return hosts , nil
}
2019-04-09 18:11:11 +00:00
func ( d * Datastore ) CleanupIncomingHosts ( now time . Time ) error {
sqlStatement := `
DELETE FROM hosts
WHERE host_name = ' ' AND osquery_version = ' '
AND created_at < ( ? - INTERVAL 5 MINUTE )
`
if _ , err := d . db . Exec ( sqlStatement , now ) ; err != nil {
return errors . Wrap ( err , "cleanup incoming hosts" )
}
return nil
}
2017-04-18 17:39:50 +00:00
func ( d * Datastore ) GenerateHostStatusStatistics ( now time . Time ) ( online , offline , mia , new uint , e error ) {
// The logic in this function should remain synchronized with
// host.Status and CountHostsInTargets
sqlStatement := fmt . Sprintf ( `
SELECT
COALESCE ( SUM ( CASE WHEN DATE_ADD ( seen_time , INTERVAL 30 DAY ) <= ? THEN 1 ELSE 0 END ) , 0 ) mia ,
COALESCE ( SUM ( CASE WHEN DATE_ADD ( seen_time , INTERVAL LEAST ( distributed_interval , config_tls_refresh ) + % d SECOND ) <= ? AND DATE_ADD ( seen_time , INTERVAL 30 DAY ) >= ? THEN 1 ELSE 0 END ) , 0 ) offline ,
COALESCE ( SUM ( CASE WHEN DATE_ADD ( seen_time , INTERVAL LEAST ( distributed_interval , config_tls_refresh ) + % d SECOND ) > ? THEN 1 ELSE 0 END ) , 0 ) online ,
COALESCE ( SUM ( CASE WHEN DATE_ADD ( created_at , INTERVAL 1 DAY ) >= ? THEN 1 ELSE 0 END ) , 0 ) new
2017-01-04 21:16:17 +00:00
FROM hosts
LIMIT 1 ;
2017-04-18 17:39:50 +00:00
` , kolide . OnlineIntervalBuffer , kolide . OnlineIntervalBuffer )
2017-01-04 21:16:17 +00:00
counts := struct {
MIA uint ` db:"mia" `
Offline uint ` db:"offline" `
Online uint ` db:"online" `
2017-01-20 13:57:47 +00:00
New uint ` db:"new" `
2017-01-04 21:16:17 +00:00
} { }
2017-04-18 17:39:50 +00:00
err := d . db . Get ( & counts , sqlStatement , now , now , now , now , now )
2017-01-16 19:52:03 +00:00
if err != nil && err != sql . ErrNoRows {
2017-01-04 21:16:17 +00:00
e = errors . Wrap ( err , "generating host statistics" )
return
}
mia = counts . MIA
offline = counts . Offline
online = counts . Online
2017-01-20 13:57:47 +00:00
new = counts . New
return online , offline , mia , new , nil
2017-01-04 21:16:17 +00:00
}
2016-11-16 13:47:49 +00:00
// EnrollHost enrolls a host
2020-05-29 16:12:39 +00:00
func ( d * Datastore ) EnrollHost ( osqueryHostID , nodeKey , secretName string ) ( * kolide . Host , error ) {
2016-12-06 19:51:11 +00:00
if osqueryHostID == "" {
2017-01-04 21:16:17 +00:00
return nil , fmt . Errorf ( "missing osquery host identifier" )
2016-11-16 13:47:49 +00:00
}
2016-12-06 19:51:11 +00:00
2020-04-07 01:10:20 +00:00
zeroTime := time . Unix ( 0 , 0 ) . Add ( 24 * time . Hour )
2016-11-16 13:47:49 +00:00
sqlInsert := `
INSERT INTO hosts (
detail_update_time ,
2020-04-07 01:10:20 +00:00
label_update_time ,
2016-12-06 19:51:11 +00:00
osquery_host_id ,
2017-01-04 21:16:17 +00:00
seen_time ,
2020-05-29 16:12:39 +00:00
node_key ,
enroll_secret_name
2020-04-07 01:10:20 +00:00
) VALUES ( ? , ? , ? , ? , ? , ? )
2016-11-16 13:47:49 +00:00
ON DUPLICATE KEY UPDATE
2020-10-22 17:51:26 +00:00
node_key = VALUES ( node_key )
2016-11-16 13:47:49 +00:00
`
var result sql . Result
2020-04-07 01:10:20 +00:00
result , err := d . db . Exec ( sqlInsert , zeroTime , zeroTime , osqueryHostID , time . Now ( ) . UTC ( ) , nodeKey , secretName )
2016-11-16 13:47:49 +00:00
if err != nil {
2017-01-04 21:16:17 +00:00
return nil , errors . Wrap ( err , "inserting" )
2016-11-16 13:47:49 +00:00
}
id , _ := result . LastInsertId ( )
sqlSelect := `
SELECT * FROM hosts WHERE id = ? LIMIT 1
`
host := & kolide . Host { }
err = d . db . Get ( host , sqlSelect , id )
if err != nil {
2017-01-04 21:16:17 +00:00
return nil , errors . Wrap ( err , "getting the host to return" )
2016-11-16 13:47:49 +00:00
}
2020-04-07 22:12:32 +00:00
_ , err = d . db . Exec ( ` INSERT IGNORE INTO label_membership (host_id, label_id) VALUES (?, (SELECT id FROM labels WHERE name = 'All Hosts' AND label_type = 1)) ` , id )
2020-04-07 01:10:20 +00:00
if err != nil {
return nil , errors . Wrap ( err , "insert new host into all hosts label" )
}
2016-11-16 13:47:49 +00:00
return host , nil
}
func ( d * Datastore ) AuthenticateHost ( nodeKey string ) ( * kolide . Host , error ) {
sqlStatement := `
2020-05-21 15:36:00 +00:00
SELECT
id ,
osquery_host_id ,
created_at ,
updated_at ,
detail_update_time ,
2020-04-22 20:54:32 +00:00
label_update_time ,
2020-05-21 15:36:00 +00:00
node_key ,
host_name ,
uuid ,
platform ,
osquery_version ,
os_version ,
build ,
platform_like ,
code_name ,
uptime ,
physical_memory ,
cpu_type ,
cpu_subtype ,
cpu_brand ,
cpu_physical_cores ,
cpu_logical_cores ,
hardware_vendor ,
hardware_model ,
hardware_version ,
hardware_serial ,
computer_name ,
primary_ip_id ,
seen_time ,
distributed_interval ,
logger_tls_period ,
2020-05-29 16:12:39 +00:00
config_tls_refresh ,
enroll_secret_name
2016-12-06 19:51:11 +00:00
FROM hosts
2020-10-22 17:51:26 +00:00
WHERE node_key = ?
2016-12-06 19:51:11 +00:00
LIMIT 1
2016-11-16 13:47:49 +00:00
`
2016-12-06 19:51:11 +00:00
2016-11-16 13:47:49 +00:00
host := & kolide . Host { }
if err := d . db . Get ( host , sqlStatement , nodeKey ) ; err != nil {
switch err {
case sql . ErrNoRows :
2017-05-25 21:10:12 +00:00
return nil , notFound ( "Host" )
2016-11-16 13:47:49 +00:00
default :
2017-01-04 21:16:17 +00:00
return nil , errors . New ( "finding host" )
2016-11-16 13:47:49 +00:00
}
}
2016-12-06 19:51:11 +00:00
return host , nil
2016-11-16 13:47:49 +00:00
}
2016-11-16 23:12:59 +00:00
func ( d * Datastore ) MarkHostSeen ( host * kolide . Host , t time . Time ) error {
sqlStatement := `
UPDATE hosts SET
2017-01-04 21:16:17 +00:00
seen_time = ?
2016-11-16 23:12:59 +00:00
WHERE node_key = ?
`
_ , err := d . db . Exec ( sqlStatement , t , host . NodeKey )
if err != nil {
2017-01-04 21:16:17 +00:00
return errors . Wrap ( err , "marking host seen" )
2016-11-16 23:12:59 +00:00
}
host . UpdatedAt = t
return nil
2016-11-16 13:47:49 +00:00
}
2016-12-06 19:51:11 +00:00
func ( d * Datastore ) searchHostsWithOmits ( query string , omit ... uint ) ( [ ] * kolide . Host , error ) {
2019-10-16 17:12:35 +00:00
hostQuery := transformQuery ( query )
2016-12-05 19:16:23 +00:00
ipQuery := ` " ` + query + ` " `
2016-12-01 17:00:00 +00:00
sqlStatement :=
`
SELECT DISTINCT *
2016-11-16 13:47:49 +00:00
FROM hosts
2016-12-01 17:00:00 +00:00
WHERE
(
2020-05-21 18:11:02 +00:00
MATCH ( host_name , uuid ) AGAINST ( ? IN BOOLEAN MODE )
OR MATCH ( primary_ip , primary_mac ) AGAINST ( ? IN BOOLEAN MODE )
2016-12-01 17:00:00 +00:00
)
2016-12-05 19:16:23 +00:00
AND id NOT IN ( ? )
2016-11-16 13:47:49 +00:00
LIMIT 10
`
2016-12-05 19:16:23 +00:00
2019-10-16 17:12:35 +00:00
sql , args , err := sqlx . In ( sqlStatement , hostQuery , ipQuery , omit )
2016-12-05 19:16:23 +00:00
if err != nil {
2017-01-04 21:16:17 +00:00
return nil , errors . Wrap ( err , "searching hosts" )
2016-11-16 13:47:49 +00:00
}
2016-12-05 19:16:23 +00:00
sql = d . db . Rebind ( sql )
2016-11-16 13:47:49 +00:00
2016-12-06 19:51:11 +00:00
hosts := [ ] * kolide . Host { }
2016-12-05 19:16:23 +00:00
err = d . db . Select ( & hosts , sql , args ... )
if err != nil {
2017-01-04 21:16:17 +00:00
return nil , errors . Wrap ( err , "searching hosts rebound" )
2016-11-16 13:47:49 +00:00
}
return hosts , nil
}
2017-01-17 14:51:04 +00:00
func ( d * Datastore ) searchHostsDefault ( omit ... uint ) ( [ ] * kolide . Host , error ) {
sqlStatement := `
SELECT * FROM hosts
2020-10-22 17:51:26 +00:00
WHERE id NOT in ( ? )
2017-01-17 14:51:04 +00:00
ORDER BY seen_time DESC
LIMIT 5
`
var in interface { }
{
// use -1 if there are no values to omit.
2020-10-22 17:51:26 +00:00
// Avoids empty args error for `sqlx.In`
2017-01-17 14:51:04 +00:00
in = omit
if len ( omit ) == 0 {
in = - 1
}
}
var hosts [ ] * kolide . Host
sql , args , err := sqlx . In ( sqlStatement , in )
if err != nil {
return nil , errors . Wrap ( err , "searching default hosts" )
}
sql = d . db . Rebind ( sql )
err = d . db . Select ( & hosts , sql , args ... )
if err != nil {
return nil , errors . Wrap ( err , "searching default hosts rebound" )
}
return hosts , nil
}
2019-10-16 17:12:35 +00:00
// SearchHosts find hosts by query containing an IP address, a host name or UUID.
// Optionally pass a list of IDs to omit from the search
2016-12-06 19:51:11 +00:00
func ( d * Datastore ) SearchHosts ( query string , omit ... uint ) ( [ ] * kolide . Host , error ) {
2019-10-16 17:12:35 +00:00
hostQuery := transformQuery ( query )
if ! queryMinLength ( hostQuery ) {
2017-01-17 14:51:04 +00:00
return d . searchHostsDefault ( omit ... )
}
2016-11-16 13:47:49 +00:00
if len ( omit ) > 0 {
return d . searchHostsWithOmits ( query , omit ... )
}
2016-12-05 19:16:23 +00:00
// Needs quotes to avoid each . marking a word boundary
ipQuery := ` " ` + query + ` " `
2016-12-01 17:00:00 +00:00
sqlStatement :=
`
SELECT DISTINCT *
FROM hosts
WHERE
(
2020-05-21 18:11:02 +00:00
MATCH ( host_name , uuid ) AGAINST ( ? IN BOOLEAN MODE )
OR MATCH ( primary_ip , primary_mac ) AGAINST ( ? IN BOOLEAN MODE )
2016-12-01 17:00:00 +00:00
)
2016-11-16 13:47:49 +00:00
LIMIT 10
`
2016-12-06 19:51:11 +00:00
hosts := [ ] * kolide . Host { }
2016-11-16 13:47:49 +00:00
2019-10-16 17:12:35 +00:00
if err := d . db . Select ( & hosts , sqlStatement , hostQuery , ipQuery ) ; err != nil {
2017-01-04 21:16:17 +00:00
return nil , errors . Wrap ( err , "searching hosts" )
2016-11-16 13:47:49 +00:00
}
2016-12-06 19:51:11 +00:00
2016-11-16 13:47:49 +00:00
return hosts , nil
}
2018-05-17 22:54:34 +00:00
func ( d * Datastore ) HostIDsByName ( hostnames [ ] string ) ( [ ] uint , error ) {
2020-01-24 05:27:20 +00:00
if len ( hostnames ) == 0 {
return [ ] uint { } , nil
}
2018-05-17 22:54:34 +00:00
sqlStatement := `
SELECT id FROM hosts
WHERE host_name IN ( ? )
`
sql , args , err := sqlx . In ( sqlStatement , hostnames )
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
}
2020-04-22 20:54:32 +00:00
func ( d * Datastore ) HostByIdentifier ( identifier string ) ( * kolide . Host , error ) {
sql := `
SELECT * FROM hosts
WHERE ? IN ( host_name , osquery_host_id , node_key , uuid )
LIMIT 1
`
host := & kolide . Host { }
err := d . db . Get ( host , sql , identifier )
if err != nil {
return nil , errors . Wrap ( err , "get host by identifier" )
}
return host , nil
}