Skip to content

Commit

Permalink
Merge pull request #21122 from abebars/b-aws_lex-building-state
Browse files Browse the repository at this point in the history
Added proper status and waiter to Lex Bot. Fixed issues with import tests.
  • Loading branch information
ewbankkit authored Oct 5, 2021
2 parents 01bde59 + fa65932 commit 06820cc
Show file tree
Hide file tree
Showing 15 changed files with 377 additions and 277 deletions.
7 changes: 7 additions & 0 deletions .changelog/20383.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:bug
aws/resource_aws_lex_bot: Correctly determine `version` attribute
```

```release-note:bug
aws/resource_aws_lex_intent: Correctly determine `version` attribute
```
3 changes: 3 additions & 0 deletions .changelog/21122.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_lex_bot: Added waiter support to account for `BUILDING` status
```
52 changes: 25 additions & 27 deletions aws/data_source_aws_lex_bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import (
"fmt"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/service/lexmodelbuildingservice"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
tflex "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/lex"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/lex/finder"
)

func dataSourceAwsLexBot() *schema.Resource {
Expand Down Expand Up @@ -75,7 +75,7 @@ func dataSourceAwsLexBot() *schema.Resource {
"version": {
Type: schema.TypeString,
Optional: true,
Default: LexBotVersionLatest,
Default: tflex.LexBotVersionLatest,
ValidateFunc: validateLexBotVersion,
},
"voice_id": {
Expand All @@ -89,41 +89,39 @@ func dataSourceAwsLexBot() *schema.Resource {
func dataSourceAwsLexBotRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).lexmodelconn

botName := d.Get("name").(string)
resp, err := conn.GetBot(&lexmodelbuildingservice.GetBotInput{
Name: aws.String(botName),
VersionOrAlias: aws.String(d.Get("version").(string)),
})
name := d.Get("name").(string)
version := d.Get("version").(string)
output, err := finder.BotVersionByName(conn, name, version)

if err != nil {
return fmt.Errorf("error reading bot %s: %w", botName, err)
return fmt.Errorf("error reading Lex Bot (%s/%s): %w", name, version, err)
}

arn := arn.ARN{
Partition: meta.(*AWSClient).partition,
Region: meta.(*AWSClient).region,
Service: "lex",
AccountID: meta.(*AWSClient).accountid,
Resource: fmt.Sprintf("bot:%s", d.Get("name").(string)),
Resource: fmt.Sprintf("bot:%s", name),
}
d.Set("arn", arn.String())
d.Set("checksum", output.Checksum)
d.Set("child_directed", output.ChildDirected)
d.Set("created_date", output.CreatedDate.Format(time.RFC3339))
d.Set("description", output.Description)
d.Set("detect_sentiment", output.DetectSentiment)
d.Set("enable_model_improvements", output.EnableModelImprovements)
d.Set("failure_reason", output.FailureReason)
d.Set("idle_session_ttl_in_seconds", output.IdleSessionTTLInSeconds)
d.Set("last_updated_date", output.LastUpdatedDate.Format(time.RFC3339))
d.Set("locale", output.Locale)
d.Set("name", output.Name)
d.Set("nlu_intent_confidence_threshold", output.NluIntentConfidenceThreshold)
d.Set("status", output.Status)
d.Set("version", output.Version)
d.Set("voice_id", output.VoiceId)

d.Set("checksum", resp.Checksum)
d.Set("child_directed", resp.ChildDirected)
d.Set("created_date", resp.CreatedDate.Format(time.RFC3339))
d.Set("description", resp.Description)
d.Set("detect_sentiment", resp.DetectSentiment)
d.Set("enable_model_improvements", resp.EnableModelImprovements)
d.Set("failure_reason", resp.FailureReason)
d.Set("idle_session_ttl_in_seconds", resp.IdleSessionTTLInSeconds)
d.Set("last_updated_date", resp.LastUpdatedDate.Format(time.RFC3339))
d.Set("locale", resp.Locale)
d.Set("name", resp.Name)
d.Set("nlu_intent_confidence_threshold", resp.NluIntentConfidenceThreshold)
d.Set("status", resp.Status)
d.Set("version", resp.Version)
d.Set("voice_id", resp.VoiceId)

d.SetId(botName)
d.SetId(name)

return nil
}
8 changes: 5 additions & 3 deletions aws/data_source_aws_lex_bot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,19 @@ func testAccDataSourceAwsLexBot_withVersion(t *testing.T) {
resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"),
resource.TestCheckResourceAttrPair(dataSourceName, "checksum", resourceName, "checksum"),
resource.TestCheckResourceAttrPair(dataSourceName, "child_directed", resourceName, "child_directed"),
resource.TestCheckResourceAttrPair(dataSourceName, "created_date", resourceName, "created_date"),
resource.TestCheckResourceAttrPair(dataSourceName, "description", resourceName, "description"),
resource.TestCheckResourceAttrPair(dataSourceName, "detect_sentiment", resourceName, "detect_sentiment"),
resource.TestCheckResourceAttrPair(dataSourceName, "enable_model_improvements", resourceName, "enable_model_improvements"),
resource.TestCheckResourceAttrPair(dataSourceName, "failure_reason", resourceName, "failure_reason"),
resource.TestCheckResourceAttrPair(dataSourceName, "idle_session_ttl_in_seconds", resourceName, "idle_session_ttl_in_seconds"),
resource.TestCheckResourceAttrPair(dataSourceName, "last_updated_date", resourceName, "last_updated_date"),
//Removed due to race condition when bots build/read/not_ready. Modified the bot status to read true status:
//https://github.com/hashicorp/terraform-provider-aws/issues/21107
//resource.TestCheckResourceAttrPair(dataSourceName, "created_date", resourceName, "created_date"),
//resource.TestCheckResourceAttrPair(dataSourceName, "last_updated_date", resourceName, "last_updated_date"),
//resource.TestCheckResourceAttrPair(dataSourceName, "status", resourceName, "status"),
resource.TestCheckResourceAttrPair(dataSourceName, "locale", resourceName, "locale"),
resource.TestCheckResourceAttrPair(dataSourceName, "name", resourceName, "name"),
resource.TestCheckResourceAttrPair(dataSourceName, "nlu_intent_confidence_threshold", resourceName, "nlu_intent_confidence_threshold"),
resource.TestCheckResourceAttrPair(dataSourceName, "status", resourceName, "status"),
resource.TestCheckResourceAttrPair(dataSourceName, "version", resourceName, "version"),
),
},
Expand Down
3 changes: 2 additions & 1 deletion aws/data_source_aws_lex_intent.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/aws/aws-sdk-go/service/lexmodelbuildingservice"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
tflex "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/lex"
)

func dataSourceAwsLexIntent() *schema.Resource {
Expand Down Expand Up @@ -52,7 +53,7 @@ func dataSourceAwsLexIntent() *schema.Resource {
"version": {
Type: schema.TypeString,
Optional: true,
Default: LexIntentVersionLatest,
Default: tflex.LexIntentVersionLatest,
ValidateFunc: validation.All(
validation.StringLenBetween(1, 64),
validation.StringMatch(regexp.MustCompile(`\$LATEST|[0-9]+`), ""),
Expand Down
6 changes: 6 additions & 0 deletions aws/internal/service/lex/enum.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package lex

const (
LexBotVersionLatest = "$LATEST"
LexIntentVersionLatest = "$LATEST"
)
120 changes: 120 additions & 0 deletions aws/internal/service/lex/finder/finder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package finder

import (
"strconv"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/lexmodelbuildingservice"
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
tflex "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/lex"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource"
)

func BotVersionByName(conn *lexmodelbuildingservice.LexModelBuildingService, name, version string) (*lexmodelbuildingservice.GetBotOutput, error) {
input := &lexmodelbuildingservice.GetBotInput{
Name: aws.String(name),
VersionOrAlias: aws.String(version),
}

output, err := conn.GetBot(input)

if tfawserr.ErrCodeEquals(err, lexmodelbuildingservice.ErrCodeNotFoundException) {
return nil, &resource.NotFoundError{
LastError: err,
LastRequest: input,
}
}

if err != nil {
return nil, err
}

if output == nil {
return nil, tfresource.NewEmptyResultError(input)
}

return output, nil
}

// LatestBotVersionByName returns the latest published version of a bot or $LATEST if the bot has never been published.
// See https://docs.aws.amazon.com/lex/latest/dg/versioning-aliases.html.
func LatestBotVersionByName(conn *lexmodelbuildingservice.LexModelBuildingService, name string) (string, error) {
input := &lexmodelbuildingservice.GetBotVersionsInput{
Name: aws.String(name),
}
var latestVersion int

err := conn.GetBotVersionsPages(input, func(page *lexmodelbuildingservice.GetBotVersionsOutput, lastPage bool) bool {
if page == nil {
return !lastPage
}

for _, bot := range page.Bots {
version := aws.StringValue(bot.Version)

if version == tflex.LexBotVersionLatest {
continue
}

if version, err := strconv.Atoi(version); err != nil {
continue
} else if version > latestVersion {
latestVersion = version
}
}

return !lastPage
})

if err != nil {
return "", err
}

if latestVersion == 0 {
return tflex.LexBotVersionLatest, nil
}

return strconv.Itoa(latestVersion), nil
}

// LatestIntentVersionByName returns the latest published version of an intent or $LATEST if the intent has never been published.
// See https://docs.aws.amazon.com/lex/latest/dg/versioning-aliases.html.
func LatestIntentVersionByName(conn *lexmodelbuildingservice.LexModelBuildingService, name string) (string, error) {
input := &lexmodelbuildingservice.GetIntentVersionsInput{
Name: aws.String(name),
}
var latestVersion int

err := conn.GetIntentVersionsPages(input, func(page *lexmodelbuildingservice.GetIntentVersionsOutput, lastPage bool) bool {
if page == nil {
return !lastPage
}

for _, intent := range page.Intents {
version := aws.StringValue(intent.Version)

if version == tflex.LexIntentVersionLatest {
continue
}

if version, err := strconv.Atoi(version); err != nil {
continue
} else if version > latestVersion {
latestVersion = version
}
}

return !lastPage
})

if err != nil {
return "", err
}

if latestVersion == 0 {
return tflex.LexIntentVersionLatest, nil
}

return strconv.Itoa(latestVersion), nil
}
48 changes: 26 additions & 22 deletions aws/internal/service/lex/waiter/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,42 @@ import (
"github.com/aws/aws-sdk-go/service/lexmodelbuildingservice"
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/lex/finder"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource"
)

const (
LexModelBuildingServiceStatusCreated = "Created"
LexModelBuildingServiceStatusNotFound = "NotFound"
LexModelBuildingServiceStatusUnknown = "Unknown"
//Lex Bot Statuses
LexModeBuildingServicesStatusBuilding = "BUILDING"
LexModeBuildingServicesStatusFailed = "FAILED"
LexModeBuildingServicesStatusNotBuilt = "NOT_BUILT"
LexModeBuildingServicesStatusReady = "READY"
LexModeBuildingServicesStatusReadyBasicTesting = "READY_BASIC_TESTING"

LexModelBuildingServiceStatusCreated = "CREATED"
LexModelBuildingServiceStatusNotFound = "NOTFOUND"
LexModelBuildingServiceStatusUnknown = "UNKNOWN"
)

func LexSlotTypeStatus(conn *lexmodelbuildingservice.LexModelBuildingService, id string) resource.StateRefreshFunc {
func BotVersionStatus(conn *lexmodelbuildingservice.LexModelBuildingService, name, version string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
output, err := conn.GetSlotTypeVersions(&lexmodelbuildingservice.GetSlotTypeVersionsInput{
Name: aws.String(id),
})
if tfawserr.ErrCodeEquals(err, lexmodelbuildingservice.ErrCodeNotFoundException) {
return nil, LexModelBuildingServiceStatusNotFound, nil
}
if err != nil {
return nil, LexModelBuildingServiceStatusUnknown, err
output, err := finder.BotVersionByName(conn, name, version)

if tfresource.NotFound(err) {
return nil, "", nil
}

if output == nil || len(output.SlotTypes) == 0 {
return nil, LexModelBuildingServiceStatusNotFound, nil
if err != nil {
return nil, "", err
}

return output, LexModelBuildingServiceStatusCreated, nil
return output, aws.StringValue(output.Status), nil
}
}

func LexIntentStatus(conn *lexmodelbuildingservice.LexModelBuildingService, id string) resource.StateRefreshFunc {
func LexSlotTypeStatus(conn *lexmodelbuildingservice.LexModelBuildingService, id string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
output, err := conn.GetIntentVersions(&lexmodelbuildingservice.GetIntentVersionsInput{
output, err := conn.GetSlotTypeVersions(&lexmodelbuildingservice.GetSlotTypeVersionsInput{
Name: aws.String(id),
})
if tfawserr.ErrCodeEquals(err, lexmodelbuildingservice.ErrCodeNotFoundException) {
Expand All @@ -45,17 +50,17 @@ func LexIntentStatus(conn *lexmodelbuildingservice.LexModelBuildingService, id s
return nil, LexModelBuildingServiceStatusUnknown, err
}

if output == nil || len(output.Intents) == 0 {
if output == nil || len(output.SlotTypes) == 0 {
return nil, LexModelBuildingServiceStatusNotFound, nil
}

return output, LexModelBuildingServiceStatusCreated, nil
}
}

func LexBotStatus(conn *lexmodelbuildingservice.LexModelBuildingService, id string) resource.StateRefreshFunc {
func LexIntentStatus(conn *lexmodelbuildingservice.LexModelBuildingService, id string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
output, err := conn.GetBotVersions(&lexmodelbuildingservice.GetBotVersionsInput{
output, err := conn.GetIntentVersions(&lexmodelbuildingservice.GetIntentVersionsInput{
Name: aws.String(id),
})
if tfawserr.ErrCodeEquals(err, lexmodelbuildingservice.ErrCodeNotFoundException) {
Expand All @@ -65,7 +70,7 @@ func LexBotStatus(conn *lexmodelbuildingservice.LexModelBuildingService, id stri
return nil, LexModelBuildingServiceStatusUnknown, err
}

if output == nil || len(output.Bots) == 0 {
if output == nil || len(output.Intents) == 0 {
return nil, LexModelBuildingServiceStatusNotFound, nil
}

Expand All @@ -85,7 +90,6 @@ func LexBotAliasStatus(conn *lexmodelbuildingservice.LexModelBuildingService, bo
if err != nil {
return nil, LexModelBuildingServiceStatusUnknown, err
}

if output == nil {
return nil, LexModelBuildingServiceStatusNotFound, nil
}
Expand Down
Loading

0 comments on commit 06820cc

Please sign in to comment.