fix(backend): validate pipeline names in K8s store before API call#13137
fix(backend): validate pipeline names in K8s store before API call#13137Priyanshu-u07 wants to merge 6 commits intokubeflow:masterfrom
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Hi @Priyanshu-u07. Thanks for your PR. I'm waiting for a kubeflow member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions 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. |
There was a problem hiding this comment.
Pull request overview
This PR adds early pipeline and pipeline-version name validation in the Kubernetes pipeline store to fail fast (before calling the Kubernetes API server) when user-provided names are invalid, and updates/extends unit tests accordingly.
Changes:
- Validate pipeline names in
CreatePipeline()beforek.client.Create(). - Validate pipeline version names in
createPipelineVersionWithPipeline()beforek.client.Create(). - Update Kubernetes store tests to use DNS-compliant names and add negative tests for invalid names.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
backend/src/apiserver/storage/pipeline_store_kubernetes.go |
Adds pre-flight name validation for pipelines and pipeline versions before Kubernetes API calls. |
backend/src/apiserver/storage/pipeline_store_kubernetes_test.go |
Updates existing tests to use lowercase/dash names and adds new tests for invalid names. |
43c8e16 to
20faef4
Compare
c8dab44 to
eea60e7
Compare
Signed-off-by: Priyanshu-u07 <connect.priyanshu8271@gmail.com>
eea60e7 to
9a058ac
Compare
Signed-off-by: Priyanshu-u07 <connect.priyanshu8271@gmail.com>
|
I reviewed the current PR diff against origin/master and found two remaining gaps.
Verification I ran locally:
Both passed. |
|
/ok-to-test |
|
That's weird. Tests were not triggered. |
|
/hold |
3fb121a to
b04f3e6
Compare
|
Thanks @jeffspahr for review! I've addressed both gaps as upload server now surfaces validation errors instead of generic responses and pipeline version creation has preflight DNS check. Both verification commands pass locally. |
|
Thanks @hbelmiro! Could you please /unhold? |
|
/unhold |
jeffspahr
left a comment
There was a problem hiding this comment.
Two issues remain on the current head.
- The new upload
BadRequestpath now passes raw*util.UserErrorvalues intowriteErrorToResponse, so clients receive the internal wrapped message/details instead of the clean external validation message this PR is trying to surface. CreatePipelineAndPipelineVersionis still not atomic when the pipeline-version name is invalid. The combined create path persists the Pipeline before the new version-name validation runs, so a failed combined create can still leave an orphaned pipeline behind.
Targeted verification on 138da32c0e000bf932708476c496b96312537a6d:
go test ./backend/src/apiserver/storage -run 'TestCreateK8sPipeline|TestCreateK8sPipelineVersion|TestCreatePipelineAndPipelineVersion' -count=1go test ./backend/src/apiserver/server -run 'TestUploadPipelineV2_NameValidation|TestUploadPipeline_NameAndNamespaceTooLong' -count=1
| return | ||
| } | ||
| if util.IsUserErrorCodeMatch(err, codes.InvalidArgument) { | ||
| glog.Errorf("Failed to create a pipeline and a pipeline version: %v", err) |
There was a problem hiding this comment.
Passing the raw *util.UserError into writeErrorToResponse leaks the internal wrapped message/details here. That helper serializes err.Error() and %+v, so clients now see strings like Failed to create ...: Invalid input error: ... instead of just the external validation message. Please unwrap UserError to ExternalMessage() before writing the HTTP response, or make the helper do that centrally.
There was a problem hiding this comment.
Done, now unwrapping with ExternalMessage() before writing the HTTP response.
|
|
||
| func (k *PipelineStoreKubernetes) createPipelineVersionWithPipeline(ctx context.Context, pipeline *model.Pipeline, pipelineVersion *model.PipelineVersion) (*model.PipelineVersion, error) { | ||
| // Validate the pipeline version name is a valid Kubernetes resource name before sending to the API. | ||
| if errs := validation.IsDNS1123Subdomain(pipelineVersion.Name); len(errs) > 0 { |
There was a problem hiding this comment.
This validation still runs too late for the combined create path. CreatePipelineAndPipelineVersion() creates the Pipeline first, then calls createPipelineVersionWithPipeline(), so a valid pipeline name plus invalid version name still returns an error after the Pipeline has already been persisted. Please validate both names before creating either resource, or delete the Pipeline on version-create failure.
There was a problem hiding this comment.
Done, now validate both names before creating either resource.
|
/retest |
138da32 to
9c0e774
Compare
9c0e774 to
3cb5a4e
Compare
jeffspahr
left a comment
There was a problem hiding this comment.
Re-reviewed the current head and the two previously reported correctness issues are fixed:
- the upload handlers now unwrap
ExternalMessage()before returning HTTP 400s CreatePipelineAndPipelineVersion()now validates the pipeline-version name before persisting the pipeline, so the combined create path is atomic again for invalid version names
I did not find any new blocking behavior issues on the current diff.
The remaining gap is test coverage. The new invalid-name handling for /pipelines/upload_version still does not have a regression test. TestUploadPipelineV2_NameValidation covers the pipeline upload path, and the existing version-upload tests cover file/length failures, but there is not yet a focused test that proves an invalid version name comes back as the intended 400 with the surfaced validation message.
Please add that upload-version invalid-name test before merge so this HTTP path is covered as well.
Verification I ran locally:
go test ./backend/src/apiserver/storage -run 'TestCreateK8sPipeline|TestCreateK8sPipelineVersion|TestCreatePipelineAndPipelineVersion' -count=1go test ./backend/src/apiserver/server -run 'TestUploadPipelineV2_NameValidation|TestUploadPipeline_NameAndNamespaceTooLong' -count=1go test ./backend/src/apiserver/server -run 'TestUploadPipelineVersion' -count=1
d31ff7a to
b43d8ab
Compare
b43d8ab to
d76af8e
Compare
Signed-off-by: Priyanshu-u07 <connect.priyanshu8271@gmail.com>
d76af8e to
c34c12d
Compare
|
@jeffspahr, Added the requested regression test All verification are passing:
|
jeffspahr
left a comment
There was a problem hiding this comment.
Re-reviewed the current head and I did not find any remaining blocking correctness issues in this diff.
The earlier gaps are fixed on 3747302b931283f76f4f70465a2fb66344a70795:
- the upload handlers now unwrap
ExternalMessage()before returning HTTP 400 validation responses CreatePipelineAndPipelineVersion()now validates the pipeline-version name before persisting the pipeline, so the combined create path is atomic again for invalid version names- the
/pipelines/upload_versioninvalid-name path now has focused regression coverage viaTestUploadPipelineVersion_InvalidName
Verification I ran locally:
go test ./backend/src/apiserver/storage -run 'TestCreateK8sPipeline|TestCreateK8sPipelineVersion|TestCreatePipelineAndPipelineVersion' -count=1go test ./backend/src/apiserver/server -run 'TestUploadPipelineV2_NameValidation|TestUploadPipeline_NameAndNamespaceTooLong|TestUploadPipelineVersion|TestUploadPipelineVersion_InvalidName' -count=1
Residual risk is low and limited to the broader unrun backend/integration suites.
|
New changes are detected. LGTM label has been removed. |
|
/retest |
Description of your changes:
Adds early pipeline name validation in pipeline_store_kubernetes.go before
k.client.Create()is called. This catches invalid names (uppercase, spaces, etc.) with a clear error message before any round-trip to the Kubernetes API server.Changes:
display_namefor human-readable labelsThis fix only affects the Kubernetes backend. The SQL backend is unchanged
Fixes #13111 .