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

Add table aws_trusted_advisor_check_summary Closes #1831 #1978

Merged
merged 14 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions aws/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ func Plugin(ctx context.Context) *plugin.Plugin {
"aws_sts_caller_identity": tableAwsSTSCallerIdentity(ctx),
"aws_tagging_resource": tableAwsTaggingResource(ctx),
"aws_transfer_server": tableAwsTransferServer(ctx),
"aws_trusted_advisor_check_summary": tableAwsTrustedAdvisorCheckSummary(ctx),
"aws_vpc": tableAwsVpc(ctx),
"aws_vpc_customer_gateway": tableAwsVpcCustomerGateway(ctx),
"aws_vpc_dhcp_options": tableAwsVpcDhcpOptions(ctx),
Expand Down
15 changes: 15 additions & 0 deletions aws/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ import (
"github.com/aws/aws-sdk-go-v2/service/ssm"
"github.com/aws/aws-sdk-go-v2/service/ssoadmin"
"github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/aws/aws-sdk-go-v2/service/support"
"github.com/aws/aws-sdk-go-v2/service/transfer"
"github.com/aws/aws-sdk-go-v2/service/waf"
"github.com/aws/aws-sdk-go-v2/service/wafregional"
Expand Down Expand Up @@ -1439,6 +1440,20 @@ func SSOAdminClient(ctx context.Context, d *plugin.QueryData) (*ssoadmin.Client,
return ssoadmin.NewFromConfig(*cfg), nil
}

func SupportClient(ctx context.Context, d *plugin.QueryData) (*support.Client, error) {
// AWS Support is a global service. This means that any endpoint that you use will update your support cases in the Support Center Console.
// For example, if you use the US East (N. Virginia) endpoint to create a case, you can use the US West (Oregon) or Europe (Ireland) endpoint to add a correspondence to the same case.
// https://docs.aws.amazon.com/awssupport/latest/user/about-support-api.html#endpoint
cfg, err := getClientForDefaultRegion(ctx, d)
if err != nil {
return nil, err
}
if cfg == nil {
return nil, nil
}
return support.NewFromConfig(*cfg), nil
}

func TransferClient(ctx context.Context, d *plugin.QueryData) (*transfer.Client, error) {
// AWS Transfer Family
cfg, err := getClientForQuerySupportedRegion(ctx, d, transferEndpoint.EndpointsID)
Expand Down
200 changes: 200 additions & 0 deletions aws/table_aws_trusted_advisor_check_summary.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
package aws

import (
"context"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/support"
"github.com/aws/aws-sdk-go-v2/service/support/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"
)

//// TABLE DEFINITION

func tableAwsTrustedAdvisorCheckSummary(_ context.Context) *plugin.Table {
return &plugin.Table{
Name: "aws_trusted_advisor_check_summary",
Description: "AWS Trusted Advisor Check Summary",
Get: &plugin.GetConfig{
KeyColumns: plugin.SingleColumn("check_id"),
Hydrate: getTrustedAdvisorCheckSummary,
Tags: map[string]string{"service": "support", "action": "DescribeTrustedAdvisorCheckSummaries"},
},
List: &plugin.ListConfig{
Hydrate: listTrustedAdvisorCheckSummaries,
Tags: map[string]string{"service": "support", "action": "DescribeTrustedAdvisorChecks"},
},
HydrateConfig: []plugin.HydrateConfig{
{
Func: getTrustedAdvisorCheckSummary,
Tags: map[string]string{"service": "support", "action": "DescribeTrustedAdvisorCheckSummaries"},
},
},
Columns: awsAccountColumns([]*plugin.Column{
{
Name: "name",
Description: "The display name for the Trusted Advisor check.",
Type: proto.ColumnType_STRING,
},
{
Name: "check_id",
Description: "The unique identifier for the Trusted Advisor check.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("Id", "CheckId"),
},
{
Name: "category",
Description: "The category of the Trusted Advisor check.",
Type: proto.ColumnType_STRING,
},
{
Name: "description",
Description: "The description of the Trusted Advisor check, which includes the alert criteria and recommended operations (contains HTML markup).",
Type: proto.ColumnType_STRING,
},
{
Name: "status",
Description: "The alert status of the check: 'ok' (green), 'warning' (yellow), 'error' (red), or 'not_available'.",
Type: proto.ColumnType_STRING,
Hydrate: getTrustedAdvisorCheckSummary,
},
{
Name: "timestamp",
Description: "The time of the last refresh of the check.",
Type: proto.ColumnType_TIMESTAMP,
Hydrate: getTrustedAdvisorCheckSummary,
},
{
Name: "resources_flagged",
Description: "The number of Amazon Web Services resources that were flagged (listed) by the Trusted Advisor check.",
Type: proto.ColumnType_INT,
Hydrate: getTrustedAdvisorCheckSummary,
Transform: transform.FromField("ResourcesSummary.ResourcesFlagged"),
},
{
Name: "resources_ignored",
Description: "The number of Amazon Web Services resources ignored by Trusted Advisor because information was unavailable.",
Type: proto.ColumnType_INT,
Hydrate: getTrustedAdvisorCheckSummary,
Transform: transform.FromField("ResourcesSummary.ResourcesIgnored"),
},
{
Name: "resources_processed",
Description: "The number of Amazon Web Services resources that were analyzed by the Trusted Advisor check.",
Type: proto.ColumnType_INT,
Hydrate: getTrustedAdvisorCheckSummary,
Transform: transform.FromField("ResourcesSummary.ResourcesProcessed"),
},
{
Name: "resources_suppressed",
Description: "The number of Amazon Web Services resources ignored by Trusted Advisor because they were marked as suppressed by the user.",
Type: proto.ColumnType_INT,
Hydrate: getTrustedAdvisorCheckSummary,
Transform: transform.FromField("ResourcesSummary.ResourcesSuppressed"),
},
{
Name: "category_specific_summary",
Description: "Summary information that relates to the category of the check. Cost Optimizing is the only category that is currently supported.",
Type: proto.ColumnType_JSON,
Hydrate: getTrustedAdvisorCheckSummary,
},
{
Name: "metadata",
Description: "The column headings for the data returned by the Trusted Advisor check. The order of the headings corresponds to the order of the data in the Metadata element of the TrustedAdvisorResourceDetail for the check. Metadata contains all the data that is shown in the Excel download, even in those cases where the UI shows just summary data.",
Type: proto.ColumnType_JSON,
},

// Steampipe standard columns
{
Name: "title",
Description: resourceInterfaceDescription("title"),
Type: proto.ColumnType_STRING,
Transform: transform.FromField("Name"),
},
}),
}
}

//// LIST FUNCTION

func listTrustedAdvisorCheckSummaries(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) {
// Create session
svc, err := SupportClient(ctx, d)
if err != nil {
plugin.Logger(ctx).Error("aws_trusted_advisor_check_summary.listTrustedAdvisorCheckSummaries", "client_error", err)
return nil, err
}
if svc == nil {
return nil, nil
}

input := &support.DescribeTrustedAdvisorChecksInput{
Language: aws.String("en"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ParthaI can this be considered as an optional qual?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@misraved, According to the API documentation, this parameter is necessary for making the API call. We can designate it as a required qualifier or as an optional qualifier with the default value set to en (if the user doesn't provide any value in the WHERE clause for it). By the way, the API does not return the 'Language' property in its response.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ParthaI I think we can update the table to use language as a required qual to best replicate the API behaviour.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated, the PR by making the language column as required qual.

}

// List call
result, err := svc.DescribeTrustedAdvisorChecks(ctx, input)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the API support pagination?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the API does not support pagination

if err != nil {
plugin.Logger(ctx).Error("aws_trusted_advisor_check_summary.listTrustedAdvisorCheckSummaries", "api_error", err)
return nil, err
}

for _, check := range result.Checks {
d.StreamListItem(ctx, check)

// Context can be cancelled due to manual cancellation or the limit has been hit
if d.RowsRemaining(ctx) == 0 {
return nil, nil
}
}

return nil, err
}

//// HYDRATE FUNCTIONS

func getTrustedAdvisorCheckSummary(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {

checkId := ""

if h.Item != nil {
checkSummary := h.Item.(types.TrustedAdvisorCheckDescription)
checkId = *checkSummary.Id
} else if d.EqualsQualString("check_id") != "" {
checkId = d.EqualsQualString("check_id")
}

// Empty check
if checkId == "" {
return nil, nil
}

// Create session
svc, err := SupportClient(ctx, d)
if err != nil {
plugin.Logger(ctx).Error("aws_trusted_advisor_check_summary.getTrustedAdvisorCheckSummary", "client_error", err)
return nil, err
}
if svc == nil {
return nil, nil
}

input := &support.DescribeTrustedAdvisorCheckSummariesInput{
CheckIds: []*string{aws.String(checkId)},
}

// Get call
result, err := svc.DescribeTrustedAdvisorCheckSummaries(ctx, input)
if err != nil {
plugin.Logger(ctx).Error("aws_trusted_advisor_check_summary.getTrustedAdvisorCheckSummary", "api_error", err)
return nil, err
}

if result != nil && len(result.Summaries) > 0 {
return result.Summaries[0], nil
}
return nil, nil
}
63 changes: 63 additions & 0 deletions docs/tables/aws_trusted_advisor_check_summary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Table: aws_trusted_advisor_check_summary

A Trusted Advisor check is a specific evaluation or assessment performed by Trusted Advisor in different categories. These checks cover various areas, including cost optimization, security, performance, and fault tolerance. Each check examines a specific aspect of your AWS resources and provides recommendations for improvement.

## Examples

### Basi info

```sql
select
name,
check_id,
category,
description,
status,
timestamp,
resources_flagged
from
aws_trusted_advisor_check_summary;
```

### Get error check summaries

```sql
select
name,
check_id,
category,
status
from
aws_trusted_advisor_check_summary
where
status = 'error';
```

### Get check summaries for the last 5 days

```sql
select
name,
check_id,
description,
status,
timestamp
from
aws_trusted_advisor_check_summary
where
timestamp >= now() - interval '5 day';
```

### Get resource summaries of each check

```sql
select
name,
check_id,
resources_flagged,
resources_ignored,
resources_processed,
resources_suppressed
from
aws_trusted_advisor_check_summary;
```
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/ssm v1.35.1
github.com/aws/aws-sdk-go-v2/service/ssoadmin v1.16.0
github.com/aws/aws-sdk-go-v2/service/sts v1.18.2
github.com/aws/aws-sdk-go-v2/service/support v1.16.5
github.com/aws/aws-sdk-go-v2/service/transfer v1.33.7
github.com/aws/aws-sdk-go-v2/service/waf v1.12.0
github.com/aws/aws-sdk-go-v2/service/wafregional v1.13.1
Expand Down
6 changes: 2 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,6 @@ github.com/aws/aws-sdk-go-v2/service/docdb v1.20.1 h1:TxhuipVhk7v9vjJGBlHTuJ7CeE
github.com/aws/aws-sdk-go-v2/service/docdb v1.20.1/go.mod h1:L5e0d7YdvUtAiG6AAQqFi5mM1kHkLz32qkoYvZLm1qU=
github.com/aws/aws-sdk-go-v2/service/drs v1.10.0 h1:7JQlmAKx339YQEImt6dK2xViu9t1MUYSs+gc340HEdA=
github.com/aws/aws-sdk-go-v2/service/drs v1.10.0/go.mod h1:+rdKQi9kdwiJXEAR8Yyl++lLbZhVql61xSPdC44YqTs=
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.18.1 h1:xmKa+GjQxvzK5xZNzrcybXuPOvjYX9JDWNkXF7fNr5c=
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.18.1/go.mod h1:uP2wpt43//qh6NqMFslaRu53A2YbnFStkV4Wn1Ldels=
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.19.0 h1:1AlVHOQPNyAxRkujCxmy5gKH7RrO53Z/bFBt1W0sHuM=
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.19.0/go.mod h1:njGV8YOTBFbXQGuoei1SU+rQO32F01qvBQ9oUIR+SSY=
github.com/aws/aws-sdk-go-v2/service/ec2 v1.81.0 h1:FuCLk1Qm2elBD1MLEM0IujYQLfklBRoOleE91Hy8qPU=
Expand Down Expand Up @@ -373,8 +371,6 @@ github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 h1:y2+VQzC
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11/go.mod h1:iV4q2hsqtNECrfmlXyord9u4zyuFEJX9eLgLpSPzWA8=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.22 h1:kv5vRAl00tozRxSnI0IszPWGXsJOyA7hmEUHFYqsyvw=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.22/go.mod h1:Od+GU5+Yx41gryN/ZGZzAJMZ9R1yn6lgA0fD5Lo5SkQ=
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.21 h1:UYhcXvg66FBsZKRpXtNc4w+2rwaTHzST/zhpQBxzhPo=
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.21/go.mod h1:NXJls8x8f9zVSaf+EKKoonqaahWK69MUWm6w6ob0FHs=
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.23 h1:5AwQnYQT3ZX/N7hPTAx4ClWyucaiqr2esQRMNbJIby0=
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.23/go.mod h1:s8OUYECPoPpevQHmRmMBemFIx6Oc91iapsw56KiXIMY=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.21 h1:5C6XgTViSb0bunmU57b3CT+MhxULqHH2721FVA+/kDM=
Expand Down Expand Up @@ -477,6 +473,8 @@ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.0 h1:Jfly6mRxk2ZOSlbCvZfKNS7T
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.0/go.mod h1:TZSH7xLO7+phDtViY/KUp9WGCJMQkLJ/VpgkTFd5gh8=
github.com/aws/aws-sdk-go-v2/service/sts v1.18.2 h1:J/4wIaGInCEYCGhTSruxCxeoA5cy91a+JT7cHFKFSHQ=
github.com/aws/aws-sdk-go-v2/service/sts v1.18.2/go.mod h1:+lGbb3+1ugwKrNTWcf2RT05Xmp543B06zDFTwiTLp7I=
github.com/aws/aws-sdk-go-v2/service/support v1.16.5 h1:JctSnGvysaiNv6gDtXilv4Ojyh3fJpCQFZHR0JAd/O4=
github.com/aws/aws-sdk-go-v2/service/support v1.16.5/go.mod h1:4YUnctd5L64X2XftCT/f8VflYCslNMiSbbpy+6dH94w=
github.com/aws/aws-sdk-go-v2/service/transfer v1.33.7 h1:iwYY0GGCnCvNlJKGMCtSXh0GXswpb8PmBEspYA/WPj0=
github.com/aws/aws-sdk-go-v2/service/transfer v1.33.7/go.mod h1:cNjXfReEhbaKtjZMVLplqrZleWl8Kdjvofc2BAeto6M=
github.com/aws/aws-sdk-go-v2/service/waf v1.12.0 h1:motSjIEk+muJFUq+jbamHME5bTc1kTNm3EgAVTp7rcQ=
Expand Down
Loading