Skip to content

Commit b290b42

Browse files
api-clients-generation-pipeline[bot]ci.datadog-api-spec
andauthored
Adding custom mapper support to Observability Pipelines OCSF Mapper (DataDog#3692)
Co-authored-by: ci.datadog-api-spec <packages@datadoghq.com>
1 parent d08c3a9 commit b290b42

16 files changed

Lines changed: 1482 additions & 0 deletions

.generator/schemas/v2/openapi.yaml

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41369,6 +41369,7 @@ components:
4136941369
example: CloudTrail Account Change
4137041370
oneOf:
4137141371
- $ref: '#/components/schemas/ObservabilityPipelineOcsfMappingLibrary'
41372+
- $ref: '#/components/schemas/ObservabilityPipelineOcsfMappingCustom'
4137241373
ObservabilityPipelineOcsfMapperProcessorType:
4137341374
default: ocsf_mapper
4137441375
description: The processor type. The value should always be `ocsf_mapper`.
@@ -41378,6 +41379,116 @@ components:
4137841379
type: string
4137941380
x-enum-varnames:
4138041381
- OCSF_MAPPER
41382+
ObservabilityPipelineOcsfMappingCustom:
41383+
description: Custom OCSF mapping configuration for transforming logs.
41384+
properties:
41385+
mapping:
41386+
description: A list of field mapping rules for transforming log fields to
41387+
OCSF schema fields.
41388+
items:
41389+
$ref: '#/components/schemas/ObservabilityPipelineOcsfMappingCustomFieldMapping'
41390+
type: array
41391+
metadata:
41392+
$ref: '#/components/schemas/ObservabilityPipelineOcsfMappingCustomMetadata'
41393+
version:
41394+
description: The version of the custom mapping configuration.
41395+
example: 1
41396+
format: int64
41397+
type: integer
41398+
required:
41399+
- mapping
41400+
- metadata
41401+
- version
41402+
type: object
41403+
ObservabilityPipelineOcsfMappingCustomFieldMapping:
41404+
description: Defines a single field mapping rule for transforming a source field
41405+
to an OCSF destination field.
41406+
properties:
41407+
default:
41408+
description: The default value to use if the source field is missing or
41409+
empty.
41410+
example: ''
41411+
dest:
41412+
description: The destination OCSF field path.
41413+
example: device.type
41414+
type: string
41415+
lookup:
41416+
$ref: '#/components/schemas/ObservabilityPipelineOcsfMappingCustomLookup'
41417+
source:
41418+
description: The source field path from the log event.
41419+
example: host.type
41420+
sources:
41421+
description: Multiple source field paths for combined mapping.
41422+
example:
41423+
- field1
41424+
- field2
41425+
value:
41426+
description: A static value to use for the destination field.
41427+
example: static_value
41428+
required:
41429+
- dest
41430+
type: object
41431+
ObservabilityPipelineOcsfMappingCustomLookup:
41432+
description: Lookup table configuration for mapping source values to destination
41433+
values.
41434+
properties:
41435+
default:
41436+
description: The default value to use if no lookup match is found.
41437+
example: unknown
41438+
table:
41439+
description: A list of lookup table entries for value transformation.
41440+
items:
41441+
$ref: '#/components/schemas/ObservabilityPipelineOcsfMappingCustomLookupTableEntry'
41442+
type: array
41443+
type: object
41444+
ObservabilityPipelineOcsfMappingCustomLookupTableEntry:
41445+
description: A single entry in a lookup table for value transformation.
41446+
properties:
41447+
contains:
41448+
description: The substring to match in the source value.
41449+
example: Desktop
41450+
type: string
41451+
equals:
41452+
description: The exact value to match in the source.
41453+
example: desktop
41454+
equals_source:
41455+
description: The source field to match against.
41456+
example: device_type
41457+
type: string
41458+
matches:
41459+
description: A regex pattern to match in the source value.
41460+
example: ^Desktop.*
41461+
type: string
41462+
not_matches:
41463+
description: A regex pattern that must not match the source value.
41464+
example: ^Mobile.*
41465+
type: string
41466+
value:
41467+
description: The value to use when a match is found.
41468+
example: desktop
41469+
type: object
41470+
ObservabilityPipelineOcsfMappingCustomMetadata:
41471+
description: Metadata for the custom OCSF mapping.
41472+
properties:
41473+
class:
41474+
description: The OCSF event class name.
41475+
example: Device Inventory Info
41476+
type: string
41477+
profiles:
41478+
description: A list of OCSF profiles to apply.
41479+
example:
41480+
- container
41481+
items:
41482+
type: string
41483+
type: array
41484+
version:
41485+
description: The OCSF schema version.
41486+
example: 1.3.0
41487+
type: string
41488+
required:
41489+
- class
41490+
- version
41491+
type: object
4138141492
ObservabilityPipelineOcsfMappingLibrary:
4138241493
description: Predefined library mappings for common log formats.
4138341494
enum:

api/datadogV2/model_observability_pipeline_ocsf_mapper_processor_mapping_mapping.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
// ObservabilityPipelineOcsfMapperProcessorMappingMapping - Defines a single mapping rule for transforming logs into the OCSF schema.
1212
type ObservabilityPipelineOcsfMapperProcessorMappingMapping struct {
1313
ObservabilityPipelineOcsfMappingLibrary *ObservabilityPipelineOcsfMappingLibrary
14+
ObservabilityPipelineOcsfMappingCustom *ObservabilityPipelineOcsfMappingCustom
1415

1516
// UnparsedObject contains the raw value of the object if there was an error when deserializing into the struct
1617
UnparsedObject interface{}
@@ -21,6 +22,11 @@ func ObservabilityPipelineOcsfMappingLibraryAsObservabilityPipelineOcsfMapperPro
2122
return ObservabilityPipelineOcsfMapperProcessorMappingMapping{ObservabilityPipelineOcsfMappingLibrary: v}
2223
}
2324

25+
// ObservabilityPipelineOcsfMappingCustomAsObservabilityPipelineOcsfMapperProcessorMappingMapping is a convenience function that returns ObservabilityPipelineOcsfMappingCustom wrapped in ObservabilityPipelineOcsfMapperProcessorMappingMapping.
26+
func ObservabilityPipelineOcsfMappingCustomAsObservabilityPipelineOcsfMapperProcessorMappingMapping(v *ObservabilityPipelineOcsfMappingCustom) ObservabilityPipelineOcsfMapperProcessorMappingMapping {
27+
return ObservabilityPipelineOcsfMapperProcessorMappingMapping{ObservabilityPipelineOcsfMappingCustom: v}
28+
}
29+
2430
// UnmarshalJSON turns data into one of the pointers in the struct.
2531
func (obj *ObservabilityPipelineOcsfMapperProcessorMappingMapping) UnmarshalJSON(data []byte) error {
2632
var err error
@@ -42,9 +48,27 @@ func (obj *ObservabilityPipelineOcsfMapperProcessorMappingMapping) UnmarshalJSON
4248
obj.ObservabilityPipelineOcsfMappingLibrary = nil
4349
}
4450

51+
// try to unmarshal data into ObservabilityPipelineOcsfMappingCustom
52+
err = datadog.Unmarshal(data, &obj.ObservabilityPipelineOcsfMappingCustom)
53+
if err == nil {
54+
if obj.ObservabilityPipelineOcsfMappingCustom != nil && obj.ObservabilityPipelineOcsfMappingCustom.UnparsedObject == nil {
55+
jsonObservabilityPipelineOcsfMappingCustom, _ := datadog.Marshal(obj.ObservabilityPipelineOcsfMappingCustom)
56+
if string(jsonObservabilityPipelineOcsfMappingCustom) == "{}" { // empty struct
57+
obj.ObservabilityPipelineOcsfMappingCustom = nil
58+
} else {
59+
match++
60+
}
61+
} else {
62+
obj.ObservabilityPipelineOcsfMappingCustom = nil
63+
}
64+
} else {
65+
obj.ObservabilityPipelineOcsfMappingCustom = nil
66+
}
67+
4568
if match != 1 { // more than 1 match
4669
// reset to nil
4770
obj.ObservabilityPipelineOcsfMappingLibrary = nil
71+
obj.ObservabilityPipelineOcsfMappingCustom = nil
4872
return datadog.Unmarshal(data, &obj.UnparsedObject)
4973
}
5074
return nil // exactly one match
@@ -56,6 +80,10 @@ func (obj ObservabilityPipelineOcsfMapperProcessorMappingMapping) MarshalJSON()
5680
return datadog.Marshal(&obj.ObservabilityPipelineOcsfMappingLibrary)
5781
}
5882

83+
if obj.ObservabilityPipelineOcsfMappingCustom != nil {
84+
return datadog.Marshal(&obj.ObservabilityPipelineOcsfMappingCustom)
85+
}
86+
5987
if obj.UnparsedObject != nil {
6088
return datadog.Marshal(obj.UnparsedObject)
6189
}
@@ -68,6 +96,10 @@ func (obj *ObservabilityPipelineOcsfMapperProcessorMappingMapping) GetActualInst
6896
return obj.ObservabilityPipelineOcsfMappingLibrary
6997
}
7098

99+
if obj.ObservabilityPipelineOcsfMappingCustom != nil {
100+
return obj.ObservabilityPipelineOcsfMappingCustom
101+
}
102+
71103
// all schemas are nil
72104
return nil
73105
}
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License.
2+
// This product includes software developed at Datadog (https://www.datadoghq.com/).
3+
// Copyright 2019-Present Datadog, Inc.
4+
5+
package datadogV2
6+
7+
import (
8+
"fmt"
9+
10+
"github.com/DataDog/datadog-api-client-go/v2/api/datadog"
11+
)
12+
13+
// ObservabilityPipelineOcsfMappingCustom Custom OCSF mapping configuration for transforming logs.
14+
type ObservabilityPipelineOcsfMappingCustom struct {
15+
// A list of field mapping rules for transforming log fields to OCSF schema fields.
16+
Mapping []ObservabilityPipelineOcsfMappingCustomFieldMapping `json:"mapping"`
17+
// Metadata for the custom OCSF mapping.
18+
Metadata ObservabilityPipelineOcsfMappingCustomMetadata `json:"metadata"`
19+
// The version of the custom mapping configuration.
20+
Version int64 `json:"version"`
21+
// UnparsedObject contains the raw value of the object if there was an error when deserializing into the struct
22+
UnparsedObject map[string]interface{} `json:"-"`
23+
AdditionalProperties map[string]interface{} `json:"-"`
24+
}
25+
26+
// NewObservabilityPipelineOcsfMappingCustom instantiates a new ObservabilityPipelineOcsfMappingCustom object.
27+
// This constructor will assign default values to properties that have it defined,
28+
// and makes sure properties required by API are set, but the set of arguments
29+
// will change when the set of required properties is changed.
30+
func NewObservabilityPipelineOcsfMappingCustom(mapping []ObservabilityPipelineOcsfMappingCustomFieldMapping, metadata ObservabilityPipelineOcsfMappingCustomMetadata, version int64) *ObservabilityPipelineOcsfMappingCustom {
31+
this := ObservabilityPipelineOcsfMappingCustom{}
32+
this.Mapping = mapping
33+
this.Metadata = metadata
34+
this.Version = version
35+
return &this
36+
}
37+
38+
// NewObservabilityPipelineOcsfMappingCustomWithDefaults instantiates a new ObservabilityPipelineOcsfMappingCustom object.
39+
// This constructor will only assign default values to properties that have it defined,
40+
// but it doesn't guarantee that properties required by API are set.
41+
func NewObservabilityPipelineOcsfMappingCustomWithDefaults() *ObservabilityPipelineOcsfMappingCustom {
42+
this := ObservabilityPipelineOcsfMappingCustom{}
43+
return &this
44+
}
45+
46+
// GetMapping returns the Mapping field value.
47+
func (o *ObservabilityPipelineOcsfMappingCustom) GetMapping() []ObservabilityPipelineOcsfMappingCustomFieldMapping {
48+
if o == nil {
49+
var ret []ObservabilityPipelineOcsfMappingCustomFieldMapping
50+
return ret
51+
}
52+
return o.Mapping
53+
}
54+
55+
// GetMappingOk returns a tuple with the Mapping field value
56+
// and a boolean to check if the value has been set.
57+
func (o *ObservabilityPipelineOcsfMappingCustom) GetMappingOk() (*[]ObservabilityPipelineOcsfMappingCustomFieldMapping, bool) {
58+
if o == nil {
59+
return nil, false
60+
}
61+
return &o.Mapping, true
62+
}
63+
64+
// SetMapping sets field value.
65+
func (o *ObservabilityPipelineOcsfMappingCustom) SetMapping(v []ObservabilityPipelineOcsfMappingCustomFieldMapping) {
66+
o.Mapping = v
67+
}
68+
69+
// GetMetadata returns the Metadata field value.
70+
func (o *ObservabilityPipelineOcsfMappingCustom) GetMetadata() ObservabilityPipelineOcsfMappingCustomMetadata {
71+
if o == nil {
72+
var ret ObservabilityPipelineOcsfMappingCustomMetadata
73+
return ret
74+
}
75+
return o.Metadata
76+
}
77+
78+
// GetMetadataOk returns a tuple with the Metadata field value
79+
// and a boolean to check if the value has been set.
80+
func (o *ObservabilityPipelineOcsfMappingCustom) GetMetadataOk() (*ObservabilityPipelineOcsfMappingCustomMetadata, bool) {
81+
if o == nil {
82+
return nil, false
83+
}
84+
return &o.Metadata, true
85+
}
86+
87+
// SetMetadata sets field value.
88+
func (o *ObservabilityPipelineOcsfMappingCustom) SetMetadata(v ObservabilityPipelineOcsfMappingCustomMetadata) {
89+
o.Metadata = v
90+
}
91+
92+
// GetVersion returns the Version field value.
93+
func (o *ObservabilityPipelineOcsfMappingCustom) GetVersion() int64 {
94+
if o == nil {
95+
var ret int64
96+
return ret
97+
}
98+
return o.Version
99+
}
100+
101+
// GetVersionOk returns a tuple with the Version field value
102+
// and a boolean to check if the value has been set.
103+
func (o *ObservabilityPipelineOcsfMappingCustom) GetVersionOk() (*int64, bool) {
104+
if o == nil {
105+
return nil, false
106+
}
107+
return &o.Version, true
108+
}
109+
110+
// SetVersion sets field value.
111+
func (o *ObservabilityPipelineOcsfMappingCustom) SetVersion(v int64) {
112+
o.Version = v
113+
}
114+
115+
// MarshalJSON serializes the struct using spec logic.
116+
func (o ObservabilityPipelineOcsfMappingCustom) MarshalJSON() ([]byte, error) {
117+
toSerialize := map[string]interface{}{}
118+
if o.UnparsedObject != nil {
119+
return datadog.Marshal(o.UnparsedObject)
120+
}
121+
toSerialize["mapping"] = o.Mapping
122+
toSerialize["metadata"] = o.Metadata
123+
toSerialize["version"] = o.Version
124+
125+
for key, value := range o.AdditionalProperties {
126+
toSerialize[key] = value
127+
}
128+
return datadog.Marshal(toSerialize)
129+
}
130+
131+
// UnmarshalJSON deserializes the given payload.
132+
func (o *ObservabilityPipelineOcsfMappingCustom) UnmarshalJSON(bytes []byte) (err error) {
133+
all := struct {
134+
Mapping *[]ObservabilityPipelineOcsfMappingCustomFieldMapping `json:"mapping"`
135+
Metadata *ObservabilityPipelineOcsfMappingCustomMetadata `json:"metadata"`
136+
Version *int64 `json:"version"`
137+
}{}
138+
if err = datadog.Unmarshal(bytes, &all); err != nil {
139+
return datadog.Unmarshal(bytes, &o.UnparsedObject)
140+
}
141+
if all.Mapping == nil {
142+
return fmt.Errorf("required field mapping missing")
143+
}
144+
if all.Metadata == nil {
145+
return fmt.Errorf("required field metadata missing")
146+
}
147+
if all.Version == nil {
148+
return fmt.Errorf("required field version missing")
149+
}
150+
additionalProperties := make(map[string]interface{})
151+
if err = datadog.Unmarshal(bytes, &additionalProperties); err == nil {
152+
datadog.DeleteKeys(additionalProperties, &[]string{"mapping", "metadata", "version"})
153+
} else {
154+
return err
155+
}
156+
157+
hasInvalidField := false
158+
o.Mapping = *all.Mapping
159+
if all.Metadata.UnparsedObject != nil && o.UnparsedObject == nil {
160+
hasInvalidField = true
161+
}
162+
o.Metadata = *all.Metadata
163+
o.Version = *all.Version
164+
165+
if len(additionalProperties) > 0 {
166+
o.AdditionalProperties = additionalProperties
167+
}
168+
169+
if hasInvalidField {
170+
return datadog.Unmarshal(bytes, &o.UnparsedObject)
171+
}
172+
173+
return nil
174+
}

0 commit comments

Comments
 (0)