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

cel: add semantic version type #123664

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Conversation

pohly
Copy link
Contributor

@pohly pohly commented Mar 4, 2024

What type of PR is this?

/kind feature

What this PR does / why we need it:

Structured parameters for Dynamic Resource Allocation use CEL expressions to filter resource instances by their attributes. One of the possible attribute value types is a semantic version string. The corresponding filter could be "attribute value >= 2.0.0".

Which issue(s) this PR fixes:

Related-to: kubernetes/enhancements#4381

Special notes for your reviewer:

The key question from an API perspective is: can Kubernetes rely on some particular semver implementation to validate API fields (not in this PR, but calling semver.Parse is what validation of the DRA API would do) and to implement the version comparsion (this PR)? See #123516 (comment) for @liggitt's comments in the context of a different solution for the same problem.

github.com/blang/semver/v4 was chosen for this in this PR because it looks like a stable, high-quality implementation and also seems to be the most widely used semver implementation in Kubernetes.

Regarding the implementation: it is derived from the quantity type and supports the same operations, with one exception: comparison across types (like <semver> == <int> ?) is not supported.

Does this PR introduce a user-facing change?

CEL: semver is a new type for semantic version string parsing and comparison.

/cc @liggitt @klueska @cici37

@k8s-ci-robot k8s-ci-robot requested a review from cici37 March 4, 2024 08:29
@k8s-ci-robot k8s-ci-robot added the release-note Denotes a PR that will be considered when it comes time to generate release notes. label Mar 4, 2024
@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. kind/feature Categorizes issue or PR as related to a new feature. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. area/apiserver area/code-generation sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. and removed do-not-merge/needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. labels Mar 4, 2024
@@ -90,6 +90,13 @@ var baseOpts = []VersionedOptions{
library.Quantity(),
},
},
{
IntroducedVersion: version.MajorMinor(1, 30),
EnvOptions: []cel.EnvOption{
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note that, in contrast to the quantity type above, CrossTypeNumericComparisons is not supported.

When I looked at the quantity type, I was surprised that comparison of two quantity values with operators ('>', '<=', etc.) is not mentioned. Only == is mentioned.

Are other operators supported indirectly via this CrossTypeNumericComparisons thing?

Are compareTo, isGreaterThan and isLessThan really useful? I implemented them for similarity with the quantity type, but overloading the comparison operators seems like a better solution to me (not tried yet).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@cici37: any opinion about this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Are other operators supported indirectly via this CrossTypeNumericComparisons thing?

I tested it, quantity("50M") < quantity("50Mi") also fails to compile.

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 will leave the actually function needed for samver reviewed by others.

The current functionality with compareTo, isGreaterThan and isLessThan is sufficient. Even just compareTo would be enough, but I think consistency with quantity is important, so let's keep isGreaterThan and isLessThan.

I am just wondering why exactly those were added for quantity. Overriding the comparison operators seems more natural to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Perhaps because cost estimation is easier when not overloading operators? I see that cost.go has entries that are just based on the function name.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes We have to go with compareTo, isGreaterThan and isLessThan since cel would not recognize >/< for extended type without handling and we do wanna set up cost properly for those comparison. :)

@pohly
Copy link
Contributor Author

pohly commented Mar 4, 2024

can Kubernetes rely on some particular semver implementation to validate API fields (not in this PR, but calling semver.Parse is what validation of the DRA API would do)

The alternative is that validation is done with a regular expression. There is even one in the spec:
https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string

The error message when validation fails is going to be less useful (similar to others, like a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')"), but that's okay.

@pohly
Copy link
Contributor Author

pohly commented Mar 4, 2024

If we are not comfortable with adding this directly to the base CEL environment in 1.30, then I can add it instead to the CEL environment that gets prepared for DRA expressions. Then it's clearly alpha and we have more time to evolve it before promoting to the base CEL environment.

@pohly
Copy link
Contributor Author

pohly commented Mar 4, 2024

I added one commit at the end to #123516 which:

  • adds the same semver lib to the DRA CEL environment (i.e. doesn't touch the base lib)
  • uses regexp for validation instead of semver/v4.Parse

That commit is probably easier to merge for 1.30 because it's all in alpha-quality code.

Copy link
Contributor

@cici37 cici37 left a comment

Choose a reason for hiding this comment

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

I will leave the actually function needed for samver reviewed by others. Wanna mention that the func cost has to be added into https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apiserver/pkg/cel/library/cost.go as well together with the tests for adding a new cel lib. Thanks!

@@ -128,6 +128,7 @@ var baseOpts = []VersionedOptions{
EnvOptions: []cel.EnvOption{
library.IP(),
library.CIDR(),
library.SemVer(),
Copy link
Contributor

Choose a reason for hiding this comment

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

Just wanna mention that adding into base as introduced in 1.30 will not enable the power immediately as we normally would set the DefaultCompatibilityVersion one version earlier iff DRA is using the same default env version :)

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 am solving this over in #123516 in pkg/apis/resource/structured/namedresources/validation/validation.go like this:

func validateSelector(opts Options, selector string, fldPath *field.Path) field.ErrorList {
	var allErrs field.ErrorList
	if selector == "" {
		allErrs = append(allErrs, field.Required(fldPath, ""))
	} else {
		// TODO (https://github.com/kubernetes/kubernetes/issues/123687):
		// when this API gets promoted to beta, we have to
		// validate new and stored expressions differently.
		// While it is alpha, new expressions are allowed to
		// use everything that is currently available.
		// envType := environment.NewExpressions
		// if opts.StoredExpressions {
		//    envType = environment.StoredExpressions
		// }
		envType := environment.StoredExpressions
		result := namedresourcescel.Compiler.CompileCELExpression(selector, envType)

Does this look right to you?

Copy link
Contributor

Choose a reason for hiding this comment

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

This would depend on how to build the env in https://github.com/kubernetes/kubernetes/blob/90ed34a12ffc3d58ecedf0e0c91c4d85a67f9aab/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/compile.go#L62C19-L62C39.
I saw it's built without version control which means all added func would be available but you'll lose the benefit of version control/backward compatibility. When a new func added in the future, the cluster might running into risk of not recognizing the expression while roll back. I guess it should be fine in Alpha, but that is something better think about going forward in beta/ga. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True, this needs more thought before proceeding to beta.

Copy link
Member

Choose a reason for hiding this comment

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

commented at https://github.com/kubernetes/kubernetes/pull/123516/files#r1516500003 with one possibility for handling this for the namedresources use

// semver("1.2.3").compareTo(semver("1.2.3")) // returns 0
// semver("1.2.3").compareTo(semver("2.0.0")) // returns -1
// semver("1.2.3").compareTo(semver("0.1.2")) // returns 1

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like tests are still pending to add :)

Copy link
Contributor Author

@pohly pohly Mar 5, 2024

Choose a reason for hiding this comment

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

Yes, more work is needed to reach better code coverage. Embarrassingly, this copy of the code actually had type conversion problems in the implementation of the functions.

Now the code is covered as well as quantity.go is. I suppose the if !ok after type assertions cannot be tested because those are just safeguards that cannot be reached from within well-formed CEL expressions.

Copy link
Contributor

Choose a reason for hiding this comment

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

We don't need type assertions anymore but we are lazy on removing them :)

@k8s-ci-robot k8s-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Mar 5, 2024
@pohly
Copy link
Contributor Author

pohly commented Mar 5, 2024

@cici37: I pushed an update.

Did I add the necessary checks for cost and library registration correctly? The cost estimates are exactly the same as for quantity. Parsing a semver string shouldn't be more expensive.

Is this perhaps okay for 1.30? If we can merge it quickly (today?) then I can drop the corresponding code from #123516 and just use this here.

If we end up not merging #123516, then this PR could get reverted unless it's seen as useful on its own.

pohly added a commit to pohly/kubernetes that referenced this pull request Mar 5, 2024
This adds support for semantic version comparison to the CEL support in the
"named resources" structured parameter model. For example, it can be used to
check that an instance supports a certain API level.

To minimize the risk, the new "semver" type is only defined in the CEL
environment for DRA expressions, not in the base library. See
kubernetes#123664 for a PR which
adds it to the base library.

Validation of semver strings is done with the regular expression from
semver.org. The actual evaluation at runtime then uses semver/v4.
pohly added a commit to pohly/kubernetes that referenced this pull request Mar 5, 2024
This adds support for semantic version comparison to the CEL support in the
"named resources" structured parameter model. For example, it can be used to
check that an instance supports a certain API level.

To minimize the risk, the new "semver" type is only defined in the CEL
environment for DRA expressions, not in the base library. See
kubernetes#123664 for a PR which
adds it to the base library.

Validation of semver strings is done with the regular expression from
semver.org. The actual evaluation at runtime then uses semver/v4.
@pohly
Copy link
Contributor Author

pohly commented Mar 5, 2024

/retest pull-kubernetes-integration pull-kubernetes-e2e-gce

@k8s-ci-robot
Copy link
Contributor

@pohly: The /retest command does not accept any targets.
The following commands are available to trigger required jobs:

  • /test pull-cadvisor-e2e-kubernetes
  • /test pull-cos-containerd-e2e-ubuntu-gce
  • /test pull-kubernetes-conformance-kind-ga-only-parallel
  • /test pull-kubernetes-coverage-unit
  • /test pull-kubernetes-dependencies
  • /test pull-kubernetes-dependencies-go-canary
  • /test pull-kubernetes-e2e-gce
  • /test pull-kubernetes-e2e-gce-100-performance
  • /test pull-kubernetes-e2e-gce-big-performance
  • /test pull-kubernetes-e2e-gce-cos
  • /test pull-kubernetes-e2e-gce-cos-canary
  • /test pull-kubernetes-e2e-gce-cos-no-stage
  • /test pull-kubernetes-e2e-gce-network-proxy-http-connect
  • /test pull-kubernetes-e2e-gce-scale-performance-manual
  • /test pull-kubernetes-e2e-kind
  • /test pull-kubernetes-e2e-kind-ipv6
  • /test pull-kubernetes-integration
  • /test pull-kubernetes-integration-go-canary
  • /test pull-kubernetes-kubemark-e2e-gce-scale
  • /test pull-kubernetes-node-e2e-containerd
  • /test pull-kubernetes-typecheck
  • /test pull-kubernetes-unit
  • /test pull-kubernetes-unit-go-canary
  • /test pull-kubernetes-update
  • /test pull-kubernetes-verify
  • /test pull-kubernetes-verify-go-canary
  • /test pull-kubernetes-verify-lint

The following commands are available to trigger optional jobs:

  • /test check-dependency-stats
  • /test pull-ci-kubernetes-unit-windows
  • /test pull-crio-cgroupv1-node-e2e-eviction
  • /test pull-crio-cgroupv1-node-e2e-features
  • /test pull-crio-cgroupv1-node-e2e-hugepages
  • /test pull-crio-cgroupv1-node-e2e-resource-managers
  • /test pull-crio-cgroupv2-imagefs-separatedisktest
  • /test pull-crio-cgroupv2-node-e2e-eviction
  • /test pull-crio-cgroupv2-splitfs-splitdisk
  • /test pull-e2e-gce-cloud-provider-disabled
  • /test pull-kubernetes-conformance-image-test
  • /test pull-kubernetes-conformance-kind-ga-only
  • /test pull-kubernetes-conformance-kind-ipv6-parallel
  • /test pull-kubernetes-cos-cgroupv1-containerd-node-e2e
  • /test pull-kubernetes-cos-cgroupv1-containerd-node-e2e-features
  • /test pull-kubernetes-cos-cgroupv2-containerd-node-e2e
  • /test pull-kubernetes-cos-cgroupv2-containerd-node-e2e-eviction
  • /test pull-kubernetes-cos-cgroupv2-containerd-node-e2e-features
  • /test pull-kubernetes-cos-cgroupv2-containerd-node-e2e-serial
  • /test pull-kubernetes-crio-node-memoryqos-cgrpv2
  • /test pull-kubernetes-cross
  • /test pull-kubernetes-e2e-autoscaling-hpa-cm
  • /test pull-kubernetes-e2e-autoscaling-hpa-cpu
  • /test pull-kubernetes-e2e-capz-azure-disk
  • /test pull-kubernetes-e2e-capz-azure-disk-vmss
  • /test pull-kubernetes-e2e-capz-azure-file
  • /test pull-kubernetes-e2e-capz-azure-file-vmss
  • /test pull-kubernetes-e2e-capz-conformance
  • /test pull-kubernetes-e2e-capz-windows-alpha-feature-vpa
  • /test pull-kubernetes-e2e-capz-windows-alpha-features
  • /test pull-kubernetes-e2e-capz-windows-master
  • /test pull-kubernetes-e2e-capz-windows-serial-slow
  • /test pull-kubernetes-e2e-capz-windows-serial-slow-hpa
  • /test pull-kubernetes-e2e-containerd-gce
  • /test pull-kubernetes-e2e-ec2
  • /test pull-kubernetes-e2e-ec2-arm64
  • /test pull-kubernetes-e2e-ec2-conformance
  • /test pull-kubernetes-e2e-ec2-conformance-arm64
  • /test pull-kubernetes-e2e-gce-canary
  • /test pull-kubernetes-e2e-gce-correctness
  • /test pull-kubernetes-e2e-gce-cos-alpha-features
  • /test pull-kubernetes-e2e-gce-csi-serial
  • /test pull-kubernetes-e2e-gce-device-plugin-gpu
  • /test pull-kubernetes-e2e-gce-disruptive-canary
  • /test pull-kubernetes-e2e-gce-kubelet-credential-provider
  • /test pull-kubernetes-e2e-gce-network-proxy-grpc
  • /test pull-kubernetes-e2e-gce-providerless
  • /test pull-kubernetes-e2e-gce-serial
  • /test pull-kubernetes-e2e-gce-serial-canary
  • /test pull-kubernetes-e2e-gce-storage-disruptive
  • /test pull-kubernetes-e2e-gce-storage-slow
  • /test pull-kubernetes-e2e-gce-storage-snapshot
  • /test pull-kubernetes-e2e-gci-gce-autoscaling
  • /test pull-kubernetes-e2e-gci-gce-ingress
  • /test pull-kubernetes-e2e-gci-gce-ipvs
  • /test pull-kubernetes-e2e-inplace-pod-resize-containerd-main-v2
  • /test pull-kubernetes-e2e-kind-alpha-beta-features
  • /test pull-kubernetes-e2e-kind-alpha-features
  • /test pull-kubernetes-e2e-kind-beta-features
  • /test pull-kubernetes-e2e-kind-canary
  • /test pull-kubernetes-e2e-kind-dual-canary
  • /test pull-kubernetes-e2e-kind-evented-pleg
  • /test pull-kubernetes-e2e-kind-ipv6-canary
  • /test pull-kubernetes-e2e-kind-ipvs-dual-canary
  • /test pull-kubernetes-e2e-kind-kms
  • /test pull-kubernetes-e2e-kind-multizone
  • /test pull-kubernetes-e2e-kind-nftables
  • /test pull-kubernetes-e2e-storage-kind-alpha-features
  • /test pull-kubernetes-e2e-storage-kind-disruptive
  • /test pull-kubernetes-e2e-ubuntu-gce-network-policies
  • /test pull-kubernetes-kind-dra
  • /test pull-kubernetes-kind-json-logging
  • /test pull-kubernetes-kind-text-logging
  • /test pull-kubernetes-kubemark-e2e-gce-big
  • /test pull-kubernetes-linter-hints
  • /test pull-kubernetes-local-e2e
  • /test pull-kubernetes-node-arm64-e2e-containerd-ec2
  • /test pull-kubernetes-node-arm64-e2e-containerd-serial-ec2
  • /test pull-kubernetes-node-arm64-ubuntu-serial-gce
  • /test pull-kubernetes-node-crio-cgrpv1-evented-pleg-e2e
  • /test pull-kubernetes-node-crio-cgrpv2-e2e
  • /test pull-kubernetes-node-crio-cgrpv2-e2e-kubetest2
  • /test pull-kubernetes-node-crio-cgrpv2-imagefs-e2e
  • /test pull-kubernetes-node-crio-cgrpv2-splitfs-e2e
  • /test pull-kubernetes-node-crio-e2e
  • /test pull-kubernetes-node-crio-e2e-kubetest2
  • /test pull-kubernetes-node-e2e-containerd-1-7-dra
  • /test pull-kubernetes-node-e2e-containerd-alpha-features
  • /test pull-kubernetes-node-e2e-containerd-ec2
  • /test pull-kubernetes-node-e2e-containerd-features
  • /test pull-kubernetes-node-e2e-containerd-features-kubetest2
  • /test pull-kubernetes-node-e2e-containerd-kubetest2
  • /test pull-kubernetes-node-e2e-containerd-serial-ec2
  • /test pull-kubernetes-node-e2e-containerd-standalone-mode
  • /test pull-kubernetes-node-e2e-containerd-standalone-mode-all-alpha
  • /test pull-kubernetes-node-e2e-crio-dra
  • /test pull-kubernetes-node-kubelet-credential-provider
  • /test pull-kubernetes-node-kubelet-serial-containerd
  • /test pull-kubernetes-node-kubelet-serial-containerd-alpha-features
  • /test pull-kubernetes-node-kubelet-serial-containerd-kubetest2
  • /test pull-kubernetes-node-kubelet-serial-containerd-sidecar-containers
  • /test pull-kubernetes-node-kubelet-serial-cpu-manager
  • /test pull-kubernetes-node-kubelet-serial-cpu-manager-kubetest2
  • /test pull-kubernetes-node-kubelet-serial-crio-cgroupv1
  • /test pull-kubernetes-node-kubelet-serial-crio-cgroupv2
  • /test pull-kubernetes-node-kubelet-serial-hugepages
  • /test pull-kubernetes-node-kubelet-serial-memory-manager
  • /test pull-kubernetes-node-kubelet-serial-pod-disruption-conditions
  • /test pull-kubernetes-node-kubelet-serial-topology-manager
  • /test pull-kubernetes-node-kubelet-serial-topology-manager-kubetest2
  • /test pull-kubernetes-node-swap-fedora
  • /test pull-kubernetes-node-swap-fedora-serial
  • /test pull-kubernetes-node-swap-ubuntu-serial
  • /test pull-kubernetes-unit-experimental
  • /test pull-publishing-bot-validate

Use /test all to run the following jobs that were automatically triggered:

  • pull-kubernetes-conformance-kind-ga-only-parallel
  • pull-kubernetes-dependencies
  • pull-kubernetes-e2e-ec2
  • pull-kubernetes-e2e-ec2-conformance
  • pull-kubernetes-e2e-gce
  • pull-kubernetes-e2e-gce-canary
  • pull-kubernetes-e2e-kind
  • pull-kubernetes-e2e-kind-ipv6
  • pull-kubernetes-integration
  • pull-kubernetes-linter-hints
  • pull-kubernetes-node-e2e-containerd
  • pull-kubernetes-typecheck
  • pull-kubernetes-unit
  • pull-kubernetes-verify
  • pull-kubernetes-verify-lint

In response to this:

/retest pull-kubernetes-integration pull-kubernetes-e2e-gce

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@k8s-ci-robot
Copy link
Contributor

LGTM label has been added.

Git tree hash: a278d15a95425c23a29b5000cdf58fe05e046444

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: cici37, pohly
Once this PR has been reviewed and has the lgtm label, please assign sttts for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found 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

@pohly
Copy link
Contributor Author

pohly commented Mar 5, 2024

/assign @liggitt

For approval as he has some context here.

return v
case types.TypeType:
return SemVerType
default:
Copy link
Member

Choose a reason for hiding this comment

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

I don't see a semVer.toString(). Do we want it? If so, we can easily implement toString there, and call it like string(ver).

Copy link
Member

@jiahuif jiahuif Mar 5, 2024

Choose a reason for hiding this comment

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

case types.StringType:
        return types.String(v.Version.String())

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 don't see the need for it.

Copy link
Member

@jiahuif jiahuif Mar 5, 2024

Choose a reason for hiding this comment

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

I am thinking of formatting an error message like "version" + string(object.version) + "is older than expected" + string(params.version) Would you want this use case?

Copy link
Member

Choose a reason for hiding this comment

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

actually no. We almost always has the string version.

semver.Version
}

func (v SemVer) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
Copy link
Member

Choose a reason for hiding this comment

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

Also, v has a value receiver instead of a pointer receiver? Is this intended?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a small struct, so I think copying by value is fine.

Copy link
Member

Choose a reason for hiding this comment

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

sgtm

@jiahuif
Copy link
Member

jiahuif commented Mar 5, 2024

/lgtm

pohly added a commit to pohly/kubernetes that referenced this pull request Mar 5, 2024
This adds support for semantic version comparison to the CEL support in the
"named resources" structured parameter model. For example, it can be used to
check that an instance supports a certain API level.

To minimize the risk, the new "semver" type is only defined in the CEL
environment for DRA expressions, not in the base library. See
kubernetes#123664 for a PR which
adds it to the base library.

Validation of semver strings is done with the regular expression from
semver.org. The actual evaluation at runtime then uses semver/v4.
return types.MaybeNoSuchOverloadErr(arg)
}

_, err := semver.Parse(str)
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 started to have second thoughts about this. In core Kubernetes, we decided to do the validation with a regular expression. The semver/v4 code then is "only" used for comparison.

But here isSemVer is implemented with semver/v4. Should this be the same regular expression as for the in-tree API?

/hold

cc @liggitt

Copy link
Member

@liggitt liggitt Mar 7, 2024

Choose a reason for hiding this comment

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

I have the same reservations here as in the REST API field about making an implementation in an external library the definition of our API surface. Using the same regexp seems equivalent in current correctness and more guaranteed to be stable long term.

If the semver library starts accepting new stuff in the future, we wouldn't want to silently expand what we accept.

if isSemVer uses our regex, and the string_to_semver ensures the string passes the regex check before calling semver.Parse, that seems ok

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ack.

@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Mar 6, 2024
pohly added a commit to pohly/kubernetes that referenced this pull request Mar 6, 2024
This adds support for semantic version comparison to the CEL support in the
"named resources" structured parameter model. For example, it can be used to
check that an instance supports a certain API level.

To minimize the risk, the new "semver" type is only defined in the CEL
environment for DRA expressions, not in the base library. See
kubernetes#123664 for a PR which
adds it to the base library.

Validation of semver strings is done with the regular expression from
semver.org. The actual evaluation at runtime then uses semver/v4.
pohly added a commit to pohly/kubernetes that referenced this pull request Mar 6, 2024
This adds support for semantic version comparison to the CEL support in the
"named resources" structured parameter model. For example, it can be used to
check that an instance supports a certain API level.

To minimize the risk, the new "semver" type is only defined in the CEL
environment for DRA expressions, not in the base library. See
kubernetes#123664 for a PR which
adds it to the base library.

Validation of semver strings is done with the regular expression from
semver.org. The actual evaluation at runtime then uses semver/v4.
pohly added a commit to pohly/kubernetes that referenced this pull request Mar 6, 2024
This adds support for semantic version comparison to the CEL support in the
"named resources" structured parameter model. For example, it can be used to
check that an instance supports a certain API level.

To minimize the risk, the new "semver" type is only defined in the CEL
environment for DRA expressions, not in the base library. See
kubernetes#123664 for a PR which
adds it to the base library.

Validation of semver strings is done with the regular expression from
semver.org. The actual evaluation at runtime then uses semver/v4.
pohly added a commit to pohly/kubernetes that referenced this pull request Mar 7, 2024
This adds support for semantic version comparison to the CEL support in the
"named resources" structured parameter model. For example, it can be used to
check that an instance supports a certain API level.

To minimize the risk, the new "semver" type is only defined in the CEL
environment for DRA expressions, not in the base library. See
kubernetes#123664 for a PR which
adds it to the base library.

Validation of semver strings is done with the regular expression from
semver.org. The actual evaluation at runtime then uses semver/v4.
pohly added a commit to pohly/kubernetes that referenced this pull request Mar 7, 2024
This adds support for semantic version comparison to the CEL support in the
"named resources" structured parameter model. For example, it can be used to
check that an instance supports a certain API level.

To minimize the risk, the new "semver" type is only defined in the CEL
environment for DRA expressions, not in the base library. See
kubernetes#123664 for a PR which
adds it to the base library.

Validation of semver strings is done with the regular expression from
semver.org. The actual evaluation at runtime then uses semver/v4.
Copy link
Member

@liggitt liggitt left a comment

Choose a reason for hiding this comment

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

left a few comments on regexp use and naming

also left a couple questions around the CEL surface area I don't know enough to answer (maybe @cici37 or @jpbetz knows)

Comment on lines +100 to +103
"semver": {
cel.Overload("string_to_semver", []*cel.Type{cel.StringType}, apiservercel.SemVerType, cel.UnaryBinding((stringToSemVer))),
},
"isSemVer": {
Copy link
Member

Choose a reason for hiding this comment

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

nit: is it weird to have semver but isSemVer?

seems like we should have a matched pair:

  • semver / isSemver
  • semVer / isSemVer

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 tend to agree. I tripped myself up with this inconsistency a few times.

I think I was starting with "Semantic Version" -> "SemVer" and then used "semver" for consistency with "quantity".

Let's use isSemver, it's simpler.


// SemVer provdes a CEL representation of a [semver.SemVer].
type SemVer struct {
semver.Version
Copy link
Member

Choose a reason for hiding this comment

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

does inlining this make the semver library fields / methods public / visible to CEL? if so, that doesn't seem desirable

Copy link
Member

Choose a reason for hiding this comment

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

No, it doesn't. To expose fields of an object we manually define them with a CEL type provider and make it index-able with a trait. This type has neither of these.

return types.WrapErr(err)
}

return apiservercel.SemVer{Version: v}
Copy link
Member

Choose a reason for hiding this comment

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

I don't know CEL stuff well enough to know if this is exposing the underlying blang semver impl fields / methods to CEL ... I don't think we want to do that, right?

Copy link
Member

Choose a reason for hiding this comment

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

It won't expose any fields. Only functions that are "exposed" are manually defined overloads, namely major(), minor(), and patch().

@@ -128,6 +128,7 @@ var baseOpts = []VersionedOptions{
EnvOptions: []cel.EnvOption{
library.IP(),
library.CIDR(),
library.SemVer(),
Copy link
Member

Choose a reason for hiding this comment

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

commented at https://github.com/kubernetes/kubernetes/pull/123516/files#r1516500003 with one possibility for handling this for the namedresources use

pohly added a commit to pohly/kubernetes that referenced this pull request Mar 7, 2024
This adds support for semantic version comparison to the CEL support in the
"named resources" structured parameter model. For example, it can be used to
check that an instance supports a certain API level.

To minimize the risk, the new "semver" type is only defined in the CEL
environment for DRA expressions, not in the base library. See
kubernetes#123664 for a PR which
adds it to the base library.

Validation of semver strings is done with the regular expression from
semver.org. The actual evaluation at runtime then uses semver/v4.
k8s-publishing-bot pushed a commit to kubernetes/api that referenced this pull request Mar 8, 2024
This adds support for semantic version comparison to the CEL support in the
"named resources" structured parameter model. For example, it can be used to
check that an instance supports a certain API level.

To minimize the risk, the new "semver" type is only defined in the CEL
environment for DRA expressions, not in the base library. See
kubernetes/kubernetes#123664 for a PR which
adds it to the base library.

Validation of semver strings is done with the regular expression from
semver.org. The actual evaluation at runtime then uses semver/v4.

Kubernetes-commit: 42ee56f093133402ed860d4c5f54b049041386c9
k8s-publishing-bot pushed a commit to kubernetes/client-go that referenced this pull request Mar 8, 2024
This adds support for semantic version comparison to the CEL support in the
"named resources" structured parameter model. For example, it can be used to
check that an instance supports a certain API level.

To minimize the risk, the new "semver" type is only defined in the CEL
environment for DRA expressions, not in the base library. See
kubernetes/kubernetes#123664 for a PR which
adds it to the base library.

Validation of semver strings is done with the regular expression from
semver.org. The actual evaluation at runtime then uses semver/v4.

Kubernetes-commit: 42ee56f093133402ed860d4c5f54b049041386c9
k8s-publishing-bot pushed a commit to kubernetes/dynamic-resource-allocation that referenced this pull request Mar 8, 2024
This adds support for semantic version comparison to the CEL support in the
"named resources" structured parameter model. For example, it can be used to
check that an instance supports a certain API level.

To minimize the risk, the new "semver" type is only defined in the CEL
environment for DRA expressions, not in the base library. See
kubernetes/kubernetes#123664 for a PR which
adds it to the base library.

Validation of semver strings is done with the regular expression from
semver.org. The actual evaluation at runtime then uses semver/v4.

Kubernetes-commit: 42ee56f093133402ed860d4c5f54b049041386c9
cmwylie19 pushed a commit to cmwylie19/kubernetes that referenced this pull request Mar 11, 2024
This adds support for semantic version comparison to the CEL support in the
"named resources" structured parameter model. For example, it can be used to
check that an instance supports a certain API level.

To minimize the risk, the new "semver" type is only defined in the CEL
environment for DRA expressions, not in the base library. See
kubernetes#123664 for a PR which
adds it to the base library.

Validation of semver strings is done with the regular expression from
semver.org. The actual evaluation at runtime then uses semver/v4.
@jiahuif
Copy link
Member

jiahuif commented Mar 12, 2024

/triage accepted

@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 Mar 12, 2024
dinhxuanvu pushed a commit to dinhxuanvu/kubernetes that referenced this pull request Mar 28, 2024
This adds support for semantic version comparison to the CEL support in the
"named resources" structured parameter model. For example, it can be used to
check that an instance supports a certain API level.

To minimize the risk, the new "semver" type is only defined in the CEL
environment for DRA expressions, not in the base library. See
kubernetes#123664 for a PR which
adds it to the base library.

Validation of semver strings is done with the regular expression from
semver.org. The actual evaluation at runtime then uses semver/v4.
cmwylie19 pushed a commit to cmwylie19/kubernetes that referenced this pull request Apr 24, 2024
This adds support for semantic version comparison to the CEL support in the
"named resources" structured parameter model. For example, it can be used to
check that an instance supports a certain API level.

To minimize the risk, the new "semver" type is only defined in the CEL
environment for DRA expressions, not in the base library. See
kubernetes#123664 for a PR which
adds it to the base library.

Validation of semver strings is done with the regular expression from
semver.org. The actual evaluation at runtime then uses semver/v4.
@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, 2024
@k8s-ci-robot
Copy link
Contributor

PR needs rebase.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@pohly
Copy link
Contributor Author

pohly commented Apr 26, 2024

@jiahuif, @cici37: what is the conclusion: do you want this in the core library or shall I keep it separate as an extension in the DRA CEL environment?

I'm leaning towards moving it to the code library, but I am also open for keeping it specific to DRA.

If you want it, then I'll rework this PR to also remove the code in DRA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/apiserver area/code-generation cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. kind/feature Categorizes issue or PR as related to a new feature. lgtm "Looks good to me", indicates that a PR is ready to be merged. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. size/XL Denotes a PR that changes 500-999 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.

None yet

5 participants