forked from osquery/osquery-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
client.go
122 lines (103 loc) · 4.25 KB
/
client.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
package osquery
import (
"context"
"time"
"github.com/kolide/osquery-go/gen/osquery"
"github.com/kolide/osquery-go/transport"
"github.com/pkg/errors"
"github.com/apache/thrift/lib/go/thrift"
)
type ExtensionManager interface {
Close()
Ping() (*osquery.ExtensionStatus, error)
Call(registry, item string, req osquery.ExtensionPluginRequest) (*osquery.ExtensionResponse, error)
Extensions() (osquery.InternalExtensionList, error)
RegisterExtension(info *osquery.InternalExtensionInfo, registry osquery.ExtensionRegistry) (*osquery.ExtensionStatus, error)
Options() (osquery.InternalOptionList, error)
Query(sql string) (*osquery.ExtensionResponse, error)
GetQueryColumns(sql string) (*osquery.ExtensionResponse, error)
}
// ExtensionManagerClient is a wrapper for the osquery Thrift extensions API.
type ExtensionManagerClient struct {
Client osquery.ExtensionManager
transport thrift.TTransport
}
// NewClient creates a new client communicating to osquery over the socket at
// the provided path. If resolving the address or connecting to the socket
// fails, this function will error.
func NewClient(path string, timeout time.Duration) (*ExtensionManagerClient, error) {
trans, err := transport.Open(path, timeout)
if err != nil {
return nil, err
}
client := osquery.NewExtensionManagerClientFactory(
trans,
thrift.NewTBinaryProtocolFactoryDefault(),
)
return &ExtensionManagerClient{client, trans}, nil
}
// Close should be called to close the transport when use of the client is
// completed.
func (c *ExtensionManagerClient) Close() {
if c.transport != nil && c.transport.IsOpen() {
c.transport.Close()
}
}
// Ping requests metadata from the extension manager.
func (c *ExtensionManagerClient) Ping() (*osquery.ExtensionStatus, error) {
return c.Client.Ping(context.Background())
}
// Call requests a call to an extension (or core) registry plugin.
func (c *ExtensionManagerClient) Call(registry, item string, request osquery.ExtensionPluginRequest) (*osquery.ExtensionResponse, error) {
return c.Client.Call(context.Background(), registry, item, request)
}
// Extensions requests the list of active registered extensions.
func (c *ExtensionManagerClient) Extensions() (osquery.InternalExtensionList, error) {
return c.Client.Extensions(context.Background())
}
// RegisterExtension registers the extension plugins with the osquery process.
func (c *ExtensionManagerClient) RegisterExtension(info *osquery.InternalExtensionInfo, registry osquery.ExtensionRegistry) (*osquery.ExtensionStatus, error) {
return c.Client.RegisterExtension(context.Background(), info, registry)
}
// Options requests the list of bootstrap or configuration options.
func (c *ExtensionManagerClient) Options() (osquery.InternalOptionList, error) {
return c.Client.Options(context.Background())
}
// Query requests a query to be run and returns the extension response.
// Consider using the QueryRow or QueryRows helpers for a more friendly
// interface.
func (c *ExtensionManagerClient) Query(sql string) (*osquery.ExtensionResponse, error) {
return c.Client.Query(context.Background(), sql)
}
// QueryRows is a helper that executes the requested query and returns the
// results. It handles checking both the transport level errors and the osquery
// internal errors by returning a normal Go error type.
func (c *ExtensionManagerClient) QueryRows(sql string) ([]map[string]string, error) {
res, err := c.Query(sql)
if err != nil {
return nil, errors.Wrap(err, "transport error in query")
}
if res.Status == nil {
return nil, errors.New("query returned nil status")
}
if res.Status.Code != 0 {
return nil, errors.Errorf("query returned error: %s", res.Status.Message)
}
return res.Response, nil
}
// QueryRow behaves similarly to QueryRows, but it returns an error if the
// query does not return exactly one row.
func (c *ExtensionManagerClient) QueryRow(sql string) (map[string]string, error) {
res, err := c.QueryRows(sql)
if err != nil {
return nil, err
}
if len(res) != 1 {
return nil, errors.Errorf("expected 1 row, got %d", len(res))
}
return res[0], nil
}
// GetQueryColumns requests the columns returned by the parsed query.
func (c *ExtensionManagerClient) GetQueryColumns(sql string) (*osquery.ExtensionResponse, error) {
return c.Client.GetQueryColumns(context.Background(), sql)
}