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

feat: Allow prefixing wildcard labelsFromPath #2052

Merged
merged 1 commit into from
Mar 26, 2024

Conversation

rexagod
Copy link
Member

@rexagod rexagod commented Apr 20, 2023

What this PR does / why we need it: Allow prefixing * paths, for instance, a "foo_" prefix like so, foo_*: [foo, bar, baz], will result in foo_baz being the key for all object resolutions under baz.

How does this change affect the cardinality of KSM: No change.

Which issue(s) this PR fixes: Self-driven.

@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Apr 20, 2023
@k8s-ci-robot k8s-ci-robot added approved Indicates a PR has been approved by an approver from all required OWNERS files. size/S Denotes a PR that changes 10-29 lines, ignoring generated files. labels Apr 20, 2023
@rexagod
Copy link
Member Author

rexagod commented Apr 20, 2023

TODO: Add a doc entry.

@rexagod rexagod changed the title Allow prefixing * paths Allow prefixing wildcard labelsFromPath Apr 22, 2023
@mrueg
Copy link
Member

mrueg commented Apr 23, 2023

/triage accepted

@mrueg
Copy link
Member

mrueg commented Apr 24, 2023

After looking a bit closer at what this does, do the semantics of this syntax look intentional to users?

If I see * I wouldn't think that this is adding a prefix but more a filter to only include keys with this specific prefix.
Can we find a better syntax?

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Apr 26, 2023
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 6, 2023
rexagod referenced this pull request in rexagod/kube-state-metrics Jun 11, 2023
@rexagod
Copy link
Member Author

rexagod commented Jun 15, 2023

Closing in favor of the newer model.

@rexagod rexagod closed this Jun 15, 2023
@rexagod
Copy link
Member Author

rexagod commented Jun 20, 2023

Reopening in favor of #2068 (comment).

@rexagod rexagod reopened this Jun 20, 2023
@dgrisonnet
Copy link
Member

/triage accepted
/assign

@k8s-ci-robot k8s-ci-robot added triage/accepted Indicates an issue or PR is ready to be actively worked on. and removed needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Jun 29, 2023
@k8s-ci-robot k8s-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/S Denotes a PR that changes 10-29 lines, ignoring generated files. labels Aug 29, 2023
@mrueg mrueg changed the title Allow prefixing wildcard labelsFromPath feat: Allow prefixing wildcard labelsFromPath Aug 29, 2023
Allow prefixing * paths, for instance, foo_*: [foo, bar, baz], will
result in foo_baz being the key for all object resolutions under baz.

Signed-off-by: Pranshu Srivastava <[email protected]>
@rexagod
Copy link
Member Author

rexagod commented Aug 29, 2023

Up for reviews.

Copy link
Member

@dgrisonnet dgrisonnet left a comment

Choose a reason for hiding this comment

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

Should we just support globbing in general for labels from path and use https://github.com/gobwas/glob instead of doing the parsing manually?

@rexagod
Copy link
Member Author

rexagod commented Aug 30, 2023

For the CRS snippet below, the output will contain labels with the prefix foo_ for every key present in the fooObj and it's values marshalled into the respective label values. There isn't actually any Match happening, and the * is but a placeholder to denote where the label keys will be inserted at.

labelsFromPath:
  "foo_*": ["bar", "fooObj"]

An actual regex match over a sample set of fooObjA, fooObjB for foo_* will return empty (which is why I doubt I might be failing to see here how we'd benefit from this library, and where). This syntax, in this context, addresses the need to manipulate generated labels, as opposed to validating them against an expression.

@rexagod
Copy link
Member Author

rexagod commented Aug 30, 2023

This basically builds on top of the originally present * labelFromPath key, which would marshal every key-value pair in an object as is, into label-values, whereas this allows prepending text to these "as-is" keys.

@rexagod
Copy link
Member Author

rexagod commented Aug 30, 2023

I can modify this PR, or send another patch in the future to truly denote * as the resolved object keys and insert keys there, not just at the prefix.

@rexagod
Copy link
Member Author

rexagod commented Aug 30, 2023

Do you mean supporting expressions such as foo_b?r.* for labelFromPaths using the library? As in, all fooObj keys that match the b?r.* pattern and include only those as labels? This may prove ambiguous for estimating where the prefix ends and the regexp begins (do we want to move prefixes to a different field)?

@@ -134,12 +134,15 @@ func Test_addPathLabels(t *testing.T) {
{name: "*", args: args{
obj: cr,
labels: map[string]valuePath{
"*1": mustCompilePath(t, "metadata", "annotations"),
"bar": mustCompilePath(t, "metadata", "labels", "foo"),
"*1": mustCompilePath(t, "metadata", "annotations"),
Copy link
Member

Choose a reason for hiding this comment

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

Unrelated to the actual PR, but why does *1 yield "qux": "quxx". Is this the way we tell the code to take the first annotation?

@dgrisonnet
Copy link
Member

Disregard #2052 (review), I got super confused with the syntax.

The use of the * character is so confusing here. I would see a lot of people, myself included to expect some kind of globbing from this *, but that not the case at all, we are just precising a prefix or suffix, which shouldn't need a * in the syntax.

The current approach has 4 scenarios:

"*": [metadata, labels]
"prefix_*": [metadata, labels]
"*_suffix": [metadata, labels]
"prefix_*_suffix": [metadata, labels]

This relies on an implicit behavior from the parser that requires users to have an understand of the code. Whereas we could make it more expressive and have something like:

labelsFromPath:
  - path: [metadata, labels]
    prefix: "lorem"
    suffix: "ipsum"

IMO, the more explicit a syntax is, the easier it is for an external user to understand.

Prometheus-adapter is a prime example of a very bad syntax. Its configuration was made overly complex in an attempt to make it more generic and adaptable (I guess), but the result is that it confuses everyone and discourage users from using the project.
Here is a "simple" example from the repo:

rules:
- seriesQuery: '{__name__=~"^container_.*",container!="POD",namespace!="",pod!=""}'
  resources:
    overrides:
      namespace: {resource: "namespace"}
      pod: {resource: "pod"}
  name:
    matches: "^container_(.*)_seconds_total$"
  metricsQuery: "sum(rate(<<.Series>>{<<.LabelMatchers>>,container!="POD"}[2m])) by (<<.GroupBy>>)"

We need to avoid reaching that point at all cost.

@rexagod
Copy link
Member Author

rexagod commented Oct 17, 2023

I see. My only concern here is when moving from,

"*": [metadata, labels]
"prefix_*": [metadata, labels]
"*_suffix": [metadata, labels]
"prefix_*_suffix": [metadata, labels]

to,

labelsFromPath:
  - path: [metadata, labels]
    prefix: "lorem"
    suffix: "ipsum"

will require multiple paths, since the lorem_* approach allows for specifying distinct paths that can differ from each other, such as,

"*": [metadata, labels, foo]
"prefix_*": [metadata, labels, bar]
"*_suffix": [metadata, labels, baz]
"prefix_*_suffix": [metadata, labels, que]

as compared to,

each:
  type: Gauge
  gauge:
    path: [status, conditions]
    labelsFromPath:
      - path: [metadata, labels, foo]
      	prefix: ""
      	suffix: ""
      - path: [metadata, labels, bar]
      	prefix: "prefix"
      	suffix: ""
      <"*_suffix" and "prefix_*_suffix" as well>
      type: ["type"]
    valueFrom: ["status"]

which may give rise to ambiguous conclusions since there's a path definition outside labelsFromPath as well, to allow relative definitions for labels such as type (above).

@dgrisonnet
Copy link
Member

which may give rise to ambiguous conclusions since there's a path definition outside labelsFromPath as well, to allow relative definitions for labels such as type (above).

I see what you mean here, although that was already the case implicitly, it will now be explicit and could be very confusing. Maybe we could call it from or fromPath?

@k8s-triage-robot
Copy link

The Kubernetes project currently lacks enough contributors to adequately respond to all PRs.

This bot triages PRs according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the PR is closed

You can:

  • Mark this PR as fresh with /remove-lifecycle stale
  • Close this PR with /close
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle stale

@k8s-ci-robot k8s-ci-robot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Feb 4, 2024
@rexagod
Copy link
Member Author

rexagod commented Feb 16, 2024

/remove-lifecycle stale

@k8s-ci-robot k8s-ci-robot removed the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Feb 16, 2024
@rexagod
Copy link
Member Author

rexagod commented Mar 3, 2024

@dgrisonnet Please correct me if I'm wrong but I believe transforming labelsFromPath to a list will be a breaking change. For instance, the following (currently the way to specify label key-values with no wildcards) will need to be adjust to conform to the newer YAML list-based format.

labelsFromPath:
  status: [conditions, "0", status]

could either be,

labelsFromPath:
  - path : [conditions, "0", status]
    prefix: "status"
    suffix: ""

or,

labelsFromPath:
  - path : [conditions, "0", status]
    prefix: ""
    suffix: "status"

both being breaking changes to the existing configuration interpretation logic IIUC.

@dgrisonnet
Copy link
Member

Yes it would be a breaking changes. That would also be the case for this comment on your other PR which would apply also here: #2068 (comment)

We will need to break the config entirely if we want to build solid foundation with CEL, so hopefully we will change it in the future. In the meantime we can continue with the current UX, but we will need to draw a line at one point. I would be fine with drawing it once your two PRs are merged and then stop accepting feature requests until we've migrated to CEL.

Copy link
Member

@dgrisonnet dgrisonnet left a comment

Choose a reason for hiding this comment

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

/lgtm
/approve

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Mar 26, 2024
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: dgrisonnet, mrueg, rexagod

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:
  • OWNERS [dgrisonnet,mrueg,rexagod]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot merged commit a3489c0 into kubernetes:main Mar 26, 2024
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. triage/accepted Indicates an issue or PR is ready to be actively worked on.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants