Skip to content

Commit c11fdca

Browse files
committed
fix: source location recreation on access control update
OTT-6361
1 parent 42dfef6 commit c11fdca

File tree

3 files changed

+100
-89
lines changed

3 files changed

+100
-89
lines changed

awsmt/helpers_source_location.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package awsmt
22

33
import (
44
"context"
5+
"fmt"
56
"github.com/aws/aws-sdk-go-v2/service/mediatailor"
67
awsTypes "github.com/aws/aws-sdk-go-v2/service/mediatailor/types"
78
"github.com/hashicorp/terraform-plugin-framework/types"
@@ -173,17 +174,17 @@ func readSourceLocationComputedValues(model sourceLocationModel, sourceLocation
173174
return model
174175
}
175176

176-
func readAccessConfiguration(model sourceLocationModel, sourceLocation mediatailor.CreateSourceLocationOutput, isResouce bool) sourceLocationModel {
177+
func readAccessConfiguration(model sourceLocationModel, sourceLocation mediatailor.CreateSourceLocationOutput, isResource bool) sourceLocationModel {
177178
if sourceLocation.AccessConfiguration == nil {
178179
return model
179180
}
180-
if model.AccessConfiguration == nil && isResouce {
181+
if model.AccessConfiguration == nil && isResource {
181182
return model
182183
}
183184

184185
model.AccessConfiguration = &accessConfigurationModel{}
185186

186-
if !(isResouce && model.AccessConfiguration.AccessType == nil) {
187+
if !(isResource && model.AccessConfiguration == nil) {
187188
accessType := string(sourceLocation.AccessConfiguration.AccessType)
188189
model.AccessConfiguration.AccessType = &accessType
189190
}
@@ -286,3 +287,18 @@ func deleteSourceLocation(client *mediatailor.Client, name *string) error {
286287

287288
return nil
288289
}
290+
291+
func recreateSourceLocation(client *mediatailor.Client, plan sourceLocationModel) (*sourceLocationModel, error) {
292+
err := deleteSourceLocation(client, plan.Name)
293+
if err != nil {
294+
return nil, err
295+
}
296+
297+
params := getCreateSourceLocationInput(plan)
298+
sourceLocation, err := client.CreateSourceLocation(context.TODO(), &params)
299+
if err != nil {
300+
return nil, fmt.Errorf("Error while creating new source location with new access configuration " + err.Error())
301+
}
302+
model := writeSourceLocationToPlan(plan, *sourceLocation, true)
303+
return &model, nil
304+
}

awsmt/resource_source_location.go

Lines changed: 27 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,14 @@ func (r *resourceSourceLocation) Read(ctx context.Context, req resource.ReadRequ
143143
}
144144

145145
func (r *resourceSourceLocation) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
146-
var plan sourceLocationModel
147-
diags := req.Plan.Get(ctx, &plan)
148-
resp.Diagnostics.Append(diags...)
146+
var currentState, plan sourceLocationModel
147+
148+
resp.Diagnostics.Append(req.State.Get(ctx, &currentState)...)
149+
if resp.Diagnostics.HasError() {
150+
return
151+
}
152+
153+
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
149154
if resp.Diagnostics.HasError() {
150155
return
151156
}
@@ -158,117 +163,54 @@ func (r *resourceSourceLocation) Update(ctx context.Context, req resource.Update
158163
return
159164
}
160165

161-
oldTags := sourceLocation.Tags
162-
newTags := plan.Tags
163-
164-
// Check if tags are different
165-
if !reflect.DeepEqual(oldTags, newTags) {
166-
err = V2UpdatesTags(r.client, oldTags, newTags, *sourceLocation.Arn)
167-
if err != nil {
168-
resp.Diagnostics.AddError(
169-
"Error while updating playback configuration tags"+err.Error(),
170-
err.Error(),
171-
)
172-
}
166+
err = V2UpdatesTags(r.client, sourceLocation.Tags, plan.Tags, *sourceLocation.Arn)
167+
if err != nil {
168+
resp.Diagnostics.AddError(
169+
"Error while updating playback configuration tags"+err.Error(),
170+
err.Error(),
171+
)
173172
}
174173

175-
if !reflect.DeepEqual(sourceLocation.AccessConfiguration, plan.AccessConfiguration) {
176-
// delete source location
177-
name := plan.Name
178-
err := deleteSourceLocation(r.client, name)
174+
if !reflect.DeepEqual(currentState.AccessConfiguration, plan.AccessConfiguration) {
175+
updatedSourceLocation, err := recreateSourceLocation(r.client, plan)
179176
if err != nil {
180-
resp.Diagnostics.AddError(
181-
"Error while deleting source location "+err.Error(),
182-
err.Error(),
183-
)
177+
resp.Diagnostics.AddError("Error while recreating source location "+err.Error(), err.Error())
184178
return
185179
}
180+
plan = *updatedSourceLocation
186181

187-
// create source location
188-
params := getCreateSourceLocationInput(plan)
189-
sourceLocation, err := r.client.CreateSourceLocation(ctx, &params)
182+
} else {
183+
params := getUpdateSourceLocationInput(plan)
184+
sourceLocationUpdated, err := r.client.UpdateSourceLocation(ctx, &params)
190185
if err != nil {
191186
resp.Diagnostics.AddError(
192-
"Error while creating new source location with new access configuration "+err.Error(),
187+
"Error updating source location. "+err.Error(),
193188
err.Error(),
194189
)
195190
return
196191
}
197-
198-
plan = writeSourceLocationToPlan(plan, *sourceLocation, true)
192+
plan = writeSourceLocationToPlan(plan, mediatailor.CreateSourceLocationOutput(*sourceLocationUpdated), true)
199193
}
200194

201-
params := getUpdateSourceLocationInput(plan)
202-
203-
sourceLocationUpdated, err := r.client.UpdateSourceLocation(ctx, &params)
204-
if err != nil {
205-
resp.Diagnostics.AddError(
206-
"Error updating source location "+err.Error(),
207-
err.Error(),
208-
)
209-
return
210-
}
211-
212-
plan = writeSourceLocationToPlan(plan, mediatailor.CreateSourceLocationOutput(*sourceLocationUpdated), true)
213-
214-
diags = resp.State.Set(ctx, plan)
215-
resp.Diagnostics.Append(diags...)
195+
resp.Diagnostics.Append(resp.State.Set(ctx, plan)...)
216196
if resp.Diagnostics.HasError() {
217197
return
218198
}
219199
}
220200

221201
func (r *resourceSourceLocation) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
222202
var state sourceLocationModel
223-
diags := req.State.Get(ctx, &state)
224-
resp.Diagnostics.Append(diags...)
203+
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
225204
if resp.Diagnostics.HasError() {
226205
return
227206
}
228207

229208
name := state.Name
230209

231-
vodSourcesList, err := r.client.ListVodSources(ctx, &mediatailor.ListVodSourcesInput{SourceLocationName: name})
232-
if err != nil {
233-
resp.Diagnostics.AddError(
234-
"Error retrieving vod sources "+err.Error(),
235-
err.Error(),
236-
)
237-
return
238-
}
239-
for _, vodSource := range vodSourcesList.Items {
240-
_, err := r.client.DeleteVodSource(ctx, &mediatailor.DeleteVodSourceInput{SourceLocationName: name, VodSourceName: vodSource.VodSourceName})
241-
if err != nil {
242-
resp.Diagnostics.AddError(
243-
"Error deleting vod sources "+err.Error(),
244-
err.Error(),
245-
)
246-
return
247-
}
248-
}
249-
250-
liveSourcesList, err := r.client.ListLiveSources(ctx, &mediatailor.ListLiveSourcesInput{SourceLocationName: name})
251-
if err != nil {
252-
resp.Diagnostics.AddError(
253-
"Error retrieving live sources "+err.Error(),
254-
err.Error(),
255-
)
256-
return
257-
}
258-
for _, liveSource := range liveSourcesList.Items {
259-
if _, err := r.client.DeleteLiveSource(ctx, &mediatailor.DeleteLiveSourceInput{LiveSourceName: liveSource.LiveSourceName, SourceLocationName: name}); err != nil {
260-
resp.Diagnostics.AddError(
261-
"Error deleting live sources "+err.Error(),
262-
err.Error(),
263-
)
264-
return
265-
}
266-
}
267-
268-
_, err = r.client.DeleteSourceLocation(ctx, &mediatailor.DeleteSourceLocationInput{SourceLocationName: name})
210+
err := deleteSourceLocation(r.client, name)
269211
if err != nil {
270212
resp.Diagnostics.AddError(
271-
"Error deleting resource "+err.Error(),
213+
"Error while deleting source location",
272214
err.Error(),
273215
)
274216
return

awsmt/resource_source_location_test.go

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"testing"
88
)
99

10-
func TestAccSourceLocationResource(t *testing.T) {
10+
func TestAccSourceLocationResourceBasic(t *testing.T) {
1111
resourceName := "awsmt_source_location.test_source_location"
1212
name := "test_source_location"
1313
baseUrl := "https://ott-mediatailor-test.s3.eu-central-1.amazonaws.com"
@@ -48,7 +48,59 @@ func TestAccSourceLocationResource(t *testing.T) {
4848
Config: basicSourceLocation(name, baseUrl2, k3, v3, k2, v2),
4949
Check: resource.ComposeAggregateTestCheckFunc(
5050
resource.TestCheckResourceAttr(resourceName, "id", "test_source_location"),
51+
resource.TestMatchResourceAttr(resourceName, "arn", regexp.MustCompile(`^arn:aws:mediatailor:[\w-]+:\d+:sourceLocation\/.*$`)),
52+
resource.TestMatchResourceAttr(resourceName, "creation_time", regexp.MustCompile(`^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(\.\d{1,3})? \+\d{4} \w+$`)),
53+
resource.TestCheckResourceAttr(resourceName, "default_segment_delivery_configuration.base_url", baseUrl2),
54+
resource.TestMatchResourceAttr(resourceName, "last_modified_time", regexp.MustCompile(`^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(\.\d{1,3})? \+\d{4} \w+$`)),
55+
resource.TestCheckResourceAttr(resourceName, "segment_delivery_configurations.0.base_url", baseUrl2),
5156
resource.TestCheckResourceAttr(resourceName, "name", "test_source_location"),
57+
resource.TestCheckResourceAttr(resourceName, "tags.Testing", "pass"),
58+
resource.TestCheckResourceAttr(resourceName, "tags.Environment", "prod"),
59+
),
60+
},
61+
// Delete testing automatically occurs in TestCase
62+
},
63+
})
64+
}
65+
66+
func TestAccSourceLocationResourceUpdateAccessControl(t *testing.T) {
67+
resourceName := "awsmt_source_location.test_source_location"
68+
name := "test_source_location"
69+
baseUrl := "https://ott-mediatailor-test.s3.eu-central-1.amazonaws.com"
70+
baseUrl2 := "https://example.com/"
71+
k1 := "Environment"
72+
v1 := "dev"
73+
k2 := "Testing"
74+
v2 := "pass"
75+
k3 := "Environment"
76+
v3 := "prod"
77+
resource.Test(t, resource.TestCase{
78+
PreCheck: func() { testAccPreCheck(t) },
79+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
80+
Steps: []resource.TestStep{
81+
// Create and Read testing
82+
{
83+
Config: basicSourceLocation(name, baseUrl, k1, v1, k2, v2),
84+
Check: resource.ComposeAggregateTestCheckFunc(
85+
resource.TestCheckResourceAttr(resourceName, "id", "test_source_location"),
86+
resource.TestMatchResourceAttr(resourceName, "arn", regexp.MustCompile(`^arn:aws:mediatailor:[\w-]+:\d+:sourceLocation\/.*$`)),
87+
resource.TestMatchResourceAttr(resourceName, "creation_time", regexp.MustCompile(`^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(\.\d{1,3})? \+\d{4} \w+$`)),
88+
resource.TestCheckResourceAttr(resourceName, "default_segment_delivery_configuration.base_url", "https://ott-mediatailor-test.s3.eu-central-1.amazonaws.com"),
89+
resource.TestCheckResourceAttr(resourceName, "http_configuration.base_url", "https://ott-mediatailor-test.s3.eu-central-1.amazonaws.com"),
90+
resource.TestMatchResourceAttr(resourceName, "last_modified_time", regexp.MustCompile(`^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(\.\d{1,3})? \+\d{4} \w+$`)),
91+
resource.TestCheckResourceAttr(resourceName, "segment_delivery_configurations.0.base_url", "https://ott-mediatailor-test.s3.eu-central-1.amazonaws.com"),
92+
resource.TestCheckResourceAttr(resourceName, "name", "test_source_location"),
93+
resource.TestCheckResourceAttr(resourceName, "tags.Testing", "pass"),
94+
resource.TestCheckResourceAttr(resourceName, "tags.Environment", "dev"),
95+
),
96+
},
97+
// Update and Read testing
98+
{
99+
Config: basicSourceLocationWithAccessConfig(name, baseUrl2, k3, v3, k2, v2),
100+
Check: resource.ComposeAggregateTestCheckFunc(
101+
resource.TestCheckResourceAttr(resourceName, "id", "test_source_location"),
102+
resource.TestCheckResourceAttr(resourceName, "name", "test_source_location"),
103+
resource.TestCheckResourceAttr(resourceName, "access_configuration.access_type", "S3_SIGV4"),
52104
resource.TestCheckResourceAttr(resourceName, "http_configuration.base_url", "https://ott-mediatailor-test.s3.eu-central-1.amazonaws.com"),
53105
resource.TestCheckResourceAttr(resourceName, "default_segment_delivery_configuration.base_url", "https://example.com/"),
54106
resource.TestCheckResourceAttr(resourceName, "segment_delivery_configurations.0.base_url", "https://example.com/"),
@@ -59,6 +111,7 @@ func TestAccSourceLocationResource(t *testing.T) {
59111
},
60112
})
61113
}
114+
62115
func TestAccSourceLocationDeleteVodResource(t *testing.T) {
63116
resourceName := "awsmt_source_location.test_source_location"
64117
resource.Test(t, resource.TestCase{

0 commit comments

Comments
 (0)