Allow filtering by status as well as label and match query when listing hosts (#1562)

This commit is contained in:
Tomas Touceda 2021-08-05 14:56:29 -03:00 committed by GitHub
parent bf57121c04
commit 3b67366bf4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 74 additions and 11 deletions

View file

@ -0,0 +1 @@
* When filtering hosts to transfer to a team, allow to filter by label, status, and query string

View file

@ -351,6 +351,21 @@ func (d *Datastore) ListHosts(filter fleet.TeamFilter, opt fleet.HostListOptions
WHERE TRUE AND %s
`, d.whereFilterHostsByTeams(filter, "h"),
)
sql, params = filterHostsByStatus(sql, opt, params)
sql, params = searchLike(sql, params, opt.MatchQuery, hostSearchColumns...)
sql = appendListOptionsToSQL(sql, opt.ListOptions)
hosts := []*fleet.Host{}
if err := d.db.Select(&hosts, sql, params...); err != nil {
return nil, errors.Wrap(err, "list hosts")
}
return hosts, nil
}
func filterHostsByStatus(sql string, opt fleet.HostListOptions, params []interface{}) (string, []interface{}) {
switch opt.StatusFilter {
case "new":
sql += "AND DATE_ADD(h.created_at, INTERVAL 1 DAY) >= ?"
@ -365,17 +380,7 @@ func (d *Datastore) ListHosts(filter fleet.TeamFilter, opt fleet.HostListOptions
sql += "AND DATE_ADD(h.seen_time, INTERVAL 30 DAY) <= ?"
params = append(params, time.Now())
}
sql, params = searchLike(sql, params, opt.MatchQuery, hostSearchColumns...)
sql = appendListOptionsToSQL(sql, opt.ListOptions)
hosts := []*fleet.Host{}
if err := d.db.Select(&hosts, sql, params...); err != nil {
return nil, errors.Wrap(err, "list hosts")
}
return hosts, nil
return sql, params
}
func (d *Datastore) CleanupIncomingHosts(now time.Time) error {

View file

@ -412,6 +412,7 @@ func (d *Datastore) ListHostsInLabel(filter fleet.TeamFilter, lid uint, opt flee
params := []interface{}{lid}
sql, params = filterHostsByStatus(sql, opt, params)
sql, params = searchLike(sql, params, opt.MatchQuery, hostSearchColumns...)
sql = appendListOptionsToSQL(sql, opt.ListOptions)

View file

@ -332,6 +332,62 @@ func TestListHostsInLabel(t *testing.T) {
}
}
func TestListHostsInLabelAndStatus(t *testing.T) {
db := CreateMySQLDS(t)
defer db.Close()
h1, err := db.NewHost(&fleet.Host{
DetailUpdatedAt: time.Now(),
LabelUpdatedAt: time.Now(),
SeenTime: time.Now(),
OsqueryHostID: "1",
NodeKey: "1",
UUID: "1",
Hostname: "foo.local",
})
require.Nil(t, err)
lastSeenTime := time.Now().Add(-1000 * time.Hour)
h2, err := db.NewHost(&fleet.Host{
DetailUpdatedAt: lastSeenTime,
LabelUpdatedAt: lastSeenTime,
SeenTime: lastSeenTime,
OsqueryHostID: "2",
NodeKey: "2",
UUID: "2",
Hostname: "bar.local",
})
require.Nil(t, err)
l1 := &fleet.LabelSpec{
ID: 1,
Name: "label foo",
Query: "query1",
}
err = db.ApplyLabelSpecs([]*fleet.LabelSpec{l1})
require.Nil(t, err)
filter := fleet.TeamFilter{User: test.UserAdmin}
for _, h := range []*fleet.Host{h1, h2} {
err = db.RecordLabelQueryExecutions(h, map[uint]bool{l1.ID: true}, time.Now())
assert.Nil(t, err)
}
{
hosts, err := db.ListHostsInLabel(filter, l1.ID, fleet.HostListOptions{StatusFilter: fleet.StatusOnline})
require.Nil(t, err)
require.Len(t, hosts, 1)
assert.Equal(t, "foo.local", hosts[0].Hostname)
}
{
hosts, err := db.ListHostsInLabel(filter, l1.ID, fleet.HostListOptions{StatusFilter: fleet.StatusMIA})
require.Nil(t, err)
require.Len(t, hosts, 1)
assert.Equal(t, "bar.local", hosts[0].Hostname)
}
}
func TestBuiltInLabels(t *testing.T) {
db := CreateMySQLDS(t)
defer db.Close()