Skip to content

Commit ac63645

Browse files
Copilottobio
andcommitted
Fix schema to use nested blocks and run acceptance tests successfully
Co-authored-by: tobio <[email protected]>
1 parent 73d4732 commit ac63645

File tree

3 files changed

+86
-73
lines changed

3 files changed

+86
-73
lines changed

internal/elasticsearch/security/role/models.go

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,34 @@ func (data *RoleData) toAPIModel(ctx context.Context) (*models.Role, diag.Diagno
278278
func (data *RoleData) fromAPIModel(ctx context.Context, role *models.Role) diag.Diagnostics {
279279
var diags diag.Diagnostics
280280

281+
// Define attribute type maps
282+
applicationAttrTypes := map[string]attr.Type{
283+
"application": types.StringType,
284+
"privileges": types.SetType{ElemType: types.StringType},
285+
"resources": types.SetType{ElemType: types.StringType},
286+
}
287+
288+
fieldSecurityAttrTypes := map[string]attr.Type{
289+
"grant": types.SetType{ElemType: types.StringType},
290+
"except": types.SetType{ElemType: types.StringType},
291+
}
292+
293+
indexPermsAttrTypes := map[string]attr.Type{
294+
"field_security": types.ListType{ElemType: types.ObjectType{AttrTypes: fieldSecurityAttrTypes}},
295+
"names": types.SetType{ElemType: types.StringType},
296+
"privileges": types.SetType{ElemType: types.StringType},
297+
"query": jsontypes.NormalizedType{},
298+
"allow_restricted_indices": types.BoolType,
299+
}
300+
301+
remoteIndexPermsAttrTypes := map[string]attr.Type{
302+
"clusters": types.SetType{ElemType: types.StringType},
303+
"field_security": types.ListType{ElemType: types.ObjectType{AttrTypes: fieldSecurityAttrTypes}},
304+
"query": jsontypes.NormalizedType{},
305+
"names": types.SetType{ElemType: types.StringType},
306+
"privileges": types.SetType{ElemType: types.StringType},
307+
}
308+
281309
data.Name = types.StringValue(role.Name)
282310

283311
// Description
@@ -299,7 +327,7 @@ func (data *RoleData) fromAPIModel(ctx context.Context, role *models.Role) diag.
299327
return diags
300328
}
301329

302-
appObj, d := types.ObjectValue(getApplicationAttrTypes(), map[string]attr.Value{
330+
appObj, d := types.ObjectValue(applicationAttrTypes, map[string]attr.Value{
303331
"application": types.StringValue(app.Name),
304332
"privileges": privSet,
305333
"resources": resSet,
@@ -312,14 +340,14 @@ func (data *RoleData) fromAPIModel(ctx context.Context, role *models.Role) diag.
312340
appElements[i] = appObj
313341
}
314342

315-
appSet, d := types.SetValue(types.ObjectType{AttrTypes: getApplicationAttrTypes()}, appElements)
343+
appSet, d := types.SetValue(types.ObjectType{AttrTypes: applicationAttrTypes}, appElements)
316344
diags.Append(d...)
317345
if diags.HasError() {
318346
return diags
319347
}
320348
data.Applications = appSet
321349
} else {
322-
data.Applications = types.SetNull(types.ObjectType{AttrTypes: getApplicationAttrTypes()})
350+
data.Applications = types.SetNull(types.ObjectType{AttrTypes: applicationAttrTypes})
323351
}
324352

325353
// Cluster
@@ -369,7 +397,12 @@ func (data *RoleData) fromAPIModel(ctx context.Context, role *models.Role) diag.
369397
queryVal = jsontypes.NewNormalizedNull()
370398
}
371399

372-
allowRestrictedVal := types.BoolPointerValue(index.AllowRestrictedIndices)
400+
var allowRestrictedVal types.Bool
401+
if index.AllowRestrictedIndices != nil {
402+
allowRestrictedVal = types.BoolValue(*index.AllowRestrictedIndices)
403+
} else {
404+
allowRestrictedVal = types.BoolNull()
405+
}
373406

374407
var fieldSecList types.List
375408
if index.FieldSecurity != nil {
@@ -385,7 +418,7 @@ func (data *RoleData) fromAPIModel(ctx context.Context, role *models.Role) diag.
385418
return diags
386419
}
387420

388-
fieldSecObj, d := types.ObjectValue(getFieldSecurityAttrTypes(), map[string]attr.Value{
421+
fieldSecObj, d := types.ObjectValue(fieldSecurityAttrTypes, map[string]attr.Value{
389422
"grant": grantSet,
390423
"except": exceptSet,
391424
})
@@ -394,16 +427,16 @@ func (data *RoleData) fromAPIModel(ctx context.Context, role *models.Role) diag.
394427
return diags
395428
}
396429

397-
fieldSecList, d = types.ListValue(types.ObjectType{AttrTypes: getFieldSecurityAttrTypes()}, []attr.Value{fieldSecObj})
430+
fieldSecList, d = types.ListValue(types.ObjectType{AttrTypes: fieldSecurityAttrTypes}, []attr.Value{fieldSecObj})
398431
diags.Append(d...)
399432
if diags.HasError() {
400433
return diags
401434
}
402435
} else {
403-
fieldSecList = types.ListNull(types.ObjectType{AttrTypes: getFieldSecurityAttrTypes()})
436+
fieldSecList = types.ListNull(types.ObjectType{AttrTypes: fieldSecurityAttrTypes})
404437
}
405438

406-
indexObj, d := types.ObjectValue(getIndexPermsAttrTypes(), map[string]attr.Value{
439+
indexObj, d := types.ObjectValue(indexPermsAttrTypes, map[string]attr.Value{
407440
"field_security": fieldSecList,
408441
"names": namesSet,
409442
"privileges": privSet,
@@ -418,14 +451,14 @@ func (data *RoleData) fromAPIModel(ctx context.Context, role *models.Role) diag.
418451
indicesElements[i] = indexObj
419452
}
420453

421-
indicesSet, d := types.SetValue(types.ObjectType{AttrTypes: getIndexPermsAttrTypes()}, indicesElements)
454+
indicesSet, d := types.SetValue(types.ObjectType{AttrTypes: indexPermsAttrTypes}, indicesElements)
422455
diags.Append(d...)
423456
if diags.HasError() {
424457
return diags
425458
}
426459
data.Indices = indicesSet
427460
} else {
428-
data.Indices = types.SetNull(types.ObjectType{AttrTypes: getIndexPermsAttrTypes()})
461+
data.Indices = types.SetNull(types.ObjectType{AttrTypes: indexPermsAttrTypes})
429462
}
430463

431464
// Remote Indices
@@ -471,7 +504,7 @@ func (data *RoleData) fromAPIModel(ctx context.Context, role *models.Role) diag.
471504
return diags
472505
}
473506

474-
fieldSecObj, d := types.ObjectValue(getFieldSecurityAttrTypes(), map[string]attr.Value{
507+
fieldSecObj, d := types.ObjectValue(fieldSecurityAttrTypes, map[string]attr.Value{
475508
"grant": grantSet,
476509
"except": exceptSet,
477510
})
@@ -480,16 +513,16 @@ func (data *RoleData) fromAPIModel(ctx context.Context, role *models.Role) diag.
480513
return diags
481514
}
482515

483-
fieldSecList, d = types.ListValue(types.ObjectType{AttrTypes: getFieldSecurityAttrTypes()}, []attr.Value{fieldSecObj})
516+
fieldSecList, d = types.ListValue(types.ObjectType{AttrTypes: fieldSecurityAttrTypes}, []attr.Value{fieldSecObj})
484517
diags.Append(d...)
485518
if diags.HasError() {
486519
return diags
487520
}
488521
} else {
489-
fieldSecList = types.ListNull(types.ObjectType{AttrTypes: getFieldSecurityAttrTypes()})
522+
fieldSecList = types.ListNull(types.ObjectType{AttrTypes: fieldSecurityAttrTypes})
490523
}
491524

492-
remoteIndexObj, d := types.ObjectValue(getRemoteIndexPermsAttrTypes(), map[string]attr.Value{
525+
remoteIndexObj, d := types.ObjectValue(remoteIndexPermsAttrTypes, map[string]attr.Value{
493526
"clusters": clustersSet,
494527
"field_security": fieldSecList,
495528
"query": queryVal,
@@ -504,14 +537,14 @@ func (data *RoleData) fromAPIModel(ctx context.Context, role *models.Role) diag.
504537
remoteIndicesElements[i] = remoteIndexObj
505538
}
506539

507-
remoteIndicesSet, d := types.SetValue(types.ObjectType{AttrTypes: getRemoteIndexPermsAttrTypes()}, remoteIndicesElements)
540+
remoteIndicesSet, d := types.SetValue(types.ObjectType{AttrTypes: remoteIndexPermsAttrTypes}, remoteIndicesElements)
508541
diags.Append(d...)
509542
if diags.HasError() {
510543
return diags
511544
}
512545
data.RemoteIndices = remoteIndicesSet
513546
} else {
514-
data.RemoteIndices = types.SetNull(types.ObjectType{AttrTypes: getRemoteIndexPermsAttrTypes()})
547+
data.RemoteIndices = types.SetNull(types.ObjectType{AttrTypes: remoteIndexPermsAttrTypes})
515548
}
516549

517550
// Metadata

internal/elasticsearch/security/role/read.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/elastic/terraform-provider-elasticstack/internal/clients/elasticsearch"
99
"github.com/elastic/terraform-provider-elasticstack/internal/diagutil"
1010
"github.com/hashicorp/terraform-plugin-framework/resource"
11+
"github.com/hashicorp/terraform-plugin-framework/types"
1112
"github.com/hashicorp/terraform-plugin-log/tflog"
1213
)
1314

@@ -49,5 +50,8 @@ func (r *roleResource) Read(ctx context.Context, req resource.ReadRequest, resp
4950
return
5051
}
5152

53+
// Set the name to the roleId we extracted to ensure consistency
54+
data.Name = types.StringValue(roleId)
55+
5256
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
5357
}

internal/elasticsearch/security/role/schema.go

Lines changed: 33 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@ import (
55
_ "embed"
66

77
"github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes"
8-
"github.com/hashicorp/terraform-plugin-framework/attr"
98
"github.com/hashicorp/terraform-plugin-framework/resource"
109
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
11-
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
1210
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
1311
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
1412
"github.com/hashicorp/terraform-plugin-framework/types"
@@ -28,27 +26,9 @@ func GetSchema() schema.Schema {
2826
MarkdownDescription: roleResourceDescription,
2927
Blocks: map[string]schema.Block{
3028
"elasticsearch_connection": providerschema.GetEsFWConnectionBlock("elasticsearch_connection", false),
31-
},
32-
Attributes: map[string]schema.Attribute{
33-
"id": schema.StringAttribute{
34-
MarkdownDescription: "Internal identifier of the resource",
35-
Computed: true,
36-
},
37-
"name": schema.StringAttribute{
38-
MarkdownDescription: "The name of the role.",
39-
Required: true,
40-
PlanModifiers: []planmodifier.String{
41-
stringplanmodifier.RequiresReplace(),
42-
},
43-
},
44-
"description": schema.StringAttribute{
45-
MarkdownDescription: "The description of the role.",
46-
Optional: true,
47-
},
48-
"applications": schema.SetNestedAttribute{
29+
"applications": schema.SetNestedBlock{
4930
MarkdownDescription: "A list of application privilege entries.",
50-
Optional: true,
51-
NestedObject: schema.NestedAttributeObject{
31+
NestedObject: schema.NestedBlockObject{
5232
Attributes: map[string]schema.Attribute{
5333
"application": schema.StringAttribute{
5434
MarkdownDescription: "The name of the application to which this entry applies.",
@@ -67,20 +47,9 @@ func GetSchema() schema.Schema {
6747
},
6848
},
6949
},
70-
"global": schema.StringAttribute{
71-
MarkdownDescription: "An object defining global privileges.",
72-
Optional: true,
73-
CustomType: jsontypes.NormalizedType{},
74-
},
75-
"cluster": schema.SetAttribute{
76-
MarkdownDescription: "A list of cluster privileges. These privileges define the cluster level actions that users with this role are able to execute.",
77-
Optional: true,
78-
ElementType: types.StringType,
79-
},
80-
"indices": schema.SetNestedAttribute{
50+
"indices": schema.SetNestedBlock{
8151
MarkdownDescription: "A list of indices permissions entries.",
82-
Optional: true,
83-
NestedObject: schema.NestedAttributeObject{
52+
NestedObject: schema.NestedBlockObject{
8453
Attributes: map[string]schema.Attribute{
8554
"field_security": schema.ListNestedAttribute{
8655
MarkdownDescription: "The document fields that the owners of the role have read access to.",
@@ -118,16 +87,13 @@ func GetSchema() schema.Schema {
11887
"allow_restricted_indices": schema.BoolAttribute{
11988
MarkdownDescription: "Include matching restricted indices in names parameter. Usage is strongly discouraged as it can grant unrestricted operations on critical data, make the entire system unstable or leak sensitive information.",
12089
Optional: true,
121-
Computed: true,
122-
Default: booldefault.StaticBool(false),
12390
},
12491
},
12592
},
12693
},
127-
"remote_indices": schema.SetNestedAttribute{
94+
"remote_indices": schema.SetNestedBlock{
12895
MarkdownDescription: "A list of remote indices permissions entries. Remote indices are effective for remote clusters configured with the API key based model. They have no effect for remote clusters configured with the certificate based model.",
129-
Optional: true,
130-
NestedObject: schema.NestedAttributeObject{
96+
NestedObject: schema.NestedBlockObject{
13197
Attributes: map[string]schema.Attribute{
13298
"clusters": schema.SetAttribute{
13399
MarkdownDescription: "A list of cluster aliases to which the permissions in this entry apply.",
@@ -170,6 +136,33 @@ func GetSchema() schema.Schema {
170136
},
171137
},
172138
},
139+
},
140+
Attributes: map[string]schema.Attribute{
141+
"id": schema.StringAttribute{
142+
MarkdownDescription: "Internal identifier of the resource",
143+
Computed: true,
144+
},
145+
"name": schema.StringAttribute{
146+
MarkdownDescription: "The name of the role.",
147+
Required: true,
148+
PlanModifiers: []planmodifier.String{
149+
stringplanmodifier.RequiresReplace(),
150+
},
151+
},
152+
"description": schema.StringAttribute{
153+
MarkdownDescription: "The description of the role.",
154+
Optional: true,
155+
},
156+
"global": schema.StringAttribute{
157+
MarkdownDescription: "An object defining global privileges.",
158+
Optional: true,
159+
CustomType: jsontypes.NormalizedType{},
160+
},
161+
"cluster": schema.SetAttribute{
162+
MarkdownDescription: "A list of cluster privileges. These privileges define the cluster level actions that users with this role are able to execute.",
163+
Optional: true,
164+
ElementType: types.StringType,
165+
},
173166
"metadata": schema.StringAttribute{
174167
MarkdownDescription: "Optional meta-data.",
175168
Optional: true,
@@ -184,20 +177,3 @@ func GetSchema() schema.Schema {
184177
},
185178
}
186179
}
187-
188-
// Helper functions to get attribute types from schema
189-
func getApplicationAttrTypes() map[string]attr.Type {
190-
return GetSchema().Attributes["applications"].GetType().(attr.TypeWithElementType).ElementType().(attr.TypeWithAttributeTypes).AttributeTypes()
191-
}
192-
193-
func getIndexPermsAttrTypes() map[string]attr.Type {
194-
return GetSchema().Attributes["indices"].GetType().(attr.TypeWithElementType).ElementType().(attr.TypeWithAttributeTypes).AttributeTypes()
195-
}
196-
197-
func getFieldSecurityAttrTypes() map[string]attr.Type {
198-
return getIndexPermsAttrTypes()["field_security"].(attr.TypeWithElementType).ElementType().(attr.TypeWithAttributeTypes).AttributeTypes()
199-
}
200-
201-
func getRemoteIndexPermsAttrTypes() map[string]attr.Type {
202-
return GetSchema().Attributes["remote_indices"].GetType().(attr.TypeWithElementType).ElementType().(attr.TypeWithAttributeTypes).AttributeTypes()
203-
}

0 commit comments

Comments
 (0)