mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-02-22 07:03:28 +00:00
DRA API: v1 registration + tests
This commit is contained in:
@@ -50,6 +50,7 @@ var apiVersionPriorities = merge(controlplaneapiserver.DefaultGenericAPIServiceP
|
||||
{Group: "node.k8s.io", Version: "v1"}: {Group: 16300, Version: 15},
|
||||
{Group: "node.k8s.io", Version: "v1alpha1"}: {Group: 16300, Version: 1},
|
||||
{Group: "node.k8s.io", Version: "v1beta1"}: {Group: 16300, Version: 9},
|
||||
{Group: "resource.k8s.io", Version: "v1"}: {Group: 16200, Version: 21},
|
||||
{Group: "resource.k8s.io", Version: "v1beta2"}: {Group: 16200, Version: 15},
|
||||
{Group: "resource.k8s.io", Version: "v1beta1"}: {Group: 16200, Version: 9},
|
||||
{Group: "resource.k8s.io", Version: "v1alpha3"}: {Group: 16200, Version: 1},
|
||||
|
||||
@@ -157,6 +157,12 @@ func TestDefaulting(t *testing.T) {
|
||||
{Group: "resource.k8s.io", Version: "v1beta2", Kind: "ResourceClaimTemplateList"}: {},
|
||||
{Group: "resource.k8s.io", Version: "v1beta2", Kind: "ResourceSlice"}: {},
|
||||
{Group: "resource.k8s.io", Version: "v1beta2", Kind: "ResourceSliceList"}: {},
|
||||
{Group: "resource.k8s.io", Version: "v1", Kind: "ResourceClaim"}: {},
|
||||
{Group: "resource.k8s.io", Version: "v1", Kind: "ResourceClaimList"}: {},
|
||||
{Group: "resource.k8s.io", Version: "v1", Kind: "ResourceClaimTemplate"}: {},
|
||||
{Group: "resource.k8s.io", Version: "v1", Kind: "ResourceClaimTemplateList"}: {},
|
||||
{Group: "resource.k8s.io", Version: "v1", Kind: "ResourceSlice"}: {},
|
||||
{Group: "resource.k8s.io", Version: "v1", Kind: "ResourceSliceList"}: {},
|
||||
{Group: "admissionregistration.k8s.io", Version: "v1alpha1", Kind: "ValidatingAdmissionPolicy"}: {},
|
||||
{Group: "admissionregistration.k8s.io", Version: "v1alpha1", Kind: "ValidatingAdmissionPolicyList"}: {},
|
||||
{Group: "admissionregistration.k8s.io", Version: "v1alpha1", Kind: "ValidatingAdmissionPolicyBinding"}: {},
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/apis/resource"
|
||||
v1 "k8s.io/kubernetes/pkg/apis/resource/v1"
|
||||
"k8s.io/kubernetes/pkg/apis/resource/v1alpha3"
|
||||
"k8s.io/kubernetes/pkg/apis/resource/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/apis/resource/v1beta2"
|
||||
@@ -38,7 +39,8 @@ func Install(scheme *runtime.Scheme) {
|
||||
utilruntime.Must(v1alpha3.AddToScheme(scheme))
|
||||
utilruntime.Must(v1beta1.AddToScheme(scheme))
|
||||
utilruntime.Must(v1beta2.AddToScheme(scheme))
|
||||
utilruntime.Must(v1.AddToScheme(scheme))
|
||||
// TODO(https://github.com/kubernetes/kubernetes/issues/129889) We should
|
||||
// change the serialization version to v1beta2 for 1.34.
|
||||
utilruntime.Must(scheme.SetVersionPriority(v1beta1.SchemeGroupVersion, v1beta2.SchemeGroupVersion, v1alpha3.SchemeGroupVersion))
|
||||
utilruntime.Must(scheme.SetVersionPriority(v1beta1.SchemeGroupVersion, v1beta2.SchemeGroupVersion, v1.SchemeGroupVersion, v1alpha3.SchemeGroupVersion))
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ import (
|
||||
nodev1 "k8s.io/api/node/v1"
|
||||
policyapiv1 "k8s.io/api/policy/v1"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
resourcev1 "k8s.io/api/resource/v1"
|
||||
resourcev1alpha3 "k8s.io/api/resource/v1alpha3"
|
||||
resourcev1beta1 "k8s.io/api/resource/v1beta1"
|
||||
resourcev1beta2 "k8s.io/api/resource/v1beta2"
|
||||
@@ -459,6 +460,7 @@ var (
|
||||
nodev1.SchemeGroupVersion,
|
||||
policyapiv1.SchemeGroupVersion,
|
||||
rbacv1.SchemeGroupVersion,
|
||||
resourcev1.SchemeGroupVersion,
|
||||
storageapiv1.SchemeGroupVersion,
|
||||
schedulingapiv1.SchemeGroupVersion,
|
||||
flowcontrolv1.SchemeGroupVersion,
|
||||
|
||||
@@ -30,7 +30,7 @@ import (
|
||||
"k8s.io/apiserver/pkg/storage"
|
||||
"k8s.io/apiserver/pkg/storage/names"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
v1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/dynamic-resource-allocation/structured"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/apis/resource"
|
||||
@@ -74,6 +74,9 @@ func (*resourceclaimStrategy) GetResetFields() map[fieldpath.APIVersion]*fieldpa
|
||||
"resource.k8s.io/v1beta2": fieldpath.NewSet(
|
||||
fieldpath.MakePathOrDie("status"),
|
||||
),
|
||||
"resource.k8s.io/v1": fieldpath.NewSet(
|
||||
fieldpath.MakePathOrDie("status"),
|
||||
),
|
||||
}
|
||||
|
||||
return fields
|
||||
@@ -151,6 +154,9 @@ func (*resourceclaimStatusStrategy) GetResetFields() map[fieldpath.APIVersion]*f
|
||||
"resource.k8s.io/v1beta2": fieldpath.NewSet(
|
||||
fieldpath.MakePathOrDie("spec"),
|
||||
),
|
||||
"resource.k8s.io/v1": fieldpath.NewSet(
|
||||
fieldpath.MakePathOrDie("spec"),
|
||||
),
|
||||
}
|
||||
|
||||
return fields
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package rest
|
||||
|
||||
import (
|
||||
resourcev1 "k8s.io/api/resource/v1"
|
||||
resourcev1alpha3 "k8s.io/api/resource/v1alpha3"
|
||||
resourcev1beta1 "k8s.io/api/resource/v1beta1"
|
||||
resourcev1beta2 "k8s.io/api/resource/v1beta2"
|
||||
@@ -47,6 +48,12 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag
|
||||
// If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities.
|
||||
// TODO refactor the plumbing to provide the information in the APIGroupInfo
|
||||
|
||||
if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter, p.NamespaceClient); err != nil {
|
||||
return genericapiserver.APIGroupInfo{}, err
|
||||
} else if len(storageMap) > 0 {
|
||||
apiGroupInfo.VersionedResourcesStorageMap[resourcev1.SchemeGroupVersion.Version] = storageMap
|
||||
}
|
||||
|
||||
if storageMap, err := p.v1alpha3Storage(apiResourceConfigSource, restOptionsGetter, p.NamespaceClient); err != nil {
|
||||
return genericapiserver.APIGroupInfo{}, err
|
||||
} else if len(storageMap) > 0 {
|
||||
@@ -68,6 +75,45 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag
|
||||
return apiGroupInfo, nil
|
||||
}
|
||||
|
||||
func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter, nsClient v1.NamespaceInterface) (map[string]rest.Storage, error) {
|
||||
storage := map[string]rest.Storage{}
|
||||
|
||||
if resource := "deviceclasses"; apiResourceConfigSource.ResourceEnabled(resourcev1.SchemeGroupVersion.WithResource(resource)) {
|
||||
deviceclassStorage, err := deviceclassstore.NewREST(restOptionsGetter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
storage[resource] = deviceclassStorage
|
||||
}
|
||||
|
||||
if resource := "resourceclaims"; apiResourceConfigSource.ResourceEnabled(resourcev1.SchemeGroupVersion.WithResource(resource)) {
|
||||
resourceClaimStorage, resourceClaimStatusStorage, err := resourceclaimstore.NewREST(restOptionsGetter, nsClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
storage[resource] = resourceClaimStorage
|
||||
storage[resource+"/status"] = resourceClaimStatusStorage
|
||||
}
|
||||
|
||||
if resource := "resourceclaimtemplates"; apiResourceConfigSource.ResourceEnabled(resourcev1.SchemeGroupVersion.WithResource(resource)) {
|
||||
resourceClaimTemplateStorage, err := resourceclaimtemplatestore.NewREST(restOptionsGetter, nsClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
storage[resource] = resourceClaimTemplateStorage
|
||||
}
|
||||
|
||||
if resource := "resourceslices"; apiResourceConfigSource.ResourceEnabled(resourcev1.SchemeGroupVersion.WithResource(resource)) {
|
||||
resourceSliceStorage, err := resourceslicestore.NewREST(restOptionsGetter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
storage[resource] = resourceSliceStorage
|
||||
}
|
||||
|
||||
return storage, nil
|
||||
}
|
||||
|
||||
func (p RESTStorageProvider) v1alpha3Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter, nsClient v1.NamespaceInterface) (map[string]rest.Storage, error) {
|
||||
storage := map[string]rest.Storage{}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ const (
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +k8s:prerelease-lifecycle-gen:introduced=1.33
|
||||
// +k8s:prerelease-lifecycle-gen:introduced=1.34
|
||||
|
||||
// ResourceSlice represents one or more resources in a pool of similar resources,
|
||||
// managed by a common driver. A pool may span more than one ResourceSlice, and exactly how many
|
||||
@@ -500,7 +500,7 @@ const (
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +k8s:prerelease-lifecycle-gen:introduced=1.33
|
||||
// +k8s:prerelease-lifecycle-gen:introduced=1.34
|
||||
|
||||
// ResourceSliceList is a collection of ResourceSlices.
|
||||
type ResourceSliceList struct {
|
||||
@@ -515,7 +515,7 @@ type ResourceSliceList struct {
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +k8s:prerelease-lifecycle-gen:introduced=1.33
|
||||
// +k8s:prerelease-lifecycle-gen:introduced=1.34
|
||||
|
||||
// ResourceClaim describes a request for access to resources in the cluster,
|
||||
// for use by workloads. For example, if a workload needs an accelerator device
|
||||
@@ -1314,7 +1314,7 @@ const (
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +k8s:prerelease-lifecycle-gen:introduced=1.33
|
||||
// +k8s:prerelease-lifecycle-gen:introduced=1.34
|
||||
|
||||
// ResourceClaimList is a collection of claims.
|
||||
type ResourceClaimList struct {
|
||||
@@ -1330,7 +1330,7 @@ type ResourceClaimList struct {
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +k8s:prerelease-lifecycle-gen:introduced=1.33
|
||||
// +k8s:prerelease-lifecycle-gen:introduced=1.34
|
||||
|
||||
// DeviceClass is a vendor- or admin-provided resource that contains
|
||||
// device configuration and selectors. It can be referenced in
|
||||
@@ -1387,7 +1387,7 @@ type DeviceClassConfiguration struct {
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +k8s:prerelease-lifecycle-gen:introduced=1.33
|
||||
// +k8s:prerelease-lifecycle-gen:introduced=1.34
|
||||
|
||||
// DeviceClassList is a collection of classes.
|
||||
type DeviceClassList struct {
|
||||
@@ -1402,7 +1402,7 @@ type DeviceClassList struct {
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +k8s:prerelease-lifecycle-gen:introduced=1.33
|
||||
// +k8s:prerelease-lifecycle-gen:introduced=1.34
|
||||
|
||||
// ResourceClaimTemplate is used to produce ResourceClaim objects.
|
||||
//
|
||||
@@ -1437,7 +1437,7 @@ type ResourceClaimTemplateSpec struct {
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +k8s:prerelease-lifecycle-gen:introduced=1.33
|
||||
// +k8s:prerelease-lifecycle-gen:introduced=1.34
|
||||
|
||||
// ResourceClaimTemplateList is a collection of claim templates.
|
||||
type ResourceClaimTemplateList struct {
|
||||
|
||||
@@ -68,6 +68,7 @@ import (
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
rbacv1alpha1 "k8s.io/api/rbac/v1alpha1"
|
||||
rbacv1beta1 "k8s.io/api/rbac/v1beta1"
|
||||
resourcev1 "k8s.io/api/resource/v1"
|
||||
resourcev1alpha3 "k8s.io/api/resource/v1alpha3"
|
||||
resourcev1beta1 "k8s.io/api/resource/v1beta1"
|
||||
resourcev1beta2 "k8s.io/api/resource/v1beta2"
|
||||
@@ -138,6 +139,7 @@ var groups = []runtime.SchemeBuilder{
|
||||
resourcev1alpha3.SchemeBuilder,
|
||||
resourcev1beta1.SchemeBuilder,
|
||||
resourcev1beta2.SchemeBuilder,
|
||||
resourcev1.SchemeBuilder,
|
||||
schedulingv1alpha1.SchemeBuilder,
|
||||
schedulingv1beta1.SchemeBuilder,
|
||||
schedulingv1.SchemeBuilder,
|
||||
|
||||
@@ -61,6 +61,7 @@ var resetFieldsStatusData = map[schema.GroupVersionResource]string{
|
||||
gvr("policy", "v1beta1", "poddisruptionbudgets"): `{"status": {"currentHealthy": 25}}`,
|
||||
gvr("resource.k8s.io", "v1beta1", "resourceclaims"): `{"status": {"allocation": {"nodeSelector": {"nodeSelectorTerms": [{"matchExpressions": [{"key": "some-label", "operator": "In", "values": ["some-other-value"]}] }]}}}}`,
|
||||
gvr("resource.k8s.io", "v1beta2", "resourceclaims"): `{"status": {"allocation": {"nodeSelector": {"nodeSelectorTerms": [{"matchExpressions": [{"key": "some-label", "operator": "In", "values": ["some-other-value"]}] }]}}}}`,
|
||||
gvr("resource.k8s.io", "v1", "resourceclaims"): `{"status": {"allocation": {"nodeSelector": {"nodeSelectorTerms": [{"matchExpressions": [{"key": "some-label", "operator": "In", "values": ["some-other-value"]}] }]}}}}`,
|
||||
gvr("internal.apiserver.k8s.io", "v1alpha1", "storageversions"): `{"status": {"commonEncodingVersion":"v1","storageVersions":[{"apiServerID":"1","decodableVersions":["v1","v2"],"encodingVersion":"v1"}],"conditions":[{"type":"AllEncodingVersionsEqual","status":"False","lastTransitionTime":"2020-01-01T00:00:00Z","reason":"allEncodingVersionsEqual","message":"all encoding versions are set to v1"}]}}`,
|
||||
// standard for []metav1.Condition
|
||||
gvr("admissionregistration.k8s.io", "v1alpha1", "validatingadmissionpolicies"): `{"status": {"conditions":[{"type":"Accepted","status":"True","lastTransitionTime":"2020-01-01T00:00:00Z","reason":"RuleApplied","message":"Rule was applied"}]}}`,
|
||||
@@ -157,6 +158,9 @@ var resetFieldsSpecData = map[schema.GroupVersionResource]string{
|
||||
gvr("resource.k8s.io", "v1beta2", "deviceclasses"): `{"metadata": {"labels":{"a":"c"}}}`,
|
||||
gvr("resource.k8s.io", "v1beta2", "resourceclaims"): `{"spec": {"devices": {"requests": [{"name": "req-0", "exactly": {"deviceClassName": "other-class"}}]}}}`, // spec is immutable, but that doesn't matter for the test.
|
||||
gvr("resource.k8s.io", "v1beta2", "resourceclaimtemplates"): `{"spec": {"spec": {"resourceClassName": "class2name"}}}`,
|
||||
gvr("resource.k8s.io", "v1", "deviceclasses"): `{"metadata": {"labels":{"a":"c"}}}`,
|
||||
gvr("resource.k8s.io", "v1", "resourceclaims"): `{"spec": {"devices": {"requests": [{"name": "req-0", "exactly": {"deviceClassName": "other-class"}}]}}}`, // spec is immutable, but that doesn't matter for the test.
|
||||
gvr("resource.k8s.io", "v1", "resourceclaimtemplates"): `{"spec": {"spec": {"resourceClassName": "class2name"}}}`,
|
||||
gvr("internal.apiserver.k8s.io", "v1alpha1", "storageversions"): `{}`,
|
||||
gvr("admissionregistration.k8s.io", "v1alpha1", "validatingadmissionpolicies"): `{"metadata": {"labels": {"a":"c"}}, "spec": {"paramKind": {"apiVersion": "apps/v1", "kind": "Deployment"}}}`,
|
||||
gvr("admissionregistration.k8s.io", "v1beta1", "validatingadmissionpolicies"): `{"metadata": {"labels": {"a":"c"}}, "spec": {"paramKind": {"apiVersion": "apps/v1", "kind": "Deployment"}}}`,
|
||||
|
||||
@@ -60,6 +60,7 @@ var statusData = map[schema.GroupVersionResource]string{
|
||||
gvr("policy", "v1beta1", "poddisruptionbudgets"): `{"status": {"currentHealthy": 5}}`,
|
||||
gvr("resource.k8s.io", "v1beta1", "resourceclaims"): `{"status": {"allocation": {"nodeSelector": {"nodeSelectorTerms": [{"matchExpressions": [{"key": "some-label", "operator": "In", "values": ["some-value"]}] }]}}}}`,
|
||||
gvr("resource.k8s.io", "v1beta2", "resourceclaims"): `{"status": {"allocation": {"nodeSelector": {"nodeSelectorTerms": [{"matchExpressions": [{"key": "some-label", "operator": "In", "values": ["some-value"]}] }]}}}}`,
|
||||
gvr("resource.k8s.io", "v1", "resourceclaims"): `{"status": {"allocation": {"nodeSelector": {"nodeSelectorTerms": [{"matchExpressions": [{"key": "some-label", "operator": "In", "values": ["some-value"]}] }]}}}}`,
|
||||
gvr("internal.apiserver.k8s.io", "v1alpha1", "storageversions"): `{"status": {"commonEncodingVersion":"v1","storageVersions":[{"apiServerID":"1","decodableVersions":["v1","v2"],"encodingVersion":"v1"}],"conditions":[{"type":"AllEncodingVersionsEqual","status":"True","lastTransitionTime":"2020-01-01T00:00:00Z","reason":"allEncodingVersionsEqual","message":"all encoding versions are set to v1"}]}}`,
|
||||
// standard for []metav1.Condition
|
||||
gvr("admissionregistration.k8s.io", "v1alpha1", "validatingadmissionpolicies"): `{"status": {"conditions":[{"type":"Accepted","status":"False","lastTransitionTime":"2020-01-01T00:00:00Z","reason":"RuleApplied","message":"Rule was applied"}]}}`,
|
||||
|
||||
@@ -651,6 +651,33 @@ func GetEtcdStorageDataForNamespaceServedAt(namespace string, v string, isEmulat
|
||||
},
|
||||
// --
|
||||
|
||||
// k8s.io/kubernetes/pkg/apis/resource/v1
|
||||
gvr("resource.k8s.io", "v1", "deviceclasses"): {
|
||||
Stub: `{"metadata": {"name": "class4name"}}`,
|
||||
ExpectedEtcdPath: "/registry/deviceclasses/class4name",
|
||||
ExpectedGVK: gvkP("resource.k8s.io", "v1beta1", "DeviceClass"),
|
||||
IntroducedVersion: "1.34",
|
||||
},
|
||||
gvr("resource.k8s.io", "v1", "resourceclaims"): {
|
||||
Stub: `{"metadata": {"name": "claim4name"}, "spec": {"devices": {"requests": [{"name": "req-0", "exactly": {"deviceClassName": "example-class", "allocationMode": "ExactCount", "count": 1}}]}}}`,
|
||||
ExpectedEtcdPath: "/registry/resourceclaims/" + namespace + "/claim4name",
|
||||
ExpectedGVK: gvkP("resource.k8s.io", "v1beta1", "ResourceClaim"),
|
||||
IntroducedVersion: "1.34",
|
||||
},
|
||||
gvr("resource.k8s.io", "v1", "resourceclaimtemplates"): {
|
||||
Stub: `{"metadata": {"name": "claimtemplate4name"}, "spec": {"spec": {"devices": {"requests": [{"name": "req-0", "exactly": {"deviceClassName": "example-class", "allocationMode": "ExactCount", "count": 1}}]}}}}`,
|
||||
ExpectedEtcdPath: "/registry/resourceclaimtemplates/" + namespace + "/claimtemplate4name",
|
||||
ExpectedGVK: gvkP("resource.k8s.io", "v1beta1", "ResourceClaimTemplate"),
|
||||
IntroducedVersion: "1.34",
|
||||
},
|
||||
gvr("resource.k8s.io", "v1", "resourceslices"): {
|
||||
Stub: `{"metadata": {"name": "node4slice"}, "spec": {"nodeName": "worker1", "driver": "dra.example.com", "pool": {"name": "worker1", "resourceSliceCount": 1}}}`,
|
||||
ExpectedEtcdPath: "/registry/resourceslices/node4slice",
|
||||
ExpectedGVK: gvkP("resource.k8s.io", "v1beta1", "ResourceSlice"),
|
||||
IntroducedVersion: "1.34",
|
||||
},
|
||||
// --
|
||||
|
||||
// k8s.io/apiserver/pkg/apis/apiserverinternal/v1alpha1
|
||||
gvr("internal.apiserver.k8s.io", "v1alpha1", "storageversions"): {
|
||||
Stub: `{"metadata":{"name":"sv1.test"},"spec":{}}`,
|
||||
|
||||
Reference in New Issue
Block a user