Skip to content

Commit cc1fe2d

Browse files
authored
Allow to override ECS objects to group or nested (#1493)
1 parent 88c7f7c commit cc1fe2d

File tree

2 files changed

+62
-3
lines changed

2 files changed

+62
-3
lines changed

internal/fields/dependency_manager.go

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,8 @@ func (dm *DependencyManager) injectFieldsWithOptions(defs []common.MapStr, optio
201201
transformed.Delete("external")
202202
}
203203

204-
// Allow to override the type only from keyword to constant_keyword,
205-
// to support the case of setting the value already in the mappings.
206-
if ttype, _ := transformed["type"].(string); ttype != "constant_keyword" || imported.Type != "keyword" {
204+
// Set the type back to the one imported, unless it is one of the allowed overrides.
205+
if ttype, _ := transformed["type"].(string); !allowedTypeOverride(imported.Type, ttype) {
207206
transformed["type"] = imported.Type
208207
}
209208

@@ -264,6 +263,28 @@ func skipField(def common.MapStr) bool {
264263
return false
265264
}
266265

266+
func allowedTypeOverride(fromType, toType string) bool {
267+
allowed := []struct {
268+
from string
269+
to string
270+
}{
271+
// Support the case of setting the value already in the mappings.
272+
{"keyword", "constant_keyword"},
273+
274+
// Support objects in ECS where the developer must decide if using
275+
// a group or nested object.
276+
{"object", "group"},
277+
{"object", "nested"},
278+
}
279+
280+
for _, a := range allowed {
281+
if a.from == fromType && a.to == toType {
282+
return true
283+
}
284+
}
285+
return false
286+
}
287+
267288
// importField method resolves dependency on a single external field using available schemas.
268289
func (dm *DependencyManager) importField(schemaName, fieldPath string) (FieldDefinition, error) {
269290
if dm == nil {

internal/fields/dependency_manager_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,44 @@ func TestDependencyManagerWithECS(t *testing.T) {
725725
},
726726
},
727727
},
728+
{
729+
title: "object to nested override",
730+
defs: []common.MapStr{
731+
{
732+
"name": "dns.answers",
733+
"external": "ecs",
734+
"type": "nested",
735+
},
736+
},
737+
options: InjectFieldsOptions{},
738+
valid: true,
739+
result: []common.MapStr{
740+
{
741+
"name": "dns.answers",
742+
"description": "An array containing an object for each answer section returned by the server.\nThe main keys that should be present in these objects are defined by ECS. Records that have more information may contain more keys than what ECS defines.\nNot all DNS data sources give all details about DNS answers. At minimum, answer objects must contain the `data` key. If more information is available, map as much of it to ECS as possible, and add any additional fields to the answer objects as custom fields.",
743+
"type": "nested",
744+
},
745+
},
746+
},
747+
{
748+
title: "object to group override",
749+
defs: []common.MapStr{
750+
{
751+
"name": "dns.answers",
752+
"external": "ecs",
753+
"type": "group",
754+
},
755+
},
756+
options: InjectFieldsOptions{},
757+
valid: true,
758+
result: []common.MapStr{
759+
{
760+
"name": "dns.answers",
761+
"description": "An array containing an object for each answer section returned by the server.\nThe main keys that should be present in these objects are defined by ECS. Records that have more information may contain more keys than what ECS defines.\nNot all DNS data sources give all details about DNS answers. At minimum, answer objects must contain the `data` key. If more information is available, map as much of it to ECS as possible, and add any additional fields to the answer objects as custom fields.",
762+
"type": "group",
763+
},
764+
},
765+
},
728766
}
729767

730768
for _, c := range cases {

0 commit comments

Comments
 (0)