зеркало из https://github.com/mozilla/fleet.git
Addresses Issue where the reset button doesn't work on options page (#1447)
Closes issue #1388. The problem here is that previously, the reset button loaded a hard coded list of default options into the component state, instead of the proper behavior which is to reset the options to default values on the back end, and then load them back into the redux store. This PR adds a ResetOptions endpoint on the server, and wires up the UI so that it triggers the endpoint, then loads the default options from the backend server.
This commit is contained in:
Родитель
f4bee00b01
Коммит
d533931799
|
@ -2,6 +2,7 @@ export default {
|
|||
CHANGE_PASSWORD: '/v1/kolide/change_password',
|
||||
CONFIG: '/v1/kolide/config',
|
||||
CONFIG_OPTIONS: '/v1/kolide/options',
|
||||
CONFIG_OPTIONS_RESET: '/v1/kolide/options/reset',
|
||||
CONFIRM_EMAIL_CHANGE: (token) => {
|
||||
return `/v1/kolide/email/change/${token}`;
|
||||
},
|
||||
|
|
|
@ -14,5 +14,11 @@ export default (client) => {
|
|||
return client.authenticatedPatch(client._endpoint(CONFIG_OPTIONS), JSON.stringify({ options }))
|
||||
.then(response => response.options);
|
||||
},
|
||||
reset: () => {
|
||||
const { CONFIG_OPTIONS_RESET } = endpoints;
|
||||
|
||||
return client.authenticatedGet(client._endpoint(CONFIG_OPTIONS_RESET))
|
||||
.then(response => response.options);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -8,7 +8,6 @@ import ConfigOptionsForm from 'components/forms/ConfigOptionsForm';
|
|||
import Icon from 'components/icons/Icon';
|
||||
import configOptionInterface from 'interfaces/config_option';
|
||||
import debounce from 'utilities/debounce';
|
||||
import defaultConfigOptions from 'pages/config/ConfigOptionsPage/default_config_options';
|
||||
import entityGetter from 'redux/utilities/entityGetter';
|
||||
import helpers from 'pages/config/ConfigOptionsPage/helpers';
|
||||
import { renderFlash } from 'redux/nodes/notifications/actions';
|
||||
|
@ -102,8 +101,17 @@ export class ConfigOptionsPage extends Component {
|
|||
}
|
||||
|
||||
onResetConfigOptions = () => {
|
||||
this.setState({ configOptions: defaultConfigOptions });
|
||||
const { dispatch } = this.props;
|
||||
|
||||
dispatch(configOptionActions.resetOptions())
|
||||
.then(() => {
|
||||
dispatch(renderFlash('success', 'Options reset to defaults.'));
|
||||
return false;
|
||||
})
|
||||
.catch(() => {
|
||||
dispatch(renderFlash('error', 'Options reset failed.'));
|
||||
return false;
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ import { mount } from 'enzyme';
|
|||
|
||||
import { ConfigOptionsPage } from 'pages/config/ConfigOptionsPage/ConfigOptionsPage';
|
||||
import { configOptionStub } from 'test/stubs';
|
||||
import defaultConfigOptions from 'pages/config/ConfigOptionsPage/default_config_options';
|
||||
import { fillInFormInput } from 'test/helpers';
|
||||
|
||||
describe('ConfigOptionsPage - component', () => {
|
||||
|
@ -36,18 +35,6 @@ describe('ConfigOptionsPage - component', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('resets config option defaults', () => {
|
||||
const page = mount(<ConfigOptionsPage {...props} />);
|
||||
const buttons = page.find('Button');
|
||||
const resetButton = buttons.find('.config-options-page__reset-btn');
|
||||
|
||||
expect(page.state('configOptions')).toEqual([]);
|
||||
|
||||
resetButton.simulate('click');
|
||||
|
||||
expect(page.state('configOptions')).toEqual(defaultConfigOptions);
|
||||
});
|
||||
|
||||
describe('removing a config option', () => {
|
||||
it('sets the option value to null in state', () => {
|
||||
const page = mount(<ConfigOptionsPage configOptions={[configOptionStub]} />);
|
||||
|
|
|
@ -1,3 +1,37 @@
|
|||
import config from './config';
|
||||
import Kolide from 'kolide';
|
||||
import config from 'redux/nodes/entities/config_options/config';
|
||||
import { formatErrorResponse } from 'redux/nodes/entities/base/helpers';
|
||||
|
||||
export default config.actions;
|
||||
const { actions } = config;
|
||||
|
||||
export const RESET_OPTIONS_START = 'RESET_OPTIONS_START';
|
||||
export const RESET_OPTIONS_SUCCESS = 'RESET_OPTIONS_SUCCESS';
|
||||
export const RESET_OPTIONS_FAILURE = 'RESET_OPTIONS_FAILURE';
|
||||
|
||||
export const resetOptionsStart = { type: RESET_OPTIONS_START };
|
||||
export const resetOptionsSuccess = (configOptions) => {
|
||||
return { type: RESET_OPTIONS_SUCCESS, payload: { configOptions } };
|
||||
};
|
||||
export const resetOptionsFailure = (errors) => {
|
||||
return { type: RESET_OPTIONS_FAILURE, payload: { errors } };
|
||||
};
|
||||
|
||||
export const resetOptions = () => {
|
||||
return (dispatch) => {
|
||||
dispatch(resetOptionsStart);
|
||||
return Kolide.configOptions.reset()
|
||||
.then((opts) => {
|
||||
return dispatch(resetOptionsSuccess(opts));
|
||||
})
|
||||
.catch((error) => {
|
||||
const formattedErrors = formatErrorResponse(error);
|
||||
dispatch(resetOptionsFailure(formattedErrors));
|
||||
throw formattedErrors;
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export default {
|
||||
...actions,
|
||||
resetOptions,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
import expect, { restoreSpies, spyOn } from 'expect';
|
||||
|
||||
import Kolide from 'kolide';
|
||||
|
||||
import { reduxMockStore } from 'test/helpers';
|
||||
|
||||
import {
|
||||
resetOptions,
|
||||
resetOptionsStart,
|
||||
resetOptionsSuccess,
|
||||
} from './actions';
|
||||
|
||||
const store = { entities: { config_options: {} } };
|
||||
const options = [
|
||||
{ id: 1, name: 'option1', type: 'int', value: 10 },
|
||||
{ id: 2, name: 'option2', type: 'string', value: 'wappa' },
|
||||
];
|
||||
|
||||
describe('Options - actions', () => {
|
||||
describe('resetOptions', () => {
|
||||
describe('successful request', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(Kolide.configOptions, 'reset').andCall(() => {
|
||||
return Promise.resolve(options);
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(restoreSpies);
|
||||
|
||||
it('calls the API', () => {
|
||||
const mockStore = reduxMockStore(store);
|
||||
return mockStore.dispatch(resetOptions())
|
||||
.then(() => {
|
||||
expect(Kolide.configOptions.reset).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('dispatches the correct actions', (done) => {
|
||||
const mockStore = reduxMockStore(store);
|
||||
mockStore.dispatch(resetOptions())
|
||||
.then(() => {
|
||||
const dispatchedActions = mockStore.getActions();
|
||||
|
||||
expect(dispatchedActions).toEqual([
|
||||
resetOptionsStart,
|
||||
resetOptionsSuccess(options),
|
||||
]);
|
||||
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,3 +1,35 @@
|
|||
import config from './config';
|
||||
import {
|
||||
RESET_OPTIONS_START,
|
||||
RESET_OPTIONS_SUCCESS,
|
||||
RESET_OPTIONS_FAILURE,
|
||||
} from './actions';
|
||||
|
||||
export default config.reducer;
|
||||
import config, { initialState } from './config';
|
||||
|
||||
export default (state = initialState, { type, payload }) => {
|
||||
switch (type) {
|
||||
case RESET_OPTIONS_START:
|
||||
return {
|
||||
...state,
|
||||
errors: {},
|
||||
loading: true,
|
||||
data: {
|
||||
...state.data,
|
||||
},
|
||||
};
|
||||
case RESET_OPTIONS_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
errors: {},
|
||||
loading: false,
|
||||
data: payload.configOptions,
|
||||
};
|
||||
case RESET_OPTIONS_FAILURE:
|
||||
return {
|
||||
...state,
|
||||
errors: payload.errors,
|
||||
};
|
||||
default:
|
||||
return config.reducer(state, { type, payload });
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
import expect from 'expect';
|
||||
import reducer from './reducer';
|
||||
import {
|
||||
resetOptionsSuccess,
|
||||
} from './actions';
|
||||
|
||||
const resetOptions = [
|
||||
{ id: 1, name: 'option1', type: 'int', value: 10 },
|
||||
{ id: 2, name: 'option2', type: 'string', value: 'original' },
|
||||
];
|
||||
|
||||
describe('Options - reducer', () => {
|
||||
describe('reset', () => {
|
||||
it('should return options on success', () => {
|
||||
const initState = {
|
||||
loading: true,
|
||||
errors: {},
|
||||
data: {},
|
||||
};
|
||||
const newState = reducer(initState, resetOptionsSuccess(resetOptions));
|
||||
expect(newState).toEqual({
|
||||
...initState,
|
||||
loading: false,
|
||||
data: resetOptions,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -22,5 +22,14 @@ export default {
|
|||
});
|
||||
},
|
||||
},
|
||||
reset: {
|
||||
valid: (bearerToken) => {
|
||||
return createRequestMock({
|
||||
bearerToken,
|
||||
endpoint: '/api/v1/kolide/options/reset',
|
||||
method: 'get',
|
||||
response: { options: [] },
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package datastore
|
|||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/kolide/kolide/server/datastore/internal/appstate"
|
||||
|
@ -98,3 +99,35 @@ func testOptionsToConfig(t *testing.T, ds kolide.Datastore) {
|
|||
assert.Len(t, resp, 11)
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,4 +77,5 @@ var testFunctions = [...]func(*testing.T, kolide.Datastore){
|
|||
testMigrationStatus,
|
||||
testUnicode,
|
||||
testCountHostsInTargets,
|
||||
testResetOptions,
|
||||
}
|
||||
|
|
|
@ -7,6 +7,10 @@ import (
|
|||
"github.com/patrickmn/sortutil"
|
||||
)
|
||||
|
||||
func (d *Datastore) ResetOptions() ([]kolide.Option, error) {
|
||||
panic("inmem is being deprecated")
|
||||
}
|
||||
|
||||
func (d *Datastore) OptionByName(name string) (*kolide.Option, error) {
|
||||
d.mtx.Lock()
|
||||
defer d.mtx.Unlock()
|
||||
|
|
|
@ -2,11 +2,82 @@ package mysql
|
|||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"github.com/kolide/kolide/server/datastore/internal/appstate"
|
||||
"github.com/kolide/kolide/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.Wrap(err, fmt.Sprintf("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, "commiting reset options")
|
||||
}
|
||||
|
||||
return opts, nil
|
||||
}
|
||||
|
||||
func (d *Datastore) OptionByName(name string) (*kolide.Option, error) {
|
||||
sqlStatement := `
|
||||
SELECT *
|
||||
|
|
|
@ -25,6 +25,10 @@ type OptionStore interface {
|
|||
// 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
|
||||
|
@ -41,6 +45,8 @@ type OptionService interface {
|
|||
// osqueryd agent if it is online. This is currently two times the most
|
||||
// frequent check-in interval.
|
||||
ExpectedCheckinInterval(ctx context.Context) (time.Duration, error)
|
||||
// ResetOptions resets all options to their default values
|
||||
ResetOptions(ctx context.Context) ([]Option, error)
|
||||
}
|
||||
|
||||
const (
|
||||
|
@ -113,7 +119,14 @@ func (ov OptionValue) Value() (dv driver.Value, err error) {
|
|||
|
||||
// Scan takes db string and turns it into an option type
|
||||
func (ov *OptionValue) Scan(src interface{}) error {
|
||||
return json.Unmarshal(src.([]byte), &ov.Val)
|
||||
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
|
||||
|
|
|
@ -34,3 +34,13 @@ func makeModifyOptionsEndpoint(svc kolide.Service) endpoint.Endpoint {
|
|||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,6 +77,7 @@ type KolideEndpoints struct {
|
|||
SearchTargets endpoint.Endpoint
|
||||
GetOptions endpoint.Endpoint
|
||||
ModifyOptions endpoint.Endpoint
|
||||
ResetOptions endpoint.Endpoint
|
||||
ImportConfig endpoint.Endpoint
|
||||
GetCertificate endpoint.Endpoint
|
||||
ChangeEmail endpoint.Endpoint
|
||||
|
@ -154,6 +155,7 @@ func MakeKolideServerEndpoints(svc kolide.Service, jwtKey string) KolideEndpoint
|
|||
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))),
|
||||
ImportConfig: authenticatedUser(jwtKey, svc, makeImportConfigEndpoint(svc)),
|
||||
GetCertificate: authenticatedUser(jwtKey, svc, makeCertificateEndpoint(svc)),
|
||||
ChangeEmail: authenticatedUser(jwtKey, svc, makeChangeEmailEndpoint(svc)),
|
||||
|
@ -232,6 +234,7 @@ type kolideHandlers struct {
|
|||
SearchTargets http.Handler
|
||||
GetOptions http.Handler
|
||||
ModifyOptions http.Handler
|
||||
ResetOptions http.Handler
|
||||
ImportConfig http.Handler
|
||||
GetCertificate http.Handler
|
||||
ChangeEmail http.Handler
|
||||
|
@ -306,6 +309,7 @@ func makeKolideKitHandlers(e KolideEndpoints, opts []kithttp.ServerOption) *koli
|
|||
SearchTargets: newServer(e.SearchTargets, decodeSearchTargetsRequest),
|
||||
GetOptions: newServer(e.GetOptions, decodeNoParamsRequest),
|
||||
ModifyOptions: newServer(e.ModifyOptions, decodeModifyOptionsRequest),
|
||||
ResetOptions: newServer(e.ResetOptions, decodeNoParamsRequest),
|
||||
ImportConfig: newServer(e.ImportConfig, decodeImportConfigRequest),
|
||||
GetCertificate: newServer(e.GetCertificate, decodeNoParamsRequest),
|
||||
ChangeEmail: newServer(e.ChangeEmail, decodeChangeEmailRequest),
|
||||
|
@ -419,6 +423,7 @@ func attachKolideAPIRoutes(r *mux.Router, h *kolideHandlers) {
|
|||
|
||||
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/targets", h.SearchTargets).Methods("POST").Name("search_targets")
|
||||
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/kolide/kolide/server/kolide"
|
||||
)
|
||||
|
||||
func (mw loggingMiddleware) GetOptions(ctx context.Context) ([]kolide.Option, error) {
|
||||
var (
|
||||
options []kolide.Option
|
||||
err error
|
||||
)
|
||||
|
||||
defer func(begin time.Time) {
|
||||
mw.logger.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
|
||||
)
|
||||
|
||||
defer func(begin time.Time) {
|
||||
mw.logger.Log(
|
||||
"method", "ModifyOptions",
|
||||
"err", err,
|
||||
"took", time.Since(begin),
|
||||
)
|
||||
}(time.Now())
|
||||
options, err = mw.Service.ModifyOptions(ctx, req)
|
||||
return options, err
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) ExpectedCheckinInterval(ctx context.Context) (time.Duration, error) {
|
||||
var (
|
||||
interval time.Duration
|
||||
err error
|
||||
)
|
||||
defer func(begin time.Time) {
|
||||
mw.logger.Log(
|
||||
"method", "ExpectedCheckinInterval",
|
||||
"err", err,
|
||||
"took", time.Since(begin),
|
||||
)
|
||||
}(time.Now())
|
||||
interval, err = mw.Service.ExpectedCheckinInterval(ctx)
|
||||
return interval, err
|
||||
}
|
||||
|
||||
func (mw loggingMiddleware) ResetOptions(ctx context.Context) ([]kolide.Option, error) {
|
||||
var (
|
||||
options []kolide.Option
|
||||
err error
|
||||
)
|
||||
defer func(begin time.Time) {
|
||||
mw.logger.Log(
|
||||
"method", "ResetOptions",
|
||||
"err", err,
|
||||
"took", time.Since(begin),
|
||||
)
|
||||
}(time.Now())
|
||||
options, err = mw.Service.ResetOptions(ctx)
|
||||
return options, err
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/kolide/kolide/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
|
||||
}
|
||||
|
||||
func (mw metricsMiddleware) ExpectedCheckinInterval(ctx context.Context) (time.Duration, error) {
|
||||
var (
|
||||
interval time.Duration
|
||||
err error
|
||||
)
|
||||
defer func(begin time.Time) {
|
||||
lvs := []string{"method", "ExpectedCheckinInterval", "error", fmt.Sprint(err != nil)}
|
||||
mw.requestCount.With(lvs...).Add(1)
|
||||
mw.requestLatency.With(lvs...).Observe(time.Since(begin).Seconds())
|
||||
}(time.Now())
|
||||
interval, err = mw.Service.ExpectedCheckinInterval(ctx)
|
||||
return interval, err
|
||||
}
|
|
@ -11,6 +11,10 @@ import (
|
|||
const expectedCheckinIntervalMultiplier = 2
|
||||
const minimumExpectedCheckinInterval = 10 * time.Second
|
||||
|
||||
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 {
|
||||
|
|
Загрузка…
Ссылка в новой задаче