Skip to content

Commit

Permalink
Merge pull request #26862 from Oltier/b-add-filters-to-iot-thing_inde…
Browse files Browse the repository at this point in the history
…xing_configuration

B add filter to iot_thing_indexing_configuration
  • Loading branch information
ewbankkit authored Oct 26, 2023
2 parents 4c44a10 + 869fadf commit a596c02
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .changelog/26859.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
resource/aws_iot_indexing_configuration: Add `thing_indexing_configuration.filter` attribute, resolving `InvalidRequestException: NamedShadowNames Filter must not be empty for enabling NamedShadowIndexingMode` errors
```
62 changes: 60 additions & 2 deletions internal/service/iot/indexing_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ package iot

import (
"context"
"log"

"github.com/YakDriver/regexache"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/iot"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
"github.com/hashicorp/terraform-provider-aws/internal/flex"
)

// @SDKResource("aws_iot_indexing_configuration")
Expand Down Expand Up @@ -109,6 +110,28 @@ func ResourceIndexingConfiguration() *schema.Resource {
Default: iot.DeviceDefenderIndexingModeOff,
ValidateFunc: validation.StringInSlice(iot.DeviceDefenderIndexingMode_Values(), false),
},
"filter": {
Type: schema.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"named_shadow_names": {
Type: schema.TypeSet,
Optional: true,
MinItems: 1,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validation.All(
validation.StringLenBetween(1, 64),
validation.StringMatch(regexache.MustCompile(`^[a-zA-Z0-9:_-]+`), "must contain only alphanumeric characters, underscores, colons, and hyphens"),
),
},
},
},
},
},
"managed_field": {
Type: schema.TypeSet,
Optional: true,
Expand Down Expand Up @@ -165,7 +188,6 @@ func resourceIndexingConfigurationPut(ctx context.Context, d *schema.ResourceDat
input.ThingIndexingConfiguration = expandThingIndexingConfiguration(v.([]interface{})[0].(map[string]interface{}))
}

log.Printf("[DEBUG] Updating IoT Indexing Configuration: %s", input)
_, err := conn.UpdateIndexingConfigurationWithContext(ctx, input)

if err != nil {
Expand Down Expand Up @@ -241,6 +263,10 @@ func flattenThingIndexingConfiguration(apiObject *iot.ThingIndexingConfiguration
tfMap["device_defender_indexing_mode"] = aws.StringValue(v)
}

if v := apiObject.Filter; v != nil {
tfMap["filter"] = []interface{}{flattenIndexingFilter(v)}
}

if v := apiObject.ManagedFields; v != nil {
tfMap["managed_field"] = flattenFields(v)
}
Expand All @@ -260,6 +286,20 @@ func flattenThingIndexingConfiguration(apiObject *iot.ThingIndexingConfiguration
return tfMap
}

func flattenIndexingFilter(apiObject *iot.IndexingFilter) map[string]interface{} {
if apiObject == nil {
return nil
}

tfMap := map[string]interface{}{}

if v := apiObject.NamedShadowNames; v != nil {
tfMap["named_shadow_names"] = aws.StringValueSlice(v)
}

return tfMap
}

func flattenField(apiObject *iot.Field) map[string]interface{} {
if apiObject == nil {
return nil
Expand Down Expand Up @@ -333,6 +373,10 @@ func expandThingIndexingConfiguration(tfMap map[string]interface{}) *iot.ThingIn
apiObject.DeviceDefenderIndexingMode = aws.String(v)
}

if v, ok := tfMap["filter"]; ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil {
apiObject.Filter = expandIndexingFilter(v.([]interface{})[0].(map[string]interface{}))
}

if v, ok := tfMap["managed_field"].(*schema.Set); ok && v.Len() > 0 {
apiObject.ManagedFields = expandFields(v.List())
}
Expand All @@ -352,6 +396,20 @@ func expandThingIndexingConfiguration(tfMap map[string]interface{}) *iot.ThingIn
return apiObject
}

func expandIndexingFilter(tfMap map[string]interface{}) *iot.IndexingFilter {
if tfMap == nil {
return nil
}

apiObject := &iot.IndexingFilter{}

if v, ok := tfMap["named_shadow_names"].(*schema.Set); ok && v.Len() > 0 {
apiObject.NamedShadowNames = flex.ExpandStringSet(v)
}

return apiObject
}

func expandField(tfMap map[string]interface{}) *iot.Field {
if tfMap == nil {
return nil
Expand Down
6 changes: 6 additions & 0 deletions internal/service/iot/indexing_configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ func testAccIndexingConfiguration_allAttributes(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "thing_indexing_configuration.0.named_shadow_indexing_mode", "ON"),
resource.TestCheckResourceAttr(resourceName, "thing_indexing_configuration.0.thing_connectivity_indexing_mode", "STATUS"),
resource.TestCheckResourceAttr(resourceName, "thing_indexing_configuration.0.thing_indexing_mode", "REGISTRY_AND_SHADOW"),
resource.TestCheckResourceAttr(resourceName, "thing_indexing_configuration.0.filter.0.named_shadow_names.#", "1"),
resource.TestCheckResourceAttr(resourceName, "thing_indexing_configuration.0.filter.0.named_shadow_names.0", "thing1shadow"),
),
},
{
Expand Down Expand Up @@ -128,6 +130,10 @@ resource "aws_iot_indexing_configuration" "test" {
device_defender_indexing_mode = "VIOLATIONS"
named_shadow_indexing_mode = "ON"
filter {
named_shadow_names = ["thing1shadow"]
}
custom_field {
name = "attributes.version"
type = "Number"
Expand Down
11 changes: 11 additions & 0 deletions website/docs/r/iot_indexing_configuration.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ resource "aws_iot_indexing_configuration" "example" {
device_defender_indexing_mode = "VIOLATIONS"
named_shadow_indexing_mode = "ON"
filter {
named_shadow_names = ["thing1shadow"]
}
custom_field {
name = "shadow.desired.power"
type = "Boolean"
Expand Down Expand Up @@ -61,6 +65,7 @@ The `thing_indexing_configuration` configuration block supports the following:
* `device_defender_indexing_mode` - (Optional) Device Defender indexing mode. Valid values: `VIOLATIONS`, `OFF`. Default: `OFF`.
* `managed_field` - (Optional) Contains fields that are indexed and whose types are already known by the Fleet Indexing service. See below.
* `named_shadow_indexing_mode` - (Optional) [Named shadow](https://docs.aws.amazon.com/iot/latest/developerguide/iot-device-shadows.html) indexing mode. Valid values: `ON`, `OFF`. Default: `OFF`.
* `filter` - (Optional) Required if `named_shadow_indexing_mode` is `ON`. Enables to add named shadows filtered by `filter` to fleet indexing configuration.
* `thing_connectivity_indexing_mode` - (Optional) Thing connectivity indexing mode. Valid values: `STATUS`, `OFF`. Default: `OFF`.
* `thing_indexing_mode` - (Required) Thing indexing mode. Valid values: `REGISTRY`, `REGISTRY_AND_SHADOW`, `OFF`.

Expand All @@ -71,6 +76,12 @@ The `custom_field` and `managed_field` configuration blocks supports the followi
* `name` - (Optional) The name of the field.
* `type` - (Optional) The data type of the field. Valid values: `Number`, `String`, `Boolean`.

### filter

The `filter` configuration block supports the following:

* `named_shadow_names` - (Optional) List of shadow names that you select to index.

## Attribute Reference

This resource exports no additional attributes.

0 comments on commit a596c02

Please sign in to comment.