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