Describe the bug
filterQuery is accepted but never applied on GET /api/model_registry/v1/serving_environments and GET /api/model_registry/v1/model_artifacts (and their v1alpha3 equivalents). Both endpoints return the full unfiltered list, and an invalid filter expression is accepted instead of being rejected as a bad request.
The handlers forward the parameter. The value is dropped in the core layer: GetServingEnvironments (internal/core/serving_environment.go:105) and GetModelArtifacts (internal/core/artifact.go:598) build models.Pagination from the incoming api.ListOptions but leave out FilterQuery. Serving environments have a second cause: ServingEnvironmentListOptions in internal/db/models/serving_environment.go does not implement GetRestEntityType, so the listOptions.(FilterApplier) assertion in internal/platform/db/repository/generic_repository.go:50 fails and the filter is skipped even once the field is set.
This is the same defect #3207 reported for /inference_services and /serves. That issue said the remaining list endpoints applied filterQuery correctly, but these two do not.
To Reproduce
Steps to reproduce the behavior:
- On
main (e43c096), add this file as internal/core/zz_repro_test.go:
package core_test
import (
"testing"
"github.com/kubeflow/hub/pkg/api"
"github.com/kubeflow/hub/pkg/openapi"
"github.com/stretchr/testify/require"
)
func TestReproFilterQueryIgnored(t *testing.T) {
svc, cleanup := SetupModelRegistryService(t)
defer cleanup()
for _, n := range []string{"prod-env", "staging-env"} {
_, err := svc.UpsertServingEnvironment(&openapi.ServingEnvironment{Name: n})
require.NoError(t, err)
}
rm, err := svc.UpsertRegisteredModel(&openapi.RegisteredModel{Name: "rm"})
require.NoError(t, err)
mv, err := svc.UpsertModelVersion(&openapi.ModelVersion{Name: "v1", RegisteredModelId: *rm.Id}, rm.Id)
require.NoError(t, err)
for _, n := range []string{"model-a", "model-b"} {
_, err := svc.UpsertModelVersionArtifact(&openapi.Artifact{
ModelArtifact: &openapi.ModelArtifact{Name: new(n), Uri: new("s3://bucket/" + n)},
}, *mv.Id)
require.NoError(t, err)
}
envFilter := "name = 'prod-env'"
envs, err := svc.GetServingEnvironments(api.ListOptions{FilterQuery: &envFilter})
require.NoError(t, err)
t.Logf("serving_environments?filterQuery=%s -> size=%d (2 exist, 1 matches)", envFilter, envs.Size)
artFilter := "name = 'model-a'"
arts, err := svc.GetModelArtifacts(api.ListOptions{FilterQuery: &artFilter}, nil)
require.NoError(t, err)
t.Logf("model_artifacts?filterQuery=%s -> size=%d (2 exist, 1 matches)", artFilter, arts.Size)
bad := "invalid <<<syntax"
_, envErr := svc.GetServingEnvironments(api.ListOptions{FilterQuery: &bad})
_, artErr := svc.GetModelArtifacts(api.ListOptions{FilterQuery: &bad}, nil)
t.Logf("invalid filter -> serving_environments err=%v; model_artifacts err=%v", envErr, artErr)
}
-
With Docker running, run go test ./internal/core/ -run TestReproFilterQueryIgnored -count=1 -v.
-
Every filter is ignored and the invalid filter returns no error:
=== RUN TestReproFilterQueryIgnored
zz_repro_test.go:33: serving_environments?filterQuery=name = 'prod-env' -> size=2 (2 exist, 1 matches)
zz_repro_test.go:38: model_artifacts?filterQuery=name = 'model-a' -> size=2 (2 exist, 1 matches)
zz_repro_test.go:43: invalid filter -> serving_environments err=<nil>; model_artifacts err=<nil>
--- PASS: TestReproFilterQueryIgnored (1.33s)
Expected behavior
filterQuery should restrict the result the same way it does on /registered_models, /model_versions, /inference_services and /serves, and an unparseable filter should fail as a bad request instead of being silently dropped. With FilterQuery propagated in both core methods and GetRestEntityType implemented on ServingEnvironmentListOptions, the same repro prints:
zz_repro_test.go:33: serving_environments?filterQuery=name = 'prod-env' -> size=1 (2 exist, 1 matches)
zz_repro_test.go:38: model_artifacts?filterQuery=name = 'model-a' -> size=1 (2 exist, 1 matches)
zz_repro_test.go:43: invalid filter -> serving_environments err=invalid filter query syntax: error parsing filter query: 1:10: unexpected token "<" (expected Value) ... : bad request; model_artifacts err=invalid filter query syntax: ... : bad request
Environment
- Kubernetes version: not applicable, reproduced against the Go core with the testcontainers MySQL 8.3 database that
make test uses
- Kubernetes distribution: not applicable
- Go 1.26.1, macOS arm64, repository at
main e43c096
Additional context
Sibling of #3207, which was fixed by #3208 for two of the four affected list endpoints. I have a fix with tests and will open a PR.
Describe the bug
filterQueryis accepted but never applied onGET /api/model_registry/v1/serving_environmentsandGET /api/model_registry/v1/model_artifacts(and their v1alpha3 equivalents). Both endpoints return the full unfiltered list, and an invalid filter expression is accepted instead of being rejected as a bad request.The handlers forward the parameter. The value is dropped in the core layer:
GetServingEnvironments(internal/core/serving_environment.go:105) andGetModelArtifacts(internal/core/artifact.go:598) buildmodels.Paginationfrom the incomingapi.ListOptionsbut leave outFilterQuery. Serving environments have a second cause:ServingEnvironmentListOptionsininternal/db/models/serving_environment.godoes not implementGetRestEntityType, so thelistOptions.(FilterApplier)assertion ininternal/platform/db/repository/generic_repository.go:50fails and the filter is skipped even once the field is set.This is the same defect #3207 reported for
/inference_servicesand/serves. That issue said the remaining list endpoints appliedfilterQuerycorrectly, but these two do not.To Reproduce
Steps to reproduce the behavior:
main(e43c096), add this file asinternal/core/zz_repro_test.go:With Docker running, run
go test ./internal/core/ -run TestReproFilterQueryIgnored -count=1 -v.Every filter is ignored and the invalid filter returns no error:
Expected behavior
filterQueryshould restrict the result the same way it does on/registered_models,/model_versions,/inference_servicesand/serves, and an unparseable filter should fail as a bad request instead of being silently dropped. WithFilterQuerypropagated in both core methods andGetRestEntityTypeimplemented onServingEnvironmentListOptions, the same repro prints:Environment
make testusesmaine43c096Additional context
Sibling of #3207, which was fixed by #3208 for two of the four affected list endpoints. I have a fix with tests and will open a PR.