-
Notifications
You must be signed in to change notification settings - Fork 108
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
Showing
3 changed files
with
345 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,219 @@ | ||
package aws | ||
|
||
import ( | ||
"context" | ||
"time" | ||
|
||
"github.com/aws/aws-sdk-go-v2/aws" | ||
"github.com/aws/aws-sdk-go-v2/service/cloudtrail" | ||
"github.com/aws/aws-sdk-go-v2/service/cloudtrail/types" | ||
|
||
cloudtrailv1 "github.com/aws/aws-sdk-go/service/cloudtrail" | ||
|
||
"github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" | ||
"github.com/turbot/steampipe-plugin-sdk/v5/plugin" | ||
"github.com/turbot/steampipe-plugin-sdk/v5/plugin/transform" | ||
) | ||
|
||
//// TABLE DEFINITION | ||
|
||
func tableAwsCloudtrailLookupEvent(_ context.Context) *plugin.Table { | ||
return &plugin.Table{ | ||
Name: "aws_cloudtrail_lookup_event", | ||
Description: "AWS CloudTrail Lookup Event", | ||
List: &plugin.ListConfig{ | ||
Hydrate: listCloudtrailLookupEvents, | ||
Tags: map[string]string{"service": "cloudtrail", "action": "LookupEvents"}, | ||
IgnoreConfig: &plugin.IgnoreConfig{ | ||
ShouldIgnoreErrorFunc: shouldIgnoreErrors([]string{"InvalidLookupAttributesException"}), | ||
}, | ||
KeyColumns: plugin.KeyColumnSlice{ | ||
{Name: "event_id", Require: plugin.Optional}, | ||
{Name: "event_name", Require: plugin.Optional}, | ||
{Name: "event_source", Require: plugin.Optional}, | ||
{Name: "read_only", Require: plugin.Optional}, | ||
{Name: "end_time", Require: plugin.Optional}, | ||
{Name: "start_time", Require: plugin.Optional}, | ||
{Name: "resource_name", Require: plugin.Optional}, | ||
{Name: "resource_type", Require: plugin.Optional}, | ||
{Name: "username", Require: plugin.Optional}, | ||
{Name: "access_key_id", Require: plugin.Optional}, | ||
}, | ||
}, | ||
GetMatrixItemFunc: SupportedRegionMatrix(cloudtrailv1.EndpointsID), | ||
Columns: awsRegionalColumns([]*plugin.Column{ | ||
{ | ||
Name: "event_id", | ||
Description: "The CloudTrail ID of the event returned.", | ||
Type: proto.ColumnType_STRING, | ||
}, | ||
{ | ||
Name: "event_name", | ||
Description: "The name of the event returned.", | ||
Type: proto.ColumnType_STRING, | ||
}, | ||
{ | ||
Name: "event_source", | ||
Description: "The Amazon Web Services service to which the request was made.", | ||
Type: proto.ColumnType_STRING, | ||
}, | ||
{ | ||
Name: "read_only", | ||
Description: "Information about whether the event is a write event or a read event.", | ||
Type: proto.ColumnType_STRING, | ||
}, | ||
{ | ||
Name: "access_key_id", | ||
Description: "The AWS access key ID that was used to sign the request. If the request was made with temporary security credentials, this is the access key ID of the temporary credentials.", | ||
Type: proto.ColumnType_STRING, | ||
}, | ||
{ | ||
Name: "event_time", | ||
Description: "The date and time of the event returned.", | ||
Type: proto.ColumnType_TIMESTAMP, | ||
}, | ||
{ | ||
Name: "end_time", | ||
Description: "Specifies that only events that occur before or at the specified time are returned. If the specified end time is before the specified start time, an error is returned.", | ||
Type: proto.ColumnType_TIMESTAMP, | ||
Transform: transform.FromQual("end_time"), | ||
}, | ||
{ | ||
Name: "start_time", | ||
Description: "Specifies that only events that occur after or at the specified time are returned. If the specified start time is after the specified end time, an error is returned.", | ||
Type: proto.ColumnType_TIMESTAMP, | ||
Transform: transform.FromQual("start_time"), | ||
}, | ||
{ | ||
Name: "resource_name", | ||
Description: "The name of the resource.", | ||
Type: proto.ColumnType_STRING, | ||
Transform: transform.FromQual("resource_name"), | ||
}, | ||
{ | ||
Name: "resource_type", | ||
Description: "The resource type.", | ||
Type: proto.ColumnType_STRING, | ||
Transform: transform.FromQual("resource_type"), | ||
}, | ||
{ | ||
Name: "username", | ||
Description: "A user name or role name of the requester that called the API in the event returned.", | ||
Type: proto.ColumnType_STRING, | ||
}, | ||
{ | ||
Name: "resources", | ||
Description: "A list of resources referenced by the event returned.", | ||
Type: proto.ColumnType_JSON, | ||
}, | ||
{ | ||
Name: "cloud_trail_event", | ||
Description: "A JSON string that contains a representation of the event returned.", | ||
Type: proto.ColumnType_JSON, | ||
}, | ||
|
||
// Steampipe standard columns | ||
{ | ||
Name: "title", | ||
Description: resourceInterfaceDescription("title"), | ||
Type: proto.ColumnType_STRING, | ||
Transform: transform.FromField("EventName"), | ||
}, | ||
}), | ||
} | ||
} | ||
|
||
//// LIST FUNCTION | ||
|
||
func listCloudtrailLookupEvents(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { | ||
// Get client | ||
svc, err := CloudTrailClient(ctx, d) | ||
if err != nil { | ||
plugin.Logger(ctx).Info("aws_cloudtrail_lookup_event.listCloudtrailLookupEvents", "client_error", err) | ||
return nil, err | ||
} | ||
|
||
input := buildCloudtrailLookupEventFilter(ctx, d.Quals) | ||
maxItems := int32(50) | ||
|
||
// Reduce the basic request limit down if the user has only requested a small number of rows | ||
if d.QueryContext.Limit != nil { | ||
limit := int32(*d.QueryContext.Limit) | ||
if limit < maxItems { | ||
maxItems = int32(limit) | ||
} | ||
} | ||
input.MaxResults = &maxItems | ||
|
||
pageLeft := true | ||
for pageLeft { | ||
// apply rate limiting | ||
d.WaitForListRateLimit(ctx) | ||
|
||
resp, err := svc.LookupEvents(ctx, input) | ||
if err != nil { | ||
plugin.Logger(ctx).Info("aws_cloudtrail_lookup_event.listCloudtrailLookupEvents", "api_error", err) | ||
return nil, err | ||
} | ||
|
||
for _, event := range resp.Events { | ||
d.StreamListItem(ctx, event) | ||
|
||
// Context may get cancelled due to manual cancellation or if the limit has been reached | ||
if d.RowsRemaining(ctx) == 0 { | ||
return nil, nil | ||
} | ||
} | ||
if resp.NextToken != nil { | ||
input.NextToken = resp.NextToken | ||
} else { | ||
pageLeft = false | ||
} | ||
} | ||
|
||
return nil, err | ||
} | ||
|
||
//// UTILITY FUNCTION | ||
|
||
// Build Cloudtrail Lookup Event list call input filter | ||
func buildCloudtrailLookupEventFilter(ctx context.Context, quals plugin.KeyColumnQualMap) *cloudtrail.LookupEventsInput { | ||
|
||
input := &cloudtrail.LookupEventsInput{ | ||
MaxResults: aws.Int32(50), | ||
} | ||
attributeKeyMap := map[string]types.LookupAttributeKey{ | ||
"event_id": types.LookupAttributeKeyEventId, | ||
"event_name": types.LookupAttributeKeyEventName, | ||
"read_only": types.LookupAttributeKeyReadOnly, | ||
"username": types.LookupAttributeKeyUsername, | ||
"event_source": types.LookupAttributeKeyEventSource, | ||
"resource_name": types.LookupAttributeKeyResourceName, | ||
"resource_type": types.LookupAttributeKeyResourceType, | ||
"access_key_id": types.LookupAttributeKeyAccessKeyId, | ||
} | ||
|
||
var lookupAttributes []types.LookupAttribute | ||
for columnName, attributeKey := range attributeKeyMap { | ||
if quals[columnName] != nil { | ||
value := getQualsValueByColumn(quals, columnName, "string") | ||
lookupAttribute := types.LookupAttribute{ | ||
AttributeKey: attributeKey, | ||
AttributeValue: aws.String(value.(string)), | ||
} | ||
lookupAttributes = append(lookupAttributes, lookupAttribute) | ||
} | ||
} | ||
input.LookupAttributes = lookupAttributes | ||
|
||
if quals["start_time"] != nil { | ||
value := getQualsValueByColumn(quals, "start_time", "time") | ||
input.StartTime = aws.Time(value.(time.Time)) | ||
} | ||
if quals["end_time"] != nil { | ||
value := getQualsValueByColumn(quals, "end_time", "time") | ||
input.StartTime = aws.Time(value.(time.Time)) | ||
} | ||
|
||
return input | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
--- | ||
title: "Steampipe Table: aws_cloudtrail_lookup_event - Query AWS CloudTrail Lookup Events using SQL" | ||
description: "Allows users to query AWS CloudTrail Lookup Events, providing information about each trail event within AWS CloudTrail. The table can be used to retrieve details such as the event time, event name, resources involved, and much more." | ||
--- | ||
|
||
# Table: aws_cloudtrail_lookup_event - Query AWS CloudTrail Lookup Events using SQL | ||
|
||
AWS CloudTrail Lookup Events is a feature within AWS CloudTrail, a service that provides a record of actions taken by a user, role, or an AWS service in AWS. This feature specifically allows you to look up and retrieve information about the events recorded by CloudTrail. | ||
|
||
## Table Usage Guide | ||
|
||
The `aws_cloudtrail_lookup_event` table in Steampipe provides you with information about each trail event within AWS CloudTrail. This table allows you, as a DevOps engineer, to query event-specific details, including event time, event name, resources involved, and more. You can utilize this table to gather insights on trail events, such as event source, user identity, and request parameters. The schema outlines the various attributes of the CloudTrail event for you, including the event ID, event version, read only, and associated tags. | ||
|
||
**Important notes:** | ||
- For improved performance, it is advised that you use the optional qual `start_time` and `end_time` to limit the result set to a specific time period. | ||
- This table supports optional quals. Queries with optional quals are optimised to use CloudWatch filters. Optional quals are supported for the following columns: | ||
- `read_only` | ||
- `event_id` | ||
- `event_name` | ||
- `event_source` | ||
- `resource_name` | ||
- `resource_type` | ||
- `access_key_id` | ||
- `start_time` | ||
- `end_time` | ||
- `username` | ||
|
||
## Examples | ||
|
||
### List events that occurred over the last five minutes | ||
This query is useful for gaining insights into recent activity within your AWS environment. It provides a quick overview of the events that have taken place in the last five minutes, which can be particularly useful for immediate incident response or real-time monitoring. | ||
|
||
```sql+postgres | ||
select | ||
event_name, | ||
event_source, | ||
event_time, | ||
username, | ||
jsonb_pretty(cloud_trail_event) as cloud_trail_event | ||
from | ||
aws_cloudtrail_lookup_event | ||
where | ||
start_time = now() | ||
and end_time = now() - interval '5 minutes'; | ||
``` | ||
|
||
```sql+sqlite | ||
select | ||
event_name, | ||
event_source, | ||
event_time, | ||
username, | ||
json(cloud_trail_event) as cloud_trail_event | ||
from | ||
aws_cloudtrail_lookup_event | ||
where | ||
start_time = datetime('now') | ||
and end_time = datetime('now', '-5 minutes'); | ||
``` | ||
|
||
### List all action events, i.e., not ReadOnly that occurred over the last hour | ||
Explore which action events have occurred in the last hour on AWS Cloudtrail. This is useful for identifying recent activities that have potentially altered your system. | ||
|
||
```sql+postgres | ||
select | ||
event_name, | ||
event_source, | ||
event_time, | ||
username, | ||
jsonb_pretty(cloud_trail_event) as cloud_trail_event | ||
from | ||
aws_cloudtrail_lookup_event | ||
where | ||
start_time = now() | ||
and end_time = now() - interval '1 hour' | ||
and read_only = 'true' | ||
order by | ||
event_time asc; | ||
``` | ||
|
||
```sql+sqlite | ||
select | ||
event_name, | ||
event_source, | ||
event_time, | ||
username, | ||
json(cloud_trail_event) as cloud_trail_event | ||
from | ||
aws_cloudtrail_lookup_event | ||
where | ||
start_time = datetime('now') | ||
and end_time = datetime('now', '-1 hour') | ||
and read_only = 'true' | ||
order by | ||
event_time asc; | ||
``` | ||
|
||
### List events for a specific service (IAM) that occurred over the last hour | ||
This query allows users to monitor recent activity for a specific service, in this case, AWS's Identity and Access Management (IAM). It is particularly useful for security audits, as it provides a chronological overview of events, including who initiated them and what actions were taken, over the last hour. | ||
|
||
```sql+postgres | ||
select | ||
event_name, | ||
event_source, | ||
event_time, | ||
jsonb_pretty(cloud_trail_event) as cloud_trail_event | ||
from | ||
aws_cloudtrail_lookup_event | ||
where | ||
and event_source = 'iam.amazonaws.com' | ||
and event_time >= now() - interval '1 hour'; | ||
``` | ||
|
||
```sql+sqlite | ||
select | ||
event_name, | ||
event_source, | ||
event_time, | ||
json(cloud_trail_event) as cloud_trail_event | ||
from | ||
aws_cloudtrail_lookup_event | ||
where | ||
and event_source = 'iam.amazonaws.com' | ||
and event_time >= datetime('now', '-1 hour'); | ||
``` |