This repository has been archived by the owner on Dec 15, 2020. It is now read-only.
/
endpoint_campaigns.go
133 lines (111 loc) · 4.45 KB
/
endpoint_campaigns.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package service
import (
"context"
"encoding/json"
"net/http"
"github.com/go-kit/kit/endpoint"
kitlog "github.com/go-kit/kit/log"
"github.com/igm/sockjs-go/v3/sockjs"
"github.com/kolide/fleet/server/contexts/viewer"
"github.com/kolide/fleet/server/kolide"
"github.com/kolide/fleet/server/websocket"
)
////////////////////////////////////////////////////////////////////////////////
// Create Distributed Query Campaign
////////////////////////////////////////////////////////////////////////////////
type createDistributedQueryCampaignRequest struct {
Query string `json:"query"`
Selected distributedQueryCampaignTargets `json:"selected"`
}
type distributedQueryCampaignTargets struct {
Labels []uint `json:"labels"`
Hosts []uint `json:"hosts"`
}
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) {
req := request.(createDistributedQueryCampaignRequest)
campaign, err := svc.NewDistributedQueryCampaign(ctx, req.Query, req.Selected.Hosts, req.Selected.Labels)
if err != nil {
return createDistributedQueryCampaignResponse{Err: err}, nil
}
return createDistributedQueryCampaignResponse{Campaign: campaign}, nil
}
}
////////////////////////////////////////////////////////////////////////////////
// Create Distributed Query Campaign By Names
////////////////////////////////////////////////////////////////////////////////
type createDistributedQueryCampaignByNamesRequest struct {
Query string `json:"query"`
Selected distributedQueryCampaignTargetsByNames `json:"selected"`
}
type distributedQueryCampaignTargetsByNames struct {
Labels []string `json:"labels"`
Hosts []string `json:"hosts"`
}
func makeCreateDistributedQueryCampaignByNamesEndpoint(svc kolide.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(createDistributedQueryCampaignByNamesRequest)
campaign, err := svc.NewDistributedQueryCampaignByNames(ctx, req.Query, req.Selected.Hosts, req.Selected.Labels)
if err != nil {
return createDistributedQueryCampaignResponse{Err: err}, nil
}
return createDistributedQueryCampaignResponse{Campaign: campaign}, nil
}
}
////////////////////////////////////////////////////////////////////////////////
// Stream Distributed Query Campaign Results and Metadata
////////////////////////////////////////////////////////////////////////////////
func makeStreamDistributedQueryCampaignResultsHandler(svc kolide.Service, jwtKey string, logger kitlog.Logger) http.Handler {
opt := sockjs.DefaultOptions
opt.Websocket = true
opt.RawWebsocket = true
return sockjs.NewHandler("/api/v1/kolide/results", opt, func(session sockjs.Session) {
defer session.Close(0, "none")
conn := &websocket.Conn{Session: session}
// Receive the auth bearer token
token, err := conn.ReadAuthToken()
if err != nil {
logger.Log("err", err, "msg", "failed to read auth token")
return
}
// Authenticate with the token
vc, err := authViewer(context.Background(), jwtKey, token, svc)
if err != nil || !vc.CanPerformActions() {
logger.Log("err", err, "msg", "unauthorized viewer")
conn.WriteJSONError("unauthorized")
return
}
ctx := viewer.NewContext(context.Background(), *vc)
msg, err := conn.ReadJSONMessage()
if err != nil {
logger.Log("err", err, "msg", "reading select_campaign JSON")
conn.WriteJSONError("error reading select_campaign")
return
}
if msg.Type != "select_campaign" {
logger.Log("err", "unexpected msg type, expected select_campaign", "msg-type", msg.Type)
conn.WriteJSONError("expected select_campaign")
return
}
var info struct {
CampaignID uint `json:"campaign_id"`
}
err = json.Unmarshal(*(msg.Data.(*json.RawMessage)), &info)
if err != nil {
logger.Log("err", err, "msg", "unmarshaling select_campaign data")
conn.WriteJSONError("error unmarshaling select_campaign data")
return
}
if info.CampaignID == 0 {
logger.Log("err", "campaign ID not set")
conn.WriteJSONError("0 is not a valid campaign ID")
return
}
svc.StreamCampaignResults(ctx, conn, info.CampaignID)
})
}