Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions api/observability/v1/output_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1262,6 +1262,7 @@ type SplunkAuthentication struct {

// Splunk Deliver log data to Splunk’s HTTP Event Collector
// Provides optional extra properties for `type: splunk_hec` ('splunk_hec_logs' after Vector 0.23
// +kubebuilder:validation:XValidation:rule="!has(self.sourceType) || has(self.payloadKey)",message="sourceType can only be set when payloadKey is defined"
type Splunk struct {
// Authentication sets credentials for authenticating the requests.
//
Expand Down Expand Up @@ -1314,7 +1315,7 @@ type Splunk struct {
// Source identifies the origin of a log event.
// The Source can be a combination of static and dynamic values consisting of field paths followed by `||` followed by another field path or a static value.
// A dynamic value is encased in single curly brackets `{}` and MUST end with a static fallback value separated with `||`.
// Static values can only contain alphanumeric characters along with dashes, underscores, dots and forward slashes.
// Static values can only contain alphanumeric characters along with dashes, underscores, dots, colons and forward slashes.
// If not specified will be detected according to .log_source and .log_type value.
// Details see in: docs/features/logforwarding/outputs/splunk-forwarding.adoc
//
Expand All @@ -1327,10 +1328,39 @@ type Splunk struct {
// 3. foo.{.bar.baz||.qux.quux.corge||.grault||"nil"}-waldo.fred{.plugh||"none"}
//
// +kubebuilder:validation:Optional
// +kubebuilder:validation:Pattern:=`^(([a-zA-Z0-9-_.\/])*(\{(\.[a-zA-Z0-9_]+|\."[^"]+")+((\|\|)(\.[a-zA-Z0-9_]+|\.?"[^"]+")+)*\|\|"[^"]*"\})*)*$`
// +kubebuilder:validation:Pattern:=`^(([a-zA-Z0-9-_.:\/])*(\{(\.[a-zA-Z0-9_]+|\."[^"]+")+((\|\|)(\.[a-zA-Z0-9_]+|\.?"[^"]+")+)*\|\|"[^"]*"\})*)*$`
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Source",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text"}
Source string `json:"source,omitempty"`

// SourceType can be used to specify a pretrained or custom source type in Splunk, but can only be set when PayloadKey is defined.
//
// WARNING: The administrator is responsible for configuring the pipeline so the source type matches the log entry. The collector makes no effort or validation to ensure they match.
//
// If SourceType is not specified, the source type used is `_json`. If using PayloadKey without SourceType, the source type used will be either `_json` or `generic_single_line`, depending on the structure of the final event payload.
// Details in: docs/features/logforwarding/outputs/splunk-forwarding.adoc
//
// The SourceType can be a combination of static and dynamic values consisting of field paths followed by `||` followed by another field path or a static value.
// A dynamic value is encased in single curly brackets `{}` and MUST end with a static fallback value separated with `||`.
//
// Static values can only contain alphanumeric characters along with dashes, underscores, dots, colons and forward slashes.
//
// Examples:
//
// 1. {.kubernetes.labels."splunk/sourcetype"||"generic_single_line"}
//
// 2. log4j
//
// 3. foo-{.bar||"none"}
//
// 4. {.foo||.bar||"missing"}
//
// 5. foo.{.bar.baz||.qux.quux.corge||.grault||"nil"}-waldo.fred{.plugh||"none"}
//
// +kubebuilder:validation:Optional
// +kubebuilder:validation:Pattern:=`^(([a-zA-Z0-9-_.:\/])*(\{(\.[a-zA-Z0-9_]+|\."[^"]+")+((\|\|)(\.[a-zA-Z0-9_]+|\.?"[^"]+")+)*\|\|"[^"]*"\})*)*$`
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="SourceType",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text"}
SourceType string `json:"sourceType,omitempty"`
Comment thread
jcantrill marked this conversation as resolved.
Comment on lines +1359 to +1362

@coderabbitai coderabbitai Bot May 5, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

SourceType pattern validation rejects colon — blocks the primary Splunk naming convention.

The pattern's static character class [a-zA-Z0-9-_.\/] does not include : (colon). The old Splunk style uses underscore separators (e.g., access_combined) while the new style uses colon separators (e.g., ibm:ldap:audit), and the tradition is to use a single colon to denote the hierarchical levels from least specific to most specific — the software product is listed first, then the specific component of the product. Real-world examples like cisco:esa:textmail, zeek:conn:json, and the PR description's own example my:custom:sourcetype would all be rejected by the current pattern.

A user wanting a static colon-separated sourcetype has no clean workaround: my:custom:sourcetype fails validation, and the template syntax cannot encode a bare static string with colons either.

🐛 Proposed fix — add : to the static character class
-	// +kubebuilder:validation:Pattern:=`^(([a-zA-Z0-9-_.\/])*(\{(\.[a-zA-Z0-9_]+|\."[^"]+")+((\|\|)(\.[a-zA-Z0-9_]+|\.?"[^"]+")+)*\|\|"[^"]*"\})*)*$`
+	// +kubebuilder:validation:Pattern:=`^(([a-zA-Z0-9-_.:\/])*(\{(\.[a-zA-Z0-9_]+|\."[^"]+")+((\|\|)(\.[a-zA-Z0-9_]+|\.?"[^"]+")+)*\|\|"[^"]*"\})*)*$`

Also note that example 2 in the doc comment ("log4j" with literal double-quotes) would not match the pattern's static portion either. The intended value is simply log4j (no quotes), which does pass. The comment is misleading and should be corrected.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// +kubebuilder:validation:Optional
// +kubebuilder:validation:Pattern:=`^(([a-zA-Z0-9-_.\/])*(\{(\.[a-zA-Z0-9_]+|\."[^"]+")+((\|\|)(\.[a-zA-Z0-9_]+|\.?"[^"]+")+)*\|\|"[^"]*"\})*)*$`
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="SourceType",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text"}
SourceType string `json:"sourceType,omitempty"`
// +kubebuilder:validation:Optional
// +kubebuilder:validation:Pattern:=`^(([a-zA-Z0-9-_.:\/])*(\{(\.[a-zA-Z0-9_]+|\."[^"]+")+((\|\|)(\.[a-zA-Z0-9_]+|\.?"[^"]+")+)*\|\|"[^"]*"\})*)*$`
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="SourceType",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text"}
SourceType string `json:"sourceType,omitempty"`
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@api/observability/v1/output_types.go` around lines 1359 - 1362, The
kubebuilder validation pattern on the SourceType field (the struct tag on
SourceType string `json:"sourceType,omitempty"`) omits ':' in the static
character class causing valid colon-separated sourcetypes to be rejected; update
the +kubebuilder:validation:Pattern annotation to include ':' inside the static
class (e.g. add : to `[a-zA-Z0-9-_.\/]`) so values like "my:custom:sourcetype"
validate, and also correct the doc comment/example that shows `"log4j"` (remove
the stray quotes) so examples match the intended valid values.

✅ Addressed in commit 17bcba0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vparfonov @Clee2691 This pattern matcher is restricted by VRL. Do we have any idea if VRL would allow us to add a colon for this type? Given our template utilities it may complicate the other fields and we may need to think about how we would accept this suggestion?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!


// PayloadKey specifies record field to use as payload.
// The PayloadKey must be a single field path.
//
Expand Down
32 changes: 30 additions & 2 deletions bundle/manifests/cluster-logging.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ metadata:
categories: OpenShift Optional, Logging & Tracing, Observability
certified: "false"
containerImage: quay.io/openshift-logging/cluster-logging-operator:latest
createdAt: "2026-05-14T19:29:17Z"
createdAt: "2026-05-15T10:01:10Z"
description: The Red Hat OpenShift Logging Operator for OCP provides a means for
configuring and managing log collection and forwarding.
features.operators.openshift.io/cnf: "false"
Expand Down Expand Up @@ -1938,7 +1938,7 @@ spec:
Source identifies the origin of a log event.
The Source can be a combination of static and dynamic values consisting of field paths followed by `||` followed by another field path or a static value.
A dynamic value is encased in single curly brackets `{}` and MUST end with a static fallback value separated with `||`.
Static values can only contain alphanumeric characters along with dashes, underscores, dots and forward slashes.
Static values can only contain alphanumeric characters along with dashes, underscores, dots, colons and forward slashes.
If not specified will be detected according to .log_source and .log_type value.
Details see in: docs/features/logforwarding/outputs/splunk-forwarding.adoc

Expand All @@ -1953,6 +1953,34 @@ spec:
path: outputs[0].splunk.source
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- description: |-
SourceType can be used to specify a pretrained or custom source type in Splunk, but can only be set when PayloadKey is defined.

WARNING: The administrator is responsible for configuring the pipeline so the source type matches the log entry. The collector makes no effort or validation to ensure they match.

If SourceType is not specified, the source type used is `_json`. If using PayloadKey without SourceType, the source type used will be either `_json` or `generic_single_line`, depending on the structure of the final event payload.
Details in: docs/features/logforwarding/outputs/splunk-forwarding.adoc

The SourceType can be a combination of static and dynamic values consisting of field paths followed by `||` followed by another field path or a static value.
A dynamic value is encased in single curly brackets `{}` and MUST end with a static fallback value separated with `||`.

Static values can only contain alphanumeric characters along with dashes, underscores, dots, colons and forward slashes.

Examples:

1. {.kubernetes.labels."splunk/sourcetype"||"generic_single_line"}

2. log4j

3. foo-{.bar||"none"}

4. {.foo||.bar||"missing"}

5. foo.{.bar.baz||.qux.quux.corge||.grault||"nil"}-waldo.fred{.plugh||"none"}
displayName: SourceType
path: outputs[0].splunk.sourceType
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- description: Tuning specs tuning for the output
displayName: Tuning Options
path: outputs[0].splunk.tuning
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3894,7 +3894,7 @@ spec:
Source identifies the origin of a log event.
The Source can be a combination of static and dynamic values consisting of field paths followed by `||` followed by another field path or a static value.
A dynamic value is encased in single curly brackets `{}` and MUST end with a static fallback value separated with `||`.
Static values can only contain alphanumeric characters along with dashes, underscores, dots and forward slashes.
Static values can only contain alphanumeric characters along with dashes, underscores, dots, colons and forward slashes.
If not specified will be detected according to .log_source and .log_type value.
Details see in: docs/features/logforwarding/outputs/splunk-forwarding.adoc

Expand All @@ -3905,7 +3905,34 @@ spec:
2. {.foo||.bar||"missing"}

3. foo.{.bar.baz||.qux.quux.corge||.grault||"nil"}-waldo.fred{.plugh||"none"}
pattern: ^(([a-zA-Z0-9-_.\/])*(\{(\.[a-zA-Z0-9_]+|\."[^"]+")+((\|\|)(\.[a-zA-Z0-9_]+|\.?"[^"]+")+)*\|\|"[^"]*"\})*)*$
pattern: ^(([a-zA-Z0-9-_.:\/])*(\{(\.[a-zA-Z0-9_]+|\."[^"]+")+((\|\|)(\.[a-zA-Z0-9_]+|\.?"[^"]+")+)*\|\|"[^"]*"\})*)*$
type: string
sourceType:
description: |-
SourceType can be used to specify a pretrained or custom source type in Splunk, but can only be set when PayloadKey is defined.

WARNING: The administrator is responsible for configuring the pipeline so the source type matches the log entry. The collector makes no effort or validation to ensure they match.

If SourceType is not specified, the source type used is `_json`. If using PayloadKey without SourceType, the source type used will be either `_json` or `generic_single_line`, depending on the structure of the final event payload.
Details in: docs/features/logforwarding/outputs/splunk-forwarding.adoc

The SourceType can be a combination of static and dynamic values consisting of field paths followed by `||` followed by another field path or a static value.
A dynamic value is encased in single curly brackets `{}` and MUST end with a static fallback value separated with `||`.

Static values can only contain alphanumeric characters along with dashes, underscores, dots, colons and forward slashes.

Examples:

1. {.kubernetes.labels."splunk/sourcetype"||"generic_single_line"}

2. log4j

3. foo-{.bar||"none"}

4. {.foo||.bar||"missing"}

5. foo.{.bar.baz||.qux.quux.corge||.grault||"nil"}-waldo.fred{.plugh||"none"}
pattern: ^(([a-zA-Z0-9-_.:\/])*(\{(\.[a-zA-Z0-9_]+|\."[^"]+")+((\|\|)(\.[a-zA-Z0-9_]+|\.?"[^"]+")+)*\|\|"[^"]*"\})*)*$
type: string
tuning:
description: Tuning specs tuning for the output
Expand Down Expand Up @@ -3960,6 +3987,9 @@ spec:
- authentication
- url
type: object
x-kubernetes-validations:
- message: sourceType can only be set when payloadKey is defined
rule: '!has(self.sourceType) || has(self.payloadKey)'
syslog:
description: Syslog configures forwarding log events to a receiver
using the syslog protocol
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3894,7 +3894,7 @@ spec:
Source identifies the origin of a log event.
The Source can be a combination of static and dynamic values consisting of field paths followed by `||` followed by another field path or a static value.
A dynamic value is encased in single curly brackets `{}` and MUST end with a static fallback value separated with `||`.
Static values can only contain alphanumeric characters along with dashes, underscores, dots and forward slashes.
Static values can only contain alphanumeric characters along with dashes, underscores, dots, colons and forward slashes.
If not specified will be detected according to .log_source and .log_type value.
Details see in: docs/features/logforwarding/outputs/splunk-forwarding.adoc

Expand All @@ -3905,7 +3905,34 @@ spec:
2. {.foo||.bar||"missing"}

3. foo.{.bar.baz||.qux.quux.corge||.grault||"nil"}-waldo.fred{.plugh||"none"}
pattern: ^(([a-zA-Z0-9-_.\/])*(\{(\.[a-zA-Z0-9_]+|\."[^"]+")+((\|\|)(\.[a-zA-Z0-9_]+|\.?"[^"]+")+)*\|\|"[^"]*"\})*)*$
pattern: ^(([a-zA-Z0-9-_.:\/])*(\{(\.[a-zA-Z0-9_]+|\."[^"]+")+((\|\|)(\.[a-zA-Z0-9_]+|\.?"[^"]+")+)*\|\|"[^"]*"\})*)*$
type: string
sourceType:
description: |-
SourceType can be used to specify a pretrained or custom source type in Splunk, but can only be set when PayloadKey is defined.

WARNING: The administrator is responsible for configuring the pipeline so the source type matches the log entry. The collector makes no effort or validation to ensure they match.

If SourceType is not specified, the source type used is `_json`. If using PayloadKey without SourceType, the source type used will be either `_json` or `generic_single_line`, depending on the structure of the final event payload.
Details in: docs/features/logforwarding/outputs/splunk-forwarding.adoc

The SourceType can be a combination of static and dynamic values consisting of field paths followed by `||` followed by another field path or a static value.
A dynamic value is encased in single curly brackets `{}` and MUST end with a static fallback value separated with `||`.

Static values can only contain alphanumeric characters along with dashes, underscores, dots, colons and forward slashes.

Examples:

1. {.kubernetes.labels."splunk/sourcetype"||"generic_single_line"}

2. log4j

Comment thread
coderabbitai[bot] marked this conversation as resolved.
3. foo-{.bar||"none"}

4. {.foo||.bar||"missing"}

5. foo.{.bar.baz||.qux.quux.corge||.grault||"nil"}-waldo.fred{.plugh||"none"}
pattern: ^(([a-zA-Z0-9-_.:\/])*(\{(\.[a-zA-Z0-9_]+|\."[^"]+")+((\|\|)(\.[a-zA-Z0-9_]+|\.?"[^"]+")+)*\|\|"[^"]*"\})*)*$
type: string
tuning:
description: Tuning specs tuning for the output
Expand Down Expand Up @@ -3960,6 +3987,9 @@ spec:
- authentication
- url
type: object
x-kubernetes-validations:
- message: sourceType can only be set when payloadKey is defined
rule: '!has(self.sourceType) || has(self.payloadKey)'
syslog:
description: Syslog configures forwarding log events to a receiver
using the syslog protocol
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1861,7 +1861,7 @@ spec:
Source identifies the origin of a log event.
The Source can be a combination of static and dynamic values consisting of field paths followed by `||` followed by another field path or a static value.
A dynamic value is encased in single curly brackets `{}` and MUST end with a static fallback value separated with `||`.
Static values can only contain alphanumeric characters along with dashes, underscores, dots and forward slashes.
Static values can only contain alphanumeric characters along with dashes, underscores, dots, colons and forward slashes.
If not specified will be detected according to .log_source and .log_type value.
Details see in: docs/features/logforwarding/outputs/splunk-forwarding.adoc

Expand All @@ -1876,6 +1876,34 @@ spec:
path: outputs[0].splunk.source
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- description: |-
SourceType can be used to specify a pretrained or custom source type in Splunk, but can only be set when PayloadKey is defined.

WARNING: The administrator is responsible for configuring the pipeline so the source type matches the log entry. The collector makes no effort or validation to ensure they match.

If SourceType is not specified, the source type used is `_json`. If using PayloadKey without SourceType, the source type used will be either `_json` or `generic_single_line`, depending on the structure of the final event payload.
Details in: docs/features/logforwarding/outputs/splunk-forwarding.adoc

The SourceType can be a combination of static and dynamic values consisting of field paths followed by `||` followed by another field path or a static value.
A dynamic value is encased in single curly brackets `{}` and MUST end with a static fallback value separated with `||`.

Static values can only contain alphanumeric characters along with dashes, underscores, dots, colons and forward slashes.

Examples:

1. {.kubernetes.labels."splunk/sourcetype"||"generic_single_line"}

2. log4j

3. foo-{.bar||"none"}

4. {.foo||.bar||"missing"}

5. foo.{.bar.baz||.qux.quux.corge||.grault||"nil"}-waldo.fred{.plugh||"none"}
displayName: SourceType
path: outputs[0].splunk.sourceType
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- description: Tuning specs tuning for the output
displayName: Tuning Options
path: outputs[0].splunk.tuning
Expand Down
Loading