Skip to content
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

Allow empty separator in relabel config #6425

Merged
merged 1 commit into from
Apr 3, 2024

Conversation

haanhvu
Copy link
Contributor

@haanhvu haanhvu commented Mar 23, 2024

Description

Fixes #5003

Currently we don't allow empty separator in relabel config. If users specify an empty separator, it will be turned into the default ; from Prometheus side. Since Prometheus makes use of empty separator, Prometheus operator should do that too.

Type of change

What type of changes does your code introduce to the Prometheus operator? Put an x in the box that apply.

  • CHANGE (fix or feature that would cause existing functionality to not work as expected)
  • FEATURE (non-breaking change which adds functionality)
  • BUGFIX (non-breaking change which fixes an issue)
  • ENHANCEMENT (non-breaking change which improves existing functionality)
  • NONE (if none of the other choices apply. Example, tooling, build system, CI, docs, etc.)

Verification

No tests broken. New tests passed.

Changelog entry

Allow empty seperator in relabel config

Question

Is this considered a breaking change?

@haanhvu haanhvu requested a review from a team as a code owner March 23, 2024 11:31
@haanhvu haanhvu changed the title Allow empty seperator in relabel config WIP: Allow empty seperator in relabel config Mar 23, 2024
@pull-request-size pull-request-size bot added size/M and removed size/L labels Mar 23, 2024
@haanhvu
Copy link
Contributor Author

haanhvu commented Mar 23, 2024

@slashpai Could you review?

Basically, I followed your PR. Just did 2 changes:

  • Change //+kubebuilder:default=; to //+kubebuilder:default=";". Without "" it would generate array type instead of string type, as you could see in your PR.
  • Fixed tests

@haanhvu haanhvu changed the title WIP: Allow empty seperator in relabel config Allow empty seperator in relabel config Mar 23, 2024
@slashpai
Copy link
Contributor

Thanks for taking this up.
Did you test with a local cluster if changes are working?

@haanhvu
Copy link
Contributor Author

haanhvu commented Mar 25, 2024

Thanks for taking this up. Did you test with a local cluster if changes are working?

I ran with ./scripts/run-external.sh -c and it ran successfully. But as you can see, some e2e are failing. At first I thought it was flaky but now looked deeper into the code I see the failure may relate to my change.

I think I need to look deeper into how this is handled in Prometheus codebase. From my experience label-related changes are very bug-prone. Don't want to reinvent the wheel and create a bunch of subtle bugs...

@haanhvu haanhvu force-pushed the issue5003-1 branch 2 times, most recently from 8eeb779 to d366d68 Compare March 25, 2024 14:06
@@ -1497,7 +1497,8 @@ type RelabelConfig struct {
SourceLabels []LabelName `json:"sourceLabels,omitempty"`

// Separator is the string between concatenated SourceLabels.
Separator string `json:"separator,omitempty"`
//+kubebuilder:default=";"
Separator string `json:"separator"`
Copy link
Contributor

Choose a reason for hiding this comment

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

The "issue" with adding a default value is that the API response will change to return separator: ";" if the field isn't set and it may disrupt some clients (reconcilers for instance).

Another option would be to change the field type to be a string pointer:

  • if the pointer is nil, don't set the separator field in the generated Prometheus config (and let Prometheus use its own default).
  • if not nil, pass the value as-is.

The risk with this option is for users that have separator: "" in their YAML manifests today as it will change the behavior for them.

Suggested change
Separator string `json:"separator"`
Separator *string `json:"separator"`

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes I agree this is a breaking change. But since this change is on par with Prometheus's behavior, I think it's worth doing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought of your suggested approach too. Will try this. I think it is less risky than the current (default ; approach) because there might be less users setting separator: "" than users not setting it at all.

Copy link
Contributor

Choose a reason for hiding this comment

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

Agreed, I don't think that separator: "" is widely used in the wild, especially knowing that as of today, it's the same as not setting it. If we follow that path, we's till need to mark it as a CHANGE in the changelog for safety.

@haanhvu
Copy link
Contributor Author

haanhvu commented Mar 25, 2024

@slashpai @simonpasquier All tests are passed now. Do you think we need to add tests for "" separator is correctly used (not ignored or replaced by ; from Prometheus side)? If yes, where should I add those tests?

@simonpasquier
Copy link
Contributor

I would extend TestAdditionalAlertRelabelConfigs to have a relabel config rule setting separator: "".

!(rc.Separator == "" ||
rc.Separator == relabel.DefaultRelabelConfig.Separator) ||
!(rc.Separator == nil ||
rc.Separator == &relabel.DefaultRelabelConfig.Separator) ||
Copy link
Contributor

Choose a reason for hiding this comment

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

The addresses will always be different. Yes, it will be the same if at some point rc.Separator = (default value in rhs) in some languages but not in go, see this. I think it might be better to dereference rc.Separator instead of getting the address of the default value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. I know what you mean. I was just too focused on the nil separator, since that's the breaking change. Will fix this in next commit.

!(rc.Separator == "" ||
rc.Separator == relabel.DefaultRelabelConfig.Separator) ||
!(rc.Separator == nil ||
rc.Separator == &relabel.DefaultRelabelConfig.Separator) ||
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here. Check this playground out.

@@ -4657,7 +4659,7 @@ func testRelabelConfigCRDValidation(t *testing.T) {
relabelConfigs: []*monitoringv1.RelabelConfig{
{
SourceLabels: []monitoringv1.LabelName{"__address__"},
Separator: ",",
Separator: &sep1,
Copy link
Contributor

Choose a reason for hiding this comment

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

(nit) you can use ptr.To instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree, using pointer package from k8s would be better.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll fix this nit tomorrow when I have more time.

@@ -4668,7 +4670,7 @@ func testRelabelConfigCRDValidation(t *testing.T) {
scenario: "empty-separator",
relabelConfigs: []*monitoringv1.RelabelConfig{
{
Separator: "",
Separator: &sep2,
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here.

@pull-request-size pull-request-size bot added size/S and removed size/M labels Mar 31, 2024
Copy link
Member

@ArthurSens ArthurSens left a comment

Choose a reason for hiding this comment

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

Just some nitpicking about file names[1][2]

I totally understand that this is beyond the scope of this PR, I'll open a separate issue for that

Comment on lines 3 to 7
- sourceLabels: [label1, label2]
separator: ""
action: replace
targetLabel: custom_label
Copy link
Member

Choose a reason for hiding this comment

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

It took me forever to understand why such a simple change (changing separator to pointer), would change so much a golden file, e.g. source labels, action, etc.

That was until I realized that this file is not really a golden file by definition, but an input! We should change the suffix of this file to something else, e.g. .input

Copy link
Contributor

Choose a reason for hiding this comment

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

👍 btw the config format is wrong since it expects Prometheus snake-case format.

@@ -392,7 +392,7 @@ func TestValidateRelabelConfig(t *testing.T) {
relabelConfig: monitoringv1.RelabelConfig{
SourceLabels: []monitoringv1.LabelName{"__tmp_port"},
TargetLabel: "__port1",
Separator: relabel.DefaultRelabelConfig.Separator,
Separator: &relabel.DefaultRelabelConfig.Separator,
Copy link
Contributor

Choose a reason for hiding this comment

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

(nit)

Suggested change
Separator: &relabel.DefaultRelabelConfig.Separator,
Separator: ptr.To(relabel.DefaultRelabelConfig.Separator),

@mviswanathsai
Copy link
Contributor

You might want to squash these commits into one (or a few) once you are done with all the changes. You might already be on it, just a reminder!

@haanhvu
Copy link
Contributor Author

haanhvu commented Apr 2, 2024

You might want to squash these commits into one (or a few) once you are done with all the changes. You might already be on it, just a reminder!

I've never done this in any of my merged PRs here. Is there any reason to do that in this PR?

@mviswanathsai
Copy link
Contributor

It's not really a necessity per se, but having one point in the final commit tree which tells you what exactly this commit did, than to have 10 or so commits that took to achieve it would be more desirable.
Ofcourse, in the PR itself there's nothing 'wrong" with having as many commits.

@mviswanathsai
Copy link
Contributor

mviswanathsai commented Apr 2, 2024

For example, "fix e2e failure" is meaningful within the context of this PR. But once merged to main, it would become rather ambiguous.
Again, it's just a nit. More of a good practice than a necessity or anything.

@haanhvu
Copy link
Contributor Author

haanhvu commented Apr 2, 2024

For example, "fix e2e failure" is meaningful within the context of this PR. But once merged to main, it would become rather ambiguous.

Yes many commits may not be meaningful out of PR. But no matter how many commits are in the PR, in the end there's only one merged commit right? Like this: 128acfc

Of course if that's really necessary I'll do it. But I have seen many merged PRs with several commits, even from maintainers. So currently I don't see any values of doing it here. If I miss something else then please specify.

@haanhvu haanhvu changed the title Allow empty seperator in relabel config Allow empty separator in relabel config Apr 3, 2024
@slashpai
Copy link
Contributor

slashpai commented Apr 3, 2024

IMHO for best practices its good to squash commits with meaningful message. Incase not doing GitHub has option squash and merge but we would still need to update comments while doing that.

@haanhvu
Copy link
Contributor Author

haanhvu commented Apr 3, 2024

IMHO for best practices its good to squash commits with meaningful message. Incase not doing GitHub has option squash and merge but we would still need to update comments while doing that.

Yes, please help me squash when you merge. The first commit message has everything you need to know about the PR. I always follow your format here.

Personally, I prefer to keep PR commits history as they are. In case I do several approaches in one PR, that PR merged, then I need to revert the PR and come back to a previous approach, commits history can help me find back that approach in my PR.

Comment on lines 4 to 7
separator: ""
action: replace
targetLabel: custom-label
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
- sourceLabels: [label-a, label-b]
separator: ""
action: replace
targetLabel: custom-label
- source_labels: [label-a, label-b]
separator: ""
action: replace
target_label: custom-label

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. Fixed it. Any ideas why the test still passed with the operator's format? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought the input file followed the operator's format. And the output (expected) file followed Prometheus's format. But from your suggestion, it means both follow Prometheus's format?

Copy link
Contributor

Choose a reason for hiding this comment

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

correct, it's because the test is about additionalScrapeConfigs which hold native Prometheus configs.

Copy link
Contributor Author

@haanhvu haanhvu Apr 3, 2024

Choose a reason for hiding this comment

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

Hmm, then do you think this test can verify our fix? I thought we needed a test regarding the operator's format? 🤔 Like, before the operator's format didn't support "" but now it does?

Copy link
Contributor

Choose a reason for hiding this comment

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

The operator appends the additional config that is specified by name (I think?) in the final generated config. In this, we process the input config (user defined) and generate a final config. I think what you're trying to test is that the generated config which contains the appended additional config still contains the "empty" value in field instead of omitting it entirely.

@haanhvu haanhvu force-pushed the issue5003-1 branch 2 times, most recently from d65d126 to 5f107bc Compare April 3, 2024 10:20
Allow empty separator in relabel config. This is corresponding to Prometheus' relabel config.

Fixes prometheus-operator#5003
@haanhvu
Copy link
Contributor Author

haanhvu commented Apr 3, 2024

CI didn't run so I squashed commits to reactivate it. It still hasn't run though... Will wait then.

@slashpai
Copy link
Contributor

slashpai commented Apr 3, 2024

@simonpasquier Is it good to merge?

@simonpasquier simonpasquier merged commit 48444eb into prometheus-operator:main Apr 3, 2024
17 checks passed
@haanhvu haanhvu mentioned this pull request Apr 10, 2024
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Concatenating labels (using empty 'separator') in relabelings not possible
5 participants