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

⚠️ Re-define how related resources are configuring/found, add support for label selectors #44

Merged
merged 12 commits into from
Apr 8, 2025

Conversation

xrstf
Copy link
Contributor

@xrstf xrstf commented Mar 20, 2025

Summary

This PR significantly changes the approach the agent uses to locate related objects.

Old Approach

My original idea was:

  1. For each related resource, the admin configures one (!) reference into the main object (by virtue of a path expression).
  2. This one (!) reference is then evaluated equally on both sides of the sync (i.e. in the original main object in kcp, and in the potentially mutated copy of it on the service cluster).

The advantage of this approach is that mutations only happen in one place: the main object. When thinking about finding the related objects, the admin does not have to consider additional mutations/renamings, because that all happened already in the main object.

For example, if you had a certificate with spec.secretName=my-cert, you would mutate this spec in the main object to become spec.secretName=$clusterName-$remoteHashYaddaYadda, for example spec.secretName=1otjakf7q2tyhbii-4827da5-278adfe. And now when we want to locate it, we just follow the same path and get the correct names. Easy!

Label Selectors

The approach above works fine if you use references because that always yields a fixed, known value.

But now we want to add label selectors for related resources. This can be used when there is no reference (like spec.secretName) in the main object. This happens for operators that just take the name of the main object and append something like -credentials to it and use this, per convention, as the secret.

The Issue with secret information

The issue is that the name of the main object usually is somewhat encoded, to ensure many workspaces do not collide on the service cluster. There is also a chance that additional, "secret" information is embedded into them (because agents might sync special customers into special namespaces with special naming rules). Long story short, the main object's name is, like every part of the sync metadata, private to the service provider and should never leak into kcp workspaces.

This also means that the names of the related objects are also considered private and we must not re-use them on the destination side of the synchronisation. But now we're in a pickle, because if we follow the old approach, we would evaluate the same label selector on both sides of the sync. On the first iteration, this will ideally find the source object, but obviously cannot yet find the destination object (we haven't create it yet). So now the agent has to decide the destination object's name by itself.

This now means that the admin, in addition to a label selector, also has to specify the naming rules for the copy of the related object. And this means that the logic is not symmetric anymore:

  • The label selector is actually applied on the origin side of the sync to find the source object.
  • But on the destination side of the sync, the selector is ignored and the naming rules are used instead to create the destination namespace/name.

Asymmetry

This asymmetry is what is ultimately causing this API break. There is no sane way to express this in the old structure, without introducing a lot of extra validations (validations the OpenAPI schema cannot handle and would either require a webhook or loooots of CEL expressions) and need for documentation. Even I, who thought through all this, was confused when I began the implementation. By my own data structures no less. Because if you have naming rules, are they also used for reference-based related resources?

Since we do not have a conversion webhook and bumping API versions in Kubernetes is a major PITA, as I've just learned from kcp itself, I chose to commit an API break in this PR.

API Break

With this PR, we the configuration is extended like this. Previously this is the structure:

spec:
  related:
    - id: credentials
      # 1 reference
      reference:
        name:
          path: metadata.name
          regex: {pattern: ..., replacement: ...}
        # optional namespace
        namespace:
          path: metadata.foobar
          regex: {pattern: ..., replacement: ...}

With this change, all configuration was moved under a new "object" key and then restructured a bit:

spec:
  related:
    - id: credentials

      object:
        # these three are mutually exclusive
        # they all refer to the _name_ of the object only
        reference: {path: ..., regex: {...}}
        selector: {matchLabels: ..., matchExpressions: ..., rewrite: {regex: ..., template: ...}}
        template: {template: ...}

        # if necessary, the namespace can be configured the same way
        namespace:
          reference: {path: ..., regex: {...}}
          selector: {matchLabels: ..., matchExpressions: ..., rewrite: {regex: ..., template: ...}}
          template: {template: ...}

Label Selectors

...are currently not super useful, because you cannot use any dynamic values in them, like variables. The old approach of having a custom variable syntax ("foo$bar") is reaching its limits and so we plan on replacing it with Go template strings. But this will be done in another PR and that PR will then add support for templated strings to the selectors.

Multiple Related Objects

Since we now have support for label selectors, a single related resource can select many objects. And this is now supported by the agent. It's not super convenient yet (the annotation on the primary object that links to the related object(s) is a bit ugly with a counter at the end, but it works).

Related issue(s)

Fixes #31

Release Notes

* [BREAKING] Add support for finding related resources via label selectors.
* Add support for having one related resource match many objects.

@kcp-ci-bot kcp-ci-bot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. release-note Denotes a PR that will be considered when it comes time to generate release notes. labels Mar 20, 2025
@kcp-ci-bot
Copy link
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@kcp-ci-bot kcp-ci-bot added dco-signoff: yes Indicates the PR's author has signed the DCO. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Mar 20, 2025
@xrstf
Copy link
Contributor Author

xrstf commented Mar 20, 2025

/test all

xrstf added 4 commits March 21, 2025 16:15
… confusing

This is because now, with support for label selectors, we need explicit naming on the destination
side, which means the old idea of "the same thing is done on both sides to figure out the names on
origin and destination" doesn't apply anymore, because the logic is now slightly different between
both sides. To not ack this in the CRD will just create endless confusion.

On-behalf-of: @SAP [email protected]
@xrstf xrstf force-pushed the label-selector-related-resources branch from 9d243a4 to 32287a9 Compare March 21, 2025 15:16
@xrstf
Copy link
Contributor Author

xrstf commented Mar 21, 2025

/test all

@xrstf
Copy link
Contributor Author

xrstf commented Mar 21, 2025

/test all

@xrstf
Copy link
Contributor Author

xrstf commented Mar 24, 2025

/test all

@xrstf
Copy link
Contributor Author

xrstf commented Mar 26, 2025

/test all

@xrstf xrstf marked this pull request as ready for review March 26, 2025 13:55
@kcp-ci-bot kcp-ci-bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Mar 26, 2025
@xrstf xrstf requested a review from embik March 26, 2025 13:56
Copy link
Member

@embik embik left a comment

Choose a reason for hiding this comment

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

Just one teeny tiny thing.

@embik
Copy link
Member

embik commented Apr 8, 2025

/kind api-change
/kind feature

@kcp-ci-bot kcp-ci-bot added kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API kind/feature Categorizes issue or PR as related to a new feature. labels Apr 8, 2025
Copy link
Member

@embik embik left a comment

Choose a reason for hiding this comment

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

/approve

@kcp-ci-bot kcp-ci-bot added the lgtm Indicates that a PR is ready to be merged. label Apr 8, 2025
@kcp-ci-bot
Copy link
Contributor

LGTM label has been added.

Git tree hash: 16ef992fad35e86a5fc39688019ade8abfe9790a

@kcp-ci-bot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: embik

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:

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

@kcp-ci-bot kcp-ci-bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Apr 8, 2025
@kcp-ci-bot kcp-ci-bot merged commit 51f25b5 into main Apr 8, 2025
8 checks passed
@kcp-ci-bot kcp-ci-bot deleted the label-selector-related-resources branch April 8, 2025 11:53
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. dco-signoff: yes Indicates the PR's author has signed the DCO. kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API kind/feature Categorizes issue or PR as related to a new feature. lgtm Indicates that a PR is ready to be merged. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feature: Related resource label selector
3 participants