mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 08:58:41 +00:00
Update labels interfaces for fleetctl (#1686)
- Remove unnecessary labels code - Remove unnecessary packs code - Update tests as appropriate
This commit is contained in:
parent
26dc30bd25
commit
bde7256a09
35 changed files with 824 additions and 1671 deletions
|
|
@ -45,8 +45,18 @@ func testDistributedQueryCampaign(t *testing.T, ds kolide.Datastore) {
|
|||
h2 := test.NewHost(t, ds, "bar.local", "192.168.1.11", "2", "2", mockClock.Now().Add(-1*time.Hour))
|
||||
h3 := test.NewHost(t, ds, "baz.local", "192.168.1.12", "3", "3", mockClock.Now().Add(-13*time.Minute))
|
||||
|
||||
l1 := test.NewLabel(t, ds, "label foo", "query foo")
|
||||
l2 := test.NewLabel(t, ds, "label bar", "query foo")
|
||||
l1 := kolide.LabelSpec{
|
||||
ID: 1,
|
||||
Name: "label foo",
|
||||
Query: "query foo",
|
||||
}
|
||||
l2 := kolide.LabelSpec{
|
||||
ID: 2,
|
||||
Name: "label bar",
|
||||
Query: "query bar",
|
||||
}
|
||||
err := ds.ApplyLabelSpecs([]*kolide.LabelSpec{&l1, &l2})
|
||||
require.Nil(t, err)
|
||||
|
||||
checkTargets(t, ds, campaign.ID, []uint{}, []uint{})
|
||||
|
||||
|
|
|
|||
|
|
@ -411,10 +411,12 @@ func testDistributedQueriesForHost(t *testing.T, ds kolide.Datastore) {
|
|||
assert.Empty(t, queries)
|
||||
|
||||
// Create a label
|
||||
l1, err := ds.NewLabel(&kolide.Label{
|
||||
l1 := kolide.LabelSpec{
|
||||
ID: 1,
|
||||
Name: "label foo",
|
||||
Query: "query1",
|
||||
})
|
||||
}
|
||||
err = ds.ApplyLabelSpecs([]*kolide.LabelSpec{&l1})
|
||||
require.Nil(t, err)
|
||||
|
||||
// Add hosts to label
|
||||
|
|
|
|||
|
|
@ -39,35 +39,34 @@ func testLabels(t *testing.T, db kolide.Datastore) {
|
|||
assert.Nil(t, err)
|
||||
assert.Empty(t, queries)
|
||||
|
||||
newLabels := []kolide.Label{
|
||||
newLabels := []*kolide.LabelSpec{
|
||||
// Note these are intentionally out of order
|
||||
kolide.Label{
|
||||
&kolide.LabelSpec{
|
||||
ID: 1,
|
||||
Name: "label3",
|
||||
Query: "query3",
|
||||
Platform: "darwin",
|
||||
},
|
||||
kolide.Label{
|
||||
&kolide.LabelSpec{
|
||||
ID: 2,
|
||||
Name: "label1",
|
||||
Query: "query1",
|
||||
},
|
||||
kolide.Label{
|
||||
&kolide.LabelSpec{
|
||||
ID: 3,
|
||||
Name: "label2",
|
||||
Query: "query2",
|
||||
Platform: "darwin",
|
||||
},
|
||||
kolide.Label{
|
||||
&kolide.LabelSpec{
|
||||
ID: 4,
|
||||
Name: "label4",
|
||||
Query: "query4",
|
||||
Platform: "darwin",
|
||||
},
|
||||
}
|
||||
|
||||
for _, label := range newLabels {
|
||||
var newLabel *kolide.Label
|
||||
newLabel, err = db.NewLabel(&label)
|
||||
assert.Nil(t, err)
|
||||
assert.NotZero(t, newLabel.ID)
|
||||
}
|
||||
err = db.ApplyLabelSpecs(newLabels)
|
||||
require.Nil(t, err)
|
||||
|
||||
expectQueries := map[string]string{
|
||||
"1": "query3",
|
||||
|
|
@ -141,66 +140,87 @@ func testLabels(t *testing.T, db kolide.Datastore) {
|
|||
}
|
||||
|
||||
func testManagingLabelsOnPacks(t *testing.T, ds kolide.Datastore) {
|
||||
monitoringPack := &kolide.Pack{
|
||||
Name: "monitoring",
|
||||
pack := &kolide.PackSpec{
|
||||
ID: 1,
|
||||
Name: "pack1",
|
||||
}
|
||||
_, err := ds.NewPack(monitoringPack)
|
||||
err := ds.ApplyPackSpecs([]*kolide.PackSpec{pack})
|
||||
require.Nil(t, err)
|
||||
|
||||
mysqlLabel := &kolide.Label{
|
||||
labels, err := ds.ListLabelsForPack(pack.ID)
|
||||
require.Nil(t, err)
|
||||
assert.Len(t, labels, 0)
|
||||
|
||||
mysqlLabel := &kolide.LabelSpec{
|
||||
ID: 1,
|
||||
Name: "MySQL Monitoring",
|
||||
Query: "select pid from processes where name = 'mysqld';",
|
||||
}
|
||||
mysqlLabel, err = ds.NewLabel(mysqlLabel)
|
||||
err = ds.ApplyLabelSpecs([]*kolide.LabelSpec{mysqlLabel})
|
||||
require.Nil(t, err)
|
||||
|
||||
err = ds.AddLabelToPack(mysqlLabel.ID, monitoringPack.ID)
|
||||
pack.Targets = kolide.PackSpecTargets{
|
||||
Labels: []string{
|
||||
mysqlLabel.Name,
|
||||
},
|
||||
}
|
||||
err = ds.ApplyPackSpecs([]*kolide.PackSpec{pack})
|
||||
require.Nil(t, err)
|
||||
|
||||
labels, err := ds.ListLabelsForPack(monitoringPack.ID)
|
||||
labels, err = ds.ListLabelsForPack(pack.ID)
|
||||
require.Nil(t, err)
|
||||
if assert.Len(t, labels, 1) {
|
||||
assert.Equal(t, "MySQL Monitoring", labels[0].Name)
|
||||
}
|
||||
|
||||
osqueryLabel := &kolide.Label{
|
||||
osqueryLabel := &kolide.LabelSpec{
|
||||
ID: 2,
|
||||
Name: "Osquery Monitoring",
|
||||
Query: "select pid from processes where name = 'osqueryd';",
|
||||
}
|
||||
osqueryLabel, err = ds.NewLabel(osqueryLabel)
|
||||
err = ds.ApplyLabelSpecs([]*kolide.LabelSpec{mysqlLabel, osqueryLabel})
|
||||
require.Nil(t, err)
|
||||
|
||||
err = ds.AddLabelToPack(osqueryLabel.ID, monitoringPack.ID)
|
||||
pack.Targets = kolide.PackSpecTargets{
|
||||
Labels: []string{
|
||||
mysqlLabel.Name,
|
||||
osqueryLabel.Name,
|
||||
},
|
||||
}
|
||||
err = ds.ApplyPackSpecs([]*kolide.PackSpec{pack})
|
||||
require.Nil(t, err)
|
||||
|
||||
labels, err = ds.ListLabelsForPack(monitoringPack.ID)
|
||||
labels, err = ds.ListLabelsForPack(pack.ID)
|
||||
require.Nil(t, err)
|
||||
assert.Len(t, labels, 2)
|
||||
|
||||
}
|
||||
|
||||
func testSearchLabels(t *testing.T, db kolide.Datastore) {
|
||||
_, err := db.NewLabel(&kolide.Label{
|
||||
Name: "foo",
|
||||
})
|
||||
specs := []*kolide.LabelSpec{
|
||||
&kolide.LabelSpec{
|
||||
ID: 1,
|
||||
Name: "foo",
|
||||
},
|
||||
&kolide.LabelSpec{
|
||||
ID: 2,
|
||||
Name: "bar",
|
||||
},
|
||||
&kolide.LabelSpec{
|
||||
ID: 3,
|
||||
Name: "foo-bar",
|
||||
},
|
||||
&kolide.LabelSpec{
|
||||
ID: 4,
|
||||
Name: "All Hosts",
|
||||
LabelType: kolide.LabelTypeBuiltIn,
|
||||
},
|
||||
}
|
||||
err := db.ApplyLabelSpecs(specs)
|
||||
require.Nil(t, err)
|
||||
|
||||
_, err = db.NewLabel(&kolide.Label{
|
||||
Name: "bar",
|
||||
})
|
||||
all, err := db.Label(specs[3].ID)
|
||||
require.Nil(t, err)
|
||||
|
||||
l3, err := db.NewLabel(&kolide.Label{
|
||||
Name: "foo-bar",
|
||||
})
|
||||
require.Nil(t, err)
|
||||
|
||||
all, err := db.NewLabel(&kolide.Label{
|
||||
Name: "All Hosts",
|
||||
LabelType: kolide.LabelTypeBuiltIn,
|
||||
})
|
||||
require.Nil(t, err)
|
||||
all, err = db.Label(all.ID)
|
||||
l3, err := db.Label(specs[2].ID)
|
||||
require.Nil(t, err)
|
||||
|
||||
// We once threw errors when the search query was empty. Verify that we
|
||||
|
|
@ -230,15 +250,18 @@ func testSearchLabelsLimit(t *testing.T, db kolide.Datastore) {
|
|||
t.Skip("inmem is being deprecated, test skipped")
|
||||
}
|
||||
|
||||
_, err := db.NewLabel(&kolide.Label{
|
||||
all := &kolide.LabelSpec{
|
||||
Name: "All Hosts",
|
||||
LabelType: kolide.LabelTypeBuiltIn,
|
||||
})
|
||||
}
|
||||
err := db.ApplyLabelSpecs([]*kolide.LabelSpec{all})
|
||||
require.Nil(t, err)
|
||||
|
||||
for i := 0; i < 15; i++ {
|
||||
_, err := db.NewLabel(&kolide.Label{
|
||||
Name: fmt.Sprintf("foo-%d", i),
|
||||
})
|
||||
l := &kolide.LabelSpec{
|
||||
Name: fmt.Sprintf("foo%d", i),
|
||||
}
|
||||
err := db.ApplyLabelSpecs([]*kolide.LabelSpec{l})
|
||||
require.Nil(t, err)
|
||||
}
|
||||
|
||||
|
|
@ -278,12 +301,13 @@ func testListHostsInLabel(t *testing.T, db kolide.Datastore) {
|
|||
})
|
||||
require.Nil(t, err)
|
||||
|
||||
l1, err := db.NewLabel(&kolide.Label{
|
||||
l1 := &kolide.LabelSpec{
|
||||
ID: 1,
|
||||
Name: "label foo",
|
||||
Query: "query1",
|
||||
})
|
||||
}
|
||||
err = db.ApplyLabelSpecs([]*kolide.LabelSpec{l1})
|
||||
require.Nil(t, err)
|
||||
require.NotZero(t, l1.ID)
|
||||
|
||||
{
|
||||
|
||||
|
|
@ -331,19 +355,18 @@ func testListUniqueHostsInLabels(t *testing.T, db kolide.Datastore) {
|
|||
hosts = append(hosts, h)
|
||||
}
|
||||
|
||||
l1, err := db.NewLabel(&kolide.Label{
|
||||
l1 := kolide.LabelSpec{
|
||||
ID: 1,
|
||||
Name: "label foo",
|
||||
Query: "query1",
|
||||
})
|
||||
require.Nil(t, err)
|
||||
require.NotZero(t, l1.ID)
|
||||
|
||||
l2, err := db.NewLabel(&kolide.Label{
|
||||
}
|
||||
l2 := kolide.LabelSpec{
|
||||
ID: 2,
|
||||
Name: "label bar",
|
||||
Query: "query2",
|
||||
})
|
||||
}
|
||||
err := db.ApplyLabelSpecs([]*kolide.LabelSpec{&l1, &l2})
|
||||
require.Nil(t, err)
|
||||
require.NotZero(t, l2.ID)
|
||||
|
||||
for i := 0; i < 3; i++ {
|
||||
err = db.RecordLabelQueryExecutions(hosts[i], map[uint]bool{l1.ID: true}, time.Now())
|
||||
|
|
@ -365,63 +388,62 @@ func testListUniqueHostsInLabels(t *testing.T, db kolide.Datastore) {
|
|||
|
||||
}
|
||||
|
||||
func testSaveLabel(t *testing.T, db kolide.Datastore) {
|
||||
func testChangeLabelDetails(t *testing.T, db kolide.Datastore) {
|
||||
if db.Name() == "inmem" {
|
||||
t.Skip("inmem is being deprecated")
|
||||
}
|
||||
label := &kolide.Label{
|
||||
|
||||
label := kolide.LabelSpec{
|
||||
ID: 1,
|
||||
Name: "my label",
|
||||
Description: "a label",
|
||||
Query: "select 1 from processes;",
|
||||
Query: "select 1 from processes",
|
||||
Platform: "darwin",
|
||||
}
|
||||
label, err := db.NewLabel(label)
|
||||
err := db.ApplyLabelSpecs([]*kolide.LabelSpec{&label})
|
||||
require.Nil(t, err)
|
||||
label.Name = "changed name"
|
||||
|
||||
label.Description = "changed description"
|
||||
_, err = db.SaveLabel(label)
|
||||
err = db.ApplyLabelSpecs([]*kolide.LabelSpec{&label})
|
||||
require.Nil(t, err)
|
||||
|
||||
saved, err := db.Label(label.ID)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, label.Name, saved.Name)
|
||||
assert.Equal(t, label.Description, saved.Description)
|
||||
}
|
||||
|
||||
func testReplaceDeletedLabel(t *testing.T, db kolide.Datastore) {
|
||||
if db.Name() == "inmem" {
|
||||
t.Skip("inmem is being deprecated, test skipped")
|
||||
func testApplyLabelSpecsRoundtrip(t *testing.T, ds kolide.Datastore) {
|
||||
expectedSpecs := []*kolide.LabelSpec{
|
||||
&kolide.LabelSpec{
|
||||
Name: "foo",
|
||||
Query: "select * from foo",
|
||||
Description: "foo description",
|
||||
Platform: "darwin",
|
||||
},
|
||||
&kolide.LabelSpec{
|
||||
Name: "bar",
|
||||
Query: "select * from bar",
|
||||
},
|
||||
&kolide.LabelSpec{
|
||||
Name: "bing",
|
||||
Query: "select * from bing",
|
||||
},
|
||||
&kolide.LabelSpec{
|
||||
Name: "All Hosts",
|
||||
Query: "SELECT 1",
|
||||
LabelType: kolide.LabelTypeBuiltIn,
|
||||
},
|
||||
}
|
||||
|
||||
label := &kolide.Label{
|
||||
Name: "my label",
|
||||
Query: "select 1 from processes;",
|
||||
}
|
||||
saved, err := db.NewLabel(label)
|
||||
err := ds.ApplyLabelSpecs(expectedSpecs)
|
||||
require.Nil(t, err)
|
||||
|
||||
saved, err = db.Label(saved.ID)
|
||||
specs, err := ds.GetLabelSpecs()
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, label.Name, saved.Name)
|
||||
assert.Equal(t, label.Description, saved.Description)
|
||||
assert.Equal(t, expectedSpecs, specs)
|
||||
|
||||
newLabel := &kolide.Label{
|
||||
Name: "my label",
|
||||
Query: " select * from time",
|
||||
}
|
||||
|
||||
// Replace should fail when label already exists and isn't soft deleted
|
||||
_, err = db.NewLabel(newLabel)
|
||||
require.NotNil(t, err)
|
||||
|
||||
// Now delete label and replace should succeed
|
||||
err = db.DeleteLabel(label.ID)
|
||||
// Should be idempotent
|
||||
err = ds.ApplyLabelSpecs(expectedSpecs)
|
||||
require.Nil(t, err)
|
||||
|
||||
saved, err = db.NewLabel(newLabel)
|
||||
specs, err = ds.GetLabelSpecs()
|
||||
require.Nil(t, err)
|
||||
|
||||
saved, err = db.Label(saved.ID)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, newLabel.Name, saved.Name)
|
||||
assert.Equal(t, newLabel.Description, saved.Description)
|
||||
assert.Equal(t, expectedSpecs, specs)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package datastore
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/WatchBeam/clock"
|
||||
|
|
@ -11,14 +12,10 @@ import (
|
|||
)
|
||||
|
||||
func testDeletePack(t *testing.T, ds kolide.Datastore) {
|
||||
pack := &kolide.Pack{
|
||||
Name: "foo",
|
||||
}
|
||||
_, err := ds.NewPack(pack)
|
||||
assert.Nil(t, err)
|
||||
pack := test.NewPack(t, ds, "foo")
|
||||
assert.NotEqual(t, uint(0), pack.ID)
|
||||
|
||||
pack, err = ds.Pack(pack.ID)
|
||||
pack, err := ds.Pack(pack.ID)
|
||||
require.Nil(t, err)
|
||||
|
||||
err = ds.DeletePack(pack.ID)
|
||||
|
|
@ -30,11 +27,7 @@ func testDeletePack(t *testing.T, ds kolide.Datastore) {
|
|||
}
|
||||
|
||||
func testGetPackByName(t *testing.T, ds kolide.Datastore) {
|
||||
pack := &kolide.Pack{
|
||||
Name: "foo",
|
||||
}
|
||||
_, err := ds.NewPack(pack)
|
||||
assert.Nil(t, err)
|
||||
pack := test.NewPack(t, ds, "foo")
|
||||
assert.NotEqual(t, uint(0), pack.ID)
|
||||
|
||||
pack, ok, err := ds.PackByName(pack.Name)
|
||||
|
|
@ -50,28 +43,64 @@ func testGetPackByName(t *testing.T, ds kolide.Datastore) {
|
|||
|
||||
}
|
||||
|
||||
func testGetHostsInPack(t *testing.T, ds kolide.Datastore) {
|
||||
func testListPacks(t *testing.T, ds kolide.Datastore) {
|
||||
p1 := &kolide.PackSpec{
|
||||
ID: 1,
|
||||
Name: "foo_pack",
|
||||
}
|
||||
p2 := &kolide.PackSpec{
|
||||
ID: 2,
|
||||
Name: "bar_pack",
|
||||
}
|
||||
err := ds.ApplyPackSpecs([]*kolide.PackSpec{p1})
|
||||
require.Nil(t, err)
|
||||
|
||||
packs, err := ds.ListPacks(kolide.ListOptions{})
|
||||
require.Nil(t, err)
|
||||
assert.Len(t, packs, 1)
|
||||
|
||||
err = ds.ApplyPackSpecs([]*kolide.PackSpec{p1, p2})
|
||||
require.Nil(t, err)
|
||||
|
||||
packs, err = ds.ListPacks(kolide.ListOptions{})
|
||||
require.Nil(t, err)
|
||||
assert.Len(t, packs, 2)
|
||||
|
||||
fmt.Println(packs[0], packs[1])
|
||||
}
|
||||
|
||||
func testListHostsInPack(t *testing.T, ds kolide.Datastore) {
|
||||
if ds.Name() == "inmem" {
|
||||
t.Skip("inmem is deprecated")
|
||||
}
|
||||
|
||||
mockClock := clock.NewMockClock()
|
||||
|
||||
p1, err := ds.NewPack(&kolide.Pack{
|
||||
l1 := kolide.LabelSpec{
|
||||
ID: 1,
|
||||
Name: "foo",
|
||||
})
|
||||
}
|
||||
err := ds.ApplyLabelSpecs([]*kolide.LabelSpec{&l1})
|
||||
require.Nil(t, err)
|
||||
|
||||
l1, err := ds.NewLabel(&kolide.Label{
|
||||
Name: "foo",
|
||||
})
|
||||
require.Nil(t, err)
|
||||
|
||||
err = ds.AddLabelToPack(l1.ID, p1.ID)
|
||||
p1 := &kolide.PackSpec{
|
||||
ID: 1,
|
||||
Name: "foo_pack",
|
||||
Targets: kolide.PackSpecTargets{
|
||||
Labels: []string{
|
||||
l1.Name,
|
||||
},
|
||||
},
|
||||
}
|
||||
err = ds.ApplyPackSpecs([]*kolide.PackSpec{p1})
|
||||
require.Nil(t, err)
|
||||
|
||||
h1 := test.NewHost(t, ds, "h1.local", "10.10.10.1", "1", "1", mockClock.Now())
|
||||
|
||||
hostsInPack, err := ds.ListHostsInPack(p1.ID, kolide.ListOptions{})
|
||||
require.Nil(t, err)
|
||||
require.Len(t, hostsInPack, 0)
|
||||
|
||||
err = ds.RecordLabelQueryExecutions(
|
||||
h1,
|
||||
map[uint]bool{l1.ID: true},
|
||||
|
|
@ -79,7 +108,7 @@ func testGetHostsInPack(t *testing.T, ds kolide.Datastore) {
|
|||
)
|
||||
require.Nil(t, err)
|
||||
|
||||
hostsInPack, err := ds.ListHostsInPack(p1.ID, kolide.ListOptions{})
|
||||
hostsInPack, err = ds.ListHostsInPack(p1.ID, kolide.ListOptions{})
|
||||
require.Nil(t, err)
|
||||
require.Len(t, hostsInPack, 1)
|
||||
|
||||
|
|
@ -99,38 +128,29 @@ func testGetHostsInPack(t *testing.T, ds kolide.Datastore) {
|
|||
hostsInPack, err = ds.ListHostsInPack(p1.ID, kolide.ListOptions{})
|
||||
require.Nil(t, err)
|
||||
require.Len(t, hostsInPack, 2)
|
||||
|
||||
h3 := test.NewHost(t, ds, "h3.local", "10.10.10.3", "3", "3", mockClock.Now())
|
||||
|
||||
err = ds.AddHostToPack(h3.ID, p1.ID)
|
||||
require.Nil(t, err)
|
||||
|
||||
hostsInPack, err = ds.ListHostsInPack(p1.ID, kolide.ListOptions{})
|
||||
require.Nil(t, err)
|
||||
require.Len(t, hostsInPack, 3)
|
||||
|
||||
explicitHostsInPack, err = ds.ListExplicitHostsInPack(p1.ID, kolide.ListOptions{})
|
||||
require.Nil(t, err)
|
||||
require.Len(t, explicitHostsInPack, 1)
|
||||
}
|
||||
|
||||
func testAddLabelToPackTwice(t *testing.T, ds kolide.Datastore) {
|
||||
l1 := test.NewLabel(t, ds, "l1", "select 1;")
|
||||
p1 := test.NewPack(t, ds, "p1")
|
||||
l1 := kolide.LabelSpec{
|
||||
ID: 1,
|
||||
Name: "l1",
|
||||
Query: "select 1",
|
||||
}
|
||||
err := ds.ApplyLabelSpecs([]*kolide.LabelSpec{&l1})
|
||||
require.Nil(t, err)
|
||||
|
||||
err := ds.AddLabelToPack(l1.ID, p1.ID)
|
||||
assert.Nil(t, err)
|
||||
|
||||
labels, err := ds.ListLabelsForPack(p1.ID)
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, labels, 1)
|
||||
|
||||
err = ds.AddLabelToPack(l1.ID, p1.ID)
|
||||
assert.Nil(t, err)
|
||||
|
||||
labels, err = ds.ListLabelsForPack(p1.ID)
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, labels, 1)
|
||||
p1 := &kolide.PackSpec{
|
||||
ID: 1,
|
||||
Name: "pack1",
|
||||
Targets: kolide.PackSpecTargets{
|
||||
Labels: []string{
|
||||
l1.Name,
|
||||
l1.Name,
|
||||
},
|
||||
},
|
||||
}
|
||||
err = ds.ApplyPackSpecs([]*kolide.PackSpec{p1})
|
||||
require.NotNil(t, err)
|
||||
}
|
||||
|
||||
func testApplyPackSpecRoundtrip(t *testing.T, ds kolide.Datastore) {
|
||||
|
|
@ -143,9 +163,22 @@ func testApplyPackSpecRoundtrip(t *testing.T, ds kolide.Datastore) {
|
|||
err := ds.ApplyQueries(zwass.ID, queries)
|
||||
require.Nil(t, err)
|
||||
|
||||
test.NewLabel(t, ds, "foo", "select * from foo")
|
||||
test.NewLabel(t, ds, "bar", "select * from bar")
|
||||
test.NewLabel(t, ds, "bing", "select * from bing")
|
||||
labels := []*kolide.LabelSpec{
|
||||
&kolide.LabelSpec{
|
||||
Name: "foo",
|
||||
Query: "select * from foo",
|
||||
},
|
||||
&kolide.LabelSpec{
|
||||
Name: "bar",
|
||||
Query: "select * from bar",
|
||||
},
|
||||
&kolide.LabelSpec{
|
||||
Name: "bing",
|
||||
Query: "select * from bing",
|
||||
},
|
||||
}
|
||||
err = ds.ApplyLabelSpecs(labels)
|
||||
require.Nil(t, err)
|
||||
|
||||
boolPtr := func(b bool) *bool { return &b }
|
||||
uintPtr := func(x uint) *uint { return &x }
|
||||
|
|
@ -196,7 +229,6 @@ func testApplyPackSpecRoundtrip(t *testing.T, ds kolide.Datastore) {
|
|||
|
||||
func testApplyPackSpecMissingQueries(t *testing.T, ds kolide.Datastore) {
|
||||
// Do not define queries mentioned in spec
|
||||
|
||||
specs := []*kolide.PackSpec{
|
||||
&kolide.PackSpec{
|
||||
ID: 1,
|
||||
|
|
@ -219,3 +251,172 @@ func testApplyPackSpecMissingQueries(t *testing.T, ds kolide.Datastore) {
|
|||
assert.Contains(t, err.Error(), "unknown query 'bar'")
|
||||
}
|
||||
}
|
||||
|
||||
func testListLabelsForPack(t *testing.T, ds kolide.Datastore) {
|
||||
labelSpecs := []*kolide.LabelSpec{
|
||||
&kolide.LabelSpec{
|
||||
Name: "foo",
|
||||
Query: "select * from foo",
|
||||
},
|
||||
&kolide.LabelSpec{
|
||||
Name: "bar",
|
||||
Query: "select * from bar",
|
||||
},
|
||||
&kolide.LabelSpec{
|
||||
Name: "bing",
|
||||
Query: "select * from bing",
|
||||
},
|
||||
}
|
||||
err := ds.ApplyLabelSpecs(labelSpecs)
|
||||
require.Nil(t, err)
|
||||
|
||||
specs := []*kolide.PackSpec{
|
||||
&kolide.PackSpec{
|
||||
ID: 1,
|
||||
Name: "test_pack",
|
||||
Targets: kolide.PackSpecTargets{
|
||||
Labels: []string{
|
||||
"foo",
|
||||
"bar",
|
||||
"bing",
|
||||
},
|
||||
},
|
||||
},
|
||||
&kolide.PackSpec{
|
||||
ID: 2,
|
||||
Name: "test 2",
|
||||
Targets: kolide.PackSpecTargets{
|
||||
Labels: []string{
|
||||
"bing",
|
||||
},
|
||||
},
|
||||
},
|
||||
&kolide.PackSpec{
|
||||
ID: 3,
|
||||
Name: "test 3",
|
||||
},
|
||||
}
|
||||
err = ds.ApplyPackSpecs(specs)
|
||||
require.Nil(t, err)
|
||||
|
||||
labels, err := ds.ListLabelsForPack(specs[0].ID)
|
||||
require.Nil(t, err)
|
||||
assert.Len(t, labels, 3)
|
||||
|
||||
labels, err = ds.ListLabelsForPack(specs[1].ID)
|
||||
require.Nil(t, err)
|
||||
assert.Len(t, labels, 1)
|
||||
assert.Equal(t, "bing", labels[0].Name)
|
||||
|
||||
labels, err = ds.ListLabelsForPack(specs[2].ID)
|
||||
require.Nil(t, err)
|
||||
assert.Len(t, labels, 0)
|
||||
}
|
||||
|
||||
func testListPacksForHost(t *testing.T, ds kolide.Datastore) {
|
||||
if ds.Name() == "inmem" {
|
||||
t.Skip("inmem is deprecated")
|
||||
}
|
||||
|
||||
mockClock := clock.NewMockClock()
|
||||
|
||||
l1 := &kolide.LabelSpec{
|
||||
ID: 1,
|
||||
Name: "foo",
|
||||
}
|
||||
l2 := &kolide.LabelSpec{
|
||||
ID: 2,
|
||||
Name: "bar",
|
||||
}
|
||||
err := ds.ApplyLabelSpecs([]*kolide.LabelSpec{l1, l2})
|
||||
require.Nil(t, err)
|
||||
|
||||
p1 := &kolide.PackSpec{
|
||||
ID: 1,
|
||||
Name: "foo_pack",
|
||||
Targets: kolide.PackSpecTargets{
|
||||
Labels: []string{
|
||||
l1.Name,
|
||||
l2.Name,
|
||||
},
|
||||
},
|
||||
}
|
||||
p2 := &kolide.PackSpec{
|
||||
ID: 2,
|
||||
Name: "shmoo_pack",
|
||||
Targets: kolide.PackSpecTargets{
|
||||
Labels: []string{
|
||||
l2.Name,
|
||||
},
|
||||
},
|
||||
}
|
||||
err = ds.ApplyPackSpecs([]*kolide.PackSpec{p1, p2})
|
||||
require.Nil(t, err)
|
||||
|
||||
h1 := test.NewHost(t, ds, "h1.local", "10.10.10.1", "1", "1", mockClock.Now())
|
||||
|
||||
packs, err := ds.ListPacksForHost(h1.ID)
|
||||
require.Nil(t, err)
|
||||
require.Len(t, packs, 0)
|
||||
|
||||
err = ds.RecordLabelQueryExecutions(
|
||||
h1,
|
||||
map[uint]bool{l1.ID: true},
|
||||
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, "foo_pack", packs[0].Name)
|
||||
}
|
||||
|
||||
err = ds.RecordLabelQueryExecutions(
|
||||
h1,
|
||||
map[uint]bool{l1.ID: false, l2.ID: true},
|
||||
mockClock.Now(),
|
||||
)
|
||||
require.Nil(t, err)
|
||||
|
||||
packs, err = ds.ListPacksForHost(h1.ID)
|
||||
require.Nil(t, err)
|
||||
assert.Len(t, packs, 2)
|
||||
|
||||
err = ds.RecordLabelQueryExecutions(
|
||||
h1,
|
||||
map[uint]bool{l1.ID: true, l2.ID: true},
|
||||
mockClock.Now(),
|
||||
)
|
||||
require.Nil(t, err)
|
||||
|
||||
packs, err = ds.ListPacksForHost(h1.ID)
|
||||
require.Nil(t, err)
|
||||
assert.Len(t, packs, 2)
|
||||
|
||||
h2 := test.NewHost(t, ds, "h2.local", "10.10.10.2", "2", "2", mockClock.Now())
|
||||
|
||||
err = ds.RecordLabelQueryExecutions(
|
||||
h2,
|
||||
map[uint]bool{l2.ID: true},
|
||||
mockClock.Now(),
|
||||
)
|
||||
require.Nil(t, err)
|
||||
|
||||
packs, err = ds.ListPacksForHost(h1.ID)
|
||||
require.Nil(t, err)
|
||||
assert.Len(t, packs, 2)
|
||||
|
||||
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, "foo_pack", packs[0].Name)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,19 +43,18 @@ func testCountHostsInTargets(t *testing.T, ds kolide.Datastore) {
|
|||
const thirtyDaysAndAMinuteAgo = -1 * (30*24*60 + 1)
|
||||
h6 := initHost(mockClock.Now().Add(thirtyDaysAndAMinuteAgo*time.Minute), 3600, 3600)
|
||||
|
||||
l1, err := ds.NewLabel(&kolide.Label{
|
||||
l1 := kolide.LabelSpec{
|
||||
ID: 1,
|
||||
Name: "label foo",
|
||||
Query: "query foo",
|
||||
})
|
||||
require.Nil(t, err)
|
||||
require.NotZero(t, l1.ID)
|
||||
|
||||
l2, err := ds.NewLabel(&kolide.Label{
|
||||
}
|
||||
l2 := kolide.LabelSpec{
|
||||
ID: 2,
|
||||
Name: "label bar",
|
||||
Query: "query foo",
|
||||
})
|
||||
Query: "query bar",
|
||||
}
|
||||
err := ds.ApplyLabelSpecs([]*kolide.LabelSpec{&l1, &l2})
|
||||
require.Nil(t, err)
|
||||
require.NotZero(t, l2.ID)
|
||||
|
||||
for _, h := range []*kolide.Host{h1, h2, h3, h6} {
|
||||
err = ds.RecordLabelQueryExecutions(h, map[uint]bool{l1.ID: true}, mockClock.Now())
|
||||
|
|
|
|||
|
|
@ -47,7 +47,9 @@ var testFunctions = [...]func(*testing.T, kolide.Datastore){
|
|||
testSaveHosts,
|
||||
testDeleteHost,
|
||||
testListHost,
|
||||
testGetHostsInPack,
|
||||
testListHostsInPack,
|
||||
testListPacksForHost,
|
||||
testListPacks,
|
||||
testDistributedQueryCampaign,
|
||||
testCleanupDistributedQueryCampaigns,
|
||||
testBuiltInLabels,
|
||||
|
|
@ -66,9 +68,8 @@ var testFunctions = [...]func(*testing.T, kolide.Datastore){
|
|||
testDuplicateNewQuery,
|
||||
testIdempotentDeleteHost,
|
||||
testChangeEmail,
|
||||
testSaveLabel,
|
||||
testChangeLabelDetails,
|
||||
testFlappingNetworkInterfaces,
|
||||
testReplaceDeletedLabel,
|
||||
testMigrationStatus,
|
||||
testUnicode,
|
||||
testCountHostsInTargets,
|
||||
|
|
@ -80,4 +81,6 @@ var testFunctions = [...]func(*testing.T, kolide.Datastore){
|
|||
testApplyQueries,
|
||||
testApplyPackSpecRoundtrip,
|
||||
testApplyPackSpecMissingQueries,
|
||||
testApplyLabelSpecsRoundtrip,
|
||||
testListLabelsForPack,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/kolide/fleet/server/kolide"
|
||||
"github.com/kolide/fleet/server/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
|
@ -14,10 +15,15 @@ func testUnicode(t *testing.T, ds kolide.Datastore) {
|
|||
t.Skip("inmem is being deprecated, test skipped")
|
||||
}
|
||||
|
||||
label, err := ds.NewLabel(&kolide.Label{Name: "測試"})
|
||||
l1 := kolide.LabelSpec{
|
||||
ID: 1,
|
||||
Name: "測試",
|
||||
Query: "query foo",
|
||||
}
|
||||
err := ds.ApplyLabelSpecs([]*kolide.LabelSpec{&l1})
|
||||
require.Nil(t, err)
|
||||
|
||||
label, err = ds.Label(label.ID)
|
||||
label, err := ds.Label(l1.ID)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, "測試", label.Name)
|
||||
|
||||
|
|
@ -35,10 +41,10 @@ func testUnicode(t *testing.T, ds kolide.Datastore) {
|
|||
require.Nil(t, err)
|
||||
|
||||
user, err = ds.User(user.Username)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, "🍱", user.Username)
|
||||
|
||||
pack, err := ds.NewPack(&kolide.Pack{Name: "👨🏾🚒"})
|
||||
require.Nil(t, err)
|
||||
pack := test.NewPack(t, ds, "👨🏾🚒")
|
||||
|
||||
pack, err = ds.Pack(pack.ID)
|
||||
assert.Equal(t, "👨🏾🚒", pack.Name)
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ type Datastore struct {
|
|||
kolide.QueryStore
|
||||
kolide.PackStore
|
||||
kolide.ScheduledQueryStore
|
||||
kolide.LabelStore
|
||||
}
|
||||
|
||||
func New(config config.KolideConfig) (*Datastore, error) {
|
||||
|
|
@ -138,7 +139,7 @@ func (d *Datastore) MigrateData() error {
|
|||
SMTPVerifySSLCerts: true,
|
||||
}
|
||||
|
||||
return d.createBuiltinLabels()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Datastore) MigrationStatus() (kolide.MigrationStatus, error) {
|
||||
|
|
@ -162,10 +163,6 @@ func (d *Datastore) Initialize() error {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := d.createDevLabels(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := d.createDevOrgInfo(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -252,18 +249,6 @@ func (d *Datastore) createDevPacksAndQueries() error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (d *Datastore) createBuiltinLabels() error {
|
||||
for _, label := range appstate.Labels2() {
|
||||
label := label
|
||||
_, err := d.NewLabel(&label)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Bootstrap a few users when using the in-memory database.
|
||||
// Each user's default password will just be their username.
|
||||
func (d *Datastore) createDevUsers() error {
|
||||
|
|
@ -465,43 +450,3 @@ func (d *Datastore) createDevOrgInfo() error {
|
|||
_, err := d.NewAppConfig(devOrgInfo)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *Datastore) createDevLabels() error {
|
||||
labels := []kolide.Label{
|
||||
{
|
||||
UpdateCreateTimestamps: kolide.UpdateCreateTimestamps{
|
||||
CreateTimestamp: kolide.CreateTimestamp{
|
||||
CreatedAt: time.Date(2016, time.October, 27, 8, 31, 16, 0, time.UTC),
|
||||
},
|
||||
UpdateTimestamp: kolide.UpdateTimestamp{
|
||||
UpdatedAt: time.Date(2016, time.October, 27, 8, 31, 16, 0, time.UTC),
|
||||
},
|
||||
},
|
||||
Name: "dev_label_apache",
|
||||
Query: "select * from processes where name like '%Apache%'",
|
||||
},
|
||||
{
|
||||
UpdateCreateTimestamps: kolide.UpdateCreateTimestamps{
|
||||
CreateTimestamp: kolide.CreateTimestamp{
|
||||
CreatedAt: time.Now().Add(-1 * time.Hour),
|
||||
},
|
||||
UpdateTimestamp: kolide.UpdateTimestamp{
|
||||
UpdatedAt: time.Now(),
|
||||
},
|
||||
},
|
||||
|
||||
Name: "dev_label_darwin",
|
||||
Query: "select * from osquery_info where platform='darwin'",
|
||||
},
|
||||
}
|
||||
|
||||
for _, label := range labels {
|
||||
label := label
|
||||
_, err := d.NewLabel(&label)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package mysql
|
|||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
|
|
@ -9,48 +10,66 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// 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 = `
|
||||
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 := `
|
||||
INSERT INTO labels (
|
||||
name,
|
||||
description,
|
||||
query,
|
||||
platform,
|
||||
label_type
|
||||
) VALUES ( ?, ?, ?, ?, ?)
|
||||
) VALUES ( ?, ?, ?, ?, ? )
|
||||
ON DUPLICATE KEY UPDATE
|
||||
name = VALUES(name),
|
||||
description = VALUES(description),
|
||||
query = VALUES(query),
|
||||
platform = VALUES(platform),
|
||||
label_type = VALUES(label_type),
|
||||
deleted = false
|
||||
`
|
||||
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)
|
||||
stmt, err := tx.Prepare(sql)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "inserting label")
|
||||
return errors.Wrap(err, "prepare ApplyLabelSpecs insert")
|
||||
}
|
||||
|
||||
id, _ := result.LastInsertId()
|
||||
label.ID = uint(id)
|
||||
return label, nil
|
||||
for _, s := range specs {
|
||||
_, 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")
|
||||
}
|
||||
|
||||
return specs, nil
|
||||
}
|
||||
|
||||
// DeleteLabel soft deletes a kolide.Label
|
||||
|
|
@ -378,17 +397,3 @@ func (d *Datastore) SearchLabels(query string, omit ...uint) ([]kolide.Label, er
|
|||
|
||||
return matches, 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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,7 +135,6 @@ func (d *Datastore) GetPackSpecs() (specs []*kolide.PackSpec, err error) {
|
|||
// Get basic specs
|
||||
query := "SELECT id, name, description, platform FROM packs"
|
||||
if err := tx.Select(&specs, query); err != nil {
|
||||
fmt.Println(err)
|
||||
return nil, errors.Wrap(err, "get packs")
|
||||
}
|
||||
|
||||
|
|
@ -151,17 +150,6 @@ WHERE pack_id = ? AND pt.type = ? AND pt.target_id = l.id
|
|||
}
|
||||
}
|
||||
|
||||
// query = `
|
||||
// INSERT INTO scheduled_queries (
|
||||
// pack_id, query_name, name, description, ` + "`interval`" + `,
|
||||
// snapshot, removed, shard, platform, version
|
||||
// )
|
||||
// VALUES (
|
||||
// ?, ?, ?, ?, ?,
|
||||
// ?, ?, ?, ?, ?
|
||||
// )
|
||||
// `
|
||||
|
||||
// Load queries
|
||||
for _, spec := range specs {
|
||||
query = `
|
||||
|
|
@ -203,67 +191,6 @@ func (d *Datastore) PackByName(name string, opts ...kolide.OptionalArg) (*kolide
|
|||
return &pack, true, nil
|
||||
}
|
||||
|
||||
// NewPack creates a new Pack
|
||||
func (d *Datastore) NewPack(pack *kolide.Pack, opts ...kolide.OptionalArg) (*kolide.Pack, error) {
|
||||
db := d.getTransaction(opts)
|
||||
var (
|
||||
deletedPack kolide.Pack
|
||||
query string
|
||||
)
|
||||
err := db.Get(&deletedPack,
|
||||
"SELECT * FROM packs WHERE name = ? AND deleted", pack.Name)
|
||||
switch err {
|
||||
case nil:
|
||||
query = `
|
||||
REPLACE INTO packs
|
||||
( name, description, platform, disabled, deleted)
|
||||
VALUES ( ?, ?, ?, ?, ?)
|
||||
`
|
||||
case sql.ErrNoRows:
|
||||
query = `
|
||||
INSERT INTO packs
|
||||
( name, description, platform, disabled, deleted)
|
||||
VALUES ( ?, ?, ?, ?, ?)
|
||||
`
|
||||
default:
|
||||
return nil, errors.Wrap(err, "check for existing pack")
|
||||
}
|
||||
|
||||
deleted := false
|
||||
result, err := db.Exec(query, pack.Name, pack.Description, pack.Platform, pack.Disabled, deleted)
|
||||
if err != nil && isDuplicate(err) {
|
||||
return nil, alreadyExists("Pack", deletedPack.ID)
|
||||
} else if err != nil {
|
||||
return nil, errors.Wrap(err, "creating new pack")
|
||||
}
|
||||
|
||||
id, _ := result.LastInsertId()
|
||||
pack.ID = uint(id)
|
||||
return pack, nil
|
||||
}
|
||||
|
||||
// SavePack stores changes to pack
|
||||
func (d *Datastore) SavePack(pack *kolide.Pack) error {
|
||||
query := `
|
||||
UPDATE packs
|
||||
SET name = ?, platform = ?, disabled = ?, description = ?
|
||||
WHERE id = ? AND NOT deleted
|
||||
`
|
||||
|
||||
results, err := d.db.Exec(query, pack.Name, pack.Platform, pack.Disabled, pack.Description, pack.ID)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "updating pack")
|
||||
}
|
||||
rowsAffected, err := results.RowsAffected()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "rows affected updating packs")
|
||||
}
|
||||
if rowsAffected == 0 {
|
||||
return notFound("Pack").WithID(pack.ID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeletePack soft deletes a kolide.Pack so that it won't show up in results
|
||||
func (d *Datastore) DeletePack(pid uint) error {
|
||||
return d.deleteEntity("packs", pid)
|
||||
|
|
@ -294,38 +221,6 @@ func (d *Datastore) ListPacks(opt kolide.ListOptions) ([]*kolide.Pack, error) {
|
|||
return packs, nil
|
||||
}
|
||||
|
||||
// AddLabelToPack associates a kolide.Label with a kolide.Pack
|
||||
func (d *Datastore) AddLabelToPack(lid uint, pid uint, opts ...kolide.OptionalArg) error {
|
||||
db := d.getTransaction(opts)
|
||||
|
||||
query := `
|
||||
INSERT INTO pack_targets ( pack_id, type, target_id )
|
||||
VALUES ( ?, ?, ? )
|
||||
ON DUPLICATE KEY UPDATE id=id
|
||||
`
|
||||
_, err := db.Exec(query, pid, kolide.TargetLabel, lid)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "adding label to pack")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddHostToPack associates a kolide.Host with a kolide.Pack
|
||||
func (d *Datastore) AddHostToPack(hid, pid uint) error {
|
||||
query := `
|
||||
INSERT INTO pack_targets ( pack_id, type, target_id )
|
||||
VALUES ( ?, ?, ? )
|
||||
ON DUPLICATE KEY UPDATE id=id
|
||||
`
|
||||
_, err := d.db.Exec(query, pid, kolide.TargetHost, hid)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "adding host to pack")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListLabelsForPack will return a list of kolide.Label records associated with kolide.Pack
|
||||
func (d *Datastore) ListLabelsForPack(pid uint) ([]*kolide.Label, error) {
|
||||
query := `
|
||||
|
|
@ -356,39 +251,26 @@ func (d *Datastore) ListLabelsForPack(pid uint) ([]*kolide.Label, error) {
|
|||
return labels, nil
|
||||
}
|
||||
|
||||
// RemoreLabelFromPack will remove the association between a kolide.Label and
|
||||
// a kolide.Pack
|
||||
func (d *Datastore) RemoveLabelFromPack(lid, pid uint) error {
|
||||
func (d *Datastore) ListPacksForHost(hid uint) ([]*kolide.Pack, error) {
|
||||
query := `
|
||||
DELETE FROM pack_targets
|
||||
WHERE target_id = ? AND pack_id = ? AND type = ?
|
||||
SELECT DISTINCT p.*
|
||||
FROM packs p
|
||||
JOIN pack_targets pt
|
||||
JOIN label_query_executions lqe
|
||||
ON (
|
||||
p.id = pt.pack_id
|
||||
AND pt.target_id = lqe.label_id
|
||||
AND pt.type = ?
|
||||
AND lqe.matches
|
||||
)
|
||||
WHERE lqe.host_id = ? AND NOT p.disabled
|
||||
`
|
||||
_, err := d.db.Exec(query, lid, pid, kolide.TargetLabel)
|
||||
if err == sql.ErrNoRows {
|
||||
return notFound("PackTarget").WithMessage(fmt.Sprintf("label ID: %d, pack ID: %d", lid, pid))
|
||||
} else if err != nil {
|
||||
return errors.Wrap(err, "removing label from pack")
|
||||
|
||||
packs := []*kolide.Pack{}
|
||||
if err := d.db.Select(&packs, query, kolide.TargetLabel, hid); err != nil && err != sql.ErrNoRows {
|
||||
return nil, errors.Wrap(err, "listing hosts in pack")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveHostFromPack will remove the association between a kolide.Host and a
|
||||
// kolide.Pack
|
||||
func (d *Datastore) RemoveHostFromPack(hid, pid uint) error {
|
||||
query := `
|
||||
DELETE FROM pack_targets
|
||||
WHERE target_id = ? AND pack_id = ? AND type = ?
|
||||
`
|
||||
_, err := d.db.Exec(query, hid, pid, kolide.TargetHost)
|
||||
if err == sql.ErrNoRows {
|
||||
return notFound("PackTarget").WithMessage(fmt.Sprintf("host ID: %d, pack ID: %d", hid, pid))
|
||||
} else if err != nil {
|
||||
return errors.Wrap(err, "removing host from pack")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
return packs, nil
|
||||
}
|
||||
|
||||
func (d *Datastore) ListHostsInPack(pid uint, opt kolide.ListOptions) ([]uint, error) {
|
||||
|
|
|
|||
|
|
@ -8,9 +8,19 @@ import (
|
|||
func (d *Datastore) ListScheduledQueriesInPack(id uint, opts kolide.ListOptions) ([]*kolide.ScheduledQuery, error) {
|
||||
query := `
|
||||
SELECT
|
||||
sq.id, sq.pack_id, sq.name, sq.query_name, q.query,
|
||||
sq.description, sq.interval, sq.snapshot, sq.removed, sq.platform,
|
||||
sq.version, sq.shard
|
||||
sq.id,
|
||||
sq.pack_id,
|
||||
COALESCE(sq.name, q.name) AS name,
|
||||
sq.query_name,
|
||||
COALESCE(sq.description, '') AS description,
|
||||
sq.interval,
|
||||
sq.snapshot,
|
||||
sq.removed,
|
||||
COALESCE(sq.platform, '') AS platform,
|
||||
sq.version,
|
||||
sq.shard,
|
||||
q.query,
|
||||
q.id AS query_id
|
||||
FROM scheduled_queries sq
|
||||
JOIN queries q
|
||||
ON sq.query_name = q.name
|
||||
|
|
|
|||
|
|
@ -6,8 +6,13 @@ import (
|
|||
)
|
||||
|
||||
type LabelStore interface {
|
||||
// ApplyLabelSpes applies a list of LabelSpecs to the datastore,
|
||||
// creating and updating labels as necessary.
|
||||
ApplyLabelSpecs(specs []*LabelSpec) error
|
||||
// GetLabelSpecs returns all of the stored LabelSpecs.
|
||||
GetLabelSpecs() ([]*LabelSpec, error)
|
||||
|
||||
// Label methods
|
||||
NewLabel(Label *Label, opts ...OptionalArg) (*Label, error)
|
||||
DeleteLabel(lid uint) error
|
||||
Label(lid uint) (*Label, error)
|
||||
ListLabels(opt ListOptions) ([]*Label, error)
|
||||
|
|
@ -38,31 +43,24 @@ type LabelStore interface {
|
|||
ListUniqueHostsInLabels(labels []uint) ([]Host, error)
|
||||
|
||||
SearchLabels(query string, omit ...uint) ([]Label, error)
|
||||
|
||||
// SaveLabel allows modification of a label's name and/or description
|
||||
SaveLabel(label *Label) (*Label, error)
|
||||
}
|
||||
|
||||
type LabelService interface {
|
||||
// ApplyLabelSpes applies a list of LabelSpecs to the datastore,
|
||||
// creating and updating labels as necessary.
|
||||
ApplyLabelSpecs(ctx context.Context, specs []*LabelSpec) error
|
||||
// GetLabelSpecs returns all of the stored LabelSpecs.
|
||||
GetLabelSpecs(ctx context.Context) ([]*LabelSpec, error)
|
||||
|
||||
ListLabels(ctx context.Context, opt ListOptions) (labels []*Label, err error)
|
||||
GetLabel(ctx context.Context, id uint) (label *Label, err error)
|
||||
NewLabel(ctx context.Context, p LabelPayload) (label *Label, err error)
|
||||
DeleteLabel(ctx context.Context, id uint) (err error)
|
||||
|
||||
// ModifyLabel is used to change editable fields belonging to a Label
|
||||
ModifyLabel(ctx context.Context, id uint, payload ModifyLabelPayload) (*Label, error)
|
||||
|
||||
// HostIDsForLabel returns ids of hosts that belong to the label identified
|
||||
// by lid
|
||||
HostIDsForLabel(lid uint) ([]uint, error)
|
||||
}
|
||||
|
||||
// ModifyLabelPayload is used to change editable fields for a Label
|
||||
type ModifyLabelPayload struct {
|
||||
Name *string `json:"name"`
|
||||
Description *string `json:"description"`
|
||||
}
|
||||
|
||||
type LabelPayload struct {
|
||||
Name *string `json:"name"`
|
||||
Query *string `json:"query"`
|
||||
|
|
@ -99,3 +97,12 @@ type LabelQueryExecution struct {
|
|||
LabelID uint
|
||||
HostID uint
|
||||
}
|
||||
|
||||
type LabelSpec struct {
|
||||
ID uint
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Query string `json:"query"`
|
||||
Platform string `json:"platform,omitempty"`
|
||||
LabelType LabelType `json:"label_type" db:"label_type"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,15 +6,12 @@ import (
|
|||
|
||||
// PackStore is the datastore interface for managing query packs.
|
||||
type PackStore interface {
|
||||
// ApplyPackSpecs applies a list of PackSpecs to the datastore,
|
||||
// creating and updating packs as necessary.
|
||||
ApplyPackSpecs(specs []*PackSpec) error
|
||||
// GetPackSpecs returns all of the stored PackSpecs.
|
||||
GetPackSpecs() ([]*PackSpec, error)
|
||||
|
||||
// NewPack creates a new pack in the datastore.
|
||||
NewPack(pack *Pack, opts ...OptionalArg) (*Pack, error)
|
||||
|
||||
// SavePack updates an existing pack in the datastore.
|
||||
SavePack(pack *Pack) error
|
||||
|
||||
// DeletePack deletes a pack record from the datastore.
|
||||
DeletePack(pid uint) error
|
||||
|
||||
|
|
@ -27,25 +24,14 @@ type PackStore interface {
|
|||
// exists the bool return value is true
|
||||
PackByName(name string, opts ...OptionalArg) (*Pack, bool, error)
|
||||
|
||||
// AddLabelToPack adds an existing label to an existing pack, both by ID.
|
||||
AddLabelToPack(lid, pid uint, opts ...OptionalArg) error
|
||||
|
||||
// RemoveLabelFromPack removes an existing label from it's association with
|
||||
// an existing pack, both by ID.
|
||||
RemoveLabelFromPack(lid, pid uint) error
|
||||
|
||||
// ListLabelsForPack lists all labels that are associated with a pack.
|
||||
ListLabelsForPack(pid uint) ([]*Label, error)
|
||||
|
||||
// AddHostToPack adds an existing host to an existing pack, both by ID.
|
||||
AddHostToPack(hid uint, pid uint) error
|
||||
// ListPacksForHost lists the packs that a host should execute.
|
||||
ListPacksForHost(hid uint) (packs []*Pack, err error)
|
||||
|
||||
// RemoveHostFromPack removes an existing host from it's association with
|
||||
// an existing pack, both by ID.
|
||||
RemoveHostFromPack(hid uint, pid uint) error
|
||||
|
||||
// ListHostsInPack lists the IDs of all hosts that are associated with a pack,
|
||||
// both through labels and manual associations.
|
||||
// ListHostsInPack lists the IDs of all hosts that are associated with a pack
|
||||
// through labels.
|
||||
ListHostsInPack(pid uint, opt ListOptions) ([]uint, error)
|
||||
|
||||
// ListExplicitHostsInPack lists the IDs of hosts that have been manually
|
||||
|
|
@ -55,38 +41,24 @@ type PackStore interface {
|
|||
|
||||
// PackService is the service interface for managing query packs.
|
||||
type PackService interface {
|
||||
// ApplyPackSpecs applies a list of PackSpecs to the datastore,
|
||||
// creating and updating packs as necessary.
|
||||
ApplyPackSpecs(ctx context.Context, specs []*PackSpec) error
|
||||
// GetPackSpecs returns all of the stored PackSpecs.
|
||||
GetPackSpecs(ctx context.Context) ([]*PackSpec, error)
|
||||
|
||||
// ListPacks lists all packs in the application.
|
||||
ListPacks(ctx context.Context, opt ListOptions) (packs []*Pack, err error)
|
||||
|
||||
// GetPack retrieves a pack by ID.
|
||||
GetPack(ctx context.Context, id uint) (pack *Pack, err error)
|
||||
|
||||
// NewPack creates a new pack in the datastore.
|
||||
NewPack(ctx context.Context, p PackPayload) (pack *Pack, err error)
|
||||
|
||||
// ModifyPack modifies an existing pack in the datastore.
|
||||
ModifyPack(ctx context.Context, id uint, p PackPayload) (pack *Pack, err error)
|
||||
|
||||
// DeletePack deletes a pack record from the datastore.
|
||||
DeletePack(ctx context.Context, id uint) (err error)
|
||||
|
||||
// AddLabelToPack adds an existing label to an existing pack, both by ID.
|
||||
AddLabelToPack(ctx context.Context, lid, pid uint) (err error)
|
||||
|
||||
// RemoveLabelFromPack removes an existing label from it's association with
|
||||
// an existing pack, both by ID.
|
||||
RemoveLabelFromPack(ctx context.Context, lid, pid uint) (err error)
|
||||
|
||||
// ListLabelsForPack lists all labels that are associated with a pack.
|
||||
ListLabelsForPack(ctx context.Context, pid uint) (labels []*Label, err error)
|
||||
|
||||
// AddHostToPack adds an existing host to an existing pack, both by ID.
|
||||
AddHostToPack(ctx context.Context, hid, pid uint) (err error)
|
||||
|
||||
// RemoveHostFromPack removes an existing host from it's association with
|
||||
// an existing pack, both by ID.
|
||||
RemoveHostFromPack(ctx context.Context, hid, pid uint) (err error)
|
||||
|
||||
// ListPacksForHost lists the packs that a host should execute.
|
||||
ListPacksForHost(ctx context.Context, hid uint) (packs []*Pack, err error)
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ type ScheduledQuery struct {
|
|||
ID uint `json:"id"`
|
||||
PackID uint `json:"pack_id" db:"pack_id"`
|
||||
Name string `json:"name"`
|
||||
QueryID uint `json:"query_id" db:"query_id"`
|
||||
QueryName string `json:"query_name" db:"query_name"`
|
||||
Query string `json:"query"` // populated via a join on queries
|
||||
Description string `json:"description"`
|
||||
|
|
|
|||
|
|
@ -12,17 +12,18 @@ package mock
|
|||
//go:generate mockimpl -o datastore_osquery_options.go "s *OsqueryOptionsStore" "kolide.OsqueryOptionsStore"
|
||||
//go:generate mockimpl -o datastore_scheduled_queries.go "s *ScheduledQueryStore" "kolide.ScheduledQueryStore"
|
||||
//go:generate mockimpl -o datastore_queries.go "s *QueryStore" "kolide.QueryStore"
|
||||
//go:generate mockimpl -o datastore_campaigns.go "s *CampaignStore" "kolide.CampaignStore"
|
||||
|
||||
import "github.com/kolide/fleet/server/kolide"
|
||||
|
||||
var _ kolide.Datastore = (*Store)(nil)
|
||||
|
||||
type Store struct {
|
||||
kolide.CampaignStore
|
||||
kolide.SessionStore
|
||||
kolide.PasswordResetStore
|
||||
kolide.YARAStore
|
||||
kolide.TargetStore
|
||||
CampaignStore
|
||||
ScheduledQueryStore
|
||||
OsqueryOptionsStore
|
||||
FileIntegrityMonitoringStore
|
||||
|
|
|
|||
83
server/mock/datastore_campaigns.go
Normal file
83
server/mock/datastore_campaigns.go
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
// Automatically generated by mockimpl. DO NOT EDIT!
|
||||
|
||||
package mock
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/kolide/fleet/server/kolide"
|
||||
)
|
||||
|
||||
var _ kolide.CampaignStore = (*CampaignStore)(nil)
|
||||
|
||||
type NewDistributedQueryCampaignFunc func(camp *kolide.DistributedQueryCampaign) (*kolide.DistributedQueryCampaign, error)
|
||||
|
||||
type DistributedQueryCampaignFunc func(id uint) (*kolide.DistributedQueryCampaign, error)
|
||||
|
||||
type SaveDistributedQueryCampaignFunc func(camp *kolide.DistributedQueryCampaign) error
|
||||
|
||||
type DistributedQueryCampaignTargetIDsFunc func(id uint) (hostIDs []uint, labelIDs []uint, err error)
|
||||
|
||||
type NewDistributedQueryCampaignTargetFunc func(target *kolide.DistributedQueryCampaignTarget) (*kolide.DistributedQueryCampaignTarget, error)
|
||||
|
||||
type NewDistributedQueryExecutionFunc func(exec *kolide.DistributedQueryExecution) (*kolide.DistributedQueryExecution, error)
|
||||
|
||||
type CleanupDistributedQueryCampaignsFunc func(now time.Time) (expired uint, deleted uint, err error)
|
||||
|
||||
type CampaignStore struct {
|
||||
NewDistributedQueryCampaignFunc NewDistributedQueryCampaignFunc
|
||||
NewDistributedQueryCampaignFuncInvoked bool
|
||||
|
||||
DistributedQueryCampaignFunc DistributedQueryCampaignFunc
|
||||
DistributedQueryCampaignFuncInvoked bool
|
||||
|
||||
SaveDistributedQueryCampaignFunc SaveDistributedQueryCampaignFunc
|
||||
SaveDistributedQueryCampaignFuncInvoked bool
|
||||
|
||||
DistributedQueryCampaignTargetIDsFunc DistributedQueryCampaignTargetIDsFunc
|
||||
DistributedQueryCampaignTargetIDsFuncInvoked bool
|
||||
|
||||
NewDistributedQueryCampaignTargetFunc NewDistributedQueryCampaignTargetFunc
|
||||
NewDistributedQueryCampaignTargetFuncInvoked bool
|
||||
|
||||
NewDistributedQueryExecutionFunc NewDistributedQueryExecutionFunc
|
||||
NewDistributedQueryExecutionFuncInvoked bool
|
||||
|
||||
CleanupDistributedQueryCampaignsFunc CleanupDistributedQueryCampaignsFunc
|
||||
CleanupDistributedQueryCampaignsFuncInvoked bool
|
||||
}
|
||||
|
||||
func (s *CampaignStore) NewDistributedQueryCampaign(camp *kolide.DistributedQueryCampaign) (*kolide.DistributedQueryCampaign, error) {
|
||||
s.NewDistributedQueryCampaignFuncInvoked = true
|
||||
return s.NewDistributedQueryCampaignFunc(camp)
|
||||
}
|
||||
|
||||
func (s *CampaignStore) DistributedQueryCampaign(id uint) (*kolide.DistributedQueryCampaign, error) {
|
||||
s.DistributedQueryCampaignFuncInvoked = true
|
||||
return s.DistributedQueryCampaignFunc(id)
|
||||
}
|
||||
|
||||
func (s *CampaignStore) SaveDistributedQueryCampaign(camp *kolide.DistributedQueryCampaign) error {
|
||||
s.SaveDistributedQueryCampaignFuncInvoked = true
|
||||
return s.SaveDistributedQueryCampaignFunc(camp)
|
||||
}
|
||||
|
||||
func (s *CampaignStore) DistributedQueryCampaignTargetIDs(id uint) (hostIDs []uint, labelIDs []uint, err error) {
|
||||
s.DistributedQueryCampaignTargetIDsFuncInvoked = true
|
||||
return s.DistributedQueryCampaignTargetIDsFunc(id)
|
||||
}
|
||||
|
||||
func (s *CampaignStore) NewDistributedQueryCampaignTarget(target *kolide.DistributedQueryCampaignTarget) (*kolide.DistributedQueryCampaignTarget, error) {
|
||||
s.NewDistributedQueryCampaignTargetFuncInvoked = true
|
||||
return s.NewDistributedQueryCampaignTargetFunc(target)
|
||||
}
|
||||
|
||||
func (s *CampaignStore) NewDistributedQueryExecution(exec *kolide.DistributedQueryExecution) (*kolide.DistributedQueryExecution, error) {
|
||||
s.NewDistributedQueryExecutionFuncInvoked = true
|
||||
return s.NewDistributedQueryExecutionFunc(exec)
|
||||
}
|
||||
|
||||
func (s *CampaignStore) CleanupDistributedQueryCampaigns(now time.Time) (expired uint, deleted uint, err error) {
|
||||
s.CleanupDistributedQueryCampaignsFuncInvoked = true
|
||||
return s.CleanupDistributedQueryCampaignsFunc(now)
|
||||
}
|
||||
|
|
@ -10,7 +10,9 @@ import (
|
|||
|
||||
var _ kolide.LabelStore = (*LabelStore)(nil)
|
||||
|
||||
type NewLabelFunc func(Label *kolide.Label, opts ...kolide.OptionalArg) (*kolide.Label, error)
|
||||
type ApplyLabelSpecsFunc func(specs []*kolide.LabelSpec) error
|
||||
|
||||
type GetLabelSpecsFunc func() ([]*kolide.LabelSpec, error)
|
||||
|
||||
type DeleteLabelFunc func(lid uint) error
|
||||
|
||||
|
|
@ -30,11 +32,12 @@ type ListUniqueHostsInLabelsFunc func(labels []uint) ([]kolide.Host, error)
|
|||
|
||||
type SearchLabelsFunc func(query string, omit ...uint) ([]kolide.Label, error)
|
||||
|
||||
type SaveLabelFunc func(label *kolide.Label) (*kolide.Label, error)
|
||||
|
||||
type LabelStore struct {
|
||||
NewLabelFunc NewLabelFunc
|
||||
NewLabelFuncInvoked bool
|
||||
ApplyLabelSpecsFunc ApplyLabelSpecsFunc
|
||||
ApplyLabelSpecsFuncInvoked bool
|
||||
|
||||
GetLabelSpecsFunc GetLabelSpecsFunc
|
||||
GetLabelSpecsFuncInvoked bool
|
||||
|
||||
DeleteLabelFunc DeleteLabelFunc
|
||||
DeleteLabelFuncInvoked bool
|
||||
|
|
@ -62,14 +65,16 @@ type LabelStore struct {
|
|||
|
||||
SearchLabelsFunc SearchLabelsFunc
|
||||
SearchLabelsFuncInvoked bool
|
||||
|
||||
SaveLabelFunc SaveLabelFunc
|
||||
SaveLabelFuncInvoked bool
|
||||
}
|
||||
|
||||
func (s *LabelStore) NewLabel(Label *kolide.Label, opts ...kolide.OptionalArg) (*kolide.Label, error) {
|
||||
s.NewLabelFuncInvoked = true
|
||||
return s.NewLabelFunc(Label, opts...)
|
||||
func (s *LabelStore) ApplyLabelSpecs(specs []*kolide.LabelSpec) error {
|
||||
s.ApplyLabelSpecsFuncInvoked = true
|
||||
return s.ApplyLabelSpecsFunc(specs)
|
||||
}
|
||||
|
||||
func (s *LabelStore) GetLabelSpecs() ([]*kolide.LabelSpec, error) {
|
||||
s.GetLabelSpecsFuncInvoked = true
|
||||
return s.GetLabelSpecsFunc()
|
||||
}
|
||||
|
||||
func (s *LabelStore) DeleteLabel(lid uint) error {
|
||||
|
|
@ -116,8 +121,3 @@ func (s *LabelStore) SearchLabels(query string, omit ...uint) ([]kolide.Label, e
|
|||
s.SearchLabelsFuncInvoked = true
|
||||
return s.SearchLabelsFunc(query, omit...)
|
||||
}
|
||||
|
||||
func (s *LabelStore) SaveLabel(label *kolide.Label) (*kolide.Label, error) {
|
||||
s.SaveLabelFuncInvoked = true
|
||||
return s.SaveLabelFunc(label)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,10 +10,6 @@ type ApplyPackSpecsFunc func(specs []*kolide.PackSpec) error
|
|||
|
||||
type GetPackSpecsFunc func() ([]*kolide.PackSpec, error)
|
||||
|
||||
type NewPackFunc func(pack *kolide.Pack, opts ...kolide.OptionalArg) (*kolide.Pack, error)
|
||||
|
||||
type SavePackFunc func(pack *kolide.Pack) error
|
||||
|
||||
type DeletePackFunc func(pid uint) error
|
||||
|
||||
type PackFunc func(pid uint) (*kolide.Pack, error)
|
||||
|
|
@ -22,15 +18,9 @@ type ListPacksFunc func(opt kolide.ListOptions) ([]*kolide.Pack, error)
|
|||
|
||||
type PackByNameFunc func(name string, opts ...kolide.OptionalArg) (*kolide.Pack, bool, error)
|
||||
|
||||
type AddLabelToPackFunc func(lid uint, pid uint, opts ...kolide.OptionalArg) error
|
||||
|
||||
type RemoveLabelFromPackFunc func(lid uint, pid uint) error
|
||||
|
||||
type ListLabelsForPackFunc func(pid uint) ([]*kolide.Label, error)
|
||||
|
||||
type AddHostToPackFunc func(hid uint, pid uint) error
|
||||
|
||||
type RemoveHostFromPackFunc func(hid uint, pid uint) error
|
||||
type ListPacksForHostFunc func(hid uint) (packs []*kolide.Pack, err error)
|
||||
|
||||
type ListHostsInPackFunc func(pid uint, opt kolide.ListOptions) ([]uint, error)
|
||||
|
||||
|
|
@ -43,12 +33,6 @@ type PackStore struct {
|
|||
GetPackSpecsFunc GetPackSpecsFunc
|
||||
GetPackSpecsFuncInvoked bool
|
||||
|
||||
NewPackFunc NewPackFunc
|
||||
NewPackFuncInvoked bool
|
||||
|
||||
SavePackFunc SavePackFunc
|
||||
SavePackFuncInvoked bool
|
||||
|
||||
DeletePackFunc DeletePackFunc
|
||||
DeletePackFuncInvoked bool
|
||||
|
||||
|
|
@ -61,20 +45,11 @@ type PackStore struct {
|
|||
PackByNameFunc PackByNameFunc
|
||||
PackByNameFuncInvoked bool
|
||||
|
||||
AddLabelToPackFunc AddLabelToPackFunc
|
||||
AddLabelToPackFuncInvoked bool
|
||||
|
||||
RemoveLabelFromPackFunc RemoveLabelFromPackFunc
|
||||
RemoveLabelFromPackFuncInvoked bool
|
||||
|
||||
ListLabelsForPackFunc ListLabelsForPackFunc
|
||||
ListLabelsForPackFuncInvoked bool
|
||||
|
||||
AddHostToPackFunc AddHostToPackFunc
|
||||
AddHostToPackFuncInvoked bool
|
||||
|
||||
RemoveHostFromPackFunc RemoveHostFromPackFunc
|
||||
RemoveHostFromPackFuncInvoked bool
|
||||
ListPacksForHostFunc ListPacksForHostFunc
|
||||
ListPacksForHostFuncInvoked bool
|
||||
|
||||
ListHostsInPackFunc ListHostsInPackFunc
|
||||
ListHostsInPackFuncInvoked bool
|
||||
|
|
@ -93,16 +68,6 @@ func (s *PackStore) GetPackSpecs() ([]*kolide.PackSpec, error) {
|
|||
return s.GetPackSpecsFunc()
|
||||
}
|
||||
|
||||
func (s *PackStore) NewPack(pack *kolide.Pack, opts ...kolide.OptionalArg) (*kolide.Pack, error) {
|
||||
s.NewPackFuncInvoked = true
|
||||
return s.NewPackFunc(pack, opts...)
|
||||
}
|
||||
|
||||
func (s *PackStore) SavePack(pack *kolide.Pack) error {
|
||||
s.SavePackFuncInvoked = true
|
||||
return s.SavePackFunc(pack)
|
||||
}
|
||||
|
||||
func (s *PackStore) DeletePack(pid uint) error {
|
||||
s.DeletePackFuncInvoked = true
|
||||
return s.DeletePackFunc(pid)
|
||||
|
|
@ -123,29 +88,14 @@ func (s *PackStore) PackByName(name string, opts ...kolide.OptionalArg) (*kolide
|
|||
return s.PackByNameFunc(name, opts...)
|
||||
}
|
||||
|
||||
func (s *PackStore) AddLabelToPack(lid uint, pid uint, opts ...kolide.OptionalArg) error {
|
||||
s.AddLabelToPackFuncInvoked = true
|
||||
return s.AddLabelToPackFunc(lid, pid, opts...)
|
||||
}
|
||||
|
||||
func (s *PackStore) RemoveLabelFromPack(lid uint, pid uint) error {
|
||||
s.RemoveLabelFromPackFuncInvoked = true
|
||||
return s.RemoveLabelFromPackFunc(lid, pid)
|
||||
}
|
||||
|
||||
func (s *PackStore) ListLabelsForPack(pid uint) ([]*kolide.Label, error) {
|
||||
s.ListLabelsForPackFuncInvoked = true
|
||||
return s.ListLabelsForPackFunc(pid)
|
||||
}
|
||||
|
||||
func (s *PackStore) AddHostToPack(hid uint, pid uint) error {
|
||||
s.AddHostToPackFuncInvoked = true
|
||||
return s.AddHostToPackFunc(hid, pid)
|
||||
}
|
||||
|
||||
func (s *PackStore) RemoveHostFromPack(hid uint, pid uint) error {
|
||||
s.RemoveHostFromPackFuncInvoked = true
|
||||
return s.RemoveHostFromPackFunc(hid, pid)
|
||||
func (s *PackStore) ListPacksForHost(hid uint) (packs []*kolide.Pack, err error) {
|
||||
s.ListPacksForHostFuncInvoked = true
|
||||
return s.ListPacksForHostFunc(hid)
|
||||
}
|
||||
|
||||
func (s *PackStore) ListHostsInPack(pid uint, opt kolide.ListOptions) ([]uint, error) {
|
||||
|
|
|
|||
|
|
@ -102,39 +102,6 @@ func makeListLabelsEndpoint(svc kolide.Service) endpoint.Endpoint {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Create Label
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
type createLabelRequest struct {
|
||||
payload kolide.LabelPayload
|
||||
}
|
||||
|
||||
type createLabelResponse struct {
|
||||
Label labelResponse `json:"label"`
|
||||
Err error `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
func (r createLabelResponse) error() error { return r.Err }
|
||||
|
||||
func makeCreateLabelEndpoint(svc kolide.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(createLabelRequest)
|
||||
|
||||
label, err := svc.NewLabel(ctx, req.payload)
|
||||
if err != nil {
|
||||
return createLabelResponse{Err: err}, nil
|
||||
}
|
||||
|
||||
labelResp, err := labelResponseForLabel(ctx, svc, label)
|
||||
if err != nil {
|
||||
return createLabelResponse{Err: err}, nil
|
||||
}
|
||||
|
||||
return createLabelResponse{Label: *labelResp}, nil
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Delete Label
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -159,36 +126,3 @@ func makeDeleteLabelEndpoint(svc kolide.Service) endpoint.Endpoint {
|
|||
return deleteLabelResponse{}, nil
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Modify Label
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
type modifyLabelRequest struct {
|
||||
ID uint
|
||||
payload kolide.ModifyLabelPayload
|
||||
}
|
||||
|
||||
type modifyLabelResponse struct {
|
||||
Label labelResponse `json:"label"`
|
||||
Err error `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
func (r modifyLabelResponse) error() error { return r.Err }
|
||||
|
||||
func makeModifyLabelEndpoint(svc kolide.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(modifyLabelRequest)
|
||||
label, err := svc.ModifyLabel(ctx, req.ID, req.payload)
|
||||
if err != nil {
|
||||
return modifyLabelResponse{Err: err}, nil
|
||||
}
|
||||
|
||||
labelResp, err := labelResponseForLabel(ctx, svc, label)
|
||||
if err != nil {
|
||||
return modifyLabelResponse{Err: err}, nil
|
||||
}
|
||||
|
||||
return modifyLabelResponse{Label: *labelResp}, err
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,75 +125,6 @@ func makeListPacksEndpoint(svc kolide.Service) endpoint.Endpoint {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Create Pack
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
type createPackRequest struct {
|
||||
payload kolide.PackPayload
|
||||
}
|
||||
|
||||
type createPackResponse struct {
|
||||
Pack packResponse `json:"pack,omitempty"`
|
||||
Err error `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
func (r createPackResponse) error() error { return r.Err }
|
||||
|
||||
func makeCreatePackEndpoint(svc kolide.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(createPackRequest)
|
||||
pack, err := svc.NewPack(ctx, req.payload)
|
||||
if err != nil {
|
||||
return createPackResponse{Err: err}, nil
|
||||
}
|
||||
|
||||
resp, err := packResponseForPack(ctx, svc, *pack)
|
||||
if err != nil {
|
||||
return createPackResponse{Err: err}, nil
|
||||
}
|
||||
|
||||
return createPackResponse{
|
||||
Pack: *resp,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Modify Pack
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
type modifyPackRequest struct {
|
||||
ID uint
|
||||
payload kolide.PackPayload
|
||||
}
|
||||
|
||||
type modifyPackResponse struct {
|
||||
Pack packResponse `json:"pack,omitempty"`
|
||||
Err error `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
func (r modifyPackResponse) error() error { return r.Err }
|
||||
|
||||
func makeModifyPackEndpoint(svc kolide.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(modifyPackRequest)
|
||||
pack, err := svc.ModifyPack(ctx, req.ID, req.payload)
|
||||
if err != nil {
|
||||
return modifyPackResponse{Err: err}, nil
|
||||
}
|
||||
|
||||
resp, err := packResponseForPack(ctx, svc, *pack)
|
||||
if err != nil {
|
||||
return modifyPackResponse{Err: err}, nil
|
||||
}
|
||||
|
||||
return modifyPackResponse{
|
||||
Pack: *resp,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Delete Pack
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -48,8 +48,6 @@ type KolideEndpoints struct {
|
|||
CreateDistributedQueryCampaign endpoint.Endpoint
|
||||
GetPack endpoint.Endpoint
|
||||
ListPacks endpoint.Endpoint
|
||||
CreatePack endpoint.Endpoint
|
||||
ModifyPack endpoint.Endpoint
|
||||
DeletePack endpoint.Endpoint
|
||||
GetScheduledQueriesInPack endpoint.Endpoint
|
||||
EnrollAgent endpoint.Endpoint
|
||||
|
|
@ -59,9 +57,7 @@ type KolideEndpoints struct {
|
|||
SubmitLogs endpoint.Endpoint
|
||||
GetLabel endpoint.Endpoint
|
||||
ListLabels endpoint.Endpoint
|
||||
CreateLabel endpoint.Endpoint
|
||||
DeleteLabel endpoint.Endpoint
|
||||
ModifyLabel endpoint.Endpoint
|
||||
ListDecorators endpoint.Endpoint
|
||||
NewDecorator endpoint.Endpoint
|
||||
ModifyDecorator endpoint.Endpoint
|
||||
|
|
@ -132,8 +128,6 @@ func MakeKolideServerEndpoints(svc kolide.Service, jwtKey string) KolideEndpoint
|
|||
CreateDistributedQueryCampaign: authenticatedUser(jwtKey, svc, makeCreateDistributedQueryCampaignEndpoint(svc)),
|
||||
GetPack: authenticatedUser(jwtKey, svc, makeGetPackEndpoint(svc)),
|
||||
ListPacks: authenticatedUser(jwtKey, svc, makeListPacksEndpoint(svc)),
|
||||
CreatePack: authenticatedUser(jwtKey, svc, makeCreatePackEndpoint(svc)),
|
||||
ModifyPack: authenticatedUser(jwtKey, svc, makeModifyPackEndpoint(svc)),
|
||||
DeletePack: authenticatedUser(jwtKey, svc, makeDeletePackEndpoint(svc)),
|
||||
GetScheduledQueriesInPack: authenticatedUser(jwtKey, svc, makeGetScheduledQueriesInPackEndpoint(svc)),
|
||||
GetHost: authenticatedUser(jwtKey, svc, makeGetHostEndpoint(svc)),
|
||||
|
|
@ -142,9 +136,7 @@ func MakeKolideServerEndpoints(svc kolide.Service, jwtKey string) KolideEndpoint
|
|||
DeleteHost: authenticatedUser(jwtKey, svc, makeDeleteHostEndpoint(svc)),
|
||||
GetLabel: authenticatedUser(jwtKey, svc, makeGetLabelEndpoint(svc)),
|
||||
ListLabels: authenticatedUser(jwtKey, svc, makeListLabelsEndpoint(svc)),
|
||||
CreateLabel: authenticatedUser(jwtKey, svc, makeCreateLabelEndpoint(svc)),
|
||||
DeleteLabel: authenticatedUser(jwtKey, svc, makeDeleteLabelEndpoint(svc)),
|
||||
ModifyLabel: authenticatedUser(jwtKey, svc, makeModifyLabelEndpoint(svc)),
|
||||
ListDecorators: authenticatedUser(jwtKey, svc, makeListDecoratorsEndpoint(svc)),
|
||||
NewDecorator: authenticatedUser(jwtKey, svc, makeNewDecoratorEndpoint(svc)),
|
||||
ModifyDecorator: authenticatedUser(jwtKey, svc, makeModifyDecoratorEndpoint(svc)),
|
||||
|
|
@ -201,8 +193,6 @@ type kolideHandlers struct {
|
|||
CreateDistributedQueryCampaign http.Handler
|
||||
GetPack http.Handler
|
||||
ListPacks http.Handler
|
||||
CreatePack http.Handler
|
||||
ModifyPack http.Handler
|
||||
DeletePack http.Handler
|
||||
GetScheduledQueriesInPack http.Handler
|
||||
EnrollAgent http.Handler
|
||||
|
|
@ -212,9 +202,7 @@ type kolideHandlers struct {
|
|||
SubmitLogs http.Handler
|
||||
GetLabel http.Handler
|
||||
ListLabels http.Handler
|
||||
CreateLabel http.Handler
|
||||
DeleteLabel http.Handler
|
||||
ModifyLabel http.Handler
|
||||
ListDecorators http.Handler
|
||||
NewDecorator http.Handler
|
||||
ModifyDecorator http.Handler
|
||||
|
|
@ -274,8 +262,6 @@ func makeKolideKitHandlers(e KolideEndpoints, opts []kithttp.ServerOption) *koli
|
|||
CreateDistributedQueryCampaign: newServer(e.CreateDistributedQueryCampaign, decodeCreateDistributedQueryCampaignRequest),
|
||||
GetPack: newServer(e.GetPack, decodeGetPackRequest),
|
||||
ListPacks: newServer(e.ListPacks, decodeListPacksRequest),
|
||||
CreatePack: newServer(e.CreatePack, decodeCreatePackRequest),
|
||||
ModifyPack: newServer(e.ModifyPack, decodeModifyPackRequest),
|
||||
DeletePack: newServer(e.DeletePack, decodeDeletePackRequest),
|
||||
GetScheduledQueriesInPack: newServer(e.GetScheduledQueriesInPack, decodeGetScheduledQueriesInPackRequest),
|
||||
EnrollAgent: newServer(e.EnrollAgent, decodeEnrollAgentRequest),
|
||||
|
|
@ -285,9 +271,7 @@ func makeKolideKitHandlers(e KolideEndpoints, opts []kithttp.ServerOption) *koli
|
|||
SubmitLogs: newServer(e.SubmitLogs, decodeSubmitLogsRequest),
|
||||
GetLabel: newServer(e.GetLabel, decodeGetLabelRequest),
|
||||
ListLabels: newServer(e.ListLabels, decodeListLabelsRequest),
|
||||
CreateLabel: newServer(e.CreateLabel, decodeCreateLabelRequest),
|
||||
DeleteLabel: newServer(e.DeleteLabel, decodeDeleteLabelRequest),
|
||||
ModifyLabel: newServer(e.ModifyLabel, decodeModifyLabelRequest),
|
||||
ListDecorators: newServer(e.ListDecorators, decodeNoParamsRequest),
|
||||
NewDecorator: newServer(e.NewDecorator, decodeNewDecoratorRequest),
|
||||
ModifyDecorator: newServer(e.ModifyDecorator, decodeModifyDecoratorRequest),
|
||||
|
|
@ -392,15 +376,11 @@ func attachKolideAPIRoutes(r *mux.Router, h *kolideHandlers) {
|
|||
|
||||
r.Handle("/api/v1/kolide/packs/{id}", h.GetPack).Methods("GET").Name("get_pack")
|
||||
r.Handle("/api/v1/kolide/packs", h.ListPacks).Methods("GET").Name("list_packs")
|
||||
r.Handle("/api/v1/kolide/packs", h.CreatePack).Methods("POST").Name("create_pack")
|
||||
r.Handle("/api/v1/kolide/packs/{id}", h.ModifyPack).Methods("PATCH").Name("modify_pack")
|
||||
r.Handle("/api/v1/kolide/packs/{id}", h.DeletePack).Methods("DELETE").Name("delete_pack")
|
||||
r.Handle("/api/v1/kolide/packs/{id}/scheduled", h.GetScheduledQueriesInPack).Methods("GET").Name("get_scheduled_queries_in_pack")
|
||||
r.Handle("/api/v1/kolide/labels/{id}", h.GetLabel).Methods("GET").Name("get_label")
|
||||
r.Handle("/api/v1/kolide/labels", h.ListLabels).Methods("GET").Name("list_labels")
|
||||
r.Handle("/api/v1/kolide/labels", h.CreateLabel).Methods("POST").Name("create_label")
|
||||
r.Handle("/api/v1/kolide/labels/{id}", h.DeleteLabel).Methods("DELETE").Name("delete_label")
|
||||
r.Handle("/api/v1/kolide/labels/{id}", h.ModifyLabel).Methods("PATCH").Name("modify_label")
|
||||
|
||||
r.Handle("/api/v1/kolide/decorators", h.ListDecorators).Methods("GET").Name("list_decorators")
|
||||
r.Handle("/api/v1/kolide/decorators", h.NewDecorator).Methods("POST").Name("create_decorator")
|
||||
|
|
|
|||
|
|
@ -7,24 +7,6 @@ import (
|
|||
"github.com/kolide/fleet/server/kolide"
|
||||
)
|
||||
|
||||
func (mw loggingMiddleware) ModifyLabel(ctx context.Context, id uint, p kolide.ModifyLabelPayload) (*kolide.Label, error) {
|
||||
var (
|
||||
label *kolide.Label
|
||||
err error
|
||||
)
|
||||
|
||||
defer func(begin time.Time) {
|
||||
mw.logger.Log(
|
||||
"method", "ModifyLabel",
|
||||
"err", err,
|
||||
"took", time.Since(begin),
|
||||
)
|
||||
}(time.Now())
|
||||
|
||||
label, err = mw.Service.ModifyLabel(ctx, id, p)
|
||||
return label, err
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) ListLabels(ctx context.Context, opt kolide.ListOptions) ([]*kolide.Label, error) {
|
||||
var (
|
||||
labels []*kolide.Label
|
||||
|
|
@ -61,24 +43,6 @@ func (mw loggingMiddleware) GetLabel(ctx context.Context, id uint) (*kolide.Labe
|
|||
return label, err
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) NewLabel(ctx context.Context, p kolide.LabelPayload) (*kolide.Label, error) {
|
||||
var (
|
||||
label *kolide.Label
|
||||
err error
|
||||
)
|
||||
|
||||
defer func(begin time.Time) {
|
||||
_ = mw.logger.Log(
|
||||
"method", "NewLabel",
|
||||
"err", err,
|
||||
"took", time.Since(begin),
|
||||
)
|
||||
}(time.Now())
|
||||
|
||||
label, err = mw.Service.NewLabel(ctx, p)
|
||||
return label, err
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) DeleteLabel(ctx context.Context, id uint) error {
|
||||
var (
|
||||
err error
|
||||
|
|
|
|||
|
|
@ -43,42 +43,6 @@ func (mw loggingMiddleware) GetPack(ctx context.Context, id uint) (*kolide.Pack,
|
|||
return pack, err
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) NewPack(ctx context.Context, p kolide.PackPayload) (*kolide.Pack, error) {
|
||||
var (
|
||||
pack *kolide.Pack
|
||||
err error
|
||||
)
|
||||
|
||||
defer func(begin time.Time) {
|
||||
_ = mw.logger.Log(
|
||||
"method", "NewPack",
|
||||
"err", err,
|
||||
"took", time.Since(begin),
|
||||
)
|
||||
}(time.Now())
|
||||
|
||||
pack, err = mw.Service.NewPack(ctx, p)
|
||||
return pack, err
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) ModifyPack(ctx context.Context, id uint, p kolide.PackPayload) (*kolide.Pack, error) {
|
||||
var (
|
||||
pack *kolide.Pack
|
||||
err error
|
||||
)
|
||||
|
||||
defer func(begin time.Time) {
|
||||
_ = mw.logger.Log(
|
||||
"method", "ModifyPack",
|
||||
"err", err,
|
||||
"took", time.Since(begin),
|
||||
)
|
||||
}(time.Now())
|
||||
|
||||
pack, err = mw.Service.ModifyPack(ctx, id, p)
|
||||
return pack, err
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) DeletePack(ctx context.Context, id uint) error {
|
||||
var (
|
||||
err error
|
||||
|
|
@ -96,40 +60,6 @@ func (mw loggingMiddleware) DeletePack(ctx context.Context, id uint) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) AddLabelToPack(ctx context.Context, lid uint, pid uint) error {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
|
||||
defer func(begin time.Time) {
|
||||
_ = mw.logger.Log(
|
||||
"method", "AddLabelToPack",
|
||||
"err", err,
|
||||
"took", time.Since(begin),
|
||||
)
|
||||
}(time.Now())
|
||||
|
||||
err = mw.Service.AddLabelToPack(ctx, lid, pid)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) RemoveLabelFromPack(ctx context.Context, lid uint, pid uint) error {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
|
||||
defer func(begin time.Time) {
|
||||
_ = mw.logger.Log(
|
||||
"method", "RemoveLabelFromPack",
|
||||
"err", err,
|
||||
"took", time.Since(begin),
|
||||
)
|
||||
}(time.Now())
|
||||
|
||||
err = mw.Service.RemoveLabelFromPack(ctx, lid, pid)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) ListLabelsForPack(ctx context.Context, pid uint) ([]*kolide.Label, error) {
|
||||
var (
|
||||
labels []*kolide.Label
|
||||
|
|
@ -148,40 +78,6 @@ func (mw loggingMiddleware) ListLabelsForPack(ctx context.Context, pid uint) ([]
|
|||
return labels, err
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) AddHostToPack(ctx context.Context, hid uint, pid uint) error {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
|
||||
defer func(begin time.Time) {
|
||||
_ = mw.logger.Log(
|
||||
"method", "AddHostToPack",
|
||||
"err", err,
|
||||
"took", time.Since(begin),
|
||||
)
|
||||
}(time.Now())
|
||||
|
||||
err = mw.Service.AddHostToPack(ctx, hid, pid)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) RemoveHostFromPack(ctx context.Context, hid uint, pid uint) error {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
|
||||
defer func(begin time.Time) {
|
||||
_ = mw.logger.Log(
|
||||
"method", "RemoveHostFromPack",
|
||||
"err", err,
|
||||
"took", time.Since(begin),
|
||||
)
|
||||
}(time.Now())
|
||||
|
||||
err = mw.Service.RemoveHostFromPack(ctx, hid, pid)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) ListPacksForHost(ctx context.Context, hid uint) ([]*kolide.Pack, error) {
|
||||
var (
|
||||
packs []*kolide.Pack
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/kolide/fleet/server/kolide"
|
||||
)
|
||||
|
||||
func (mw metricsMiddleware) ModifyLabel(ctx context.Context, id uint, p kolide.ModifyLabelPayload) (*kolide.Label, error) {
|
||||
var (
|
||||
lic *kolide.Label
|
||||
err error
|
||||
)
|
||||
defer func(begin time.Time) {
|
||||
lvs := []string{"method", "ModifyLabel", "error", fmt.Sprint(err != nil)}
|
||||
mw.requestCount.With(lvs...).Add(1)
|
||||
mw.requestLatency.With(lvs...).Observe(time.Since(begin).Seconds())
|
||||
}(time.Now())
|
||||
lic, err = mw.Service.ModifyLabel(ctx, id, p)
|
||||
return lic, err
|
||||
|
||||
}
|
||||
|
|
@ -6,6 +6,14 @@ import (
|
|||
"github.com/kolide/fleet/server/kolide"
|
||||
)
|
||||
|
||||
func (svc service) ApplyLabelSpecs(ctx context.Context, specs []*kolide.LabelSpec) error {
|
||||
return svc.ds.ApplyLabelSpecs(specs)
|
||||
}
|
||||
|
||||
func (svc service) GetLabelSpecs(ctx context.Context) ([]*kolide.LabelSpec, error) {
|
||||
return svc.ds.GetLabelSpecs()
|
||||
}
|
||||
|
||||
func (svc service) ListLabels(ctx context.Context, opt kolide.ListOptions) ([]*kolide.Label, error) {
|
||||
return svc.ds.ListLabels(opt)
|
||||
}
|
||||
|
|
@ -14,34 +22,6 @@ func (svc service) GetLabel(ctx context.Context, id uint) (*kolide.Label, error)
|
|||
return svc.ds.Label(id)
|
||||
}
|
||||
|
||||
func (svc service) NewLabel(ctx context.Context, p kolide.LabelPayload) (*kolide.Label, error) {
|
||||
label := &kolide.Label{}
|
||||
|
||||
if p.Name == nil {
|
||||
return nil, newInvalidArgumentError("name", "missing required argument")
|
||||
}
|
||||
label.Name = *p.Name
|
||||
|
||||
if p.Query == nil {
|
||||
return nil, newInvalidArgumentError("query", "missing required argument")
|
||||
}
|
||||
label.Query = *p.Query
|
||||
|
||||
if p.Platform != nil {
|
||||
label.Platform = *p.Platform
|
||||
}
|
||||
|
||||
if p.Description != nil {
|
||||
label.Description = *p.Description
|
||||
}
|
||||
|
||||
label, err := svc.ds.NewLabel(label)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return label, nil
|
||||
}
|
||||
|
||||
func (svc service) DeleteLabel(ctx context.Context, id uint) error {
|
||||
return svc.ds.DeleteLabel(id)
|
||||
}
|
||||
|
|
@ -57,17 +37,3 @@ func (svc service) HostIDsForLabel(lid uint) ([]uint, error) {
|
|||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
func (svc service) ModifyLabel(ctx context.Context, id uint, payload kolide.ModifyLabelPayload) (*kolide.Label, error) {
|
||||
label, err := svc.ds.Label(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if payload.Name != nil {
|
||||
label.Name = *payload.Name
|
||||
}
|
||||
if payload.Description != nil {
|
||||
label.Description = *payload.Description
|
||||
}
|
||||
return svc.ds.SaveLabel(label)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,62 +7,9 @@ import (
|
|||
"github.com/kolide/fleet/server/config"
|
||||
"github.com/kolide/fleet/server/datastore/inmem"
|
||||
"github.com/kolide/fleet/server/kolide"
|
||||
"github.com/kolide/fleet/server/mock"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestModifyLabel(t *testing.T) {
|
||||
ds := new(mock.Store)
|
||||
ds.LabelFunc = func(id uint) (*kolide.Label, error) {
|
||||
l := &kolide.Label{
|
||||
ID: id,
|
||||
Name: "name",
|
||||
Description: "desc",
|
||||
}
|
||||
return l, nil
|
||||
}
|
||||
ds.SaveLabelFunc = func(l *kolide.Label) (*kolide.Label, error) {
|
||||
return l, nil
|
||||
}
|
||||
svc, err := newTestService(ds, nil)
|
||||
require.Nil(t, err)
|
||||
lp := kolide.ModifyLabelPayload{
|
||||
Name: stringPtr("new name"),
|
||||
Description: stringPtr("new desc"),
|
||||
}
|
||||
l, err := svc.ModifyLabel(context.Background(), uint(1), lp)
|
||||
assert.Equal(t, "new name", l.Name)
|
||||
assert.Equal(t, "new desc", l.Description)
|
||||
assert.True(t, ds.LabelFuncInvoked)
|
||||
assert.True(t, ds.SaveLabelFuncInvoked)
|
||||
}
|
||||
|
||||
func TestListLabels(t *testing.T) {
|
||||
ds, err := inmem.New(config.TestConfig())
|
||||
assert.Nil(t, err)
|
||||
|
||||
svc, err := newTestService(ds, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
labels, err := svc.ListLabels(ctx, kolide.ListOptions{})
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, labels, 0)
|
||||
|
||||
_, err = ds.NewLabel(&kolide.Label{
|
||||
Name: "foo",
|
||||
Query: "select * from foo;",
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
|
||||
labels, err = svc.ListLabels(ctx, kolide.ListOptions{})
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, labels, 1)
|
||||
assert.Equal(t, "foo", labels[0].Name)
|
||||
}
|
||||
|
||||
func TestGetLabel(t *testing.T) {
|
||||
ds, err := inmem.New(config.TestConfig())
|
||||
assert.Nil(t, err)
|
||||
|
|
@ -85,31 +32,6 @@ func TestGetLabel(t *testing.T) {
|
|||
assert.Equal(t, label.ID, labelVerify.ID)
|
||||
}
|
||||
|
||||
func TestNewLabel(t *testing.T) {
|
||||
ds, err := inmem.New(config.TestConfig())
|
||||
assert.Nil(t, err)
|
||||
|
||||
svc, err := newTestService(ds, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
name := "foo"
|
||||
query := "select * from foo;"
|
||||
label, err := svc.NewLabel(ctx, kolide.LabelPayload{
|
||||
Name: &name,
|
||||
Query: &query,
|
||||
})
|
||||
assert.NotZero(t, label.ID)
|
||||
|
||||
assert.Nil(t, err)
|
||||
|
||||
labels, err := ds.ListLabels(kolide.ListOptions{})
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, labels, 1)
|
||||
assert.Equal(t, "foo", labels[0].Name)
|
||||
}
|
||||
|
||||
func TestDeleteLabel(t *testing.T) {
|
||||
ds, err := inmem.New(config.TestConfig())
|
||||
assert.Nil(t, err)
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ func (svc service) GetClientConfig(ctx context.Context) (map[string]interface{},
|
|||
config["decorators"] = json.RawMessage(decJSON)
|
||||
}
|
||||
|
||||
packs, err := svc.ListPacksForHost(ctx, host.ID)
|
||||
packs, err := svc.ds.ListPacksForHost(host.ID)
|
||||
if err != nil {
|
||||
return nil, osqueryError{message: "database error: " + err.Error()}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -219,19 +219,33 @@ func TestHostDetailQueries(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestGetDistributedQueriesMissingHost(t *testing.T) {
|
||||
svc, err := newTestService(&mock.Store{}, nil)
|
||||
require.Nil(t, err)
|
||||
|
||||
_, _, err = svc.GetDistributedQueries(context.Background())
|
||||
require.NotNil(t, err)
|
||||
assert.Contains(t, err.Error(), "missing host")
|
||||
}
|
||||
|
||||
func TestLabelQueries(t *testing.T) {
|
||||
ds, svc, mockClock := setupOsqueryTests(t)
|
||||
ctx := context.Background()
|
||||
|
||||
_, err := svc.EnrollAgent(ctx, "", "host123")
|
||||
mockClock := clock.NewMockClock()
|
||||
ds := new(mock.Store)
|
||||
svc, err := newTestServiceWithClock(ds, nil, mockClock)
|
||||
require.Nil(t, err)
|
||||
|
||||
hosts, err := ds.ListHosts(kolide.ListOptions{})
|
||||
require.Nil(t, err)
|
||||
require.Len(t, hosts, 1)
|
||||
host := hosts[0]
|
||||
ds.LabelQueriesForHostFunc = func(host *kolide.Host, cutoff time.Time) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
}
|
||||
ds.DistributedQueriesForHostFunc = func(host *kolide.Host) (map[uint]string, error) {
|
||||
return map[uint]string{}, nil
|
||||
}
|
||||
ds.SaveHostFunc = func(host *kolide.Host) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
ctx = hostctx.NewContext(ctx, *host)
|
||||
host := &kolide.Host{}
|
||||
ctx := hostctx.NewContext(context.Background(), *host)
|
||||
|
||||
// With a new host, we should get the detail queries (and accelerate
|
||||
// should be turned on so that we can quickly fill labels)
|
||||
|
|
@ -244,7 +258,6 @@ func TestLabelQueries(t *testing.T) {
|
|||
host.DetailUpdateTime = mockClock.Now().Add(-1 * time.Minute)
|
||||
host.Platform = "darwin"
|
||||
host.HostName = "zwass.local"
|
||||
ds.SaveHost(host)
|
||||
ctx = hostctx.NewContext(ctx, *host)
|
||||
|
||||
queries, acc, err = svc.GetDistributedQueries(ctx)
|
||||
|
|
@ -252,32 +265,12 @@ func TestLabelQueries(t *testing.T) {
|
|||
assert.Len(t, queries, 0)
|
||||
assert.Zero(t, acc)
|
||||
|
||||
labels := []kolide.Label{
|
||||
kolide.Label{
|
||||
Name: "label1",
|
||||
Query: "query1",
|
||||
Platform: "darwin",
|
||||
},
|
||||
kolide.Label{
|
||||
Name: "label2",
|
||||
Query: "query2",
|
||||
Platform: "darwin",
|
||||
},
|
||||
kolide.Label{
|
||||
Name: "label3",
|
||||
Query: "query3",
|
||||
Platform: "darwin,linux",
|
||||
},
|
||||
kolide.Label{
|
||||
Name: "label4",
|
||||
Query: "query4",
|
||||
Platform: "linux",
|
||||
},
|
||||
}
|
||||
|
||||
for _, label := range labels {
|
||||
_, err := ds.NewLabel(&label)
|
||||
assert.Nil(t, err)
|
||||
ds.LabelQueriesForHostFunc = func(host *kolide.Host, cutoff time.Time) (map[string]string, error) {
|
||||
return map[string]string{
|
||||
"label1": "query1",
|
||||
"label2": "query2",
|
||||
"label3": "query3",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Now we should get the label queries
|
||||
|
|
@ -286,6 +279,16 @@ func TestLabelQueries(t *testing.T) {
|
|||
assert.Len(t, queries, 3)
|
||||
assert.Zero(t, acc)
|
||||
|
||||
var gotHost *kolide.Host
|
||||
var gotResults map[uint]bool
|
||||
var gotTime time.Time
|
||||
ds.RecordLabelQueryExecutionsFunc = func(host *kolide.Host, results map[uint]bool, t time.Time) error {
|
||||
gotHost = host
|
||||
gotResults = results
|
||||
gotTime = t
|
||||
return nil
|
||||
}
|
||||
|
||||
// Record a query execution
|
||||
err = svc.SubmitDistributedQueryResults(
|
||||
ctx,
|
||||
|
|
@ -295,32 +298,13 @@ func TestLabelQueries(t *testing.T) {
|
|||
map[string]string{},
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, host, gotHost)
|
||||
assert.Equal(t, mockClock.Now(), gotTime)
|
||||
if assert.Len(t, gotResults, 1) {
|
||||
assert.Equal(t, true, gotResults[1])
|
||||
}
|
||||
|
||||
// Verify that labels are set appropriately
|
||||
hostLabels, err := ds.ListLabelsForHost(host.ID)
|
||||
assert.Len(t, hostLabels, 1)
|
||||
assert.Equal(t, "label1", hostLabels[0].Name)
|
||||
|
||||
// Now that query should not be returned
|
||||
queries, acc, err = svc.GetDistributedQueries(ctx)
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, queries, 2)
|
||||
assert.NotContains(t, queries, "kolide_label_query_1")
|
||||
assert.Zero(t, acc)
|
||||
|
||||
// Advance the time
|
||||
mockClock.AddTime(1*time.Hour + 1*time.Minute)
|
||||
|
||||
// Keep the host details fresh
|
||||
host.DetailUpdateTime = mockClock.Now().Add(-1 * time.Minute)
|
||||
ds.SaveHost(host)
|
||||
ctx = hostctx.NewContext(ctx, *host)
|
||||
|
||||
// Now we should get all the label queries again
|
||||
queries, acc, err = svc.GetDistributedQueries(ctx)
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, queries, 3)
|
||||
assert.Zero(t, acc)
|
||||
mockClock.AddTime(1 * time.Second)
|
||||
|
||||
// Record a query execution
|
||||
err = svc.SubmitDistributedQueryResults(
|
||||
|
|
@ -332,20 +316,11 @@ func TestLabelQueries(t *testing.T) {
|
|||
map[string]string{},
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Now these should no longer show up in the necessary to run queries
|
||||
queries, acc, err = svc.GetDistributedQueries(ctx)
|
||||
assert.Nil(t, err)
|
||||
assert.Len(t, queries, 1)
|
||||
assert.Zero(t, acc)
|
||||
|
||||
// Verify that labels are set appropriately
|
||||
hostLabels, err = ds.ListLabelsForHost(host.ID)
|
||||
assert.Len(t, hostLabels, 2)
|
||||
expectLabelNames := map[string]bool{"label1": true, "label2": true}
|
||||
for _, label := range hostLabels {
|
||||
assert.Contains(t, expectLabelNames, label.Name)
|
||||
delete(expectLabelNames, label.Name)
|
||||
assert.Equal(t, host, gotHost)
|
||||
assert.Equal(t, mockClock.Now(), gotTime)
|
||||
if assert.Len(t, gotResults, 2) {
|
||||
assert.Equal(t, true, gotResults[2])
|
||||
assert.Equal(t, false, gotResults[3])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -354,32 +329,9 @@ func TestGetClientConfig(t *testing.T) {
|
|||
ds.ListDecoratorsFunc = func(opt ...kolide.OptionalArg) ([]*kolide.Decorator, error) {
|
||||
return []*kolide.Decorator{}, nil
|
||||
}
|
||||
ds.ListPacksFunc = func(opt kolide.ListOptions) ([]*kolide.Pack, error) {
|
||||
ds.ListPacksForHostFunc = func(hid uint) ([]*kolide.Pack, error) {
|
||||
return []*kolide.Pack{}, nil
|
||||
}
|
||||
ds.ListLabelsForHostFunc = func(hid uint) ([]kolide.Label, error) {
|
||||
return []kolide.Label{
|
||||
{ID: 1, Name: "foo_label"},
|
||||
}, nil
|
||||
}
|
||||
ds.ListLabelsForPackFunc = func(pid uint) ([]*kolide.Label, error) {
|
||||
switch pid {
|
||||
case 1, 2:
|
||||
return []*kolide.Label{
|
||||
{ID: 1, Name: "foo_label"},
|
||||
}, nil
|
||||
default:
|
||||
return []*kolide.Label{}, nil
|
||||
}
|
||||
}
|
||||
ds.ListExplicitHostsInPackFunc = func(pid uint, opt kolide.ListOptions) ([]uint, error) {
|
||||
switch pid {
|
||||
case 4:
|
||||
return []uint{1}, nil
|
||||
default:
|
||||
return []uint{}, nil
|
||||
}
|
||||
}
|
||||
ds.ListScheduledQueriesInPackFunc = func(pid uint, opt kolide.ListOptions) ([]*kolide.ScheduledQuery, error) {
|
||||
tru := true
|
||||
fals := false
|
||||
|
|
@ -411,7 +363,8 @@ func TestGetClientConfig(t *testing.T) {
|
|||
svc, err := newTestService(ds, nil)
|
||||
require.Nil(t, err)
|
||||
|
||||
ctx := hostctx.NewContext(context.Background(), kolide.Host{ID: 1})
|
||||
ctx1 := hostctx.NewContext(context.Background(), kolide.Host{ID: 1})
|
||||
ctx2 := hostctx.NewContext(context.Background(), kolide.Host{ID: 2})
|
||||
|
||||
expectedOptions := map[string]interface{}{
|
||||
"distributed_interval": float64(11),
|
||||
|
|
@ -419,25 +372,36 @@ func TestGetClientConfig(t *testing.T) {
|
|||
}
|
||||
|
||||
// No packs loaded yet
|
||||
conf, err := svc.GetClientConfig(ctx)
|
||||
conf, err := svc.GetClientConfig(ctx1)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, map[string]interface{}{"options": expectedOptions}, conf)
|
||||
|
||||
conf, err = svc.GetClientConfig(ctx2)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, map[string]interface{}{"options": expectedOptions}, conf)
|
||||
|
||||
// Now add packs
|
||||
ds.ListPacksFunc = func(opt kolide.ListOptions) ([]*kolide.Pack, error) {
|
||||
return []*kolide.Pack{
|
||||
{ID: 1, Name: "pack_by_label"},
|
||||
{ID: 2, Name: "disabled_pack", Disabled: true},
|
||||
{ID: 3, Name: "not_matching_pack"},
|
||||
{ID: 4, Name: "pack_by_explicit_host"},
|
||||
}, nil
|
||||
ds.ListPacksForHostFunc = func(hid uint) ([]*kolide.Pack, error) {
|
||||
switch hid {
|
||||
case 1:
|
||||
return []*kolide.Pack{
|
||||
{ID: 1, Name: "pack_by_label"},
|
||||
{ID: 4, Name: "pack_by_other_label"},
|
||||
}, nil
|
||||
|
||||
case 2:
|
||||
return []*kolide.Pack{
|
||||
{ID: 1, Name: "pack_by_label"},
|
||||
}, nil
|
||||
}
|
||||
return []*kolide.Pack{}, nil
|
||||
}
|
||||
|
||||
conf, err = svc.GetClientConfig(ctx)
|
||||
conf, err = svc.GetClientConfig(ctx1)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, expectedOptions, conf["options"])
|
||||
assert.JSONEq(t, `{
|
||||
"pack_by_explicit_host": {
|
||||
"pack_by_other_label": {
|
||||
"queries": {
|
||||
"foobar":{"query":"select 3","interval":20,"shard":42},
|
||||
"froobing":{"query":"select 'guacamole'","interval":60,"snapshot":true}
|
||||
|
|
@ -451,6 +415,19 @@ func TestGetClientConfig(t *testing.T) {
|
|||
}`,
|
||||
string(conf["packs"].(json.RawMessage)),
|
||||
)
|
||||
|
||||
conf, err = svc.GetClientConfig(ctx2)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, expectedOptions, conf["options"])
|
||||
assert.JSONEq(t, `{
|
||||
"pack_by_label": {
|
||||
"queries":{
|
||||
"time":{"query":"select * from time","interval":30,"removed":false}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
string(conf["packs"].(json.RawMessage)),
|
||||
)
|
||||
}
|
||||
|
||||
func TestDetailQueriesWithEmptyStrings(t *testing.T) {
|
||||
|
|
@ -785,71 +762,97 @@ func TestDetailQueries(t *testing.T) {
|
|||
assert.Zero(t, acc)
|
||||
}
|
||||
|
||||
func TestDistributedQueries(t *testing.T) {
|
||||
ds, err := inmem.New(config.TestConfig())
|
||||
require.Nil(t, err)
|
||||
|
||||
_, err = ds.NewAppConfig(&kolide.AppConfig{EnrollSecret: ""})
|
||||
require.Nil(t, err)
|
||||
|
||||
func TestNewDistributedQueryCampaign(t *testing.T) {
|
||||
mockClock := clock.NewMockClock()
|
||||
|
||||
rs := pubsub.NewInmemQueryResults()
|
||||
|
||||
svc, err := newTestServiceWithClock(ds, rs, mockClock)
|
||||
ds := new(mock.Store)
|
||||
svc, err := newTestServiceWithClock(ds, nil, mockClock)
|
||||
require.Nil(t, err)
|
||||
|
||||
ctx := context.Background()
|
||||
ds.LabelQueriesForHostFunc = func(host *kolide.Host, cutoff time.Time) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
}
|
||||
ds.DistributedQueriesForHostFunc = func(host *kolide.Host) (map[uint]string, error) {
|
||||
return map[uint]string{}, nil
|
||||
}
|
||||
ds.SaveHostFunc = func(host *kolide.Host) error {
|
||||
return nil
|
||||
}
|
||||
var gotQuery *kolide.Query
|
||||
ds.NewQueryFunc = func(query *kolide.Query, opts ...kolide.OptionalArg) (*kolide.Query, error) {
|
||||
gotQuery = query
|
||||
query.ID = 42
|
||||
return query, nil
|
||||
}
|
||||
var gotCampaign *kolide.DistributedQueryCampaign
|
||||
ds.NewDistributedQueryCampaignFunc = func(camp *kolide.DistributedQueryCampaign) (*kolide.DistributedQueryCampaign, error) {
|
||||
gotCampaign = camp
|
||||
camp.ID = 21
|
||||
return camp, nil
|
||||
}
|
||||
var gotTargets []*kolide.DistributedQueryCampaignTarget
|
||||
ds.NewDistributedQueryCampaignTargetFunc = func(target *kolide.DistributedQueryCampaignTarget) (*kolide.DistributedQueryCampaignTarget, error) {
|
||||
gotTargets = append(gotTargets, target)
|
||||
return target, nil
|
||||
}
|
||||
|
||||
nodeKey, err := svc.EnrollAgent(ctx, "", "host123")
|
||||
require.Nil(t, err)
|
||||
|
||||
host, err := ds.AuthenticateHost(nodeKey)
|
||||
require.Nil(t, err)
|
||||
|
||||
host.Platform = "centos"
|
||||
host.HostName = "zwass.local"
|
||||
require.Nil(t, ds.SaveHost(host))
|
||||
|
||||
// Create label
|
||||
n := "foo"
|
||||
q := "select * from foo;"
|
||||
label, err := svc.NewLabel(ctx, kolide.LabelPayload{
|
||||
Name: &n,
|
||||
Query: &q,
|
||||
})
|
||||
require.Nil(t, err)
|
||||
|
||||
// Record match with label
|
||||
ctx = viewer.NewContext(ctx, viewer.Viewer{
|
||||
viewerCtx := viewer.NewContext(context.Background(), viewer.Viewer{
|
||||
User: &kolide.User{
|
||||
ID: 0,
|
||||
},
|
||||
})
|
||||
err = ds.RecordLabelQueryExecutions(host, map[uint]bool{label.ID: true}, mockClock.Now())
|
||||
q := "select year, month, day, hour, minutes, seconds from time"
|
||||
campaign, err := svc.NewDistributedQueryCampaign(viewerCtx, q, []uint{2}, []uint{1})
|
||||
require.Nil(t, err)
|
||||
err = ds.MarkHostSeen(host, mockClock.Now())
|
||||
require.Nil(t, err)
|
||||
ctx = hostctx.NewContext(ctx, *host)
|
||||
assert.Equal(t, gotQuery.ID, gotCampaign.QueryID)
|
||||
assert.Equal(t, []*kolide.DistributedQueryCampaignTarget{
|
||||
&kolide.DistributedQueryCampaignTarget{
|
||||
Type: kolide.TargetHost,
|
||||
DistributedQueryCampaignID: campaign.ID,
|
||||
TargetID: 2,
|
||||
},
|
||||
&kolide.DistributedQueryCampaignTarget{
|
||||
Type: kolide.TargetLabel,
|
||||
DistributedQueryCampaignID: campaign.ID,
|
||||
TargetID: 1,
|
||||
},
|
||||
}, gotTargets,
|
||||
)
|
||||
}
|
||||
|
||||
q = "select year, month, day, hour, minutes, seconds from time"
|
||||
campaign, err := svc.NewDistributedQueryCampaign(ctx, q, []uint{}, []uint{label.ID})
|
||||
func TestDistributedQueryResults(t *testing.T) {
|
||||
mockClock := clock.NewMockClock()
|
||||
ds := new(mock.Store)
|
||||
rs := pubsub.NewInmemQueryResults()
|
||||
svc, err := newTestServiceWithClock(ds, rs, mockClock)
|
||||
require.Nil(t, err)
|
||||
|
||||
// Manually set the campaign to running (so that it shows up when
|
||||
// requesting queries)
|
||||
campaign.Status = kolide.QueryRunning
|
||||
err = ds.SaveDistributedQueryCampaign(campaign)
|
||||
require.Nil(t, err)
|
||||
campaign := &kolide.DistributedQueryCampaign{ID: 42}
|
||||
|
||||
queryKey := fmt.Sprintf("%s%d", hostDistributedQueryPrefix, campaign.ID)
|
||||
ds.LabelQueriesForHostFunc = func(host *kolide.Host, cutoff time.Time) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
}
|
||||
ds.SaveHostFunc = func(host *kolide.Host) error {
|
||||
return nil
|
||||
}
|
||||
ds.DistributedQueriesForHostFunc = func(host *kolide.Host) (map[uint]string, error) {
|
||||
return map[uint]string{campaign.ID: "select * from time"}, nil
|
||||
}
|
||||
var gotExecution *kolide.DistributedQueryExecution
|
||||
ds.NewDistributedQueryExecutionFunc = func(exec *kolide.DistributedQueryExecution) (*kolide.DistributedQueryExecution, error) {
|
||||
gotExecution = exec
|
||||
return exec, nil
|
||||
}
|
||||
|
||||
host := &kolide.Host{ID: 1}
|
||||
hostCtx := hostctx.NewContext(context.Background(), *host)
|
||||
|
||||
// Now we should get the active distributed query
|
||||
queries, acc, err := svc.GetDistributedQueries(ctx)
|
||||
queries, acc, err := svc.GetDistributedQueries(hostCtx)
|
||||
require.Nil(t, err)
|
||||
assert.Len(t, queries, len(detailQueries)+1)
|
||||
assert.Equal(t, q, queries[queryKey])
|
||||
assert.Zero(t, acc)
|
||||
queryKey := fmt.Sprintf("%s%d", hostDistributedQueryPrefix, campaign.ID)
|
||||
assert.Equal(t, "select * from time", queries[queryKey])
|
||||
assert.NotZero(t, acc)
|
||||
|
||||
expectedRows := []map[string]string{
|
||||
{
|
||||
|
|
@ -866,7 +869,7 @@ func TestDistributedQueries(t *testing.T) {
|
|||
}
|
||||
|
||||
// TODO use service method
|
||||
readChan, err := rs.ReadChannel(ctx, *campaign)
|
||||
readChan, err := rs.ReadChannel(context.Background(), *campaign)
|
||||
require.Nil(t, err)
|
||||
|
||||
// We need to listen for the result in a separate thread to prevent the
|
||||
|
|
@ -901,17 +904,11 @@ func TestDistributedQueries(t *testing.T) {
|
|||
// this test.
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
|
||||
err = svc.SubmitDistributedQueryResults(ctx, results, map[string]string{})
|
||||
err = svc.SubmitDistributedQueryResults(hostCtx, results, map[string]string{})
|
||||
require.Nil(t, err)
|
||||
|
||||
// Now the distributed query should be completed and not returned
|
||||
queries, acc, err = svc.GetDistributedQueries(ctx)
|
||||
require.Nil(t, err)
|
||||
assert.Len(t, queries, len(detailQueries))
|
||||
assert.NotContains(t, queries, queryKey)
|
||||
assert.Zero(t, acc)
|
||||
|
||||
waitComplete.Wait()
|
||||
assert.Equal(t, campaign.ID, gotExecution.DistributedQueryCampaignID)
|
||||
assert.Equal(t, host.ID, gotExecution.HostID)
|
||||
assert.Equal(t, kolide.ExecutionSucceeded, gotExecution.Status)
|
||||
}
|
||||
|
||||
func TestOrphanedQueryCampaign(t *testing.T) {
|
||||
|
|
@ -983,12 +980,9 @@ func TestUpdateHostIntervals(t *testing.T) {
|
|||
ds.ListDecoratorsFunc = func(opt ...kolide.OptionalArg) ([]*kolide.Decorator, error) {
|
||||
return []*kolide.Decorator{}, nil
|
||||
}
|
||||
ds.ListPacksFunc = func(opt kolide.ListOptions) ([]*kolide.Pack, error) {
|
||||
ds.ListPacksForHostFunc = func(hid uint) ([]*kolide.Pack, error) {
|
||||
return []*kolide.Pack{}, nil
|
||||
}
|
||||
ds.ListLabelsForHostFunc = func(hid uint) ([]kolide.Label, error) {
|
||||
return []kolide.Label{}, nil
|
||||
}
|
||||
|
||||
var testCases = []struct {
|
||||
initHost kolide.Host
|
||||
|
|
|
|||
|
|
@ -6,6 +6,14 @@ import (
|
|||
"github.com/kolide/fleet/server/kolide"
|
||||
)
|
||||
|
||||
func (svc service) ApplyPackSpecs(ctx context.Context, specs []*kolide.PackSpec) error {
|
||||
return svc.ds.ApplyPackSpecs(specs)
|
||||
}
|
||||
|
||||
func (svc service) GetPackSpecs(ctx context.Context) ([]*kolide.PackSpec, error) {
|
||||
return svc.ds.GetPackSpecs()
|
||||
}
|
||||
|
||||
func (svc service) ListPacks(ctx context.Context, opt kolide.ListOptions) ([]*kolide.Pack, error) {
|
||||
return svc.ds.ListPacks(opt)
|
||||
}
|
||||
|
|
@ -14,201 +22,14 @@ func (svc service) GetPack(ctx context.Context, id uint) (*kolide.Pack, error) {
|
|||
return svc.ds.Pack(id)
|
||||
}
|
||||
|
||||
func (svc service) NewPack(ctx context.Context, p kolide.PackPayload) (*kolide.Pack, error) {
|
||||
var pack kolide.Pack
|
||||
|
||||
if p.Name != nil {
|
||||
pack.Name = *p.Name
|
||||
}
|
||||
|
||||
if p.Description != nil {
|
||||
pack.Description = *p.Description
|
||||
}
|
||||
|
||||
if p.Platform != nil {
|
||||
pack.Platform = *p.Platform
|
||||
}
|
||||
|
||||
if p.Disabled != nil {
|
||||
pack.Disabled = *p.Disabled
|
||||
}
|
||||
|
||||
_, err := svc.ds.NewPack(&pack)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if p.HostIDs != nil {
|
||||
for _, hostID := range *p.HostIDs {
|
||||
err = svc.AddHostToPack(ctx, hostID, pack.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if p.LabelIDs != nil {
|
||||
for _, labelID := range *p.LabelIDs {
|
||||
err = svc.AddLabelToPack(ctx, labelID, pack.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &pack, nil
|
||||
}
|
||||
|
||||
func (svc service) ModifyPack(ctx context.Context, id uint, p kolide.PackPayload) (*kolide.Pack, error) {
|
||||
pack, err := svc.ds.Pack(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if p.Name != nil {
|
||||
pack.Name = *p.Name
|
||||
}
|
||||
|
||||
if p.Description != nil {
|
||||
pack.Description = *p.Description
|
||||
}
|
||||
|
||||
if p.Platform != nil {
|
||||
pack.Platform = *p.Platform
|
||||
}
|
||||
|
||||
if p.Disabled != nil {
|
||||
pack.Disabled = *p.Disabled
|
||||
}
|
||||
|
||||
err = svc.ds.SavePack(pack)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// we must determine what hosts are attached to this pack. then, given
|
||||
// our new set of host_ids, we will mutate the database to reflect the
|
||||
// desired state.
|
||||
if p.HostIDs != nil {
|
||||
|
||||
// first, let's retrieve the total set of hosts
|
||||
hosts, err := svc.ListHostsInPack(ctx, pack.ID, kolide.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// it will be efficient to create a data structure with constant time
|
||||
// lookups to determine whether or not a host is already added
|
||||
existingHosts := map[uint]bool{}
|
||||
for _, host := range hosts {
|
||||
existingHosts[host] = true
|
||||
}
|
||||
|
||||
// we will also make a constant time lookup map for the desired set of
|
||||
// hosts as well.
|
||||
desiredHosts := map[uint]bool{}
|
||||
for _, hostID := range *p.HostIDs {
|
||||
desiredHosts[hostID] = true
|
||||
}
|
||||
|
||||
// if the request declares a host ID but the host is not already
|
||||
// associated with the pack, we add it
|
||||
for _, hostID := range *p.HostIDs {
|
||||
if !existingHosts[hostID] {
|
||||
err = svc.AddHostToPack(ctx, hostID, pack.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if the request does not declare the ID of a host which currently
|
||||
// exists, we delete the existing relationship
|
||||
for hostID := range existingHosts {
|
||||
if !desiredHosts[hostID] {
|
||||
err = svc.RemoveHostFromPack(ctx, hostID, pack.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we must determine what labels are attached to this pack. then, given
|
||||
// our new set of label_ids, we will mutate the database to reflect the
|
||||
// desired state.
|
||||
if p.LabelIDs != nil {
|
||||
|
||||
// first, let's retrieve the total set of labels
|
||||
labels, err := svc.ListLabelsForPack(ctx, pack.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// it will be efficient to create a data structure with constant time
|
||||
// lookups to determine whether or not a label is already added
|
||||
existingLabels := map[uint]bool{}
|
||||
for _, label := range labels {
|
||||
existingLabels[label.ID] = true
|
||||
}
|
||||
|
||||
// we will also make a constant time lookup map for the desired set of
|
||||
// labels as well.
|
||||
desiredLabels := map[uint]bool{}
|
||||
for _, labelID := range *p.LabelIDs {
|
||||
desiredLabels[labelID] = true
|
||||
}
|
||||
|
||||
// if the request declares a label ID but the label is not already
|
||||
// associated with the pack, we add it
|
||||
for _, labelID := range *p.LabelIDs {
|
||||
if !existingLabels[labelID] {
|
||||
err = svc.AddLabelToPack(ctx, labelID, pack.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if the request does not declare the ID of a label which currently
|
||||
// exists, we delete the existing relationship
|
||||
for labelID := range existingLabels {
|
||||
if !desiredLabels[labelID] {
|
||||
err = svc.RemoveLabelFromPack(ctx, labelID, pack.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pack, err
|
||||
}
|
||||
|
||||
func (svc service) DeletePack(ctx context.Context, id uint) error {
|
||||
return svc.ds.DeletePack(id)
|
||||
}
|
||||
|
||||
func (svc service) AddLabelToPack(ctx context.Context, lid, pid uint) error {
|
||||
return svc.ds.AddLabelToPack(lid, pid)
|
||||
}
|
||||
|
||||
func (svc service) ListLabelsForPack(ctx context.Context, pid uint) ([]*kolide.Label, error) {
|
||||
return svc.ds.ListLabelsForPack(pid)
|
||||
}
|
||||
|
||||
func (svc service) RemoveLabelFromPack(ctx context.Context, lid, pid uint) error {
|
||||
return svc.ds.RemoveLabelFromPack(lid, pid)
|
||||
}
|
||||
|
||||
func (svc service) AddHostToPack(ctx context.Context, hid, pid uint) error {
|
||||
return svc.ds.AddHostToPack(hid, pid)
|
||||
}
|
||||
|
||||
func (svc service) RemoveHostFromPack(ctx context.Context, hid, pid uint) error {
|
||||
return svc.ds.RemoveHostFromPack(hid, pid)
|
||||
}
|
||||
|
||||
func (svc service) ListHostsInPack(ctx context.Context, pid uint, opt kolide.ListOptions) ([]uint, error) {
|
||||
return svc.ds.ListHostsInPack(pid, opt)
|
||||
}
|
||||
|
|
@ -218,65 +39,5 @@ func (svc service) ListExplicitHostsInPack(ctx context.Context, pid uint, opt ko
|
|||
}
|
||||
|
||||
func (svc service) ListPacksForHost(ctx context.Context, hid uint) ([]*kolide.Pack, error) {
|
||||
packs := []*kolide.Pack{}
|
||||
|
||||
// we will need to give some subset of packs to this host based on the
|
||||
// labels which this host is known to belong to
|
||||
allPacks, err := svc.ds.ListPacks(kolide.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// pull the labels that this host belongs to
|
||||
labels, err := svc.ds.ListLabelsForHost(hid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// in order to use o(1) array indexing in an o(n) loop vs a o(n^2) double
|
||||
// for loop iteration, we must create the array which may be indexed below
|
||||
labelIDs := map[uint]bool{}
|
||||
for _, label := range labels {
|
||||
labelIDs[label.ID] = true
|
||||
}
|
||||
|
||||
for _, pack := range allPacks {
|
||||
// don't include packs which have been disabled
|
||||
if pack.Disabled {
|
||||
continue
|
||||
}
|
||||
|
||||
// for each pack, we must know what labels have been assigned to that
|
||||
// pack
|
||||
labelsForPack, err := svc.ds.ListLabelsForPack(pack.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// o(n) iteration to determine whether or not a pack is enabled
|
||||
// in this case, n is len(labelsForPack)
|
||||
for _, label := range labelsForPack {
|
||||
if labelIDs[label.ID] {
|
||||
packs = append(packs, pack)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// for each pack, we must know what host have been assigned to that pack
|
||||
hostsForPack, err := svc.ds.ListExplicitHostsInPack(pack.ID, kolide.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// o(n) iteration to determine whether or not a pack is enabled
|
||||
// in this case, n is len(hostsForPack)
|
||||
for _, host := range hostsForPack {
|
||||
if host == hid {
|
||||
packs = append(packs, pack)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return packs, nil
|
||||
return svc.ds.ListPacksForHost(hid)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,13 +4,10 @@ import (
|
|||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/WatchBeam/clock"
|
||||
"github.com/kolide/fleet/server/config"
|
||||
"github.com/kolide/fleet/server/datastore/inmem"
|
||||
"github.com/kolide/fleet/server/kolide"
|
||||
"github.com/kolide/fleet/server/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestListPacks(t *testing.T) {
|
||||
|
|
@ -58,95 +55,6 @@ func TestGetPack(t *testing.T) {
|
|||
assert.Equal(t, pack.ID, packVerify.ID)
|
||||
}
|
||||
|
||||
func TestNewPack(t *testing.T) {
|
||||
ds, err := inmem.New(config.TestConfig())
|
||||
assert.Nil(t, err)
|
||||
|
||||
svc, err := newTestService(ds, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
labelName := "label"
|
||||
labelQuery := "select 1"
|
||||
label, err := svc.NewLabel(ctx, kolide.LabelPayload{
|
||||
Name: &labelName,
|
||||
Query: &labelQuery,
|
||||
})
|
||||
|
||||
packName := "foo"
|
||||
packLabelIDs := []uint{label.ID}
|
||||
pack, err := svc.NewPack(ctx, kolide.PackPayload{
|
||||
Name: &packName,
|
||||
LabelIDs: &packLabelIDs,
|
||||
})
|
||||
|
||||
assert.Nil(t, err)
|
||||
|
||||
packs, err := ds.ListPacks(kolide.ListOptions{})
|
||||
assert.Nil(t, err)
|
||||
require.Len(t, packs, 1)
|
||||
assert.Equal(t, pack.ID, packs[0].ID)
|
||||
|
||||
labels, err := ds.ListLabelsForPack(pack.ID)
|
||||
assert.Nil(t, err)
|
||||
require.Len(t, labels, 1)
|
||||
assert.Equal(t, label.ID, labels[0].ID)
|
||||
}
|
||||
|
||||
func TestModifyPack(t *testing.T) {
|
||||
ds, err := inmem.New(config.TestConfig())
|
||||
assert.Nil(t, err)
|
||||
|
||||
svc, err := newTestService(ds, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
label := &kolide.Label{
|
||||
Name: "label",
|
||||
Query: "select 1",
|
||||
}
|
||||
label, err = ds.NewLabel(label)
|
||||
assert.Nil(t, err)
|
||||
assert.NotZero(t, label.ID)
|
||||
|
||||
pack := &kolide.Pack{
|
||||
Name: "foo",
|
||||
}
|
||||
pack, err = ds.NewPack(pack)
|
||||
assert.Nil(t, err)
|
||||
assert.NotZero(t, pack.ID)
|
||||
|
||||
newName := "bar"
|
||||
labelIDs := []uint{label.ID}
|
||||
packVerify, err := svc.ModifyPack(ctx, pack.ID, kolide.PackPayload{
|
||||
Name: &newName,
|
||||
LabelIDs: &labelIDs,
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, pack.ID, packVerify.ID)
|
||||
assert.Equal(t, "bar", packVerify.Name)
|
||||
|
||||
labels, err := ds.ListLabelsForPack(pack.ID)
|
||||
assert.Nil(t, err)
|
||||
require.Len(t, labels, 1)
|
||||
assert.Equal(t, label.ID, labels[0].ID)
|
||||
|
||||
newLabelIDs := []uint{}
|
||||
packVerify2, err := svc.ModifyPack(ctx, pack.ID, kolide.PackPayload{
|
||||
LabelIDs: &newLabelIDs,
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, pack.ID, packVerify2.ID)
|
||||
|
||||
labels, err = ds.ListLabelsForPack(pack.ID)
|
||||
assert.Nil(t, err)
|
||||
require.Len(t, labels, 0)
|
||||
}
|
||||
|
||||
func TestDeletePack(t *testing.T) {
|
||||
ds, err := inmem.New(config.TestConfig())
|
||||
assert.Nil(t, err)
|
||||
|
|
@ -170,38 +78,3 @@ func TestDeletePack(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
assert.Len(t, queries, 0)
|
||||
}
|
||||
|
||||
func TestListPacksForHost(t *testing.T) {
|
||||
ds, err := inmem.New(config.TestConfig())
|
||||
assert.Nil(t, err)
|
||||
|
||||
mockClock := clock.NewMockClock()
|
||||
|
||||
svc, err := newTestService(ds, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
h1 := test.NewHost(t, ds, "h1", "10.10.10.1", "1", "1", mockClock.Now())
|
||||
h2 := test.NewHost(t, ds, "h2", "10.10.10.2", "2", "2", mockClock.Now())
|
||||
|
||||
p1 := test.NewPack(t, ds, "p1")
|
||||
p2 := test.NewPack(t, ds, "p2")
|
||||
|
||||
require.Nil(t, svc.AddHostToPack(ctx, h1.ID, p1.ID))
|
||||
require.Nil(t, svc.AddHostToPack(ctx, h2.ID, p1.ID))
|
||||
|
||||
require.Nil(t, svc.AddHostToPack(ctx, h1.ID, p2.ID))
|
||||
|
||||
{
|
||||
packs, err := svc.ListPacksForHost(ctx, h1.ID)
|
||||
require.Nil(t, err)
|
||||
require.Len(t, packs, 2)
|
||||
}
|
||||
{
|
||||
packs, err := svc.ListPacksForHost(ctx, h2.ID)
|
||||
require.Nil(t, err)
|
||||
require.Len(t, packs, 1)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,18 +2,9 @@ package service
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func decodeCreateLabelRequest(ctx context.Context, r *http.Request) (interface{}, error) {
|
||||
var req createLabelRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req.payload); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func decodeDeleteLabelRequest(ctx context.Context, r *http.Request) (interface{}, error) {
|
||||
id, err := idFromRequest(r, "id")
|
||||
if err != nil {
|
||||
|
|
@ -41,17 +32,3 @@ func decodeListLabelsRequest(ctx context.Context, r *http.Request) (interface{},
|
|||
}
|
||||
return listLabelsRequest{ListOptions: opt}, nil
|
||||
}
|
||||
|
||||
func decodeModifyLabelRequest(ctx context.Context, r *http.Request) (interface{}, error) {
|
||||
id, err := idFromRequest(r, "id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var resp modifyLabelRequest
|
||||
err = json.NewDecoder(r.Body).Decode(&resp.payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp.ID = id
|
||||
return resp, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
|
|
@ -11,31 +10,6 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestDecodeCreateLabelRequest(t *testing.T) {
|
||||
router := mux.NewRouter()
|
||||
router.HandleFunc("/api/v1/kolide/labels", func(writer http.ResponseWriter, request *http.Request) {
|
||||
r, err := decodeCreateLabelRequest(context.Background(), request)
|
||||
assert.Nil(t, err)
|
||||
|
||||
params := r.(createLabelRequest)
|
||||
assert.Equal(t, "foo", *params.payload.Name)
|
||||
assert.Equal(t, "select * from foo;", *params.payload.Query)
|
||||
assert.Equal(t, "darwin", *params.payload.Platform)
|
||||
}).Methods("POST")
|
||||
|
||||
var body bytes.Buffer
|
||||
body.Write([]byte(`{
|
||||
"name": "foo",
|
||||
"query": "select * from foo;",
|
||||
"platform": "darwin"
|
||||
}`))
|
||||
|
||||
router.ServeHTTP(
|
||||
httptest.NewRecorder(),
|
||||
httptest.NewRequest("POST", "/api/v1/kolide/labels", &body),
|
||||
)
|
||||
}
|
||||
|
||||
func TestDecodeDeleteLabelRequest(t *testing.T) {
|
||||
router := mux.NewRouter()
|
||||
router.HandleFunc("/api/v1/kolide/labels/{id}", func(writer http.ResponseWriter, request *http.Request) {
|
||||
|
|
|
|||
|
|
@ -2,32 +2,9 @@ package service
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func decodeCreatePackRequest(ctx context.Context, r *http.Request) (interface{}, error) {
|
||||
var req createPackRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req.payload); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func decodeModifyPackRequest(ctx context.Context, r *http.Request) (interface{}, error) {
|
||||
id, err := idFromRequest(r, "id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var req modifyPackRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req.payload); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.ID = id
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func decodeDeletePackRequest(ctx context.Context, r *http.Request) (interface{}, error) {
|
||||
id, err := idFromRequest(r, "id")
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
|
|
@ -9,68 +8,8 @@ import (
|
|||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDecodeCreatePackRequest(t *testing.T) {
|
||||
router := mux.NewRouter()
|
||||
router.HandleFunc("/api/v1/kolide/packs", func(writer http.ResponseWriter, request *http.Request) {
|
||||
r, err := decodeCreatePackRequest(context.Background(), request)
|
||||
assert.Nil(t, err)
|
||||
|
||||
params := r.(createPackRequest)
|
||||
assert.Equal(t, "foo", *params.payload.Name)
|
||||
assert.Equal(t, "bar", *params.payload.Description)
|
||||
require.NotNil(t, params.payload.HostIDs)
|
||||
assert.Len(t, *params.payload.HostIDs, 3)
|
||||
require.NotNil(t, params.payload.LabelIDs)
|
||||
assert.Len(t, *params.payload.LabelIDs, 2)
|
||||
}).Methods("POST")
|
||||
|
||||
var body bytes.Buffer
|
||||
body.Write([]byte(`{
|
||||
"name": "foo",
|
||||
"description": "bar",
|
||||
"host_ids": [1, 2, 3],
|
||||
"label_ids": [1, 5]
|
||||
}`))
|
||||
|
||||
router.ServeHTTP(
|
||||
httptest.NewRecorder(),
|
||||
httptest.NewRequest("POST", "/api/v1/kolide/packs", &body),
|
||||
)
|
||||
}
|
||||
|
||||
func TestDecodeModifyPackRequest(t *testing.T) {
|
||||
router := mux.NewRouter()
|
||||
router.HandleFunc("/api/v1/kolide/packs/{id}", func(writer http.ResponseWriter, request *http.Request) {
|
||||
r, err := decodeModifyPackRequest(context.Background(), request)
|
||||
assert.Nil(t, err)
|
||||
|
||||
params := r.(modifyPackRequest)
|
||||
assert.Equal(t, uint(1), params.ID)
|
||||
assert.Equal(t, "foo", *params.payload.Name)
|
||||
assert.Equal(t, "bar", *params.payload.Description)
|
||||
require.NotNil(t, params.payload.HostIDs)
|
||||
assert.Len(t, *params.payload.HostIDs, 3)
|
||||
require.NotNil(t, params.payload.LabelIDs)
|
||||
assert.Len(t, *params.payload.LabelIDs, 2)
|
||||
}).Methods("PATCH")
|
||||
|
||||
var body bytes.Buffer
|
||||
body.Write([]byte(`{
|
||||
"name": "foo",
|
||||
"description": "bar",
|
||||
"host_ids": [1, 2, 3],
|
||||
"label_ids": [1, 5]
|
||||
}`))
|
||||
|
||||
router.ServeHTTP(
|
||||
httptest.NewRecorder(),
|
||||
httptest.NewRequest("PATCH", "/api/v1/kolide/packs/1", &body),
|
||||
)
|
||||
}
|
||||
|
||||
func TestDecodeDeletePackRequest(t *testing.T) {
|
||||
router := mux.NewRouter()
|
||||
router.HandleFunc("/api/v1/kolide/packs/{id}", func(writer http.ResponseWriter, request *http.Request) {
|
||||
|
|
|
|||
|
|
@ -25,13 +25,12 @@ func NewQuery(t *testing.T, ds kolide.Datastore, name, q string, authorID uint,
|
|||
}
|
||||
|
||||
func NewPack(t *testing.T, ds kolide.Datastore, name string) *kolide.Pack {
|
||||
pack, err := ds.NewPack(&kolide.Pack{
|
||||
Name: name,
|
||||
})
|
||||
err := ds.ApplyPackSpecs([]*kolide.PackSpec{&kolide.PackSpec{Name: name}})
|
||||
require.Nil(t, err)
|
||||
|
||||
// Loading gives us the timestamps
|
||||
pack, err = ds.Pack(pack.ID)
|
||||
pack, ok, err := ds.PackByName(name)
|
||||
require.True(t, ok)
|
||||
require.Nil(t, err)
|
||||
|
||||
return pack
|
||||
|
|
@ -104,15 +103,6 @@ func NewHost(t *testing.T, ds kolide.Datastore, name, ip, key, uuid string, now
|
|||
return h
|
||||
}
|
||||
|
||||
func NewLabel(t *testing.T, ds kolide.Datastore, name, query string) *kolide.Label {
|
||||
l, err := ds.NewLabel(&kolide.Label{Name: name, Query: query})
|
||||
|
||||
require.Nil(t, err)
|
||||
require.NotZero(t, l.ID)
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func NewUser(t *testing.T, ds kolide.Datastore, name, username, email string, admin bool) *kolide.User {
|
||||
u, err := ds.NewUser(&kolide.User{
|
||||
Password: []byte("garbage"),
|
||||
|
|
|
|||
Loading…
Reference in a new issue