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

r/servicecatalog_provisioned_product: New resource #19459

Merged
merged 30 commits into from
Jun 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
c8fd523
provider: Add servicecat_provisioned_product
YakDriver May 20, 2021
526cdfd
r/servicecat_prov_prod: New resource
YakDriver May 20, 2021
cc65a1c
tests/r/servicecat_prov_prod: New resource
YakDriver May 20, 2021
23585dd
docs/r/servicecat_prov_prod: New resource
YakDriver May 20, 2021
648733d
r/servicecat_prov_prod: Add changelog
YakDriver May 20, 2021
6912227
servicecat: Work with RecordTags
YakDriver May 26, 2021
2575d13
i/r/servicecat_prov_prod: Add statuser
YakDriver May 26, 2021
5b3c959
i/r/servicecat_prov_prod: Add waiter
YakDriver May 26, 2021
6b7ff33
r/servicecat_prov_prod: Add guts of resource
YakDriver May 26, 2021
81c0fb9
tests/r/servicecat_prov_prod: Add test foundations
YakDriver May 26, 2021
f5a3438
docs/r/servicecat_prod: Fix import typo
YakDriver May 26, 2021
3a8f264
docs/r/servicecat_prov_prod: Add bulk of docs
YakDriver May 26, 2021
7cf4fb5
r/servicecat_prov_prod: Remove extraneous check
YakDriver May 26, 2021
ac9d0c4
r/servicecat_prov_prod: Update enum
YakDriver Jun 29, 2021
f249a76
tests/r/servicecat_prov_prod: Build up tests
YakDriver Jun 29, 2021
99320de
i/servicecatalog: Add waiter status
YakDriver Jun 29, 2021
c112efd
tests/r/servicecat_prov_prod: Fix response if wait finds none
YakDriver Jun 29, 2021
ab4eadc
tests/r/servicecat_prov_prod: Put tests right
YakDriver Jun 29, 2021
118dde5
tests/r/servicecat_prov_prod: Placate linter dragon
YakDriver Jun 29, 2021
488fc84
internal/keyvaluetags: Remove unused func
YakDriver Jun 29, 2021
6be8983
tests/r/servicecat_prov_prod: Add new test for tags, udpate
YakDriver Jun 29, 2021
623d7b1
r/servicecat_prov_prod: Cleanup, make sure only one of either/or
YakDriver Jun 29, 2021
57d6dcb
tests/r/servicecat_prov_prod: Appease linter
YakDriver Jun 29, 2021
177b7fa
r/servicecatalog_prov_prod: Lintery
YakDriver Jun 29, 2021
4d4b4e0
r/servicecat_prov_prod: Rename argument
YakDriver Jun 29, 2021
7e93945
docs/r/servicecat_prov_prod: Rename argument
YakDriver Jun 29, 2021
1b30ee6
tests/r/servicecat_prov_prod: Rework dependencies
YakDriver Jun 30, 2021
95df4cb
r/servicecat_prov_prod: Add retry to avoid not found error
YakDriver Jun 30, 2021
ee0a831
i/servicecat: Make state changes more stable
YakDriver Jun 30, 2021
c410a9d
i/servicecat: Use consts for state change arguments
YakDriver Jun 30, 2021
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
3 changes: 3 additions & 0 deletions .changelog/19459.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
aws_servicecatalog_provisioned_product
```
10 changes: 10 additions & 0 deletions aws/internal/keyvaluetags/servicecatalog_tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,13 @@ func ServiceCatalogProductUpdateTags(conn *servicecatalog.ServiceCatalog, identi

return nil
}

func ServicecatalogRecordKeyValueTags(tags []*servicecatalog.RecordTag) KeyValueTags {
m := make(map[string]*string, len(tags))

for _, tag := range tags {
m[aws.StringValue(tag.Key)] = tag.Value
}

return New(m)
}
61 changes: 61 additions & 0 deletions aws/internal/service/servicecatalog/waiter/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -356,3 +356,64 @@ func LaunchPathsStatus(conn *servicecatalog.ServiceCatalog, acceptLanguage, prod
return summaries, servicecatalog.StatusAvailable, err
}
}

func ProvisionedProductStatus(conn *servicecatalog.ServiceCatalog, acceptLanguage, id, name string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
input := &servicecatalog.DescribeProvisionedProductInput{}

if acceptLanguage != "" {
input.AcceptLanguage = aws.String(acceptLanguage)
}

// one or the other but not both
if id != "" {
input.Id = aws.String(id)
} else if name != "" {
input.Name = aws.String(name)
}

output, err := conn.DescribeProvisionedProduct(input)

if tfawserr.ErrCodeEquals(err, servicecatalog.ErrCodeResourceNotFoundException) {
return nil, StatusNotFound, err
}

if err != nil {
return nil, servicecatalog.StatusFailed, err
}

if output == nil || output.ProvisionedProductDetail == nil {
return nil, StatusNotFound, err
}

return output, aws.StringValue(output.ProvisionedProductDetail.Status), err
}
}

func RecordStatus(conn *servicecatalog.ServiceCatalog, acceptLanguage, id string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
input := &servicecatalog.DescribeRecordInput{
Id: aws.String(id),
}

if acceptLanguage != "" {
input.AcceptLanguage = aws.String(acceptLanguage)
}

output, err := conn.DescribeRecord(input)

if tfawserr.ErrCodeEquals(err, servicecatalog.ErrCodeResourceNotFoundException) {
return nil, StatusNotFound, err
}

if err != nil {
return nil, servicecatalog.StatusFailed, err
}

if output == nil || output.RecordDetail == nil {
return nil, StatusNotFound, err
}

return output, aws.StringValue(output.RecordDetail.Status), err
}
}
130 changes: 104 additions & 26 deletions aws/internal/service/servicecatalog/waiter/waiter.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ const (

LaunchPathsReadyTimeout = 3 * time.Minute

ProvisionedProductReadyTimeout = 3 * time.Minute
ProvisionedProductDeleteTimeout = 3 * time.Minute

RecordReadyTimeout = 3 * time.Minute

MinTimeout = 2 * time.Second
NotFoundChecks = 5
ContinuousTargetOccurrence = 2

StatusNotFound = "NOT_FOUND"
StatusUnavailable = "UNAVAILABLE"

Expand All @@ -54,10 +63,13 @@ const (

func ProductReady(conn *servicecatalog.ServiceCatalog, acceptLanguage, productID string) (*servicecatalog.DescribeProductAsAdminOutput, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{servicecatalog.StatusCreating, StatusNotFound, StatusUnavailable},
Target: []string{servicecatalog.StatusAvailable, StatusCreated},
Refresh: ProductStatus(conn, acceptLanguage, productID),
Timeout: ProductReadyTimeout,
Pending: []string{servicecatalog.StatusCreating, StatusNotFound, StatusUnavailable},
Target: []string{servicecatalog.StatusAvailable, StatusCreated},
Refresh: ProductStatus(conn, acceptLanguage, productID),
Timeout: ProductReadyTimeout,
ContinuousTargetOccurence: ContinuousTargetOccurrence,
NotFoundChecks: NotFoundChecks,
MinTimeout: MinTimeout,
}

outputRaw, err := stateConf.WaitForState()
Expand Down Expand Up @@ -223,10 +235,13 @@ func OrganizationsAccessStable(conn *servicecatalog.ServiceCatalog) (string, err

func ConstraintReady(conn *servicecatalog.ServiceCatalog, acceptLanguage, id string) (*servicecatalog.DescribeConstraintOutput, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{StatusNotFound, servicecatalog.StatusCreating, StatusUnavailable},
Target: []string{servicecatalog.StatusAvailable},
Refresh: ConstraintStatus(conn, acceptLanguage, id),
Timeout: ConstraintReadyTimeout,
Pending: []string{StatusNotFound, servicecatalog.StatusCreating, StatusUnavailable},
Target: []string{servicecatalog.StatusAvailable},
Refresh: ConstraintStatus(conn, acceptLanguage, id),
Timeout: ConstraintReadyTimeout,
ContinuousTargetOccurence: ContinuousTargetOccurrence,
NotFoundChecks: NotFoundChecks,
MinTimeout: MinTimeout,
}

outputRaw, err := stateConf.WaitForState()
Expand All @@ -253,10 +268,13 @@ func ConstraintDeleted(conn *servicecatalog.ServiceCatalog, acceptLanguage, id s

func ProductPortfolioAssociationReady(conn *servicecatalog.ServiceCatalog, acceptLanguage, portfolioID, productID string) (*servicecatalog.PortfolioDetail, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{StatusNotFound, StatusUnavailable},
Target: []string{servicecatalog.StatusAvailable},
Refresh: ProductPortfolioAssociationStatus(conn, acceptLanguage, portfolioID, productID),
Timeout: ProductPortfolioAssociationReadyTimeout,
Pending: []string{StatusNotFound, StatusUnavailable},
Target: []string{servicecatalog.StatusAvailable},
Refresh: ProductPortfolioAssociationStatus(conn, acceptLanguage, portfolioID, productID),
Timeout: ProductPortfolioAssociationReadyTimeout,
ContinuousTargetOccurence: ContinuousTargetOccurrence,
NotFoundChecks: NotFoundChecks,
MinTimeout: MinTimeout,
}

outputRaw, err := stateConf.WaitForState()
Expand Down Expand Up @@ -377,10 +395,13 @@ func TagOptionResourceAssociationDeleted(conn *servicecatalog.ServiceCatalog, ta

func ProvisioningArtifactReady(conn *servicecatalog.ServiceCatalog, id, productID string) (*servicecatalog.DescribeProvisioningArtifactOutput, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{servicecatalog.StatusCreating, StatusNotFound, StatusUnavailable},
Target: []string{servicecatalog.StatusAvailable, StatusCreated},
Refresh: ProvisioningArtifactStatus(conn, id, productID),
Timeout: ProvisioningArtifactReadyTimeout,
Pending: []string{servicecatalog.StatusCreating, StatusNotFound, StatusUnavailable},
Target: []string{servicecatalog.StatusAvailable, StatusCreated},
Refresh: ProvisioningArtifactStatus(conn, id, productID),
Timeout: ProvisioningArtifactReadyTimeout,
ContinuousTargetOccurence: ContinuousTargetOccurrence,
NotFoundChecks: NotFoundChecks,
MinTimeout: MinTimeout,
}

outputRaw, err := stateConf.WaitForState()
Expand Down Expand Up @@ -415,12 +436,13 @@ func ProvisioningArtifactDeleted(conn *servicecatalog.ServiceCatalog, id, produc

func PrincipalPortfolioAssociationReady(conn *servicecatalog.ServiceCatalog, acceptLanguage, principalARN, portfolioID string) (*servicecatalog.Principal, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{StatusNotFound, StatusUnavailable},
Target: []string{servicecatalog.StatusAvailable},
Refresh: PrincipalPortfolioAssociationStatus(conn, acceptLanguage, principalARN, portfolioID),
Timeout: PrincipalPortfolioAssociationReadyTimeout,
NotFoundChecks: 5,
MinTimeout: 10 * time.Second,
Pending: []string{StatusNotFound, StatusUnavailable},
Target: []string{servicecatalog.StatusAvailable},
Refresh: PrincipalPortfolioAssociationStatus(conn, acceptLanguage, principalARN, portfolioID),
Timeout: PrincipalPortfolioAssociationReadyTimeout,
ContinuousTargetOccurence: ContinuousTargetOccurrence,
NotFoundChecks: NotFoundChecks,
MinTimeout: MinTimeout,
}

outputRaw, err := stateConf.WaitForState()
Expand Down Expand Up @@ -448,10 +470,13 @@ func PrincipalPortfolioAssociationDeleted(conn *servicecatalog.ServiceCatalog, a

func LaunchPathsReady(conn *servicecatalog.ServiceCatalog, acceptLanguage, productID string) ([]*servicecatalog.LaunchPathSummary, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{StatusNotFound},
Target: []string{servicecatalog.StatusAvailable},
Refresh: LaunchPathsStatus(conn, acceptLanguage, productID),
Timeout: LaunchPathsReadyTimeout,
Pending: []string{StatusNotFound},
Target: []string{servicecatalog.StatusAvailable},
Refresh: LaunchPathsStatus(conn, acceptLanguage, productID),
Timeout: LaunchPathsReadyTimeout,
ContinuousTargetOccurence: ContinuousTargetOccurrence,
NotFoundChecks: NotFoundChecks,
MinTimeout: MinTimeout,
}

outputRaw, err := stateConf.WaitForState()
Expand All @@ -462,3 +487,56 @@ func LaunchPathsReady(conn *servicecatalog.ServiceCatalog, acceptLanguage, produ

return nil, err
}

func ProvisionedProductReady(conn *servicecatalog.ServiceCatalog, acceptLanguage, id, name string) (*servicecatalog.DescribeProvisionedProductOutput, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{StatusNotFound, StatusUnavailable, servicecatalog.ProvisionedProductStatusUnderChange, servicecatalog.ProvisionedProductStatusPlanInProgress},
Target: []string{servicecatalog.StatusAvailable},
Refresh: ProvisionedProductStatus(conn, acceptLanguage, id, name),
Timeout: ProvisionedProductReadyTimeout,
ContinuousTargetOccurence: ContinuousTargetOccurrence,
NotFoundChecks: NotFoundChecks,
MinTimeout: MinTimeout,
}

outputRaw, err := stateConf.WaitForState()

if output, ok := outputRaw.(*servicecatalog.DescribeProvisionedProductOutput); ok {
return output, err
}

return nil, err
}

func ProvisionedProductTerminated(conn *servicecatalog.ServiceCatalog, acceptLanguage, id, name string) error {
stateConf := &resource.StateChangeConf{
Pending: []string{servicecatalog.StatusAvailable, servicecatalog.ProvisionedProductStatusUnderChange},
Target: []string{StatusNotFound, StatusUnavailable},
Refresh: ProvisionedProductStatus(conn, acceptLanguage, id, name),
Timeout: ProvisionedProductDeleteTimeout,
}

_, err := stateConf.WaitForState()

return err
}

func RecordReady(conn *servicecatalog.ServiceCatalog, acceptLanguage, id string) (*servicecatalog.DescribeRecordOutput, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{StatusNotFound, StatusUnavailable, servicecatalog.ProvisionedProductStatusUnderChange, servicecatalog.ProvisionedProductStatusPlanInProgress},
Target: []string{servicecatalog.RecordStatusSucceeded, servicecatalog.StatusAvailable},
Refresh: RecordStatus(conn, acceptLanguage, id),
Timeout: RecordReadyTimeout,
ContinuousTargetOccurence: ContinuousTargetOccurrence,
NotFoundChecks: NotFoundChecks,
MinTimeout: MinTimeout,
}

outputRaw, err := stateConf.WaitForState()

if output, ok := outputRaw.(*servicecatalog.DescribeRecordOutput); ok {
return output, err
}

return nil, err
}
1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,7 @@ func Provider() *schema.Provider {
"aws_servicecatalog_portfolio": resourceAwsServiceCatalogPortfolio(),
"aws_servicecatalog_portfolio_share": resourceAwsServiceCatalogPortfolioShare(),
"aws_servicecatalog_product": resourceAwsServiceCatalogProduct(),
"aws_servicecatalog_provisioned_product": resourceAwsServiceCatalogProvisionedProduct(),
"aws_servicecatalog_service_action": resourceAwsServiceCatalogServiceAction(),
"aws_servicecatalog_tag_option": resourceAwsServiceCatalogTagOption(),
"aws_servicecatalog_tag_option_resource_association": resourceAwsServiceCatalogTagOptionResourceAssociation(),
Expand Down
Loading