diff --git a/integration/appaccess/pack.go b/integration/appaccess/pack.go index e0917907702b6..a10ef45bacfad 100644 --- a/integration/appaccess/pack.go +++ b/integration/appaccess/pack.go @@ -43,6 +43,7 @@ import ( "github.com/gravitational/teleport/lib/auth" "github.com/gravitational/teleport/lib/auth/native" "github.com/gravitational/teleport/lib/client" + "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/httplib/csrf" "github.com/gravitational/teleport/lib/reversetunnel" "github.com/gravitational/teleport/lib/service" @@ -357,16 +358,15 @@ func (p *Pack) makeWebapiRequest(method, endpoint string, payload []byte) (int, } func (p *Pack) ensureAuditEvent(t *testing.T, eventType string, checkEvent func(event apievents.AuditEvent)) { + ctx := context.Background() require.Eventuallyf(t, func() bool { - events, _, err := p.rootCluster.Process.GetAuthServer().SearchEvents( - time.Now().Add(-time.Hour), - time.Now().Add(time.Hour), - apidefaults.Namespace, - []string{eventType}, - 1, - types.EventOrderDescending, - "", - ) + events, _, err := p.rootCluster.Process.GetAuthServer().SearchEvents(ctx, events.SearchEventsRequest{ + From: time.Now().Add(-time.Hour), + To: time.Now().Add(time.Hour), + EventTypes: []string{eventType}, + Limit: 1, + Order: types.EventOrderDescending, + }) require.NoError(t, err) if len(events) == 0 { return false diff --git a/integration/helpers/helpers.go b/integration/helpers/helpers.go index 9a6a27686fbd2..32074a24ee936 100644 --- a/integration/helpers/helpers.go +++ b/integration/helpers/helpers.go @@ -47,6 +47,7 @@ import ( "github.com/gravitational/teleport/lib/client/identityfile" "github.com/gravitational/teleport/lib/cloud" "github.com/gravitational/teleport/lib/defaults" + "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/multiplexer" "github.com/gravitational/teleport/lib/service" "github.com/gravitational/teleport/lib/service/servicecfg" @@ -258,8 +259,15 @@ func WaitForAuditEventTypeWithBackoff(t *testing.T, cli *auth.Server, startTime if err != nil { t.Fatalf("failed to create linear backoff: %v", err) } + ctx := context.Background() for { - events, _, err := cli.SearchEvents(startTime, time.Now().Add(time.Hour), apidefaults.Namespace, []string{eventType}, 100, types.EventOrderAscending, "") + events, _, err := cli.SearchEvents(ctx, events.SearchEventsRequest{ + From: startTime, + To: time.Now().Add(time.Hour), + EventTypes: []string{eventType}, + Limit: 100, + Order: types.EventOrderAscending, + }) if err != nil { t.Fatalf("failed to call SearchEvents: %v", err) } diff --git a/integration/integration_test.go b/integration/integration_test.go index 5d0806cf3f189..b8d32d1911ba6 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -2324,7 +2324,12 @@ func twoClustersTunnel(t *testing.T, suite *integrationTestSuite, now time.Time, eventTypes := []string{events.ExecEvent} return func() bool { - eventsInSite, _, err := site.SearchEvents(now, now.Add(1*time.Hour), defaults.Namespace, eventTypes, 0, types.EventOrderAscending, "") + eventsInSite, _, err := site.SearchEvents(ctx, events.SearchEventsRequest{ + From: now, + To: now.Add(1 * time.Hour), + EventTypes: eventTypes, + Order: types.EventOrderAscending, + }) require.NoError(t, err) return len(eventsInSite) == count } diff --git a/lib/auth/apiserver.go b/lib/auth/apiserver.go index 0c2014267a96e..9f1eef66f072d 100644 --- a/lib/auth/apiserver.go +++ b/lib/auth/apiserver.go @@ -824,7 +824,13 @@ func (s *APIServer) searchEvents(auth ClientI, w http.ResponseWriter, r *http.Re } eventTypes := query[events.EventType] - eventsList, _, err := auth.SearchEvents(from, to, apidefaults.Namespace, eventTypes, limit, types.EventOrderDescending, "") + eventsList, _, err := auth.SearchEvents(r.Context(), events.SearchEventsRequest{ + From: from, + To: to, + EventTypes: eventTypes, + Limit: limit, + Order: types.EventOrderDescending, + }) if err != nil { return nil, trace.Wrap(err) } @@ -864,7 +870,12 @@ func (s *APIServer) searchSessionEvents(auth ClientI, w http.ResponseWriter, r * } } // only pull back start and end events to build list of completed sessions - eventsList, _, err := auth.SearchSessionEvents(from, to, limit, types.EventOrderDescending, "", nil, "") + eventsList, _, err := auth.SearchSessionEvents(r.Context(), events.SearchSessionEventsRequest{ + From: from, + To: to, + Limit: limit, + Order: types.EventOrderDescending, + }) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/auth/auth_with_roles.go b/lib/auth/auth_with_roles.go index c4f0ddbc11165..5420bfea7d55d 100644 --- a/lib/auth/auth_with_roles.go +++ b/lib/auth/auth_with_roles.go @@ -3565,13 +3565,17 @@ func (a *ServerWithRoles) GetSessionEvents(namespace string, sid session.ID, aft } func (a *ServerWithRoles) findSessionEndEvent(namespace string, sid session.ID) (apievents.AuditEvent, error) { - sessionEvents, _, err := a.alog.SearchSessionEvents(time.Time{}, a.authServer.clock.Now().UTC(), - defaults.EventsIterationLimit, types.EventOrderAscending, "", - &types.WhereExpr{Equals: types.WhereExpr2{ + sessionEvents, _, err := a.alog.SearchSessionEvents(context.TODO(), events.SearchSessionEventsRequest{ + From: time.Time{}, + To: a.authServer.clock.Now().UTC(), + Limit: defaults.EventsIterationLimit, + Order: types.EventOrderAscending, + Cond: &types.WhereExpr{Equals: types.WhereExpr2{ L: &types.WhereExpr{Field: events.SessionEventID}, R: &types.WhereExpr{Literal: sid.String()}, - }}, sid.String(), - ) + }}, + SessionID: sid.String(), + }) if err != nil { return nil, trace.Wrap(err) } @@ -4882,37 +4886,38 @@ func (a *ServerWithRoles) IsMFARequired(ctx context.Context, req *proto.IsMFAReq } // SearchEvents allows searching audit events with pagination support. -func (a *ServerWithRoles) SearchEvents(fromUTC, toUTC time.Time, namespace string, eventTypes []string, limit int, order types.EventOrder, startKey string) (events []apievents.AuditEvent, lastKey string, err error) { +func (a *ServerWithRoles) SearchEvents(ctx context.Context, req events.SearchEventsRequest) (outEvents []apievents.AuditEvent, lastKey string, err error) { if err := a.action(apidefaults.Namespace, types.KindEvent, types.VerbList); err != nil { return nil, "", trace.Wrap(err) } - events, lastKey, err = a.alog.SearchEvents(fromUTC, toUTC, namespace, eventTypes, limit, order, startKey) + outEvents, lastKey, err = a.alog.SearchEvents(ctx, req) if err != nil { return nil, "", trace.Wrap(err) } - return events, lastKey, nil + return outEvents, lastKey, nil } // SearchSessionEvents allows searching session audit events with pagination support. -func (a *ServerWithRoles) SearchSessionEvents(fromUTC, toUTC time.Time, limit int, order types.EventOrder, startKey string, cond *types.WhereExpr, sessionID string) (events []apievents.AuditEvent, lastKey string, err error) { - if cond != nil { +func (a *ServerWithRoles) SearchSessionEvents(ctx context.Context, req events.SearchSessionEventsRequest) (outEvents []apievents.AuditEvent, lastKey string, err error) { + if req.Cond != nil { return nil, "", trace.BadParameter("cond is an internal parameter, should not be set by client") } - cond, err = a.actionForListWithCondition(apidefaults.Namespace, types.KindSession, services.SessionIdentifier) + cond, err := a.actionForListWithCondition(apidefaults.Namespace, types.KindSession, services.SessionIdentifier) if err != nil { return nil, "", trace.Wrap(err) } // TODO(codingllama): Refactor cond out of SearchSessionEvents and simplify signature. - events, lastKey, err = a.alog.SearchSessionEvents(fromUTC, toUTC, limit, order, startKey, cond, sessionID) + req.Cond = cond + outEvents, lastKey, err = a.alog.SearchSessionEvents(ctx, req) if err != nil { return nil, "", trace.Wrap(err) } - return events, lastKey, nil + return outEvents, lastKey, nil } // GetLock gets a lock by name. diff --git a/lib/auth/auth_with_roles_test.go b/lib/auth/auth_with_roles_test.go index fd5b41dcca99d..19fb928ae421b 100644 --- a/lib/auth/auth_with_roles_test.go +++ b/lib/auth/auth_with_roles_test.go @@ -1441,15 +1441,13 @@ func TestStreamSessionEvents_User(t *testing.T) { // we need to wait for a short period to ensure the event is returned time.Sleep(500 * time.Millisecond) - searchEvents, _, err := srv.AuthServer.AuditLog.SearchEvents( - srv.Clock().Now().Add(-time.Hour), - srv.Clock().Now().Add(time.Hour), - defaults.Namespace, - []string{events.SessionRecordingAccessEvent}, - 1, - types.EventOrderDescending, - "", - ) + searchEvents, _, err := srv.AuthServer.AuditLog.SearchEvents(ctx, events.SearchEventsRequest{ + From: srv.Clock().Now().Add(-time.Hour), + To: srv.Clock().Now().Add(time.Hour), + EventTypes: []string{events.SessionRecordingAccessEvent}, + Limit: 1, + Order: types.EventOrderDescending, + }) require.NoError(t, err) event := searchEvents[0].(*apievents.SessionRecordingAccess) @@ -1474,15 +1472,13 @@ func TestStreamSessionEvents_Builtin(t *testing.T) { // we need to wait for a short period to ensure the event is returned time.Sleep(500 * time.Millisecond) - searchEvents, _, err := srv.AuthServer.AuditLog.SearchEvents( - srv.Clock().Now().Add(-time.Hour), - srv.Clock().Now().Add(time.Hour), - defaults.Namespace, - []string{events.SessionRecordingAccessEvent}, - 1, - types.EventOrderDescending, - "", - ) + searchEvents, _, err := srv.AuthServer.AuditLog.SearchEvents(ctx, events.SearchEventsRequest{ + From: srv.Clock().Now().Add(-time.Hour), + To: srv.Clock().Now().Add(time.Hour), + EventTypes: []string{events.SessionRecordingAccessEvent}, + Limit: 1, + Order: types.EventOrderDescending, + }) require.NoError(t, err) require.Equal(t, 0, len(searchEvents)) @@ -1507,16 +1503,14 @@ func TestGetSessionEvents(t *testing.T) { // we need to wait for a short period to ensure the event is returned time.Sleep(500 * time.Millisecond) - - searchEvents, _, err := srv.AuthServer.AuditLog.SearchEvents( - srv.Clock().Now().Add(-time.Hour), - srv.Clock().Now().Add(time.Hour), - defaults.Namespace, - []string{events.SessionRecordingAccessEvent}, - 1, - types.EventOrderDescending, - "", - ) + ctx := context.Background() + searchEvents, _, err := srv.AuthServer.AuditLog.SearchEvents(ctx, events.SearchEventsRequest{ + From: srv.Clock().Now().Add(-time.Hour), + To: srv.Clock().Now().Add(time.Hour), + EventTypes: []string{events.SessionRecordingAccessEvent}, + Limit: 1, + Order: types.EventOrderDescending, + }) require.NoError(t, err) event := searchEvents[0].(*apievents.SessionRecordingAccess) @@ -2808,7 +2802,13 @@ func TestListResources_SearchAsRoles(t *testing.T) { if len(tc.expectSearchEventRoles) > 0 { require.Eventually(t, func() bool { // make sure an audit event is logged for the search - auditEvents, _, err := srv.AuthServer.AuditLog.SearchEvents(time.Time{}, time.Now(), "", []string{events.AccessRequestResourceSearch}, 10, 0, "") + auditEvents, _, err := srv.AuthServer.AuditLog.SearchEvents(ctx, events.SearchEventsRequest{ + From: time.Time{}, + To: time.Now(), + EventTypes: []string{events.AccessRequestResourceSearch}, + Limit: 10, + Order: types.EventOrderAscending, + }) require.NoError(t, err) if len(auditEvents) == 0 { t.Log("no search audit events found") diff --git a/lib/auth/clt.go b/lib/auth/clt.go index bc5f2f5cab431..8eba35b95dfbc 100644 --- a/lib/auth/clt.go +++ b/lib/auth/clt.go @@ -27,6 +27,7 @@ import ( "github.com/gravitational/teleport/api/client" "github.com/gravitational/teleport/api/client/proto" + apidefaults "github.com/gravitational/teleport/api/defaults" devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1" loginrulepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/loginrule/v1" pluginspb "github.com/gravitational/teleport/api/gen/proto/go/teleport/plugins/v1" @@ -289,8 +290,8 @@ func (c *Client) StreamSessionEvents(ctx context.Context, sessionID session.ID, } // SearchEvents allows searching for audit events with pagination support. -func (c *Client) SearchEvents(fromUTC, toUTC time.Time, namespace string, eventTypes []string, limit int, order types.EventOrder, startKey string) ([]apievents.AuditEvent, string, error) { - events, lastKey, err := c.APIClient.SearchEvents(context.TODO(), fromUTC, toUTC, namespace, eventTypes, limit, order, startKey) +func (c *Client) SearchEvents(ctx context.Context, req events.SearchEventsRequest) ([]apievents.AuditEvent, string, error) { + events, lastKey, err := c.APIClient.SearchEvents(ctx, req.From, req.To, apidefaults.Namespace, req.EventTypes, req.Limit, req.Order, req.StartKey) if err != nil { return nil, "", trace.Wrap(err) } @@ -299,8 +300,8 @@ func (c *Client) SearchEvents(fromUTC, toUTC time.Time, namespace string, eventT } // SearchSessionEvents returns session related events to find completed sessions. -func (c *Client) SearchSessionEvents(fromUTC, toUTC time.Time, limit int, order types.EventOrder, startKey string, cond *types.WhereExpr, sessionID string) ([]apievents.AuditEvent, string, error) { - events, lastKey, err := c.APIClient.SearchSessionEvents(context.TODO(), fromUTC, toUTC, limit, order, startKey) +func (c *Client) SearchSessionEvents(ctx context.Context, req events.SearchSessionEventsRequest) ([]apievents.AuditEvent, string, error) { + events, lastKey, err := c.APIClient.SearchSessionEvents(ctx, req.From, req.To, req.Limit, req.Order, req.StartKey) if err != nil { return nil, "", trace.Wrap(err) } diff --git a/lib/auth/grpcserver.go b/lib/auth/grpcserver.go index 9f587a3256926..6a04f34f59d68 100644 --- a/lib/auth/grpcserver.go +++ b/lib/auth/grpcserver.go @@ -3429,7 +3429,14 @@ func (g *GRPCServer) GetEvents(ctx context.Context, req *proto.GetEventsRequest) return nil, trace.Wrap(err) } - rawEvents, lastkey, err := auth.ServerWithRoles.SearchEvents(req.StartDate, req.EndDate, req.Namespace, req.EventTypes, int(req.Limit), types.EventOrder(req.Order), req.StartKey) + rawEvents, lastkey, err := auth.ServerWithRoles.SearchEvents(ctx, events.SearchEventsRequest{ + From: req.StartDate, + To: req.EndDate, + EventTypes: req.EventTypes, + Limit: int(req.Limit), + Order: types.EventOrder(req.Order), + StartKey: req.StartKey, + }) if err != nil { return nil, trace.Wrap(err) } @@ -3458,7 +3465,13 @@ func (g *GRPCServer) GetSessionEvents(ctx context.Context, req *proto.GetSession return nil, trace.Wrap(err) } - rawEvents, lastkey, err := auth.ServerWithRoles.SearchSessionEvents(req.StartDate, req.EndDate, int(req.Limit), types.EventOrder(req.Order), req.StartKey, nil, "") + rawEvents, lastkey, err := auth.ServerWithRoles.SearchSessionEvents(ctx, events.SearchSessionEventsRequest{ + From: req.StartDate, + To: req.EndDate, + Limit: int(req.Limit), + Order: types.EventOrder(req.Order), + StartKey: req.StartKey, + }) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/auth/join_test.go b/lib/auth/join_test.go index 2121b44874c44..fbeca2fef6d07 100644 --- a/lib/auth/join_test.go +++ b/lib/auth/join_test.go @@ -28,7 +28,6 @@ import ( "golang.org/x/crypto/ssh" "github.com/gravitational/teleport/api/client/proto" - apidefaults "github.com/gravitational/teleport/api/defaults" "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/api/types/wrappers" @@ -391,15 +390,13 @@ func TestRegister_Bot(t *testing.T) { require.True(t, id.Renewable) // Check audit event - evts, _, err := srv.Auth().SearchEvents( - start, - srv.Clock().Now(), - apidefaults.Namespace, - []string{events.BotJoinEvent}, - 1, - types.EventOrderDescending, - "", - ) + evts, _, err := srv.Auth().SearchEvents(ctx, events.SearchEventsRequest{ + From: start, + To: srv.Clock().Now(), + EventTypes: []string{events.BotJoinEvent}, + Limit: 1, + Order: types.EventOrderDescending, + }) require.NoError(t, err) require.Len(t, evts, 1) evt, ok := evts[0].(*apievents.BotJoin) diff --git a/lib/client/client.go b/lib/client/client.go index 21fa01599a7ca..6150d7a1365b4 100644 --- a/lib/client/client.go +++ b/lib/client/client.go @@ -1987,8 +1987,13 @@ func GetPaginatedSessions(ctx context.Context, fromUTC, toUTC time.Time, pageSiz if remaining := max - len(sessions); remaining < pageSize { pageSize = remaining } - nextEvents, eventKey, err := authClient.SearchSessionEvents(fromUTC, toUTC, - pageSize, order, prevEventKey, nil /* where condition */, "" /* session ID */) + nextEvents, eventKey, err := authClient.SearchSessionEvents(ctx, events.SearchSessionEventsRequest{ + From: fromUTC, + To: toUTC, + Limit: pageSize, + Order: order, + StartKey: prevEventKey, + }) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/events/api.go b/lib/events/api.go index 59f23f2640462..777ebeba0a3e8 100644 --- a/lib/events/api.go +++ b/lib/events/api.go @@ -841,6 +841,42 @@ type SessionStreamer interface { StreamSessionEvents(ctx context.Context, sessionID session.ID, startIndex int64) (chan apievents.AuditEvent, chan error) } +type SearchEventsRequest struct { + // From is oldest date of returned events, can be zero. + From time.Time + // To is the newest date of returned events. + To time.Time + // EventTypes is optional, if not set, returns all events. + EventTypes []string + // Limit is the maximum amount of events returned. + Limit int + // Order specifies an ascending or descending order of events. + Order types.EventOrder + // StartKey is used to resume a query in order to enable pagination. + // If the previous response had LastKey set then this should be + // set to its value. Otherwise leave empty. + StartKey string +} + +type SearchSessionEventsRequest struct { + // From is oldest date of returned events, can be zero. + From time.Time + // To is the newest date of returned events. + To time.Time + // Limit is the maximum amount of events returned. + Limit int + // Order specifies an ascending or descending order of events. + Order types.EventOrder + // StartKey is used to resume a query in order to enable pagination. + // If the previous response had LastKey set then this should be + // set to its value. Otherwise leave empty. + StartKey string + // Cond can be used to pass additional expression to query, can be empty. + Cond *types.WhereExpr + // SessionID is optional parameter to return session events only to given session. + SessionID string +} + // AuditLogger defines which methods need to implemented by audit loggers. type AuditLogger interface { // Closer releases connection and resources associated with log if any @@ -857,7 +893,7 @@ type AuditLogger interface { // The only mandatory requirement is a date range (UTC). // // This function may never return more than 1 MiB of event data. - SearchEvents(fromUTC, toUTC time.Time, namespace string, eventTypes []string, limit int, order types.EventOrder, startKey string) ([]apievents.AuditEvent, string, error) + SearchEvents(ctx context.Context, req SearchEventsRequest) ([]apievents.AuditEvent, string, error) // SearchSessionEvents is a flexible way to find session events. // Only session.end events are returned by this function. @@ -867,7 +903,7 @@ type AuditLogger interface { // a query to be resumed. // // This function may never return more than 1 MiB of event data. - SearchSessionEvents(fromUTC, toUTC time.Time, limit int, order types.EventOrder, startKey string, cond *types.WhereExpr, sessionID string) ([]apievents.AuditEvent, string, error) + SearchSessionEvents(ctx context.Context, req SearchSessionEventsRequest) ([]apievents.AuditEvent, string, error) } // EventFields instance is attached to every logged event diff --git a/lib/events/athena/athena.go b/lib/events/athena/athena.go index b403dc5d73853..888bdfded3616 100644 --- a/lib/events/athena/athena.go +++ b/lib/events/athena/athena.go @@ -30,9 +30,9 @@ import ( log "github.com/sirupsen/logrus" "github.com/gravitational/teleport" - "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/lib/backend" + "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/utils" ) @@ -397,12 +397,12 @@ func (l *Log) EmitAuditEvent(ctx context.Context, in apievents.AuditEvent) error return trace.Wrap(l.publisher.EmitAuditEvent(ctx, in)) } -func (l *Log) SearchEvents(fromUTC, toUTC time.Time, namespace string, eventTypes []string, limit int, order types.EventOrder, startKey string) ([]apievents.AuditEvent, string, error) { - return l.querier.SearchEvents(fromUTC, toUTC, namespace, eventTypes, limit, order, startKey) +func (l *Log) SearchEvents(ctx context.Context, req events.SearchEventsRequest) ([]apievents.AuditEvent, string, error) { + return l.querier.SearchEvents(ctx, req.From, req.To, req.EventTypes, req.Limit, req.Order, req.StartKey) } -func (l *Log) SearchSessionEvents(fromUTC, toUTC time.Time, limit int, order types.EventOrder, startKey string, cond *types.WhereExpr, sessionID string) ([]apievents.AuditEvent, string, error) { - return l.querier.SearchSessionEvents(fromUTC, toUTC, limit, order, startKey, cond, sessionID) +func (l *Log) SearchSessionEvents(ctx context.Context, req events.SearchSessionEventsRequest) ([]apievents.AuditEvent, string, error) { + return l.querier.SearchSessionEvents(ctx, req.From, req.To, req.Limit, req.Order, req.StartKey, req.Cond, req.SessionID) } func (l *Log) Close() error { diff --git a/lib/events/athena/integration_test.go b/lib/events/athena/integration_test.go index 44cf2dd0afd72..3f0a407e2d0ba 100644 --- a/lib/events/athena/integration_test.go +++ b/lib/events/athena/integration_test.go @@ -134,7 +134,12 @@ func TestIntegrationAthenaLargeEvents(t *testing.T) { var history []apievents.AuditEvent // We have batch time 10s, and 5s for upload and additional buffer for s3 download err = retryutils.RetryStaticFor(time.Second*20, time.Second*2, func() error { - history, _, err = ac.log.SearchEvents(ac.clock.Now().UTC().Add(-1*time.Minute), ac.clock.Now().UTC(), "", nil, 10, types.EventOrderDescending, "") + history, _, err = ac.log.SearchEvents(ctx, events.SearchEventsRequest{ + From: ac.clock.Now().UTC().Add(-1 * time.Minute), + To: ac.clock.Now().UTC(), + Limit: 10, + Order: types.EventOrderDescending, + }) if err != nil { return err } @@ -428,7 +433,7 @@ func (e *eventuallyConsitentAuditLogger) EmitAuditEvent(ctx context.Context, in return e.inner.EmitAuditEvent(ctx, in) } -func (e *eventuallyConsitentAuditLogger) SearchEvents(fromUTC, toUTC time.Time, namespace string, eventTypes []string, limit int, order types.EventOrder, startKey string) ([]apievents.AuditEvent, string, error) { +func (e *eventuallyConsitentAuditLogger) SearchEvents(ctx context.Context, req events.SearchEventsRequest) ([]apievents.AuditEvent, string, error) { e.mu.Lock() defer e.mu.Unlock() if e.emitWasAfterLastDelay { @@ -436,10 +441,10 @@ func (e *eventuallyConsitentAuditLogger) SearchEvents(fromUTC, toUTC time.Time, // clear emit delay e.emitWasAfterLastDelay = false } - return e.inner.SearchEvents(fromUTC, toUTC, namespace, eventTypes, limit, order, startKey) + return e.inner.SearchEvents(ctx, req) } -func (e *eventuallyConsitentAuditLogger) SearchSessionEvents(fromUTC, toUTC time.Time, limit int, order types.EventOrder, startKey string, cond *types.WhereExpr, sessionID string) ([]apievents.AuditEvent, string, error) { +func (e *eventuallyConsitentAuditLogger) SearchSessionEvents(ctx context.Context, req events.SearchSessionEventsRequest) ([]apievents.AuditEvent, string, error) { e.mu.Lock() defer e.mu.Unlock() if e.emitWasAfterLastDelay { @@ -447,7 +452,7 @@ func (e *eventuallyConsitentAuditLogger) SearchSessionEvents(fromUTC, toUTC time // clear emit delay e.emitWasAfterLastDelay = false } - return e.inner.SearchSessionEvents(fromUTC, toUTC, limit, order, startKey, cond, sessionID) + return e.inner.SearchSessionEvents(ctx, req) } func (e *eventuallyConsitentAuditLogger) Close() error { diff --git a/lib/events/athena/querier.go b/lib/events/athena/querier.go index 0518388cd7fe0..0b0660986e2c6 100644 --- a/lib/events/athena/querier.go +++ b/lib/events/athena/querier.go @@ -113,11 +113,11 @@ func newQuerier(cfg querierConfig) (*querier, error) { }, nil } -func (q *querier) SearchEvents(fromUTC, toUTC time.Time, namespace string, +func (q *querier) SearchEvents(ctx context.Context, fromUTC, toUTC time.Time, eventTypes []string, limit int, order types.EventOrder, startKey string, ) ([]apievents.AuditEvent, string, error) { filter := searchEventsFilter{eventTypes: eventTypes} - events, keyset, err := q.searchEvents(context.TODO(), searchEventsRequest{ + events, keyset, err := q.searchEvents(ctx, searchEventsRequest{ fromUTC: fromUTC, toUTC: toUTC, limit: limit, @@ -129,7 +129,7 @@ func (q *querier) SearchEvents(fromUTC, toUTC time.Time, namespace string, return events, keyset, trace.Wrap(err) } -func (q *querier) SearchSessionEvents(fromUTC, toUTC time.Time, limit int, +func (q *querier) SearchSessionEvents(ctx context.Context, fromUTC, toUTC time.Time, limit int, order types.EventOrder, startKey string, cond *types.WhereExpr, sessionID string, ) ([]apievents.AuditEvent, string, error) { // TODO(tobiaszheller): maybe if fromUTC is 0000-00-00, ask first last 30days and fallback to -inf - now-30 @@ -142,7 +142,7 @@ func (q *querier) SearchSessionEvents(fromUTC, toUTC time.Time, limit int, } filter.condition = condFn } - events, keyset, err := q.searchEvents(context.TODO(), searchEventsRequest{ + events, keyset, err := q.searchEvents(ctx, searchEventsRequest{ fromUTC: fromUTC, toUTC: toUTC, limit: limit, diff --git a/lib/events/auditlog.go b/lib/events/auditlog.go index f88fbd14c5653..ff2db8b0d27f7 100644 --- a/lib/events/auditlog.go +++ b/lib/events/auditlog.go @@ -39,7 +39,6 @@ import ( "github.com/gravitational/teleport" apidefaults "github.com/gravitational/teleport/api/defaults" - "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/observability/metrics" @@ -897,27 +896,29 @@ func (l *AuditLog) auditDirs() ([]string, error) { return out, nil } -func (l *AuditLog) SearchEvents(fromUTC, toUTC time.Time, namespace string, eventType []string, limit int, order types.EventOrder, startKey string) ([]apievents.AuditEvent, string, error) { - g := l.log.WithFields(log.Fields{"namespace": namespace, "eventType": eventType, "limit": limit}) - g.Debugf("SearchEvents(%v, %v)", fromUTC, toUTC) +func (l *AuditLog) SearchEvents(ctx context.Context, req SearchEventsRequest) ([]apievents.AuditEvent, string, error) { + g := l.log.WithFields(log.Fields{"eventType": req.EventTypes, "limit": req.Limit}) + g.Debugf("SearchEvents(%v, %v)", req.From, req.To) + limit := req.Limit if limit <= 0 { limit = defaults.EventsIterationLimit } if limit > defaults.EventsMaxIterationLimit { return nil, "", trace.BadParameter("limit %v exceeds max iteration limit %v", limit, defaults.MaxIterationLimit) } + req.Limit = limit if l.ExternalLog != nil { - return l.ExternalLog.SearchEvents(fromUTC, toUTC, namespace, eventType, limit, order, startKey) + return l.ExternalLog.SearchEvents(ctx, req) } - return l.localLog.SearchEvents(fromUTC, toUTC, namespace, eventType, limit, order, startKey) + return l.localLog.SearchEvents(ctx, req) } -func (l *AuditLog) SearchSessionEvents(fromUTC, toUTC time.Time, limit int, order types.EventOrder, startKey string, cond *types.WhereExpr, sessionID string) ([]apievents.AuditEvent, string, error) { - l.log.Debugf("SearchSessionEvents(%v, %v, %v)", fromUTC, toUTC, limit) +func (l *AuditLog) SearchSessionEvents(ctx context.Context, req SearchSessionEventsRequest) ([]apievents.AuditEvent, string, error) { + l.log.Debugf("SearchSessionEvents(%v, %v, %v)", req.From, req.To, req.Limit) if l.ExternalLog != nil { - return l.ExternalLog.SearchSessionEvents(fromUTC, toUTC, limit, order, startKey, cond, sessionID) + return l.ExternalLog.SearchSessionEvents(ctx, req) } - return l.localLog.SearchSessionEvents(fromUTC, toUTC, limit, order, startKey, cond, sessionID) + return l.localLog.SearchSessionEvents(ctx, req) } // StreamSessionEvents streams all events from a given session recording. An error is returned on the first diff --git a/lib/events/auditlog_test.go b/lib/events/auditlog_test.go index ba0c569638b22..6a0e178a8ec05 100644 --- a/lib/events/auditlog_test.go +++ b/lib/events/auditlog_test.go @@ -29,7 +29,6 @@ import ( "github.com/jonboulle/clockwork" "github.com/stretchr/testify/require" - apidefaults "github.com/gravitational/teleport/api/defaults" "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/lib/events" @@ -96,14 +95,11 @@ func TestLogRotation(t *testing.T) { require.NoError(t, err) require.Equal(t, string(bytes), string(contents)) - found, _, err := alog.SearchEvents( - now.Add(-time.Hour), - now.Add(time.Hour), - apidefaults.Namespace, - nil, // event types - 0, // limit - types.EventOrderAscending, - "") // start key + found, _, err := alog.SearchEvents(ctx, events.SearchEventsRequest{ + From: now.Add(-time.Hour), + To: now.Add(time.Hour), + Order: types.EventOrderAscending, + }) require.NoError(t, err) require.Len(t, found, 1) } diff --git a/lib/events/discard.go b/lib/events/discard.go index 90e9fcb37b572..30d0aaa764daf 100644 --- a/lib/events/discard.go +++ b/lib/events/discard.go @@ -18,11 +18,9 @@ package events import ( "context" - "time" log "github.com/sirupsen/logrus" - "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/lib/session" ) @@ -48,11 +46,11 @@ func (d *DiscardAuditLog) GetSessionEvents(namespace string, sid session.ID, aft return make([]EventFields, 0), nil } -func (d *DiscardAuditLog) SearchEvents(fromUTC, toUTC time.Time, namespace string, eventType []string, limit int, order types.EventOrder, startKey string) ([]apievents.AuditEvent, string, error) { +func (d *DiscardAuditLog) SearchEvents(ctx context.Context, req SearchEventsRequest) ([]apievents.AuditEvent, string, error) { return make([]apievents.AuditEvent, 0), "", nil } -func (d *DiscardAuditLog) SearchSessionEvents(fromUTC, toUTC time.Time, limit int, order types.EventOrder, startKey string, cond *types.WhereExpr, sessionID string) ([]apievents.AuditEvent, string, error) { +func (d *DiscardAuditLog) SearchSessionEvents(ctx context.Context, req SearchSessionEventsRequest) ([]apievents.AuditEvent, string, error) { return make([]apievents.AuditEvent, 0), "", nil } diff --git a/lib/events/dynamoevents/dynamoevents.go b/lib/events/dynamoevents/dynamoevents.go index 3b31388461406..92760f042e19d 100644 --- a/lib/events/dynamoevents/dynamoevents.go +++ b/lib/events/dynamoevents/dynamoevents.go @@ -492,8 +492,8 @@ type checkpointKey struct { // The only mandatory requirement is a date range (UTC). // // This function may never return more than 1 MiB of event data. -func (l *Log) SearchEvents(fromUTC, toUTC time.Time, namespace string, eventTypes []string, limit int, order types.EventOrder, startKey string) ([]apievents.AuditEvent, string, error) { - return l.searchEventsWithFilter(context.TODO(), fromUTC, toUTC, namespace, limit, order, startKey, searchEventsFilter{eventTypes: eventTypes}, "") +func (l *Log) SearchEvents(ctx context.Context, req events.SearchEventsRequest) ([]apievents.AuditEvent, string, error) { + return l.searchEventsWithFilter(ctx, req.From, req.To, apidefaults.Namespace, req.Limit, req.Order, req.StartKey, searchEventsFilter{eventTypes: req.EventTypes}, "") } func (l *Log) searchEventsWithFilter(ctx context.Context, fromUTC, toUTC time.Time, namespace string, limit int, order types.EventOrder, startKey string, filter searchEventsFilter, sessionID string) ([]apievents.AuditEvent, string, error) { @@ -708,18 +708,18 @@ func getSubPageCheckpoint(e *event) (string, error) { // SearchSessionEvents returns session related events only. This is used to // find completed session. -func (l *Log) SearchSessionEvents(fromUTC, toUTC time.Time, limit int, order types.EventOrder, startKey string, cond *types.WhereExpr, sessionID string) ([]apievents.AuditEvent, string, error) { +func (l *Log) SearchSessionEvents(ctx context.Context, req events.SearchSessionEventsRequest) ([]apievents.AuditEvent, string, error) { filter := searchEventsFilter{eventTypes: []string{events.SessionEndEvent, events.WindowsDesktopSessionEndEvent}} - if cond != nil { + if req.Cond != nil { params := condFilterParams{attrValues: make(map[string]interface{}), attrNames: make(map[string]string)} - expr, err := fromWhereExpr(cond, ¶ms) + expr, err := fromWhereExpr(req.Cond, ¶ms) if err != nil { return nil, "", trace.Wrap(err) } filter.condExpr = expr filter.condParams = params } - return l.searchEventsWithFilter(context.TODO(), fromUTC, toUTC, apidefaults.Namespace, limit, order, startKey, filter, sessionID) + return l.searchEventsWithFilter(ctx, req.From, req.To, apidefaults.Namespace, req.Limit, req.Order, req.StartKey, filter, req.SessionID) } type searchEventsFilter struct { diff --git a/lib/events/dynamoevents/dynamoevents_test.go b/lib/events/dynamoevents/dynamoevents_test.go index 3dea115ed6e09..dbcba77f54a30 100644 --- a/lib/events/dynamoevents/dynamoevents_test.go +++ b/lib/events/dynamoevents/dynamoevents_test.go @@ -32,7 +32,6 @@ import ( "github.com/stretchr/testify/require" "github.com/gravitational/teleport" - apidefaults "github.com/gravitational/teleport/api/defaults" "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/lib/events" @@ -134,20 +133,19 @@ func TestSizeBreak(t *testing.T) { } var checkpoint string - events := make([]apievents.AuditEvent, 0) - + gotEvents := make([]apievents.AuditEvent, 0) + ctx := context.Background() for { - fetched, lCheckpoint, err := tt.log.SearchEvents( - tt.suite.Clock.Now().UTC().Add(-time.Hour), - tt.suite.Clock.Now().UTC().Add(time.Hour), - apidefaults.Namespace, - nil, - eventCount, - types.EventOrderDescending, - checkpoint) + fetched, lCheckpoint, err := tt.log.SearchEvents(ctx, events.SearchEventsRequest{ + From: tt.suite.Clock.Now().UTC().Add(-time.Hour), + To: tt.suite.Clock.Now().UTC().Add(time.Hour), + Limit: eventCount, + Order: types.EventOrderDescending, + StartKey: checkpoint, + }) require.NoError(t, err) checkpoint = lCheckpoint - events = append(events, fetched...) + gotEvents = append(gotEvents, fetched...) if checkpoint == "" { break @@ -156,7 +154,7 @@ func TestSizeBreak(t *testing.T) { lastTime := tt.suite.Clock.Now().UTC().Add(time.Hour) - for _, event := range events { + for _, event := range gotEvents { require.True(t, event.GetTime().Before(lastTime)) lastTime = event.GetTime() } @@ -211,17 +209,15 @@ func TestLargeTableRetrieve(t *testing.T) { history []apievents.AuditEvent err error ) + ctx := context.Background() for i := 0; i < dynamoDBLargeQueryRetries; i++ { time.Sleep(tt.suite.QueryDelay) - history, _, err = tt.suite.Log.SearchEvents( - tt.suite.Clock.Now().Add(-1*time.Hour), - tt.suite.Clock.Now().Add(time.Hour), - apidefaults.Namespace, - nil, - 0, - types.EventOrderAscending, - "") + history, _, err = tt.suite.Log.SearchEvents(ctx, events.SearchEventsRequest{ + From: tt.suite.Clock.Now().Add(-1 * time.Hour), + To: tt.suite.Clock.Now().Add(time.Hour), + Order: types.EventOrderAscending, + }) require.NoError(t, err) if len(history) == eventCount { @@ -273,14 +269,12 @@ func TestEmitAuditEventForLargeEvents(t *testing.T) { err := tt.suite.Log.EmitAuditEvent(ctx, dbQueryEvent) require.NoError(t, err) - result, _, err := tt.suite.Log.SearchEvents( - now.Add(-1*time.Hour), - now.Add(time.Hour), - apidefaults.Namespace, - []string{events.DatabaseSessionQueryEvent}, - 0, types.EventOrderAscending, - "", - ) + result, _, err := tt.suite.Log.SearchEvents(ctx, events.SearchEventsRequest{ + From: now.Add(-1 * time.Hour), + To: now.Add(time.Hour), + EventTypes: []string{events.DatabaseSessionQueryEvent}, + Order: types.EventOrderAscending, + }) require.NoError(t, err) require.Len(t, result, 1) diff --git a/lib/events/filelog.go b/lib/events/filelog.go index b6f6aded303a4..3810a04e95d80 100644 --- a/lib/events/filelog.go +++ b/lib/events/filelog.go @@ -35,7 +35,6 @@ import ( log "github.com/sirupsen/logrus" "github.com/gravitational/teleport" - apidefaults "github.com/gravitational/teleport/api/defaults" "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/lib/defaults" @@ -210,12 +209,12 @@ type messageSizeTrimmer interface { // The only mandatory requirement is a date range (UTC). // // This function may never return more than 1 MiB of event data. -func (l *FileLog) SearchEvents(fromUTC, toUTC time.Time, namespace string, eventTypes []string, limit int, order types.EventOrder, startAfter string) ([]apievents.AuditEvent, string, error) { - l.Debugf("SearchEvents(%v, %v, namespace=%v, eventType=%v, limit=%v)", fromUTC, toUTC, namespace, eventTypes, limit) - return l.searchEventsWithFilter(fromUTC, toUTC, namespace, limit, order, startAfter, searchEventsFilter{eventTypes: eventTypes}) +func (l *FileLog) SearchEvents(ctx context.Context, req SearchEventsRequest) ([]apievents.AuditEvent, string, error) { + l.Debugf("SearchEvents(%v, %v, eventType=%v, limit=%v)", req.From, req.To, req.EventTypes, req.Limit) + return l.searchEventsWithFilter(req.From, req.To, req.Limit, req.Order, req.StartKey, searchEventsFilter{eventTypes: req.EventTypes}) } -func (l *FileLog) searchEventsWithFilter(fromUTC, toUTC time.Time, namespace string, limit int, order types.EventOrder, startAfter string, filter searchEventsFilter) ([]apievents.AuditEvent, string, error) { +func (l *FileLog) searchEventsWithFilter(fromUTC, toUTC time.Time, limit int, order types.EventOrder, startAfter string, filter searchEventsFilter) ([]apievents.AuditEvent, string, error) { if limit <= 0 { limit = defaults.EventsIterationLimit } @@ -361,17 +360,17 @@ func getCheckpointFromEvent(event apievents.AuditEvent) (string, error) { return event.GetID(), nil } -func (l *FileLog) SearchSessionEvents(fromUTC, toUTC time.Time, limit int, order types.EventOrder, startKey string, cond *types.WhereExpr, sessionID string) ([]apievents.AuditEvent, string, error) { - l.Debugf("SearchSessionEvents(%v, %v, order=%v, limit=%v, cond=%q)", fromUTC, toUTC, order, limit, cond) +func (l *FileLog) SearchSessionEvents(ctx context.Context, req SearchSessionEventsRequest) ([]apievents.AuditEvent, string, error) { + l.Debugf("SearchSessionEvents(%v, %v, order=%v, limit=%v, cond=%q)", req.From, req.To, req.Order, req.Limit, req.Cond) filter := searchEventsFilter{eventTypes: []string{SessionEndEvent, WindowsDesktopSessionEndEvent}} - if cond != nil { - condFn, err := utils.ToFieldsCondition(cond) + if req.Cond != nil { + condFn, err := utils.ToFieldsCondition(req.Cond) if err != nil { return nil, "", trace.Wrap(err) } filter.condition = condFn } - events, lastKey, err := l.searchEventsWithFilter(fromUTC, toUTC, apidefaults.Namespace, limit, order, startKey, filter) + events, lastKey, err := l.searchEventsWithFilter(req.From, req.To, req.Limit, req.Order, req.StartKey, filter) return events, lastKey, trace.Wrap(err) } diff --git a/lib/events/filelog_test.go b/lib/events/filelog_test.go index a1f4c31e9468d..87c76ec255321 100644 --- a/lib/events/filelog_test.go +++ b/lib/events/filelog_test.go @@ -28,7 +28,6 @@ import ( "github.com/jonboulle/clockwork" "github.com/stretchr/testify/require" - apidefaults "github.com/gravitational/teleport/api/defaults" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/api/types/events" ) @@ -82,12 +81,23 @@ func TestFileLogPagination(t *testing.T) { from := clock.Now().Add(-time.Hour).UTC() to := clock.Now().Add(time.Hour).UTC() - eventArr, checkpoint, err := log.SearchEvents(from, to, apidefaults.Namespace, nil, 2, types.EventOrderAscending, "") + eventArr, checkpoint, err := log.SearchEvents(ctx, SearchEventsRequest{ + From: from, + To: to, + Limit: 2, + Order: types.EventOrderAscending, + }) require.NoError(t, err) require.Len(t, eventArr, 2) require.NotEmpty(t, checkpoint) - eventArr, checkpoint, err = log.SearchEvents(from, to, apidefaults.Namespace, nil, 2, types.EventOrderAscending, checkpoint) + eventArr, checkpoint, err = log.SearchEvents(ctx, SearchEventsRequest{ + From: from, + To: to, + Limit: 2, + Order: types.EventOrderAscending, + StartKey: checkpoint, + }) require.Nil(t, err) require.Len(t, eventArr, 1) require.Empty(t, checkpoint) @@ -115,7 +125,12 @@ func TestSearchSessionEvents(t *testing.T) { })) clock.Advance(1 * time.Minute) - result, _, err := log.SearchSessionEvents(start, clock.Now(), 10, types.EventOrderAscending, "", nil, "") + result, _, err := log.SearchSessionEvents(ctx, SearchSessionEventsRequest{ + From: start, + To: clock.Now(), + Limit: 10, + Order: types.EventOrderAscending, + }) require.NoError(t, err) require.Len(t, result, 1) require.Equal(t, result[0].GetType(), SessionEndEvent) @@ -131,7 +146,12 @@ func TestSearchSessionEvents(t *testing.T) { })) clock.Advance(1 * time.Minute) - result, _, err = log.SearchSessionEvents(start, clock.Now(), 10, types.EventOrderAscending, "", nil, "") + result, _, err = log.SearchSessionEvents(ctx, SearchSessionEventsRequest{ + From: start, + To: clock.Now(), + Limit: 10, + Order: types.EventOrderAscending, + }) require.NoError(t, err) require.Len(t, result, 1) require.Equal(t, result[0].GetType(), SessionEndEvent) @@ -147,7 +167,12 @@ func TestSearchSessionEvents(t *testing.T) { })) clock.Advance(1 * time.Minute) - result, _, err = log.SearchSessionEvents(start, clock.Now(), 10, types.EventOrderAscending, "", nil, "") + result, _, err = log.SearchSessionEvents(ctx, SearchSessionEventsRequest{ + From: start, + To: clock.Now(), + Limit: 10, + Order: types.EventOrderAscending, + }) require.NoError(t, err) require.Len(t, result, 2) require.Equal(t, result[0].GetType(), SessionEndEvent) @@ -270,6 +295,7 @@ func makeQueryEvent(id string, query string) *events.DatabaseSessionQuery { DatabaseQuery: query, } } + func makeAccessRequestEvent(id string, in string) *events.AccessRequestDelete { return &events.AccessRequestDelete{ Metadata: events.Metadata{ @@ -281,15 +307,13 @@ func makeAccessRequestEvent(id string, in string) *events.AccessRequestDelete { } func mustSearchEvent(t *testing.T, log *FileLog, start time.Time) []events.AuditEvent { - result, _, err := log.SearchEvents( - start, - start.Add(time.Hour), - "", - []string{}, - 100, - types.EventOrderAscending, - "", - ) + ctx := context.TODO() + result, _, err := log.SearchEvents(ctx, SearchEventsRequest{ + From: start, + To: start.Add(time.Hour), + Limit: 100, + Order: types.EventOrderAscending, + }) require.NoError(t, err) return result } diff --git a/lib/events/firestoreevents/firestoreevents.go b/lib/events/firestoreevents/firestoreevents.go index 29804f9319b96..b76ac56d94d1d 100644 --- a/lib/events/firestoreevents/firestoreevents.go +++ b/lib/events/firestoreevents/firestoreevents.go @@ -347,8 +347,8 @@ func (l *Log) EmitAuditEvent(ctx context.Context, in apievents.AuditEvent) error // The only mandatory requirement is a date range (UTC). // // This function may never return more than 1 MiB of event data. -func (l *Log) SearchEvents(fromUTC, toUTC time.Time, namespace string, eventTypes []string, limit int, order types.EventOrder, startKey string) ([]apievents.AuditEvent, string, error) { - return l.searchEventsWithFilter(fromUTC, toUTC, namespace, limit, order, startKey, searchEventsFilter{eventTypes: eventTypes}, "") +func (l *Log) SearchEvents(ctx context.Context, req events.SearchEventsRequest) ([]apievents.AuditEvent, string, error) { + return l.searchEventsWithFilter(req.From, req.To, apidefaults.Namespace, req.Limit, req.Order, req.StartKey, searchEventsFilter{eventTypes: req.EventTypes}, "") } func (l *Log) searchEventsWithFilter(fromUTC, toUTC time.Time, namespace string, limit int, order types.EventOrder, lastKey string, filter searchEventsFilter, sessionID string) ([]apievents.AuditEvent, string, error) { @@ -472,16 +472,16 @@ func (l *Log) searchEventsWithFilter(fromUTC, toUTC time.Time, namespace string, // SearchSessionEvents returns session related events only. This is used to // find completed sessions. -func (l *Log) SearchSessionEvents(fromUTC, toUTC time.Time, limit int, order types.EventOrder, startKey string, cond *types.WhereExpr, sessionID string) ([]apievents.AuditEvent, string, error) { +func (l *Log) SearchSessionEvents(ctx context.Context, req events.SearchSessionEventsRequest) ([]apievents.AuditEvent, string, error) { filter := searchEventsFilter{eventTypes: []string{events.SessionEndEvent, events.WindowsDesktopSessionEndEvent}} - if cond != nil { - condFn, err := utils.ToFieldsCondition(cond) + if req.Cond != nil { + condFn, err := utils.ToFieldsCondition(req.Cond) if err != nil { return nil, "", trace.Wrap(err) } filter.condition = condFn } - return l.searchEventsWithFilter(fromUTC, toUTC, apidefaults.Namespace, limit, order, startKey, filter, sessionID) + return l.searchEventsWithFilter(req.From, req.To, apidefaults.Namespace, req.Limit, req.Order, req.StartKey, filter, req.SessionID) } type searchEventsFilter struct { diff --git a/lib/events/multilog.go b/lib/events/multilog.go index cb5e04d405572..f7f22792b43ef 100644 --- a/lib/events/multilog.go +++ b/lib/events/multilog.go @@ -17,11 +17,10 @@ limitations under the License. package events import ( - "time" + "context" "github.com/gravitational/trace" - "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" ) @@ -66,9 +65,9 @@ func (m *MultiLog) Close() error { // The only mandatory requirement is a date range (UTC). // // This function may never return more than 1 MiB of event data. -func (m *MultiLog) SearchEvents(fromUTC, toUTC time.Time, namespace string, eventTypes []string, limit int, order types.EventOrder, startKey string) (events []apievents.AuditEvent, lastKey string, err error) { +func (m *MultiLog) SearchEvents(ctx context.Context, req SearchEventsRequest) (events []apievents.AuditEvent, lastKey string, err error) { for _, log := range m.loggers { - events, lastKey, err := log.SearchEvents(fromUTC, toUTC, namespace, eventTypes, limit, order, startKey) + events, lastKey, err := log.SearchEvents(ctx, req) if !trace.IsNotImplemented(err) { return events, lastKey, err } @@ -82,9 +81,9 @@ func (m *MultiLog) SearchEvents(fromUTC, toUTC time.Time, namespace string, even // // Event types to filter can be specified and pagination is handled by an iterator key that allows // a query to be resumed. -func (m *MultiLog) SearchSessionEvents(fromUTC, toUTC time.Time, limit int, order types.EventOrder, startKey string, cond *types.WhereExpr, sessionID string) (events []apievents.AuditEvent, lastKey string, err error) { +func (m *MultiLog) SearchSessionEvents(ctx context.Context, req SearchSessionEventsRequest) (events []apievents.AuditEvent, lastKey string, err error) { for _, log := range m.loggers { - events, lastKey, err = log.SearchSessionEvents(fromUTC, toUTC, limit, order, startKey, cond, sessionID) + events, lastKey, err = log.SearchSessionEvents(ctx, req) if !trace.IsNotImplemented(err) { return events, lastKey, err } diff --git a/lib/events/search_limiter.go b/lib/events/search_limiter.go index 644e9f69f5724..bf40bb052169e 100644 --- a/lib/events/search_limiter.go +++ b/lib/events/search_limiter.go @@ -15,12 +15,12 @@ package events import ( + "context" "time" "github.com/gravitational/trace" "golang.org/x/time/rate" - "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" ) @@ -74,22 +74,18 @@ func NewSearchEventLimiter(cfg SearchEventsLimiterConfig) (*SearchEventsLimiter, }, nil } -func (s *SearchEventsLimiter) SearchEvents(fromUTC, toUTC time.Time, namespace string, - eventTypes []string, limit int, order types.EventOrder, startKey string, -) ([]apievents.AuditEvent, string, error) { +func (s *SearchEventsLimiter) SearchEvents(ctx context.Context, req SearchEventsRequest) ([]apievents.AuditEvent, string, error) { if !s.limiter.Allow() { return nil, "", trace.LimitExceeded("rate limit exceeded for searching events") } - out, keyset, err := s.AuditLogger.SearchEvents(fromUTC, toUTC, namespace, eventTypes, limit, order, startKey) + out, keyset, err := s.AuditLogger.SearchEvents(ctx, req) return out, keyset, trace.Wrap(err) } -func (s *SearchEventsLimiter) SearchSessionEvents(fromUTC, toUTC time.Time, limit int, - order types.EventOrder, startKey string, cond *types.WhereExpr, sessionID string, -) ([]apievents.AuditEvent, string, error) { +func (s *SearchEventsLimiter) SearchSessionEvents(ctx context.Context, req SearchSessionEventsRequest) ([]apievents.AuditEvent, string, error) { if !s.limiter.Allow() { return nil, "", trace.LimitExceeded("rate limit exceeded for searching events") } - out, keyset, err := s.AuditLogger.SearchSessionEvents(fromUTC, toUTC, limit, order, startKey, cond, sessionID) + out, keyset, err := s.AuditLogger.SearchSessionEvents(ctx, req) return out, keyset, trace.Wrap(err) } diff --git a/lib/events/search_limiter_test.go b/lib/events/search_limiter_test.go index 829ce13c01f43..4fe1e9a3df11c 100644 --- a/lib/events/search_limiter_test.go +++ b/lib/events/search_limiter_test.go @@ -57,35 +57,53 @@ func TestSearchEventsLimiter(t *testing.T) { require.NoError(t, err) someDate := clockwork.NewFakeClock().Now().UTC() - // searchEvents and searchSessionEvents are helper fn to avoid coping those methods with huge - // number of attributes multiple times in that test case. - searchEvents := func() ([]apievents.AuditEvent, string, error) { - return s.SearchEvents(someDate, someDate, "default", nil /* eventTypes */, 100 /* limit */, types.EventOrderAscending, "" /* startKey */) - } - searchSessionEvents := func() ([]apievents.AuditEvent, string, error) { - return s.SearchSessionEvents(someDate, someDate, 100 /* limit */, types.EventOrderAscending, "" /* startKey */, nil /* cond */, "" /* sessionID */) - } + ctx := context.Background() for i := 0; i < burst; i++ { var err error // rate limit is shared between both search endpoints. if i%2 == 0 { - _, _, err = searchEvents() + _, _, err = s.SearchEvents(ctx, events.SearchEventsRequest{ + From: someDate, + To: someDate, + Limit: 100, + Order: types.EventOrderAscending, + }) } else { - _, _, err = searchSessionEvents() + _, _, err = s.SearchSessionEvents(ctx, events.SearchSessionEventsRequest{ + From: someDate, + To: someDate, + Limit: 100, + Order: types.EventOrderAscending, + }) } require.NoError(t, err) } // Now all tokens from rate limit should be used - _, _, err = searchEvents() + _, _, err = s.SearchEvents(ctx, events.SearchEventsRequest{ + From: someDate, + To: someDate, + Limit: 100, + Order: types.EventOrderAscending, + }) require.True(t, trace.IsLimitExceeded(err)) // Also on SearchSessionEvents - _, _, err = searchSessionEvents() + _, _, err = s.SearchSessionEvents(ctx, events.SearchSessionEventsRequest{ + From: someDate, + To: someDate, + Limit: 100, + Order: types.EventOrderAscending, + }) require.True(t, trace.IsLimitExceeded(err)) // After 20ms 1 token should be added according to rate. require.Eventually(t, func() bool { - _, _, err := searchEvents() + _, _, err := s.SearchEvents(ctx, events.SearchEventsRequest{ + From: someDate, + To: someDate, + Limit: 100, + Order: types.EventOrderAscending, + }) return err == nil }, 40*time.Millisecond, 5*time.Millisecond) }) @@ -155,11 +173,11 @@ type mockAuditLogger struct { events.AuditLogger } -func (m *mockAuditLogger) SearchEvents(fromUTC, toUTC time.Time, namespace string, eventTypes []string, limit int, order types.EventOrder, startKey string) ([]apievents.AuditEvent, string, error) { +func (m *mockAuditLogger) SearchEvents(ctx context.Context, req events.SearchEventsRequest) ([]apievents.AuditEvent, string, error) { return m.searchEventsRespFn() } -func (m *mockAuditLogger) SearchSessionEvents(fromUTC, toUTC time.Time, limit int, order types.EventOrder, startKey string, cond *types.WhereExpr, sessionID string) ([]apievents.AuditEvent, string, error) { +func (m *mockAuditLogger) SearchSessionEvents(ctx context.Context, req events.SearchSessionEventsRequest) ([]apievents.AuditEvent, string, error) { return m.searchEventsRespFn() } diff --git a/lib/events/test/suite.go b/lib/events/test/suite.go index d393fa69c1637..cce3d68323dd0 100644 --- a/lib/events/test/suite.go +++ b/lib/events/test/suite.go @@ -29,7 +29,6 @@ import ( "github.com/stretchr/testify/require" "golang.org/x/exp/slices" - apidefaults "github.com/gravitational/teleport/api/defaults" "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/api/utils/retryutils" @@ -111,8 +110,15 @@ func (s *EventsSuite) EventPagination(t *testing.T) { var err error var checkpoint string + ctx := context.Background() err = retryutils.RetryStaticFor(time.Minute*5, time.Second*5, func() error { - arr, checkpoint, err = s.Log.SearchEvents(baseTime, toTime, apidefaults.Namespace, nil, 100, types.EventOrderAscending, checkpoint) + arr, checkpoint, err = s.Log.SearchEvents(ctx, events.SearchEventsRequest{ + From: baseTime, + To: toTime, + Limit: 100, + Order: types.EventOrderAscending, + StartKey: checkpoint, + }) return err }) require.NoError(t, err) @@ -120,7 +126,13 @@ func (s *EventsSuite) EventPagination(t *testing.T) { require.Equal(t, checkpoint, "") for _, name := range names { - arr, checkpoint, err = s.Log.SearchEvents(baseTime, toTime, apidefaults.Namespace, nil, 1, types.EventOrderAscending, checkpoint) + arr, checkpoint, err = s.Log.SearchEvents(ctx, events.SearchEventsRequest{ + From: baseTime, + To: toTime, + Limit: 1, + Order: types.EventOrderAscending, + StartKey: checkpoint, + }) require.NoError(t, err) require.Len(t, arr, 1) event, ok := arr[0].(*apievents.UserLogin) @@ -128,7 +140,13 @@ func (s *EventsSuite) EventPagination(t *testing.T) { require.Equal(t, name, event.User) } if checkpoint != "" { - arr, checkpoint, err = s.Log.SearchEvents(baseTime, toTime, apidefaults.Namespace, nil, 1, types.EventOrderAscending, checkpoint) + arr, checkpoint, err = s.Log.SearchEvents(ctx, events.SearchEventsRequest{ + From: baseTime, + To: toTime, + Limit: 1, + Order: types.EventOrderAscending, + StartKey: checkpoint, + }) require.NoError(t, err) require.Len(t, arr, 0) } @@ -137,7 +155,13 @@ func (s *EventsSuite) EventPagination(t *testing.T) { for _, i := range []int{0, 2} { nameA := names[i] nameB := names[i+1] - arr, checkpoint, err = s.Log.SearchEvents(baseTime, toTime, apidefaults.Namespace, nil, 2, types.EventOrderAscending, checkpoint) + arr, checkpoint, err = s.Log.SearchEvents(ctx, events.SearchEventsRequest{ + From: baseTime, + To: toTime, + Limit: 2, + Order: types.EventOrderAscending, + StartKey: checkpoint, + }) require.NoError(t, err) require.Len(t, arr, 2) eventA, okA := arr[0].(*apievents.UserLogin) @@ -148,14 +172,26 @@ func (s *EventsSuite) EventPagination(t *testing.T) { require.Equal(t, nameB, eventB.User) } if checkpoint != "" { - arr, checkpoint, err = s.Log.SearchEvents(baseTime, toTime, apidefaults.Namespace, nil, 1, types.EventOrderAscending, checkpoint) + arr, checkpoint, err = s.Log.SearchEvents(ctx, events.SearchEventsRequest{ + From: baseTime, + To: toTime, + Limit: 1, + Order: types.EventOrderAscending, + StartKey: checkpoint, + }) require.NoError(t, err) require.Len(t, arr, 0) } require.Equal(t, checkpoint, "") for i := len(names) - 1; i >= 0; i-- { - arr, checkpoint, err = s.Log.SearchEvents(baseTime, toTime, apidefaults.Namespace, nil, 1, types.EventOrderDescending, checkpoint) + arr, checkpoint, err = s.Log.SearchEvents(ctx, events.SearchEventsRequest{ + From: baseTime, + To: toTime, + Limit: 1, + Order: types.EventOrderDescending, + StartKey: checkpoint, + }) require.NoError(t, err) require.Len(t, arr, 1) event, ok := arr[0].(*apievents.UserLogin) @@ -163,7 +199,13 @@ func (s *EventsSuite) EventPagination(t *testing.T) { require.Equal(t, names[i], event.User) } if checkpoint != "" { - arr, checkpoint, err = s.Log.SearchEvents(baseTime, toTime, apidefaults.Namespace, nil, 1, types.EventOrderDescending, checkpoint) + arr, checkpoint, err = s.Log.SearchEvents(ctx, events.SearchEventsRequest{ + From: baseTime, + To: toTime, + Limit: 1, + Order: types.EventOrderDescending, + StartKey: checkpoint, + }) require.NoError(t, err) require.Len(t, arr, 0) } @@ -188,7 +230,13 @@ func (s *EventsSuite) EventPagination(t *testing.T) { Outer: for i := 0; i < len(names); i++ { - arr, checkpoint, err = s.Log.SearchEvents(baseTime2, baseTime2.Add(time.Second), apidefaults.Namespace, nil, 1, types.EventOrderAscending, checkpoint) + arr, checkpoint, err = s.Log.SearchEvents(ctx, events.SearchEventsRequest{ + From: baseTime2, + To: baseTime2.Add(time.Second), + Limit: 1, + Order: types.EventOrderAscending, + StartKey: checkpoint, + }) require.NoError(t, err) require.Len(t, arr, 1) event, ok := arr[0].(*apievents.UserLogin) @@ -231,9 +279,14 @@ func (s *EventsSuite) SessionEventsCRUD(t *testing.T) { } var history []apievents.AuditEvent - + ctx := context.Background() err = retryutils.RetryStaticFor(time.Minute*5, time.Second*5, func() error { - history, _, err = s.Log.SearchEvents(loginTime.Add(-1*time.Hour), loginTime.Add(time.Hour), apidefaults.Namespace, nil, 100, types.EventOrderAscending, "") + history, _, err = s.Log.SearchEvents(ctx, events.SearchEventsRequest{ + From: loginTime.Add(-1 * time.Hour), + To: loginTime.Add(time.Hour), + Limit: 100, + Order: types.EventOrderAscending, + }) if err != nil { t.Logf("Retrying searching of events because of: %v", err) } @@ -284,7 +337,12 @@ func (s *EventsSuite) SessionEventsCRUD(t *testing.T) { // search for the session event. err = retryutils.RetryStaticFor(time.Minute*5, time.Second*5, func() error { - history, _, err = s.Log.SearchEvents(s.Clock.Now().UTC().Add(-1*time.Hour), s.Clock.Now().UTC().Add(time.Hour), apidefaults.Namespace, nil, 100, types.EventOrderAscending, "") + history, _, err = s.Log.SearchEvents(ctx, events.SearchEventsRequest{ + From: s.Clock.Now().UTC().Add(-1 * time.Hour), + To: s.Clock.Now().UTC().Add(time.Hour), + Limit: 100, + Order: types.EventOrderAscending, + }) if err != nil { t.Logf("Retrying searching of events because of: %v", err) } @@ -296,7 +354,12 @@ func (s *EventsSuite) SessionEventsCRUD(t *testing.T) { require.Equal(t, history[1].GetType(), events.SessionStartEvent) require.Equal(t, history[2].GetType(), events.SessionEndEvent) - history, _, err = s.Log.SearchSessionEvents(s.Clock.Now().UTC().Add(-1*time.Hour), s.Clock.Now().UTC().Add(2*time.Hour), 100, types.EventOrderAscending, "", nil, "") + history, _, err = s.Log.SearchSessionEvents(ctx, events.SearchSessionEventsRequest{ + From: s.Clock.Now().UTC().Add(-1 * time.Hour), + To: s.Clock.Now().UTC().Add(2 * time.Hour), + Limit: 100, + Order: types.EventOrderAscending, + }) require.NoError(t, err) require.Len(t, history, 1) @@ -307,15 +370,32 @@ func (s *EventsSuite) SessionEventsCRUD(t *testing.T) { }} } - history, _, err = s.Log.SearchSessionEvents(s.Clock.Now().UTC().Add(-1*time.Hour), s.Clock.Now().UTC().Add(2*time.Hour), 100, types.EventOrderAscending, "", withParticipant("alice"), "") + history, _, err = s.Log.SearchSessionEvents(ctx, events.SearchSessionEventsRequest{ + From: s.Clock.Now().UTC().Add(-1 * time.Hour), + To: s.Clock.Now().UTC().Add(2 * time.Hour), + Limit: 100, + Order: types.EventOrderAscending, + Cond: withParticipant("alice"), + }) require.NoError(t, err) require.Len(t, history, 1) - history, _, err = s.Log.SearchSessionEvents(s.Clock.Now().UTC().Add(-1*time.Hour), s.Clock.Now().UTC().Add(2*time.Hour), 100, types.EventOrderAscending, "", withParticipant("cecile"), "") + history, _, err = s.Log.SearchSessionEvents(ctx, events.SearchSessionEventsRequest{ + From: s.Clock.Now().UTC().Add(-1 * time.Hour), + To: s.Clock.Now().UTC().Add(2 * time.Hour), + Limit: 100, + Order: types.EventOrderAscending, + Cond: withParticipant("cecile"), + }) require.NoError(t, err) require.Len(t, history, 0) - history, _, err = s.Log.SearchSessionEvents(s.Clock.Now().UTC().Add(-1*time.Hour), sessionEndTime.Add(-time.Second), 100, types.EventOrderAscending, "", nil, "") + history, _, err = s.Log.SearchSessionEvents(ctx, events.SearchSessionEventsRequest{ + From: s.Clock.Now().UTC().Add(-1 * time.Hour), + To: sessionEndTime.Add(-time.Second), + Limit: 100, + Order: types.EventOrderAscending, + }) require.NoError(t, err) require.Len(t, history, 0) } @@ -348,7 +428,14 @@ func (s *EventsSuite) SearchSessionEventsBySessionID(t *testing.T) { done := make(chan struct{}) go func() { defer close(done) - events, _, err := s.Log.SearchSessionEvents(from, to, 1000, types.EventOrderDescending, "", nil, secondID) + ctx := context.Background() + events, _, err := s.Log.SearchSessionEvents(ctx, events.SearchSessionEventsRequest{ + From: from, + To: to, + Limit: 1000, + Order: types.EventOrderDescending, + SessionID: secondID, + }) require.NoError(t, err) require.Len(t, events, 1) e, ok := events[0].(*apievents.WindowsDesktopSessionEnd) diff --git a/lib/events/writer.go b/lib/events/writer.go index ac8f1a411a07b..bf034c8b0202e 100644 --- a/lib/events/writer.go +++ b/lib/events/writer.go @@ -17,13 +17,12 @@ limitations under the License. package events import ( + "context" "io" - "time" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" - "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/lib/utils" ) @@ -58,7 +57,7 @@ func (w *WriterLog) Close() error { // // The only mandatory requirement is a date range (UTC). Results must always // show up sorted by date (newest first) -func (w *WriterLog) SearchEvents(fromUTC, toUTC time.Time, namespace string, eventTypes []string, limit int, order types.EventOrder, startKey string) (events []apievents.AuditEvent, lastKey string, err error) { +func (w *WriterLog) SearchEvents(ctx context.Context, req SearchEventsRequest) (events []apievents.AuditEvent, lastKey string, err error) { return nil, "", trace.NotImplemented("not implemented") } @@ -68,6 +67,6 @@ func (w *WriterLog) SearchEvents(fromUTC, toUTC time.Time, namespace string, eve // // Event types to filter can be specified and pagination is handled by an iterator key that allows // a query to be resumed. -func (w *WriterLog) SearchSessionEvents(fromUTC, toUTC time.Time, limit int, order types.EventOrder, startKey string, cond *types.WhereExpr, sessionID string) (events []apievents.AuditEvent, lastKey string, err error) { +func (w *WriterLog) SearchSessionEvents(ctx context.Context, req SearchSessionEventsRequest) (events []apievents.AuditEvent, lastKey string, err error) { return nil, "", trace.NotImplemented("not implemented") } diff --git a/lib/srv/app/server_test.go b/lib/srv/app/server_test.go index 1a53371060bdc..93580eddb278f 100644 --- a/lib/srv/app/server_test.go +++ b/lib/srv/app/server_test.go @@ -130,8 +130,7 @@ type suiteConfig struct { RoleAppLabels types.Labels } -type fakeConnMonitor struct { -} +type fakeConnMonitor struct{} func (f fakeConnMonitor) MonitorConn(ctx context.Context, authzCtx *authz.Context, conn net.Conn) (context.Context, error) { return ctx, nil @@ -938,7 +937,14 @@ func TestRequestAuditEvents(t *testing.T) { }, 500*time.Millisecond, 50*time.Millisecond, "app.session.request event not generated") }) - searchEvents, _, err := s.authServer.AuditLog.SearchEvents(time.Time{}, time.Now().Add(time.Minute), "", []string{events.AppSessionChunkEvent}, 10, types.EventOrderDescending, "") + ctx := context.Background() + searchEvents, _, err := s.authServer.AuditLog.SearchEvents(ctx, events.SearchEventsRequest{ + From: time.Time{}, + To: time.Now().Add(time.Minute), + EventTypes: []string{events.AppSessionChunkEvent}, + Limit: 10, + Order: types.EventOrderDescending, + }) require.NoError(t, err) require.Len(t, searchEvents, 1) diff --git a/lib/web/apiserver.go b/lib/web/apiserver.go index bd5fc2753f5f1..3114c08ac4d60 100644 --- a/lib/web/apiserver.go +++ b/lib/web/apiserver.go @@ -3040,7 +3040,14 @@ func (h *Handler) clusterSearchEvents(w http.ResponseWriter, r *http.Request, p } searchEvents := func(clt auth.ClientI, from, to time.Time, limit int, order types.EventOrder, startKey string) ([]apievents.AuditEvent, string, error) { - return clt.SearchEvents(from, to, apidefaults.Namespace, eventTypes, limit, order, startKey) + return clt.SearchEvents(r.Context(), events.SearchEventsRequest{ + From: from, + To: to, + EventTypes: eventTypes, + Limit: limit, + Order: order, + StartKey: startKey, + }) } return clusterEventsList(r.Context(), sctx, site, r.URL.Query(), searchEvents) } @@ -3061,7 +3068,13 @@ func (h *Handler) clusterSearchEvents(w http.ResponseWriter, r *http.Request, p // If no order is provided it defaults to descending. func (h *Handler) clusterSearchSessionEvents(w http.ResponseWriter, r *http.Request, p httprouter.Params, sctx *SessionContext, site reversetunnel.RemoteSite) (interface{}, error) { searchSessionEvents := func(clt auth.ClientI, from, to time.Time, limit int, order types.EventOrder, startKey string) ([]apievents.AuditEvent, string, error) { - return clt.SearchSessionEvents(from, to, limit, order, startKey, nil, "") + return clt.SearchSessionEvents(r.Context(), events.SearchSessionEventsRequest{ + From: from, + To: to, + Limit: limit, + Order: order, + StartKey: startKey, + }) } return clusterEventsList(r.Context(), sctx, site, r.URL.Query(), searchSessionEvents) } diff --git a/lib/web/apiserver_test.go b/lib/web/apiserver_test.go index d8de3572801be..7591845377dcf 100644 --- a/lib/web/apiserver_test.go +++ b/lib/web/apiserver_test.go @@ -2288,15 +2288,14 @@ func TestLogin(t *testing.T) { }) require.NoError(t, err) - events, _, err := s.server.AuthServer.AuditLog.SearchEvents( - s.clock.Now().Add(-time.Hour), - s.clock.Now().Add(time.Hour), - apidefaults.Namespace, - []string{events.UserLoginEvent}, - 1, - types.EventOrderDescending, - "", - ) + ctx := context.Background() + events, _, err := s.server.AuthServer.AuditLog.SearchEvents(ctx, events.SearchEventsRequest{ + From: s.clock.Now().Add(-time.Hour), + To: s.clock.Now().Add(time.Hour), + EventTypes: []string{events.UserLoginEvent}, + Limit: 1, + Order: types.EventOrderDescending, + }) require.NoError(t, err) event := events[0].(*apievents.UserLogin) require.Equal(t, true, event.Success) @@ -2479,7 +2478,8 @@ echo AutomaticUpgrades: {{ .AutomaticUpgrades }} TestFeatures: modules.Features{ Cloud: true, AutomaticUpgrades: true, - }}) + }, + }) t.Run("default-installer", func(t *testing.T) { re, err := wc.Get(s.ctx, wc.Endpoint("webapi", "scripts", "installer", "default-installer"), url.Values{}) diff --git a/tool/tsh/proxy_test.go b/tool/tsh/proxy_test.go index d2a4a6dc676c9..f9f61b5f57778 100644 --- a/tool/tsh/proxy_test.go +++ b/tool/tsh/proxy_test.go @@ -36,7 +36,6 @@ import ( "golang.org/x/crypto/ssh/agent" "github.com/gravitational/teleport" - apidefaults "github.com/gravitational/teleport/api/defaults" "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/api/utils/retryutils" @@ -842,14 +841,12 @@ func mustFailToRunOpenSSHCommand(t *testing.T, configFile string, sshConnString func mustSearchEvents(t *testing.T, auth *auth.Server) []apievents.AuditEvent { now := time.Now() - events, _, err := auth.SearchEvents( - now.Add(-time.Hour), - now.Add(time.Hour), - apidefaults.Namespace, - nil, - 0, - types.EventOrderDescending, - "") + ctx := context.Background() + events, _, err := auth.SearchEvents(ctx, events.SearchEventsRequest{ + From: now.Add(-time.Hour), + To: now.Add(time.Hour), + Order: types.EventOrderDescending, + }) require.NoError(t, err) return events @@ -1053,6 +1050,7 @@ type fakeAWSAppInfo struct { func (f fakeAWSAppInfo) GetAppName() string { return "fake-aws-app" } + func (f fakeAWSAppInfo) GetEnvVars() (map[string]string, error) { envVars := map[string]string{ "AWS_ACCESS_KEY_ID": "FAKE_ID", @@ -1064,9 +1062,11 @@ func (f fakeAWSAppInfo) GetEnvVars() (map[string]string, error) { } return envVars, nil } + func (f fakeAWSAppInfo) GetEndpointURL() string { return "https://127.0.0.1:12345" } + func (f fakeAWSAppInfo) GetForwardProxyAddr() string { return f.forwardProxyAddr }