@@ -20,17 +20,16 @@ import (
20
20
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
21
21
"github.com/hashicorp/terraform-plugin-framework/types"
22
22
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
23
- "github.com/hashicorp/terraform-provider-aws/internal/create"
24
23
"github.com/hashicorp/terraform-provider-aws/internal/enum"
25
24
"github.com/hashicorp/terraform-provider-aws/internal/errs"
26
25
"github.com/hashicorp/terraform-provider-aws/internal/errs/fwdiag"
27
26
"github.com/hashicorp/terraform-provider-aws/internal/framework"
28
- "github.com/hashicorp/terraform-provider-aws/internal/framework/flex"
27
+ fwflex "github.com/hashicorp/terraform-provider-aws/internal/framework/flex"
28
+ tfslices "github.com/hashicorp/terraform-provider-aws/internal/slices"
29
29
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
30
30
"github.com/hashicorp/terraform-provider-aws/names"
31
31
)
32
32
33
- // Function annotations are used for resource registration to the Provider. DO NOT EDIT.
34
33
// @FrameworkResource("aws_notifications_notification_hub", name="Notification Hub")
35
34
func newResourceNotificationHub (_ context.Context ) (resource.ResourceWithConfigure , error ) {
36
35
r := & resourceNotificationHub {}
@@ -41,20 +40,16 @@ func newResourceNotificationHub(_ context.Context) (resource.ResourceWithConfigu
41
40
return r , nil
42
41
}
43
42
44
- const (
45
- ResNameNotificationHub = "Notification Hub"
46
- )
47
-
48
43
type resourceNotificationHub struct {
49
44
framework.ResourceWithConfigure
50
45
framework.WithTimeouts
51
46
framework.WithNoUpdate
52
47
}
53
48
54
- func (r * resourceNotificationHub ) Schema (ctx context.Context , req resource.SchemaRequest , resp * resource.SchemaResponse ) {
55
- resp .Schema = schema.Schema {
49
+ func (r * resourceNotificationHub ) Schema (ctx context.Context , request resource.SchemaRequest , response * resource.SchemaResponse ) {
50
+ response .Schema = schema.Schema {
56
51
Attributes : map [string ]schema.Attribute {
57
- names . AttrRegion : schema.StringAttribute {
52
+ "notification_hub_region" : schema.StringAttribute {
58
53
Required : true ,
59
54
PlanModifiers : []planmodifier.String {
60
55
stringplanmodifier .RequiresReplace (),
@@ -70,164 +65,162 @@ func (r *resourceNotificationHub) Schema(ctx context.Context, req resource.Schem
70
65
}
71
66
}
72
67
73
- func (r * resourceNotificationHub ) Create (ctx context.Context , req resource.CreateRequest , resp * resource.CreateResponse ) {
74
- conn := r .Meta ().NotificationsClient (ctx )
75
-
76
- var plan resourceNotificationHubModel
77
- resp .Diagnostics .Append (req .Plan .Get (ctx , & plan )... )
78
- if resp .Diagnostics .HasError () {
68
+ func (r * resourceNotificationHub ) Create (ctx context.Context , request resource.CreateRequest , response * resource.CreateResponse ) {
69
+ var data resourceNotificationHubModel
70
+ response .Diagnostics .Append (request .Plan .Get (ctx , & data )... )
71
+ if response .Diagnostics .HasError () {
79
72
return
80
73
}
81
74
82
- var input notifications.RegisterNotificationHubInput
83
- resp .Diagnostics .Append (flex .Expand (ctx , plan , & input , flex .WithFieldNamePrefix ("NotificationHub" ))... )
84
- if resp .Diagnostics .HasError () {
85
- return
75
+ conn := r .Meta ().NotificationsClient (ctx )
76
+
77
+ region := fwflex .StringValueFromFramework (ctx , data .NotificationHubRegion )
78
+ input := notifications.RegisterNotificationHubInput {
79
+ NotificationHubRegion : aws .String (region ),
86
80
}
81
+ _ , err := conn .RegisterNotificationHub (ctx , & input )
87
82
88
- out , err := conn .RegisterNotificationHub (ctx , & input )
89
83
if err != nil {
90
- resp .Diagnostics .AddError (
91
- create .ProblemStandardMessage (names .Notifications , create .ErrActionCreating , ResNameNotificationHub , plan .Region .String (), err ),
92
- err .Error (),
93
- )
94
- return
95
- }
96
- if out == nil {
97
- resp .Diagnostics .AddError (
98
- create .ProblemStandardMessage (names .Notifications , create .ErrActionCreating , ResNameNotificationHub , plan .Region .String (), nil ),
99
- errors .New ("empty output" ).Error (),
100
- )
101
- return
102
- }
84
+ response .Diagnostics .AddError (fmt .Sprintf ("registering User Notifications Notification Hub (%s)" , region ), err .Error ())
103
85
104
- resp .Diagnostics .Append (flex .Flatten (ctx , out , & plan )... )
105
- if resp .Diagnostics .HasError () {
106
86
return
107
87
}
108
88
109
- createTimeout := r .CreateTimeout (ctx , plan .Timeouts )
110
- _ , err = waitNotificationHubCreated (ctx , conn , plan .Region .ValueString (), createTimeout )
111
- if err != nil {
112
- resp .Diagnostics .AddError (
113
- create .ProblemStandardMessage (names .Notifications , create .ErrActionWaitingForCreation , ResNameNotificationHub , plan .Region .String (), err ),
114
- err .Error (),
115
- )
89
+ if _ , err := waitNotificationHubCreated (ctx , conn , region , r .CreateTimeout (ctx , data .Timeouts )); err != nil {
90
+ response .Diagnostics .AddError (fmt .Sprintf ("waiting for User Notifications Notification Hub (%s) create" , region ), err .Error ())
91
+
116
92
return
117
93
}
118
94
119
- resp .Diagnostics .Append (resp .State .Set (ctx , plan )... )
95
+ response .Diagnostics .Append (response .State .Set (ctx , data )... )
120
96
}
121
97
122
- func (r * resourceNotificationHub ) Read (ctx context.Context , req resource.ReadRequest , resp * resource.ReadResponse ) {
123
- conn := r .Meta ().NotificationsClient (ctx )
124
-
125
- var state resourceNotificationHubModel
126
- resp .Diagnostics .Append (req .State .Get (ctx , & state )... )
127
- if resp .Diagnostics .HasError () {
98
+ func (r * resourceNotificationHub ) Read (ctx context.Context , request resource.ReadRequest , response * resource.ReadResponse ) {
99
+ var data resourceNotificationHubModel
100
+ response .Diagnostics .Append (request .State .Get (ctx , & data )... )
101
+ if response .Diagnostics .HasError () {
128
102
return
129
103
}
130
104
131
- out , err := findNotificationHubByRegion (ctx , conn , state .Region .ValueString ())
105
+ conn := r .Meta ().NotificationsClient (ctx )
106
+
107
+ _ , err := findNotificationHubByRegion (ctx , conn , data .NotificationHubRegion .ValueString ())
108
+
132
109
if tfresource .NotFound (err ) {
133
- resp .Diagnostics .Append (fwdiag .NewResourceNotFoundWarningDiagnostic (err ))
134
- resp .State .RemoveResource (ctx )
110
+ response .Diagnostics .Append (fwdiag .NewResourceNotFoundWarningDiagnostic (err ))
111
+ response .State .RemoveResource (ctx )
112
+
135
113
return
136
114
}
115
+
137
116
if err != nil {
138
- resp .Diagnostics .AddError (
139
- create .ProblemStandardMessage (names .Notifications , create .ErrActionReading , ResNameNotificationHub , state .Region .String (), err ),
140
- err .Error (),
141
- )
142
- return
143
- }
117
+ response .Diagnostics .AddError (fmt .Sprintf ("reading User Notifications Notification Hub (%s)" , data .NotificationHubRegion .ValueString ()), err .Error ())
144
118
145
- resp .Diagnostics .Append (flex .Flatten (ctx , out , & state )... )
146
- if resp .Diagnostics .HasError () {
147
119
return
148
120
}
149
121
150
- resp .Diagnostics .Append (resp .State .Set (ctx , & state )... )
122
+ response .Diagnostics .Append (response .State .Set (ctx , & data )... )
151
123
}
152
124
153
- func (r * resourceNotificationHub ) Delete (ctx context.Context , req resource.DeleteRequest , resp * resource.DeleteResponse ) {
125
+ func (r * resourceNotificationHub ) Delete (ctx context.Context , request resource.DeleteRequest , response * resource.DeleteResponse ) {
126
+ var data resourceNotificationHubModel
127
+ response .Diagnostics .Append (request .State .Get (ctx , & data )... )
128
+ if response .Diagnostics .HasError () {
129
+ return
130
+ }
131
+
154
132
conn := r .Meta ().NotificationsClient (ctx )
155
133
156
- var state resourceNotificationHubModel
157
- resp .Diagnostics .Append (req .State .Get (ctx , & state )... )
158
- if resp .Diagnostics .HasError () {
134
+ region := fwflex .StringValueFromFramework (ctx , data .NotificationHubRegion )
135
+ input := notifications.DeregisterNotificationHubInput {
136
+ NotificationHubRegion : aws .String (region ),
137
+ }
138
+ _ , err := conn .DeregisterNotificationHub (ctx , & input )
139
+
140
+ if errs.IsA [* awstypes.ResourceNotFoundException ](err ) {
159
141
return
160
142
}
161
143
162
- input := notifications. DeregisterNotificationHubInput {
163
- NotificationHubRegion : state . Region . ValueStringPointer (),
144
+ if errs . IsAErrorMessageContains [ * awstypes. ConflictException ]( err , "Cannot deregister last ACTIVE notification hub" ) {
145
+ return
164
146
}
165
147
166
- _ , err := conn .DeregisterNotificationHub (ctx , & input )
167
148
if err != nil {
168
- if errs.IsA [* awstypes.ResourceNotFoundException ](err ) {
169
- return
170
- }
149
+ response .Diagnostics .AddError (fmt .Sprintf ("deregistering User Notifications Notification Hub (%s)" , region ), err .Error ())
171
150
172
- resp .Diagnostics .AddError (
173
- create .ProblemStandardMessage (names .Notifications , create .ErrActionDeleting , ResNameNotificationHub , state .Region .String (), err ),
174
- err .Error (),
175
- )
176
151
return
177
152
}
178
153
179
- deleteTimeout := r .DeleteTimeout (ctx , state .Timeouts )
180
- _ , err = waitNotificationHubDeleted (ctx , conn , state .Region .ValueString (), deleteTimeout )
181
- if err != nil {
182
- resp .Diagnostics .AddError (
183
- create .ProblemStandardMessage (names .Notifications , create .ErrActionWaitingForDeletion , ResNameNotificationHub , state .Region .String (), err ),
184
- err .Error (),
185
- )
154
+ if _ , err := waitNotificationHubDeleted (ctx , conn , region , r .DeleteTimeout (ctx , data .Timeouts )); err != nil {
155
+ response .Diagnostics .AddError (fmt .Sprintf ("waiting for User Notifications Notification Hub (%s) delete" , region ), err .Error ())
156
+
186
157
return
187
158
}
188
159
}
189
160
190
- func (r * resourceNotificationHub ) ImportState (ctx context.Context , req resource.ImportStateRequest , resp * resource.ImportStateResponse ) {
191
- resource .ImportStatePassthroughID (ctx , path .Root (names . AttrRegion ), req , resp )
161
+ func (r * resourceNotificationHub ) ImportState (ctx context.Context , request resource.ImportStateRequest , response * resource.ImportStateResponse ) {
162
+ resource .ImportStatePassthroughID (ctx , path .Root ("notification_hub_region" ), request , response )
192
163
}
193
164
194
- func waitNotificationHubCreated (ctx context.Context , conn * notifications.Client , id string , timeout time. Duration ) (* awstypes.NotificationHubOverview , error ) {
195
- stateConf := & retry. StateChangeConf {
196
- Pending : enum . Slice ( awstypes .NotificationHubStatusRegistering ),
197
- Target : enum . Slice ( awstypes . NotificationHubStatusActive ),
198
- Refresh : statusNotificationHub ( ctx , conn , id ),
199
- Timeout : timeout ,
200
- NotFoundChecks : 20 ,
201
- ContinuousTargetOccurence : 2 ,
165
+ func findNotificationHubByRegion (ctx context.Context , conn * notifications.Client , region string ) (* awstypes.NotificationHubOverview , error ) {
166
+ var input notifications. ListNotificationHubsInput
167
+ output , err := findNotificationHub ( ctx , conn , & input , func ( v * awstypes.NotificationHubOverview ) bool {
168
+ return aws . ToString ( v . NotificationHubRegion ) == region
169
+ })
170
+
171
+ if err != nil {
172
+ return nil , err
202
173
}
203
174
204
- outputRaw , err := stateConf .WaitForStateContext (ctx )
205
- if out , ok := outputRaw .(* awstypes.NotificationHubOverview ); ok {
206
- return out , err
175
+ if output .StatusSummary == nil {
176
+ return nil , tfresource .NewEmptyResultError (input )
207
177
}
208
178
209
- return nil , err
179
+ return output , nil
210
180
}
211
181
212
- func waitNotificationHubDeleted (ctx context.Context , conn * notifications.Client , id string , timeout time.Duration ) (* awstypes.NotificationHubOverview , error ) {
213
- stateConf := & retry.StateChangeConf {
214
- Pending : enum .Slice (awstypes .NotificationHubStatusDeregistering ),
215
- Target : []string {},
216
- Refresh : statusNotificationHub (ctx , conn , id ),
217
- Timeout : timeout ,
182
+ func findNotificationHub (ctx context.Context , conn * notifications.Client , input * notifications.ListNotificationHubsInput , filter tfslices.Predicate [* awstypes.NotificationHubOverview ]) (* awstypes.NotificationHubOverview , error ) {
183
+ output , err := findNotificationHubs (ctx , conn , input , filter )
184
+
185
+ if err != nil {
186
+ return nil , err
218
187
}
219
188
220
- outputRaw , err := stateConf .WaitForStateContext (ctx )
221
- if out , ok := outputRaw .(* awstypes.NotificationHubOverview ); ok {
222
- return out , err
189
+ return tfresource .AssertSingleValueResult (output )
190
+ }
191
+
192
+ func findNotificationHubs (ctx context.Context , conn * notifications.Client , input * notifications.ListNotificationHubsInput , filter tfslices.Predicate [* awstypes.NotificationHubOverview ]) ([]awstypes.NotificationHubOverview , error ) {
193
+ var output []awstypes.NotificationHubOverview
194
+
195
+ pages := notifications .NewListNotificationHubsPaginator (conn , input )
196
+ for pages .HasMorePages () {
197
+ page , err := pages .NextPage (ctx )
198
+
199
+ if errs.IsA [* awstypes.ResourceNotFoundException ](err ) {
200
+ return nil , & retry.NotFoundError {
201
+ LastError : err ,
202
+ LastRequest : input ,
203
+ }
204
+ }
205
+
206
+ if err != nil {
207
+ return nil , err
208
+ }
209
+
210
+ for _ , v := range page .NotificationHubs {
211
+ if filter (& v ) {
212
+ output = append (output , v )
213
+ }
214
+ }
223
215
}
224
216
225
- return nil , err
217
+ return output , nil
226
218
}
227
219
228
- func statusNotificationHub (ctx context.Context , conn * notifications.Client , id string ) retry.StateRefreshFunc {
220
+ func statusNotificationHub (ctx context.Context , conn * notifications.Client , region string ) retry.StateRefreshFunc {
229
221
return func () (any , string , error ) {
230
- out , err := findNotificationHubByRegion (ctx , conn , id )
222
+ output , err := findNotificationHubByRegion (ctx , conn , region )
223
+
231
224
if tfresource .NotFound (err ) {
232
225
return nil , "" , nil
233
226
}
@@ -236,41 +229,50 @@ func statusNotificationHub(ctx context.Context, conn *notifications.Client, id s
236
229
return nil , "" , err
237
230
}
238
231
239
- return out , string (out .StatusSummary .Status ), nil
232
+ return output , string (output .StatusSummary .Status ), nil
240
233
}
241
234
}
242
235
243
- func findNotificationHubByRegion (ctx context.Context , conn * notifications.Client , region string ) (* awstypes.NotificationHubOverview , error ) {
244
- var input notifications.ListNotificationHubsInput
245
-
246
- out , err := conn .ListNotificationHubs (ctx , & input )
247
- if err != nil {
248
- if errs.IsA [* awstypes.ResourceNotFoundException ](err ) {
249
- return nil , & retry.NotFoundError {
250
- LastError : err ,
251
- LastRequest : & input ,
252
- }
253
- }
254
- return nil , err
236
+ func waitNotificationHubCreated (ctx context.Context , conn * notifications.Client , region string , timeout time.Duration ) (* awstypes.NotificationHubOverview , error ) {
237
+ stateConf := & retry.StateChangeConf {
238
+ Pending : enum .Slice (awstypes .NotificationHubStatusRegistering ),
239
+ Target : enum .Slice (awstypes .NotificationHubStatusActive ),
240
+ Refresh : statusNotificationHub (ctx , conn , region ),
241
+ Timeout : timeout ,
242
+ ContinuousTargetOccurence : 2 ,
255
243
}
256
244
257
- if out == nil || out .NotificationHubs == nil {
258
- return nil , tfresource .NewEmptyResultError (& input )
245
+ outputRaw , err := stateConf .WaitForStateContext (ctx )
246
+
247
+ if output , ok := outputRaw .(* awstypes.NotificationHubOverview ); ok {
248
+ tfresource .SetLastError (err , errors .New (aws .ToString (output .StatusSummary .Reason )))
249
+
250
+ return output , err
259
251
}
260
252
261
- for _ , hub := range out .NotificationHubs {
262
- if aws .ToString (hub .NotificationHubRegion ) == region {
263
- return & hub , nil
264
- }
253
+ return nil , err
254
+ }
255
+
256
+ func waitNotificationHubDeleted (ctx context.Context , conn * notifications.Client , region string , timeout time.Duration ) (* awstypes.NotificationHubOverview , error ) {
257
+ stateConf := & retry.StateChangeConf {
258
+ Pending : enum .Slice (awstypes .NotificationHubStatusDeregistering ),
259
+ Target : []string {},
260
+ Refresh : statusNotificationHub (ctx , conn , region ),
261
+ Timeout : timeout ,
265
262
}
266
263
267
- return nil , & retry.NotFoundError {
268
- LastError : fmt .Errorf ("notification Hub for region %q not found" , region ),
269
- LastRequest : & input ,
264
+ outputRaw , err := stateConf .WaitForStateContext (ctx )
265
+
266
+ if output , ok := outputRaw .(* awstypes.NotificationHubOverview ); ok {
267
+ tfresource .SetLastError (err , errors .New (aws .ToString (output .StatusSummary .Reason )))
268
+
269
+ return output , err
270
270
}
271
+
272
+ return nil , err
271
273
}
272
274
273
275
type resourceNotificationHubModel struct {
274
- Region types.String `tfsdk:"region "`
275
- Timeouts timeouts.Value `tfsdk:"timeouts"`
276
+ NotificationHubRegion types.String `tfsdk:"notification_hub_region "`
277
+ Timeouts timeouts.Value `tfsdk:"timeouts"`
276
278
}
0 commit comments