Skip to content

Commit

Permalink
feat: Add new aws_synthetics_runtime_version data source
Browse files Browse the repository at this point in the history
  • Loading branch information
acwwat committed Sep 7, 2024
1 parent 9475b29 commit aaa0654
Show file tree
Hide file tree
Showing 5 changed files with 323 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/39180.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
```release-note:new-data-source
aws_synthetics_runtime_version
```
```release-note:new-data-source
aws_synthetics_runtime_versions
```
185 changes: 185 additions & 0 deletions internal/service/synthetics/runtime_version_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package synthetics

import (
"context"
"fmt"
"strings"
"time"

"github.com/YakDriver/regexache"
"github.com/aws/aws-sdk-go-v2/aws"
awstypes "github.com/aws/aws-sdk-go-v2/service/synthetics/types"
"github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
"github.com/hashicorp/terraform-plugin-framework-validators/boolvalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-provider-aws/internal/create"
"github.com/hashicorp/terraform-provider-aws/internal/framework"
"github.com/hashicorp/terraform-provider-aws/internal/framework/flex"
"github.com/hashicorp/terraform-provider-aws/names"
)

// @FrameworkDataSource(name="Runtime Version")
func newDataSourceRuntimeVersion(context.Context) (datasource.DataSourceWithConfigure, error) {
return &dataSourceRuntimeVersion{}, nil
}

const (
DSNameRuntimeVersion = "Runtime Version Data Source"
)

type dataSourceRuntimeVersion struct {
framework.DataSourceWithConfigure
}

func (d *dataSourceRuntimeVersion) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { // nosemgrep:ci.meta-in-func-name
resp.TypeName = "aws_synthetics_runtime_version"
}

func (d *dataSourceRuntimeVersion) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"deprecation_date": schema.StringAttribute{
CustomType: timetypes.RFC3339Type{},
Computed: true,
},
names.AttrDescription: schema.StringAttribute{
Computed: true,
},
names.AttrID: framework.IDAttribute(),
"release_date": schema.StringAttribute{
CustomType: timetypes.RFC3339Type{},
Computed: true,
},
"latest": schema.BoolAttribute{
Optional: true,
Validators: []validator.Bool{
boolValueEqualsValidator{
Value: true,
},
boolvalidator.ExactlyOneOf(path.Expressions{
path.MatchRoot("latest"),
path.MatchRoot(names.AttrVersion),
}...),
},
},
names.AttrPrefix: schema.StringAttribute{
Required: true,
Validators: []validator.String{
stringvalidator.RegexMatches(regexache.MustCompile(`^.*[^-]$`), "must not end with a hyphen"),
},
},
names.AttrVersion: schema.StringAttribute{
Optional: true,
Validators: []validator.String{
stringvalidator.RegexMatches(regexache.MustCompile(`^\d.*$`), "must start with a digit"),
stringvalidator.ExactlyOneOf(path.Expressions{
path.MatchRoot("latest"),
path.MatchRoot(names.AttrVersion),
}...),
},
},
"version_name": schema.StringAttribute{
Computed: true,
},
},
}
}

func (d *dataSourceRuntimeVersion) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
conn := d.Meta().SyntheticsClient(ctx)

var data dataSourceRuntimeVersionModel
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}

latest := data.Latest.ValueBool()
prefix := data.Prefix.ValueString()
version := data.Version.ValueString()

out, err := FindRuntimeVersions(ctx, conn)
if err != nil {
resp.Diagnostics.AddError(
create.ProblemStandardMessage(names.Synthetics, create.ErrActionReading, DSNameRuntimeVersion, "", err),
err.Error(),
)
return
}

var runtimeVersion *awstypes.RuntimeVersion
var latestReleaseDate *time.Time

for _, v := range out {
if strings.HasPrefix(aws.ToString(v.VersionName), prefix) {
if latest {
if latestReleaseDate == nil || aws.ToTime(v.ReleaseDate).After(*latestReleaseDate) {
latestReleaseDate = v.ReleaseDate
runtimeVersion = &v
}
} else {
if aws.ToString(v.VersionName) == fmt.Sprintf("%s-%s", prefix, version) {
runtimeVersion = &v
break
}
}
}
}

if runtimeVersion == nil {
resp.Diagnostics.AddError(
create.ProblemStandardMessage(names.Synthetics, create.ErrActionReading, DSNameRuntimeVersion, "", err),
"Query returned no results.",
)
return
}

data.ID = flex.StringToFramework(ctx, runtimeVersion.VersionName)
resp.Diagnostics.Append(flex.Flatten(ctx, runtimeVersion, &data, flex.WithFieldNamePrefix("{{ .Resource }}"))...)
if resp.Diagnostics.HasError() {
return
}

resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}

type dataSourceRuntimeVersionModel struct {
DeprecationDate timetypes.RFC3339 `tfsdk:"deprecation_date"`
Description types.String `tfsdk:"description"`
ID types.String `tfsdk:"id"`
Latest types.Bool `tfsdk:"latest"`
Prefix types.String `tfsdk:"prefix"`
ReleaseDate timetypes.RFC3339 `tfsdk:"release_date"`
Version types.String `tfsdk:"version"`
VersionName types.String `tfsdk:"version_name"`
}

type boolValueEqualsValidator struct {
Value bool
}

func (v boolValueEqualsValidator) Description(ctx context.Context) string {
return fmt.Sprintf("Value must be equal to %t", v.Value)
}

func (v boolValueEqualsValidator) MarkdownDescription(ctx context.Context) string {
return v.Description(ctx)
}

func (v boolValueEqualsValidator) ValidateBool(ctx context.Context, req validator.BoolRequest, resp *validator.BoolResponse) {
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
return
}

if req.ConfigValue.ValueBool() != v.Value {
resp.Diagnostics.AddAttributeError(req.Path, "Invalid Bool Value", fmt.Sprintf("Value must be equal to %t", v.Value))
}
}
80 changes: 80 additions & 0 deletions internal/service/synthetics/runtime_version_data_source_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package synthetics_test

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-provider-aws/internal/acctest"
"github.com/hashicorp/terraform-provider-aws/names"
)

func TestAccSyntheticsRuntimeVersionDataSource_basic(t *testing.T) {
ctx := acctest.Context(t)
dataSourceName := "data.aws_synthetics_runtime_version.test"
prefix := "syn-nodejs-puppeteer"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, names.SyntheticsServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccRuntimeVersionDataSourceConfig_basic(prefix),
Check: resource.ComposeTestCheckFunc(
acctest.CheckResourceAttrHasPrefix(dataSourceName, "version_name", prefix),
resource.TestCheckResourceAttrPair(dataSourceName, names.AttrID, dataSourceName, "version_name"),
resource.TestCheckNoResourceAttr(dataSourceName, "deprecation_date"),
resource.TestCheckResourceAttrSet(dataSourceName, names.AttrDescription),
resource.TestCheckResourceAttrSet(dataSourceName, "release_date"),
),
},
},
})
}

func TestAccSyntheticsRuntimeVersionDataSource_deprecatedVersion(t *testing.T) {
ctx := acctest.Context(t)
dataSourceName := "data.aws_synthetics_runtime_version.test"
prefix := "syn-nodejs-puppeteer"
version := "3.0"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, names.SyntheticsServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccRuntimeVersionDataSourceConfig_version(prefix, version),
Check: resource.ComposeTestCheckFunc(
acctest.CheckResourceAttrHasPrefix(dataSourceName, "version_name", fmt.Sprintf("%s-%s", prefix, version)),
resource.TestCheckResourceAttrPair(dataSourceName, names.AttrID, dataSourceName, "version_name"),
resource.TestCheckResourceAttrSet(dataSourceName, "deprecation_date"),
resource.TestCheckResourceAttrSet(dataSourceName, names.AttrDescription),
resource.TestCheckResourceAttrSet(dataSourceName, "release_date"),
),
},
},
})
}

func testAccRuntimeVersionDataSourceConfig_basic(prefix string) string {
return fmt.Sprintf(`
data "aws_synthetics_runtime_version" "test" {
prefix = %[1]q
latest = true
}
`, prefix)
}

func testAccRuntimeVersionDataSourceConfig_version(prefix, version string) string {
return fmt.Sprintf(`
data "aws_synthetics_runtime_version" "test" {
prefix = %[1]q
version = %[2]q
}
`, prefix, version)
}
4 changes: 4 additions & 0 deletions internal/service/synthetics/service_package_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 51 additions & 0 deletions website/docs/d/synthetics_runtime_version.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
subcategory: "CloudWatch Synthetics"
layout: "aws"
page_title: "AWS: aws_synthetics_runtime_version"
description: |-
Terraform data source for managing an AWS CloudWatch Synthetics Runtime Version.
---
# Data Source: aws_synthetics_runtime_version

Terraform data source for managing an AWS CloudWatch Synthetics Runtime Version.

## Example Usage

### Latest Runtime Version

```terraform
data "aws_synthetics_runtime_version" "example" {
prefix = "syn-nodejs-puppeteer"
latest = true
}
```

### Specific Runtime Version

```terraform
data "aws_synthetics_runtime_version" "example" {
prefix = "syn-nodejs-puppeteer"
version = "9.0"
}
```

## Argument Reference

The following arguments are required:

* `prefix` - (Required) Name prefix of the runtime version (for example, `syn-nodejs-puppeteer`).

The following arguments are optional:

* `latest` - (Optional) Whether the latest version of the runtime should be fetched. Conflicts with `version`. Valid values: `true`.
* `version` - (Optional) Version of the runtime to be fetched (for example, `9.0`). Conflicts with `latest`.

## Attribute Reference

This data source exports the following attributes in addition to the arguments above:

* `deprecation_date` - Date of deprecation if the runtme version is deprecated.
* `description` - Description of the runtime version, created by Amazon.
* `id` - Name of the runtime version. For a list of valid runtime versions, see [Canary Runtime Versions](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html).
* `release_date` - Date that the runtime version was released.
* `version_name` - Name of the runtime version. For a list of valid runtime versions, see [Canary Runtime Versions](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html).

0 comments on commit aaa0654

Please sign in to comment.