-
Notifications
You must be signed in to change notification settings - Fork 2.2k
feat: allow wildcards as part of annotations and labels in allowlists #2873
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -178,24 +178,52 @@ func isPrefixedNativeResource(name v1.ResourceName) bool { | |
| // createPrometheusLabelKeysValues takes in passed kubernetes annotations/labels | ||
| // and associated allowed list in kubernetes label format. | ||
| // It returns only those allowed annotations/labels that exist in the list and converts them to Prometheus labels. | ||
| // Full wildcards (*) can only be set as first in the allow list, partial wildcards can appear anywhere in the list | ||
| func createPrometheusLabelKeysValues(prefix string, allKubeData map[string]string, allowList []string) ([]string, []string) { | ||
| allowedKubeData := make(map[string]string) | ||
|
|
||
| if len(allowList) > 0 { | ||
| if allowList[0] == options.LabelWildcard { | ||
| return kubeMapToPrometheusLabels(prefix, allKubeData) | ||
| for i, l := range allowList { | ||
| // only the first label can be the wildcard label | ||
| if l == options.LabelWildcard { | ||
| if i == 0 { | ||
| return kubeMapToPrometheusLabels(prefix, allKubeData) | ||
| } | ||
| continue | ||
| } | ||
|
|
||
| for _, l := range allowList { | ||
| v, found := allKubeData[l] | ||
| if found { | ||
| allowedKubeData[l] = v | ||
| // prepare regular expression based on potential wildcards | ||
| re, err := regexp.Compile(expandWildcard(l, options.MaxPartialWildcardsPerLabel)) | ||
| if err != nil { | ||
| continue | ||
| } | ||
|
Comment on lines
+196
to
+198
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We'd want to surface these to the user.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How do you suggest I'd implement that? The function |
||
| for k, v := range allKubeData { | ||
| if re.MatchString(k) { | ||
| allowedKubeData[k] = v | ||
| } | ||
| } | ||
|
skoef marked this conversation as resolved.
Comment on lines
+185
to
203
|
||
| } | ||
|
|
||
| return kubeMapToPrometheusLabels(prefix, allowedKubeData) | ||
| } | ||
|
|
||
| // expandWildcard expands wildcards (*) to regular expressions, up to a limited number of wildcards | ||
| func expandWildcard(pattern string, limit uint) string { | ||
|
skoef marked this conversation as resolved.
|
||
| var result strings.Builder | ||
| var replacements uint | ||
| for i, literal := range strings.Split(pattern, options.LabelWildcard) { | ||
| if i > 0 { | ||
| result.WriteString(".*") | ||
| replacements++ | ||
| } | ||
|
|
||
| result.WriteString(regexp.QuoteMeta(literal)) | ||
| if replacements >= limit { | ||
| break | ||
| } | ||
| } | ||
| return "^" + result.String() + "$" | ||
| } | ||
|
Comment on lines
+209
to
+225
|
||
|
|
||
| // mergeKeyValues merges label keys and values slice pairs into a single slice pair. | ||
| // Arguments are passed as equal-length pairs of slices, where the first slice contains keys and second contains values. | ||
| // Example: mergeKeyValues(keys1, values1, keys2, values2) => (keys1+keys2, values1+values2) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
createPrometheusLabelKeysValues now compiles a regexp and scans allKubeData for every allowList entry, even when the allowList entry is an exact key (no '*'). This changes the complexity from O(len(allowList)) map lookups to O(len(allowList)len(allKubeData)) and adds per-object regexp compilation. Consider fast-pathing entries without '' using a direct map lookup, and only compiling/scanning for patterns that actually contain a wildcard (or precompiling patterns once when parsing options).
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we use the label(-description) as the basis for the regex, we can't prepare the regex outside of this loop.