Skip to content

Commit a3dc57b

Browse files
authored
Add security list item (#1492)
1 parent 04fcf34 commit a3dc57b

File tree

27 files changed

+1035
-48
lines changed

27 files changed

+1035
-48
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# First create a security list
2+
resource "elasticstack_kibana_security_list" "my_list" {
3+
list_id = "allowed_domains"
4+
name = "Allowed Domains"
5+
description = "List of allowed domains"
6+
type = "keyword"
7+
}
8+
9+
# Add an item to the list
10+
resource "elasticstack_kibana_security_list_item" "domain_example" {
11+
list_id = elasticstack_kibana_security_list.my_list.list_id
12+
value = "example.com"
13+
meta = jsonencode({
14+
category = "internal"
15+
owner = "infrastructure-team"
16+
note = "Primary internal domain"
17+
})
18+
}

internal/clients/kibana_oapi/security_lists.go

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package kibana_oapi
22

33
import (
44
"context"
5+
"encoding/json"
56
"net/http"
67

78
"github.com/elastic/terraform-provider-elasticstack/generated/kbapi"
@@ -26,15 +27,20 @@ func CreateListIndex(ctx context.Context, client *Client, spaceId string) diag.D
2627
}
2728

2829
// GetList reads a security list from the API by ID
29-
func GetList(ctx context.Context, client *Client, spaceId string, params *kbapi.ReadListParams) (*kbapi.ReadListResponse, diag.Diagnostics) {
30+
func GetList(ctx context.Context, client *Client, spaceId string, params *kbapi.ReadListParams) (*kbapi.SecurityListsAPIList, diag.Diagnostics) {
3031
resp, err := client.API.ReadListWithResponse(ctx, kbapi.SpaceId(spaceId), params)
3132
if err != nil {
3233
return nil, diagutil.FrameworkDiagFromError(err)
3334
}
3435

3536
switch resp.StatusCode() {
3637
case http.StatusOK:
37-
return resp, nil
38+
if resp.JSON200 == nil {
39+
return nil, diag.Diagnostics{
40+
diag.NewErrorDiagnostic("Failed to parse list response", "API returned 200 but JSON200 is nil"),
41+
}
42+
}
43+
return resp.JSON200, nil
3844
case http.StatusNotFound:
3945
return nil, nil
4046
default:
@@ -43,30 +49,40 @@ func GetList(ctx context.Context, client *Client, spaceId string, params *kbapi.
4349
}
4450

4551
// CreateList creates a new security list.
46-
func CreateList(ctx context.Context, client *Client, spaceId string, body kbapi.CreateListJSONRequestBody) (*kbapi.CreateListResponse, diag.Diagnostics) {
52+
func CreateList(ctx context.Context, client *Client, spaceId string, body kbapi.CreateListJSONRequestBody) (*kbapi.SecurityListsAPIList, diag.Diagnostics) {
4753
resp, err := client.API.CreateListWithResponse(ctx, kbapi.SpaceId(spaceId), body)
4854
if err != nil {
4955
return nil, diagutil.FrameworkDiagFromError(err)
5056
}
5157

5258
switch resp.StatusCode() {
5359
case http.StatusOK:
54-
return resp, nil
60+
if resp.JSON200 == nil {
61+
return nil, diag.Diagnostics{
62+
diag.NewErrorDiagnostic("Failed to parse list response", "API returned 200 but JSON200 is nil"),
63+
}
64+
}
65+
return resp.JSON200, nil
5566
default:
5667
return nil, reportUnknownError(resp.StatusCode(), resp.Body)
5768
}
5869
}
5970

6071
// UpdateList updates an existing security list.
61-
func UpdateList(ctx context.Context, client *Client, spaceId string, body kbapi.UpdateListJSONRequestBody) (*kbapi.UpdateListResponse, diag.Diagnostics) {
72+
func UpdateList(ctx context.Context, client *Client, spaceId string, body kbapi.UpdateListJSONRequestBody) (*kbapi.SecurityListsAPIList, diag.Diagnostics) {
6273
resp, err := client.API.UpdateListWithResponse(ctx, kbapi.SpaceId(spaceId), body)
6374
if err != nil {
6475
return nil, diagutil.FrameworkDiagFromError(err)
6576
}
6677

6778
switch resp.StatusCode() {
6879
case http.StatusOK:
69-
return resp, nil
80+
if resp.JSON200 == nil {
81+
return nil, diag.Diagnostics{
82+
diag.NewErrorDiagnostic("Failed to parse list response", "API returned 200 but JSON200 is nil"),
83+
}
84+
}
85+
return resp.JSON200, nil
7086
default:
7187
return nil, reportUnknownError(resp.StatusCode(), resp.Body)
7288
}
@@ -90,15 +106,24 @@ func DeleteList(ctx context.Context, client *Client, spaceId string, params *kba
90106
}
91107

92108
// GetListItem reads a security list item from the API by ID or list_id and value
93-
func GetListItem(ctx context.Context, client *Client, spaceId string, params *kbapi.ReadListItemParams) (*kbapi.ReadListItemResponse, diag.Diagnostics) {
109+
// The response can be a single item or an array, so we unmarshal from the body.
110+
// When querying by ID, we expect a single item.
111+
func GetListItem(ctx context.Context, client *Client, spaceId string, params *kbapi.ReadListItemParams) (*kbapi.SecurityListsAPIListItem, diag.Diagnostics) {
94112
resp, err := client.API.ReadListItemWithResponse(ctx, kbapi.SpaceId(spaceId), params)
95113
if err != nil {
96114
return nil, diagutil.FrameworkDiagFromError(err)
97115
}
98116

99117
switch resp.StatusCode() {
100118
case http.StatusOK:
101-
return resp, nil
119+
var listItem kbapi.SecurityListsAPIListItem
120+
if err := json.Unmarshal(resp.Body, &listItem); err != nil {
121+
return nil, diag.Diagnostics{
122+
diag.NewErrorDiagnostic("Failed to parse list item response", err.Error()),
123+
}
124+
}
125+
126+
return &listItem, nil
102127
case http.StatusNotFound:
103128
return nil, nil
104129
default:
@@ -107,30 +132,40 @@ func GetListItem(ctx context.Context, client *Client, spaceId string, params *kb
107132
}
108133

109134
// CreateListItem creates a new security list item.
110-
func CreateListItem(ctx context.Context, client *Client, spaceId string, body kbapi.CreateListItemJSONRequestBody) (*kbapi.CreateListItemResponse, diag.Diagnostics) {
135+
func CreateListItem(ctx context.Context, client *Client, spaceId string, body kbapi.CreateListItemJSONRequestBody) (*kbapi.SecurityListsAPIListItem, diag.Diagnostics) {
111136
resp, err := client.API.CreateListItemWithResponse(ctx, kbapi.SpaceId(spaceId), body)
112137
if err != nil {
113138
return nil, diagutil.FrameworkDiagFromError(err)
114139
}
115140

116141
switch resp.StatusCode() {
117142
case http.StatusOK:
118-
return resp, nil
143+
if resp.JSON200 == nil {
144+
return nil, diag.Diagnostics{
145+
diag.NewErrorDiagnostic("Failed to parse list item response", "API returned 200 but JSON200 is nil"),
146+
}
147+
}
148+
return resp.JSON200, nil
119149
default:
120150
return nil, reportUnknownError(resp.StatusCode(), resp.Body)
121151
}
122152
}
123153

124154
// UpdateListItem updates an existing security list item.
125-
func UpdateListItem(ctx context.Context, client *Client, spaceId string, body kbapi.UpdateListItemJSONRequestBody) (*kbapi.UpdateListItemResponse, diag.Diagnostics) {
155+
func UpdateListItem(ctx context.Context, client *Client, spaceId string, body kbapi.UpdateListItemJSONRequestBody) (*kbapi.SecurityListsAPIListItem, diag.Diagnostics) {
126156
resp, err := client.API.UpdateListItemWithResponse(ctx, kbapi.SpaceId(spaceId), body)
127157
if err != nil {
128158
return nil, diagutil.FrameworkDiagFromError(err)
129159
}
130160

131161
switch resp.StatusCode() {
132162
case http.StatusOK:
133-
return resp, nil
163+
if resp.JSON200 == nil {
164+
return nil, diag.Diagnostics{
165+
diag.NewErrorDiagnostic("Failed to parse list item response", "API returned 200 but JSON200 is nil"),
166+
}
167+
}
168+
return resp.JSON200, nil
134169
default:
135170
return nil, reportUnknownError(resp.StatusCode(), resp.Body)
136171
}

internal/kibana/security_list/create.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,36 +31,36 @@ func (r *securityListResource) Create(ctx context.Context, req resource.CreateRe
3131

3232
// Create the list
3333
spaceID := plan.SpaceID.ValueString()
34-
createResp, diags := kibana_oapi.CreateList(ctx, client, spaceID, *createReq)
34+
createdList, diags := kibana_oapi.CreateList(ctx, client, spaceID, *createReq)
3535
resp.Diagnostics.Append(diags...)
3636
if resp.Diagnostics.HasError() {
3737
return
3838
}
3939

40-
if createResp == nil || createResp.JSON200 == nil {
40+
if createdList == nil {
4141
resp.Diagnostics.AddError("Failed to create security list", "API returned empty response")
4242
return
4343
}
4444

4545
// Read the created list to populate state
4646
readParams := &kbapi.ReadListParams{
47-
Id: createResp.JSON200.Id,
47+
Id: createdList.Id,
4848
}
4949

50-
readResp, diags := kibana_oapi.GetList(ctx, client, spaceID, readParams)
50+
list, diags := kibana_oapi.GetList(ctx, client, spaceID, readParams)
5151
resp.Diagnostics.Append(diags...)
5252
if resp.Diagnostics.HasError() {
5353
return
5454
}
5555

56-
if readResp == nil || readResp.JSON200 == nil {
56+
if list == nil {
5757
resp.State.RemoveResource(ctx)
5858
resp.Diagnostics.AddError("Failed to fetch security list", "API returned empty response")
5959
return
6060
}
6161

6262
// Update state with read response
63-
diags = plan.fromAPI(ctx, readResp.JSON200)
63+
diags = plan.fromAPI(ctx, list)
6464
resp.Diagnostics.Append(diags...)
6565
if resp.Diagnostics.HasError() {
6666
return

internal/kibana/security_list/models.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/elastic/terraform-provider-elasticstack/generated/kbapi"
99
"github.com/elastic/terraform-provider-elasticstack/internal/clients"
1010
"github.com/elastic/terraform-provider-elasticstack/internal/utils"
11+
"github.com/elastic/terraform-provider-elasticstack/internal/utils/typeutils"
1112
"github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes"
1213
"github.com/hashicorp/terraform-plugin-framework/diag"
1314
"github.com/hashicorp/terraform-plugin-framework/types"
@@ -120,10 +121,10 @@ func (m *SecurityListModel) fromAPI(ctx context.Context, apiList *kbapi.Security
120121
}
121122
m.ID = types.StringValue(compId.String())
122123

123-
m.ListID = utils.StringishValue(apiList.Id)
124-
m.Name = utils.StringishValue(apiList.Name)
125-
m.Description = utils.StringishValue(apiList.Description)
126-
m.Type = utils.StringishValue(apiList.Type)
124+
m.ListID = typeutils.StringishValue(apiList.Id)
125+
m.Name = typeutils.StringishValue(apiList.Name)
126+
m.Description = typeutils.StringishValue(apiList.Description)
127+
m.Type = typeutils.StringishValue(apiList.Type)
127128
m.Immutable = types.BoolValue(apiList.Immutable)
128129
m.Version = types.Int64Value(int64(apiList.Version))
129130
m.TieBreakerID = types.StringValue(apiList.TieBreakerId)
@@ -133,11 +134,11 @@ func (m *SecurityListModel) fromAPI(ctx context.Context, apiList *kbapi.Security
133134
m.UpdatedBy = types.StringValue(apiList.UpdatedBy)
134135

135136
// Set optional _version field
136-
m.VersionID = utils.StringishPointerValue(apiList.UnderscoreVersion)
137+
m.VersionID = typeutils.StringishPointerValue(apiList.UnderscoreVersion)
137138

138-
m.Deserializer = utils.StringishPointerValue(apiList.Deserializer)
139+
m.Deserializer = typeutils.StringishPointerValue(apiList.Deserializer)
139140

140-
m.Serializer = utils.StringishPointerValue(apiList.Serializer)
141+
m.Serializer = typeutils.StringishPointerValue(apiList.Serializer)
141142

142143
if apiList.Meta != nil {
143144
metaBytes, err := json.Marshal(apiList.Meta)

internal/kibana/security_list/read.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,19 @@ func (r *securityListResource) Read(ctx context.Context, req resource.ReadReques
3939
Id: kbapi.SecurityListsAPIListId(listID),
4040
}
4141

42-
readResp, diags := kibana_oapi.GetList(ctx, client, spaceID, params)
42+
list, diags := kibana_oapi.GetList(ctx, client, spaceID, params)
4343
resp.Diagnostics.Append(diags...)
4444
if resp.Diagnostics.HasError() {
4545
return
4646
}
4747

48-
if readResp == nil || readResp.JSON200 == nil {
48+
if list == nil {
4949
resp.State.RemoveResource(ctx)
5050
return
5151
}
5252

5353
// Convert API response to model
54-
diags = state.fromAPI(ctx, readResp.JSON200)
54+
diags = state.fromAPI(ctx, list)
5555
resp.Diagnostics.Append(diags...)
5656
if resp.Diagnostics.HasError() {
5757
return

internal/kibana/security_list/schema.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ func (r *securityListResource) Schema(_ context.Context, _ resource.SchemaReques
9191
Computed: true,
9292
},
9393
"version_id": schema.StringAttribute{
94-
MarkdownDescription: "The version id, normally returned by the API when the document is retrieved. Use it ensure updates are done against the latest version.",
94+
MarkdownDescription: "The version id, normally returned by the API when the document is retrieved. Use it to ensure updates are done against the latest version.",
9595
Computed: true,
9696
},
9797
"immutable": schema.BoolAttribute{

internal/kibana/security_list/update.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,36 +37,36 @@ func (r *securityListResource) Update(ctx context.Context, req resource.UpdateRe
3737

3838
// Update the list
3939
spaceID := plan.SpaceID.ValueString()
40-
updateResp, diags := kibana_oapi.UpdateList(ctx, client, spaceID, *updateReq)
40+
updatedList, diags := kibana_oapi.UpdateList(ctx, client, spaceID, *updateReq)
4141
resp.Diagnostics.Append(diags...)
4242
if resp.Diagnostics.HasError() {
4343
return
4444
}
4545

46-
if updateResp == nil || updateResp.JSON200 == nil {
46+
if updatedList == nil {
4747
resp.Diagnostics.AddError("Failed to update security list", "API returned empty response")
4848
return
4949
}
5050

5151
// Read the updated list to populate state
5252
readParams := &kbapi.ReadListParams{
53-
Id: updateResp.JSON200.Id,
53+
Id: updatedList.Id,
5454
}
5555

56-
readResp, diags := kibana_oapi.GetList(ctx, client, spaceID, readParams)
56+
list, diags := kibana_oapi.GetList(ctx, client, spaceID, readParams)
5757
resp.Diagnostics.Append(diags...)
5858
if resp.Diagnostics.HasError() {
5959
return
6060
}
6161

62-
if readResp == nil || readResp.JSON200 == nil {
62+
if list == nil {
6363
resp.State.RemoveResource(ctx)
6464
resp.Diagnostics.AddError("Failed to fetch security list", "API returned empty response")
6565
return
6666
}
6767

6868
// Update state with read response
69-
diags = plan.fromAPI(ctx, readResp.JSON200)
69+
diags = plan.fromAPI(ctx, list)
7070
resp.Diagnostics.Append(diags...)
7171
if resp.Diagnostics.HasError() {
7272
return

0 commit comments

Comments
 (0)