Skip to content

Commit a316669

Browse files
authored
Merge pull request #34310 from skyscrapr/f-aws_bedrock_custom_model
F aws bedrock custom model
2 parents 191165a + 2222c5c commit a316669

28 files changed

+2499
-214
lines changed

.changelog/34310.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
```release-note:new-data-source
2+
aws_bedrock_custom_model
3+
```
4+
5+
```release-note:new-data-source
6+
aws_bedrock_custom_models
7+
```
8+
9+
```release-note:resource
10+
aws_bedrock_custom_model
11+
```

internal/framework/base.go

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/aws/aws-sdk-go-v2/aws/arn"
1111
"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts"
1212
"github.com/hashicorp/terraform-plugin-framework/datasource"
13+
"github.com/hashicorp/terraform-plugin-framework/diag"
1314
"github.com/hashicorp/terraform-plugin-framework/path"
1415
"github.com/hashicorp/terraform-plugin-framework/resource"
1516
"github.com/hashicorp/terraform-plugin-framework/types"
@@ -107,10 +108,26 @@ func (w *WithImportByID) ImportState(ctx context.Context, request resource.Impor
107108
resource.ImportStatePassthroughID(ctx, path.Root(names.AttrID), request, response)
108109
}
109110

110-
// WithNoOpUpdate is intended to be embedded in resources which have no need of an Update method.
111-
type WithNoOpUpdate struct{}
111+
// WithNoUpdate is intended to be embedded in resources which cannot be updated.
112+
type WithNoUpdate struct{}
112113

113-
func (w *WithNoOpUpdate) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) {
114+
func (w *WithNoUpdate) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) {
115+
response.Diagnostics.Append(diag.NewErrorDiagnostic("not supported", "This resource's Update method should not have been called"))
116+
}
117+
118+
// WithNoOpUpdate is intended to be embedded in resources which have no need of a custom Update method.
119+
// For example, resources where only `tags` can be updated and that is handled via transparent tagging.
120+
type WithNoOpUpdate[T any] struct{}
121+
122+
func (w *WithNoOpUpdate[T]) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) {
123+
var t T
124+
125+
response.Diagnostics.Append(request.Plan.Get(ctx, &t)...)
126+
if response.Diagnostics.HasError() {
127+
return
128+
}
129+
130+
response.Diagnostics.Append(response.State.Set(ctx, &t)...)
114131
}
115132

116133
// DataSourceWithConfigure is a structure to be embedded within a DataSource that implements the DataSourceWithConfigure interface.

internal/framework/types/mapof.go

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,26 @@ import (
1616
)
1717

1818
var (
19-
_ basetypes.MapTypable = MapTypeOf[basetypes.StringValue]{}
19+
_ basetypes.MapTypable = mapTypeOf[basetypes.StringValue]{}
2020
_ basetypes.MapValuable = MapValueOf[basetypes.StringValue]{}
2121
)
2222

23-
// MapTypeOf is the attribute type of a MapValueOf.
24-
type MapTypeOf[T attr.Value] struct {
23+
var (
24+
// MapOfStringType is a custom type used for defining a Map of strings.
25+
MapOfStringType = mapTypeOf[basetypes.StringValue]{basetypes.MapType{ElemType: basetypes.StringType{}}}
26+
)
27+
28+
type mapTypeOf[T attr.Value] struct {
2529
basetypes.MapType
2630
}
2731

28-
func NewMapTypeOf[T attr.Value](ctx context.Context) MapTypeOf[T] {
32+
func NewMapTypeOf[T attr.Value](ctx context.Context) mapTypeOf[T] {
2933
var zero T
30-
return MapTypeOf[T]{basetypes.MapType{ElemType: zero.Type(ctx)}}
34+
return mapTypeOf[T]{basetypes.MapType{ElemType: zero.Type(ctx)}}
3135
}
3236

33-
func (t MapTypeOf[T]) Equal(o attr.Type) bool {
34-
other, ok := o.(MapTypeOf[T])
37+
func (t mapTypeOf[T]) Equal(o attr.Type) bool {
38+
other, ok := o.(mapTypeOf[T])
3539

3640
if !ok {
3741
return false
@@ -40,18 +44,19 @@ func (t MapTypeOf[T]) Equal(o attr.Type) bool {
4044
return t.MapType.Equal(other.MapType)
4145
}
4246

43-
func (t MapTypeOf[T]) String() string {
47+
func (t mapTypeOf[T]) String() string {
4448
var zero T
4549
return fmt.Sprintf("%T", zero)
4650
}
4751

48-
func (t MapTypeOf[T]) ValueFromMap(ctx context.Context, in basetypes.MapValue) (basetypes.MapValuable, diag.Diagnostics) {
52+
func (t mapTypeOf[T]) ValueFromMap(ctx context.Context, in basetypes.MapValue) (basetypes.MapValuable, diag.Diagnostics) {
4953
var diags diag.Diagnostics
5054
var zero T
5155

5256
if in.IsNull() {
5357
return NewMapValueOfNull[T](ctx), diags
5458
}
59+
5560
if in.IsUnknown() {
5661
return NewMapValueOfUnknown[T](ctx), diags
5762
}
@@ -73,7 +78,7 @@ func (t MapTypeOf[T]) ValueFromMap(ctx context.Context, in basetypes.MapValue) (
7378
return value, diags
7479
}
7580

76-
func (t MapTypeOf[T]) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) {
81+
func (t mapTypeOf[T]) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) {
7782
attrValue, err := t.MapType.ValueFromTerraform(ctx, in)
7883

7984
if err != nil {
@@ -93,11 +98,11 @@ func (t MapTypeOf[T]) ValueFromTerraform(ctx context.Context, in tftypes.Value)
9398
return mapValuable, nil
9499
}
95100

96-
func (t MapTypeOf[T]) ValueType(ctx context.Context) attr.Value {
101+
func (t mapTypeOf[T]) ValueType(ctx context.Context) attr.Value {
97102
return MapValueOf[T]{}
98103
}
99104

100-
// MapValueOf represents a Terraform Plugin Framework Map value whose elements are of type MapTypeOf.
105+
// MapValueOf represents a Terraform Plugin Framework Map value whose elements are of type mapTypeOf.
101106
type MapValueOf[T attr.Value] struct {
102107
basetypes.MapValue
103108
}

internal/framework/types/string_enum.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ func (v StringEnum[T]) ValueEnum() T {
177177

178178
// StringEnumValue is useful if you have a zero value StringEnum but need a
179179
// way to get a non-zero value such as when flattening.
180+
// It's called via reflection inside AutoFlEx.
180181
func (v StringEnum[T]) StringEnumValue(value string) StringEnum[T] {
181182
return StringEnum[T]{StringValue: basetypes.NewStringValue(value)}
182183
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package validators
5+
6+
import (
7+
"context"
8+
9+
"github.com/YakDriver/regexache"
10+
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag"
11+
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
12+
)
13+
14+
// s3URIValidator validates that a string Attribute's value is a valid S3 URI.
15+
type s3URIValidator struct{}
16+
17+
func (validator s3URIValidator) Description(_ context.Context) string {
18+
return "value must be a valid S3 URI"
19+
}
20+
21+
func (validator s3URIValidator) MarkdownDescription(ctx context.Context) string {
22+
return validator.Description(ctx)
23+
}
24+
25+
func (validator s3URIValidator) ValidateString(ctx context.Context, request validator.StringRequest, response *validator.StringResponse) {
26+
if request.ConfigValue.IsNull() || request.ConfigValue.IsUnknown() {
27+
return
28+
}
29+
30+
if !regexache.MustCompile(`^s3://[a-z0-9][\.\-a-z0-9]{1,61}[a-z0-9](/.*)?$`).MatchString(request.ConfigValue.ValueString()) {
31+
response.Diagnostics.Append(validatordiag.InvalidAttributeValueDiagnostic(
32+
request.Path,
33+
validator.Description(ctx),
34+
request.ConfigValue.ValueString(),
35+
))
36+
return
37+
}
38+
}
39+
40+
// S3URI returns a string validator which ensures that any configured
41+
// attribute value:
42+
//
43+
// - Is a string, which represents a valid S3 URI (s3://bucket[/key]).
44+
//
45+
// Null (unconfigured) and unknown (known after apply) values are skipped.
46+
func S3URI() validator.String {
47+
return s3URIValidator{}
48+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package validators_test
5+
6+
import (
7+
"context"
8+
"testing"
9+
10+
"github.com/google/go-cmp/cmp"
11+
"github.com/hashicorp/terraform-plugin-framework/diag"
12+
"github.com/hashicorp/terraform-plugin-framework/path"
13+
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
14+
"github.com/hashicorp/terraform-plugin-framework/types"
15+
fwvalidators "github.com/hashicorp/terraform-provider-aws/internal/framework/validators"
16+
)
17+
18+
func TestS3URIValidator(t *testing.T) {
19+
t.Parallel()
20+
21+
type testCase struct {
22+
val types.String
23+
expectedDiagnostics diag.Diagnostics
24+
}
25+
tests := map[string]testCase{
26+
"unknown String": {
27+
val: types.StringUnknown(),
28+
},
29+
"null String": {
30+
val: types.StringNull(),
31+
},
32+
"invalid String": {
33+
val: types.StringValue("test-value"),
34+
expectedDiagnostics: diag.Diagnostics{
35+
diag.NewAttributeErrorDiagnostic(
36+
path.Root("test"),
37+
"Invalid Attribute Value",
38+
`Attribute test value must be a valid S3 URI, got: test-value`,
39+
),
40+
},
41+
},
42+
"valid S3 URI": {
43+
val: types.StringValue("s3://bucket/path/to/key"),
44+
},
45+
"invalid characters": {
46+
val: types.StringValue("s3://asbcdefg--#/key"),
47+
expectedDiagnostics: diag.Diagnostics{
48+
diag.NewAttributeErrorDiagnostic(
49+
path.Root("test"),
50+
"Invalid Attribute Value",
51+
`Attribute test value must be a valid S3 URI, got: s3://asbcdefg--#/key`,
52+
),
53+
},
54+
},
55+
}
56+
57+
for name, test := range tests {
58+
name, test := name, test
59+
t.Run(name, func(t *testing.T) {
60+
t.Parallel()
61+
62+
ctx := context.Background()
63+
64+
request := validator.StringRequest{
65+
Path: path.Root("test"),
66+
PathExpression: path.MatchRoot("test"),
67+
ConfigValue: test.val,
68+
}
69+
response := validator.StringResponse{}
70+
fwvalidators.S3URI().ValidateString(ctx, request, &response)
71+
72+
if diff := cmp.Diff(response.Diagnostics, test.expectedDiagnostics); diff != "" {
73+
t.Errorf("unexpected diagnostics difference: %s", diff)
74+
}
75+
})
76+
}
77+
}

internal/service/bedrock/consts.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package bedrock
5+
6+
import (
7+
"time"
8+
)
9+
10+
const (
11+
propagationTimeout = 2 * time.Minute
12+
)

0 commit comments

Comments
 (0)