Skip to content

filterQuery is ignored on GET /serving_environments and GET /model_artifacts #3219

Description

@rishabhsai

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:

  1. 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)
}
  1. With Docker running, run go test ./internal/core/ -run TestReproFilterQueryIgnored -count=1 -v.

  2. 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions