@@ -6,48 +6,48 @@ package appconfig
6
6
import (
7
7
"context"
8
8
"fmt"
9
+ "iter"
9
10
10
11
"github.com/YakDriver/regexache"
11
12
"github.com/aws/aws-sdk-go-v2/aws"
12
13
"github.com/aws/aws-sdk-go-v2/service/appconfig"
13
14
awstypes "github.com/aws/aws-sdk-go-v2/service/appconfig/types"
15
+ "github.com/hashicorp/terraform-plugin-framework-validators/datasourcevalidator"
14
16
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
15
17
"github.com/hashicorp/terraform-plugin-framework/datasource"
16
18
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
19
+ "github.com/hashicorp/terraform-plugin-framework/path"
17
20
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
18
21
"github.com/hashicorp/terraform-plugin-framework/types"
19
- "github.com/hashicorp/terraform-provider-aws/internal/errs"
20
22
"github.com/hashicorp/terraform-provider-aws/internal/framework"
21
23
"github.com/hashicorp/terraform-provider-aws/internal/framework/flex"
22
- "github.com/hashicorp/terraform-provider-aws/internal/retry "
24
+ tfslices "github.com/hashicorp/terraform-provider-aws/internal/slices "
23
25
"github.com/hashicorp/terraform-provider-aws/internal/smerr"
26
+ "github.com/hashicorp/terraform-provider-aws/internal/tfresource"
24
27
"github.com/hashicorp/terraform-provider-aws/names"
25
28
)
26
29
27
- // Function annotations are used for datasource registration to the Provider. DO NOT EDIT.
28
30
// @FrameworkDataSource("aws_appconfig_application", name="Application")
29
31
func newDataSourceApplication (context.Context ) (datasource.DataSourceWithConfigure , error ) {
30
32
return & dataSourceApplication {}, nil
31
33
}
32
34
33
- const (
34
- DSNameApplication = "Application Data Source"
35
- )
36
-
37
35
type dataSourceApplication struct {
38
36
framework.DataSourceWithModel [dataSourceApplicationModel ]
39
37
}
40
38
41
39
func (d * dataSourceApplication ) Schema (ctx context.Context , req datasource.SchemaRequest , resp * datasource.SchemaResponse ) {
42
40
resp .Schema = schema.Schema {
43
41
Attributes : map [string ]schema.Attribute {
42
+ names .AttrARN : framework .ARNAttributeComputedOnly (),
44
43
names .AttrDescription : schema.StringAttribute {
45
44
Computed : true ,
46
45
Validators : []validator.String {
47
46
stringvalidator .LengthBetween (0 , 1024 ),
48
47
},
49
48
},
50
49
names .AttrID : schema.StringAttribute {
50
+ Optional : true ,
51
51
Computed : true ,
52
52
Validators : []validator.String {
53
53
stringvalidator .RegexMatches (
@@ -56,9 +56,9 @@ func (d *dataSourceApplication) Schema(ctx context.Context, req datasource.Schem
56
56
),
57
57
},
58
58
},
59
- //names.AttrARN: framework.ARNAttributeComputedOnly(),
60
59
names .AttrName : schema.StringAttribute {
61
- Required : true ,
60
+ Optional : true ,
61
+ Computed : true ,
62
62
Validators : []validator.String {
63
63
stringvalidator .LengthBetween (1 , 64 ),
64
64
},
@@ -76,53 +76,87 @@ func (d *dataSourceApplication) Read(ctx context.Context, req datasource.ReadReq
76
76
return
77
77
}
78
78
79
- out , err := findApplicationByName (ctx , conn , data .Name .ValueString ())
79
+ var out * awstypes.Application
80
+ var err error
81
+ var input appconfig.ListApplicationsInput
82
+ if ! data .ID .IsNull () {
83
+ out , err = findApplicationWithFilter (ctx , conn , & input , func (v * awstypes.Application ) bool {
84
+ return aws .ToString (v .Id ) == data .ID .ValueString ()
85
+ }, tfslices .WithReturnFirstMatch )
86
+ }
87
+
88
+ if ! data .Name .IsNull () {
89
+ out , err = findApplicationWithFilter (ctx , conn , & input , func (v * awstypes.Application ) bool {
90
+ return aws .ToString (v .Name ) == data .Name .ValueString ()
91
+ }, tfslices .WithReturnFirstMatch )
92
+ }
93
+
80
94
if err != nil {
81
95
smerr .AddError (ctx , & resp .Diagnostics , err , smerr .ID , data .Name .String ())
82
96
return
83
97
}
84
98
85
- smerr .EnrichAppend (ctx , & resp .Diagnostics , flex .Flatten (ctx , out , & data , flex . WithFieldNamePrefix ( "Application" ) ), smerr .ID , data .Name .String ())
99
+ smerr .EnrichAppend (ctx , & resp .Diagnostics , flex .Flatten (ctx , out , & data ), smerr .ID , data .Name .String ())
86
100
if resp .Diagnostics .HasError () {
87
101
return
88
102
}
89
103
104
+ data .ARN = flex .StringValueToFramework (ctx , d .Meta ().RegionalARN (ctx , "appconfig" , "application/" + data .ID .ValueString ()))
105
+
90
106
smerr .EnrichAppend (ctx , & resp .Diagnostics , resp .State .Set (ctx , & data ), smerr .ID , data .Name .String ())
91
107
}
92
108
109
+ func (d * dataSourceApplication ) ConfigValidators (_ context.Context ) []datasource.ConfigValidator {
110
+ return []datasource.ConfigValidator {
111
+ datasourcevalidator .ExactlyOneOf (
112
+ path .MatchRoot (names .AttrID ),
113
+ path .MatchRoot (names .AttrName ),
114
+ ),
115
+ }
116
+ }
117
+
93
118
type dataSourceApplicationModel struct {
94
119
framework.WithRegionModel
120
+ ARN types.String `tfsdk:"arn"`
95
121
Description types.String `tfsdk:"description"`
96
122
ID types.String `tfsdk:"id"`
97
123
Name types.String `tfsdk:"name"`
98
124
}
99
125
100
- func findApplicationByName (ctx context.Context , conn * appconfig.Client , name string ) (* appconfig.GetApplicationOutput , error ) {
101
- input := & appconfig.ListApplicationsInput {}
102
-
103
- pages := appconfig .NewListApplicationsPaginator (conn , input )
104
- for pages .HasMorePages () {
105
- page , err := pages .NextPage (ctx )
106
-
107
- if errs.IsA [* awstypes.ResourceNotFoundException ](err ) {
108
- return nil , & retry.NotFoundError {
109
- LastError : err ,
110
- }
111
- }
112
-
126
+ func findApplicationWithFilter (ctx context.Context , conn * appconfig.Client , input * appconfig.ListApplicationsInput , filter tfslices.Predicate [* awstypes.Application ], optFns ... tfslices.FinderOptionsFunc ) (* awstypes.Application , error ) {
127
+ opts := tfslices .NewFinderOptions (optFns )
128
+ var output []awstypes.Application
129
+ for value , err := range listApplications (ctx , conn , input , filter ) {
113
130
if err != nil {
114
131
return nil , err
115
132
}
116
133
117
- for _ , app := range page .Items {
118
- if aws .ToString (app .Name ) == name {
119
- // AppConfig does not support duplicate names, so we can return the first match
120
- return findApplicationByID (ctx , conn , aws .ToString (app .Id ))
121
- }
134
+ output = append (output , value )
135
+ if opts .ReturnFirstMatch () {
136
+ break
122
137
}
123
138
}
124
139
125
- return nil , & retry.NotFoundError {
126
- LastError : fmt .Errorf ("AppConfig Application (%s) not found" , name ),
140
+ return tfresource .AssertSingleValueResult (output )
141
+ }
142
+
143
+ func listApplications (ctx context.Context , conn * appconfig.Client , input * appconfig.ListApplicationsInput , filter tfslices.Predicate [* awstypes.Application ]) iter.Seq2 [awstypes.Application , error ] {
144
+ return func (yield func (awstypes.Application , error ) bool ) {
145
+ pages := appconfig .NewListApplicationsPaginator (conn , input )
146
+ for pages .HasMorePages () {
147
+ page , err := pages .NextPage (ctx )
148
+ if err != nil {
149
+ yield (awstypes.Application {}, fmt .Errorf ("listing AppConfig Applications: %w" , err ))
150
+ return
151
+ }
152
+
153
+ for _ , v := range page .Items {
154
+ if filter (& v ) {
155
+ if ! yield (v , nil ) {
156
+ return
157
+ }
158
+ }
159
+ }
160
+ }
127
161
}
128
162
}
0 commit comments