Skip to content

Commit cb6e171

Browse files
committed
Add security list
1 parent 437ba8e commit cb6e171

File tree

14 files changed

+856
-0
lines changed

14 files changed

+856
-0
lines changed
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "elasticstack_kibana_security_list Resource - terraform-provider-elasticstack"
4+
subcategory: "Kibana"
5+
description: |-
6+
Manages Kibana security lists (also known as value lists). Security lists are used by exception items to define sets of values for matching or excluding in security rules.
7+
Example Usage
8+
9+
resource "elasticstack_kibana_security_list" "ip_list" {
10+
space_id = "default"
11+
name = "Trusted IP Addresses"
12+
description = "List of trusted IP addresses for security rules"
13+
type = "ip"
14+
}
15+
16+
resource "elasticstack_kibana_security_list" "keyword_list" {
17+
space_id = "security"
18+
list_id = "custom-keywords"
19+
name = "Custom Keywords"
20+
description = "Custom keyword list for detection rules"
21+
type = "keyword"
22+
}
23+
24+
Notes
25+
Security lists define the type of data they can contain via the type attributeOnce created, the type of a list cannot be changedLists can be referenced by exception items to create more sophisticated matching rulesThe list_id is auto-generated if not provided
26+
---
27+
28+
# elasticstack_kibana_security_list (Resource)
29+
30+
Manages Kibana security lists (also known as value lists). Security lists are used by exception items to define sets of values for matching or excluding in security rules.
31+
32+
## Example Usage
33+
34+
```terraform
35+
resource "elasticstack_kibana_security_list" "ip_list" {
36+
space_id = "default"
37+
name = "Trusted IP Addresses"
38+
description = "List of trusted IP addresses for security rules"
39+
type = "ip"
40+
}
41+
42+
resource "elasticstack_kibana_security_list" "keyword_list" {
43+
space_id = "security"
44+
list_id = "custom-keywords"
45+
name = "Custom Keywords"
46+
description = "Custom keyword list for detection rules"
47+
type = "keyword"
48+
}
49+
```
50+
51+
## Notes
52+
53+
- Security lists define the type of data they can contain via the `type` attribute
54+
- Once created, the `type` of a list cannot be changed
55+
- Lists can be referenced by exception items to create more sophisticated matching rules
56+
- The `list_id` is auto-generated if not provided
57+
58+
## Example Usage
59+
60+
### IP address list
61+
62+
```terraform
63+
resource "elasticstack_kibana_security_list" "ip_list" {
64+
space_id = "default"
65+
name = "Trusted IP Addresses"
66+
description = "List of trusted IP addresses for security rules"
67+
type = "ip"
68+
}
69+
```
70+
71+
### Keyword list with custom list_id
72+
73+
```terraform
74+
resource "elasticstack_kibana_security_list" "keyword_list" {
75+
space_id = "security"
76+
list_id = "custom-keywords"
77+
name = "Custom Keywords"
78+
description = "Custom keyword list for detection rules"
79+
type = "keyword"
80+
}
81+
```
82+
83+
<!-- schema generated by tfplugindocs -->
84+
## Schema
85+
86+
### Required
87+
88+
- `description` (String) Describes the security list.
89+
- `name` (String) The name of the security list.
90+
- `type` (String) Specifies the Elasticsearch data type of values the list contains. Valid values include: `binary`, `boolean`, `byte`, `date`, `date_nanos`, `date_range`, `double`, `double_range`, `float`, `float_range`, `geo_point`, `geo_shape`, `half_float`, `integer`, `integer_range`, `ip`, `ip_range`, `keyword`, `long`, `long_range`, `shape`, `short`, `text`.
91+
92+
### Optional
93+
94+
- `deserializer` (String) Determines how retrieved list item values are presented. By default, list items are presented using Handlebars expressions based on the type.
95+
- `id` (String) The unique identifier of the security list (auto-generated by Kibana if not specified).
96+
- `list_id` (String) The value list's human-readable identifier.
97+
- `meta` (String) Placeholder for metadata about the value list as JSON string.
98+
- `serializer` (String) Determines how uploaded list item values are parsed. By default, list items are parsed using named regex groups based on the type.
99+
- `space_id` (String) An identifier for the space. If space_id is not provided, the default space is used.
100+
- `version` (Number) The document version number.
101+
102+
### Read-Only
103+
104+
- `created_at` (String) The timestamp of when the list was created.
105+
- `created_by` (String) The user who created the list.
106+
- `immutable` (Boolean) Whether the list is immutable.
107+
- `tie_breaker_id` (String) Field used in search to ensure all containers are sorted and returned correctly.
108+
- `updated_at` (String) The timestamp of when the list was last updated.
109+
- `updated_by` (String) The user who last updated the list.
110+
- `version_id` (String) The version id, normally returned by the API when the document is retrieved.
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package security_list_test
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/elastic/terraform-provider-elasticstack/internal/acctest"
8+
"github.com/elastic/terraform-provider-elasticstack/internal/clients"
9+
"github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi"
10+
"github.com/google/uuid"
11+
"github.com/hashicorp/terraform-plugin-testing/config"
12+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
13+
)
14+
15+
func ensureListIndexExists(t *testing.T) {
16+
client, err := clients.NewAcceptanceTestingClient()
17+
if err != nil {
18+
t.Fatalf("Failed to create client: %v", err)
19+
}
20+
21+
kibanaClient, err := client.GetKibanaOapiClient()
22+
if err != nil {
23+
t.Fatalf("Failed to get Kibana client: %v", err)
24+
}
25+
26+
diags := kibana_oapi.CreateListIndex(context.Background(), kibanaClient, "default")
27+
if diags.HasError() {
28+
// It's OK if it already exists, we'll only fail on other errors
29+
for _, d := range diags {
30+
if d.Summary() != "Unexpected status code from server: got HTTP 409" {
31+
t.Fatalf("Failed to create list index: %v", d.Detail())
32+
}
33+
}
34+
}
35+
}
36+
37+
func TestAccResourceSecurityList(t *testing.T) {
38+
listID := "test-list-" + uuid.New().String()
39+
resource.Test(t, resource.TestCase{
40+
PreCheck: func() {
41+
acctest.PreCheck(t)
42+
ensureListIndexExists(t)
43+
},
44+
ProtoV6ProviderFactories: acctest.Providers,
45+
Steps: []resource.TestStep{
46+
{ // Create
47+
ConfigDirectory: acctest.NamedTestCaseDirectory("create"),
48+
ConfigVariables: config.Variables{
49+
"list_id": config.StringVariable(listID),
50+
"name": config.StringVariable("Test Security List"),
51+
"description": config.StringVariable("A test security list for IP addresses"),
52+
"type": config.StringVariable("ip"),
53+
},
54+
Check: resource.ComposeTestCheckFunc(
55+
resource.TestCheckResourceAttrSet("elasticstack_kibana_security_list.test", "id"),
56+
resource.TestCheckResourceAttr("elasticstack_kibana_security_list.test", "name", "Test Security List"),
57+
resource.TestCheckResourceAttr("elasticstack_kibana_security_list.test", "description", "A test security list for IP addresses"),
58+
resource.TestCheckResourceAttr("elasticstack_kibana_security_list.test", "type", "ip"),
59+
resource.TestCheckResourceAttrSet("elasticstack_kibana_security_list.test", "created_at"),
60+
resource.TestCheckResourceAttrSet("elasticstack_kibana_security_list.test", "created_by"),
61+
resource.TestCheckResourceAttrSet("elasticstack_kibana_security_list.test", "updated_at"),
62+
resource.TestCheckResourceAttrSet("elasticstack_kibana_security_list.test", "updated_by"),
63+
),
64+
},
65+
{ // Update
66+
ConfigDirectory: acctest.NamedTestCaseDirectory("update"),
67+
ConfigVariables: config.Variables{
68+
"list_id": config.StringVariable(listID),
69+
"name": config.StringVariable("Updated Security List"),
70+
"description": config.StringVariable("An updated test security list"),
71+
"type": config.StringVariable("ip"),
72+
},
73+
Check: resource.ComposeTestCheckFunc(
74+
resource.TestCheckResourceAttr("elasticstack_kibana_security_list.test", "name", "Updated Security List"),
75+
resource.TestCheckResourceAttr("elasticstack_kibana_security_list.test", "description", "An updated test security list"),
76+
),
77+
},
78+
},
79+
})
80+
}
81+
82+
func TestAccResourceSecurityList_KeywordType(t *testing.T) {
83+
listID := "keyword-list-" + uuid.New().String()
84+
resource.Test(t, resource.TestCase{
85+
PreCheck: func() {
86+
acctest.PreCheck(t)
87+
ensureListIndexExists(t)
88+
},
89+
ProtoV6ProviderFactories: acctest.Providers,
90+
Steps: []resource.TestStep{
91+
{
92+
ConfigDirectory: acctest.NamedTestCaseDirectory("keyword_type"),
93+
ConfigVariables: config.Variables{
94+
"list_id": config.StringVariable(listID),
95+
"name": config.StringVariable("Keyword Security List"),
96+
"description": config.StringVariable("A test security list for keywords"),
97+
"type": config.StringVariable("keyword"),
98+
},
99+
Check: resource.ComposeTestCheckFunc(
100+
resource.TestCheckResourceAttr("elasticstack_kibana_security_list.test", "type", "keyword"),
101+
),
102+
},
103+
},
104+
})
105+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package security_list
2+
3+
import (
4+
"context"
5+
6+
"github.com/elastic/terraform-provider-elasticstack/generated/kbapi"
7+
"github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi"
8+
"github.com/hashicorp/terraform-plugin-framework/resource"
9+
)
10+
11+
func (r *securityListResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
12+
var plan SecurityListModel
13+
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
14+
if resp.Diagnostics.HasError() {
15+
return
16+
}
17+
18+
// Get Kibana client
19+
client, err := r.client.GetKibanaOapiClient()
20+
if err != nil {
21+
resp.Diagnostics.AddError("Failed to get Kibana client", err.Error())
22+
return
23+
}
24+
25+
// Convert plan to API request
26+
createReq, diags := plan.toCreateRequest()
27+
resp.Diagnostics.Append(diags...)
28+
if resp.Diagnostics.HasError() {
29+
return
30+
}
31+
32+
// Create the list
33+
spaceID := plan.SpaceID.ValueString()
34+
createResp, diags := kibana_oapi.CreateList(ctx, client, spaceID, *createReq)
35+
resp.Diagnostics.Append(diags...)
36+
if resp.Diagnostics.HasError() {
37+
return
38+
}
39+
40+
if createResp == nil || createResp.JSON200 == nil {
41+
resp.Diagnostics.AddError("Failed to create security list", "API returned empty response")
42+
return
43+
}
44+
45+
// Read the created list to populate state
46+
readParams := &kbapi.ReadListParams{
47+
Id: createResp.JSON200.Id,
48+
}
49+
50+
readResp, diags := kibana_oapi.GetList(ctx, client, spaceID, readParams)
51+
resp.Diagnostics.Append(diags...)
52+
if resp.Diagnostics.HasError() {
53+
return
54+
}
55+
56+
if readResp == nil || readResp.JSON200 == nil {
57+
resp.State.RemoveResource(ctx)
58+
return
59+
}
60+
61+
// Update state with read response
62+
diags = plan.fromAPI(ctx, readResp.JSON200)
63+
resp.Diagnostics.Append(diags...)
64+
if resp.Diagnostics.HasError() {
65+
return
66+
}
67+
68+
resp.Diagnostics.Append(resp.State.Set(ctx, plan)...)
69+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package security_list
2+
3+
import (
4+
"context"
5+
6+
"github.com/elastic/terraform-provider-elasticstack/generated/kbapi"
7+
"github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi"
8+
"github.com/hashicorp/terraform-plugin-framework/resource"
9+
)
10+
11+
func (r *securityListResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
12+
var state SecurityListModel
13+
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
14+
if resp.Diagnostics.HasError() {
15+
return
16+
}
17+
18+
client, err := r.client.GetKibanaOapiClient()
19+
if err != nil {
20+
resp.Diagnostics.AddError("Failed to get Kibana client", err.Error())
21+
return
22+
}
23+
24+
spaceID := state.SpaceID.ValueString()
25+
listID := state.ListID.ValueString()
26+
27+
params := &kbapi.DeleteListParams{
28+
Id: kbapi.SecurityListsAPIListId(listID),
29+
}
30+
31+
diags := kibana_oapi.DeleteList(ctx, client, spaceID, params)
32+
resp.Diagnostics.Append(diags...)
33+
}

0 commit comments

Comments
 (0)