Skip to content

Commit 18c8a9d

Browse files
committed
[processor/k8sattributes] remove deprecated FieldExtractConfig.Regex parameter
Signed-off-by: odubajDT <[email protected]>
1 parent 44eb293 commit 18c8a9d

File tree

7 files changed

+41
-253
lines changed

7 files changed

+41
-253
lines changed

.chloggen/regex-deprecation.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: breaking
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: processor/k8sattributes
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: "Remove deprecated FieldExtractConfig.Regex parameter"
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [25128]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext:
19+
20+
# If your change doesn't affect end users or the exported elements of any package,
21+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: []

processor/k8sattributesprocessor/README.md

Lines changed: 3 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -233,21 +233,18 @@ extract:
233233
- tag_name: a1 # extracts value of annotation from pods with key `annotation-one` and inserts it as a tag with key `a1`
234234
key: annotation-one
235235
from: pod
236-
- tag_name: a2 # extracts value of annotation from namespaces with key `annotation-two` with regexp and inserts it as a tag with key `a2`
236+
- tag_name: a2 # extracts value of annotation from namespaces with key `annotation-two` and inserts it as a tag with key `a2`
237237
key: annotation-two
238-
regex: field=(?P<value>.+)
239238
from: namespace
240-
- tag_name: a3 # extracts value of annotation from nodes with key `annotation-three` with regexp and inserts it as a tag with key `a3`
239+
- tag_name: a3 # extracts value of annotation from nodes with key `annotation-three` and inserts it as a tag with key `a3`
241240
key: annotation-three
242-
regex: field=(?P<value>.+)
243241
from: node
244242
labels:
245243
- tag_name: l1 # extracts value of label from namespaces with key `label1` and inserts it as a tag with key `l1`
246244
key: label1
247245
from: namespace
248-
- tag_name: l2 # extracts value of label from pods with key `label2` with regexp and inserts it as a tag with key `l2`
246+
- tag_name: l2 # extracts value of label from pods with key `label2` and inserts it as a tag with key `l2`
249247
key: label2
250-
regex: field=(?P<value>.+)
251248
from: pod
252249
- tag_name: l3 # extracts value of label from nodes with key `label3` and inserts it as a tag with key `l3`
253250
key: label3
@@ -474,51 +471,3 @@ as tags.
474471

475472
By default, the `k8s.pod.start_time` uses [Time.MarshalText()](https://pkg.go.dev/time#Time.MarshalText) to format the
476473
timestamp value as an RFC3339 compliant timestamp.
477-
478-
## Feature Gate
479-
480-
### `k8sattr.fieldExtractConfigRegex.disallow`
481-
482-
The `k8sattr.fieldExtractConfigRegex.disallow` [feature gate](https://github.com/open-telemetry/opentelemetry-collector/blob/main/featuregate/README.md#collector-feature-gates) disallows the usage of the `extract.annotations.regex` and `extract.labels.regex` fields.
483-
The validation performed on the configuration will fail, if at least one of the parameters is set (non-empty) and `k8sattr.fieldExtractConfigRegex.disallow` is set to `true` (default `false`).
484-
485-
#### Example Usage
486-
487-
The following config with the feature gate set will lead to validation error:
488-
489-
`config.yaml`:
490-
491-
```yaml
492-
extract:
493-
labels:
494-
regex: <my-regex1>
495-
annotations:
496-
regex: <my-regex2>
497-
```
498-
499-
Run collector: `./otelcol --config config.yaml --feature-gates=k8sattr.fieldExtractConfigRegex.disallow`
500-
501-
#### Migration
502-
503-
Deprecation of the `extract.annotations.regex` and `extract.labels.regex` fields means that it is recommended to use the `ExtractPatterns` function from the transform processor instead. To convert your current configuration please check the `ExtractPatterns` function [documentation](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/ottl/ottlfuncs#extractpatterns). You should use the `pattern` parameter of `ExtractPatterns` instead of using the `extract.annotations.regex` and `extract.labels.regex` fields.
504-
505-
##### Example
506-
507-
The following configuration of `k8sattributes processor`:
508-
509-
`config.yaml`:
510-
511-
```yaml
512-
annotations:
513-
- tag_name: a2 # extracts value of annotation with key `annotation2` with regexp and inserts it as a tag with key `a2`
514-
key: annotation2
515-
regex: field=(?P<value>.+)
516-
from: pod
517-
```
518-
519-
can be converted with the usage of `ExtractPatterns` function:
520-
521-
```yaml
522-
- set(cache["annotations"], ExtractPatterns(attributes["k8s.pod.annotations["annotation2"], "field=(?P<value>.+))")
523-
- set(k8s.pod.annotations["a2"], cache["annotations"]["value"])
524-
```

processor/k8sattributesprocessor/config.go

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,12 @@ import (
88
"regexp"
99
"time"
1010

11-
"go.opentelemetry.io/collector/featuregate"
1211
conventions "go.opentelemetry.io/collector/semconv/v1.6.1"
1312

1413
"github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8sconfig"
1514
"github.com/open-telemetry/opentelemetry-collector-contrib/processor/k8sattributesprocessor/internal/kube"
1615
)
1716

18-
var disallowFieldExtractConfigRegex = featuregate.GlobalRegistry().MustRegister(
19-
"k8sattr.fieldExtractConfigRegex.disallow",
20-
featuregate.StageBeta,
21-
featuregate.WithRegisterDescription("When enabled, usage of the FieldExtractConfig.Regex field is disallowed"),
22-
featuregate.WithRegisterFromVersion("v0.106.0"),
23-
)
24-
2517
// Config defines configuration for k8s attributes processor.
2618
type Config struct {
2719
k8sconfig.APIConfig `mapstructure:",squash"`
@@ -77,20 +69,6 @@ func (cfg *Config) Validate() error {
7769
return fmt.Errorf("%s is not a valid choice for From. Must be one of: pod, namespace, node", f.From)
7870
}
7971

80-
if f.Regex != "" {
81-
if disallowFieldExtractConfigRegex.IsEnabled() {
82-
return fmt.Errorf("the extract.annotations.regex and extract.labels.regex fields have been deprecated, please use the `ExtractPatterns` function in the transform processor instead")
83-
}
84-
r, err := regexp.Compile(f.Regex)
85-
if err != nil {
86-
return err
87-
}
88-
names := r.SubexpNames()
89-
if len(names) != 2 || names[1] != "value" {
90-
return fmt.Errorf("regex must contain exactly one named submatch (value)")
91-
}
92-
}
93-
9472
if f.KeyRegex != "" {
9573
_, err := regexp.Compile("^(?:" + f.KeyRegex + ")$")
9674
if err != nil {
@@ -212,29 +190,6 @@ type FieldExtractConfig struct {
212190
// Out of Key or KeyRegex, only one option is expected to be configured at a time.
213191
KeyRegex string `mapstructure:"key_regex"`
214192

215-
// Regex is an optional field used to extract a sub-string from a complex field value.
216-
// The supplied regular expression must contain one named parameter with the string "value"
217-
// as the name. For example, if your pod spec contains the following annotation,
218-
//
219-
// kubernetes.io/change-cause: 2019-08-28T18:34:33Z APP_NAME=my-app GIT_SHA=58a1e39 CI_BUILD=4120
220-
//
221-
// and you'd like to extract the GIT_SHA and the CI_BUILD values as tags, then you must
222-
// specify the following two extraction rules:
223-
//
224-
// extract:
225-
// annotations:
226-
// - tag_name: git.sha
227-
// key: kubernetes.io/change-cause
228-
// regex: GIT_SHA=(?P<value>\w+)
229-
// - tag_name: ci.build
230-
// key: kubernetes.io/change-cause
231-
// regex: JENKINS=(?P<value>[\w]+)
232-
//
233-
// this will add the `git.sha` and `ci.build` resource attributes.
234-
// Deprecated: [v0.106.0] Use the `ExtractPatterns` function in the transform processor instead.
235-
// More information about how to replace the regex field can be found in the k8sattributes processor readme.
236-
Regex string `mapstructure:"regex"`
237-
238193
// From represents the source of the labels/annotations.
239194
// Allowed values are "pod", "namespace", and "node". The default is pod.
240195
From string `mapstructure:"from"`

processor/k8sattributesprocessor/config_test.go

Lines changed: 4 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"github.com/stretchr/testify/require"
1313
"go.opentelemetry.io/collector/component"
1414
"go.opentelemetry.io/collector/confmap/confmaptest"
15-
"go.opentelemetry.io/collector/featuregate"
1615

1716
"github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8sconfig"
1817
"github.com/open-telemetry/opentelemetry-collector-contrib/processor/k8sattributesprocessor/internal/kube"
@@ -23,9 +22,8 @@ func TestLoadConfig(t *testing.T) {
2322
t.Parallel()
2423

2524
tests := []struct {
26-
id component.ID
27-
expected component.Config
28-
disallowRegex bool
25+
id component.ID
26+
expected component.Config
2927
}{
3028
{
3129
id: component.NewID(metadata.Type),
@@ -47,11 +45,11 @@ func TestLoadConfig(t *testing.T) {
4745
Metadata: []string{"k8s.pod.name", "k8s.pod.uid", "k8s.pod.ip", "k8s.deployment.name", "k8s.namespace.name", "k8s.node.name", "k8s.pod.start_time", "k8s.cluster.uid"},
4846
Annotations: []FieldExtractConfig{
4947
{TagName: "a1", Key: "annotation-one", From: "pod"},
50-
{TagName: "a2", Key: "annotation-two", Regex: "field=(?P<value>.+)", From: kube.MetadataFromPod},
48+
{TagName: "a2", Key: "annotation-two", From: kube.MetadataFromPod},
5149
},
5250
Labels: []FieldExtractConfig{
5351
{TagName: "l1", Key: "label1", From: "pod"},
54-
{TagName: "l2", Key: "label2", Regex: "field=(?P<value>.+)", From: kube.MetadataFromPod},
52+
{TagName: "l2", Key: "label2", From: kube.MetadataFromPod},
5553
},
5654
},
5755
Filter: FilterConfig{
@@ -109,7 +107,6 @@ func TestLoadConfig(t *testing.T) {
109107
},
110108
WaitForMetadataTimeout: 10 * time.Second,
111109
},
112-
disallowRegex: false,
113110
},
114111
{
115112
id: component.NewIDWithName(metadata.Type, "3"),
@@ -134,37 +131,9 @@ func TestLoadConfig(t *testing.T) {
134131
WaitForMetadataTimeout: 10 * time.Second,
135132
},
136133
},
137-
{
138-
id: component.NewIDWithName(metadata.Type, "deprecated-regex"),
139-
expected: &Config{
140-
APIConfig: k8sconfig.APIConfig{AuthType: k8sconfig.AuthTypeKubeConfig},
141-
Passthrough: false,
142-
Extract: ExtractConfig{
143-
Metadata: enabledAttributes(),
144-
Annotations: []FieldExtractConfig{
145-
{Regex: "field=(?P<value>.+)", From: "pod"},
146-
},
147-
Labels: []FieldExtractConfig{
148-
{Regex: "field=(?P<value>.+)", From: "pod"},
149-
},
150-
},
151-
Exclude: ExcludeConfig{
152-
Pods: []ExcludePodConfig{
153-
{Name: "jaeger-agent"},
154-
{Name: "jaeger-collector"},
155-
},
156-
},
157-
WaitForMetadataTimeout: 10 * time.Second,
158-
},
159-
disallowRegex: false,
160-
},
161134
{
162135
id: component.NewIDWithName(metadata.Type, "too_many_sources"),
163136
},
164-
{
165-
id: component.NewIDWithName(metadata.Type, "deprecated-regex"),
166-
disallowRegex: true,
167-
},
168137
{
169138
id: component.NewIDWithName(metadata.Type, "bad_keys_labels"),
170139
},
@@ -177,30 +146,12 @@ func TestLoadConfig(t *testing.T) {
177146
{
178147
id: component.NewIDWithName(metadata.Type, "bad_from_annotations"),
179148
},
180-
{
181-
id: component.NewIDWithName(metadata.Type, "bad_regex_labels"),
182-
},
183-
{
184-
id: component.NewIDWithName(metadata.Type, "bad_regex_annotations"),
185-
},
186149
{
187150
id: component.NewIDWithName(metadata.Type, "bad_keyregex_labels"),
188151
},
189152
{
190153
id: component.NewIDWithName(metadata.Type, "bad_keyregex_annotations"),
191154
},
192-
{
193-
id: component.NewIDWithName(metadata.Type, "bad_regex_groups_labels"),
194-
},
195-
{
196-
id: component.NewIDWithName(metadata.Type, "bad_regex_groups_annotations"),
197-
},
198-
{
199-
id: component.NewIDWithName(metadata.Type, "bad_regex_name_labels"),
200-
},
201-
{
202-
id: component.NewIDWithName(metadata.Type, "bad_regex_name_annotations"),
203-
},
204155
{
205156
id: component.NewIDWithName(metadata.Type, "bad_filter_label_op"),
206157
},
@@ -211,12 +162,6 @@ func TestLoadConfig(t *testing.T) {
211162

212163
for _, tt := range tests {
213164
t.Run(tt.id.String(), func(t *testing.T) {
214-
if !tt.disallowRegex {
215-
require.NoError(t, featuregate.GlobalRegistry().Set(disallowFieldExtractConfigRegex.ID(), false))
216-
t.Cleanup(func() {
217-
require.NoError(t, featuregate.GlobalRegistry().Set(disallowFieldExtractConfigRegex.ID(), true))
218-
})
219-
}
220165
cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config.yaml"))
221166
require.NoError(t, err)
222167

processor/k8sattributesprocessor/options.go

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -236,15 +236,6 @@ func extractFieldRules(fieldType string, fields ...FieldExtractConfig) ([]kube.F
236236
name = fmt.Sprintf("k8s.%v.%v.%v", a.From, fieldType, a.Key)
237237
}
238238

239-
var r *regexp.Regexp
240-
if a.Regex != "" {
241-
var err error
242-
r, err = regexp.Compile(a.Regex)
243-
if err != nil {
244-
return rules, err
245-
}
246-
}
247-
248239
var keyRegex *regexp.Regexp
249240
var hasKeyRegexReference bool
250241
if a.KeyRegex != "" {
@@ -260,7 +251,7 @@ func extractFieldRules(fieldType string, fields ...FieldExtractConfig) ([]kube.F
260251
}
261252

262253
rules = append(rules, kube.FieldExtractionRule{
263-
Name: name, Key: a.Key, KeyRegex: keyRegex, HasKeyRegexReference: hasKeyRegexReference, Regex: r, From: a.From,
254+
Name: name, Key: a.Key, KeyRegex: keyRegex, HasKeyRegexReference: hasKeyRegexReference, From: a.From,
264255
})
265256
}
266257
return rules, nil

processor/k8sattributesprocessor/options_test.go

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -89,16 +89,14 @@ func TestWithExtractAnnotations(t *testing.T) {
8989
{
9090
TagName: "tag1",
9191
Key: "key1",
92-
Regex: "field=(?P<value>.+)",
9392
From: kube.MetadataFromPod,
9493
},
9594
},
9695
[]kube.FieldExtractionRule{
9796
{
98-
Name: "tag1",
99-
Key: "key1",
100-
Regex: regexp.MustCompile(`field=(?P<value>.+)`),
101-
From: kube.MetadataFromPod,
97+
Name: "tag1",
98+
Key: "key1",
99+
From: kube.MetadataFromPod,
102100
},
103101
},
104102
"",
@@ -228,16 +226,14 @@ func TestWithExtractLabels(t *testing.T) {
228226
{
229227
TagName: "tag1",
230228
Key: "key1",
231-
Regex: "field=(?P<value>.+)",
232229
From: kube.MetadataFromPod,
233230
},
234231
},
235232
[]kube.FieldExtractionRule{
236233
{
237-
Name: "tag1",
238-
Key: "key1",
239-
Regex: regexp.MustCompile(`field=(?P<value>.+)`),
240-
From: kube.MetadataFromPod,
234+
Name: "tag1",
235+
Key: "key1",
236+
From: kube.MetadataFromPod,
241237
},
242238
},
243239
"",
@@ -610,18 +606,6 @@ func Test_extractFieldRules(t *testing.T) {
610606
},
611607
},
612608
},
613-
{
614-
name: "badregex",
615-
args: args{"field", []FieldExtractConfig{
616-
{
617-
TagName: "name",
618-
Key: "key",
619-
Regex: "[",
620-
From: kube.MetadataFromPod,
621-
},
622-
}},
623-
wantErr: true,
624-
},
625609
{
626610
name: "keyregex-capture-group",
627611
args: args{"labels", []FieldExtractConfig{

0 commit comments

Comments
 (0)