From 090cff3a30903d4c7e59099b0fe9f9cf1857435d Mon Sep 17 00:00:00 2001 From: ParthaI Date: Tue, 5 Dec 2023 16:46:46 +0530 Subject: [PATCH 01/13] Add table aws_iot_thing Closes #1994 --- .../aws_iot_thing/test-get-expected.json | 7 + .../tests/aws_iot_thing/test-get-query.sql | 3 + .../aws_iot_thing/test-list-expected.json | 10 + .../tests/aws_iot_thing/test-list-query.sql | 3 + .../aws_iot_thing/test-notfound-expected.json | 1 + .../aws_iot_thing/test-notfound-query.sql | 3 + .../aws_iot_thing/test-turbot-expected.json | 8 + .../tests/aws_iot_thing/test-turbot-query.sql | 3 + aws-test/tests/aws_iot_thing/variables.tf | 83 +++++++ aws/plugin.go | 1 + aws/service.go | 13 ++ aws/table_aws_iot_thing.go | 217 ++++++++++++++++++ docs/tables/aws_iot_thing.md | 48 ++++ go.mod | 3 +- go.sum | 20 +- 15 files changed, 414 insertions(+), 9 deletions(-) create mode 100644 aws-test/tests/aws_iot_thing/test-get-expected.json create mode 100644 aws-test/tests/aws_iot_thing/test-get-query.sql create mode 100644 aws-test/tests/aws_iot_thing/test-list-expected.json create mode 100644 aws-test/tests/aws_iot_thing/test-list-query.sql create mode 100644 aws-test/tests/aws_iot_thing/test-notfound-expected.json create mode 100644 aws-test/tests/aws_iot_thing/test-notfound-query.sql create mode 100644 aws-test/tests/aws_iot_thing/test-turbot-expected.json create mode 100644 aws-test/tests/aws_iot_thing/test-turbot-query.sql create mode 100644 aws-test/tests/aws_iot_thing/variables.tf create mode 100644 aws/table_aws_iot_thing.go create mode 100644 docs/tables/aws_iot_thing.md diff --git a/aws-test/tests/aws_iot_thing/test-get-expected.json b/aws-test/tests/aws_iot_thing/test-get-expected.json new file mode 100644 index 000000000..1f5cc1583 --- /dev/null +++ b/aws-test/tests/aws_iot_thing/test-get-expected.json @@ -0,0 +1,7 @@ +[ + { + "arn": "{{ output.resource_aka.value }}", + "default_client_id": "{{ output.default_client_id.value }}", + "thing_name": "{{ resourceName }}" + } +] diff --git a/aws-test/tests/aws_iot_thing/test-get-query.sql b/aws-test/tests/aws_iot_thing/test-get-query.sql new file mode 100644 index 000000000..d988cfdba --- /dev/null +++ b/aws-test/tests/aws_iot_thing/test-get-query.sql @@ -0,0 +1,3 @@ +select thing_name, arn, default_client_id +from aws.aws_iot_thing +where thing_name = '{{ resourceName }}'; \ No newline at end of file diff --git a/aws-test/tests/aws_iot_thing/test-list-expected.json b/aws-test/tests/aws_iot_thing/test-list-expected.json new file mode 100644 index 000000000..a5bf895a5 --- /dev/null +++ b/aws-test/tests/aws_iot_thing/test-list-expected.json @@ -0,0 +1,10 @@ +[ + { + "arn": "{{ output.resource_aka.value }}", + "attributes": { + "Name": "{{ resourceName }}" + }, + "thing_name": "{{ resourceName }}", + "version": "{{ output.version.value }}" + } +] diff --git a/aws-test/tests/aws_iot_thing/test-list-query.sql b/aws-test/tests/aws_iot_thing/test-list-query.sql new file mode 100644 index 000000000..5cc3e0780 --- /dev/null +++ b/aws-test/tests/aws_iot_thing/test-list-query.sql @@ -0,0 +1,3 @@ +select thing_name, arn, version::text, attributes +from aws.aws_iot_thing +where title = '{{ resourceName }}'; \ No newline at end of file diff --git a/aws-test/tests/aws_iot_thing/test-notfound-expected.json b/aws-test/tests/aws_iot_thing/test-notfound-expected.json new file mode 100644 index 000000000..19765bd50 --- /dev/null +++ b/aws-test/tests/aws_iot_thing/test-notfound-expected.json @@ -0,0 +1 @@ +null diff --git a/aws-test/tests/aws_iot_thing/test-notfound-query.sql b/aws-test/tests/aws_iot_thing/test-notfound-query.sql new file mode 100644 index 000000000..807fd4c9a --- /dev/null +++ b/aws-test/tests/aws_iot_thing/test-notfound-query.sql @@ -0,0 +1,3 @@ +select * +from aws.aws_iot_thing +where thing_name = 'dummy-{{ resourceName }}'; \ No newline at end of file diff --git a/aws-test/tests/aws_iot_thing/test-turbot-expected.json b/aws-test/tests/aws_iot_thing/test-turbot-expected.json new file mode 100644 index 000000000..3ac169de0 --- /dev/null +++ b/aws-test/tests/aws_iot_thing/test-turbot-expected.json @@ -0,0 +1,8 @@ +[ + { + "akas": [ + "{{ output.resource_aka.value }}" + ], + "title": "{{ resourceName }}" + } +] \ No newline at end of file diff --git a/aws-test/tests/aws_iot_thing/test-turbot-query.sql b/aws-test/tests/aws_iot_thing/test-turbot-query.sql new file mode 100644 index 000000000..9564572da --- /dev/null +++ b/aws-test/tests/aws_iot_thing/test-turbot-query.sql @@ -0,0 +1,3 @@ +select akas, title +from aws.aws_iot_thing +where thing_name = '{{ resourceName }}'; \ No newline at end of file diff --git a/aws-test/tests/aws_iot_thing/variables.tf b/aws-test/tests/aws_iot_thing/variables.tf new file mode 100644 index 000000000..58f1d797f --- /dev/null +++ b/aws-test/tests/aws_iot_thing/variables.tf @@ -0,0 +1,83 @@ +variable "resource_name" { + type = string + default = "turbot-test-20200125-create-update" + description = "Name of the resource used throughout the test." +} + +variable "aws_profile" { + type = string + default = "default" + description = "AWS credentials profile used for the test. Default is to use the default profile." +} + +variable "aws_region" { + type = string + default = "us-east-1" + description = "AWS region used for the test. Does not work with default region in config, so must be defined here." +} + +variable "aws_region_alternate" { + type = string + default = "us-east-2" + description = "Alternate AWS region used for tests that require two regions (e.g. DynamoDB global tables)." +} + +provider "aws" { + profile = var.aws_profile + region = var.aws_region +} + +provider "aws" { + alias = "alternate" + profile = var.aws_profile + region = var.aws_region_alternate +} + +data "aws_partition" "current" {} +data "aws_caller_identity" "current" {} +data "aws_region" "primary" {} +data "aws_region" "alternate" { + provider = aws.alternate +} + +data "null_data_source" "resource" { + inputs = { + scope = "arn:${data.aws_partition.current.partition}:::${data.aws_caller_identity.current.account_id}" + } +} + +resource "aws_iot_thing" "named_test_resource" { + name = var.resource_name + + attributes = { + Name = var.resource_name + } +} + +output "resource_aka" { + value = aws_iot_thing.named_test_resource.arn +} + +output "resource_name" { + value = var.resource_name +} + +output "version" { + value = aws_iot_thing.named_test_resource.version +} + +output "default_client_id" { + value = aws_iot_thing.named_test_resource.default_client_id +} + +output "account_id" { + value = data.aws_caller_identity.current.account_id +} + +output "aws_partition" { + value = data.aws_partition.current.partition +} + +output "aws_region" { + value = var.aws_region +} \ No newline at end of file diff --git a/aws/plugin.go b/aws/plugin.go index d04aa2d0c..de08e5ab4 100644 --- a/aws/plugin.go +++ b/aws/plugin.go @@ -301,6 +301,7 @@ func Plugin(ctx context.Context) *plugin.Plugin { "aws_inspector_assessment_template": tableAwsInspectorAssessmentTemplate(ctx), "aws_inspector_exclusion": tableAwsInspectorExclusion(ctx), "aws_inspector_finding": tableAwsInspectorFinding(ctx), + "aws_iot_thing": tableAwsIotThing(ctx), "aws_kinesis_consumer": tableAwsKinesisConsumer(ctx), "aws_kinesis_firehose_delivery_stream": tableAwsKinesisFirehoseDeliveryStream(ctx), "aws_kinesis_stream": tableAwsKinesisStream(ctx), diff --git a/aws/service.go b/aws/service.go index 6c770f0d4..f4e1a32ec 100644 --- a/aws/service.go +++ b/aws/service.go @@ -75,6 +75,7 @@ import ( "github.com/aws/aws-sdk-go-v2/service/identitystore" "github.com/aws/aws-sdk-go-v2/service/inspector" "github.com/aws/aws-sdk-go-v2/service/inspector2" + "github.com/aws/aws-sdk-go-v2/service/iot" "github.com/aws/aws-sdk-go-v2/service/kafka" "github.com/aws/aws-sdk-go-v2/service/kinesis" "github.com/aws/aws-sdk-go-v2/service/kinesisanalyticsv2" @@ -154,6 +155,7 @@ import ( glacierEndpoint "github.com/aws/aws-sdk-go/service/glacier" inspectorEndpoint "github.com/aws/aws-sdk-go/service/inspector" inspector2Endpoint "github.com/aws/aws-sdk-go/service/inspector2" + iotEndpoint "github.com/aws/aws-sdk-go/service/iot" kafkaEndpoint "github.com/aws/aws-sdk-go/service/kafka" kinesisanalyticsv2Endpoint "github.com/aws/aws-sdk-go/service/kinesisanalyticsv2" kinesisvideoEndpoint "github.com/aws/aws-sdk-go/service/kinesisvideo" @@ -832,6 +834,17 @@ func Inspector2Client(ctx context.Context, d *plugin.QueryData) (*inspector2.Cli return inspector2.NewFromConfig(*cfg), nil } +func IOTClient(ctx context.Context, d *plugin.QueryData) (*iot.Client, error) { + cfg, err := getClientForQuerySupportedRegion(ctx, d, iotEndpoint.EndpointsID) + if err != nil { + return nil, err + } + if cfg == nil { + return nil, nil + } + return iot.NewFromConfig(*cfg), nil +} + func KafkaClient(ctx context.Context, d *plugin.QueryData) (*kafka.Client, error) { cfg, err := getClientForQuerySupportedRegion(ctx, d, kafkaEndpoint.EndpointsID) if err != nil { diff --git a/aws/table_aws_iot_thing.go b/aws/table_aws_iot_thing.go new file mode 100644 index 000000000..a7ec513a7 --- /dev/null +++ b/aws/table_aws_iot_thing.go @@ -0,0 +1,217 @@ +package aws + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/iot" + "github.com/aws/aws-sdk-go-v2/service/iot/types" + + iotv1 "github.com/aws/aws-sdk-go/service/iot" + + "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 tableAwsIotThing(_ context.Context) *plugin.Table { + return &plugin.Table{ + Name: "aws_iot_thing", + Description: "AWS Iot Thing", + Get: &plugin.GetConfig{ + KeyColumns: plugin.SingleColumn("thing_name"), + Hydrate: getIotThing, + Tags: map[string]string{"service": "iot", "action": "DescribeThing"}, + IgnoreConfig: &plugin.IgnoreConfig{ + ShouldIgnoreErrorFunc: shouldIgnoreErrors([]string{"ResourceNotFoundException"}), + }, + }, + List: &plugin.ListConfig{ + Hydrate: listIotThings, + IgnoreConfig: &plugin.IgnoreConfig{ + ShouldIgnoreErrorFunc: shouldIgnoreErrors([]string{"ResourceNotFoundException"}), + }, + Tags: map[string]string{"service": "iot", "action": "ListThings"}, + KeyColumns: []*plugin.KeyColumn{ + {Name: "attribute_name", Require: plugin.Optional, Operators: []string{"="}}, + {Name: "attribute_value", Require: plugin.Optional, Operators: []string{"="}}, + {Name: "thing_type_name", Require: plugin.Optional, Operators: []string{"="}}, + }, + }, + GetMatrixItemFunc: SupportedRegionMatrix(iotv1.EndpointsID), + Columns: awsRegionalColumns([]*plugin.Column{ + { + Name: "thing_name", + Type: proto.ColumnType_STRING, + Description: "The name of the thing.", + }, + { + Name: "thing_id", + Description: "The ID of the thing to describe.", + Type: proto.ColumnType_STRING, + Hydrate: getIotThing, + }, + { + Name: "arn", + Description: "The Amazon Resource Name (ARN) for the thing.", + Type: proto.ColumnType_STRING, + Transform: transform.FromField("ThingArn"), + }, + { + Name: "thing_type_name", + Description: "The name of the thing type, if the thing has been associated with a type.", + Type: proto.ColumnType_STRING, + }, + { + Name: "attribute_name", + Description: "The attribute name of the thing.", + Type: proto.ColumnType_STRING, + Transform: transform.FromQual("attribute_name"), + }, + { + Name: "attribute_value", + Description: "The attribute value for the attribute name of the thing.", + Type: proto.ColumnType_STRING, + Transform: transform.FromQual("attribute_value"), + }, + { + Name: "billing_group_name", + Description: "The name of the billing group the thing belongs to.", + Type: proto.ColumnType_STRING, + Hydrate: getIotThing, + }, + { + Name: "default_client_id", + Description: "The default MQTT client ID. For a typical device, the thing name is also used as the default MQTT client ID.", + Type: proto.ColumnType_STRING, + Hydrate: getIotThing, + }, + { + Name: "version", + Description: "The version of the thing record in the registry.", + Type: proto.ColumnType_INT, + }, + { + Name: "attributes", + Description: "A list of thing attributes which are name-value pairs.", + Type: proto.ColumnType_JSON, + }, + + // Steampipe standard columns + { + Name: "title", + Description: resourceInterfaceDescription("title"), + Type: proto.ColumnType_STRING, + Transform: transform.FromField("ThingName"), + }, + { + Name: "akas", + Description: resourceInterfaceDescription("akas"), + Type: proto.ColumnType_JSON, + Transform: transform.FromField("ThingArn").Transform(transform.EnsureStringArray), + }, + }), + } +} + +//// LIST FUNCTION + +func listIotThings(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { + // Create Session + svc, err := IOTClient(ctx, d) + if err != nil { + plugin.Logger(ctx).Error("aws_iot_thing.listIotThings", "connection_error", err) + return nil, err + } + if svc == nil { + // Unsupported region, return no data + return nil, nil + } + + // Limiting the results + maxLimit := int32(250) + if d.QueryContext.Limit != nil { + limit := int32(*d.QueryContext.Limit) + if limit < maxLimit { + maxLimit = limit + } + } + + input := &iot.ListThingsInput{ + MaxResults: aws.Int32(maxLimit), + UsePrefixAttributeValue: false, + } + + if d.EqualsQualString("attribute_name") != "" { + input.AttributeName = aws.String(d.EqualsQualString("attribute_name")) + } + if d.EqualsQualString("attribute_value") != "" && d.EqualsQualString("thing_type_name") != "" { + input.AttributeValue = aws.String(d.EqualsQualString("attribute_value")) + input.ThingTypeName = aws.String(d.EqualsQualString("thing_type_name")) + } + + paginator := iot.NewListThingsPaginator(svc, input, func(o *iot.ListThingsPaginatorOptions) { + o.Limit = maxLimit + o.StopOnDuplicateToken = true + }) + + // List call + for paginator.HasMorePages() { + // apply rate limiting + d.WaitForListRateLimit(ctx) + + output, err := paginator.NextPage(ctx) + if err != nil { + plugin.Logger(ctx).Error("aws_iot_thing.listIotThings", "api_error", err) + return nil, err + } + + for _, item := range output.Things { + d.StreamListItem(ctx, item) + + // 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 getIotThing(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { + thingName := "" + if h.Item != nil { + thing := h.Item.(types.ThingAttribute) + thingName = *thing.ThingName + } else { + thingName = d.EqualsQualString("thing_name") + } + + if thingName == "" { + return nil, nil + } + + // Create service + svc, err := IOTClient(ctx, d) + if err != nil { + plugin.Logger(ctx).Error("aws_iot_thing.getIotThing", "connection_error", err) + return nil, err + } + + params := &iot.DescribeThingInput{ + ThingName: aws.String(thingName), + } + + thing, err := svc.DescribeThing(ctx, params) + if err != nil { + plugin.Logger(ctx).Error("aws_iot_thing.getIotThing", "api_error", err) + return nil, err + } + + return thing, nil +} \ No newline at end of file diff --git a/docs/tables/aws_iot_thing.md b/docs/tables/aws_iot_thing.md new file mode 100644 index 000000000..4c0bd6a03 --- /dev/null +++ b/docs/tables/aws_iot_thing.md @@ -0,0 +1,48 @@ +# Table: aws_iot_thing + +AWS IoT Things refer to the virtual representations of physical devices or assets in AWS IoT Core, which is a part of Amazon Web Services (AWS) designed for the Internet of Things (IoT). These "Things" can be any connected device, such as sensors, appliances, machinery, or any other objects that can collect and exchange data over the internet or other networks. + +## Examples + +### Basic info + +```sql +select + thing_name, + thing_id, + arn, + thing_type_name, + version +from + aws_iot_thing; +``` + +### Filter things by attribute name + +```sql +select + thing_name, + thing_id, + arn, + thing_type_name, + version +from + aws_iot_thing +where + attribute_name = 'foo'; +``` + +### List things for a given type name + +```sql +select + thing_name, + arn, + thing_id, + thing_type_name, + attribute_value +from + aws_iot_thing +where + thing_type_name = 'foo'; +``` diff --git a/go.mod b/go.mod index 4d25d0459..1b705166b 100644 --- a/go.mod +++ b/go.mod @@ -68,6 +68,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/identitystore v1.16.0 github.com/aws/aws-sdk-go-v2/service/inspector v1.13.0 github.com/aws/aws-sdk-go-v2/service/inspector2 v1.11.5 + github.com/aws/aws-sdk-go-v2/service/iot v1.40.0 github.com/aws/aws-sdk-go-v2/service/kafka v1.19.0 github.com/aws/aws-sdk-go-v2/service/kinesis v1.17.1 github.com/aws/aws-sdk-go-v2/service/kinesisanalyticsv2 v1.16.0 @@ -119,7 +120,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/wafv2 v1.24.2 github.com/aws/aws-sdk-go-v2/service/wellarchitected v1.20.1 github.com/aws/aws-sdk-go-v2/service/workspaces v1.28.0 - github.com/aws/smithy-go v1.14.2 + github.com/aws/smithy-go v1.18.1 github.com/gocarina/gocsv v0.0.0-20201208093247-67c824bc04d4 github.com/golang/protobuf v1.5.3 github.com/turbot/go-kit v0.8.0-rc.0 diff --git a/go.sum b/go.sum index 8e1b3b1d6..05bb277e6 100644 --- a/go.sum +++ b/go.sum @@ -212,10 +212,11 @@ github.com/aws/aws-sdk-go-v2 v1.17.5/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3eP github.com/aws/aws-sdk-go-v2 v1.17.6/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= github.com/aws/aws-sdk-go-v2 v1.18.0/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= github.com/aws/aws-sdk-go-v2 v1.18.1/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= -github.com/aws/aws-sdk-go-v2 v1.19.0 h1:klAT+y3pGFBU/qVf1uzwttpBbiuozJYWzNLHioyDJ+k= github.com/aws/aws-sdk-go-v2 v1.19.0/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= github.com/aws/aws-sdk-go-v2 v1.21.0 h1:gMT0IW+03wtYJhRqTVYn0wLzwdnK9sRMcxmtfGzRdJc= github.com/aws/aws-sdk-go-v2 v1.21.0/go.mod h1:/RfNgGmRxI+iFOB1OeJUyxiU+9s88k3pfHvDagGEp0M= +github.com/aws/aws-sdk-go-v2 v1.23.5 h1:xK6C4udTyDMd82RFvNkDQxtAd00xlzFUtX4fF2nMZyg= +github.com/aws/aws-sdk-go-v2 v1.23.5/go.mod h1:t3szzKfP0NeRU27uBFczDivYJjsmSnqI8kIvKyWb9ds= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 h1:dK82zF6kkPeCo8J1e+tGx4JdvDIQzj7ygIoLg8WMuGs= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10/go.mod h1:VeTZetY5KRJLuD/7fkQXMU6Mw7H5m/KP2J5Iy9osMno= github.com/aws/aws-sdk-go-v2/config v1.18.10 h1:Znce11DWswdh+5kOsIp+QaNfY9igp1QUN+fZHCKmeCI= @@ -229,19 +230,21 @@ github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.29/go.mod h1:Dip3sIGv48 github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.30/go.mod h1:LUBAO3zNXQjoONBKn/kR1y0Q4cj/D02Ts0uHYjcCQLM= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.33/go.mod h1:7i0PF1ME/2eUPFcjkVIwq+DOygHEoK92t5cDqNgYbIw= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.34/go.mod h1:wZpTEecJe0Btj3IYnDx/VlUzor9wm3fJHyvLpQF0VwY= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.35 h1:hMUCiE3Zi5AHrRNGf5j985u0WyqI6r2NULhUfo0N/No= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.35/go.mod h1:ipR5PvpSPqIqL5Mi82BxLnfMkHVbmco8kUwO2xrCi0M= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 h1:22dGT7PneFMx4+b3pz7lMTRyN8ZKH7M2cW4GP9yUS2g= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41/go.mod h1:CrObHAuPneJBlfEJ5T3szXOUkLEThaGfvnhTf33buas= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.8 h1:8GVZIR0y6JRIUNSYI1xAMF4HDfV8H/bOsZ/8AD/uY5Q= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.8/go.mod h1:rwBfu0SoUkBUZndVgPZKAD9Y2JigaZtRP68unRiYToQ= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.21/go.mod h1:+Gxn8jYn5k9ebfHEqlhrMirFjSW0v0C9fI+KN5vk2kE= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.23/go.mod h1:mr6c4cHC+S/MMkrjtSlG4QA36kOznDep+0fga5L/fGQ= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.24/go.mod h1:gAuCezX/gob6BSMbItsSlMb6WZGV7K2+fWOvk8xBSto= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.27/go.mod h1:UrHnn3QV/d0pBZ6QBAEQcqFLf8FAzLmoUfPVIueOvoM= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.28/go.mod h1:7VRpKQQedkfIEXb4k52I7swUnZP0wohVajJMRn3vsUw= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.29 h1:yOpYx+FTBdpk/g+sBU6Cb1H0U/TLEcYYp66mYqsPpcc= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.29/go.mod h1:M/eUABlDbw2uVrdAn+UsI6M727qp2fxkp8K0ejcBDUY= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 h1:SijA0mgjV8E+8G45ltVHs0fvKpTj8xmZJ3VwhGKtUSI= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35/go.mod h1:SJC1nEVVva1g3pHAIdCp7QsRIkMmLAgoDquQ9Rr8kYw= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.8 h1:ZE2ds/qeBkhk3yqYvS3CDCFNvd9ir5hMjlVStLZWrvM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.8/go.mod h1:/lAPPymDYL023+TS6DJmjuL42nxix2AvEvfjqOBRODk= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.28 h1:KeTxcGdNnQudb46oOl4d90f2I33DF/c6q3RnZAmvQdQ= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.28/go.mod h1:yRZVr/iT0AqyHeep00SZ4YfBAKojXz08w3XMBscdi0c= github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.18 h1:H/mF2LNWwX00lD6FlYfKpLLZgUW7oIzCBkig78x4Xok= @@ -378,6 +381,10 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.21 h1:5C6XgTViS github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.21/go.mod h1:lRToEJsn+DRA9lW4O9L9+/3hjTkUzlzyzHqn8MTds5k= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.21 h1:vY5siRXvW5TrOKm2qKEf9tliBfdLxdfy0i02LOcmqUo= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.21/go.mod h1:WZvNXT1XuH8dnJM0HvOlvk+RNn7NbAPvA/ACO0QarSc= +github.com/aws/aws-sdk-go-v2/service/iot v1.40.0 h1:eFwM4T+/J2twoWpuJuJTSJgo+Sf26w/QJ7QvfcwN3U0= +github.com/aws/aws-sdk-go-v2/service/iot v1.40.0/go.mod h1:b1vPM022rvUGeaV3d3VFXLMh4SmEWhAj/xd+shV6IvA= +github.com/aws/aws-sdk-go-v2/service/iot v1.46.2 h1:O24ngWnPXOmUpIb9ziBJY1+hIfq6iEY1WzR1qxR1lkw= +github.com/aws/aws-sdk-go-v2/service/iot v1.46.2/go.mod h1:dfWYfJ1cAvasl0tIigPpZWk0khs4HjkCpf8tZoitg+M= github.com/aws/aws-sdk-go-v2/service/kafka v1.19.0 h1:mVSEFtTTXa3huVlgDqM4Ng9BGbNTmavaW7jmoQJOCnc= github.com/aws/aws-sdk-go-v2/service/kafka v1.19.0/go.mod h1:H1d6K7aIv7anW0Qxnp9bAD5XGZ4PGi3fMLv9W3imMp0= github.com/aws/aws-sdk-go-v2/service/kinesis v1.17.1 h1:h24DBIGQoSJIb8zY9GFV4Ma1nrNgDSne9MTff07GV7I= @@ -485,12 +492,9 @@ github.com/aws/aws-sdk-go-v2/service/wellarchitected v1.20.1/go.mod h1:Hb9paYQ+u github.com/aws/aws-sdk-go-v2/service/workspaces v1.28.0 h1:sjfoG4ahd0yE77sKiBokTlZHd9pk1k+vPGNJo6ct2QQ= github.com/aws/aws-sdk-go-v2/service/workspaces v1.28.0/go.mod h1:oudvE1/KOdqMDrq9PG1QjLpvQb8S5R3y2Fci+Vuc6To= github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= -github.com/aws/smithy-go v1.14.1 h1:EFKMUmH/iHMqLiwoEDx2rRjRQpI1YCn5jTysoaDujFs= -github.com/aws/smithy-go v1.14.1/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= -github.com/aws/smithy-go v1.14.2 h1:MJU9hqBGbvWZdApzpvoF2WAIJDbtjK2NDJSiJP7HblQ= github.com/aws/smithy-go v1.14.2/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/aws/smithy-go v1.18.1 h1:pOdBTUfXNazOlxLrgeYalVnuTpKreACHtc62xLwIB3c= +github.com/aws/smithy-go v1.18.1/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= From b40b7e9dd92a4974d5cb479f0e3135b194e69f1c Mon Sep 17 00:00:00 2001 From: ParthaI Date: Wed, 6 Dec 2023 16:16:09 +0530 Subject: [PATCH 02/13] Add table aws_iot_fleet_metric Closes #1994 --- aws/plugin.go | 1 + aws/table_aws_iot_fleet_metric.go | 289 ++++++++++++++++++++++++++++ docs/tables/aws_iot_fleet_metric.md | 49 +++++ 3 files changed, 339 insertions(+) create mode 100644 aws/table_aws_iot_fleet_metric.go create mode 100644 docs/tables/aws_iot_fleet_metric.md diff --git a/aws/plugin.go b/aws/plugin.go index d04aa2d0c..4721f8c07 100644 --- a/aws/plugin.go +++ b/aws/plugin.go @@ -301,6 +301,7 @@ func Plugin(ctx context.Context) *plugin.Plugin { "aws_inspector_assessment_template": tableAwsInspectorAssessmentTemplate(ctx), "aws_inspector_exclusion": tableAwsInspectorExclusion(ctx), "aws_inspector_finding": tableAwsInspectorFinding(ctx), + "aws_iot_fleet_metric": tableAwsIotFleetMetric(ctx), "aws_kinesis_consumer": tableAwsKinesisConsumer(ctx), "aws_kinesis_firehose_delivery_stream": tableAwsKinesisFirehoseDeliveryStream(ctx), "aws_kinesis_stream": tableAwsKinesisStream(ctx), diff --git a/aws/table_aws_iot_fleet_metric.go b/aws/table_aws_iot_fleet_metric.go new file mode 100644 index 000000000..0df856d47 --- /dev/null +++ b/aws/table_aws_iot_fleet_metric.go @@ -0,0 +1,289 @@ +package aws + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/iot" + "github.com/aws/aws-sdk-go-v2/service/iot/types" + + iotv1 "github.com/aws/aws-sdk-go/service/iot" + + "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 tableAwsIotFleetMetric(_ context.Context) *plugin.Table { + return &plugin.Table{ + Name: "aws_iot_fleet_metric", + Description: "AWS IoT Fleet Metric", + Get: &plugin.GetConfig{ + KeyColumns: plugin.SingleColumn("metric_name"), + Hydrate: getIotFleetMetric, + Tags: map[string]string{"service": "iot", "action": "DescribeFleetMetric"}, + IgnoreConfig: &plugin.IgnoreConfig{ + ShouldIgnoreErrorFunc: shouldIgnoreErrors([]string{"ResourceNotFoundException"}), + }, + }, + List: &plugin.ListConfig{ + Hydrate: listIotFleetMetrics, + Tags: map[string]string{"service": "iot", "action": "ListFleetMetrics"}, + }, + GetMatrixItemFunc: SupportedRegionMatrix(iotv1.EndpointsID), + Columns: awsRegionalColumns([]*plugin.Column{ + { + Name: "metric_name", + Description: "The name of the thing type.", + Type: proto.ColumnType_STRING, + }, + { + Name: "arn", + Description: "The Amazon Resource Name (ARN) for the thing type.", + Type: proto.ColumnType_STRING, + Transform: transform.FromField("MetricArn"), + }, + { + Name: "index_name", + Description: "The name of the index to search.", + Type: proto.ColumnType_STRING, + Hydrate: getIotFleetMetric, + }, + { + Name: "description", + Description: "The fleet metric description.", + Type: proto.ColumnType_STRING, + Hydrate: getIotFleetMetric, + }, + { + Name: "creation_date", + Description: "The date when the fleet metric is created.", + Type: proto.ColumnType_TIMESTAMP, + Hydrate: getIotFleetMetric, + Transform: transform.FromField("CreationDate"), + }, + { + Name: "last_modified_date", + Description: "The date when the fleet metric is last modified.", + Type: proto.ColumnType_TIMESTAMP, + Hydrate: getIotFleetMetric, + }, + { + Name: "aggregation_field", + Description: "The field to aggregate.", + Type: proto.ColumnType_STRING, + Hydrate: getIotFleetMetric, + }, + { + Name: "aggregation_type_name", + Description: "The name of the aggregation type.", + Type: proto.ColumnType_STRING, + Hydrate: getIotFleetMetric, + Transform: transform.FromField("AggregationType.Name"), + }, + { + Name: "period", + Description: "The time in seconds between fleet metric emissions. Range [60(1 min), 86400(1 day)] and must be multiple of 60.", + Type: proto.ColumnType_INT, + Hydrate: getIotFleetMetric, + }, + { + Name: "query_string", + Description: "The search query string.", + Type: proto.ColumnType_STRING, + Hydrate: getIotFleetMetric, + }, + { + Name: "query_version", + Description: "The search query version.", + Type: proto.ColumnType_STRING, + Hydrate: getIotFleetMetric, + }, + { + Name: "unit", + Description: "Used to support unit transformation such as milliseconds to seconds. The unit must be supported by CW metric (https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_MetricDatum.html)", + Type: proto.ColumnType_STRING, + Hydrate: getIotFleetMetric, + }, + { + Name: "version", + Description: "The version of the fleet metric.", + Type: proto.ColumnType_STRING, + Hydrate: getIotFleetMetric, + }, + { + Name: "aggregation_type_values", + Description: "A list of the values of aggregation types.", + Type: proto.ColumnType_JSON, + Hydrate: getIotFleetMetric, + Transform: transform.FromField("AggregationType.Values"), + }, + { + Name: "tags_src", + Description: "A list of tags currently associated with the thing type.", + Type: proto.ColumnType_JSON, + Hydrate: getIotFleetMetricTags, + Transform: transform.FromField("Tags"), + }, + + // Steampipe standard columns + { + Name: "title", + Description: resourceInterfaceDescription("title"), + Type: proto.ColumnType_STRING, + Transform: transform.FromField("MetricName"), + }, + { + Name: "tags", + Description: resourceInterfaceDescription("tags"), + Type: proto.ColumnType_JSON, + Hydrate: getIotFleetMetricTags, + Transform: transform.From(iotFleetMetricTagListToTagsMap), + }, + { + Name: "akas", + Description: resourceInterfaceDescription("akas"), + Type: proto.ColumnType_JSON, + Transform: transform.FromField("MetricArn").Transform(transform.EnsureStringArray), + }, + }), + } +} + +//// LIST FUNCTION + +func listIotFleetMetrics(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { + // Create Session + svc, err := IOTClient(ctx, d) + if err != nil { + plugin.Logger(ctx).Error("aws_iot_fleet_metric.listIotFleetMetrics", "connection_error", err) + return nil, err + } + if svc == nil { + // Unsupported region, return no data + return nil, nil + } + + // Limiting the results + maxLimit := int32(250) + if d.QueryContext.Limit != nil { + limit := int32(*d.QueryContext.Limit) + if limit < maxLimit { + maxLimit = limit + } + } + + input := &iot.ListFleetMetricsInput{ + MaxResults: aws.Int32(maxLimit), + } + + paginator := iot.NewListFleetMetricsPaginator(svc, input, func(o *iot.ListFleetMetricsPaginatorOptions) { + o.Limit = maxLimit + o.StopOnDuplicateToken = true + }) + + // List call + for paginator.HasMorePages() { + // apply rate limiting + d.WaitForListRateLimit(ctx) + + output, err := paginator.NextPage(ctx) + if err != nil { + plugin.Logger(ctx).Error("aws_iot_fleet_metric.listIotFleetMetrics", "api_error", err) + return nil, err + } + + for _, item := range output.FleetMetrics { + d.StreamListItem(ctx, item) + + // 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 getIotFleetMetric(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { + metricName := "" + if h.Item != nil { + t := h.Item.(types.FleetMetricNameAndArn) + metricName = *t.MetricName + } else { + metricName = d.EqualsQualString("metric_name") + } + + if metricName == "" { + return nil, nil + } + + // Create service + svc, err := IOTClient(ctx, d) + if err != nil { + plugin.Logger(ctx).Error("aws_iot_fleet_metric.getIotFleetMetric", "connection_error", err) + return nil, err + } + + params := &iot.DescribeFleetMetricInput{ + MetricName: aws.String(metricName), + } + + resp, err := svc.DescribeFleetMetric(ctx, params) + if err != nil { + plugin.Logger(ctx).Error("aws_iot_fleet_metric.getIotFleetMetric", "api_error", err) + return nil, err + } + + return resp, nil +} + +func getIotFleetMetricTags(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { + typeArn := "" + switch item := h.Item.(type) { + case *iot.DescribeThingTypeOutput: + typeArn = *item.ThingTypeArn + case types.ThingTypeDefinition: + typeArn = *item.ThingTypeArn + } + + // Create service + svc, err := IOTClient(ctx, d) + if err != nil { + plugin.Logger(ctx).Error("aws_iot_fleet_metric.getIotFleetMetricTags", "connection_error", err) + return nil, err + } + + params := &iot.ListTagsForResourceInput{ + ResourceArn: aws.String(typeArn), + } + + endpointTags, err := svc.ListTagsForResource(ctx, params) + if err != nil { + plugin.Logger(ctx).Error("aws_iot_fleet_metric.getIotFleetMetricTags", "api_error", err) + return nil, err + } + + return endpointTags, nil +} + +//// TRANSFORM FUNCTIONS + +func iotFleetMetricTagListToTagsMap(_ context.Context, d *transform.TransformData) (interface{}, error) { + data := d.HydrateItem.(*iot.ListTagsForResourceOutput) + + // Mapping the resource tags inside turbotTags + if data.Tags != nil { + turbotTagsMap := map[string]string{} + for _, i := range data.Tags { + turbotTagsMap[*i.Key] = *i.Value + } + return turbotTagsMap, nil + } + return nil, nil +} diff --git a/docs/tables/aws_iot_fleet_metric.md b/docs/tables/aws_iot_fleet_metric.md new file mode 100644 index 000000000..899eee64d --- /dev/null +++ b/docs/tables/aws_iot_fleet_metric.md @@ -0,0 +1,49 @@ +# Table: aws_iot_fleet_metric + +AWS IoT Fleet Metrics is a feature in AWS IoT Device Management that allows you to monitor and manage the status and performance of your IoT device fleet. It enables you to define custom metrics based on device data reported to AWS IoT Core, such as device states or telemetry data. These metrics provide insights into various aspects of your IoT fleet, helping you make informed decisions about device maintenance, operations, and performance optimization. + +## Examples + +### Basic info + +```sql +select + metric_name, + arn, + index_name, + creation_date, + last_modified_date +from + aws_iot_fleet_metric; +``` + +### Aggregate fleet metric by type name + +```sql +select + metric_name, + aggregation_field, + creation_date, + aggregation_type_name, + query_string +from + aws_iot_fleet_metric +group by + aggregation_type_name; +``` + +### List fleet metrics updated in the last 30 days + +```sql +select + metric_name, + index_name, + creation_date, + last_modified_date, + query_version, + version +from + aws_iot_fleet_metric +where + last_modified_date >= now() - interval '30' day; +``` \ No newline at end of file From 7b23560c50c7c8b1312d9ab7a19ffc648adc7118 Mon Sep 17 00:00:00 2001 From: ParthaI Date: Tue, 30 Jan 2024 16:16:45 +0530 Subject: [PATCH 03/13] go mod tidy --- go.sum | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/go.sum b/go.sum index d81980e67..801768097 100644 --- a/go.sum +++ b/go.sum @@ -215,8 +215,6 @@ github.com/aws/aws-sdk-go-v2 v1.18.1/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3eP github.com/aws/aws-sdk-go-v2 v1.19.0/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= github.com/aws/aws-sdk-go-v2 v1.21.0 h1:gMT0IW+03wtYJhRqTVYn0wLzwdnK9sRMcxmtfGzRdJc= github.com/aws/aws-sdk-go-v2 v1.21.0/go.mod h1:/RfNgGmRxI+iFOB1OeJUyxiU+9s88k3pfHvDagGEp0M= -github.com/aws/aws-sdk-go-v2 v1.23.5 h1:xK6C4udTyDMd82RFvNkDQxtAd00xlzFUtX4fF2nMZyg= -github.com/aws/aws-sdk-go-v2 v1.23.5/go.mod h1:t3szzKfP0NeRU27uBFczDivYJjsmSnqI8kIvKyWb9ds= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 h1:dK82zF6kkPeCo8J1e+tGx4JdvDIQzj7ygIoLg8WMuGs= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10/go.mod h1:VeTZetY5KRJLuD/7fkQXMU6Mw7H5m/KP2J5Iy9osMno= github.com/aws/aws-sdk-go-v2/config v1.18.10 h1:Znce11DWswdh+5kOsIp+QaNfY9igp1QUN+fZHCKmeCI= @@ -233,8 +231,6 @@ github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.34/go.mod h1:wZpTEecJe0 github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.35/go.mod h1:ipR5PvpSPqIqL5Mi82BxLnfMkHVbmco8kUwO2xrCi0M= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 h1:22dGT7PneFMx4+b3pz7lMTRyN8ZKH7M2cW4GP9yUS2g= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41/go.mod h1:CrObHAuPneJBlfEJ5T3szXOUkLEThaGfvnhTf33buas= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.8 h1:8GVZIR0y6JRIUNSYI1xAMF4HDfV8H/bOsZ/8AD/uY5Q= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.8/go.mod h1:rwBfu0SoUkBUZndVgPZKAD9Y2JigaZtRP68unRiYToQ= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.21/go.mod h1:+Gxn8jYn5k9ebfHEqlhrMirFjSW0v0C9fI+KN5vk2kE= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.23/go.mod h1:mr6c4cHC+S/MMkrjtSlG4QA36kOznDep+0fga5L/fGQ= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.24/go.mod h1:gAuCezX/gob6BSMbItsSlMb6WZGV7K2+fWOvk8xBSto= @@ -243,8 +239,6 @@ github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.28/go.mod h1:7VRpKQQedkf github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.29/go.mod h1:M/eUABlDbw2uVrdAn+UsI6M727qp2fxkp8K0ejcBDUY= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 h1:SijA0mgjV8E+8G45ltVHs0fvKpTj8xmZJ3VwhGKtUSI= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35/go.mod h1:SJC1nEVVva1g3pHAIdCp7QsRIkMmLAgoDquQ9Rr8kYw= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.8 h1:ZE2ds/qeBkhk3yqYvS3CDCFNvd9ir5hMjlVStLZWrvM= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.8/go.mod h1:/lAPPymDYL023+TS6DJmjuL42nxix2AvEvfjqOBRODk= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.28 h1:KeTxcGdNnQudb46oOl4d90f2I33DF/c6q3RnZAmvQdQ= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.28/go.mod h1:yRZVr/iT0AqyHeep00SZ4YfBAKojXz08w3XMBscdi0c= github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.18 h1:H/mF2LNWwX00lD6FlYfKpLLZgUW7oIzCBkig78x4Xok= @@ -321,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= @@ -379,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= @@ -389,8 +379,6 @@ github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.21 h1:vY5siRXvW5TrO github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.21/go.mod h1:WZvNXT1XuH8dnJM0HvOlvk+RNn7NbAPvA/ACO0QarSc= github.com/aws/aws-sdk-go-v2/service/iot v1.40.0 h1:eFwM4T+/J2twoWpuJuJTSJgo+Sf26w/QJ7QvfcwN3U0= github.com/aws/aws-sdk-go-v2/service/iot v1.40.0/go.mod h1:b1vPM022rvUGeaV3d3VFXLMh4SmEWhAj/xd+shV6IvA= -github.com/aws/aws-sdk-go-v2/service/iot v1.46.2 h1:O24ngWnPXOmUpIb9ziBJY1+hIfq6iEY1WzR1qxR1lkw= -github.com/aws/aws-sdk-go-v2/service/iot v1.46.2/go.mod h1:dfWYfJ1cAvasl0tIigPpZWk0khs4HjkCpf8tZoitg+M= github.com/aws/aws-sdk-go-v2/service/kafka v1.19.0 h1:mVSEFtTTXa3huVlgDqM4Ng9BGbNTmavaW7jmoQJOCnc= github.com/aws/aws-sdk-go-v2/service/kafka v1.19.0/go.mod h1:H1d6K7aIv7anW0Qxnp9bAD5XGZ4PGi3fMLv9W3imMp0= github.com/aws/aws-sdk-go-v2/service/kinesis v1.17.1 h1:h24DBIGQoSJIb8zY9GFV4Ma1nrNgDSne9MTff07GV7I= From 22b0de0f0ffb2172437b6a98c16698f345ebf919 Mon Sep 17 00:00:00 2001 From: ParthaI Date: Tue, 30 Jan 2024 16:22:57 +0530 Subject: [PATCH 04/13] Updated the doc to match the latest doc format --- docs/tables/aws_iot_thing.md | 65 +++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 8 deletions(-) diff --git a/docs/tables/aws_iot_thing.md b/docs/tables/aws_iot_thing.md index 4c0bd6a03..ab2c31dcd 100644 --- a/docs/tables/aws_iot_thing.md +++ b/docs/tables/aws_iot_thing.md @@ -1,12 +1,22 @@ -# Table: aws_iot_thing +--- +title: "Steampipe Table: aws_iot_thing - Query AWS Internet of Things using SQL" +description: "Allows users to query AWS Internet of Things to retrieve detailed information about the the virtual model of a physical device with in an AWS account." +--- -AWS IoT Things refer to the virtual representations of physical devices or assets in AWS IoT Core, which is a part of Amazon Web Services (AWS) designed for the Internet of Things (IoT). These "Things" can be any connected device, such as sensors, appliances, machinery, or any other objects that can collect and exchange data over the internet or other networks. +# Table: aws_iot_thing - Query AWS IoT Things using SQL + +AWS IoT Core allows for the management and connection of Internet of Things (IoT) devices to the AWS cloud. In this service, an IoT "Thing" represents the virtual model of a physical device or asset. These things, which can range from sensors and appliances to machinery, are capable of collecting and exchanging data over the internet or other networks. + +## Table Usage Guide + +The `aws_iot_thing` table facilitates the exploration and management of AWS IoT Things. Utilize this table to access comprehensive details about each IoT Thing, including its name, ID, type, and attributes. This is particularly beneficial for IoT administrators and developers who need to oversee IoT device configurations and statuses within the AWS ecosystem. ## Examples -### Basic info +### Basic Info +Retrieve fundamental details about your AWS IoT Things. This query is crucial for a general overview of IoT Things in your environment, including their identifiers and types. -```sql +```sql+postgres select thing_name, thing_id, @@ -17,9 +27,21 @@ from aws_iot_thing; ``` -### Filter things by attribute name +```sql+sqlite +select + thing_name, + thing_id, + arn, + thing_type_name, + version +from + aws_iot_thing; +``` + +### Filter Things by Attribute Name +Identify specific IoT Things based on a particular attribute name. This query is useful for segmenting IoT Things according to custom-defined criteria or characteristics. -```sql +```sql+postgres select thing_name, thing_id, @@ -32,9 +54,36 @@ where attribute_name = 'foo'; ``` -### List things for a given type name +```sql+sqlite +select + thing_name, + thing_id, + arn, + thing_type_name, + version +from + aws_iot_thing +where + attribute_name = 'foo'; +``` + +### List Things for a Given Type Name +Find all IoT Things that belong to a specific type. This query aids in understanding the distribution and categorization of IoT Things by type within your AWS IoT environment. + +```sql+postgres +select + thing_name, + arn, + thing_id, + thing_type_name, + attribute_value +from + aws_iot_thing +where + thing_type_name = 'foo'; +``` -```sql +```sql+sqlite select thing_name, arn, From d9be0e02cfc299f3c1e2b9f822556738573e0e59 Mon Sep 17 00:00:00 2001 From: ParthaI Date: Tue, 30 Jan 2024 17:06:35 +0530 Subject: [PATCH 05/13] Added the rate limiter config for the hydrated function and rearrange the optional qualifier as per input param --- aws/table_aws_iot_thing.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/aws/table_aws_iot_thing.go b/aws/table_aws_iot_thing.go index a7ec513a7..37da3c7e7 100644 --- a/aws/table_aws_iot_thing.go +++ b/aws/table_aws_iot_thing.go @@ -40,12 +40,18 @@ func tableAwsIotThing(_ context.Context) *plugin.Table { {Name: "thing_type_name", Require: plugin.Optional, Operators: []string{"="}}, }, }, + HydrateConfig: []plugin.HydrateConfig{ + { + Func: getIotThing, + Tags: map[string]string{"service": "iot", "action": "DescribeThing"}, + }, + }, GetMatrixItemFunc: SupportedRegionMatrix(iotv1.EndpointsID), Columns: awsRegionalColumns([]*plugin.Column{ { Name: "thing_name", - Type: proto.ColumnType_STRING, Description: "The name of the thing.", + Type: proto.ColumnType_STRING, }, { Name: "thing_id", @@ -147,8 +153,10 @@ func listIotThings(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateDa if d.EqualsQualString("attribute_name") != "" { input.AttributeName = aws.String(d.EqualsQualString("attribute_name")) } - if d.EqualsQualString("attribute_value") != "" && d.EqualsQualString("thing_type_name") != "" { + if d.EqualsQualString("attribute_value") != "" && d.EqualsQualString("attribute_name") != ""{ input.AttributeValue = aws.String(d.EqualsQualString("attribute_value")) + } + if d.EqualsQualString("thing_type_name") != "" { input.ThingTypeName = aws.String(d.EqualsQualString("thing_type_name")) } @@ -214,4 +222,4 @@ func getIotThing(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData } return thing, nil -} \ No newline at end of file +} From 4a20e3d5c9986c50fdaa48535091d7560a6a6812 Mon Sep 17 00:00:00 2001 From: ParthaI Date: Tue, 30 Jan 2024 18:14:40 +0530 Subject: [PATCH 06/13] Added the rate limiter config for the hydrated function and updated the doc to match the latest doc format --- aws/table_aws_iot_fleet_metric.go | 6 +++ docs/tables/aws_iot_fleet_metric.md | 70 ++++++++++++++++++++++++----- 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/aws/table_aws_iot_fleet_metric.go b/aws/table_aws_iot_fleet_metric.go index 0df856d47..202d1a499 100644 --- a/aws/table_aws_iot_fleet_metric.go +++ b/aws/table_aws_iot_fleet_metric.go @@ -32,6 +32,12 @@ func tableAwsIotFleetMetric(_ context.Context) *plugin.Table { Hydrate: listIotFleetMetrics, Tags: map[string]string{"service": "iot", "action": "ListFleetMetrics"}, }, + HydrateConfig: []plugin.HydrateConfig{ + { + Func: getIotFleetMetric, + Tags: map[string]string{"service": "iot", "action": "DescribeFleetMetric"}, + }, + }, GetMatrixItemFunc: SupportedRegionMatrix(iotv1.EndpointsID), Columns: awsRegionalColumns([]*plugin.Column{ { diff --git a/docs/tables/aws_iot_fleet_metric.md b/docs/tables/aws_iot_fleet_metric.md index 899eee64d..5b771dfe0 100644 --- a/docs/tables/aws_iot_fleet_metric.md +++ b/docs/tables/aws_iot_fleet_metric.md @@ -1,12 +1,22 @@ -# Table: aws_iot_fleet_metric +--- +title: "Steampipe Table: aws_iot_fleet_metric - Query AWS IoT Fleet Metrics using SQL" +description: "Allows users to query AWS IoT Fleet Metrics to gain insights into each fleet metric's configuration, including ARN, creation date, and aggregation information." +--- -AWS IoT Fleet Metrics is a feature in AWS IoT Device Management that allows you to monitor and manage the status and performance of your IoT device fleet. It enables you to define custom metrics based on device data reported to AWS IoT Core, such as device states or telemetry data. These metrics provide insights into various aspects of your IoT fleet, helping you make informed decisions about device maintenance, operations, and performance optimization. +# Table: aws_iot_fleet_metric - Query AWS IoT Fleet Metrics using SQL + +AWS IoT Fleet Metrics, part of AWS IoT Device Management, allows for the monitoring and management of the status and performance of your IoT device fleet. It enables the definition of custom metrics based on device data reported to AWS IoT Core, such as device states or telemetry data. These metrics are instrumental in providing insights into various aspects of your IoT fleet, aiding in decisions related to device maintenance, operations, and performance optimization. + +## Table Usage Guide + +The `aws_iot_fleet_metric` table can be utilized to access detailed information about custom metrics defined for IoT device fleets. This table is essential for IoT administrators and analysts who need to oversee fleet performance, status, and operational metrics within AWS. ## Examples -### Basic info +### Basic Info +Retrieve fundamental details about AWS IoT Fleet Metrics, including metric names, associated ARNs, index names, and dates of creation and modification. -```sql +```sql+postgres select metric_name, arn, @@ -17,9 +27,34 @@ from aws_iot_fleet_metric; ``` -### Aggregate fleet metric by type name +```sql+sqlite +select + metric_name, + arn, + index_name, + creation_date, + last_modified_date +from + aws_iot_fleet_metric; +``` + +### Aggregate Fleet Metric by Type Name +Group fleet metrics by their aggregation type name. This query is useful for analyzing metrics across different aggregation types, providing a broader view of fleet data categorization. + +```sql+postgres +select + metric_name, + aggregation_field, + creation_date, + aggregation_type_name, + query_string +from + aws_iot_fleet_metric +group by + aggregation_type_name; +``` -```sql +```sql+sqlite select metric_name, aggregation_field, @@ -32,9 +67,10 @@ group by aggregation_type_name; ``` -### List fleet metrics updated in the last 30 days +### List Fleet Metrics Updated in the Last 30 Days +Find fleet metrics that have been updated within the last 30 days. This query assists in identifying recent changes or updates in fleet metric configurations. -```sql +```sql+postgres select metric_name, index_name, @@ -45,5 +81,19 @@ select from aws_iot_fleet_metric where - last_modified_date >= now() - interval '30' day; -``` \ No newline at end of file + last_modified_date >= now() - interval '30 days'; +``` + +```sql+sqlite +select + metric_name, + index_name, + creation_date, + last_modified_date, + query_version, + version +from + aws_iot_fleet_metric +where + datetime(last_modified_date) >= datetime('now', '-30 days'); +``` From 24c661269a36a7d63a2bed27faabbe7db884f010 Mon Sep 17 00:00:00 2001 From: ParthaI <47887552+ParthaI@users.noreply.github.com> Date: Thu, 1 Feb 2024 18:07:08 +0530 Subject: [PATCH 07/13] Update aws/table_aws_iot_thing.go Co-authored-by: Khushboo <46913995+khushboo9024@users.noreply.github.com> --- aws/table_aws_iot_thing.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/table_aws_iot_thing.go b/aws/table_aws_iot_thing.go index 37da3c7e7..3ca7c8930 100644 --- a/aws/table_aws_iot_thing.go +++ b/aws/table_aws_iot_thing.go @@ -19,7 +19,7 @@ import ( func tableAwsIotThing(_ context.Context) *plugin.Table { return &plugin.Table{ Name: "aws_iot_thing", - Description: "AWS Iot Thing", + Description: "AWS IoT Thing", Get: &plugin.GetConfig{ KeyColumns: plugin.SingleColumn("thing_name"), Hydrate: getIotThing, From 48be8cb790e3efa25453d7ad3564ba8259d3358c Mon Sep 17 00:00:00 2001 From: ParthaI Date: Thu, 1 Feb 2024 18:29:18 +0530 Subject: [PATCH 08/13] Update the word IOT to IoT --- aws/plugin.go | 2 +- aws/service.go | 2 +- aws/table_aws_iot_thing.go | 30 +++++++++++++++--------------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/aws/plugin.go b/aws/plugin.go index de43c442c..cd4c12224 100644 --- a/aws/plugin.go +++ b/aws/plugin.go @@ -302,7 +302,7 @@ func Plugin(ctx context.Context) *plugin.Plugin { "aws_inspector_assessment_template": tableAwsInspectorAssessmentTemplate(ctx), "aws_inspector_exclusion": tableAwsInspectorExclusion(ctx), "aws_inspector_finding": tableAwsInspectorFinding(ctx), - "aws_iot_thing": tableAwsIotThing(ctx), + "aws_iot_thing": tableAwsIoTThing(ctx), "aws_kinesis_consumer": tableAwsKinesisConsumer(ctx), "aws_kinesis_firehose_delivery_stream": tableAwsKinesisFirehoseDeliveryStream(ctx), "aws_kinesis_stream": tableAwsKinesisStream(ctx), diff --git a/aws/service.go b/aws/service.go index ae863dbfd..4a2211fee 100644 --- a/aws/service.go +++ b/aws/service.go @@ -855,7 +855,7 @@ func Inspector2Client(ctx context.Context, d *plugin.QueryData) (*inspector2.Cli return inspector2.NewFromConfig(*cfg), nil } -func IOTClient(ctx context.Context, d *plugin.QueryData) (*iot.Client, error) { +func IoTClient(ctx context.Context, d *plugin.QueryData) (*iot.Client, error) { cfg, err := getClientForQuerySupportedRegion(ctx, d, iotEndpoint.EndpointsID) if err != nil { return nil, err diff --git a/aws/table_aws_iot_thing.go b/aws/table_aws_iot_thing.go index 3ca7c8930..32e097ef7 100644 --- a/aws/table_aws_iot_thing.go +++ b/aws/table_aws_iot_thing.go @@ -16,20 +16,20 @@ import ( //// TABLE DEFINITION -func tableAwsIotThing(_ context.Context) *plugin.Table { +func tableAwsIoTThing(_ context.Context) *plugin.Table { return &plugin.Table{ Name: "aws_iot_thing", Description: "AWS IoT Thing", Get: &plugin.GetConfig{ KeyColumns: plugin.SingleColumn("thing_name"), - Hydrate: getIotThing, + Hydrate: getIoTThing, Tags: map[string]string{"service": "iot", "action": "DescribeThing"}, IgnoreConfig: &plugin.IgnoreConfig{ ShouldIgnoreErrorFunc: shouldIgnoreErrors([]string{"ResourceNotFoundException"}), }, }, List: &plugin.ListConfig{ - Hydrate: listIotThings, + Hydrate: listIoTThings, IgnoreConfig: &plugin.IgnoreConfig{ ShouldIgnoreErrorFunc: shouldIgnoreErrors([]string{"ResourceNotFoundException"}), }, @@ -42,7 +42,7 @@ func tableAwsIotThing(_ context.Context) *plugin.Table { }, HydrateConfig: []plugin.HydrateConfig{ { - Func: getIotThing, + Func: getIoTThing, Tags: map[string]string{"service": "iot", "action": "DescribeThing"}, }, }, @@ -57,7 +57,7 @@ func tableAwsIotThing(_ context.Context) *plugin.Table { Name: "thing_id", Description: "The ID of the thing to describe.", Type: proto.ColumnType_STRING, - Hydrate: getIotThing, + Hydrate: getIoTThing, }, { Name: "arn", @@ -86,13 +86,13 @@ func tableAwsIotThing(_ context.Context) *plugin.Table { Name: "billing_group_name", Description: "The name of the billing group the thing belongs to.", Type: proto.ColumnType_STRING, - Hydrate: getIotThing, + Hydrate: getIoTThing, }, { Name: "default_client_id", Description: "The default MQTT client ID. For a typical device, the thing name is also used as the default MQTT client ID.", Type: proto.ColumnType_STRING, - Hydrate: getIotThing, + Hydrate: getIoTThing, }, { Name: "version", @@ -124,11 +124,11 @@ func tableAwsIotThing(_ context.Context) *plugin.Table { //// LIST FUNCTION -func listIotThings(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { +func listIoTThings(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create Session - svc, err := IOTClient(ctx, d) + svc, err := IoTClient(ctx, d) if err != nil { - plugin.Logger(ctx).Error("aws_iot_thing.listIotThings", "connection_error", err) + plugin.Logger(ctx).Error("aws_iot_thing.listIoTThings", "connection_error", err) return nil, err } if svc == nil { @@ -172,7 +172,7 @@ func listIotThings(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateDa output, err := paginator.NextPage(ctx) if err != nil { - plugin.Logger(ctx).Error("aws_iot_thing.listIotThings", "api_error", err) + plugin.Logger(ctx).Error("aws_iot_thing.listIoTThings", "api_error", err) return nil, err } @@ -191,7 +191,7 @@ func listIotThings(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateDa //// HYDRATE FUNCTIONS -func getIotThing(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { +func getIoTThing(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { thingName := "" if h.Item != nil { thing := h.Item.(types.ThingAttribute) @@ -205,9 +205,9 @@ func getIotThing(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData } // Create service - svc, err := IOTClient(ctx, d) + svc, err := IoTClient(ctx, d) if err != nil { - plugin.Logger(ctx).Error("aws_iot_thing.getIotThing", "connection_error", err) + plugin.Logger(ctx).Error("aws_iot_thing.getIoTThing", "connection_error", err) return nil, err } @@ -217,7 +217,7 @@ func getIotThing(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData thing, err := svc.DescribeThing(ctx, params) if err != nil { - plugin.Logger(ctx).Error("aws_iot_thing.getIotThing", "api_error", err) + plugin.Logger(ctx).Error("aws_iot_thing.getIoTThing", "api_error", err) return nil, err } From d9f16637b253b43f3463abf8a5d36905775bcea5 Mon Sep 17 00:00:00 2001 From: ParthaI Date: Thu, 1 Feb 2024 20:03:59 +0530 Subject: [PATCH 09/13] Replace the word Iot by IoT --- aws/plugin.go | 2 +- aws/table_aws_iot_fleet_metric.go | 64 ++++++++++++++++--------------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/aws/plugin.go b/aws/plugin.go index ab5195777..8def2f839 100644 --- a/aws/plugin.go +++ b/aws/plugin.go @@ -303,7 +303,7 @@ func Plugin(ctx context.Context) *plugin.Plugin { "aws_inspector_exclusion": tableAwsInspectorExclusion(ctx), "aws_inspector_finding": tableAwsInspectorFinding(ctx), "aws_iot_thing": tableAwsIoTThing(ctx), - "aws_iot_fleet_metric": tableAwsIotFleetMetric(ctx), + "aws_iot_fleet_metric": tableAwsIoTFleetMetric(ctx), "aws_kinesis_consumer": tableAwsKinesisConsumer(ctx), "aws_kinesis_firehose_delivery_stream": tableAwsKinesisFirehoseDeliveryStream(ctx), "aws_kinesis_stream": tableAwsKinesisStream(ctx), diff --git a/aws/table_aws_iot_fleet_metric.go b/aws/table_aws_iot_fleet_metric.go index 202d1a499..b3f27374a 100644 --- a/aws/table_aws_iot_fleet_metric.go +++ b/aws/table_aws_iot_fleet_metric.go @@ -16,27 +16,31 @@ import ( //// TABLE DEFINITION -func tableAwsIotFleetMetric(_ context.Context) *plugin.Table { +func tableAwsIoTFleetMetric(_ context.Context) *plugin.Table { return &plugin.Table{ Name: "aws_iot_fleet_metric", Description: "AWS IoT Fleet Metric", Get: &plugin.GetConfig{ KeyColumns: plugin.SingleColumn("metric_name"), - Hydrate: getIotFleetMetric, + Hydrate: getIoTFleetMetric, Tags: map[string]string{"service": "iot", "action": "DescribeFleetMetric"}, IgnoreConfig: &plugin.IgnoreConfig{ ShouldIgnoreErrorFunc: shouldIgnoreErrors([]string{"ResourceNotFoundException"}), }, }, List: &plugin.ListConfig{ - Hydrate: listIotFleetMetrics, + Hydrate: listIoTFleetMetrics, Tags: map[string]string{"service": "iot", "action": "ListFleetMetrics"}, }, HydrateConfig: []plugin.HydrateConfig{ { - Func: getIotFleetMetric, + Func: getIoTFleetMetric, Tags: map[string]string{"service": "iot", "action": "DescribeFleetMetric"}, }, + { + Func: getIoTFleetMetricTags, + Tags: map[string]string{"service": "iot", "action": "ListTagsForResource"}, + }, }, GetMatrixItemFunc: SupportedRegionMatrix(iotv1.EndpointsID), Columns: awsRegionalColumns([]*plugin.Column{ @@ -55,82 +59,82 @@ func tableAwsIotFleetMetric(_ context.Context) *plugin.Table { Name: "index_name", Description: "The name of the index to search.", Type: proto.ColumnType_STRING, - Hydrate: getIotFleetMetric, + Hydrate: getIoTFleetMetric, }, { Name: "description", Description: "The fleet metric description.", Type: proto.ColumnType_STRING, - Hydrate: getIotFleetMetric, + Hydrate: getIoTFleetMetric, }, { Name: "creation_date", Description: "The date when the fleet metric is created.", Type: proto.ColumnType_TIMESTAMP, - Hydrate: getIotFleetMetric, + Hydrate: getIoTFleetMetric, Transform: transform.FromField("CreationDate"), }, { Name: "last_modified_date", Description: "The date when the fleet metric is last modified.", Type: proto.ColumnType_TIMESTAMP, - Hydrate: getIotFleetMetric, + Hydrate: getIoTFleetMetric, }, { Name: "aggregation_field", Description: "The field to aggregate.", Type: proto.ColumnType_STRING, - Hydrate: getIotFleetMetric, + Hydrate: getIoTFleetMetric, }, { Name: "aggregation_type_name", Description: "The name of the aggregation type.", Type: proto.ColumnType_STRING, - Hydrate: getIotFleetMetric, + Hydrate: getIoTFleetMetric, Transform: transform.FromField("AggregationType.Name"), }, { Name: "period", Description: "The time in seconds between fleet metric emissions. Range [60(1 min), 86400(1 day)] and must be multiple of 60.", Type: proto.ColumnType_INT, - Hydrate: getIotFleetMetric, + Hydrate: getIoTFleetMetric, }, { Name: "query_string", Description: "The search query string.", Type: proto.ColumnType_STRING, - Hydrate: getIotFleetMetric, + Hydrate: getIoTFleetMetric, }, { Name: "query_version", Description: "The search query version.", Type: proto.ColumnType_STRING, - Hydrate: getIotFleetMetric, + Hydrate: getIoTFleetMetric, }, { Name: "unit", Description: "Used to support unit transformation such as milliseconds to seconds. The unit must be supported by CW metric (https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_MetricDatum.html)", Type: proto.ColumnType_STRING, - Hydrate: getIotFleetMetric, + Hydrate: getIoTFleetMetric, }, { Name: "version", Description: "The version of the fleet metric.", Type: proto.ColumnType_STRING, - Hydrate: getIotFleetMetric, + Hydrate: getIoTFleetMetric, }, { Name: "aggregation_type_values", Description: "A list of the values of aggregation types.", Type: proto.ColumnType_JSON, - Hydrate: getIotFleetMetric, + Hydrate: getIoTFleetMetric, Transform: transform.FromField("AggregationType.Values"), }, { Name: "tags_src", Description: "A list of tags currently associated with the thing type.", Type: proto.ColumnType_JSON, - Hydrate: getIotFleetMetricTags, + Hydrate: getIoTFleetMetricTags, Transform: transform.FromField("Tags"), }, @@ -145,7 +149,7 @@ func tableAwsIotFleetMetric(_ context.Context) *plugin.Table { Name: "tags", Description: resourceInterfaceDescription("tags"), Type: proto.ColumnType_JSON, - Hydrate: getIotFleetMetricTags, + Hydrate: getIoTFleetMetricTags, Transform: transform.From(iotFleetMetricTagListToTagsMap), }, { @@ -160,11 +164,11 @@ func tableAwsIotFleetMetric(_ context.Context) *plugin.Table { //// LIST FUNCTION -func listIotFleetMetrics(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { +func listIoTFleetMetrics(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create Session - svc, err := IOTClient(ctx, d) + svc, err := IoTClient(ctx, d) if err != nil { - plugin.Logger(ctx).Error("aws_iot_fleet_metric.listIotFleetMetrics", "connection_error", err) + plugin.Logger(ctx).Error("aws_iot_fleet_metric.listIoTFleetMetrics", "connection_error", err) return nil, err } if svc == nil { @@ -197,7 +201,7 @@ func listIotFleetMetrics(ctx context.Context, d *plugin.QueryData, _ *plugin.Hyd output, err := paginator.NextPage(ctx) if err != nil { - plugin.Logger(ctx).Error("aws_iot_fleet_metric.listIotFleetMetrics", "api_error", err) + plugin.Logger(ctx).Error("aws_iot_fleet_metric.listIoTFleetMetrics", "api_error", err) return nil, err } @@ -216,7 +220,7 @@ func listIotFleetMetrics(ctx context.Context, d *plugin.QueryData, _ *plugin.Hyd //// HYDRATE FUNCTIONS -func getIotFleetMetric(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { +func getIoTFleetMetric(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { metricName := "" if h.Item != nil { t := h.Item.(types.FleetMetricNameAndArn) @@ -230,9 +234,9 @@ func getIotFleetMetric(ctx context.Context, d *plugin.QueryData, h *plugin.Hydra } // Create service - svc, err := IOTClient(ctx, d) + svc, err := IoTClient(ctx, d) if err != nil { - plugin.Logger(ctx).Error("aws_iot_fleet_metric.getIotFleetMetric", "connection_error", err) + plugin.Logger(ctx).Error("aws_iot_fleet_metric.getIoTFleetMetric", "connection_error", err) return nil, err } @@ -242,14 +246,14 @@ func getIotFleetMetric(ctx context.Context, d *plugin.QueryData, h *plugin.Hydra resp, err := svc.DescribeFleetMetric(ctx, params) if err != nil { - plugin.Logger(ctx).Error("aws_iot_fleet_metric.getIotFleetMetric", "api_error", err) + plugin.Logger(ctx).Error("aws_iot_fleet_metric.getIoTFleetMetric", "api_error", err) return nil, err } return resp, nil } -func getIotFleetMetricTags(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { +func getIoTFleetMetricTags(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { typeArn := "" switch item := h.Item.(type) { case *iot.DescribeThingTypeOutput: @@ -259,9 +263,9 @@ func getIotFleetMetricTags(ctx context.Context, d *plugin.QueryData, h *plugin.H } // Create service - svc, err := IOTClient(ctx, d) + svc, err := IoTClient(ctx, d) if err != nil { - plugin.Logger(ctx).Error("aws_iot_fleet_metric.getIotFleetMetricTags", "connection_error", err) + plugin.Logger(ctx).Error("aws_iot_fleet_metric.getIoTFleetMetricTags", "connection_error", err) return nil, err } @@ -271,7 +275,7 @@ func getIotFleetMetricTags(ctx context.Context, d *plugin.QueryData, h *plugin.H endpointTags, err := svc.ListTagsForResource(ctx, params) if err != nil { - plugin.Logger(ctx).Error("aws_iot_fleet_metric.getIotFleetMetricTags", "api_error", err) + plugin.Logger(ctx).Error("aws_iot_fleet_metric.getIoTFleetMetricTags", "api_error", err) return nil, err } From 2e26c77c879c6dba1416d4e6069d62accb6d1527 Mon Sep 17 00:00:00 2001 From: Khushboo <46913995+khushboo9024@users.noreply.github.com> Date: Mon, 1 Apr 2024 14:20:34 +0530 Subject: [PATCH 10/13] Update aws_iot_fleet_metric.md --- docs/tables/aws_iot_fleet_metric.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tables/aws_iot_fleet_metric.md b/docs/tables/aws_iot_fleet_metric.md index 5b771dfe0..e6539c0c2 100644 --- a/docs/tables/aws_iot_fleet_metric.md +++ b/docs/tables/aws_iot_fleet_metric.md @@ -13,7 +13,7 @@ The `aws_iot_fleet_metric` table can be utilized to access detailed information ## Examples -### Basic Info +### Basic info Retrieve fundamental details about AWS IoT Fleet Metrics, including metric names, associated ARNs, index names, and dates of creation and modification. ```sql+postgres @@ -38,7 +38,7 @@ from aws_iot_fleet_metric; ``` -### Aggregate Fleet Metric by Type Name +### Group fleet metrics by aggregation type name Group fleet metrics by their aggregation type name. This query is useful for analyzing metrics across different aggregation types, providing a broader view of fleet data categorization. ```sql+postgres @@ -67,7 +67,7 @@ group by aggregation_type_name; ``` -### List Fleet Metrics Updated in the Last 30 Days +### List fleet metrics updated in the last 30 days Find fleet metrics that have been updated within the last 30 days. This query assists in identifying recent changes or updates in fleet metric configurations. ```sql+postgres From 8879d331f5e71bfe3880d825fa3f1a1eb94eb415 Mon Sep 17 00:00:00 2001 From: ParthaI <47887552+ParthaI@users.noreply.github.com> Date: Mon, 1 Apr 2024 15:09:17 +0530 Subject: [PATCH 11/13] Update aws/table_aws_iot_fleet_metric.go Co-authored-by: Khushboo <46913995+khushboo9024@users.noreply.github.com> --- aws/table_aws_iot_fleet_metric.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/table_aws_iot_fleet_metric.go b/aws/table_aws_iot_fleet_metric.go index b3f27374a..e2e54a9b5 100644 --- a/aws/table_aws_iot_fleet_metric.go +++ b/aws/table_aws_iot_fleet_metric.go @@ -46,7 +46,7 @@ func tableAwsIoTFleetMetric(_ context.Context) *plugin.Table { Columns: awsRegionalColumns([]*plugin.Column{ { Name: "metric_name", - Description: "The name of the thing type.", + Description: "The name of the fleet metric to describe.", Type: proto.ColumnType_STRING, }, { From 96cbae30e299742576921032b63002d9e9572758 Mon Sep 17 00:00:00 2001 From: ParthaI <47887552+ParthaI@users.noreply.github.com> Date: Mon, 1 Apr 2024 15:09:23 +0530 Subject: [PATCH 12/13] Update aws/table_aws_iot_fleet_metric.go Co-authored-by: Khushboo <46913995+khushboo9024@users.noreply.github.com> --- aws/table_aws_iot_fleet_metric.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/table_aws_iot_fleet_metric.go b/aws/table_aws_iot_fleet_metric.go index e2e54a9b5..b6624f3db 100644 --- a/aws/table_aws_iot_fleet_metric.go +++ b/aws/table_aws_iot_fleet_metric.go @@ -51,7 +51,7 @@ func tableAwsIoTFleetMetric(_ context.Context) *plugin.Table { }, { Name: "arn", - Description: "The Amazon Resource Name (ARN) for the thing type.", + Description: "The ARN of the fleet metric to describe.", Type: proto.ColumnType_STRING, Transform: transform.FromField("MetricArn"), }, From 773cf991e979b3a0d532979a031297e0a75ccbfe Mon Sep 17 00:00:00 2001 From: ParthaI <47887552+ParthaI@users.noreply.github.com> Date: Mon, 1 Apr 2024 15:11:10 +0530 Subject: [PATCH 13/13] Update table_aws_iot_fleet_metric.go --- aws/table_aws_iot_fleet_metric.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/table_aws_iot_fleet_metric.go b/aws/table_aws_iot_fleet_metric.go index b6624f3db..5ac2c0763 100644 --- a/aws/table_aws_iot_fleet_metric.go +++ b/aws/table_aws_iot_fleet_metric.go @@ -120,7 +120,7 @@ func tableAwsIoTFleetMetric(_ context.Context) *plugin.Table { { Name: "version", Description: "The version of the fleet metric.", - Type: proto.ColumnType_STRING, + Type: proto.ColumnType_INT, Hydrate: getIoTFleetMetric, }, {