From dfac039422ab01c2ab83f50e584c07a2cb8129fd Mon Sep 17 00:00:00 2001 From: Zachary Wasserman Date: Mon, 13 Aug 2018 10:07:10 -0700 Subject: [PATCH] Fix targeting packs to individual hosts (#1897) Packs can be targeted to individual hosts through the UI. This was supported previously and was broken with refactoring in Fleet 2.0. There is currently no support in the fleetctl format for targeting individual hosts, but this could be added at a later date. Fixes #1878 --- server/datastore/datastore_packs_test.go | 36 ++++++++++++++++++++++++ server/datastore/mysql/packs.go | 15 +++++++--- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/server/datastore/datastore_packs_test.go b/server/datastore/datastore_packs_test.go index 38f889b910..f1badbef65 100644 --- a/server/datastore/datastore_packs_test.go +++ b/server/datastore/datastore_packs_test.go @@ -432,4 +432,40 @@ func testListPacksForHost(t *testing.T, ds kolide.Datastore) { if assert.Len(t, packs, 1) { assert.Equal(t, "foo_pack", packs[0].Name) } + + // Add host directly to pack + err = ds.AddHostToPack(h1.ID, p2.ID) + require.Nil(t, err) + + packs, err = ds.ListPacksForHost(h1.ID) + require.Nil(t, err) + assert.Len(t, packs, 2) + + // Remove label membership for both + err = ds.RecordLabelQueryExecutions( + h1, + map[uint]bool{l2.ID: false, l1.ID: false}, + mockClock.Now(), + ) + require.Nil(t, err) + + err = ds.RecordLabelQueryExecutions( + h1, + map[uint]bool{l2.ID: false}, + mockClock.Now(), + ) + require.Nil(t, err) + packs, err = ds.ListPacksForHost(h1.ID) + require.Nil(t, err) + if assert.Len(t, packs, 1) { + assert.Equal(t, p2.Name, packs[0].Name) + } + + // Now host is added directly to both packs + err = ds.AddHostToPack(h1.ID, p1.ID) + require.Nil(t, err) + + packs, err = ds.ListPacksForHost(h1.ID) + require.Nil(t, err) + assert.Len(t, packs, 2) } diff --git a/server/datastore/mysql/packs.go b/server/datastore/mysql/packs.go index 9bfabf2764..8fa2e69b42 100644 --- a/server/datastore/mysql/packs.go +++ b/server/datastore/mysql/packs.go @@ -445,8 +445,9 @@ func (d *Datastore) ListLabelsForPack(pid uint) ([]*kolide.Label, error) { func (d *Datastore) ListPacksForHost(hid uint) ([]*kolide.Pack, error) { query := ` - SELECT DISTINCT p.* - FROM packs p + SELECT DISTINCT packs.* + FROM + ((SELECT p.* FROM packs p JOIN pack_targets pt JOIN label_query_executions lqe ON ( @@ -455,11 +456,17 @@ func (d *Datastore) ListPacksForHost(hid uint) ([]*kolide.Pack, error) { AND pt.type = ? AND lqe.matches ) - WHERE lqe.host_id = ? AND NOT p.disabled + WHERE lqe.host_id = ? AND NOT p.disabled) + UNION ALL + (SELECT p.* + FROM packs p + JOIN pack_targets pt + ON (p.id = pt.pack_id AND pt.type = ? AND pt.target_id = ?)) + ) packs ` packs := []*kolide.Pack{} - if err := d.db.Select(&packs, query, kolide.TargetLabel, hid); err != nil && err != sql.ErrNoRows { + if err := d.db.Select(&packs, query, kolide.TargetLabel, hid, kolide.TargetHost, hid); err != nil && err != sql.ErrNoRows { return nil, errors.Wrap(err, "listing hosts in pack") } return packs, nil