Skip to content

filterBy cannot filtered by time related parameters #9938

Open
@lex1ng

Description

@lex1ng

What happened?

When I request GET /api/v1/pod?filterBy=creationTimestamp,2025-02-10T14:54:03Z, it fails and the api pod log shows:

2025/02/12 02:48:42 http: panic serving xxxx:xxx: interface conversion: dataselect.ComparableValue is dataselect.StdComparableString, not dataselect.StdComparableTime
goroutine 5112 [running]:
net/http.(*conn).serve.func1()
        net/http/server.go:1947 +0xbe
panic({0x1f04360?, 0xc00130b410?})
        runtime/panic.go:785 +0x132
k8s.io/dashboard/api/pkg/resource/dataselect.StdComparableTime.Compare({0x0?, 0x0?, 0x381a080?}, {0x25620f0?, 0xc000ea9500?})
        k8s.io/dashboard/api/pkg/resource/dataselect/stdcomparabletypes.go:74 +0xb7
k8s.io/dashboard/api/pkg/resource/dataselect.StdComparableTime.Contains(...)
        k8s.io/dashboard/api/pkg/resource/dataselect/stdcomparabletypes.go:79
k8s.io/dashboard/api/pkg/resource/dataselect.(*DataSelector).Filter(0xc0004b9b40)
        k8s.io/dashboard/api/pkg/resource/dataselect/dataselect.go:115 +0x20a
k8s.io/dashboard/api/pkg/resource/dataselect.GenericDataSelectWithFilterAndMetrics({0xc001e94008?, 0xc0004ba6f8?, 0x0?}, 0x0?, 0x0?, {0x257c7a0, 0xc000352570})
        k8s.io/dashboard/api/pkg/resource/dataselect/dataselect.go:284 +0xbd
k8s.io/dashboard/api/pkg/resource/pod.ToPodList({0xc001f16000, 0xf2, 0x7fcda238c108?}, {0xc004c00000, 0x151b, 0x15eb}, {0x383eac0?, 0x7fcc5b462bc0?, 0x40?}, 0xc00309bae0, ...)
...
...
...

And I check the code and found that at modules/api/pkg/resource/dataselect/dataselectquery.go, it always transform the filterValue into dataselect.StdComparableString.

func NewFilterQuery(filterByListRaw []string) *FilterQuery {
	if filterByListRaw == nil || len(filterByListRaw)%2 == 1 {
		return NoFilter
	}
	filterByList := []FilterBy{}
	for i := 0; i+1 < len(filterByListRaw); i += 2 {
		propertyName := filterByListRaw[i]
		propertyValue := filterByListRaw[i+1]
		filterBy := FilterBy{
			Property: PropertyName(propertyName),
			Value:    StdComparableString(propertyValue),
		}
		// Add to the filter options.
		filterByList = append(filterByList, filterBy)
	}
	return &FilterQuery{
		FilterByList: filterByList,
	}
}

And when I want to filterBy creationTimestamp, the filterBy Property is dataselect.StdComparableTime (in modules/api/pkg/resource/pod/common.go)

func (self PodCell) GetProperty(name dataselect.PropertyName) dataselect.ComparableValue {
	switch name {
	case dataselect.NameProperty:
		return dataselect.StdComparableString(self.ObjectMeta.Name)
	case dataselect.StatusProperty:
		return dataselect.StdComparableString(getPodStatus(v1.Pod(self)))
	case dataselect.CreationTimestampProperty:
		return dataselect.StdComparableTime(self.ObjectMeta.CreationTimestamp.Time)
	case dataselect.NamespaceProperty:
		return dataselect.StdComparableString(self.ObjectMeta.Namespace)
	default:
		// if name is not supported then just return a constant dummy value, sort will have no effect.
		return nil
	}
}

As a consequnce, when the actual filter action perform, the code check StdComparableTime.Contains(StdComparableString) (found in modules/api/pkg/resource/dataselect/dataselect.go)

func (self *DataSelector) Filter() *DataSelector {
	filteredList := []DataCell{}

	for _, c := range self.GenericDataList {
		matches := true
		for _, filterBy := range self.DataSelectQuery.FilterQuery.FilterByList {
			v := c.GetProperty(filterBy.Property)
			if v == nil || !v.Contains(filterBy.Value) {
				matches = false
				break
			}
		}
		if matches {
			filteredList = append(filteredList, c)
		}
	}

	self.GenericDataList = filteredList
	return self
}

And the error occurs since the StdComparableString cannot be transfromed into StdComparableTime, (modules/api/pkg/resource/dataselect/stdcomparabletypes.go)

func (self StdComparableTime) Compare(otherV ComparableValue) int {
	other := otherV.(StdComparableTime)
	return ints64Compare(time.Time(self).Unix(), time.Time(other).Unix())
}

What did you expect to happen?

can filterBy time related parameters, like creationTimestamp, firstSeen, etc..

If the StdComparableString can not transform into StdComparableTime, I think we should transform the filterBy value into different StdComparableXXX according to the filterBy key. Actually, I don't see any usage about StdComparableInt, StdComparableRFC3339Timestamp and StdComparableTime.

BTW, How can I pass in the time related value as the filerBy valule in my request. I just copied the creationTimestamp in the objectMeta.creationTimestamp.

How can we reproduce it (as minimally and precisely as possible)?

Try GET /api/v1/pod?filterBy=creationTimestamp,2025-02-10T14:54:03Z.

Anything else we need to know?

I'd like to work on this issue and submit a pull request if needed.

if there is a need for submitting a pr, are there any specific implementation details I should be aware of?

What browsers are you seeing the problem on?

No response

Kubernetes Dashboard version

api images: dashboard-api:1.10.1

Kubernetes version

Client Version: version.Info{Major:"1", Minor:"24", GitVersion:"v1.24.4", GitCommit:"95ee5ab382d64cfe6c28967f36b53970b8374491", GitTreeState:"clean", BuildDate:"2022-08-17T18:54:23Z", GoVersion:"go1.18.5", Compiler:"gc", Platform:"linux/amd64"} Kustomize Version: v4.5.4 Server Version: version.Info{Major:"1", Minor:"24", GitVersion:"v1.24.4", GitCommit:"95ee5ab382d64cfe6c28967f36b53970b8374491", GitTreeState:"clean", BuildDate:"2022-08-17T18:47:37Z", GoVersion:"go1.18.5", Compiler:"gc", Platform:"linux/amd64"}

Dev environment

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugCategorizes issue or PR as related to a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions