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

Add validation for Workload via webhook #225

Merged
merged 1 commit into from
May 6, 2022

Conversation

knight42
Copy link
Member

Signed-off-by: Jian Zeng [email protected]

What type of PR is this?

/kind feature

What this PR does / why we need it:

Add basic validating webhook for Workload.

Which issue(s) this PR fixes:

Part of #171

Special notes for your reviewer:

@k8s-ci-robot k8s-ci-robot added 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. labels Apr 20, 2022
@k8s-ci-robot k8s-ci-robot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Apr 20, 2022
@knight42
Copy link
Member Author

/cc @ahg-g @kerthcet

@k8s-ci-robot k8s-ci-robot requested a review from ahg-g April 20, 2022 03:56
@k8s-ci-robot
Copy link
Contributor

@knight42: GitHub didn't allow me to request PR reviews from the following users: kerthcet.

Note that only kubernetes-sigs members and repo collaborators can review this PR, and authors cannot review their own PRs.

In response to this:

/cc @ahg-g @kerthcet

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.

}

// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
func (r *Workload) ValidateDelete() error {
return nil
}

func validateWorkload(obj *Workload) field.ErrorList {
Copy link
Contributor

Choose a reason for hiding this comment

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

We should also validate the PriorityClassName, it should be a DNS subdomain, although we ensured this in JobController, but we will have multi implements in the future, it can prevent the problem as early as possible.

Copy link
Contributor

Choose a reason for hiding this comment

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

Should we also make sure the queue name shouldn't be empty as I asked before. I think so if we don't have default ones. @ahg-g

Copy link
Member

Choose a reason for hiding this comment

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

Should we also make sure the queue name shouldn't be empty as I asked before. I think so if we don't have default ones.

How about if the user create the default queue after the workload created ?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should not fail the Workload creation if the queue name is missing. This is because a user could create a Job without a queue annotation and decide to add it later. We need the Workload object to post an Event that indicates why the workload is not schedulable.

Copy link
Member

@denkensk denkensk left a comment

Choose a reason for hiding this comment

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

Thanks @knight42
some comments.

}

// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
func (r *Workload) ValidateDelete() error {
return nil
}

func validateWorkload(obj *Workload) field.ErrorList {
Copy link
Member

Choose a reason for hiding this comment

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

Should we also make sure the queue name shouldn't be empty as I asked before. I think so if we don't have default ones.

How about if the user create the default queue after the workload created ?

for i, podSet := range obj.Spec.PodSets {
if podSet.Count <= 0 {
allErrs = append(allErrs, field.Invalid(
field.NewPath("spec").Child("podSets").Index(i).Child("count"),
Copy link
Member

Choose a reason for hiding this comment

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

Can you also check the priority in workload?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah of course, the highest priority for user defined priority class is 1 biliion, should we take predefined system priority classes into account as well?

@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Apr 20, 2022
@knight42 knight42 requested a review from denkensk April 20, 2022 15:32
@alculquicondor
Copy link
Contributor

/assign

@alculquicondor
Copy link
Contributor

/retitle Add validation for Workload via webhook

@k8s-ci-robot k8s-ci-robot changed the title feat: add validating webhook for Workload Add validation for Workload via webhook Apr 25, 2022
}

// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
func (r *Workload) ValidateDelete() error {
return nil
}

func validateWorkload(obj *Workload) field.ErrorList {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should not fail the Workload creation if the queue name is missing. This is because a user could create a Job without a queue annotation and decide to add it later. We need the Workload object to post an Event that indicates why the workload is not schedulable.

@knight42 knight42 requested a review from alculquicondor April 27, 2022 17:07
)

// makeWorkload is copied from "sigs.k8s.io/kueue/pkg/util/testing"
// NOTE: we could not import "sigs.k8s.io/kueue/pkg/util/testing" because of cyclic import.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you can avoid the circular dependency doing this: https://github.com/golang/go/wiki/CodeReviewComments#import-dot

Copy link
Member Author

Choose a reason for hiding this comment

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

@alculquicondor Hi, I have switched to dot import, but it seems a workaround to me, should me move the validation logic to a separate package, such as pkg/validation?

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah, that's actually a better idea.

Let's do it in apis/kueue/v1alpha1/validation

Copy link
Member Author

Choose a reason for hiding this comment

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

hmm I just realize this won't work, the circular dependency still persists: the package apis/kueue/v1alpha1/validation imports the Worload struct from apis/kueue/v1alpha1, and apis/kueue/v1alpha1 imports apis/kueue/v1alpha1/validation for the validator. The root cause is that the validator function is called inside apis/kueue/v1alpha1 package.

Copy link
Contributor

Choose a reason for hiding this comment

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

Workload doesn't have to implement the Defaulter or Validator interface. You could create a new type for it that lives in a webhooks package.

Copy link
Member Author

Choose a reason for hiding this comment

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

Regarding of the definition of Defaulter or Validator interface:

type Defaulter interface {
	runtime.Object
	Default()
}
type Validator interface {
	runtime.Object
	ValidateCreate() error
	ValidateUpdate(old runtime.Object) error
	ValidateDelete() error
}

it seems these interfaces could only be implements on the Workload struct, otherwise we could not access the fields.

Copy link
Contributor

Choose a reason for hiding this comment

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

ahhh, I missed that they depend on runtime.Object 😞

I guess we have to go the dotimport route then.

@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 30, 2022
@knight42 knight42 force-pushed the feat/validate-webhook branch from 8335f02 to 977d6b7 Compare April 30, 2022 12:00
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Apr 30, 2022
@knight42 knight42 force-pushed the feat/validate-webhook branch from 977d6b7 to 9409e57 Compare April 30, 2022 12:15
@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 1, 2022
@knight42 knight42 force-pushed the feat/validate-webhook branch from 9409e57 to 0053275 Compare May 1, 2022 12:00
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 1, 2022
@ahg-g
Copy link
Contributor

ahg-g commented May 5, 2022

@knight42 do you need help moving forward with this PR?

@knight42
Copy link
Member Author

knight42 commented May 5, 2022

@ahg-g Hi! Sorry for the late response, I just return from vacation, I am discussing with @alculquicondor about the implmenetation details: #225 (comment). It would be nice if I could hear your advice!

@ahg-g
Copy link
Contributor

ahg-g commented May 5, 2022

@ahg-g Hi! Sorry for the late response, I just return from vacation, I am discussing with @alculquicondor about the implmenetation details: #225 (comment).

Thank a lot @knight42 , I was just wondering if there is something you needed help with, I hope you had a great vacation :)

It would be nice if I could hear your advice!

I will leave this to Aldo just so you get consistent feedback.

@@ -0,0 +1,57 @@
// Rename the package to avoid circular dependencies which is caused by "sigs.k8s.io/kueue/pkg/util/testing".
// See also: https://github.com/golang/go/wiki/CodeReviewComments#import-dot
Copy link
Contributor

Choose a reason for hiding this comment

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

This file is missing the copyright notice.

Also, a comment just up from the package name makes it part of the package doc. Can you move it bellow?

return w
}

func (w *WorkloadWrapper) PodSetCount(count int32) *WorkloadWrapper {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is way too specific. Just use PodSets to pass a list with the necessary count.

err := k8sClient.Create(ctx, workload)
gomega.Expect(err).Should(gomega.HaveOccurred())
status := err.(*errors.StatusError).Status()
gomega.Expect(status).Should(testing.Equal(metav1.Status{
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be clearer to just use errors.IsInvalid.

@knight42 knight42 requested a review from alculquicondor May 5, 2022 16:11
Copy link
Contributor

@alculquicondor alculquicondor left a comment

Choose a reason for hiding this comment

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

Awesome

/approve

Can you please squash the commits?

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: alculquicondor, knight42

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

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label May 5, 2022
@knight42 knight42 force-pushed the feat/validate-webhook branch from e8d2cc3 to e5d79ab Compare May 6, 2022 04:21
@knight42 knight42 requested a review from alculquicondor May 6, 2022 04:24
Copy link
Contributor

@alculquicondor alculquicondor left a comment

Choose a reason for hiding this comment

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

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label May 6, 2022
@k8s-ci-robot k8s-ci-robot merged commit 4bd0feb into kubernetes-sigs:main May 6, 2022
@knight42 knight42 deleted the feat/validate-webhook branch May 15, 2022 13:09
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. 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. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants