2016-09-26 18:48:55 +00:00
|
|
|
package service
|
2016-09-06 21:28:07 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2016-09-21 03:08:11 +00:00
|
|
|
"fmt"
|
2016-09-06 21:28:07 +00:00
|
|
|
"testing"
|
2016-09-21 03:08:11 +00:00
|
|
|
"time"
|
2016-09-06 21:28:07 +00:00
|
|
|
|
2016-09-21 03:08:11 +00:00
|
|
|
"github.com/WatchBeam/clock"
|
2016-09-29 04:21:39 +00:00
|
|
|
hostctx "github.com/kolide/kolide-ose/server/contexts/host"
|
2016-09-26 18:48:55 +00:00
|
|
|
"github.com/kolide/kolide-ose/server/datastore"
|
|
|
|
"github.com/kolide/kolide-ose/server/kolide"
|
2016-09-06 21:28:07 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
2016-09-21 03:08:11 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
2016-09-06 21:28:07 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestEnrollAgent(t *testing.T) {
|
|
|
|
ds, err := datastore.New("gorm-sqlite3", ":memory:")
|
|
|
|
assert.Nil(t, err)
|
|
|
|
|
2016-09-21 03:08:11 +00:00
|
|
|
svc, err := newTestService(ds)
|
2016-09-06 21:28:07 +00:00
|
|
|
assert.Nil(t, err)
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
hosts, err := ds.Hosts()
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.Len(t, hosts, 0)
|
|
|
|
|
2016-09-21 03:08:11 +00:00
|
|
|
nodeKey, err := svc.EnrollAgent(ctx, "", "host123")
|
2016-09-06 21:28:07 +00:00
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.NotEmpty(t, nodeKey)
|
|
|
|
|
|
|
|
hosts, err = ds.Hosts()
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.Len(t, hosts, 1)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestEnrollAgentIncorrectEnrollSecret(t *testing.T) {
|
|
|
|
ds, err := datastore.New("gorm-sqlite3", ":memory:")
|
|
|
|
assert.Nil(t, err)
|
|
|
|
|
2016-09-21 03:08:11 +00:00
|
|
|
svc, err := newTestService(ds)
|
2016-09-06 21:28:07 +00:00
|
|
|
assert.Nil(t, err)
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
hosts, err := ds.Hosts()
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.Len(t, hosts, 0)
|
|
|
|
|
|
|
|
nodeKey, err := svc.EnrollAgent(ctx, "not_correct", "host123")
|
|
|
|
assert.NotNil(t, err)
|
|
|
|
assert.Empty(t, nodeKey)
|
|
|
|
|
|
|
|
hosts, err = ds.Hosts()
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.Len(t, hosts, 0)
|
|
|
|
}
|
2016-09-21 03:08:11 +00:00
|
|
|
|
|
|
|
func TestHostDetailQueries(t *testing.T) {
|
|
|
|
host := kolide.Host{
|
|
|
|
ID: 1,
|
|
|
|
CreatedAt: time.Now(),
|
|
|
|
UpdatedAt: time.Now(),
|
|
|
|
NodeKey: "test_key",
|
|
|
|
HostName: "test_hostname",
|
|
|
|
UUID: "test_uuid",
|
|
|
|
}
|
|
|
|
|
|
|
|
queries := hostDetailQueries(host)
|
|
|
|
assert.Len(t, queries, 1)
|
|
|
|
if assert.Contains(t, queries, "kolide_detail_query_platform") {
|
|
|
|
assert.Equal(t,
|
|
|
|
"select build_platform from osquery_info;",
|
|
|
|
queries["kolide_detail_query_platform"],
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
host.Platform = "test_platform"
|
|
|
|
|
|
|
|
queries = hostDetailQueries(host)
|
|
|
|
assert.Len(t, queries, 0)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetDistributedQueries(t *testing.T) {
|
|
|
|
ds, err := datastore.New("gorm-sqlite3", ":memory:")
|
|
|
|
assert.Nil(t, err)
|
|
|
|
|
|
|
|
mockClock := clock.NewMockClock()
|
|
|
|
|
|
|
|
svc, err := newTestServiceWithClock(ds, mockClock)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
_, err = svc.EnrollAgent(ctx, "", "host123")
|
|
|
|
assert.Nil(t, err)
|
|
|
|
|
|
|
|
hosts, err := ds.Hosts()
|
|
|
|
require.Nil(t, err)
|
|
|
|
require.Len(t, hosts, 1)
|
|
|
|
host := hosts[0]
|
|
|
|
|
2016-09-29 04:21:39 +00:00
|
|
|
ctx = hostctx.NewContext(ctx, *host)
|
2016-09-21 03:08:11 +00:00
|
|
|
|
|
|
|
// With no platform set, we should get the details query
|
|
|
|
queries, err := svc.GetDistributedQueries(ctx)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.Len(t, queries, 1)
|
|
|
|
if assert.Contains(t, queries, "kolide_detail_query_platform") {
|
|
|
|
assert.Equal(t,
|
|
|
|
"select build_platform from osquery_info;",
|
|
|
|
queries["kolide_detail_query_platform"],
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
host.Platform = "darwin"
|
2016-09-29 04:21:39 +00:00
|
|
|
ds.SaveHost(host)
|
|
|
|
ctx = hostctx.NewContext(ctx, *host)
|
2016-09-21 03:08:11 +00:00
|
|
|
|
|
|
|
// With the platform set, we should get the label queries (but none
|
|
|
|
// exist yet)
|
|
|
|
queries, err = svc.GetDistributedQueries(ctx)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.Len(t, queries, 0)
|
|
|
|
|
|
|
|
// Add some queries and labels to ensure they are returned
|
|
|
|
|
|
|
|
labelQueries := []*kolide.Query{
|
|
|
|
&kolide.Query{
|
|
|
|
ID: 1,
|
|
|
|
Name: "query1",
|
|
|
|
Platform: "darwin",
|
|
|
|
Query: "query1",
|
|
|
|
},
|
|
|
|
&kolide.Query{
|
|
|
|
ID: 2,
|
|
|
|
Name: "query2",
|
|
|
|
Platform: "darwin",
|
|
|
|
Query: "query2",
|
|
|
|
},
|
|
|
|
&kolide.Query{
|
|
|
|
ID: 3,
|
|
|
|
Name: "query3",
|
|
|
|
Platform: "darwin",
|
|
|
|
Query: "query3",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
expectQueries := make(map[string]string)
|
|
|
|
|
|
|
|
for _, query := range labelQueries {
|
2016-09-30 01:19:51 +00:00
|
|
|
_, err := ds.NewQuery(query)
|
|
|
|
assert.Nil(t, err)
|
2016-09-21 03:08:11 +00:00
|
|
|
expectQueries[fmt.Sprintf("kolide_label_query_%d", query.ID)] = query.Query
|
|
|
|
}
|
|
|
|
// this one should not show up
|
2016-09-30 01:19:51 +00:00
|
|
|
_, err = ds.NewQuery(&kolide.Query{
|
2016-09-21 03:08:11 +00:00
|
|
|
ID: 4,
|
|
|
|
Name: "query4",
|
|
|
|
Platform: "not_darwin",
|
|
|
|
Query: "query4",
|
2016-09-30 01:19:51 +00:00
|
|
|
})
|
|
|
|
assert.Nil(t, err)
|
2016-09-21 03:08:11 +00:00
|
|
|
|
|
|
|
labels := []*kolide.Label{
|
|
|
|
&kolide.Label{
|
|
|
|
Name: "label1",
|
|
|
|
QueryID: 1,
|
|
|
|
},
|
|
|
|
&kolide.Label{
|
|
|
|
Name: "label2",
|
|
|
|
QueryID: 2,
|
|
|
|
},
|
|
|
|
&kolide.Label{
|
|
|
|
Name: "label3",
|
|
|
|
QueryID: 3,
|
|
|
|
},
|
|
|
|
&kolide.Label{
|
|
|
|
Name: "label4",
|
|
|
|
QueryID: 4,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, label := range labels {
|
2016-09-30 01:19:51 +00:00
|
|
|
_, err := ds.NewLabel(label)
|
|
|
|
assert.Nil(t, err)
|
2016-09-21 03:08:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Now we should get the label queries
|
|
|
|
queries, err = svc.GetDistributedQueries(ctx)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.Len(t, queries, 3)
|
|
|
|
assert.Equal(t, expectQueries, queries)
|
|
|
|
|
|
|
|
// Record a query execution
|
|
|
|
err = ds.RecordLabelQueryExecutions(host, map[string]bool{"1": true}, mockClock.Now())
|
2016-09-30 01:19:51 +00:00
|
|
|
assert.Nil(t, err)
|
2016-09-21 03:08:11 +00:00
|
|
|
|
|
|
|
// Now that query should not be returned
|
|
|
|
queries, err = svc.GetDistributedQueries(ctx)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.Len(t, queries, 2)
|
|
|
|
assert.NotContains(t, queries, "kolide_label_query_1")
|
|
|
|
|
|
|
|
// Advance the time
|
|
|
|
mockClock.AddTime(1*time.Hour + 1*time.Minute)
|
|
|
|
|
|
|
|
// Now we should get all the label queries again
|
|
|
|
queries, err = svc.GetDistributedQueries(ctx)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.Len(t, queries, 3)
|
|
|
|
assert.Equal(t, expectQueries, queries)
|
|
|
|
|
|
|
|
// Record an old query execution -- Shouldn't change the return
|
|
|
|
err = ds.RecordLabelQueryExecutions(host, map[string]bool{"2": true}, mockClock.Now().Add(-10*time.Hour))
|
2016-09-30 01:19:51 +00:00
|
|
|
assert.Nil(t, err)
|
2016-09-21 03:08:11 +00:00
|
|
|
queries, err = svc.GetDistributedQueries(ctx)
|
2016-09-30 01:19:51 +00:00
|
|
|
assert.Nil(t, err)
|
2016-09-21 03:08:11 +00:00
|
|
|
assert.Equal(t, expectQueries, queries)
|
|
|
|
|
|
|
|
// Record a newer execution for that query and another
|
|
|
|
err = ds.RecordLabelQueryExecutions(host, map[string]bool{"2": true, "3": false}, mockClock.Now().Add(-1*time.Minute))
|
2016-09-30 01:19:51 +00:00
|
|
|
assert.Nil(t, err)
|
2016-09-21 03:08:11 +00:00
|
|
|
|
|
|
|
// Now these should no longer show up in the necessary to run queries
|
|
|
|
delete(expectQueries, "kolide_label_query_2")
|
|
|
|
delete(expectQueries, "kolide_label_query_3")
|
|
|
|
queries, err = svc.GetDistributedQueries(ctx)
|
2016-09-30 01:19:51 +00:00
|
|
|
assert.Nil(t, err)
|
2016-09-21 03:08:11 +00:00
|
|
|
assert.Equal(t, expectQueries, queries)
|
|
|
|
}
|