-
Notifications
You must be signed in to change notification settings - Fork 110
Add aws_ses_template table #2480
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This pull request adds support for querying AWS SES Templates by introducing a new table definition and corresponding integration tests.
- Introduces documentation for the aws_ses_template table.
- Implements the aws_ses_template table in Go with list and get hydrate functions.
- Updates the plugin to register the new table.
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
File | Description |
---|---|
docs/tables/aws_ses_template.md | Adds documentation and usage examples for the aws_ses_template table. |
aws/table_aws_ses_template.go | Implements the aws_ses_template table with list and get functions using AWS SDK v2 and v1 where applicable. |
aws/plugin.go | Registers the aws_ses_template table with the plugin. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @misraved, the changes look great. However, I've added a couple of suggestions—could you please take a look?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@misraved, left a few review comments; please take a look. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @misraved,
Could you please take a look at the following points:
- There seems to be a mismatch between the List and Get API responses.
- The List API returns a property called
Name
, while the Get API returns a field namedTemplateName
. - When running the query:
select * from aws_ses_template where name = 'MySimpleTemplate';
the Get API is triggered. Although it successfully returns the template data, thename
column in the result appears asnull
because the Get API response does not include aName
field—onlyTemplateName
. As a result, the query displays an empty row. - Additionally, I’m encountering the following error:
> select * from aws_ses_template where name = 'MySimpleTemplate';
Error: rpc error: code = Internal desc = aws: rpc error: code = Internal desc = hydrate function getSESTemplateARN failed with panic interface conversion: interface {} is *types.Template, not types.TemplateMetadata (SQLSTATE HV000)
+------+--------------+-----------+-----------+-------------------+-------+------+-----------+--------+------------+--------------------+--------+------+
| name | subject_part | text_part | html_part | created_timestamp | title | akas | partition | region | account_id | sp_connection_name | sp_ctx | _ctx |
+------+--------------+-----------+-----------+-------------------+-------+------+-----------+--------+------------+--------------------+--------+------+
+------+--------------+-----------+-----------+-------------------+-------+------+-----------+--------+------------+--------------------+--------+------+
Purpose-designed for
Updated code: package aws
import (
"context"
"github.com/aws/aws-sdk-go-v2/service/ses"
"github.com/aws/aws-sdk-go-v2/service/ses/types"
"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"
)
func tableAwsSESTemplate(_ context.Context) *plugin.Table {
return &plugin.Table{
Name: "aws_ses_template",
Description: "AWS SES Template",
List: &plugin.ListConfig{
Hydrate: listSESTemplates,
KeyColumns: plugin.KeyColumnSlice{
{Name: "name", Require: plugin.Optional},
},
Tags: map[string]string{"service": "ses", "action": "ListTemplates"},
},
HydrateConfig: []plugin.HydrateConfig{
{
Func: getSESTemplate,
Tags: map[string]string{"service": "ses", "action": "GetTemplate"},
},
},
GetMatrixItemFunc: SupportedRegionMatrix(AWS_EMAIL_SERVICE_ID),
Columns: awsRegionalColumns([]*plugin.Column{
{
Name: "name",
Description: "The name of the template.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("Name", "TemplateName"),
},
{
Name: "subject_part",
Description: "The subject line of the email.",
Type: proto.ColumnType_STRING,
Hydrate: getSESTemplate,
},
{
Name: "text_part",
Description: "The email body that will be visible to recipients whose email clients do not display HTML.",
Type: proto.ColumnType_STRING,
Hydrate: getSESTemplate,
},
{
Name: "html_part",
Description: "The HTML body of the email.",
Type: proto.ColumnType_STRING,
Hydrate: getSESTemplate,
},
{
Name: "created_timestamp",
Description: "The time and date the template was created.",
Type: proto.ColumnType_TIMESTAMP,
},
// Standard columns for all tables
{
Name: "title",
Description: resourceInterfaceDescription("title"),
Type: proto.ColumnType_STRING,
Transform: transform.FromField("Name", "TemplateName"),
},
{
Name: "akas",
Description: resourceInterfaceDescription("akas"),
Type: proto.ColumnType_JSON,
Hydrate: getSESTemplateARN,
Transform: transform.FromValue().Transform(transform.EnsureStringArray),
},
}),
}
}
//// LIST FUNCTION
func listSESTemplates(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) {
// Create Session
svc, err := SESClient(ctx, d)
if err != nil {
plugin.Logger(ctx).Error("aws_ses_template.listSESTemplates", "connection_error", err)
return nil, err
}
if svc == nil {
// Unsupported region check
return nil, nil
}
maxItems := int32(1000)
// Limiting the results
if d.QueryContext.Limit != nil {
limit := int32(*d.QueryContext.Limit)
if limit < maxItems {
maxItems = limit
}
}
input := &ses.ListTemplatesInput{
MaxItems: &maxItems,
}
// List call
output, err := svc.ListTemplates(ctx, input)
if err != nil {
plugin.Logger(ctx).Error("aws_ses_template.listSESTemplates", "api_error", err)
return nil, err
}
for _, template := range output.TemplatesMetadata {
d.StreamListItem(ctx, template)
// Context can be cancelled due to manual cancellation or the limit has been hit
if d.RowsRemaining(ctx) == 0 {
return nil, nil
}
}
return nil, nil
}
//// HYDRATE FUNCTIONS
func getSESTemplate(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
var templateName string
if h.Item != nil {
templateName = *h.Item.(types.TemplateMetadata).Name
}
// Minimize the api call based on the quals
if d.EqualsQualString("name") != "" && templateName != d.EqualsQualString("name") {
plugin.Logger(ctx).Error("DID NOT match stop API call execution", templateName)
return nil, nil
}
// Create Session
svc, err := SESClient(ctx, d)
if err != nil {
plugin.Logger(ctx).Error("aws_ses_template.getSESTemplate", "connection_error", err)
return nil, err
}
if svc == nil {
// Unsupported region check
return nil, nil
}
// Build the params
params := &ses.GetTemplateInput{
TemplateName: &templateName,
}
// Get call
op, err := svc.GetTemplate(ctx, params)
if err != nil {
plugin.Logger(ctx).Error("aws_ses_template.getSESTemplate", "api_error", err)
return nil, err
}
return op.Template, nil
}
func getSESTemplateARN(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
var templateName string
switch item := h.Item.(type) {
case types.TemplateMetadata:
templateName = *item.Name
case *types.Template:
templateName = *item.TemplateName
default:
return nil, nil
}
region := d.EqualsQualString(matrixKeyRegion)
c, err := getCommonColumns(ctx, d, h)
if err != nil {
plugin.Logger(ctx).Error("aws_ses_template.getSESTemplateARN", "api_error", err)
return nil, err
}
commonColumnData := c.(*awsCommonColumnData)
arn := "arn:" + commonColumnData.Partition + ":ses:" + region + ":" + commonColumnData.AccountId + ":template/" + templateName
return arn, nil
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds a new Steampipe table for querying AWS SES Templates, including documentation and implementation for listing and retrieving template details.
- Introduces detailed markdown documentation with usage examples for the aws_ses_template table.
- Implements the table and its list/hydrate functions in Go.
- Updates the plugin registration to include the new table.
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
File | Description |
---|---|
docs/tables/aws_ses_template.md | Adds documentation and usage examples for aws_ses_template. |
aws/table_aws_ses_template.go | Implements the aws_ses_template table and related functions. |
aws/plugin.go | Registers the new aws_ses_template table. |
Comments suppressed due to low confidence (1)
aws/table_aws_ses_template.go:65
- [nitpick] The 'title' column uses the same transformation as the 'name' column, which could be ambiguous. Consider clarifying its purpose or using a distinct transform if it is intended to offer different information.
{
Co-authored-by: Copilot <[email protected]>
Integration test logs
Logs
Example query results
Results