Osquery Options - /config/osquery-options #365 (#729)

This commit is contained in:
John Murphy 2016-12-31 11:56:54 -06:00 committed by GitHub
parent e4fa278f59
commit d1ef37b92c
9 changed files with 77 additions and 18 deletions

View file

@ -56,3 +56,19 @@ func testOptions(t *testing.T, ds kolide.Datastore) {
assert.Equal(t, false, opt2.GetValue())
}
func testOptionsToConfig(t *testing.T, ds kolide.Datastore) {
resp, err := ds.GetOsqueryConfigOptions()
require.Nil(t, err)
assert.Len(t, resp, 10)
assert.Equal(t, "/api/v1/osquery/distributed/read", resp["distributed_tls_read_endpoint"])
opt, _ := ds.OptionByName("aws_profile_name")
assert.False(t, opt.OptionSet())
opt.SetValue("zip")
err = ds.SaveOptions([]kolide.Option{*opt})
require.Nil(t, err)
resp, err = ds.GetOsqueryConfigOptions()
require.Nil(t, err)
assert.Len(t, resp, 11)
assert.Equal(t, "zip", resp["aws_profile_name"])
}

View file

@ -58,4 +58,5 @@ var testFunctions = [...]func(*testing.T, kolide.Datastore){
testSaveScheduledQuery,
testOptions,
testNewScheduledQuery,
testOptionsToConfig,
}

View file

@ -72,3 +72,15 @@ func (d *Datastore) ListOptions() ([]kolide.Option, error) {
sortutil.AscByField(result, "Name")
return result, nil
}
func (d *Datastore) GetOsqueryConfigOptions() (map[string]interface{}, error) {
d.mtx.Lock()
defer d.mtx.Unlock()
optConfig := map[string]interface{}{}
for _, opt := range d.options {
if opt.OptionSet() {
optConfig[opt.Name] = opt.GetValue()
}
}
return optConfig, nil
}

View file

@ -94,3 +94,25 @@ func (d *Datastore) ListOptions() ([]kolide.Option, error) {
}
return opts, nil
}
func (d *Datastore) GetOsqueryConfigOptions() (map[string]interface{}, error) {
// Retrieve all the options that are set. The value field is JSON formatted so
// to retrieve options that are set, we check JSON null keyword
sqlStatement := `
SELECT *
FROM options
WHERE value != "null"
`
var opts []kolide.Option
if err := d.db.Select(&opts, sqlStatement); err != nil {
if err == sql.ErrNoRows {
return nil, notFound("Option")
}
return nil, errors.Wrap(err, "select from options")
}
optConfig := map[string]interface{}{}
for _, opt := range opts {
optConfig[opt.Name] = opt.GetValue()
}
return optConfig, nil
}

View file

@ -22,6 +22,9 @@ type OptionStore interface {
Option(id uint) (*Option, error)
// OptionByName returns an option uniquely identified by name
OptionByName(name string) (*Option, error)
// GetOsqueryConfigOptions returns options in a format that will be the options
// section of osquery configuration
GetOsqueryConfigOptions() (map[string]interface{}, error)
}
// OptionService interface describes methods that operate on osquery options

View file

@ -39,11 +39,6 @@ type PackContent struct {
type Packs map[string]PackContent
type OsqueryOptions struct {
PackDelimiter string `json:"pack_delimiter,omitempty"`
DisableDistributed bool `json:"disable_distributed"`
}
type Decorators struct {
Load []string `json:"load,omitempty"`
Always []string `json:"always,omitempty"`
@ -51,9 +46,9 @@ type Decorators struct {
}
type OsqueryConfig struct {
Options OsqueryOptions `json:"options,omitempty"`
Decorators Decorators `json:"decorators,omitempty"`
Packs Packs `json:"packs,omitempty"`
Options map[string]interface{} `json:"options"`
Decorators Decorators `json:"decorators,omitempty"`
Packs Packs `json:"packs,omitempty"`
}
type OsqueryResultLog struct {

View file

@ -64,12 +64,14 @@ func (svc service) GetClientConfig(ctx context.Context) (*kolide.OsqueryConfig,
return nil, osqueryError{message: "internal error: missing host from request context"}
}
options, err := svc.ds.GetOsqueryConfigOptions()
if err != nil {
return nil, osqueryError{message: "internal error: unable to fetch configuration options"}
}
config := &kolide.OsqueryConfig{
Options: kolide.OsqueryOptions{
PackDelimiter: "/",
DisableDistributed: false,
},
Packs: kolide.Packs{},
Options: options,
Packs: kolide.Packs{},
}
packs, err := svc.ListPacksForHost(ctx, host.ID)

View file

@ -405,8 +405,16 @@ func TestGetClientConfig(t *testing.T) {
config, err := svc.GetClientConfig(ctx)
require.Nil(t, err)
assert.NotNil(t, config)
assert.False(t, config.Options.DisableDistributed)
assert.Equal(t, "/", config.Options.PackDelimiter)
val, ok := config.Options["disable_distributed"]
require.True(t, ok)
disabled, ok := val.(bool)
require.True(t, ok)
assert.False(t, disabled)
val, ok = config.Options["pack_delimiter"]
require.True(t, ok)
delim, ok := val.(string)
require.True(t, ok)
assert.Equal(t, "/", delim)
// this will be greater than 0 if we ever start inserting an administration
// pack

View file

@ -1,7 +1,7 @@
package service
import (
"fmt"
"errors"
"github.com/kolide/kolide-ose/server/kolide"
"golang.org/x/net/context"
@ -25,8 +25,8 @@ func (mw validationMiddleware) ModifyOptions(ctx context.Context, req kolide.Opt
}
var (
errTypeMismatch = fmt.Errorf("type mismatch")
errInvalidType = fmt.Errorf("invalid option type")
errTypeMismatch = errors.New("type mismatch")
errInvalidType = errors.New("invalid option type")
)
func validateValueMapsToOptionType(opt kolide.Option) error {