Skip to content

Commit 8770ac1

Browse files
committed
Add tests for schema validations
1 parent a3c2efd commit 8770ac1

File tree

14 files changed

+697
-0
lines changed

14 files changed

+697
-0
lines changed

internal/kibana/security/exception_item/acc_test.go

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package exception_item_test
22

33
import (
44
"fmt"
5+
"regexp"
56
"testing"
67

78
"github.com/elastic/terraform-provider-elasticstack/internal/acctest"
@@ -304,3 +305,170 @@ func TestAccResourceExceptionItemEntryType_Wildcard(t *testing.T) {
304305
},
305306
})
306307
}
308+
309+
func TestAccResourceExceptionItemValidation(t *testing.T) {
310+
listID := fmt.Sprintf("test-exception-list-validation-%s", uuid.New().String()[:8])
311+
itemID := fmt.Sprintf("test-exception-item-validation-%s", uuid.New().String()[:8])
312+
313+
resource.Test(t, resource.TestCase{
314+
PreCheck: func() { acctest.PreCheck(t) },
315+
Steps: []resource.TestStep{
316+
// Test 1: Match entry missing value
317+
{
318+
SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport),
319+
ProtoV6ProviderFactories: acctest.Providers,
320+
ConfigDirectory: acctest.NamedTestCaseDirectory("validation_match_missing_value"),
321+
ConfigVariables: config.Variables{
322+
"list_id": config.StringVariable(listID),
323+
"item_id": config.StringVariable(itemID),
324+
},
325+
ExpectError: regexp.MustCompile("Entry type 'match' requires 'value' to be set"),
326+
PlanOnly: true,
327+
},
328+
// Test 2: Match entry missing operator
329+
{
330+
SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport),
331+
ProtoV6ProviderFactories: acctest.Providers,
332+
ConfigDirectory: acctest.NamedTestCaseDirectory("validation_match_missing_operator"),
333+
ConfigVariables: config.Variables{
334+
"list_id": config.StringVariable(listID),
335+
"item_id": config.StringVariable(itemID),
336+
},
337+
ExpectError: regexp.MustCompile("Entry type 'match' requires 'operator' to be set"),
338+
PlanOnly: true,
339+
},
340+
// Test 3: Wildcard entry missing value
341+
{
342+
SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport),
343+
ProtoV6ProviderFactories: acctest.Providers,
344+
ConfigDirectory: acctest.NamedTestCaseDirectory("validation_wildcard_missing_value"),
345+
ConfigVariables: config.Variables{
346+
"list_id": config.StringVariable(listID),
347+
"item_id": config.StringVariable(itemID),
348+
},
349+
ExpectError: regexp.MustCompile("Entry type 'wildcard' requires 'value' to be set"),
350+
PlanOnly: true,
351+
},
352+
// Test 4: MatchAny entry missing values
353+
{
354+
SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport),
355+
ProtoV6ProviderFactories: acctest.Providers,
356+
ConfigDirectory: acctest.NamedTestCaseDirectory("validation_match_any_missing_values"),
357+
ConfigVariables: config.Variables{
358+
"list_id": config.StringVariable(listID),
359+
"item_id": config.StringVariable(itemID),
360+
},
361+
ExpectError: regexp.MustCompile("Entry type 'match_any' requires 'values' to be set"),
362+
PlanOnly: true,
363+
},
364+
// Test 5: MatchAny entry missing operator
365+
{
366+
SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport),
367+
ProtoV6ProviderFactories: acctest.Providers,
368+
ConfigDirectory: acctest.NamedTestCaseDirectory("validation_match_any_missing_operator"),
369+
ConfigVariables: config.Variables{
370+
"list_id": config.StringVariable(listID),
371+
"item_id": config.StringVariable(itemID),
372+
},
373+
ExpectError: regexp.MustCompile("Entry type 'match_any' requires 'operator' to be set"),
374+
PlanOnly: true,
375+
},
376+
// Test 6: List entry missing list object
377+
{
378+
SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport),
379+
ProtoV6ProviderFactories: acctest.Providers,
380+
ConfigDirectory: acctest.NamedTestCaseDirectory("validation_list_missing_list_object"),
381+
ConfigVariables: config.Variables{
382+
"list_id": config.StringVariable(listID),
383+
"item_id": config.StringVariable(itemID),
384+
},
385+
ExpectError: regexp.MustCompile("Entry type 'list' requires 'list' object to be set"),
386+
PlanOnly: true,
387+
},
388+
// Test 7: List entry missing list.id
389+
{
390+
SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport),
391+
ProtoV6ProviderFactories: acctest.Providers,
392+
ConfigDirectory: acctest.NamedTestCaseDirectory("validation_list_missing_list_id"),
393+
ConfigVariables: config.Variables{
394+
"list_id": config.StringVariable(listID),
395+
"item_id": config.StringVariable(itemID),
396+
},
397+
ExpectError: regexp.MustCompile(`attribute "id" is required`),
398+
PlanOnly: true,
399+
},
400+
// Test 8: List entry missing list.type
401+
{
402+
SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport),
403+
ProtoV6ProviderFactories: acctest.Providers,
404+
ConfigDirectory: acctest.NamedTestCaseDirectory("validation_list_missing_list_type"),
405+
ConfigVariables: config.Variables{
406+
"list_id": config.StringVariable(listID),
407+
"item_id": config.StringVariable(itemID),
408+
},
409+
ExpectError: regexp.MustCompile(`attribute "type" is required`),
410+
PlanOnly: true,
411+
},
412+
// Test 9: Exists entry missing operator
413+
{
414+
SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport),
415+
ProtoV6ProviderFactories: acctest.Providers,
416+
ConfigDirectory: acctest.NamedTestCaseDirectory("validation_exists_missing_operator"),
417+
ConfigVariables: config.Variables{
418+
"list_id": config.StringVariable(listID),
419+
"item_id": config.StringVariable(itemID),
420+
},
421+
ExpectError: regexp.MustCompile("Entry type 'exists' requires 'operator' to be set"),
422+
PlanOnly: true,
423+
},
424+
// Test 10: Nested entry missing entries
425+
{
426+
SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport),
427+
ProtoV6ProviderFactories: acctest.Providers,
428+
ConfigDirectory: acctest.NamedTestCaseDirectory("validation_nested_missing_entries"),
429+
ConfigVariables: config.Variables{
430+
"list_id": config.StringVariable(listID),
431+
"item_id": config.StringVariable(itemID),
432+
},
433+
ExpectError: regexp.MustCompile("Entry type 'nested' requires 'entries' to be set"),
434+
PlanOnly: true,
435+
},
436+
// Test 11: Nested entry with invalid entry type
437+
{
438+
SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport),
439+
ProtoV6ProviderFactories: acctest.Providers,
440+
ConfigDirectory: acctest.NamedTestCaseDirectory("validation_nested_invalid_entry_type"),
441+
ConfigVariables: config.Variables{
442+
"list_id": config.StringVariable(listID),
443+
"item_id": config.StringVariable(itemID),
444+
},
445+
ExpectError: regexp.MustCompile(`(Nested entry .* has invalid type|value must be one of:.*"match".*"match_any".*"exists")`),
446+
PlanOnly: true,
447+
},
448+
// Test 12: Nested match entry missing value
449+
{
450+
SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport),
451+
ProtoV6ProviderFactories: acctest.Providers,
452+
ConfigDirectory: acctest.NamedTestCaseDirectory("validation_nested_entry_missing_value"),
453+
ConfigVariables: config.Variables{
454+
"list_id": config.StringVariable(listID),
455+
"item_id": config.StringVariable(itemID),
456+
},
457+
ExpectError: regexp.MustCompile("Nested entry type 'match' requires 'value' to be set"),
458+
PlanOnly: true,
459+
},
460+
// Test 13: Nested entry missing operator
461+
{
462+
SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport),
463+
ProtoV6ProviderFactories: acctest.Providers,
464+
ConfigDirectory: acctest.NamedTestCaseDirectory("validation_nested_entry_missing_operator"),
465+
ConfigVariables: config.Variables{
466+
"list_id": config.StringVariable(listID),
467+
"item_id": config.StringVariable(itemID),
468+
},
469+
ExpectError: regexp.MustCompile(`(Nested entry requires 'operator' to be set|attribute "operator" is required)`),
470+
PlanOnly: true,
471+
},
472+
},
473+
})
474+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
variable "list_id" {
2+
description = "The exception list ID"
3+
type = string
4+
}
5+
6+
variable "item_id" {
7+
description = "The exception item ID"
8+
type = string
9+
}
10+
11+
provider "elasticstack" {
12+
elasticsearch {}
13+
kibana {}
14+
}
15+
16+
resource "elasticstack_kibana_security_exception_list" "test" {
17+
list_id = var.list_id
18+
name = "Test Exception List"
19+
description = "Test exception list for validation"
20+
type = "detection"
21+
namespace_type = "single"
22+
}
23+
24+
resource "elasticstack_kibana_security_exception_item" "test" {
25+
list_id = elasticstack_kibana_security_exception_list.test.list_id
26+
item_id = var.item_id
27+
name = "Test Exception Item - Exists Missing Operator"
28+
description = "Test validation: exists entry without operator"
29+
type = "simple"
30+
namespace_type = "single"
31+
entries = [
32+
{
33+
type = "exists"
34+
field = "file.hash.sha256"
35+
# Missing operator - should trigger validation error
36+
}
37+
]
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
variable "list_id" {
2+
description = "The exception list ID"
3+
type = string
4+
}
5+
6+
variable "item_id" {
7+
description = "The exception item ID"
8+
type = string
9+
}
10+
11+
provider "elasticstack" {
12+
elasticsearch {}
13+
kibana {}
14+
}
15+
16+
resource "elasticstack_kibana_security_exception_list" "test" {
17+
list_id = var.list_id
18+
name = "Test Exception List"
19+
description = "Test exception list for validation"
20+
type = "detection"
21+
namespace_type = "single"
22+
}
23+
24+
resource "elasticstack_kibana_security_exception_item" "test" {
25+
list_id = elasticstack_kibana_security_exception_list.test.list_id
26+
item_id = var.item_id
27+
name = "Test Exception Item - List Missing List ID"
28+
description = "Test validation: list entry without list.id"
29+
type = "simple"
30+
namespace_type = "single"
31+
entries = [
32+
{
33+
type = "list"
34+
field = "source.ip"
35+
operator = "included"
36+
list = {
37+
type = "ip"
38+
# Missing id - should trigger validation error
39+
}
40+
}
41+
]
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
variable "list_id" {
2+
description = "The exception list ID"
3+
type = string
4+
}
5+
6+
variable "item_id" {
7+
description = "The exception item ID"
8+
type = string
9+
}
10+
11+
provider "elasticstack" {
12+
elasticsearch {}
13+
kibana {}
14+
}
15+
16+
resource "elasticstack_kibana_security_exception_list" "test" {
17+
list_id = var.list_id
18+
name = "Test Exception List"
19+
description = "Test exception list for validation"
20+
type = "detection"
21+
namespace_type = "single"
22+
}
23+
24+
resource "elasticstack_kibana_security_exception_item" "test" {
25+
list_id = elasticstack_kibana_security_exception_list.test.list_id
26+
item_id = var.item_id
27+
name = "Test Exception Item - List Missing List Object"
28+
description = "Test validation: list entry without list object"
29+
type = "simple"
30+
namespace_type = "single"
31+
entries = [
32+
{
33+
type = "list"
34+
field = "source.ip"
35+
operator = "included"
36+
# Missing list object - should trigger validation error
37+
}
38+
]
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
variable "list_id" {
2+
description = "The exception list ID"
3+
type = string
4+
}
5+
6+
variable "item_id" {
7+
description = "The exception item ID"
8+
type = string
9+
}
10+
11+
provider "elasticstack" {
12+
elasticsearch {}
13+
kibana {}
14+
}
15+
16+
resource "elasticstack_kibana_security_exception_list" "test" {
17+
list_id = var.list_id
18+
name = "Test Exception List"
19+
description = "Test exception list for validation"
20+
type = "detection"
21+
namespace_type = "single"
22+
}
23+
24+
resource "elasticstack_kibana_security_exception_item" "test" {
25+
list_id = elasticstack_kibana_security_exception_list.test.list_id
26+
item_id = var.item_id
27+
name = "Test Exception Item - List Missing List Type"
28+
description = "Test validation: list entry without list.type"
29+
type = "simple"
30+
namespace_type = "single"
31+
entries = [
32+
{
33+
type = "list"
34+
field = "source.ip"
35+
operator = "included"
36+
list = {
37+
id = "test-value-list"
38+
# Missing type - should trigger validation error
39+
}
40+
}
41+
]
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
variable "list_id" {
2+
description = "The exception list ID"
3+
type = string
4+
}
5+
6+
variable "item_id" {
7+
description = "The exception item ID"
8+
type = string
9+
}
10+
11+
provider "elasticstack" {
12+
elasticsearch {}
13+
kibana {}
14+
}
15+
16+
resource "elasticstack_kibana_security_exception_list" "test" {
17+
list_id = var.list_id
18+
name = "Test Exception List"
19+
description = "Test exception list for validation"
20+
type = "detection"
21+
namespace_type = "single"
22+
}
23+
24+
resource "elasticstack_kibana_security_exception_item" "test" {
25+
list_id = elasticstack_kibana_security_exception_list.test.list_id
26+
item_id = var.item_id
27+
name = "Test Exception Item - MatchAny Missing Operator"
28+
description = "Test validation: match_any entry without operator"
29+
type = "simple"
30+
namespace_type = "single"
31+
entries = [
32+
{
33+
type = "match_any"
34+
field = "process.name"
35+
values = ["process1", "process2"]
36+
# Missing operator - should trigger validation error
37+
}
38+
]
39+
}

0 commit comments

Comments
 (0)