Add service method/endpoint for creating distributed query campaign (#485)

This commit is contained in:
Zachary Wasserman 2016-11-16 13:07:50 -08:00 committed by GitHub
parent eb3f3cd765
commit 34625ce4d0
10 changed files with 266 additions and 196 deletions

View file

@ -36,7 +36,6 @@ CREATE TABLE `distributed_query_campaigns` (
`deleted_at` timestamp NULL DEFAULT NULL,
`deleted` tinyint(1) NOT NULL DEFAULT FALSE,
`query_id` int(10) unsigned DEFAULT NULL,
`max_duration` bigint(20) DEFAULT NULL,
`status` int(11) DEFAULT NULL,
`user_id` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`)

View file

@ -90,18 +90,15 @@ func (d *Datastore) ListQueries(opt kolide.ListOptions) ([]*kolide.Query, error)
}
func (d *Datastore) SaveDistributedQueryCampaign(camp *kolide.DistributedQueryCampaign) error {
sqlStatement := `
UPDATE distributed_query_campaigns SET
query_id = ?,
max_duration = ?,
status = ?,
user_id = ?
WHERE id = ?
AND NOT deleted
`
_, err := d.db.Exec(sqlStatement, camp.QueryID, camp.MaxDuration,
camp.Status, camp.UserID, camp.ID)
_, err := d.db.Exec(sqlStatement, camp.QueryID, camp.Status, camp.UserID, camp.ID)
if err != nil {
return errors.DatabaseError(err)
}
@ -114,13 +111,12 @@ func (d *Datastore) NewDistributedQueryCampaign(camp *kolide.DistributedQueryCam
sqlStatement := `
INSERT INTO distributed_query_campaigns (
query_id,
max_duration,
status,
user_id
)
VALUES(?,?,?,?)
VALUES(?,?,?)
`
result, err := d.db.Exec(sqlStatement, camp.QueryID, camp.MaxDuration, camp.Status, camp.UserID)
result, err := d.db.Exec(sqlStatement, camp.QueryID, camp.Status, camp.UserID)
if err != nil {
return nil, errors.DatabaseError(err)
}

View file

@ -33,6 +33,7 @@ type QueryService interface {
NewQuery(ctx context.Context, p QueryPayload) (*Query, error)
ModifyQuery(ctx context.Context, id uint, p QueryPayload) (*Query, error)
DeleteQuery(ctx context.Context, id uint) error
NewDistributedQueryCampaign(ctx context.Context, userID uint, queryString string, hosts []uint, labels []uint) (*DistributedQueryCampaign, error)
}
type QueryPayload struct {
@ -76,11 +77,10 @@ const (
type DistributedQueryCampaign struct {
UpdateCreateTimestamps
DeleteFields
ID uint
QueryID uint `db:"query_id"`
MaxDuration time.Duration `db:"max_duration"`
Status DistributedQueryStatus
UserID uint
ID uint `json:"id"`
QueryID uint `json:"query_id" db:"query_id"`
Status DistributedQueryStatus `json:"status"`
UserID uint `json:"user_id"`
}
type DistributedQueryCampaignTarget struct {

View file

@ -2,6 +2,7 @@ package service
import (
"github.com/go-kit/kit/endpoint"
"github.com/kolide/kolide-ose/server/contexts/viewer"
"github.com/kolide/kolide-ose/server/kolide"
"golang.org/x/net/context"
)
@ -139,3 +140,39 @@ func makeDeleteQueryEndpoint(svc kolide.Service) endpoint.Endpoint {
return deleteQueryResponse{}, nil
}
}
////////////////////////////////////////////////////////////////////////////////
// Create Distributed Query Campaign
////////////////////////////////////////////////////////////////////////////////
type createDistributedQueryCampaignRequest struct {
UserID uint
Query string `json:"query"`
Selected struct {
Labels []uint `json:"labels"`
Hosts []uint `json:"hosts"`
} `json:"selected"`
}
type createDistributedQueryCampaignResponse struct {
Campaign *kolide.DistributedQueryCampaign `json:"campaign,omitempty"`
Err error `json:"error,omitempty"`
}
func (r createDistributedQueryCampaignResponse) error() error { return r.Err }
func makeCreateDistributedQueryCampaignEndpoint(svc kolide.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
vc, ok := viewer.FromContext(ctx)
if !ok {
return nil, errNoContext
}
req := request.(createDistributedQueryCampaignRequest)
campaign, err := svc.NewDistributedQueryCampaign(ctx, vc.UserID(), req.Query, req.Selected.Hosts, req.Selected.Labels)
if err != nil {
return createQueryResponse{Err: err}, nil
}
return createDistributedQueryCampaignResponse{campaign, nil}, nil
}
}

View file

@ -7,7 +7,7 @@ import (
)
////////////////////////////////////////////////////////////////////////////////
// Search Targrets
// Search Targets
////////////////////////////////////////////////////////////////////////////////
type searchTargetsRequest struct {

View file

@ -14,53 +14,54 @@ import (
// KolideEndpoints is a collection of RPC endpoints implemented by the Kolide API.
type KolideEndpoints struct {
Login endpoint.Endpoint
Logout endpoint.Endpoint
ForgotPassword endpoint.Endpoint
ResetPassword endpoint.Endpoint
Me endpoint.Endpoint
CreateUser endpoint.Endpoint
GetUser endpoint.Endpoint
ListUsers endpoint.Endpoint
ModifyUser endpoint.Endpoint
GetSessionsForUserInfo endpoint.Endpoint
DeleteSessionsForUser endpoint.Endpoint
GetSessionInfo endpoint.Endpoint
DeleteSession endpoint.Endpoint
GetAppConfig endpoint.Endpoint
ModifyAppConfig endpoint.Endpoint
CreateInvite endpoint.Endpoint
ListInvites endpoint.Endpoint
DeleteInvite endpoint.Endpoint
GetQuery endpoint.Endpoint
ListQueries endpoint.Endpoint
CreateQuery endpoint.Endpoint
ModifyQuery endpoint.Endpoint
DeleteQuery endpoint.Endpoint
GetPack endpoint.Endpoint
ListPacks endpoint.Endpoint
CreatePack endpoint.Endpoint
ModifyPack endpoint.Endpoint
DeletePack endpoint.Endpoint
AddQueryToPack endpoint.Endpoint
GetQueriesInPack endpoint.Endpoint
DeleteQueryFromPack endpoint.Endpoint
EnrollAgent endpoint.Endpoint
GetClientConfig endpoint.Endpoint
GetDistributedQueries endpoint.Endpoint
SubmitDistributedQueryResults endpoint.Endpoint
SubmitLogs endpoint.Endpoint
GetLabel endpoint.Endpoint
ListLabels endpoint.Endpoint
CreateLabel endpoint.Endpoint
DeleteLabel endpoint.Endpoint
AddLabelToPack endpoint.Endpoint
GetLabelsForPack endpoint.Endpoint
DeleteLabelFromPack endpoint.Endpoint
GetHost endpoint.Endpoint
DeleteHost endpoint.Endpoint
ListHosts endpoint.Endpoint
SearchTargets endpoint.Endpoint
Login endpoint.Endpoint
Logout endpoint.Endpoint
ForgotPassword endpoint.Endpoint
ResetPassword endpoint.Endpoint
Me endpoint.Endpoint
CreateUser endpoint.Endpoint
GetUser endpoint.Endpoint
ListUsers endpoint.Endpoint
ModifyUser endpoint.Endpoint
GetSessionsForUserInfo endpoint.Endpoint
DeleteSessionsForUser endpoint.Endpoint
GetSessionInfo endpoint.Endpoint
DeleteSession endpoint.Endpoint
GetAppConfig endpoint.Endpoint
ModifyAppConfig endpoint.Endpoint
CreateInvite endpoint.Endpoint
ListInvites endpoint.Endpoint
DeleteInvite endpoint.Endpoint
GetQuery endpoint.Endpoint
ListQueries endpoint.Endpoint
CreateQuery endpoint.Endpoint
ModifyQuery endpoint.Endpoint
DeleteQuery endpoint.Endpoint
CreateDistributedQueryCampaign endpoint.Endpoint
GetPack endpoint.Endpoint
ListPacks endpoint.Endpoint
CreatePack endpoint.Endpoint
ModifyPack endpoint.Endpoint
DeletePack endpoint.Endpoint
AddQueryToPack endpoint.Endpoint
GetQueriesInPack endpoint.Endpoint
DeleteQueryFromPack endpoint.Endpoint
EnrollAgent endpoint.Endpoint
GetClientConfig endpoint.Endpoint
GetDistributedQueries endpoint.Endpoint
SubmitDistributedQueryResults endpoint.Endpoint
SubmitLogs endpoint.Endpoint
GetLabel endpoint.Endpoint
ListLabels endpoint.Endpoint
CreateLabel endpoint.Endpoint
DeleteLabel endpoint.Endpoint
AddLabelToPack endpoint.Endpoint
GetLabelsForPack endpoint.Endpoint
DeleteLabelFromPack endpoint.Endpoint
GetHost endpoint.Endpoint
DeleteHost endpoint.Endpoint
ListHosts endpoint.Endpoint
SearchTargets endpoint.Endpoint
}
// MakeKolideServerEndpoints creates the Kolide API endpoints.
@ -73,43 +74,44 @@ func MakeKolideServerEndpoints(svc kolide.Service, jwtKey string) KolideEndpoint
CreateUser: makeCreateUserEndpoint(svc),
// Authenticated user endpoints
Me: authenticatedUser(jwtKey, svc, makeGetSessionUserEndpoint(svc)),
GetUser: authenticatedUser(jwtKey, svc, canReadUser(makeGetUserEndpoint(svc))),
ListUsers: authenticatedUser(jwtKey, svc, canPerformActions(makeListUsersEndpoint(svc))),
ModifyUser: authenticatedUser(jwtKey, svc, validateModifyUserRequest(makeModifyUserEndpoint(svc))),
GetSessionsForUserInfo: authenticatedUser(jwtKey, svc, canReadUser(makeGetInfoAboutSessionsForUserEndpoint(svc))),
DeleteSessionsForUser: authenticatedUser(jwtKey, svc, canModifyUser(makeDeleteSessionsForUserEndpoint(svc))),
GetSessionInfo: authenticatedUser(jwtKey, svc, mustBeAdmin(makeGetInfoAboutSessionEndpoint(svc))),
DeleteSession: authenticatedUser(jwtKey, svc, mustBeAdmin(makeDeleteSessionEndpoint(svc))),
GetAppConfig: authenticatedUser(jwtKey, svc, makeGetAppConfigEndpoint(svc)),
ModifyAppConfig: authenticatedUser(jwtKey, svc, mustBeAdmin(makeModifyAppConfigRequest(svc))),
CreateInvite: authenticatedUser(jwtKey, svc, mustBeAdmin(makeCreateInviteEndpoint(svc))),
ListInvites: authenticatedUser(jwtKey, svc, mustBeAdmin(makeListInvitesEndpoint(svc))),
DeleteInvite: authenticatedUser(jwtKey, svc, mustBeAdmin(makeDeleteInviteEndpoint(svc))),
GetQuery: authenticatedUser(jwtKey, svc, makeGetQueryEndpoint(svc)),
ListQueries: authenticatedUser(jwtKey, svc, makeListQueriesEndpoint(svc)),
CreateQuery: authenticatedUser(jwtKey, svc, makeCreateQueryEndpoint(svc)),
ModifyQuery: authenticatedUser(jwtKey, svc, makeModifyQueryEndpoint(svc)),
DeleteQuery: authenticatedUser(jwtKey, svc, makeDeleteQueryEndpoint(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)),
AddQueryToPack: authenticatedUser(jwtKey, svc, makeAddQueryToPackEndpoint(svc)),
GetQueriesInPack: authenticatedUser(jwtKey, svc, makeGetQueriesInPackEndpoint(svc)),
DeleteQueryFromPack: authenticatedUser(jwtKey, svc, makeDeleteQueryFromPackEndpoint(svc)),
GetHost: authenticatedUser(jwtKey, svc, makeGetHostEndpoint(svc)),
ListHosts: authenticatedUser(jwtKey, svc, makeListHostsEndpoint(svc)),
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)),
AddLabelToPack: authenticatedUser(jwtKey, svc, makeAddLabelToPackEndpoint(svc)),
GetLabelsForPack: authenticatedUser(jwtKey, svc, makeGetLabelsForPackEndpoint(svc)),
DeleteLabelFromPack: authenticatedUser(jwtKey, svc, makeDeleteLabelFromPackEndpoint(svc)),
SearchTargets: authenticatedUser(jwtKey, svc, makeSearchTargetsEndpoint(svc)),
Me: authenticatedUser(jwtKey, svc, makeGetSessionUserEndpoint(svc)),
GetUser: authenticatedUser(jwtKey, svc, canReadUser(makeGetUserEndpoint(svc))),
ListUsers: authenticatedUser(jwtKey, svc, canPerformActions(makeListUsersEndpoint(svc))),
ModifyUser: authenticatedUser(jwtKey, svc, validateModifyUserRequest(makeModifyUserEndpoint(svc))),
GetSessionsForUserInfo: authenticatedUser(jwtKey, svc, canReadUser(makeGetInfoAboutSessionsForUserEndpoint(svc))),
DeleteSessionsForUser: authenticatedUser(jwtKey, svc, canModifyUser(makeDeleteSessionsForUserEndpoint(svc))),
GetSessionInfo: authenticatedUser(jwtKey, svc, mustBeAdmin(makeGetInfoAboutSessionEndpoint(svc))),
DeleteSession: authenticatedUser(jwtKey, svc, mustBeAdmin(makeDeleteSessionEndpoint(svc))),
GetAppConfig: authenticatedUser(jwtKey, svc, makeGetAppConfigEndpoint(svc)),
ModifyAppConfig: authenticatedUser(jwtKey, svc, mustBeAdmin(makeModifyAppConfigRequest(svc))),
CreateInvite: authenticatedUser(jwtKey, svc, mustBeAdmin(makeCreateInviteEndpoint(svc))),
ListInvites: authenticatedUser(jwtKey, svc, mustBeAdmin(makeListInvitesEndpoint(svc))),
DeleteInvite: authenticatedUser(jwtKey, svc, mustBeAdmin(makeDeleteInviteEndpoint(svc))),
GetQuery: authenticatedUser(jwtKey, svc, makeGetQueryEndpoint(svc)),
ListQueries: authenticatedUser(jwtKey, svc, makeListQueriesEndpoint(svc)),
CreateQuery: authenticatedUser(jwtKey, svc, makeCreateQueryEndpoint(svc)),
ModifyQuery: authenticatedUser(jwtKey, svc, makeModifyQueryEndpoint(svc)),
DeleteQuery: authenticatedUser(jwtKey, svc, makeDeleteQueryEndpoint(svc)),
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)),
AddQueryToPack: authenticatedUser(jwtKey, svc, makeAddQueryToPackEndpoint(svc)),
GetQueriesInPack: authenticatedUser(jwtKey, svc, makeGetQueriesInPackEndpoint(svc)),
DeleteQueryFromPack: authenticatedUser(jwtKey, svc, makeDeleteQueryFromPackEndpoint(svc)),
GetHost: authenticatedUser(jwtKey, svc, makeGetHostEndpoint(svc)),
ListHosts: authenticatedUser(jwtKey, svc, makeListHostsEndpoint(svc)),
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)),
AddLabelToPack: authenticatedUser(jwtKey, svc, makeAddLabelToPackEndpoint(svc)),
GetLabelsForPack: authenticatedUser(jwtKey, svc, makeGetLabelsForPackEndpoint(svc)),
DeleteLabelFromPack: authenticatedUser(jwtKey, svc, makeDeleteLabelFromPackEndpoint(svc)),
SearchTargets: authenticatedUser(jwtKey, svc, makeSearchTargetsEndpoint(svc)),
// Osquery endpoints
EnrollAgent: makeEnrollAgentEndpoint(svc),
@ -121,53 +123,54 @@ func MakeKolideServerEndpoints(svc kolide.Service, jwtKey string) KolideEndpoint
}
type kolideHandlers struct {
Login *kithttp.Server
Logout *kithttp.Server
ForgotPassword *kithttp.Server
ResetPassword *kithttp.Server
Me *kithttp.Server
CreateUser *kithttp.Server
GetUser *kithttp.Server
ListUsers *kithttp.Server
ModifyUser *kithttp.Server
GetSessionsForUserInfo *kithttp.Server
DeleteSessionsForUser *kithttp.Server
GetSessionInfo *kithttp.Server
DeleteSession *kithttp.Server
GetAppConfig *kithttp.Server
ModifyAppConfig *kithttp.Server
CreateInvite *kithttp.Server
ListInvites *kithttp.Server
DeleteInvite *kithttp.Server
GetQuery *kithttp.Server
ListQueries *kithttp.Server
CreateQuery *kithttp.Server
ModifyQuery *kithttp.Server
DeleteQuery *kithttp.Server
GetPack *kithttp.Server
ListPacks *kithttp.Server
CreatePack *kithttp.Server
ModifyPack *kithttp.Server
DeletePack *kithttp.Server
AddQueryToPack *kithttp.Server
GetQueriesInPack *kithttp.Server
DeleteQueryFromPack *kithttp.Server
EnrollAgent *kithttp.Server
GetClientConfig *kithttp.Server
GetDistributedQueries *kithttp.Server
SubmitDistributedQueryResults *kithttp.Server
SubmitLogs *kithttp.Server
GetLabel *kithttp.Server
ListLabels *kithttp.Server
CreateLabel *kithttp.Server
DeleteLabel *kithttp.Server
AddLabelToPack *kithttp.Server
GetLabelsForPack *kithttp.Server
DeleteLabelFromPack *kithttp.Server
GetHost *kithttp.Server
DeleteHost *kithttp.Server
ListHosts *kithttp.Server
SearchTargets *kithttp.Server
Login *kithttp.Server
Logout *kithttp.Server
ForgotPassword *kithttp.Server
ResetPassword *kithttp.Server
Me *kithttp.Server
CreateUser *kithttp.Server
GetUser *kithttp.Server
ListUsers *kithttp.Server
ModifyUser *kithttp.Server
GetSessionsForUserInfo *kithttp.Server
DeleteSessionsForUser *kithttp.Server
GetSessionInfo *kithttp.Server
DeleteSession *kithttp.Server
GetAppConfig *kithttp.Server
ModifyAppConfig *kithttp.Server
CreateInvite *kithttp.Server
ListInvites *kithttp.Server
DeleteInvite *kithttp.Server
GetQuery *kithttp.Server
ListQueries *kithttp.Server
CreateQuery *kithttp.Server
ModifyQuery *kithttp.Server
DeleteQuery *kithttp.Server
CreateDistributedQueryCampaign *kithttp.Server
GetPack *kithttp.Server
ListPacks *kithttp.Server
CreatePack *kithttp.Server
ModifyPack *kithttp.Server
DeletePack *kithttp.Server
AddQueryToPack *kithttp.Server
GetQueriesInPack *kithttp.Server
DeleteQueryFromPack *kithttp.Server
EnrollAgent *kithttp.Server
GetClientConfig *kithttp.Server
GetDistributedQueries *kithttp.Server
SubmitDistributedQueryResults *kithttp.Server
SubmitLogs *kithttp.Server
GetLabel *kithttp.Server
ListLabels *kithttp.Server
CreateLabel *kithttp.Server
DeleteLabel *kithttp.Server
AddLabelToPack *kithttp.Server
GetLabelsForPack *kithttp.Server
DeleteLabelFromPack *kithttp.Server
GetHost *kithttp.Server
DeleteHost *kithttp.Server
ListHosts *kithttp.Server
SearchTargets *kithttp.Server
}
func makeKolideKitHandlers(ctx context.Context, e KolideEndpoints, opts []kithttp.ServerOption) kolideHandlers {
@ -175,29 +178,30 @@ func makeKolideKitHandlers(ctx context.Context, e KolideEndpoints, opts []kithtt
return kithttp.NewServer(ctx, e, decodeFn, encodeResponse, opts...)
}
return kolideHandlers{
Login: newServer(e.Login, decodeLoginRequest),
Logout: newServer(e.Logout, decodeNoParamsRequest),
ForgotPassword: newServer(e.ForgotPassword, decodeForgotPasswordRequest),
ResetPassword: newServer(e.ResetPassword, decodeResetPasswordRequest),
Me: newServer(e.Me, decodeNoParamsRequest),
CreateUser: newServer(e.CreateUser, decodeCreateUserRequest),
GetUser: newServer(e.GetUser, decodeGetUserRequest),
ListUsers: newServer(e.ListUsers, decodeListUsersRequest),
ModifyUser: newServer(e.ModifyUser, decodeModifyUserRequest),
GetSessionsForUserInfo: newServer(e.GetSessionsForUserInfo, decodeGetInfoAboutSessionsForUserRequest),
DeleteSessionsForUser: newServer(e.DeleteSessionsForUser, decodeDeleteSessionsForUserRequest),
GetSessionInfo: newServer(e.GetSessionInfo, decodeGetInfoAboutSessionRequest),
DeleteSession: newServer(e.DeleteSession, decodeDeleteSessionRequest),
GetAppConfig: newServer(e.GetAppConfig, decodeNoParamsRequest),
ModifyAppConfig: newServer(e.ModifyAppConfig, decodeModifyAppConfigRequest),
CreateInvite: newServer(e.CreateInvite, decodeCreateInviteRequest),
ListInvites: newServer(e.ListInvites, decodeListInvitesRequest),
DeleteInvite: newServer(e.DeleteInvite, decodeDeleteInviteRequest),
GetQuery: newServer(e.GetQuery, decodeGetQueryRequest),
ListQueries: newServer(e.ListQueries, decodeListQueriesRequest),
CreateQuery: newServer(e.CreateQuery, decodeCreateQueryRequest),
ModifyQuery: newServer(e.ModifyQuery, decodeModifyQueryRequest),
DeleteQuery: newServer(e.DeleteQuery, decodeDeleteQueryRequest),
Login: newServer(e.Login, decodeLoginRequest),
Logout: newServer(e.Logout, decodeNoParamsRequest),
ForgotPassword: newServer(e.ForgotPassword, decodeForgotPasswordRequest),
ResetPassword: newServer(e.ResetPassword, decodeResetPasswordRequest),
Me: newServer(e.Me, decodeNoParamsRequest),
CreateUser: newServer(e.CreateUser, decodeCreateUserRequest),
GetUser: newServer(e.GetUser, decodeGetUserRequest),
ListUsers: newServer(e.ListUsers, decodeListUsersRequest),
ModifyUser: newServer(e.ModifyUser, decodeModifyUserRequest),
GetSessionsForUserInfo: newServer(e.GetSessionsForUserInfo, decodeGetInfoAboutSessionsForUserRequest),
DeleteSessionsForUser: newServer(e.DeleteSessionsForUser, decodeDeleteSessionsForUserRequest),
GetSessionInfo: newServer(e.GetSessionInfo, decodeGetInfoAboutSessionRequest),
DeleteSession: newServer(e.DeleteSession, decodeDeleteSessionRequest),
GetAppConfig: newServer(e.GetAppConfig, decodeNoParamsRequest),
ModifyAppConfig: newServer(e.ModifyAppConfig, decodeModifyAppConfigRequest),
CreateInvite: newServer(e.CreateInvite, decodeCreateInviteRequest),
ListInvites: newServer(e.ListInvites, decodeListInvitesRequest),
DeleteInvite: newServer(e.DeleteInvite, decodeDeleteInviteRequest),
GetQuery: newServer(e.GetQuery, decodeGetQueryRequest),
ListQueries: newServer(e.ListQueries, decodeListQueriesRequest),
CreateQuery: newServer(e.CreateQuery, decodeCreateQueryRequest),
ModifyQuery: newServer(e.ModifyQuery, decodeModifyQueryRequest),
DeleteQuery: newServer(e.DeleteQuery, decodeDeleteQueryRequest),
CreateDistributedQueryCampaign: newServer(e.CreateDistributedQueryCampaign, decodeCreateDistributedQueryCampaignRequest),
GetPack: newServer(e.GetPack, decodeGetPackRequest),
ListPacks: newServer(e.ListPacks, decodeListPacksRequest),
CreatePack: newServer(e.CreatePack, decodeCreatePackRequest),
@ -275,6 +279,7 @@ func attachKolideAPIRoutes(r *mux.Router, h kolideHandlers) {
r.Handle("/api/v1/kolide/queries", h.CreateQuery).Methods("POST")
r.Handle("/api/v1/kolide/queries/{id}", h.ModifyQuery).Methods("PATCH")
r.Handle("/api/v1/kolide/queries/{id}", h.DeleteQuery).Methods("DELETE")
r.Handle("/api/v1/kolide/queries/run", h.CreateDistributedQueryCampaign).Methods("POST")
r.Handle("/api/v1/kolide/packs/{id}", h.GetPack).Methods("GET")
r.Handle("/api/v1/kolide/packs", h.ListPacks).Methods("GET")

View file

@ -103,6 +103,10 @@ func TestAPIRoutes(t *testing.T) {
verb: "DELETE",
uri: "/api/v1/kolide/queries/1",
},
{
verb: "POST",
uri: "/api/v1/kolide/queries/run",
},
{
verb: "GET",
uri: "/api/v1/kolide/packs/1",

View file

@ -630,35 +630,11 @@ func TestDistributedQueries(t *testing.T) {
err = ds.RecordLabelQueryExecutions(host, map[string]bool{labelId: true}, mockClock.Now())
require.Nil(t, err)
// Create query
n = "time"
q = "select year, month, day, hour, minutes, seconds from time"
query, err := svc.NewQuery(ctx, kolide.QueryPayload{
Name: &n,
Query: &q,
})
campaign, err := svc.NewDistributedQueryCampaign(ctx, 0, q, []uint{}, []uint{label.ID})
require.Nil(t, err)
// Create query campaign
c1 := &kolide.DistributedQueryCampaign{
QueryID: query.ID,
Status: kolide.QueryRunning,
}
// TODO use service method
c1, err = ds.NewDistributedQueryCampaign(c1)
require.Nil(t, err)
// Add a target to the campaign (targeting the matching label)
target := &kolide.DistributedQueryCampaignTarget{
Type: kolide.TargetLabel,
DistributedQueryCampaignID: c1.ID,
TargetID: label.ID,
}
// TODO use service method
target, err = ds.NewDistributedQueryCampaignTarget(target)
require.Nil(t, err)
queryKey := fmt.Sprintf("%s%d", hostDistributedQueryPrefix, c1.ID)
queryKey := fmt.Sprintf("%s%d", hostDistributedQueryPrefix, campaign.ID)
// Now we should get the active distributed query
queries, err := svc.GetDistributedQueries(ctx)
@ -685,7 +661,7 @@ func TestDistributedQueries(t *testing.T) {
assert.NotNil(t, err)
// TODO use service method
readChan, err := rs.ReadChannel(ctx, *c1)
readChan, err := rs.ReadChannel(ctx, *campaign)
require.Nil(t, err)
// We need to listen for the result in a separate thread to prevent the
@ -698,7 +674,7 @@ func TestDistributedQueries(t *testing.T) {
select {
case val := <-readChan:
if res, ok := val.(kolide.DistributedQueryResult); ok {
assert.Equal(t, c1.ID, res.DistributedQueryCampaignID)
assert.Equal(t, campaign.ID, res.DistributedQueryCampaignID)
assert.Equal(t, expectedRows, res.Rows)
assert.Equal(t, *host, res.Host)
} else {

View file

@ -114,3 +114,48 @@ func (svc service) DeleteQuery(ctx context.Context, id uint) error {
return nil
}
func (svc service) NewDistributedQueryCampaign(ctx context.Context, userID uint, queryString string, hosts []uint, labels []uint) (*kolide.DistributedQueryCampaign, error) {
query, err := svc.NewQuery(ctx, kolide.QueryPayload{
Name: &queryString,
Query: &queryString,
})
if err != nil {
return nil, err
}
campaign, err := svc.ds.NewDistributedQueryCampaign(&kolide.DistributedQueryCampaign{
QueryID: query.ID,
Status: kolide.QueryRunning,
UserID: userID,
})
if err != nil {
return nil, err
}
// Add host targets
for _, hid := range hosts {
_, err = svc.ds.NewDistributedQueryCampaignTarget(&kolide.DistributedQueryCampaignTarget{
Type: kolide.TargetHost,
DistributedQueryCampaignID: campaign.ID,
TargetID: hid,
})
if err != nil {
return nil, err
}
}
// Add label targets
for _, lid := range labels {
_, err = svc.ds.NewDistributedQueryCampaignTarget(&kolide.DistributedQueryCampaignTarget{
Type: kolide.TargetLabel,
DistributedQueryCampaignID: campaign.ID,
TargetID: lid,
})
if err != nil {
return nil, err
}
}
return campaign, nil
}

View file

@ -55,3 +55,11 @@ func decodeListQueriesRequest(ctx context.Context, r *http.Request) (interface{}
}
return listQueriesRequest{ListOptions: opt}, nil
}
func decodeCreateDistributedQueryCampaignRequest(ctx context.Context, r *http.Request) (interface{}, error) {
var req createDistributedQueryCampaignRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
return nil, err
}
return req, nil
}