From fd61dcab67f341c9e47fb6cb968171650c19a681 Mon Sep 17 00:00:00 2001 From: Zachary Wasserman Date: Wed, 8 Jul 2020 13:02:18 -0700 Subject: [PATCH] Clean up unused DB tables, migrations, and code (#2258) This PR removes unused types, code, DB tables, and associated migrations that are unused since Fleet 2.0. An existing migration was refactored, and should remain compatible with both existing and new Fleet installations. --- server/datastore/datastore_options_test.go | 135 ------------- server/datastore/datastore_test.go | 5 - server/datastore/datastore_yara_test.go | 107 ----------- .../file_integrity_monitoring_test.go | 45 ----- server/datastore/inmem/decorators.go | 50 ----- .../inmem/file_integrity_monitoring.go | 27 --- server/datastore/inmem/inmem.go | 22 --- server/datastore/inmem/options.go | 90 --------- server/datastore/inmem/yara.go | 35 ---- server/datastore/internal/appstate/options.go | 78 -------- .../mysql/file_integrity_monitoring.go | 74 ------- .../20161223115449_InsertOsqueryOptions.go | 54 ------ .../20170309091824_AddBuiltInDecorators.go | 40 ---- .../20171027173700_AddTitlesToDecorators.go | 33 ---- .../20171212182458_MigrateOsqueryOptions.go | 123 ------------ ...0171116163618_CreateTableOsqueryOptions.go | 146 +++++++++++++- .../tables/20200707120000_DropUnusedTables.go | 54 ++++++ .../migrations/tables/deprecated_types.go | 180 +++++++++++++++++ server/datastore/mysql/options.go | 174 ----------------- server/datastore/mysql/yara.go | 122 ------------ server/kolide/datastore.go | 3 - server/kolide/decorators.go | 89 --------- server/kolide/file_integrity_monitoring.go | 45 ----- server/kolide/options.go | 181 ------------------ server/kolide/options_test.go | 47 ----- server/kolide/osquery.go | 24 --- server/kolide/service.go | 2 - server/kolide/yara.go | 31 --- server/mock/datastore.go | 3 - server/mock/datastore_fim.go | 39 ---- server/mock/datastore_options.go | 69 ------- server/service/endpoint_fim.go | 40 ---- server/service/endpoint_options.go | 46 ----- server/service/endpoint_options_test.go | 83 -------- server/service/endpoint_test.go | 4 - server/service/handler.go | 26 --- server/service/logging_fim.go | 32 ---- server/service/logging_options.go | 66 ------- server/service/metrics_fim.go | 29 --- server/service/metrics_options.go | 51 ----- server/service/service_fim.go | 66 ------- server/service/service_fim_test.go | 101 ---------- server/service/service_options.go | 26 --- server/service/transport_fim.go | 17 -- server/service/transport_options.go | 17 -- server/service/validation_options.go | 53 ----- 46 files changed, 378 insertions(+), 2406 deletions(-) delete mode 100644 server/datastore/datastore_options_test.go delete mode 100644 server/datastore/datastore_yara_test.go delete mode 100644 server/datastore/file_integrity_monitoring_test.go delete mode 100644 server/datastore/inmem/decorators.go delete mode 100644 server/datastore/inmem/file_integrity_monitoring.go delete mode 100644 server/datastore/inmem/options.go delete mode 100644 server/datastore/inmem/yara.go delete mode 100644 server/datastore/internal/appstate/options.go delete mode 100644 server/datastore/mysql/file_integrity_monitoring.go delete mode 100644 server/datastore/mysql/migrations/data/20161223115449_InsertOsqueryOptions.go delete mode 100644 server/datastore/mysql/migrations/data/20170309091824_AddBuiltInDecorators.go delete mode 100644 server/datastore/mysql/migrations/data/20171027173700_AddTitlesToDecorators.go delete mode 100644 server/datastore/mysql/migrations/data/20171212182458_MigrateOsqueryOptions.go create mode 100644 server/datastore/mysql/migrations/tables/20200707120000_DropUnusedTables.go create mode 100644 server/datastore/mysql/migrations/tables/deprecated_types.go delete mode 100644 server/datastore/mysql/options.go delete mode 100644 server/datastore/mysql/yara.go delete mode 100644 server/kolide/decorators.go delete mode 100644 server/kolide/file_integrity_monitoring.go delete mode 100644 server/kolide/options.go delete mode 100644 server/kolide/options_test.go delete mode 100644 server/kolide/yara.go delete mode 100644 server/mock/datastore_fim.go delete mode 100644 server/mock/datastore_options.go delete mode 100644 server/service/endpoint_fim.go delete mode 100644 server/service/endpoint_options.go delete mode 100644 server/service/endpoint_options_test.go delete mode 100644 server/service/logging_fim.go delete mode 100644 server/service/logging_options.go delete mode 100644 server/service/metrics_fim.go delete mode 100644 server/service/metrics_options.go delete mode 100644 server/service/service_fim.go delete mode 100644 server/service/service_fim_test.go delete mode 100644 server/service/service_options.go delete mode 100644 server/service/transport_fim.go delete mode 100644 server/service/transport_options.go delete mode 100644 server/service/validation_options.go diff --git a/server/datastore/datastore_options_test.go b/server/datastore/datastore_options_test.go deleted file mode 100644 index 62b9421622..0000000000 --- a/server/datastore/datastore_options_test.go +++ /dev/null @@ -1,135 +0,0 @@ -package datastore - -import ( - "reflect" - "sort" - "testing" - - "github.com/kolide/fleet/server/datastore/internal/appstate" - "github.com/kolide/fleet/server/kolide" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func testOptions(t *testing.T, ds kolide.Datastore) { - if ds.Name() == "inmem" { - t.Skip("inmem is being depracated") - } - require.Nil(t, ds.MigrateData()) - // were options pre-loaded? - opts, err := ds.ListOptions() - require.Nil(t, err) - assert.Len(t, opts, len(appstate.Options())) - - opt, err := ds.OptionByName("aws_profile_name") - require.Nil(t, err) - assert.False(t, opt.OptionSet()) - - // try to save non-readonly list of options with same values, it should not err out - var writableOpts []kolide.Option - for _, o := range opts { - if !o.ReadOnly { - writableOpts = append(writableOpts, o) - } - } - err = ds.SaveOptions(writableOpts) - assert.Nil(t, err) - - opt, err = ds.OptionByName("aws_access_key_id") - require.Nil(t, err) - require.NotNil(t, opt) - opt2, err := ds.Option(opt.ID) - require.Nil(t, err) - require.NotNil(t, opt2) - assert.True(t, reflect.DeepEqual(opt, opt2)) - - opt.SetValue("somekey") - err = ds.SaveOptions([]kolide.Option{*opt}) - require.Nil(t, err) - opt, err = ds.Option(opt.ID) - require.Nil(t, err) - assert.Equal(t, "somekey", opt.GetValue()) - - // can't change a read only option - opt, err = ds.OptionByName("disable_distributed") - require.Nil(t, err) - opt.SetValue(true) - err = ds.SaveOptions([]kolide.Option{*opt}) - assert.NotNil(t, err) - // check that it didn't change - opt, err = ds.OptionByName("disable_distributed") - require.Nil(t, err) - require.False(t, opt.GetValue().(bool)) - - opt, _ = ds.OptionByName("aws_profile_name") - assert.False(t, opt.OptionSet()) - opt.SetValue("zip") - opt2, _ = ds.OptionByName("disable_distributed") - assert.Equal(t, false, opt2.GetValue()) - opt2.SetValue(true) - modList := []kolide.Option{*opt, *opt2} - // The aws access key option can be saved but because the disable_events can't - // be we want to verify that the whole transaction is rolled back - tx, err := ds.Begin() - require.Nil(t, err) - err = ds.SaveOptions(modList, kolide.HasTransaction(tx)) - assert.NotNil(t, err) - err = tx.Rollback() - require.Nil(t, err) - - opt2, err = ds.OptionByName("disable_distributed") - require.Nil(t, err) - assert.Equal(t, false, opt2.GetValue()) - opt, err = ds.OptionByName("aws_profile_name") - require.Nil(t, err) - assert.False(t, opt.OptionSet()) - -} - -func testOptionsToConfig(t *testing.T, ds kolide.Datastore) { - require.Nil(t, ds.MigrateData()) - resp, err := ds.GetOsqueryConfigOptions() - require.Nil(t, err) - assert.Len(t, resp, 8) - 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, 9) - assert.Equal(t, "zip", resp["aws_profile_name"]) -} - -func testResetOptions(t *testing.T, ds kolide.Datastore) { - if ds.Name() == "inmem" { - t.Skip("inmem is being deprecated, test skipped") - } - require.Nil(t, ds.MigrateData()) - // get originals - originals, err := ds.ListOptions() - require.Nil(t, err) - sort.SliceStable(originals, func(i, j int) bool { return originals[i].ID < originals[j].ID }) - - // grab and options, change it, save it, verify that saved - opt, err := ds.OptionByName("aws_profile_name") - require.Nil(t, err) - assert.False(t, opt.OptionSet()) - opt.SetValue("zip") - err = ds.SaveOptions([]kolide.Option{*opt}) - require.Nil(t, err) - opt, _ = ds.OptionByName("aws_profile_name") - assert.Equal(t, "zip", opt.GetValue()) - - resetOptions, err := ds.ResetOptions() - require.Nil(t, err) - sort.SliceStable(resetOptions, func(i, j int) bool { return resetOptions[i].ID < resetOptions[j].ID }) - require.Equal(t, len(originals), len(resetOptions)) - - for i, _ := range originals { - require.Equal(t, originals[i].ID, resetOptions[i].ID) - require.Equal(t, originals[i].GetValue(), resetOptions[i].GetValue()) - require.Equal(t, originals[i].Name, resetOptions[i].Name) - } -} diff --git a/server/datastore/datastore_test.go b/server/datastore/datastore_test.go index 0d6d4888ac..40587da628 100644 --- a/server/datastore/datastore_test.go +++ b/server/datastore/datastore_test.go @@ -64,12 +64,8 @@ var testFunctions = [...]func(*testing.T, kolide.Datastore){ testNewScheduledQuery, testListScheduledQueriesInPack, testCascadingDeletionOfQueries, - testOptions, - testOptionsToConfig, testGetPackByName, testGetQueryByName, - testFileIntegrityMonitoring, - testYARAStore, testAddLabelToPackTwice, testGenerateHostStatusStatistics, testMarkHostSeen, @@ -83,7 +79,6 @@ var testFunctions = [...]func(*testing.T, kolide.Datastore){ testUnicode, testCountHostsInTargets, testHostStatus, - testResetOptions, testApplyOsqueryOptions, testApplyOsqueryOptionsNoOverrides, testOsqueryOptionsForHost, diff --git a/server/datastore/datastore_yara_test.go b/server/datastore/datastore_yara_test.go deleted file mode 100644 index de8bf66cec..0000000000 --- a/server/datastore/datastore_yara_test.go +++ /dev/null @@ -1,107 +0,0 @@ -package datastore - -import ( - "testing" - - "github.com/kolide/fleet/server/kolide" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func testYARAStore(t *testing.T, ds kolide.Datastore) { - ysg := &kolide.YARASignatureGroup{ - SignatureName: "sig1", - Paths: []string{ - "path1", - "path2", - }, - } - ysg, err := ds.NewYARASignatureGroup(ysg) - require.Nil(t, err) - require.True(t, ysg.ID > 0) - fp := &kolide.FIMSection{ - SectionName: "fp1", - Paths: []string{ - "path1", - "path2", - "path3", - }, - } - fp, err = ds.NewFIMSection(fp) - require.Nil(t, err) - assert.True(t, fp.ID > 0) - - err = ds.NewYARAFilePath("fp1", "sig1") - require.Nil(t, err) - yaraSection, err := ds.YARASection() - require.Nil(t, err) - require.Len(t, yaraSection.FilePaths, 1) - assert.Len(t, yaraSection.FilePaths["fp1"], 1) - require.Len(t, yaraSection.Signatures, 1) - assert.Len(t, yaraSection.Signatures["sig1"], 2) - ysg = &kolide.YARASignatureGroup{ - SignatureName: "sig2", - Paths: []string{ - "path3", - }, - } - ysg, err = ds.NewYARASignatureGroup(ysg) - require.Nil(t, err) - yaraSection, err = ds.YARASection() - require.Nil(t, err) - assert.Len(t, yaraSection.Signatures["sig2"], 1) -} - -func testYARATransactions(t *testing.T, ds kolide.Datastore) { - if ds.Name() == "inmem" { - t.Skip("not implemented for inmem") - } - - ysg := &kolide.YARASignatureGroup{ - SignatureName: "sig1", - Paths: []string{ - "path1", - "path2", - }, - } - ysg, err := ds.NewYARASignatureGroup(ysg) - require.Nil(t, err) - require.True(t, ysg.ID > 0) - fp := &kolide.FIMSection{ - SectionName: "fp1", - Paths: []string{ - "path1", - "path2", - "path3", - }, - } - fp, err = ds.NewFIMSection(fp) - require.Nil(t, err) - assert.True(t, fp.ID > 0) - tx, err := ds.Begin() - require.Nil(t, err) - - err = ds.NewYARAFilePath("fp1", "sig1", kolide.HasTransaction(tx)) - require.Nil(t, err) - err = tx.Rollback() - require.Nil(t, err) - yaraSection, err := ds.YARASection() - require.Nil(t, err) - require.NotNil(t, yaraSection) - // there shouldn't be any file paths because we rolled back the transaction - require.Len(t, yaraSection.FilePaths, 0) - - // try it again - tx, err = ds.Begin() - require.Nil(t, err) - err = ds.NewYARAFilePath("fp1", "sig1", kolide.HasTransaction(tx)) - require.Nil(t, err) - err = tx.Commit() - require.Nil(t, err) - yaraSection, err = ds.YARASection() - require.Nil(t, err) - require.NotNil(t, yaraSection) - // file path should exist because we committed - require.Len(t, yaraSection.FilePaths, 1) - -} diff --git a/server/datastore/file_integrity_monitoring_test.go b/server/datastore/file_integrity_monitoring_test.go deleted file mode 100644 index e751001491..0000000000 --- a/server/datastore/file_integrity_monitoring_test.go +++ /dev/null @@ -1,45 +0,0 @@ -package datastore - -import ( - "testing" - - "github.com/kolide/fleet/server/kolide" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func testFileIntegrityMonitoring(t *testing.T, ds kolide.Datastore) { - fp := &kolide.FIMSection{ - SectionName: "fp1", - Paths: []string{ - "path1", - "path2", - "path3", - }, - } - fp, err := ds.NewFIMSection(fp) - require.Nil(t, err) - assert.True(t, fp.ID > 0) - fp = &kolide.FIMSection{ - SectionName: "fp2", - Paths: []string{ - "path4", - "path5", - }, - } - _, err = ds.NewFIMSection(fp) - require.Nil(t, err) - - actual, err := ds.FIMSections() - require.Nil(t, err) - assert.Len(t, actual, 2) - assert.Len(t, actual["fp1"], 3) - assert.Len(t, actual["fp2"], 2) - - err = ds.ClearFIMSections() - require.Nil(t, err) - fs, err := ds.FIMSections() - assert.Nil(t, err) - assert.Len(t, fs, 0) - -} diff --git a/server/datastore/inmem/decorators.go b/server/datastore/inmem/decorators.go deleted file mode 100644 index bb56a14dde..0000000000 --- a/server/datastore/inmem/decorators.go +++ /dev/null @@ -1,50 +0,0 @@ -package inmem - -import "github.com/kolide/fleet/server/kolide" - -func (d *Datastore) SaveDecorator(dec *kolide.Decorator, opts ...kolide.OptionalArg) error { - d.mtx.Lock() - defer d.mtx.Unlock() - if _, ok := d.decorators[dec.ID]; !ok { - return notFound("Decorator") - } - d.decorators[dec.ID] = dec - return nil -} - -func (d *Datastore) NewDecorator(decorator *kolide.Decorator, opts ...kolide.OptionalArg) (*kolide.Decorator, error) { - d.mtx.Lock() - defer d.mtx.Unlock() - decorator.ID = d.nextID(decorator) - d.decorators[decorator.ID] = decorator - return decorator, nil -} - -func (d *Datastore) DeleteDecorator(id uint) error { - d.mtx.Lock() - defer d.mtx.Unlock() - if _, ok := d.decorators[id]; !ok { - return notFound("Decorator").WithID(id) - } - delete(d.decorators, id) - return nil -} - -func (d *Datastore) Decorator(id uint) (*kolide.Decorator, error) { - d.mtx.Lock() - defer d.mtx.Unlock() - if result, ok := d.decorators[id]; ok { - return result, nil - } - return nil, notFound("Decorator").WithID(id) -} - -func (d *Datastore) ListDecorators(opts ...kolide.OptionalArg) ([]*kolide.Decorator, error) { - d.mtx.Lock() - defer d.mtx.Unlock() - var result []*kolide.Decorator - for _, dec := range d.decorators { - result = append(result, dec) - } - return result, nil -} diff --git a/server/datastore/inmem/file_integrity_monitoring.go b/server/datastore/inmem/file_integrity_monitoring.go deleted file mode 100644 index 844666949b..0000000000 --- a/server/datastore/inmem/file_integrity_monitoring.go +++ /dev/null @@ -1,27 +0,0 @@ -package inmem - -import ( - "github.com/kolide/fleet/server/kolide" -) - -func (d *Datastore) NewFIMSection(fp *kolide.FIMSection, opts ...kolide.OptionalArg) (*kolide.FIMSection, error) { - d.mtx.Lock() - defer d.mtx.Unlock() - fp.ID = d.nextID(fp) - d.filePaths[fp.ID] = fp - return fp, nil -} - -func (d *Datastore) FIMSections() (kolide.FIMSections, error) { - d.mtx.Lock() - defer d.mtx.Unlock() - result := make(kolide.FIMSections) - for _, filePath := range d.filePaths { - result[filePath.SectionName] = append(result[filePath.SectionName], filePath.Paths...) - } - return result, nil -} - -func (d *Datastore) ClearFIMSections() error { - panic("inmem is being deprecated") -} diff --git a/server/datastore/inmem/inmem.go b/server/datastore/inmem/inmem.go index 628844b578..9fe90fd220 100644 --- a/server/datastore/inmem/inmem.go +++ b/server/datastore/inmem/inmem.go @@ -8,7 +8,6 @@ import ( "time" "github.com/kolide/fleet/server/config" - "github.com/kolide/fleet/server/datastore/internal/appstate" "github.com/kolide/fleet/server/kolide" "github.com/patrickmn/sortutil" ) @@ -32,11 +31,6 @@ type Datastore struct { distributedQueryExecutions map[uint]kolide.DistributedQueryExecution distributedQueryCampaigns map[uint]kolide.DistributedQueryCampaign distributedQueryCampaignTargets map[uint]kolide.DistributedQueryCampaignTarget - options map[uint]*kolide.Option - decorators map[uint]*kolide.Decorator - filePaths map[uint]*kolide.FIMSection - yaraFilePaths kolide.YARAFilePaths - yaraSignatureGroups map[uint]*kolide.YARASignatureGroup appConfig *kolide.AppConfig config *config.KolideConfig @@ -105,27 +99,11 @@ func (d *Datastore) MigrateTables() error { d.distributedQueryExecutions = make(map[uint]kolide.DistributedQueryExecution) d.distributedQueryCampaigns = make(map[uint]kolide.DistributedQueryCampaign) d.distributedQueryCampaignTargets = make(map[uint]kolide.DistributedQueryCampaignTarget) - d.options = make(map[uint]*kolide.Option) - d.decorators = make(map[uint]*kolide.Decorator) - d.filePaths = make(map[uint]*kolide.FIMSection) - d.yaraFilePaths = make(kolide.YARAFilePaths) - d.yaraSignatureGroups = make(map[uint]*kolide.YARASignatureGroup) return nil } func (d *Datastore) MigrateData() error { - for _, initData := range appstate.Options() { - opt := kolide.Option{ - Name: initData.Name, - Value: kolide.OptionValue{Val: initData.Value}, - Type: initData.Type, - ReadOnly: initData.ReadOnly, - } - opt.ID = d.nextID(opt) - d.options[opt.ID] = &opt - } - d.appConfig = &kolide.AppConfig{ ID: 1, SMTPEnableTLS: true, diff --git a/server/datastore/inmem/options.go b/server/datastore/inmem/options.go deleted file mode 100644 index ab41e6c611..0000000000 --- a/server/datastore/inmem/options.go +++ /dev/null @@ -1,90 +0,0 @@ -package inmem - -import ( - "fmt" - - "github.com/kolide/fleet/server/kolide" - "github.com/patrickmn/sortutil" -) - -func (d *Datastore) ResetOptions() ([]kolide.Option, error) { - panic("inmem is being deprecated") -} - -func (d *Datastore) OptionByName(name string, args ...kolide.OptionalArg) (*kolide.Option, error) { - d.mtx.Lock() - defer d.mtx.Unlock() - for _, opt := range d.options { - if opt.Name == name { - result := *opt - return &result, nil - } - } - return nil, notFound("options") -} - -type optPair struct { - newOpt kolide.Option - existingOpt *kolide.Option -} - -func (d *Datastore) SaveOptions(opts []kolide.Option, args ...kolide.OptionalArg) error { - d.mtx.Lock() - defer d.mtx.Unlock() - var validPairs []optPair - for _, opt := range opts { - if opt.ReadOnly { - return fmt.Errorf("readonly option can't be changed") - } - existing, ok := d.options[opt.ID] - if !ok { - return notFound("option") - } - if existing.Type != opt.Type { - return fmt.Errorf("type mismatch for option") - } - validPairs = append(validPairs, optPair{opt, existing}) - } - // if all the options to be modified pass validation copy values over to - // existing options - if len(validPairs) == len(opts) { - for _, pair := range validPairs { - pair.existingOpt.Value.Val = pair.newOpt.Value.Val - } - } - return nil -} - -func (d *Datastore) Option(id uint) (*kolide.Option, error) { - d.mtx.Lock() - defer d.mtx.Unlock() - saved, ok := d.options[id] - if !ok { - return nil, notFound("Option").WithID(id) - } - result := *saved - return &result, nil -} - -func (d *Datastore) ListOptions() ([]kolide.Option, error) { - d.mtx.Lock() - defer d.mtx.Unlock() - result := []kolide.Option{} - for _, opt := range d.options { - result = append(result, *opt) - } - 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 -} diff --git a/server/datastore/inmem/yara.go b/server/datastore/inmem/yara.go deleted file mode 100644 index 8969231a61..0000000000 --- a/server/datastore/inmem/yara.go +++ /dev/null @@ -1,35 +0,0 @@ -package inmem - -import "github.com/kolide/fleet/server/kolide" - -func (d *Datastore) NewYARASignatureGroup(ysg *kolide.YARASignatureGroup, opts ...kolide.OptionalArg) (*kolide.YARASignatureGroup, error) { - d.mtx.Lock() - defer d.mtx.Unlock() - ysg.ID = d.nextID(ysg) - d.yaraSignatureGroups[ysg.ID] = ysg - return ysg, nil -} - -func (d *Datastore) NewYARAFilePath(fileSectionName, sigGroupName string, opts ...kolide.OptionalArg) error { - d.mtx.Lock() - defer d.mtx.Unlock() - d.yaraFilePaths[fileSectionName] = append(d.yaraFilePaths[fileSectionName], sigGroupName) - return nil -} - -func (d *Datastore) YARASection() (*kolide.YARASection, error) { - d.mtx.Lock() - defer d.mtx.Unlock() - result := &kolide.YARASection{ - Signatures: make(map[string][]string), - FilePaths: make(map[string][]string), - } - for _, ysg := range d.yaraSignatureGroups { - result.Signatures[ysg.SignatureName] = append(result.Signatures[ysg.SignatureName], ysg.Paths...) - } - for fileSection, sigSection := range d.yaraFilePaths { - result.FilePaths[fileSection] = append(result.FilePaths[fileSection], sigSection...) - } - - return result, nil -} diff --git a/server/datastore/internal/appstate/options.go b/server/datastore/internal/appstate/options.go deleted file mode 100644 index 85c88ceea9..0000000000 --- a/server/datastore/internal/appstate/options.go +++ /dev/null @@ -1,78 +0,0 @@ -package appstate - -import "github.com/kolide/fleet/server/kolide" - -// Options is the set of builtin osquery options that should be populated in -// the datastore -func Options() []struct { - Name string - Value interface{} - Type kolide.OptionType - ReadOnly bool -} { - - return []struct { - Name string - Value interface{} - Type kolide.OptionType - ReadOnly bool - }{ - // These options are read only, attempting to modify one of these will - // raise an error - {"disable_distributed", false, kolide.OptionTypeBool, kolide.ReadOnly}, - {"distributed_plugin", "tls", kolide.OptionTypeString, kolide.ReadOnly}, - {"pack_delimiter", "/", kolide.OptionTypeString, kolide.ReadOnly}, - // These options may be modified by an admin user - {"aws_access_key_id", nil, kolide.OptionTypeString, kolide.NotReadOnly}, - {"aws_firehose_period", nil, kolide.OptionTypeInt, kolide.NotReadOnly}, - {"aws_firehose_stream", nil, kolide.OptionTypeString, kolide.NotReadOnly}, - {"aws_kinesis_period", nil, kolide.OptionTypeInt, kolide.NotReadOnly}, - {"aws_kinesis_random_partition_key", nil, kolide.OptionTypeBool, kolide.NotReadOnly}, - {"aws_kinesis_stream", nil, kolide.OptionTypeString, kolide.NotReadOnly}, - {"aws_profile_name", nil, kolide.OptionTypeString, kolide.NotReadOnly}, - {"aws_region", nil, kolide.OptionTypeString, kolide.NotReadOnly}, - {"aws_secret_access_key", nil, kolide.OptionTypeString, kolide.NotReadOnly}, - {"aws_sts_arn_role", nil, kolide.OptionTypeString, kolide.NotReadOnly}, - {"aws_sts_region", nil, kolide.OptionTypeString, kolide.NotReadOnly}, - {"aws_sts_session_name", nil, kolide.OptionTypeString, kolide.NotReadOnly}, - {"aws_sts_timeout", nil, kolide.OptionTypeInt, kolide.NotReadOnly}, - {"buffered_log_max", nil, kolide.OptionTypeInt, kolide.NotReadOnly}, - {"decorations_top_level", nil, kolide.OptionTypeBool, kolide.NotReadOnly}, - {"disable_caching", nil, kolide.OptionTypeBool, kolide.NotReadOnly}, - {"disable_database", nil, kolide.OptionTypeBool, kolide.NotReadOnly}, - {"disable_decorators", nil, kolide.OptionTypeBool, kolide.NotReadOnly}, - {"disable_events", nil, kolide.OptionTypeBool, kolide.NotReadOnly}, - {"disable_kernel", nil, kolide.OptionTypeBool, kolide.NotReadOnly}, - {"disable_logging", nil, kolide.OptionTypeBool, kolide.NotReadOnly}, - {"disable_tables", nil, kolide.OptionTypeString, kolide.NotReadOnly}, - {"distributed_interval", 10, kolide.OptionTypeInt, kolide.NotReadOnly}, - {"distributed_tls_max_attempts", 3, kolide.OptionTypeInt, kolide.NotReadOnly}, - {"enable_foreign", nil, kolide.OptionTypeBool, kolide.NotReadOnly}, - {"enable_monitor", nil, kolide.OptionTypeBool, kolide.NotReadOnly}, - {"ephemeral", nil, kolide.OptionTypeBool, kolide.NotReadOnly}, - {"events_expiry", nil, kolide.OptionTypeInt, kolide.NotReadOnly}, - {"events_max", nil, kolide.OptionTypeInt, kolide.NotReadOnly}, - {"events_optimize", nil, kolide.OptionTypeBool, kolide.NotReadOnly}, - {"host_identifier", nil, kolide.OptionTypeString, kolide.NotReadOnly}, - {"logger_event_type", nil, kolide.OptionTypeBool, kolide.NotReadOnly}, - {"logger_mode", nil, kolide.OptionTypeString, kolide.NotReadOnly}, - {"logger_path", nil, kolide.OptionTypeString, kolide.NotReadOnly}, - {"logger_plugin", "tls", kolide.OptionTypeString, kolide.NotReadOnly}, - {"logger_secondary_status_only", nil, kolide.OptionTypeBool, kolide.NotReadOnly}, - {"logger_syslog_facility", nil, kolide.OptionTypeInt, kolide.NotReadOnly}, - {"logger_tls_compress", nil, kolide.OptionTypeBool, kolide.NotReadOnly}, - {"logger_tls_endpoint", "/api/v1/osquery/log", kolide.OptionTypeString, kolide.NotReadOnly}, - {"logger_tls_max", nil, kolide.OptionTypeInt, kolide.NotReadOnly}, - {"logger_tls_period", 10, kolide.OptionTypeInt, kolide.NotReadOnly}, - {"pack_refresh_interval", nil, kolide.OptionTypeInt, kolide.NotReadOnly}, - {"read_max", nil, kolide.OptionTypeInt, kolide.NotReadOnly}, - {"read_user_max", nil, kolide.OptionTypeInt, kolide.NotReadOnly}, - {"schedule_default_interval", nil, kolide.OptionTypeInt, kolide.NotReadOnly}, - {"schedule_splay_percent", nil, kolide.OptionTypeInt, kolide.NotReadOnly}, - {"schedule_timeout", nil, kolide.OptionTypeInt, kolide.NotReadOnly}, - {"utc", nil, kolide.OptionTypeBool, kolide.NotReadOnly}, - {"value_max", nil, kolide.OptionTypeInt, kolide.NotReadOnly}, - {"verbose", nil, kolide.OptionTypeBool, kolide.NotReadOnly}, - {"worker_threads", nil, kolide.OptionTypeInt, kolide.NotReadOnly}, - } -} diff --git a/server/datastore/mysql/file_integrity_monitoring.go b/server/datastore/mysql/file_integrity_monitoring.go deleted file mode 100644 index 4679257111..0000000000 --- a/server/datastore/mysql/file_integrity_monitoring.go +++ /dev/null @@ -1,74 +0,0 @@ -package mysql - -import ( - "database/sql" - - "github.com/kolide/fleet/server/kolide" - "github.com/pkg/errors" -) - -func (d *Datastore) NewFIMSection(fp *kolide.FIMSection, opts ...kolide.OptionalArg) (result *kolide.FIMSection, err error) { - db := d.getTransaction(opts) - - sqlStatement := ` - INSERT INTO file_integrity_monitorings ( - section_name, - description - ) VALUES( ?, ?) - ` - var resp sql.Result - resp, err = db.Exec(sqlStatement, fp.SectionName, fp.Description) - if isDuplicate(err) { - return nil, alreadyExists("fim_section", 0) - } - if err != nil { - return nil, errors.Wrap(err, "creating fim section") - } - id, _ := resp.LastInsertId() - fp.ID = uint(id) - sqlStatement = ` - INSERT INTO file_integrity_monitoring_files ( - file, - file_integrity_monitoring_id - ) VALUES( ?, ? ) - ` - for _, fileName := range fp.Paths { - _, err = db.Exec(sqlStatement, fileName, fp.ID) - if err != nil { - return nil, errors.Wrap(err, "adding path to fim section") - } - } - return fp, nil -} - -func (d *Datastore) ClearFIMSections() error { - sqlStatement := "DELETE FROM file_integrity_monitorings" - _, err := d.db.Exec(sqlStatement) - return err -} - -func (d *Datastore) FIMSections() (kolide.FIMSections, error) { - sqlStatement := ` - SELECT fim.section_name, mf.file FROM - file_integrity_monitorings AS fim - INNER JOIN file_integrity_monitoring_files AS mf - ON (fim.id = mf.file_integrity_monitoring_id) - ` - rows, err := d.db.Query(sqlStatement) - if err != nil { - if err == sql.ErrNoRows { - return nil, notFound("FilePath") - } - return nil, errors.Wrap(err, "retrieving fim sections") - } - result := make(kolide.FIMSections) - for rows.Next() { - var sectionName, fileName string - err = rows.Scan(§ionName, &fileName) - if err != nil { - return nil, errors.Wrap(err, "retrieving path for fim section") - } - result[sectionName] = append(result[sectionName], fileName) - } - return result, nil -} diff --git a/server/datastore/mysql/migrations/data/20161223115449_InsertOsqueryOptions.go b/server/datastore/mysql/migrations/data/20161223115449_InsertOsqueryOptions.go deleted file mode 100644 index 6bf500a510..0000000000 --- a/server/datastore/mysql/migrations/data/20161223115449_InsertOsqueryOptions.go +++ /dev/null @@ -1,54 +0,0 @@ -package data - -import ( - "database/sql" - - "github.com/kolide/fleet/server/datastore/internal/appstate" - "github.com/kolide/fleet/server/kolide" -) - -func init() { - MigrationClient.AddMigration(Up_20161223115449, Down_20161223115449) -} - -func Up_20161223115449(tx *sql.Tx) error { - sqlStatement := ` - INSERT INTO options ( - name, - type, - value, - read_only - ) VALUES (?, ?, ?, ?) - ` - - for _, opt := range appstate.Options() { - ov := kolide.Option{ - Name: opt.Name, - ReadOnly: opt.ReadOnly, - Type: opt.Type, - Value: kolide.OptionValue{ - Val: opt.Value, - }, - } - _, err := tx.Exec(sqlStatement, ov.Name, ov.Type, ov.Value, ov.ReadOnly) - if err != nil { - return err - } - - } - return nil -} - -func Down_20161223115449(tx *sql.Tx) error { - sqlStatement := ` - DELETE FROM options - WHERE name = ? - ` - for _, opt := range appstate.Options() { - _, err := tx.Exec(sqlStatement, opt.Name) - if err != nil { - return err - } - } - return nil -} diff --git a/server/datastore/mysql/migrations/data/20170309091824_AddBuiltInDecorators.go b/server/datastore/mysql/migrations/data/20170309091824_AddBuiltInDecorators.go deleted file mode 100644 index 8e61693371..0000000000 --- a/server/datastore/mysql/migrations/data/20170309091824_AddBuiltInDecorators.go +++ /dev/null @@ -1,40 +0,0 @@ -package data - -import ( - "database/sql" - - "github.com/kolide/fleet/server/kolide" -) - -func init() { - MigrationClient.AddMigration(Up_20170309091824, Down_20170309091824) -} - -func Up_20170309091824(tx *sql.Tx) error { - sql := "INSERT INTO decorators (" + - "`type`, " + - "`query`, " + - "`built_in`, " + - "`interval`" + - ") VALUES ( ?, ?, TRUE, 0 )" - - rows := []struct { - t kolide.DecoratorType - q string - }{ - {kolide.DecoratorLoad, "SELECT uuid AS host_uuid FROM system_info;"}, - {kolide.DecoratorLoad, "SELECT hostname AS hostname FROM system_info;"}, - } - for _, row := range rows { - _, err := tx.Exec(sql, row.t, row.q) - if err != nil { - return err - } - } - return nil -} - -func Down_20170309091824(tx *sql.Tx) error { - _, err := tx.Exec("DELETE FROM decorators WHERE built_in = TRUE") - return err -} diff --git a/server/datastore/mysql/migrations/data/20171027173700_AddTitlesToDecorators.go b/server/datastore/mysql/migrations/data/20171027173700_AddTitlesToDecorators.go deleted file mode 100644 index e330aa1cb3..0000000000 --- a/server/datastore/mysql/migrations/data/20171027173700_AddTitlesToDecorators.go +++ /dev/null @@ -1,33 +0,0 @@ -package data - -import ( - "database/sql" -) - -func init() { - MigrationClient.AddMigration(Up_20171027173700, Down_20171027173700) -} - -func Up_20171027173700(tx *sql.Tx) error { - sql := "UPDATE decorators SET name=? where query=?" - - rows := []struct { - name string - query string - }{ - {"Host UUID", "SELECT uuid AS host_uuid FROM system_info;"}, - {"Hostname", "SELECT hostname AS hostname FROM system_info;"}, - } - for _, row := range rows { - _, err := tx.Exec(sql, row.name, row.query) - if err != nil { - return err - } - } - return nil -} - -func Down_20171027173700(tx *sql.Tx) error { - _, err := tx.Exec("UPDATE decorators SET name='' WHERE built_in = TRUE") - return err -} diff --git a/server/datastore/mysql/migrations/data/20171212182458_MigrateOsqueryOptions.go b/server/datastore/mysql/migrations/data/20171212182458_MigrateOsqueryOptions.go deleted file mode 100644 index 2030b28fb4..0000000000 --- a/server/datastore/mysql/migrations/data/20171212182458_MigrateOsqueryOptions.go +++ /dev/null @@ -1,123 +0,0 @@ -package data - -import ( - "database/sql" - "encoding/json" - "fmt" - "strconv" - - "github.com/jmoiron/sqlx" - "github.com/jmoiron/sqlx/reflectx" - "github.com/kolide/fleet/server/kolide" - "github.com/pkg/errors" -) - -func init() { - MigrationClient.AddMigration(Up_20171212182458, Down_20171212182458) -} - -type configForExport struct { - Options map[string]interface{} `json:"options"` - FilePaths map[string][]string `json:"file_paths,omitempty"` - Decorators kolide.Decorators `json:"decorators"` -} - -func Up_20171212182458(tx *sql.Tx) error { - // Migrate pre fleetctl osquery options to the new osquery options - // formats. - txx := sqlx.Tx{Tx: tx, Mapper: reflectx.NewMapperFunc("db", sqlx.NameMapper)} - - // Get basic osquery options - query := ` - SELECT * - FROM options - WHERE value != "null" - ` - // Intentionally initialize empty instead of nil so that we generate a - // config with empty options rather than a null value. - var opts []kolide.Option - if err := txx.Select(&opts, query); err != nil && err != sql.ErrNoRows { - return errors.Wrap(err, "getting options") - } - optConfig := map[string]interface{}{} - for _, opt := range opts { - optConfig[opt.Name] = opt.GetValue() - } - - // Get FIM paths from fim table - query = ` - SELECT fim.section_name, mf.file - FROM file_integrity_monitorings AS fim - INNER JOIN file_integrity_monitoring_files AS mf - ON (fim.id = mf.file_integrity_monitoring_id) - ` - rows, err := txx.Query(query) - if err != nil && err != sql.ErrNoRows { - return errors.Wrap(err, "retrieving fim paths") - } - fimConfig := kolide.FIMSections{} - for rows.Next() { - var sectionName, fileName string - err = rows.Scan(§ionName, &fileName) - if err != nil { - return errors.Wrap(err, "retrieving path for fim section") - } - fimConfig[sectionName] = append(fimConfig[sectionName], fileName) - } - - query = ` - SELECT * - FROM decorators - ORDER by built_in DESC, name ASC - ` - var decorators []*kolide.Decorator - err = txx.Select(&decorators, query) - if err != nil { - return errors.Wrap(err, "retrieving decorators") - } - - decConfig := kolide.Decorators{ - Interval: make(map[string][]string), - } - for _, dec := range decorators { - switch dec.Type { - case kolide.DecoratorLoad: - decConfig.Load = append(decConfig.Load, dec.Query) - case kolide.DecoratorAlways: - decConfig.Always = append(decConfig.Always, dec.Query) - case kolide.DecoratorInterval: - key := strconv.Itoa(int(dec.Interval)) - decConfig.Interval[key] = append(decConfig.Interval[key], dec.Query) - default: - fmt.Printf("Unable to migrate decorator. Please migrate manually: '%s'\n", dec.Query) - } - } - - // Create config JSON - config := configForExport{ - Options: optConfig, - FilePaths: fimConfig, - Decorators: decConfig, - } - confJSON, err := json.Marshal(config) - if err != nil { - return errors.Wrap(err, "marshal config JSON") - } - - // Save config JSON - query = ` - INSERT INTO osquery_options ( - override_type, override_identifier, options - ) VALUES (?, ?, ?) - ` - if _, err = txx.Exec(query, kolide.OptionOverrideTypeDefault, "", string(confJSON)); err != nil { - return errors.Wrap(err, "saving converted options") - } - - return nil -} - -func Down_20171212182458(tx *sql.Tx) error { - // No down migration - return nil -} diff --git a/server/datastore/mysql/migrations/tables/20171116163618_CreateTableOsqueryOptions.go b/server/datastore/mysql/migrations/tables/20171116163618_CreateTableOsqueryOptions.go index 947390893e..2ec8372eba 100644 --- a/server/datastore/mysql/migrations/tables/20171116163618_CreateTableOsqueryOptions.go +++ b/server/datastore/mysql/migrations/tables/20171116163618_CreateTableOsqueryOptions.go @@ -1,6 +1,16 @@ package tables -import "database/sql" +import ( + "database/sql" + "encoding/json" + "fmt" + "strconv" + + "github.com/jmoiron/sqlx" + "github.com/jmoiron/sqlx/reflectx" + "github.com/kolide/fleet/server/kolide" + "github.com/pkg/errors" +) func init() { MigrationClient.AddMigration(Up_20171116163618, Down_20171116163618) @@ -15,7 +25,139 @@ func Up_20171116163618(tx *sql.Tx) error { "PRIMARY KEY (`id`)" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8;" _, err := tx.Exec(sqlStatement) - return err + if err != nil { + return errors.Wrap(err, "create table osquery_options") + } + + // Check whether there are existing options to migrate, or we should insert + // a new default set of options + var count int + err = tx.QueryRow("SELECT count(1) FROM options").Scan(&count) + if err != nil { + return errors.Wrap(err, "get options count") + } + + if count > 0 { + // Migrate existing options + err = migrateOptions(tx) + if err != nil { + return errors.Wrap(err, "migrate options") + } + } else { + // Insert default options + _, err = tx.Exec("INSERT INTO `osquery_options`" + + "(override_type, override_identifier, options)" + + `VALUES (0, "", '{"options": {"logger_plugin": "tls", "pack_delimiter": "/", "logger_tls_period": 10, "distributed_plugin": "tls", "disable_distributed": false, "logger_tls_endpoint": "/api/v1/osquery/log", "distributed_interval": 10, "distributed_tls_max_attempts": 3}, "decorators": {"load": ["SELECT uuid AS host_uuid FROM system_info;", "SELECT hostname AS hostname FROM system_info;"]}}')`, + ) + if err != nil { + return errors.Wrap(err, "insert options") + } + } + + return nil +} + +func migrateOptions(tx *sql.Tx) error { + // This migration uses the deprecated types in deprecated_types.go + + type configForExport struct { + Options map[string]interface{} `json:"options"` + FilePaths map[string][]string `json:"file_paths,omitempty"` + Decorators decorators `json:"decorators"` + } + + // Migrate pre fleetctl osquery options to the new osquery options + // formats. + txx := sqlx.Tx{Tx: tx, Mapper: reflectx.NewMapperFunc("db", sqlx.NameMapper)} + + // Get basic osquery options + query := ` + SELECT * + FROM options + WHERE value != "null" + ` + // Intentionally initialize empty instead of nil so that we generate a + // config with empty options rather than a null value. + var opts []option + if err := txx.Select(&opts, query); err != nil && err != sql.ErrNoRows { + return errors.Wrap(err, "getting options") + } + optConfig := map[string]interface{}{} + for _, opt := range opts { + optConfig[opt.Name] = opt.GetValue() + } + + // Get FIM paths from fim table + query = ` + SELECT fim.section_name, mf.file + FROM file_integrity_monitorings AS fim + INNER JOIN file_integrity_monitoring_files AS mf + ON (fim.id = mf.file_integrity_monitoring_id) + ` + rows, err := txx.Query(query) + if err != nil && err != sql.ErrNoRows { + return errors.Wrap(err, "retrieving fim paths") + } + fimConfig := map[string][]string{} + for rows.Next() { + var sectionName, fileName string + err = rows.Scan(§ionName, &fileName) + if err != nil { + return errors.Wrap(err, "retrieving path for fim section") + } + fimConfig[sectionName] = append(fimConfig[sectionName], fileName) + } + + query = ` + SELECT * + FROM decorators + ORDER by built_in DESC, name ASC + ` + var decs []*decorator + err = txx.Select(&decs, query) + if err != nil { + return errors.Wrap(err, "retrieving decorators") + } + + decConfig := decorators{ + Interval: make(map[string][]string), + } + for _, dec := range decs { + switch dec.Type { + case decoratorLoad: + decConfig.Load = append(decConfig.Load, dec.Query) + case decoratorAlways: + decConfig.Always = append(decConfig.Always, dec.Query) + case decoratorInterval: + key := strconv.Itoa(int(dec.Interval)) + decConfig.Interval[key] = append(decConfig.Interval[key], dec.Query) + default: + fmt.Printf("Unable to migrate decorator. Please migrate manually: '%s'\n", dec.Query) + } + } + + // Create config JSON + config := configForExport{ + Options: optConfig, + FilePaths: fimConfig, + Decorators: decConfig, + } + confJSON, err := json.Marshal(config) + if err != nil { + return errors.Wrap(err, "marshal config JSON") + } + + // Save config JSON + query = ` + INSERT INTO osquery_options ( + override_type, override_identifier, options + ) VALUES (?, ?, ?) + ` + if _, err = txx.Exec(query, kolide.OptionOverrideTypeDefault, "", string(confJSON)); err != nil { + return errors.Wrap(err, "saving converted options") + } + + return nil } func Down_20171116163618(tx *sql.Tx) error { diff --git a/server/datastore/mysql/migrations/tables/20200707120000_DropUnusedTables.go b/server/datastore/mysql/migrations/tables/20200707120000_DropUnusedTables.go new file mode 100644 index 0000000000..e2cfb5f10e --- /dev/null +++ b/server/datastore/mysql/migrations/tables/20200707120000_DropUnusedTables.go @@ -0,0 +1,54 @@ +package tables + +import ( + "database/sql" + + "github.com/pkg/errors" +) + +func init() { + MigrationClient.AddMigration(Up_20200707120000, Down_20200707120000) +} + +func Up_20200707120000(tx *sql.Tx) error { + _, err := tx.Exec("DROP TABLE `decorators`") + if err != nil { + return errors.Wrap(err, "drop decorators table") + } + + _, err = tx.Exec("DROP TABLE `yara_file_paths`") + if err != nil { + return errors.Wrap(err, "drop yara_file_paths table") + } + + _, err = tx.Exec("DROP TABLE `yara_signature_paths`") + if err != nil { + return errors.Wrap(err, "drop yara_signature_paths table") + } + + _, err = tx.Exec("DROP TABLE `yara_signatures`") + if err != nil { + return errors.Wrap(err, "drop yara_signatures table") + } + + _, err = tx.Exec("DROP TABLE `file_integrity_monitoring_files`") + if err != nil { + return errors.Wrap(err, "drop file_integrity_monitoring_files table") + } + + _, err = tx.Exec("DROP TABLE `file_integrity_monitorings`") + if err != nil { + return errors.Wrap(err, "drop file_integrity_monitorings table") + } + + _, err = tx.Exec("DROP TABLE `options`") + if err != nil { + return errors.Wrap(err, "drop file_integrity_monitorings table") + } + + return nil +} + +func Down_20200707120000(tx *sql.Tx) error { + return nil +} diff --git a/server/datastore/mysql/migrations/tables/deprecated_types.go b/server/datastore/mysql/migrations/tables/deprecated_types.go new file mode 100644 index 0000000000..9a7bc9cd44 --- /dev/null +++ b/server/datastore/mysql/migrations/tables/deprecated_types.go @@ -0,0 +1,180 @@ +package tables + +import ( + "database/sql/driver" + "encoding/json" + "errors" + "fmt" + "strings" +) + +// Include a number of types here that were previously used but not needed +// at global scope any more + +type decorator struct { + ID uint `json:"id"` + // Name is an optional human friendly name for the decorator + Name string `json:"name"` + Type decoratorType `json:"type"` + // Interval note this is only pertinent for decoratorInterval type. + Interval uint `json:"interval"` + Query string `json:"query"` + // BuiltIn decorators are loaded in migrations and may not be changed + BuiltIn bool `json:"built_in" db:"built_in"` +} + +type decorators struct { + Load []string `json:"load,omitempty"` + Always []string `json:"always,omitempty"` + Interval map[string][]string `json:"interval,omitempty"` +} + +// optionType defines the type of the value assigned to an option +type optionType int + +const ( + optionTypeString optionType = iota + optionTypeInt + optionTypeBool +) + +// MarshalJSON marshals option type to strings +func (ot optionType) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"%s"`, ot)), nil +} + +// UnmarshalJSON converts json to optionType +func (ot *optionType) UnmarshalJSON(b []byte) error { + switch typ := string(b); strings.Trim(typ, `"`) { + case "string": + *ot = optionTypeString + case "bool": + *ot = optionTypeBool + case "int": + *ot = optionTypeInt + default: + return fmt.Errorf("unsupported option type '%s'", typ) + } + return nil +} + +// String is used to marshal optionType to human readable strings used in JSON payloads +func (ot optionType) String() string { + switch ot { + case optionTypeString: + return "string" + case optionTypeInt: + return "int" + case optionTypeBool: + return "bool" + default: + panic("stringer not implemented for optionType") + } +} + +// optionValue supports Valuer and Scan interfaces for reading and writing +// to the database, and also JSON marshaling +type optionValue struct { + Val interface{} +} + +// Value is called by the DB driver. Note that we store data as JSON +// types, so we can use the JSON marshaller to assign the appropriate +// type when we fetch it from the db +func (ov optionValue) Value() (dv driver.Value, err error) { + return json.Marshal(ov.Val) +} + +// Scan takes db string and turns it into an option type +func (ov *optionValue) Scan(src interface{}) error { + if err := json.Unmarshal(src.([]byte), &ov.Val); err != nil { + return err + } + switch v := ov.Val.(type) { + case float64: + ov.Val = int(v) + } + return nil +} + +// MarshalJSON implements the json.Marshaler interface +func (ov optionValue) MarshalJSON() ([]byte, error) { + return json.Marshal(ov.Val) +} + +// UnmarshalJSON implements the json.Unmarshaler interface +func (ov *optionValue) UnmarshalJSON(b []byte) error { + return json.Unmarshal(b, &ov.Val) +} + +// option represents a possible osquery confguration option +// See https://osquery.readthedocs.io/en/stable/deployment/configuration/ +type option struct { + // ID unique identifier for option assigned by the dbms + ID uint `json:"id"` + // Name of the option which must be unique + Name string `json:"name"` + // Type of value for the option + Type optionType `json:"type"` + // Value of the option which may be nil, bool, int, or string. + Value optionValue `json:"value"` + // ReadOnly if true, this option is required for Fleet to function + // properly and cannot be modified by the end user + ReadOnly bool `json:"read_only" db:"read_only"` +} + +// GetValue returns the value associated with the option +func (opt option) GetValue() interface{} { + return opt.Value.Val +} + +// decoratorType refers to the allowable types of decorator queries. +// See https://osquery.readthedocs.io/en/stable/deployment/configuration/ +type decoratorType int + +const ( + decoratorLoad decoratorType = iota + decoratorAlways + decoratorInterval + decoratorUndefined + + decoratorLoadName = "load" + decoratorAlwaysName = "always" + decoratorIntervalName = "interval" +) + +func (dt decoratorType) String() string { + switch dt { + case decoratorLoad: + return decoratorLoadName + case decoratorAlways: + return decoratorAlwaysName + case decoratorInterval: + return decoratorIntervalName + default: + return "" + } +} + +func (dt *decoratorType) MarshalJSON() ([]byte, error) { + name := dt.String() + if name == "" { + return nil, errors.New("Invalid decorator type") + } + return []byte(`"` + name + `"`), nil +} + +func (dt *decoratorType) UnmarshalJSON(data []byte) error { + name := strings.Trim(string(data), `"`) + switch name { + case decoratorLoadName: + *dt = decoratorLoad + case decoratorAlwaysName: + *dt = decoratorAlways + case decoratorIntervalName: + *dt = decoratorInterval + default: + *dt = decoratorUndefined + } + return nil +} diff --git a/server/datastore/mysql/options.go b/server/datastore/mysql/options.go deleted file mode 100644 index 3f539a73f3..0000000000 --- a/server/datastore/mysql/options.go +++ /dev/null @@ -1,174 +0,0 @@ -package mysql - -import ( - "database/sql" - - "github.com/kolide/fleet/server/datastore/internal/appstate" - "github.com/kolide/fleet/server/kolide" - "github.com/pkg/errors" -) - -// ResetOptions note we use named return values so we can preserve and return -// errors in our defer function -func (d *Datastore) ResetOptions() (opts []kolide.Option, err error) { - // Atomically remove all existing options, reset auto increment so id's will be the - // same as original defaults, and re-insert defaults in option table. - var txn *sql.Tx - txn, err = d.db.Begin() - if err != nil { - return nil, errors.Wrap(err, "reset options begin transaction") - } - - defer func() { - if err != nil { - if txErr := txn.Rollback(); txErr != nil { - err = errors.Wrapf(err, "reset options failed, transaction rollback failed with error: %s", txErr) - } - } - }() - _, err = txn.Exec("DELETE FROM options") - if err != nil { - return nil, errors.Wrap(err, "deleting options in reset options") - } - // Reset auto increment - _, err = txn.Exec("ALTER TABLE `options` AUTO_INCREMENT = 1") - if err != nil { - return nil, errors.Wrap(err, "resetting auto increment counter in reset options") - } - sqlStatement := ` - INSERT INTO options ( - name, - type, - value, - read_only - ) VALUES (?, ?, ?, ?) - ` - for _, defaultOpt := range appstate.Options() { - opt := kolide.Option{ - Name: defaultOpt.Name, - ReadOnly: defaultOpt.ReadOnly, - Type: defaultOpt.Type, - Value: kolide.OptionValue{ - Val: defaultOpt.Value, - }, - } - dbResponse, err := txn.Exec( - sqlStatement, - opt.Name, - opt.Type, - opt.Value, - opt.ReadOnly, - ) - if err != nil { - return nil, errors.Wrap(err, "inserting default option in reset options") - } - id, err := dbResponse.LastInsertId() - if err != nil { - return nil, errors.Wrap(err, "fetching id in reset options") - } - opt.ID = uint(id) - opts = append(opts, opt) - } - err = txn.Commit() - if err != nil { - return nil, errors.Wrap(err, "committing reset options") - } - - return opts, nil -} - -func (d *Datastore) OptionByName(name string, args ...kolide.OptionalArg) (*kolide.Option, error) { - db := d.getTransaction(args) - sqlStatement := ` - SELECT * - FROM options - WHERE name = ? - ` - var option kolide.Option - if err := db.Get(&option, sqlStatement, name); err != nil { - if err == sql.ErrNoRows { - return nil, notFound("Option") - } - return nil, errors.Wrap(err, sqlStatement) - } - return &option, nil -} - -func (d *Datastore) SaveOptions(opts []kolide.Option, args ...kolide.OptionalArg) (err error) { - db := d.getTransaction(args) - - sqlStatement := ` - UPDATE options - SET value = ? - WHERE id = ? AND type = ? AND NOT read_only - ` - - for _, opt := range opts { - resultInfo, err := db.Exec(sqlStatement, opt.Value, opt.ID, opt.Type) - if err != nil { - return errors.Wrap(err, "update options") - } - rowsMatched, err := resultInfo.RowsAffected() - if err != nil { - return errors.Wrap(err, "update options reading rows matched") - } - if rowsMatched == 0 { - return notFound("Option").WithID(opt.ID) - } - } - return err -} - -func (d *Datastore) Option(id uint) (*kolide.Option, error) { - sqlStatement := ` - SELECT * - FROM options - WHERE id = ? - ` - var opt kolide.Option - if err := d.db.Get(&opt, sqlStatement, id); err != nil { - if err == sql.ErrNoRows { - return nil, notFound("Option").WithID(id) - } - return nil, errors.Wrap(err, "select option by ID") - } - return &opt, nil -} - -func (d *Datastore) ListOptions() ([]kolide.Option, error) { - sqlStatement := ` - SELECT * - FROM options - ORDER BY name ASC - ` - 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") - } - 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 -} diff --git a/server/datastore/mysql/yara.go b/server/datastore/mysql/yara.go deleted file mode 100644 index 6c400ef72e..0000000000 --- a/server/datastore/mysql/yara.go +++ /dev/null @@ -1,122 +0,0 @@ -package mysql - -import ( - "database/sql" - - "github.com/kolide/fleet/server/kolide" - "github.com/pkg/errors" -) - -func (d *Datastore) NewYARASignatureGroup(ysg *kolide.YARASignatureGroup, opts ...kolide.OptionalArg) (sg *kolide.YARASignatureGroup, err error) { - dbTx := d.getTransaction(opts) - - sqlStatement := ` - INSERT INTO yara_signatures ( - signature_name - ) VALUES( ? ) - ` - var result sql.Result - result, err = dbTx.Exec(sqlStatement, ysg.SignatureName) - if isDuplicate(err) { - return nil, alreadyExists("yara signature", 0) - } - if err != nil { - return nil, errors.Wrap(err, "inserting new yara signature group") - } - id, _ := result.LastInsertId() - ysg.ID = uint(id) - sqlStatement = ` - INSERT INTO yara_signature_paths ( - file_path, - yara_signature_id - ) VALUES( ?, ? ) - ` - - for _, path := range ysg.Paths { - _, err = dbTx.Exec(sqlStatement, path, ysg.ID) - if err != nil { - return nil, errors.Wrap(err, "inserting new signature path") - } - } - return ysg, nil -} - -func (d *Datastore) NewYARAFilePath(fileSectionName, sigGroupName string, opts ...kolide.OptionalArg) error { - dbTx := d.getTransaction(opts) - - sqlStatement := ` - INSERT INTO yara_file_paths ( - file_integrity_monitoring_id, - yara_signature_id - ) VALUES ( - ( - SELECT fim.id - FROM file_integrity_monitorings AS fim - WHERE fim.section_name = ? - LIMIT 1 - ), - ( - SELECT ys.id AS ys - FROM yara_signatures AS ys - WHERE ys.signature_name = ? - LIMIT 1 - ) - ) - ` - _, err := dbTx.Exec(sqlStatement, fileSectionName, sigGroupName) - if isDuplicate(err) { - return alreadyExists("yara file path", 0) - } - if err != nil { - return errors.Wrap(err, "inserting yara file path") - } - return nil -} - -func (d *Datastore) YARASection() (*kolide.YARASection, error) { - result := &kolide.YARASection{ - Signatures: make(map[string][]string), - FilePaths: make(map[string][]string), - } - sqlStatement := ` - SELECT s.signature_name, p.file_path - FROM yara_signatures AS s - INNER JOIN yara_signature_paths AS p - ON ( s.id = p.yara_signature_id ) - ` - rows, err := d.db.Query(sqlStatement) - if err != nil { - return nil, errors.Wrap(err, "selecting yara information") - } - for rows.Next() { - var sigName, sigPath string - err = rows.Scan(&sigName, &sigPath) - if err != nil { - return nil, errors.Wrap(err, "scanning yara information") - } - result.Signatures[sigName] = append(result.Signatures[sigName], sigPath) - } - - sqlStatement = ` - SELECT f.section_name, y.signature_name - FROM file_integrity_monitorings AS f - INNER JOIN yara_file_paths AS yfp - ON (f.id = yfp.file_integrity_monitoring_id) - INNER JOIN yara_signatures AS y - ON (y.id = yfp.yara_signature_id ) - ` - rows, err = d.db.Query(sqlStatement) - if err != nil { - return nil, errors.Wrap(err, "selecting yara signatures") - } - for rows.Next() { - var sectionName, signatureName string - err = rows.Scan(§ionName, &signatureName) - if err != nil { - return nil, errors.Wrap(err, "scanning yara signature values") - } - result.FilePaths[sectionName] = append(result.FilePaths[sectionName], signatureName) - } - - return result, nil -} diff --git a/server/kolide/datastore.go b/server/kolide/datastore.go index 43faa91699..40dcb8a067 100644 --- a/server/kolide/datastore.go +++ b/server/kolide/datastore.go @@ -14,9 +14,6 @@ type Datastore interface { AppConfigStore InviteStore ScheduledQueryStore - OptionStore - FileIntegrityMonitoringStore - YARAStore OsqueryOptionsStore Name() string Drop() error diff --git a/server/kolide/decorators.go b/server/kolide/decorators.go deleted file mode 100644 index a664edfbcc..0000000000 --- a/server/kolide/decorators.go +++ /dev/null @@ -1,89 +0,0 @@ -package kolide - -import ( - "errors" - "strings" -) - -// DEPRECATED -// Decorators are now stored as JSON in the config, so these types are only -// useful for migrating existing Fleet installations. - -// DecoratorType refers to the allowable types of decorator queries. -// See https://osquery.readthedocs.io/en/stable/deployment/configuration/ -type DecoratorType int - -const ( - DecoratorLoad DecoratorType = iota - DecoratorAlways - DecoratorInterval - DecoratorUndefined - - DecoratorLoadName = "load" - DecoratorAlwaysName = "always" - DecoratorIntervalName = "interval" -) - -func (dt DecoratorType) String() string { - switch dt { - case DecoratorLoad: - return DecoratorLoadName - case DecoratorAlways: - return DecoratorAlwaysName - case DecoratorInterval: - return DecoratorIntervalName - default: - return "" - } -} - -func (dt *DecoratorType) MarshalJSON() ([]byte, error) { - name := dt.String() - if name == "" { - return nil, errors.New("Invalid decorator type") - } - return []byte(`"` + name + `"`), nil -} - -var decNameToType = map[string]DecoratorType{ - DecoratorLoadName: DecoratorLoad, - DecoratorAlwaysName: DecoratorAlways, - DecoratorIntervalName: DecoratorInterval, -} - -func (dt *DecoratorType) UnmarshalJSON(data []byte) error { - name := strings.Trim(string(data), `"`) - switch name { - case DecoratorLoadName: - *dt = DecoratorLoad - case DecoratorAlwaysName: - *dt = DecoratorAlways - case DecoratorIntervalName: - *dt = DecoratorInterval - default: - *dt = DecoratorUndefined - } - return nil -} - -// Decorator contains information about a decorator query. -type Decorator struct { - UpdateCreateTimestamps - ID uint `json:"id"` - // Name is an optional human friendly name for the decorator - Name string `json:"name"` - Type DecoratorType `json:"type"` - // Interval note this is only pertinent for DecoratorInterval type. - Interval uint `json:"interval"` - Query string `json:"query"` - // BuiltIn decorators are loaded in migrations and may not be changed - BuiltIn bool `json:"built_in" db:"built_in"` -} - -type DecoratorPayload struct { - ID uint `json:"id"` - Name *string `json:"name"` - DecoratorType *DecoratorType `json:"type"` - Interval *uint `json:"interval"` - Query *string `json:"query"` -} diff --git a/server/kolide/file_integrity_monitoring.go b/server/kolide/file_integrity_monitoring.go deleted file mode 100644 index e910fdcb35..0000000000 --- a/server/kolide/file_integrity_monitoring.go +++ /dev/null @@ -1,45 +0,0 @@ -package kolide - -import "context" - -type FIMSections map[string][]string - -type FileIntegrityMonitoringStore interface { - // NewFIMSection creates a named group of file paths - NewFIMSection(path *FIMSection, opts ...OptionalArg) (*FIMSection, error) - // FIMSections returns all named file sections - FIMSections() (FIMSections, error) - // ClearFIMSections removes all the FIM information - ClearFIMSections() error -} - -// FileIntegrityMonitoringService methods to update -type FileIntegrityMonitoringService interface { - // GetFIM returns the FIM config - GetFIM(ctx context.Context) (*FIMConfig, error) - // ModifyFIM replaces existing FIM. To disable FIM send FIMConfig with - // empty FilePaths - ModifyFIM(ctx context.Context, fim FIMConfig) error -} - -// FIMSection maps a name to a group of files for the osquery file_paths -// section. -// See https://osquery.readthedocs.io/en/stable/deployment/configuration/ -type FIMSection struct { - ID uint - SectionName string `db:"section_name"` - Description string - Paths []string `db:"-"` -} - -// FIMConfig information to set up File Integrity Monitoring -type FIMConfig struct { - // Interval defines the frequency when the file monitor will run. - Interval uint `json:"interval"` - // FilePaths contains named groups of files to monitor. The hash key is the - // name, the array of strings contains paths to be monitored. - // See https://osquery.readthedocs.io/en/stable/deployment/file-integrity-monitoring/ - FilePaths FIMSections `json:"file_paths,omitempty"` - // FileAccesses defines those name groups of FIMSections which will be monitored for file accesses - FileAccesses []string `json:"file_accesses,omitempty"` -} diff --git a/server/kolide/options.go b/server/kolide/options.go deleted file mode 100644 index 7440dbfcfc..0000000000 --- a/server/kolide/options.go +++ /dev/null @@ -1,181 +0,0 @@ -package kolide - -import ( - "context" - "database/sql/driver" - "encoding/json" - "fmt" - "strings" -) - -// OptionStore interface describes methods to access datastore -type OptionStore interface { - // SaveOptions transactional write of options to storage. If one or more - // values fails validation none of the writes will succeed. Note only option - // values are written. Other option fields are created in migration and do - // not change. Attempting to write ReadOnly options will cause an error. - SaveOptions(opts []Option, args ...OptionalArg) error - // Options returns all options - ListOptions() ([]Option, error) - // Option return an option by ID - Option(id uint) (*Option, error) - // OptionByName returns an option uniquely identified by name - OptionByName(name string, args ...OptionalArg) (*Option, error) - // GetOsqueryConfigOptions returns options in a format that will be the options - // section of osquery configuration - GetOsqueryConfigOptions() (map[string]interface{}, error) - // ResetOptions will reset options to their initial values. This should be used - // with caution as it will remove any options or changes to defaults made by - // the user. Returns a list of default options. - ResetOptions() ([]Option, error) -} - -// OptionService interface describes methods that operate on osquery options -type OptionService interface { - // GetOptions retrieves all options - GetOptions(ctx context.Context) ([]Option, error) - // ModifyOptions will change values of the options in OptionRequest. Note - // passing ReadOnly options will cause an error. - ModifyOptions(ctx context.Context, req OptionRequest) ([]Option, error) - // ResetOptions resets all options to their default values - ResetOptions(ctx context.Context) ([]Option, error) -} - -const ( - ReadOnly = true - NotReadOnly = !ReadOnly -) - -// OptionType defines the type of the value assigned to an option -type OptionType int - -const ( - OptionTypeString OptionType = iota - OptionTypeInt - OptionTypeBool -) - -// String values that map from JSON to OptionType -const ( - optionTypeString = "string" - optionTypeInt = "int" - optionTypeBool = "bool" -) - -// MarshalJSON marshals option type to strings -func (ot OptionType) MarshalJSON() ([]byte, error) { - return []byte(fmt.Sprintf(`"%s"`, ot)), nil -} - -// UnmarshalJSON converts json to OptionType -func (ot *OptionType) UnmarshalJSON(b []byte) error { - switch typ := string(b); strings.Trim(typ, `"`) { - case optionTypeString: - *ot = OptionTypeString - case optionTypeBool: - *ot = OptionTypeBool - case optionTypeInt: - *ot = OptionTypeInt - default: - return fmt.Errorf("unsupported option type '%s'", typ) - } - return nil -} - -// String is used to marshal OptionType to human readable strings used in JSON payloads -func (ot OptionType) String() string { - switch ot { - case OptionTypeString: - return optionTypeString - case OptionTypeInt: - return optionTypeInt - case OptionTypeBool: - return optionTypeBool - default: - panic("stringer not implemented for OptionType") - } -} - -// OptionValue supports Valuer and Scan interfaces for reading and writing -// to the database, and also JSON marshaling -type OptionValue struct { - Val interface{} -} - -// Value is called by the DB driver. Note that we store data as JSON -// types, so we can use the JSON marshaller to assign the appropriate -// type when we fetch it from the db -func (ov OptionValue) Value() (dv driver.Value, err error) { - return json.Marshal(ov.Val) -} - -// Scan takes db string and turns it into an option type -func (ov *OptionValue) Scan(src interface{}) error { - if err := json.Unmarshal(src.([]byte), &ov.Val); err != nil { - return err - } - switch v := ov.Val.(type) { - case float64: - ov.Val = int(v) - } - return nil -} - -// MarshalJSON implements the json.Marshaler interface -func (ov OptionValue) MarshalJSON() ([]byte, error) { - return json.Marshal(ov.Val) -} - -// UnmarshalJSON implements the json.Unmarshaler interface -func (ov *OptionValue) UnmarshalJSON(b []byte) error { - return json.Unmarshal(b, &ov.Val) -} - -// Option represents a possible osquery confguration option -// See https://osquery.readthedocs.io/en/stable/deployment/configuration/ -type Option struct { - // ID unique identifier for option assigned by the dbms - ID uint `json:"id"` - // Name of the option which must be unique - Name string `json:"name"` - // Type of value for the option - Type OptionType `json:"type"` - // Value of the option which may be nil, bool, int, or string. - Value OptionValue `json:"value"` - // ReadOnly if true, this option is required for Fleet to function - // properly and cannot be modified by the end user - ReadOnly bool `json:"read_only" db:"read_only"` -} - -// SetValue sets the value associated with the option -func (opt *Option) SetValue(v interface{}) { - opt.Value.Val = v -} - -func (opt *Option) SameType(compare interface{}) bool { - switch compare.(type) { - case float64: - return opt.Type == OptionTypeInt - case string: - return opt.Type == OptionTypeString - case bool: - return opt.Type == OptionTypeBool - default: - return false - } -} - -// OptionSet returns true if the option has a value assigned to it -func (opt *Option) OptionSet() bool { - return opt.Value.Val != nil -} - -// GetValue returns the value associated with the option -func (opt Option) GetValue() interface{} { - return opt.Value.Val -} - -// OptionRequest contains options that are passed to modify options requests. -type OptionRequest struct { - Options []Option `json:"options"` -} diff --git a/server/kolide/options_test.go b/server/kolide/options_test.go deleted file mode 100644 index 5869cc8f0a..0000000000 --- a/server/kolide/options_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package kolide - -import ( - "encoding/json" - "reflect" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestOptionMarshaller(t *testing.T) { - tests := []struct { - value interface{} - typ OptionType - expected interface{} - }{ - {23, OptionTypeInt, float64(23)}, - {true, OptionTypeBool, true}, - {"foobar", OptionTypeString, "foobar"}, - } - - for _, test := range tests { - optIn := &Option{1, "foo", test.typ, OptionValue{test.value}, true} - buff, err := json.Marshal(optIn) - require.Nil(t, err) - optOut := &Option{} - err = json.Unmarshal(buff, optOut) - require.Nil(t, err) - assert.Equal(t, optIn.ID, optOut.ID) - assert.Equal(t, optIn.Name, optOut.Name) - assert.Equal(t, optIn.ReadOnly, optOut.ReadOnly) - assert.Equal(t, optIn.Type, optOut.Type) - assert.Equal(t, test.expected, optOut.Value.Val) - - } - - // test nil - optIn := &Option{1, "bar", OptionTypeString, OptionValue{nil}, true} - buff, err := json.Marshal(optIn) - require.Nil(t, err) - optOut := &Option{} - err = json.Unmarshal(buff, optOut) - require.Nil(t, err) - assert.True(t, reflect.DeepEqual(optIn, optOut)) - -} diff --git a/server/kolide/osquery.go b/server/kolide/osquery.go index 0d79c897a9..4fc79a55a3 100644 --- a/server/kolide/osquery.go +++ b/server/kolide/osquery.go @@ -78,27 +78,3 @@ type PermissivePackContent struct { type Packs map[string]PackContent type PermissivePacks map[string]PermissivePackContent - -// Decorators is the format of the decorator configuration in an osquery config. -type Decorators struct { - Load []string `json:"load,omitempty"` - Always []string `json:"always,omitempty"` - Interval map[string][]string `json:"interval,omitempty"` -} - -// OsqueryConfig is a struct that can be serialized into a valid osquery config -// using Go's JSON tooling. -type OsqueryConfig struct { - Schedule map[string]QueryContent `json:"schedule,omitempty"` - Options map[string]interface{} `json:"options"` - Decorators Decorators `json:"decorators,omitempty"` - Packs Packs `json:"packs,omitempty"` - // FilePaths contains named collections of file paths used for - // FIM (File Integrity Monitoring) - FilePaths FIMSections `json:"file_paths,omitempty"` -} - -type PermissiveOsqueryConfig struct { - OsqueryConfig - Packs PermissivePacks `jsoon:"packs,omitempty"` -} diff --git a/server/kolide/service.go b/server/kolide/service.go index 9f76e0f322..77c3bbb6c4 100644 --- a/server/kolide/service.go +++ b/server/kolide/service.go @@ -15,7 +15,5 @@ type Service interface { InviteService TargetService ScheduledQueryService - OptionService - FileIntegrityMonitoringService StatusService } diff --git a/server/kolide/yara.go b/server/kolide/yara.go deleted file mode 100644 index f82a6c7bc7..0000000000 --- a/server/kolide/yara.go +++ /dev/null @@ -1,31 +0,0 @@ -package kolide - -// YARAFilePaths represents the files_path section of an osquery config. The -// key maps to file_paths section_name and maps to one or more YARA signature -// group names -type YARAFilePaths map[string][]string - -type YARAStore interface { - // NewYARASignatureGroup creates a new mapping of a name to - // a group of YARA signatures - NewYARASignatureGroup(ysg *YARASignatureGroup, opts ...OptionalArg) (*YARASignatureGroup, error) - // NewYARAFilePath maps a named set of files to one or more - // groups of YARA signatures - NewYARAFilePath(fileSectionName, sigGroupName string, opts ...OptionalArg) error - // YARASection creates the osquery configuration YARA section - YARASection() (*YARASection, error) -} - -// YARASignatureGroup maps a name to a group of YARA Signatures -// See https://osquery.readthedocs.io/en/stable/deployment/yara/ -type YARASignatureGroup struct { - ID uint - SignatureName string `db:"signature_name"` - Paths []string `db:"-"` -} - -// YARASection represents the osquery config for YARA -type YARASection struct { - Signatures map[string][]string `json:"signatures"` - FilePaths map[string][]string `json:"file_paths"` -} diff --git a/server/mock/datastore.go b/server/mock/datastore.go index 09a7e5fbdb..8bf9612e6d 100644 --- a/server/mock/datastore.go +++ b/server/mock/datastore.go @@ -21,18 +21,15 @@ var _ kolide.Datastore = (*Store)(nil) type Store struct { kolide.PasswordResetStore - kolide.YARAStore TargetStore SessionStore CampaignStore ScheduledQueryStore OsqueryOptionsStore - FileIntegrityMonitoringStore AppConfigStore HostStore InviteStore LabelStore - OptionStore PackStore UserStore QueryStore diff --git a/server/mock/datastore_fim.go b/server/mock/datastore_fim.go deleted file mode 100644 index 8047161e61..0000000000 --- a/server/mock/datastore_fim.go +++ /dev/null @@ -1,39 +0,0 @@ -// Automatically generated by mockimpl. DO NOT EDIT! - -package mock - -import "github.com/kolide/fleet/server/kolide" - -var _ kolide.FileIntegrityMonitoringStore = (*FileIntegrityMonitoringStore)(nil) - -type NewFIMSectionFunc func(path *kolide.FIMSection, opts ...kolide.OptionalArg) (*kolide.FIMSection, error) - -type FIMSectionsFunc func() (kolide.FIMSections, error) - -type ClearFIMSectionsFunc func() error - -type FileIntegrityMonitoringStore struct { - NewFIMSectionFunc NewFIMSectionFunc - NewFIMSectionFuncInvoked bool - - FIMSectionsFunc FIMSectionsFunc - FIMSectionsFuncInvoked bool - - ClearFIMSectionsFunc ClearFIMSectionsFunc - ClearFIMSectionsFuncInvoked bool -} - -func (s *FileIntegrityMonitoringStore) NewFIMSection(path *kolide.FIMSection, opts ...kolide.OptionalArg) (*kolide.FIMSection, error) { - s.NewFIMSectionFuncInvoked = true - return s.NewFIMSectionFunc(path, opts...) -} - -func (s *FileIntegrityMonitoringStore) FIMSections() (kolide.FIMSections, error) { - s.FIMSectionsFuncInvoked = true - return s.FIMSectionsFunc() -} - -func (s *FileIntegrityMonitoringStore) ClearFIMSections() error { - s.ClearFIMSectionsFuncInvoked = true - return s.ClearFIMSectionsFunc() -} diff --git a/server/mock/datastore_options.go b/server/mock/datastore_options.go deleted file mode 100644 index c768f80464..0000000000 --- a/server/mock/datastore_options.go +++ /dev/null @@ -1,69 +0,0 @@ -// Automatically generated by mockimpl. DO NOT EDIT! - -package mock - -import "github.com/kolide/fleet/server/kolide" - -var _ kolide.OptionStore = (*OptionStore)(nil) - -type SaveOptionsFunc func(opts []kolide.Option, args ...kolide.OptionalArg) error - -type ListOptionsFunc func() ([]kolide.Option, error) - -type OptionFunc func(id uint) (*kolide.Option, error) - -type OptionByNameFunc func(name string, args ...kolide.OptionalArg) (*kolide.Option, error) - -type GetOsqueryConfigOptionsFunc func() (map[string]interface{}, error) - -type ResetOptionsFunc func() ([]kolide.Option, error) - -type OptionStore struct { - SaveOptionsFunc SaveOptionsFunc - SaveOptionsFuncInvoked bool - - ListOptionsFunc ListOptionsFunc - ListOptionsFuncInvoked bool - - OptionFunc OptionFunc - OptionFuncInvoked bool - - OptionByNameFunc OptionByNameFunc - OptionByNameFuncInvoked bool - - GetOsqueryConfigOptionsFunc GetOsqueryConfigOptionsFunc - GetOsqueryConfigOptionsFuncInvoked bool - - ResetOptionsFunc ResetOptionsFunc - ResetOptionsFuncInvoked bool -} - -func (s *OptionStore) SaveOptions(opts []kolide.Option, args ...kolide.OptionalArg) error { - s.SaveOptionsFuncInvoked = true - return s.SaveOptionsFunc(opts, args...) -} - -func (s *OptionStore) ListOptions() ([]kolide.Option, error) { - s.ListOptionsFuncInvoked = true - return s.ListOptionsFunc() -} - -func (s *OptionStore) Option(id uint) (*kolide.Option, error) { - s.OptionFuncInvoked = true - return s.OptionFunc(id) -} - -func (s *OptionStore) OptionByName(name string, args ...kolide.OptionalArg) (*kolide.Option, error) { - s.OptionByNameFuncInvoked = true - return s.OptionByNameFunc(name, args...) -} - -func (s *OptionStore) GetOsqueryConfigOptions() (map[string]interface{}, error) { - s.GetOsqueryConfigOptionsFuncInvoked = true - return s.GetOsqueryConfigOptionsFunc() -} - -func (s *OptionStore) ResetOptions() ([]kolide.Option, error) { - s.ResetOptionsFuncInvoked = true - return s.ResetOptionsFunc() -} diff --git a/server/service/endpoint_fim.go b/server/service/endpoint_fim.go deleted file mode 100644 index 099f67acf2..0000000000 --- a/server/service/endpoint_fim.go +++ /dev/null @@ -1,40 +0,0 @@ -package service - -import ( - "context" - - "github.com/go-kit/kit/endpoint" - "github.com/kolide/fleet/server/kolide" -) - -type modifyFIMResponse struct { - Err error `json:"error,omitempty"` -} - -func (m modifyFIMResponse) error() error { return m.Err } - -func makeModifyFIMEndpoint(svc kolide.Service) endpoint.Endpoint { - return func(ctx context.Context, req interface{}) (interface{}, error) { - fimConfig := req.(kolide.FIMConfig) - var resp modifyFIMResponse - if err := svc.ModifyFIM(ctx, fimConfig); err != nil { - resp.Err = err - } - return resp, nil - } -} - -type getFIMResponse struct { - Err error `json:"error,omitempty"` - Payload *kolide.FIMConfig `json:"payload,omitempty"` -} - -func makeGetFIMEndpoint(svc kolide.Service) endpoint.Endpoint { - return func(ctx context.Context, _ interface{}) (interface{}, error) { - fimConfig, err := svc.GetFIM(ctx) - if err != nil { - return getFIMResponse{Err: err}, nil - } - return getFIMResponse{Payload: fimConfig}, nil - } -} diff --git a/server/service/endpoint_options.go b/server/service/endpoint_options.go deleted file mode 100644 index 45133d3a5a..0000000000 --- a/server/service/endpoint_options.go +++ /dev/null @@ -1,46 +0,0 @@ -package service - -import ( - "context" - - "github.com/go-kit/kit/endpoint" - "github.com/kolide/fleet/server/kolide" -) - -type optionsResponse struct { - Options []kolide.Option `json:"options,omitempty"` - Err error `json:"error,omitempty"` -} - -func (or optionsResponse) error() error { return or.Err } - -func makeGetOptionsEndpoint(svc kolide.Service) endpoint.Endpoint { - return func(ctx context.Context, request interface{}) (interface{}, error) { - options, err := svc.GetOptions(ctx) - if err != nil { - return optionsResponse{Err: err}, nil - } - return optionsResponse{Options: options}, nil - } -} - -func makeModifyOptionsEndpoint(svc kolide.Service) endpoint.Endpoint { - return func(ctx context.Context, request interface{}) (interface{}, error) { - payload := request.(kolide.OptionRequest) - opts, err := svc.ModifyOptions(ctx, payload) - if err != nil { - return optionsResponse{Err: err}, nil - } - return optionsResponse{Options: opts}, nil - } -} - -func makeResetOptionsEndpoint(svc kolide.Service) endpoint.Endpoint { - return func(ctx context.Context, request interface{}) (interface{}, error) { - options, err := svc.ResetOptions(ctx) - if err != nil { - return optionsResponse{Err: err}, nil - } - return optionsResponse{Options: options}, nil - } -} diff --git a/server/service/endpoint_options_test.go b/server/service/endpoint_options_test.go deleted file mode 100644 index 6cb9ca6cce..0000000000 --- a/server/service/endpoint_options_test.go +++ /dev/null @@ -1,83 +0,0 @@ -package service - -import ( - "bytes" - "encoding/json" - "fmt" - "net/http" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func testOptionNotFound(t *testing.T, r *testResource) { - // id 6000 is not an actual option - inJson := `{"options":[ - {"id":6000,"name":"aws_access_key_id","type":"string","value":"foo","read_only":false}, - {"id":7,"name":"aws_firehose_period","type":"int","value":23,"read_only":false}]}` - buff := bytes.NewBufferString(inJson) - req, err := http.NewRequest("PATCH", r.server.URL+"/api/v1/kolide/options", buff) - require.Nil(t, err) - req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", r.adminToken)) - client := &http.Client{} - resp, err := client.Do(req) - require.Nil(t, err) - assert.Equal(t, http.StatusNotFound, resp.StatusCode) -} - -func testGetOptions(t *testing.T, r *testResource) { - req, err := http.NewRequest("GET", r.server.URL+"/api/v1/kolide/options", nil) - require.Nil(t, err) - req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", r.adminToken)) - client := &http.Client{} - resp, err := client.Do(req) - require.Nil(t, err) - require.Equal(t, http.StatusOK, resp.StatusCode) - var optsResp optionsResponse - err = json.NewDecoder(resp.Body).Decode(&optsResp) - require.Nil(t, err) - require.NotNil(t, optsResp.Options) - assert.Equal(t, "aws_access_key_id", optsResp.Options[0].Name) -} - -func testModifyOptions(t *testing.T, r *testResource) { - inJson := `{"options":[ - {"id":6,"name":"aws_access_key_id","type":"string","value":"foo","read_only":false}, - {"id":7,"name":"aws_firehose_period","type":"int","value":23,"read_only":false}]}` - buff := bytes.NewBufferString(inJson) - req, err := http.NewRequest("PATCH", r.server.URL+"/api/v1/kolide/options", buff) - require.Nil(t, err) - req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", r.adminToken)) - client := &http.Client{} - resp, err := client.Do(req) - require.Nil(t, err) - - var optsResp optionsResponse - err = json.NewDecoder(resp.Body).Decode(&optsResp) - require.Nil(t, err) - require.NotNil(t, optsResp.Options) - require.Len(t, optsResp.Options, 2) - assert.Equal(t, "foo", optsResp.Options[0].GetValue()) - assert.Equal(t, float64(23), optsResp.Options[1].GetValue()) -} - -func testModifyOptionsValidationFail(t *testing.T, r *testResource) { - inJson := `{"options":[ - {"id":6,"name":"aws_access_key_id","type":"string","value":"foo","read_only":false}, - {"id":7,"name":"aws_firehose_period","type":"int","value":"xxs","read_only":false}]}` - buff := bytes.NewBufferString(inJson) - req, err := http.NewRequest("PATCH", r.server.URL+"/api/v1/kolide/options", buff) - require.Nil(t, err) - req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", r.adminToken)) - client := &http.Client{} - resp, err := client.Do(req) - require.Nil(t, err) - assert.Equal(t, http.StatusUnprocessableEntity, resp.StatusCode) - var errStruct mockValidationError - err = json.NewDecoder(resp.Body).Decode(&errStruct) - require.Nil(t, err) - require.Len(t, errStruct.Errors, 1) - assert.Equal(t, "aws_firehose_period", errStruct.Errors[0].Name) - assert.Equal(t, "type mismatch", errStruct.Errors[0].Reason) -} diff --git a/server/service/endpoint_test.go b/server/service/endpoint_test.go index ef48f5f630..18c638a25a 100644 --- a/server/service/endpoint_test.go +++ b/server/service/endpoint_test.go @@ -103,10 +103,6 @@ var testFunctions = [...]func(*testing.T, *testResource){ testGetAppConfig, testModifyAppConfig, testModifyAppConfigWithValidationFail, - testGetOptions, - testModifyOptions, - testModifyOptionsValidationFail, - testOptionNotFound, testAdminUserSetAdmin, testNonAdminUserSetAdmin, testAdminUserSetEnabled, diff --git a/server/service/handler.go b/server/service/handler.go index a254e771c4..74879883ea 100644 --- a/server/service/handler.go +++ b/server/service/handler.go @@ -87,9 +87,6 @@ type KolideEndpoints struct { ListHosts endpoint.Endpoint GetHostSummary endpoint.Endpoint SearchTargets endpoint.Endpoint - GetOptions endpoint.Endpoint - ModifyOptions endpoint.Endpoint - ResetOptions endpoint.Endpoint ApplyOsqueryOptionsSpec endpoint.Endpoint GetOsqueryOptionsSpec endpoint.Endpoint GetCertificate endpoint.Endpoint @@ -97,8 +94,6 @@ type KolideEndpoints struct { InitiateSSO endpoint.Endpoint CallbackSSO endpoint.Endpoint SSOSettings endpoint.Endpoint - GetFIM endpoint.Endpoint - ModifyFIM endpoint.Endpoint StatusResultStore endpoint.Endpoint StatusLiveQuery endpoint.Endpoint } @@ -185,15 +180,10 @@ func MakeKolideServerEndpoints(svc kolide.Service, jwtKey, urlPrefix string) Kol GetLabelSpecs: authenticatedUser(jwtKey, svc, makeGetLabelSpecsEndpoint(svc)), GetLabelSpec: authenticatedUser(jwtKey, svc, makeGetLabelSpecEndpoint(svc)), SearchTargets: authenticatedUser(jwtKey, svc, makeSearchTargetsEndpoint(svc)), - GetOptions: authenticatedUser(jwtKey, svc, mustBeAdmin(makeGetOptionsEndpoint(svc))), - ModifyOptions: authenticatedUser(jwtKey, svc, mustBeAdmin(makeModifyOptionsEndpoint(svc))), - ResetOptions: authenticatedUser(jwtKey, svc, mustBeAdmin(makeResetOptionsEndpoint(svc))), ApplyOsqueryOptionsSpec: authenticatedUser(jwtKey, svc, makeApplyOsqueryOptionsSpecEndpoint(svc)), GetOsqueryOptionsSpec: authenticatedUser(jwtKey, svc, makeGetOsqueryOptionsSpecEndpoint(svc)), GetCertificate: authenticatedUser(jwtKey, svc, makeCertificateEndpoint(svc)), ChangeEmail: authenticatedUser(jwtKey, svc, makeChangeEmailEndpoint(svc)), - GetFIM: authenticatedUser(jwtKey, svc, makeGetFIMEndpoint(svc)), - ModifyFIM: authenticatedUser(jwtKey, svc, makeModifyFIMEndpoint(svc)), // Authenticated status endpoints StatusResultStore: authenticatedUser(jwtKey, svc, makeStatusResultStoreEndpoint(svc)), @@ -280,9 +270,6 @@ type kolideHandlers struct { ListHosts http.Handler GetHostSummary http.Handler SearchTargets http.Handler - GetOptions http.Handler - ModifyOptions http.Handler - ResetOptions http.Handler ApplyOsqueryOptionsSpec http.Handler GetOsqueryOptionsSpec http.Handler GetCertificate http.Handler @@ -290,8 +277,6 @@ type kolideHandlers struct { InitiateSSO http.Handler CallbackSSO http.Handler SettingsSSO http.Handler - ModifyFIM http.Handler - GetFIM http.Handler StatusResultStore http.Handler StatusLiveQuery http.Handler } @@ -372,9 +357,6 @@ func makeKolideKitHandlers(e KolideEndpoints, opts []kithttp.ServerOption) *koli ListHosts: newServer(e.ListHosts, decodeListHostsRequest), GetHostSummary: newServer(e.GetHostSummary, decodeNoParamsRequest), SearchTargets: newServer(e.SearchTargets, decodeSearchTargetsRequest), - GetOptions: newServer(e.GetOptions, decodeNoParamsRequest), - ModifyOptions: newServer(e.ModifyOptions, decodeModifyOptionsRequest), - ResetOptions: newServer(e.ResetOptions, decodeNoParamsRequest), ApplyOsqueryOptionsSpec: newServer(e.ApplyOsqueryOptionsSpec, decodeApplyOsqueryOptionsSpecRequest), GetOsqueryOptionsSpec: newServer(e.GetOsqueryOptionsSpec, decodeNoParamsRequest), GetCertificate: newServer(e.GetCertificate, decodeNoParamsRequest), @@ -382,8 +364,6 @@ func makeKolideKitHandlers(e KolideEndpoints, opts []kithttp.ServerOption) *koli InitiateSSO: newServer(e.InitiateSSO, decodeInitiateSSORequest), CallbackSSO: newServer(e.CallbackSSO, decodeCallbackSSORequest), SettingsSSO: newServer(e.SSOSettings, decodeNoParamsRequest), - ModifyFIM: newServer(e.ModifyFIM, decodeModifyFIMRequest), - GetFIM: newServer(e.GetFIM, decodeNoParamsRequest), StatusResultStore: newServer(e.StatusResultStore, decodeNoParamsRequest), StatusLiveQuery: newServer(e.StatusLiveQuery, decodeNoParamsRequest), } @@ -506,12 +486,6 @@ func attachKolideAPIRoutes(r *mux.Router, h *kolideHandlers) { r.Handle("/api/v1/kolide/hosts/{id}", h.GetHost).Methods("GET").Name("get_host") r.Handle("/api/v1/kolide/hosts/{id}", h.DeleteHost).Methods("DELETE").Name("delete_host") - r.Handle("/api/v1/kolide/fim", h.GetFIM).Methods("GET").Name("get_fim") - r.Handle("/api/v1/kolide/fim", h.ModifyFIM).Methods("PATCH").Name("post_fim") - - r.Handle("/api/v1/kolide/options", h.GetOptions).Methods("GET").Name("get_options") - r.Handle("/api/v1/kolide/options", h.ModifyOptions).Methods("PATCH").Name("modify_options") - r.Handle("/api/v1/kolide/options/reset", h.ResetOptions).Methods("GET").Name("reset_options") r.Handle("/api/v1/kolide/spec/osquery_options", h.ApplyOsqueryOptionsSpec).Methods("POST").Name("apply_osquery_options_spec") r.Handle("/api/v1/kolide/spec/osquery_options", h.GetOsqueryOptionsSpec).Methods("GET").Name("get_osquery_options_spec") diff --git a/server/service/logging_fim.go b/server/service/logging_fim.go deleted file mode 100644 index 37cc593ee3..0000000000 --- a/server/service/logging_fim.go +++ /dev/null @@ -1,32 +0,0 @@ -package service - -import ( - "context" - "time" - - "github.com/kolide/fleet/server/kolide" -) - -func (mw loggingMiddleware) GetFIM(ctx context.Context) (cfg *kolide.FIMConfig, err error) { - defer func(begin time.Time) { - _ = mw.loggerDebug(err).Log( - "method", "GetFIM", - "err", err, - "took", time.Since(begin), - ) - }(time.Now()) - cfg, err = mw.Service.GetFIM(ctx) - return cfg, err -} - -func (mw loggingMiddleware) ModifyFIM(ctx context.Context, fim kolide.FIMConfig) (err error) { - defer func(begin time.Time) { - _ = mw.loggerInfo(err).Log( - "method", "ModifyFIM", - "err", err, - "took", time.Since(begin), - ) - }(time.Now()) - err = mw.Service.ModifyFIM(ctx, fim) - return err -} diff --git a/server/service/logging_options.go b/server/service/logging_options.go deleted file mode 100644 index e268234925..0000000000 --- a/server/service/logging_options.go +++ /dev/null @@ -1,66 +0,0 @@ -package service - -import ( - "context" - "time" - - "github.com/kolide/fleet/server/contexts/viewer" - "github.com/kolide/fleet/server/kolide" -) - -func (mw loggingMiddleware) GetOptions(ctx context.Context) ([]kolide.Option, error) { - var ( - options []kolide.Option - err error - ) - - defer func(begin time.Time) { - _ = mw.loggerDebug(err).Log( - "method", "GetOptions", - "err", err, - "took", time.Since(begin), - ) - }(time.Now()) - options, err = mw.Service.GetOptions(ctx) - return options, err -} - -func (mw loggingMiddleware) ModifyOptions(ctx context.Context, req kolide.OptionRequest) ([]kolide.Option, error) { - var ( - options []kolide.Option - err error - loggedInUser = "unauthenticated" - ) - - if vc, ok := viewer.FromContext(ctx); ok { - - loggedInUser = vc.Username() - } - - defer func(begin time.Time) { - _ = mw.loggerInfo(err).Log( - "method", "ModifyOptions", - "err", err, - "user", loggedInUser, - "took", time.Since(begin), - ) - }(time.Now()) - options, err = mw.Service.ModifyOptions(ctx, req) - return options, err -} - -func (mw loggingMiddleware) ResetOptions(ctx context.Context) ([]kolide.Option, error) { - var ( - options []kolide.Option - err error - ) - defer func(begin time.Time) { - _ = mw.loggerInfo(err).Log( - "method", "ResetOptions", - "err", err, - "took", time.Since(begin), - ) - }(time.Now()) - options, err = mw.Service.ResetOptions(ctx) - return options, err -} diff --git a/server/service/metrics_fim.go b/server/service/metrics_fim.go deleted file mode 100644 index a7fd868e1a..0000000000 --- a/server/service/metrics_fim.go +++ /dev/null @@ -1,29 +0,0 @@ -package service - -import ( - "context" - "fmt" - "time" - - "github.com/kolide/fleet/server/kolide" -) - -func (mw metricsMiddleware) GetFIM(ctx context.Context) (cfg *kolide.FIMConfig, err error) { - defer func(begin time.Time) { - lvs := []string{"method", "GetFIM", "error", fmt.Sprint(err != nil)} - mw.requestCount.With(lvs...).Add(1) - mw.requestLatency.With(lvs...).Observe(time.Since(begin).Seconds()) - }(time.Now()) - cfg, err = mw.Service.GetFIM(ctx) - return cfg, err -} - -func (mw metricsMiddleware) ModifyFIM(ctx context.Context, fim kolide.FIMConfig) (err error) { - defer func(begin time.Time) { - lvs := []string{"method", "ModifyFIM", "error", fmt.Sprint(err != nil)} - mw.requestCount.With(lvs...).Add(1) - mw.requestLatency.With(lvs...).Observe(time.Since(begin).Seconds()) - }(time.Now()) - err = mw.Service.ModifyFIM(ctx, fim) - return err -} diff --git a/server/service/metrics_options.go b/server/service/metrics_options.go deleted file mode 100644 index 01bfb50a2f..0000000000 --- a/server/service/metrics_options.go +++ /dev/null @@ -1,51 +0,0 @@ -package service - -import ( - "context" - "fmt" - "time" - - "github.com/kolide/fleet/server/kolide" -) - -func (mw metricsMiddleware) GetOptions(ctx context.Context) ([]kolide.Option, error) { - var ( - options []kolide.Option - err error - ) - defer func(begin time.Time) { - lvs := []string{"method", "GetOptions", "error", fmt.Sprint(err != nil)} - mw.requestCount.With(lvs...).Add(1) - mw.requestLatency.With(lvs...).Observe(time.Since(begin).Seconds()) - }(time.Now()) - options, err = mw.Service.GetOptions(ctx) - return options, err -} - -func (mw metricsMiddleware) ModifyOptions(ctx context.Context, or kolide.OptionRequest) ([]kolide.Option, error) { - var ( - options []kolide.Option - err error - ) - defer func(begin time.Time) { - lvs := []string{"method", "ModifyOptions", "error", fmt.Sprint(err != nil)} - mw.requestCount.With(lvs...).Add(1) - mw.requestLatency.With(lvs...).Observe(time.Since(begin).Seconds()) - }(time.Now()) - options, err = mw.Service.ModifyOptions(ctx, or) - return options, err -} - -func (mw metricsMiddleware) ResetOptions(ctx context.Context) ([]kolide.Option, error) { - var ( - options []kolide.Option - err error - ) - defer func(begin time.Time) { - lvs := []string{"method", "ResetOptions", "error", fmt.Sprint(err != nil)} - mw.requestCount.With(lvs...).Add(1) - mw.requestLatency.With(lvs...).Observe(time.Since(begin).Seconds()) - }(time.Now()) - options, err = mw.Service.ResetOptions(ctx) - return options, err -} diff --git a/server/service/service_fim.go b/server/service/service_fim.go deleted file mode 100644 index 15ab66e5e2..0000000000 --- a/server/service/service_fim.go +++ /dev/null @@ -1,66 +0,0 @@ -package service - -import ( - "context" - "encoding/json" - - "github.com/kolide/fleet/server/kolide" - "github.com/pkg/errors" -) - -func (svc service) GetFIM(ctx context.Context) (*kolide.FIMConfig, error) { - config, err := svc.ds.AppConfig() - if err != nil { - return nil, errors.Wrap(err, "getting fim config") - } - paths, err := svc.ds.FIMSections() - if err != nil { - return nil, errors.Wrap(err, "getting fim paths") - } - - var arr []string - if len(config.FIMFileAccesses) > 0 { - if err = json.Unmarshal([]byte(config.FIMFileAccesses), &arr); err != nil { - return nil, errors.Wrap(err, "Error reading fim section, fileaccesses must be formatted as an array [\"cassandra\",\"etc\",\"homes\"]") - } - } - - result := &kolide.FIMConfig{ - Interval: uint(config.FIMInterval), - FilePaths: paths, - FileAccesses: arr, - } - return result, nil -} - -// ModifyFIM will remove existing FIM settings and replace it -func (svc service) ModifyFIM(ctx context.Context, fim kolide.FIMConfig) error { - if err := svc.ds.ClearFIMSections(); err != nil { - return errors.Wrap(err, "updating fim") - } - config, err := svc.ds.AppConfig() - if err != nil { - return errors.Wrap(err, "updating fim") - } - - config.FIMInterval = int(fim.Interval) - - if len(fim.FileAccesses) > 0 { - fileAccesses, err := json.Marshal(fim.FileAccesses) - if err != nil { - return errors.Wrap(err, "Error creating fim section, fileaccesses must be formatted as an array [\"cassandra\",\"etc\",\"homes\"]") - } - config.FIMFileAccesses = string(fileAccesses) - } - - for sectionName, paths := range fim.FilePaths { - section := kolide.FIMSection{ - SectionName: sectionName, - Paths: paths, - } - if _, err := svc.ds.NewFIMSection(§ion); err != nil { - return errors.Wrap(err, "creating fim section") - } - } - return svc.ds.SaveAppConfig(config) -} diff --git a/server/service/service_fim_test.go b/server/service/service_fim_test.go deleted file mode 100644 index c89f85278e..0000000000 --- a/server/service/service_fim_test.go +++ /dev/null @@ -1,101 +0,0 @@ -package service - -import ( - "context" - "testing" - - "github.com/kolide/fleet/server/kolide" - "github.com/kolide/fleet/server/mock" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestGetFIMService(t *testing.T) { - fileAccessesString := "[\"etc\", \"home\", \"cassandra\"]" - fileAccessStringValue := []string{"etc", "home", "cassandra"} - fimIntervalTestValue := 500 //300 is the default value - - ds := &mock.Store{ - AppConfigStore: mock.AppConfigStore{ - AppConfigFunc: func() (*kolide.AppConfig, error) { - config := &kolide.AppConfig{ - FIMInterval: fimIntervalTestValue, - FIMFileAccesses: fileAccessesString, - } - return config, nil - }, - }, - FileIntegrityMonitoringStore: mock.FileIntegrityMonitoringStore{ - FIMSectionsFunc: func() (kolide.FIMSections, error) { - result := kolide.FIMSections{ - "etc": []string{ - "/etc/config/%%", - "/etc/zipp", - }, - } - return result, nil - }, - }, - } - svc := service{ - ds: ds, - } - resp, err := svc.GetFIM(context.Background()) - require.Nil(t, err) - require.NotNil(t, resp) - assert.Equal(t, resp.Interval, uint(fimIntervalTestValue)) - assert.Equal(t, resp.FileAccesses, fileAccessStringValue) - paths, ok := resp.FilePaths["etc"] - require.True(t, ok) - assert.Len(t, paths, 2) -} - -func TestUpdateFIM(t *testing.T) { - fileAccessesString := "[\"etc\", \"home\", \"cassandra\"]" - fileAccessStringValue := []string{"etc", "home", "cassandra"} - fimIntervalTestValue := 500 //300 is the default value - - ds := &mock.Store{ - AppConfigStore: mock.AppConfigStore{ - AppConfigFunc: func() (*kolide.AppConfig, error) { - config := &kolide.AppConfig{ - FIMInterval: fimIntervalTestValue, - FIMFileAccesses: fileAccessesString, - } - return config, nil - }, - SaveAppConfigFunc: func(_ *kolide.AppConfig) error { - return nil - }, - }, - FileIntegrityMonitoringStore: mock.FileIntegrityMonitoringStore{ - ClearFIMSectionsFunc: func() error { - return nil - }, - NewFIMSectionFunc: func(fs *kolide.FIMSection, _ ...kolide.OptionalArg) (*kolide.FIMSection, error) { - fs.ID = 1 - return fs, nil - }, - }, - } - svc := service{ - ds: ds, - } - fim := kolide.FIMConfig{ - Interval: uint(fimIntervalTestValue), - FileAccesses: fileAccessStringValue, - FilePaths: kolide.FIMSections{ - "etc": []string{ - "/etc/config/%%", - "/etc/zipp", - }, - }, - } - err := svc.ModifyFIM(context.Background(), fim) - require.Nil(t, err) - assert.True(t, ds.NewFIMSectionFuncInvoked) - assert.True(t, ds.ClearFIMSectionsFuncInvoked) - assert.True(t, ds.AppConfigFuncInvoked) - assert.True(t, ds.SaveAppConfigFuncInvoked) - -} diff --git a/server/service/service_options.go b/server/service/service_options.go deleted file mode 100644 index 8828290b4c..0000000000 --- a/server/service/service_options.go +++ /dev/null @@ -1,26 +0,0 @@ -package service - -import ( - "context" - - "github.com/kolide/fleet/server/kolide" -) - -func (svc service) ResetOptions(ctx context.Context) ([]kolide.Option, error) { - return svc.ds.ResetOptions() -} - -func (svc service) GetOptions(ctx context.Context) ([]kolide.Option, error) { - opts, err := svc.ds.ListOptions() - if err != nil { - return nil, err - } - return opts, nil -} - -func (svc service) ModifyOptions(ctx context.Context, req kolide.OptionRequest) ([]kolide.Option, error) { - if err := svc.ds.SaveOptions(req.Options); err != nil { - return nil, err - } - return req.Options, nil -} diff --git a/server/service/transport_fim.go b/server/service/transport_fim.go deleted file mode 100644 index 6da59357fd..0000000000 --- a/server/service/transport_fim.go +++ /dev/null @@ -1,17 +0,0 @@ -package service - -import ( - "context" - "encoding/json" - "net/http" - - "github.com/kolide/fleet/server/kolide" -) - -func decodeModifyFIMRequest(ctx context.Context, r *http.Request) (interface{}, error) { - var fimConfig kolide.FIMConfig - if err := json.NewDecoder(r.Body).Decode(&fimConfig); err != nil { - return nil, err - } - return fimConfig, nil -} diff --git a/server/service/transport_options.go b/server/service/transport_options.go deleted file mode 100644 index c38b2969ac..0000000000 --- a/server/service/transport_options.go +++ /dev/null @@ -1,17 +0,0 @@ -package service - -import ( - "context" - "encoding/json" - "net/http" - - "github.com/kolide/fleet/server/kolide" -) - -func decodeModifyOptionsRequest(ctx context.Context, r *http.Request) (interface{}, error) { - var req kolide.OptionRequest - if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - return nil, err - } - return req, nil -} diff --git a/server/service/validation_options.go b/server/service/validation_options.go deleted file mode 100644 index 37bf384f66..0000000000 --- a/server/service/validation_options.go +++ /dev/null @@ -1,53 +0,0 @@ -package service - -import ( - "context" - "errors" - - "github.com/kolide/fleet/server/kolide" -) - -func (mw validationMiddleware) ModifyOptions(ctx context.Context, req kolide.OptionRequest) ([]kolide.Option, error) { - invalid := &invalidArgumentError{} - for _, opt := range req.Options { - if opt.ReadOnly { - invalid.Append(opt.Name, "readonly option") - continue - } - if err := validateValueMapsToOptionType(opt); err != nil { - invalid.Append(opt.Name, err.Error()) - } - } - if invalid.HasErrors() { - return nil, invalid - } - return mw.Service.ModifyOptions(ctx, req) -} - -var ( - errTypeMismatch = errors.New("type mismatch") - errInvalidType = errors.New("invalid option type") -) - -func validateValueMapsToOptionType(opt kolide.Option) error { - if !opt.OptionSet() { - return nil - } - switch opt.GetValue().(type) { - case int, uint, uint64, float64: - if opt.Type != kolide.OptionTypeInt { - return errTypeMismatch - } - case string: - if opt.Type != kolide.OptionTypeString { - return errTypeMismatch - } - case bool: - if opt.Type != kolide.OptionTypeBool { - return errTypeMismatch - } - default: - return errInvalidType - } - return nil -}