Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed invalid parameter exception for the table aws_s3_object Closes #2381 #2409

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
60 changes: 60 additions & 0 deletions aws/table_aws_s3_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,16 @@ func tableAwsS3Object(_ context.Context) *plugin.Table {
KeyColumns: []*plugin.KeyColumn{
{Name: "bucket_name", Require: plugin.Required, CacheMatch: query_cache.CacheMatchExact},
{Name: "prefix", Require: plugin.Optional, CacheMatch: query_cache.CacheMatchExact},

// If you encrypt an object by using server-side encryption with customer-provided
// encryption keys (SSE-C) when you store the object in Amazon S3, then when you
// GET the object, you must use the following query parameter:
{Name: "sse_customer_algorithm", Require: plugin.Optional, CacheMatch: query_cache.CacheMatchExact},
{Name: "sse_customer_key", Require: plugin.Optional, CacheMatch: query_cache.CacheMatchExact},
{Name: "sse_customer_key_md5", Require: plugin.Optional, CacheMatch: query_cache.CacheMatchExact},
},
},

HydrateConfig: []plugin.HydrateConfig{
{
Func: getBucketRegionForObjects,
Expand Down Expand Up @@ -287,6 +295,13 @@ func tableAwsS3Object(_ context.Context) *plugin.Table {
Transform: transform.FromField("SSECustomerAlgorithm"),
Hydrate: headS3Object,
},
{
Name: "sse_customer_key",
Description: "Specifies the customer-provided encryption key for Amazon S3 to use in encrypting data. This value is used to store the object and then it is discarded; Amazon S3 does not store the encryption key. The key must be appropriate for use with the algorithm specified in the x-amz-server-side-encryption-customer-algorithm header.",
Type: proto.ColumnType_STRING,
Transform: transform.FromQual("sse_customer_key"),
Hydrate: headS3Object,
},
{
Name: "sse_customer_key_md5",
Description: "If server-side encryption with a customer-provided encryption key was requested, the response will include this header to provide round-trip message integrity verification of the customer-provided encryption key.",
Expand Down Expand Up @@ -469,6 +484,9 @@ func listS3Objects(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateDa

func getS3Object(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
bucketName := d.EqualsQuals["bucket_name"].GetStringValue()
sseCusAlgorithm := d.EqualsQuals["sse_customer_algorithm"].GetStringValue()
sseCusKeyMd5 := d.EqualsQuals["sse_customer_key_md5"].GetStringValue()
sseCusKey := d.EqualsQuals["sse_customer_key"].GetStringValue()
bucketRegion := ""

// Bucket location will be nil if getBucketLocationForObjects returned an error but
Expand Down Expand Up @@ -497,6 +515,18 @@ func getS3Object(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData
Key: key,
}

// If you encrypt an object by using server-side encryption with customer-provided
// encryption keys (SSE-C) when you store the object in Amazon S3.
if sseCusAlgorithm != "" {
params.SSECustomerAlgorithm = &sseCusAlgorithm
}
if sseCusKey != "" {
params.SSECustomerKey = &sseCusKey
}
if sseCusKeyMd5 != "" {
params.SSECustomerKeyMD5 = &sseCusKeyMd5
}

object, err := svc.GetObject(ctx, params)
if err != nil {
// if the key is unavailable in the provided bucket
Expand All @@ -512,6 +542,9 @@ func getS3Object(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData

func headS3Object(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
bucketName := d.EqualsQuals["bucket_name"].GetStringValue()
sseCusAlgorithm := d.EqualsQuals["sse_customer_algorithm"].GetStringValue()
sseCusKeyMd5 := d.EqualsQuals["sse_customer_key_md5"].GetStringValue()
sseCusKey := d.EqualsQuals["sse_customer_key"].GetStringValue()
bucketRegion := ""

// Bucket location will be nil if getBucketLocationForObjects returned an error but
Expand Down Expand Up @@ -540,6 +573,18 @@ func headS3Object(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateDat
Key: key,
}

// If you encrypt an object by using server-side encryption with customer-provided
// encryption keys (SSE-C) when you store the object in Amazon S3.
if sseCusAlgorithm != "" {
params.SSECustomerAlgorithm = &sseCusAlgorithm
}
if sseCusKey != "" {
params.SSECustomerKey = &sseCusKey
}
if sseCusKeyMd5 != "" {
params.SSECustomerKeyMD5 = &sseCusKeyMd5
}

object, err := svc.HeadObject(ctx, params)
if err != nil {
// if the key is unavailable in the provided bucket
Expand All @@ -555,6 +600,9 @@ func headS3Object(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateDat

func getS3ObjectAttributes(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
bucketName := d.EqualsQuals["bucket_name"].GetStringValue()
sseCusAlgorithm := d.EqualsQuals["sse_customer_algorithm"].GetStringValue()
sseCusKeyMd5 := d.EqualsQuals["sse_customer_key_md5"].GetStringValue()
sseCusKey := d.EqualsQuals["sse_customer_key"].GetStringValue()
bucketRegion := ""

// Bucket location will be nil if getBucketLocationForObjects returned an error but
Expand Down Expand Up @@ -584,6 +632,18 @@ func getS3ObjectAttributes(ctx context.Context, d *plugin.QueryData, h *plugin.H
ObjectAttributes: []types.ObjectAttributes{types.ObjectAttributesChecksum, types.ObjectAttributesObjectParts},
}

// If you encrypt an object by using server-side encryption with customer-provided
// encryption keys (SSE-C) when you store the object in Amazon S3.
if sseCusAlgorithm != "" {
params.SSECustomerAlgorithm = &sseCusAlgorithm
}
if sseCusKey != "" {
params.SSECustomerKey = &sseCusKey
}
if sseCusKeyMd5 != "" {
params.SSECustomerKeyMD5 = &sseCusKeyMd5
}

objectAttributes, err := svc.GetObjectAttributes(ctx, params)
if err != nil {
plugin.Logger(ctx).Error("aws_s3_object.GetObjectAttributes", "api_error", err)
Expand Down
4 changes: 4 additions & 0 deletions docs/tables/aws_s3_object.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ The `aws_s3_object` table in Steampipe provides you with information about objec
- It's recommended that you specify the `prefix` column when querying buckets with a large number of objects to reduce the query time.
- The `body` column returns the raw bytes of the object data as a string. If the bytes entirely consist of valid UTF8 runes, e.g., `.txt files`, an UTF8 data will be set as column value and you will be able to query the object body ([refer example below](#get-data-details-of-a-particular-object-in-a-bucket)). However, for the invalid UTF8 runes, e.g., `.png files`, the bas64 encoding of the bytes will be set as column value and you will not be able to query the object body for those objects.
- Using this table adds to the cost of your monthly bill from AWS. Optimizations have been put in place to minimize the impact as much as possible. You should refer to AWS S3 Pricing to understand the cost implications.
- If you encrypt an object by using server-side encryption with customer-provided encryption keys (SSE-C) when you store the object in Amazon S3, then when you GET the object, you must use the following query parameter:
- `sse_customer_algorithm`
- `sse_customer_key_md5`
- `sse_customer_key`

## Examples

Expand Down
Loading