Skip to content

Commit 72d079c

Browse files
author
Matheus Politano
committed
small fix and add datasource
1 parent cf6f255 commit 72d079c

File tree

3 files changed

+213
-5
lines changed

3 files changed

+213
-5
lines changed

stackit/internal/services/cdn/distribution/datasource.go

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ var dataSourceConfigTypes = map[string]attr.Type{
3838
"optimizer": types.ObjectType{
3939
AttrTypes: optimizerTypes, // Shared from resource.go
4040
},
41+
"redirects": types.ObjectType{
42+
AttrTypes: redirectsTypes, // Shared from resource.go
43+
},
4144
}
4245

4346
type distributionDataSource struct {
@@ -199,6 +202,57 @@ func (r *distributionDataSource) Schema(_ context.Context, _ datasource.SchemaRe
199202
},
200203
},
201204
},
205+
"redirects": schema.SingleNestedAttribute{
206+
Computed: true,
207+
Description: schemaDescriptions["config_redirects"],
208+
Attributes: map[string]schema.Attribute{
209+
"rules": schema.ListNestedAttribute{
210+
Description: schemaDescriptions["config_redirects_rules"],
211+
Computed: true,
212+
NestedObject: schema.NestedAttributeObject{
213+
Attributes: map[string]schema.Attribute{
214+
"description": schema.StringAttribute{
215+
Description: schemaDescriptions["config_redirects_rule_description"],
216+
Computed: true,
217+
},
218+
"enabled": schema.BoolAttribute{
219+
Computed: true,
220+
Description: schemaDescriptions["config_redirects_rule_enabled"],
221+
},
222+
"target_url": schema.StringAttribute{
223+
Computed: true,
224+
Description: schemaDescriptions["config_redirects_rule_target_url"],
225+
},
226+
"status_code": schema.Int32Attribute{
227+
Computed: true,
228+
Description: schemaDescriptions["config_redirects_rule_status_code"],
229+
},
230+
"rule_match_condition": schema.StringAttribute{
231+
Computed: true,
232+
Description: schemaDescriptions["config_redirects_rule_match_condition"],
233+
},
234+
"matchers": schema.ListNestedAttribute{
235+
Description: schemaDescriptions["config_redirects_rule_matchers"],
236+
Computed: true,
237+
NestedObject: schema.NestedAttributeObject{
238+
Attributes: map[string]schema.Attribute{
239+
"values": schema.ListAttribute{
240+
Description: schemaDescriptions["config_redirects_rule_matcher_values"],
241+
Computed: true,
242+
ElementType: types.StringType,
243+
},
244+
"value_match_condition": schema.StringAttribute{
245+
Description: schemaDescriptions["config_redirects_rule_match_condition"],
246+
Computed: true,
247+
},
248+
},
249+
},
250+
},
251+
},
252+
},
253+
},
254+
},
255+
},
202256
},
203257
},
204258
},
@@ -300,6 +354,99 @@ func mapDataSourceFields(ctx context.Context, distribution *cdn.Distribution, mo
300354
return core.DiagsToError(diags)
301355
}
302356

357+
// redirects
358+
redirectsVal := types.ObjectNull(redirectsTypes)
359+
if distribution.Config != nil && distribution.Config.Redirects != nil && distribution.Config.Redirects.Rules != nil {
360+
var tfRules []attr.Value
361+
for _, r := range *distribution.Config.Redirects.Rules {
362+
var tfMatchers []attr.Value
363+
if r.Matchers != nil {
364+
for _, m := range *r.Matchers {
365+
var tfValues []attr.Value
366+
if m.Values != nil {
367+
for _, v := range *m.Values {
368+
tfValues = append(tfValues, types.StringValue(v))
369+
}
370+
}
371+
tfValuesList, diags := types.ListValue(types.StringType, tfValues)
372+
if diags.HasError() {
373+
return core.DiagsToError(diags)
374+
}
375+
376+
tfValMatchCond := types.StringNull()
377+
if m.ValueMatchCondition != nil {
378+
tfValMatchCond = types.StringValue(string(*m.ValueMatchCondition))
379+
}
380+
381+
tfMatcherObj, diags := types.ObjectValue(matcherTypes, map[string]attr.Value{
382+
"values": tfValuesList,
383+
"value_match_condition": tfValMatchCond,
384+
})
385+
if diags.HasError() {
386+
return core.DiagsToError(diags)
387+
}
388+
tfMatchers = append(tfMatchers, tfMatcherObj)
389+
}
390+
}
391+
392+
tfMatchersList, diags := types.ListValue(types.ObjectType{AttrTypes: matcherTypes}, tfMatchers)
393+
if diags.HasError() {
394+
return core.DiagsToError(diags)
395+
}
396+
397+
tfDesc := types.StringNull()
398+
if r.Description != nil {
399+
tfDesc = types.StringValue(*r.Description)
400+
}
401+
402+
tfEnabled := types.BoolNull()
403+
if r.Enabled != nil {
404+
tfEnabled = types.BoolValue(*r.Enabled)
405+
}
406+
407+
tfTargetUrl := types.StringNull()
408+
if r.TargetUrl != nil {
409+
tfTargetUrl = types.StringValue(*r.TargetUrl)
410+
}
411+
412+
tfStatusCode := types.Int32Null()
413+
if r.StatusCode != nil {
414+
tfStatusCode = types.Int32Value(int32(*r.StatusCode))
415+
}
416+
417+
tfRuleMatchCond := types.StringNull()
418+
if r.RuleMatchCondition != nil {
419+
tfRuleMatchCond = types.StringValue(string(*r.RuleMatchCondition))
420+
}
421+
422+
tfRuleObj, diags := types.ObjectValue(redirectRuleTypes, map[string]attr.Value{
423+
"description": tfDesc,
424+
"enabled": tfEnabled,
425+
"target_url": tfTargetUrl,
426+
"status_code": tfStatusCode,
427+
"rule_match_condition": tfRuleMatchCond,
428+
"matchers": tfMatchersList,
429+
})
430+
if diags.HasError() {
431+
return core.DiagsToError(diags)
432+
}
433+
tfRules = append(tfRules, tfRuleObj)
434+
}
435+
436+
tfRulesList, diags := types.ListValue(types.ObjectType{AttrTypes: redirectRuleTypes}, tfRules)
437+
if diags.HasError() {
438+
return core.DiagsToError(diags)
439+
}
440+
441+
var objDiags diag.Diagnostics
442+
redirectsVal, objDiags = types.ObjectValue(redirectsTypes, map[string]attr.Value{
443+
"rules": tfRulesList,
444+
})
445+
if objDiags.HasError() {
446+
return core.DiagsToError(objDiags)
447+
}
448+
}
449+
303450
// Prepare Backend Values
304451
var backendValues map[string]attr.Value
305452
originRequestHeaders := types.MapNull(types.StringType)
@@ -383,6 +530,7 @@ func mapDataSourceFields(ctx context.Context, distribution *cdn.Distribution, mo
383530
"regions": modelRegions,
384531
"blocked_countries": modelBlockedCountries,
385532
"optimizer": optimizerVal,
533+
"redirects": redirectsVal,
386534
})
387535
if diags.HasError() {
388536
return core.DiagsToError(diags)

stackit/internal/services/cdn/distribution/datasource_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/google/go-cmp/cmp"
99
"github.com/hashicorp/terraform-plugin-framework/attr"
1010
"github.com/hashicorp/terraform-plugin-framework/types"
11+
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
1112
"github.com/stackitcloud/stackit-sdk-go/services/cdn"
1213
)
1314

@@ -39,13 +40,53 @@ func TestMapDataSourceFields(t *testing.T) {
3940
optimizer := types.ObjectValueMust(optimizerTypes, map[string]attr.Value{
4041
"enabled": types.BoolValue(true),
4142
})
43+
redirectsAttrTypes := configTypes["redirects"].(basetypes.ObjectType).AttrTypes
4244
config := types.ObjectValueMust(dataSourceConfigTypes, map[string]attr.Value{
4345
"backend": backend,
4446
"regions": regionsFixture,
4547
"blocked_countries": blockedCountriesFixture,
4648
"optimizer": types.ObjectNull(optimizerTypes),
49+
"redirects": types.ObjectNull(redirectsAttrTypes),
4750
})
51+
redirectsInput := &cdn.RedirectConfig{
52+
Rules: &[]cdn.RedirectRule{
53+
{
54+
Description: cdn.PtrString("Test redirect"),
55+
Enabled: cdn.PtrBool(true),
56+
TargetUrl: cdn.PtrString("https://example.com/redirect"),
57+
StatusCode: cdn.RedirectRuleStatusCode(301).Ptr(),
58+
RuleMatchCondition: cdn.MatchCondition("ANY").Ptr(),
59+
Matchers: &[]cdn.Matcher{
60+
{
61+
Values: &[]string{"/shop/*"},
62+
ValueMatchCondition: cdn.MatchCondition("ANY").Ptr(),
63+
},
64+
},
65+
},
66+
},
67+
}
68+
matcherValuesExpected := types.ListValueMust(types.StringType, []attr.Value{
69+
types.StringValue("/shop/*"),
70+
})
71+
matcherValExpected := types.ObjectValueMust(matcherTypes, map[string]attr.Value{
72+
"values": matcherValuesExpected,
73+
"value_match_condition": types.StringValue("ANY"),
74+
})
75+
matchersListExpected := types.ListValueMust(types.ObjectType{AttrTypes: matcherTypes}, []attr.Value{matcherValExpected})
76+
77+
ruleValExpected := types.ObjectValueMust(redirectRuleTypes, map[string]attr.Value{
78+
"description": types.StringValue("Test redirect"),
79+
"enabled": types.BoolValue(true),
80+
"target_url": types.StringValue("https://example.com/redirect"),
81+
"status_code": types.Int32Value(301),
82+
"rule_match_condition": types.StringValue("ANY"),
83+
"matchers": matchersListExpected,
84+
})
85+
rulesListExpected := types.ListValueMust(types.ObjectType{AttrTypes: redirectRuleTypes}, []attr.Value{ruleValExpected})
4886

87+
redirectsConfigExpected := types.ObjectValueMust(redirectsTypes, map[string]attr.Value{
88+
"rules": rulesListExpected,
89+
})
4990
emtpyErrorsList := types.ListValueMust(types.StringType, []attr.Value{})
5091
managedDomain := types.ObjectValueMust(domainTypes, map[string]attr.Value{
5192
"name": types.StringValue("test.stackit-cdn.com"),
@@ -132,6 +173,7 @@ func TestMapDataSourceFields(t *testing.T) {
132173
"regions": regionsFixture,
133174
"optimizer": optimizer,
134175
"blocked_countries": blockedCountriesFixture,
176+
"redirects": types.ObjectNull(redirectsAttrTypes),
135177
})
136178
}),
137179
Input: distributionFixture(func(d *cdn.Distribution) {
@@ -157,6 +199,7 @@ func TestMapDataSourceFields(t *testing.T) {
157199
"regions": regionsFixture,
158200
"blocked_countries": blockedCountriesFixture,
159201
"optimizer": types.ObjectNull(optimizerTypes),
202+
"redirects": types.ObjectNull(redirectsAttrTypes),
160203
})
161204
}),
162205
IsValid: true,
@@ -176,6 +219,7 @@ func TestMapDataSourceFields(t *testing.T) {
176219
"regions": regionsFixture,
177220
"optimizer": types.ObjectNull(optimizerTypes),
178221
"blocked_countries": blockedCountriesFixture,
222+
"redirects": types.ObjectNull(redirectsAttrTypes),
179223
})
180224
}),
181225
Input: distributionFixture(func(d *cdn.Distribution) {
@@ -192,6 +236,21 @@ func TestMapDataSourceFields(t *testing.T) {
192236
}),
193237
IsValid: true,
194238
},
239+
"happy_path_with_redirects": {
240+
Expected: expectedModel(func(m *Model) {
241+
m.Config = types.ObjectValueMust(dataSourceConfigTypes, map[string]attr.Value{
242+
"backend": backend,
243+
"regions": regionsFixture,
244+
"optimizer": types.ObjectNull(optimizerTypes),
245+
"blocked_countries": blockedCountriesFixture,
246+
"redirects": redirectsConfigExpected,
247+
})
248+
}),
249+
Input: distributionFixture(func(d *cdn.Distribution) {
250+
d.Config.Redirects = redirectsInput
251+
}),
252+
IsValid: true,
253+
},
195254
"happy_path_custom_domain": {
196255
Expected: expectedModel(func(m *Model) {
197256
managedDomain := types.ObjectValueMust(domainTypes, map[string]attr.Value{

stackit/internal/services/cdn/distribution/resource.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ func (r *distributionResource) Schema(_ context.Context, _ resource.SchemaReques
331331
},
332332
},
333333
"redirects": schema.SingleNestedAttribute{
334-
Required: true,
334+
Optional: true,
335335
Description: schemaDescriptions["config_redirects"],
336336
Attributes: map[string]schema.Attribute{
337337
"rules": schema.ListNestedAttribute{
@@ -352,16 +352,16 @@ func (r *distributionResource) Schema(_ context.Context, _ resource.SchemaReques
352352
Description: schemaDescriptions["config_redirects_rule_enabled"],
353353
Default: booldefault.StaticBool(true),
354354
},
355-
"targetUrl": schema.StringAttribute{
355+
"target_url": schema.StringAttribute{
356356
Required: true,
357357
Description: schemaDescriptions["config_redirects_rule_target_url"],
358358
},
359-
"statusCode": schema.Int32Attribute{
359+
"status_code": schema.Int32Attribute{
360360
Required: true,
361361
Description: schemaDescriptions["config_redirects_rule_status_code"],
362362
Validators: []validator.Int32{int32validator.OneOf(statusCode...)},
363363
},
364-
"ruleMatchCondition": schema.StringAttribute{
364+
"rule_match_condition": schema.StringAttribute{
365365
Optional: true,
366366
Computed: true,
367367
Description: schemaDescriptions["config_redirects_rule_match_condition"],
@@ -379,11 +379,12 @@ func (r *distributionResource) Schema(_ context.Context, _ resource.SchemaReques
379379
"values": schema.ListAttribute{
380380
Description: schemaDescriptions["config_redirects_rule_matcher_values"],
381381
Required: true,
382+
ElementType: types.StringType,
382383
Validators: []validator.List{
383384
listvalidator.SizeAtLeast(1),
384385
},
385386
},
386-
"ruleMatchCondition": schema.StringAttribute{
387+
"value_match_condition": schema.StringAttribute{
387388
Optional: true,
388389
Description: schemaDescriptions["config_redirects_rule_match_condition"],
389390
Default: stringdefault.StaticString("ANY"),

0 commit comments

Comments
 (0)