staging: add ResourceClaim support code

This is similar to the support code for generic ephemeral inline volumes.
Differences:
- to avoid stuttering, the functions are just resourceclaim.Name and
  resourceclaim.IsForPod
- resourceclaim.Name returns the right name for both cases (template
  and reference), which will simplify some code

Other helper functions check some simple status conditions.
This commit is contained in:
Patrick Ohly 2022-03-22 10:57:34 +01:00
parent 76cb805af2
commit 59d46c026f
5 changed files with 319 additions and 1 deletions

View File

@ -4,4 +4,30 @@ module k8s.io/dynamic-resource-allocation
go 1.19
replace k8s.io/dynamic-resource-allocation => ../dynamic-resource-allocation
require (
k8s.io/api v0.0.0
k8s.io/apimachinery v0.0.0
)
require (
github.com/go-logr/logr v1.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/gofuzz v1.1.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
golang.org/x/net v0.1.1-0.20221027164007-c63010009c80 // indirect
golang.org/x/text v0.4.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/klog/v2 v2.80.1 // indirect
k8s.io/utils v0.0.0-20221107191617-1a15be271d1d // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
)
replace (
k8s.io/api => ../api
k8s.io/apimachinery => ../apimachinery
k8s.io/dynamic-resource-allocation => ../dynamic-resource-allocation
)

View File

@ -0,0 +1,77 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.1.1-0.20221027164007-c63010009c80 h1:CtRWmqbiPSOXwJV1JoY7pWiTx2xzVKQ813bvU+Y/9jI=
golang.org/x/net v0.1.1-0.20221027164007-c63010009c80/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=
k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/utils v0.0.0-20221107191617-1a15be271d1d h1:0Smp/HP1OH4Rvhe+4B8nWGERtlqAGSftbSbbmm45oFs=
k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=

View File

@ -0,0 +1,81 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package resourceclaim provides code that supports the usual pattern
// for accessing the ResourceClaim that is referenced by a PodResourceClaim:
//
// - determine the ResourceClaim name that corresponds to the PodResourceClaim
// - retrieve the ResourceClaim
// - verify that the ResourceClaim is owned by the pod if generated from a template
// - use the ResourceClaim
package resourceclaim
import (
"fmt"
v1 "k8s.io/api/core/v1"
resourcev1alpha1 "k8s.io/api/resource/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Name returns the name of the ResourceClaim object that gets referenced by or
// created for the PodResourceClaim. The name is deterministic and therefore
// this function does not need any additional information and it will never
// fail.
//
// Either podClaim.ResourceClaimName or podClaim.Template must be non-nil, but not
// both. This is enforced by API validation.
//
// If podClaim.Template is not nil, the caller must check that the
// ResourceClaim is indeed the one that was created for the Pod by calling
// IsUsable.
func Name(pod *v1.Pod, podClaim *v1.PodResourceClaim) string {
if podClaim.Source.ResourceClaimName != nil {
return *podClaim.Source.ResourceClaimName
}
return pod.Name + "-" + podClaim.Name
}
// IsForPod checks that the ResourceClaim is the ephemeral volume that
// was created for the Pod. It returns an error that is informative
// enough to be returned by the caller without adding further details
// about the Pod or ResourceClaim.
func IsForPod(pod *v1.Pod, claim *resourcev1alpha1.ResourceClaim) error {
// Checking the namespaces is just a precaution. The caller should
// never pass in a ResourceClaim that isn't from the same namespace as the
// Pod.
if claim.Namespace != pod.Namespace || !metav1.IsControlledBy(claim, pod) {
return fmt.Errorf("ResourceClaim %s/%s was not created for pod %s/%s (pod is not owner)", claim.Namespace, claim.Name, pod.Namespace, pod.Name)
}
return nil
}
// IsReservedForPod checks whether a claim lists the pod as one of the objects
// that the claim was reserved for.
func IsReservedForPod(pod *v1.Pod, claim *resourcev1alpha1.ResourceClaim) bool {
for _, reserved := range claim.Status.ReservedFor {
if reserved.UID == pod.UID {
return true
}
}
return false
}
// CanBeReserved checks whether the claim could be reserved for another object.
func CanBeReserved(claim *resourcev1alpha1.ResourceClaim) bool {
return claim.Status.Allocation.Shareable ||
len(claim.Status.ReservedFor) == 0
}

View File

@ -0,0 +1,127 @@
/*
Copyright 2021 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package resourceclaim
import (
"fmt"
"testing"
v1 "k8s.io/api/core/v1"
resourcev1alpha1 "k8s.io/api/resource/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)
func TestResourceClaimIsForPod(t *testing.T) {
uid := 0
newUID := func() types.UID {
uid++
return types.UID(fmt.Sprintf("%d", uid))
}
isController := true
podNotOwner := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Namespace: "kube-system",
Name: "podNotOwner",
UID: newUID(),
},
}
podOwner := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Namespace: "kube-system",
Name: "podOwner",
UID: newUID(),
},
}
claimNoOwner := &resourcev1alpha1.ResourceClaim{
ObjectMeta: metav1.ObjectMeta{
Namespace: "kube-system",
Name: "claimNoOwner",
UID: newUID(),
},
}
claimWithOwner := &resourcev1alpha1.ResourceClaim{
ObjectMeta: metav1.ObjectMeta{
Namespace: "kube-system",
Name: "claimNoOwner",
UID: newUID(),
OwnerReferences: []metav1.OwnerReference{
{
UID: podOwner.UID,
Controller: &isController,
},
},
},
}
userClaimWithOwner := &resourcev1alpha1.ResourceClaim{
ObjectMeta: metav1.ObjectMeta{
Namespace: "user-namespace",
Name: "userClaimWithOwner",
UID: newUID(),
OwnerReferences: []metav1.OwnerReference{
{
UID: podOwner.UID,
Controller: &isController,
},
},
},
}
testcases := map[string]struct {
pod *v1.Pod
claim *resourcev1alpha1.ResourceClaim
expectedError string
}{
"owned": {
pod: podOwner,
claim: claimWithOwner,
},
"other-pod": {
pod: podNotOwner,
claim: claimWithOwner,
expectedError: `ResourceClaim kube-system/claimNoOwner was not created for pod kube-system/podNotOwner (pod is not owner)`,
},
"no-owner": {
pod: podOwner,
claim: claimNoOwner,
expectedError: `ResourceClaim kube-system/claimNoOwner was not created for pod kube-system/podOwner (pod is not owner)`,
},
"different-namespace": {
pod: podOwner,
claim: userClaimWithOwner,
expectedError: `ResourceClaim user-namespace/userClaimWithOwner was not created for pod kube-system/podOwner (pod is not owner)`,
},
}
for name, tc := range testcases {
t.Run(name, func(t *testing.T) {
err := IsForPod(tc.pod, tc.claim)
if tc.expectedError == "" {
if err != nil {
t.Errorf("expected no error, got %v", err)
}
} else {
if err == nil {
t.Errorf("expected error %q, got nil", tc.expectedError)
} else if tc.expectedError != err.Error() {
t.Errorf("expected error %q, got %v", tc.expectedError, err)
}
}
})
}
}

7
vendor/modules.txt vendored
View File

@ -1305,6 +1305,7 @@ k8s.io/api/policy/v1beta1
k8s.io/api/rbac/v1
k8s.io/api/rbac/v1alpha1
k8s.io/api/rbac/v1beta1
k8s.io/api/resource/v1alpha1
k8s.io/api/scheduling/v1
k8s.io/api/scheduling/v1alpha1
k8s.io/api/scheduling/v1beta1
@ -1642,6 +1643,7 @@ k8s.io/client-go/applyconfigurations/policy/v1beta1
k8s.io/client-go/applyconfigurations/rbac/v1
k8s.io/client-go/applyconfigurations/rbac/v1alpha1
k8s.io/client-go/applyconfigurations/rbac/v1beta1
k8s.io/client-go/applyconfigurations/resource/v1alpha1
k8s.io/client-go/applyconfigurations/scheduling/v1
k8s.io/client-go/applyconfigurations/scheduling/v1alpha1
k8s.io/client-go/applyconfigurations/scheduling/v1beta1
@ -1713,6 +1715,8 @@ k8s.io/client-go/informers/rbac
k8s.io/client-go/informers/rbac/v1
k8s.io/client-go/informers/rbac/v1alpha1
k8s.io/client-go/informers/rbac/v1beta1
k8s.io/client-go/informers/resource
k8s.io/client-go/informers/resource/v1alpha1
k8s.io/client-go/informers/scheduling
k8s.io/client-go/informers/scheduling/v1
k8s.io/client-go/informers/scheduling/v1alpha1
@ -1810,6 +1814,8 @@ k8s.io/client-go/kubernetes/typed/rbac/v1alpha1
k8s.io/client-go/kubernetes/typed/rbac/v1alpha1/fake
k8s.io/client-go/kubernetes/typed/rbac/v1beta1
k8s.io/client-go/kubernetes/typed/rbac/v1beta1/fake
k8s.io/client-go/kubernetes/typed/resource/v1alpha1
k8s.io/client-go/kubernetes/typed/resource/v1alpha1/fake
k8s.io/client-go/kubernetes/typed/scheduling/v1
k8s.io/client-go/kubernetes/typed/scheduling/v1/fake
k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1
@ -1860,6 +1866,7 @@ k8s.io/client-go/listers/policy/v1beta1
k8s.io/client-go/listers/rbac/v1
k8s.io/client-go/listers/rbac/v1alpha1
k8s.io/client-go/listers/rbac/v1beta1
k8s.io/client-go/listers/resource/v1alpha1
k8s.io/client-go/listers/scheduling/v1
k8s.io/client-go/listers/scheduling/v1alpha1
k8s.io/client-go/listers/scheduling/v1beta1