Skip to content

Commit

Permalink
Allow to override ECS objects to group or nested (#1493)
Browse files Browse the repository at this point in the history
  • Loading branch information
jsoriano authored Oct 6, 2023
1 parent 88c7f7c commit cc1fe2d
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 3 deletions.
27 changes: 24 additions & 3 deletions internal/fields/dependency_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,8 @@ func (dm *DependencyManager) injectFieldsWithOptions(defs []common.MapStr, optio
transformed.Delete("external")
}

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

Expand Down Expand Up @@ -264,6 +263,28 @@ func skipField(def common.MapStr) bool {
return false
}

func allowedTypeOverride(fromType, toType string) bool {
allowed := []struct {
from string
to string
}{
// Support the case of setting the value already in the mappings.
{"keyword", "constant_keyword"},

// Support objects in ECS where the developer must decide if using
// a group or nested object.
{"object", "group"},
{"object", "nested"},
}

for _, a := range allowed {
if a.from == fromType && a.to == toType {
return true
}
}
return false
}

// importField method resolves dependency on a single external field using available schemas.
func (dm *DependencyManager) importField(schemaName, fieldPath string) (FieldDefinition, error) {
if dm == nil {
Expand Down
38 changes: 38 additions & 0 deletions internal/fields/dependency_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,44 @@ func TestDependencyManagerWithECS(t *testing.T) {
},
},
},
{
title: "object to nested override",
defs: []common.MapStr{
{
"name": "dns.answers",
"external": "ecs",
"type": "nested",
},
},
options: InjectFieldsOptions{},
valid: true,
result: []common.MapStr{
{
"name": "dns.answers",
"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.",
"type": "nested",
},
},
},
{
title: "object to group override",
defs: []common.MapStr{
{
"name": "dns.answers",
"external": "ecs",
"type": "group",
},
},
options: InjectFieldsOptions{},
valid: true,
result: []common.MapStr{
{
"name": "dns.answers",
"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.",
"type": "group",
},
},
},
}

for _, c := range cases {
Expand Down

0 comments on commit cc1fe2d

Please sign in to comment.