From eb1470d60d54612fdb3955916fe0c707e9895fd9 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Tue, 20 Feb 2024 14:01:24 +0100 Subject: [PATCH 01/18] scheduler: fix assume cache with no index The assume cache in the volumbinding plugin can be created with no separate index, but List then failed because it tried to use the empty index name instead of using the store's List function. --- .../plugins/volumebinding/assume_cache.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/pkg/scheduler/framework/plugins/volumebinding/assume_cache.go b/pkg/scheduler/framework/plugins/volumebinding/assume_cache.go index 77b78d172b1..945c7a3efff 100644 --- a/pkg/scheduler/framework/plugins/volumebinding/assume_cache.go +++ b/pkg/scheduler/framework/plugins/volumebinding/assume_cache.go @@ -283,10 +283,16 @@ func (c *assumeCache) List(indexObj interface{}) []interface{} { defer c.rwMutex.RUnlock() allObjs := []interface{}{} - objs, err := c.store.Index(c.indexName, &objInfo{latestObj: indexObj}) - if err != nil { - c.logger.Error(err, "List index error") - return nil + var objs []interface{} + if c.indexName != "" { + o, err := c.store.Index(c.indexName, &objInfo{latestObj: indexObj}) + if err != nil { + c.logger.Error(err, "List index error") + return nil + } + objs = o + } else { + objs = c.store.List() } for _, obj := range objs { From 39bbcedbcae84bf716923b3f9464968ca70b42e7 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Wed, 14 Feb 2024 14:38:42 +0100 Subject: [PATCH 02/18] dra api: add structured parameters NodeResourceSlice will be used by kubelet to publish resource information on behalf of DRA drivers on the node. NodeName and DriverName in NodeResourceSlice must be immutable. This simplifies tracking the different objects because what they are for cannot change after creation. The new field in ResourceClass tells scheduler and autoscaler that they are expected to handle allocation. ResourceClaimParameters and ResourceClassParameters are new types for telling in-tree components how to handle claims. --- api/discovery/aggregated_v2beta1.json | 60 + .../apis__resource.k8s.io__v1alpha2.json | 51 + api/openapi-spec/swagger.json | 2557 ++++++++++ ...is__resource.k8s.io__v1alpha2_openapi.json | 4494 +++++++++++++++++ hack/update-codegen.sh | 2 +- pkg/apis/resource/register.go | 6 + pkg/apis/resource/types.go | 206 + pkg/apis/resource/v1alpha2/conversion.go | 14 + .../v1alpha2/zz_generated.conversion.go | 762 ++- pkg/apis/resource/validation/validation.go | 209 +- .../validation_noderesourceslice_test.go | 256 + .../validation_resourceclaim_test.go | 77 +- ...validation_resourceclaimparameters_test.go | 308 ++ ...validation_resourceclassparameters_test.go | 312 ++ pkg/apis/resource/zz_generated.deepcopy.go | 416 +- pkg/generated/openapi/zz_generated.openapi.go | 621 +++ pkg/printers/internalversion/printers.go | 96 + .../noderesourceslice/storage/storage.go | 62 + .../noderesourceslice/storage/storage_test.go | 146 + .../resource/noderesourceslice/strategy.go | 139 + .../noderesourceslice/strategy_test.go | 82 + .../storage/storage.go | 57 + .../storage/storage_test.go | 145 + .../resourceclaimparameters/strategy.go | 103 + .../resourceclaimparameters/strategy_test.go | 81 + .../storage/storage.go | 57 + .../storage/storage_test.go | 145 + .../resourceclassparameters/strategy.go | 103 + .../resourceclassparameters/strategy_test.go | 81 + .../resource/rest/storage_resource.go | 27 + .../api/resource/v1alpha2/generated.pb.go | 3829 +++++++++++++- .../api/resource/v1alpha2/generated.proto | 215 + .../k8s.io/api/resource/v1alpha2/register.go | 6 + .../src/k8s.io/api/resource/v1alpha2/types.go | 254 + .../v1alpha2/types_swagger_doc_generated.go | 175 +- .../v1alpha2/zz_generated.deepcopy.go | 404 +- ...rce.k8s.io.v1alpha2.NodeResourceSlice.json | 48 + ...ource.k8s.io.v1alpha2.NodeResourceSlice.pb | Bin 0 -> 447 bytes ...rce.k8s.io.v1alpha2.NodeResourceSlice.yaml | 36 + ...esource.k8s.io.v1alpha2.ResourceClaim.json | 39 +- .../resource.k8s.io.v1alpha2.ResourceClaim.pb | Bin 688 -> 1018 bytes ...esource.k8s.io.v1alpha2.ResourceClaim.yaml | 24 + ...s.io.v1alpha2.ResourceClaimParameters.json | 81 + ...k8s.io.v1alpha2.ResourceClaimParameters.pb | Bin 0 -> 688 bytes ...s.io.v1alpha2.ResourceClaimParameters.yaml | 56 + ...esource.k8s.io.v1alpha2.ResourceClass.json | 3 +- .../resource.k8s.io.v1alpha2.ResourceClass.pb | Bin 565 -> 567 bytes ...esource.k8s.io.v1alpha2.ResourceClass.yaml | 1 + ...s.io.v1alpha2.ResourceClassParameters.json | 72 + ...k8s.io.v1alpha2.ResourceClassParameters.pb | Bin 0 -> 616 bytes ...s.io.v1alpha2.ResourceClassParameters.yaml | 50 + ....v1alpha2.ResourceClass.after_roundtrip.pb | Bin 0 -> 565 bytes ....v1alpha2.ResourceClass.after_roundtrip.pb | Bin 0 -> 565 bytes .../applyconfigurations/internal/internal.go | 141 + .../v1alpha2/driverallocationresult.go | 45 + .../resource/v1alpha2/driverrequests.go | 66 + .../resource/v1alpha2/noderesourceslice.go | 257 + .../v1alpha2/resourceclaimparameters.go | 272 + .../resource/v1alpha2/resourceclass.go | 9 + .../v1alpha2/resourceclassparameters.go | 277 + .../resource/v1alpha2/resourcefilter.go | 44 + .../resource/v1alpha2/resourcehandle.go | 13 +- .../resource/v1alpha2/resourcerequest.go | 45 + .../v1alpha2/structuredresourcehandle.go | 75 + .../resource/v1alpha2/vendorparameters.go | 52 + .../client-go/applyconfigurations/utils.go | 18 + .../src/k8s.io/client-go/informers/generic.go | 6 + .../informers/resource/v1alpha2/interface.go | 21 + .../resource/v1alpha2/noderesourceslice.go | 89 + .../v1alpha2/resourceclaimparameters.go | 90 + .../v1alpha2/resourceclassparameters.go | 90 + .../v1alpha2/fake/fake_noderesourceslice.go | 145 + .../v1alpha2/fake/fake_resource_client.go | 12 + .../fake/fake_resourceclaimparameters.go | 154 + .../fake/fake_resourceclassparameters.go | 154 + .../resource/v1alpha2/generated_expansion.go | 6 + .../resource/v1alpha2/noderesourceslice.go | 197 + .../resource/v1alpha2/resource_client.go | 15 + .../v1alpha2/resourceclaimparameters.go | 208 + .../v1alpha2/resourceclassparameters.go | 208 + .../resource/v1alpha2/expansion_generated.go | 20 + .../resource/v1alpha2/noderesourceslice.go | 68 + .../v1alpha2/resourceclaimparameters.go | 99 + .../v1alpha2/resourceclassparameters.go | 99 + test/integration/etcd/data.go | 12 + 85 files changed, 19855 insertions(+), 120 deletions(-) create mode 100644 pkg/apis/resource/validation/validation_noderesourceslice_test.go create mode 100644 pkg/apis/resource/validation/validation_resourceclaimparameters_test.go create mode 100644 pkg/apis/resource/validation/validation_resourceclassparameters_test.go create mode 100644 pkg/registry/resource/noderesourceslice/storage/storage.go create mode 100644 pkg/registry/resource/noderesourceslice/storage/storage_test.go create mode 100644 pkg/registry/resource/noderesourceslice/strategy.go create mode 100644 pkg/registry/resource/noderesourceslice/strategy_test.go create mode 100644 pkg/registry/resource/resourceclaimparameters/storage/storage.go create mode 100644 pkg/registry/resource/resourceclaimparameters/storage/storage_test.go create mode 100644 pkg/registry/resource/resourceclaimparameters/strategy.go create mode 100644 pkg/registry/resource/resourceclaimparameters/strategy_test.go create mode 100644 pkg/registry/resource/resourceclassparameters/storage/storage.go create mode 100644 pkg/registry/resource/resourceclassparameters/storage/storage_test.go create mode 100644 pkg/registry/resource/resourceclassparameters/strategy.go create mode 100644 pkg/registry/resource/resourceclassparameters/strategy_test.go create mode 100644 staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.json create mode 100644 staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.pb create mode 100644 staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.yaml create mode 100644 staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaimParameters.json create mode 100644 staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaimParameters.pb create mode 100644 staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaimParameters.yaml create mode 100644 staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClassParameters.json create mode 100644 staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClassParameters.pb create mode 100644 staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClassParameters.yaml create mode 100644 staging/src/k8s.io/api/testdata/v1.28.0/resource.k8s.io.v1alpha2.ResourceClass.after_roundtrip.pb create mode 100644 staging/src/k8s.io/api/testdata/v1.29.0/resource.k8s.io.v1alpha2.ResourceClass.after_roundtrip.pb create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/driverallocationresult.go create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/driverrequests.go create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/noderesourceslice.go create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimparameters.go create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclassparameters.go create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcefilter.go create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcerequest.go create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/structuredresourcehandle.go create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/vendorparameters.go create mode 100644 staging/src/k8s.io/client-go/informers/resource/v1alpha2/noderesourceslice.go create mode 100644 staging/src/k8s.io/client-go/informers/resource/v1alpha2/resourceclaimparameters.go create mode 100644 staging/src/k8s.io/client-go/informers/resource/v1alpha2/resourceclassparameters.go create mode 100644 staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_noderesourceslice.go create mode 100644 staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resourceclaimparameters.go create mode 100644 staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resourceclassparameters.go create mode 100644 staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/noderesourceslice.go create mode 100644 staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaimparameters.go create mode 100644 staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclassparameters.go create mode 100644 staging/src/k8s.io/client-go/listers/resource/v1alpha2/noderesourceslice.go create mode 100644 staging/src/k8s.io/client-go/listers/resource/v1alpha2/resourceclaimparameters.go create mode 100644 staging/src/k8s.io/client-go/listers/resource/v1alpha2/resourceclassparameters.go diff --git a/api/discovery/aggregated_v2beta1.json b/api/discovery/aggregated_v2beta1.json index 84a3efc6ca2..dcada7821e6 100644 --- a/api/discovery/aggregated_v2beta1.json +++ b/api/discovery/aggregated_v2beta1.json @@ -1891,6 +1891,26 @@ { "freshness": "Current", "resources": [ + { + "resource": "noderesourceslices", + "responseKind": { + "group": "", + "kind": "NodeResourceSlice", + "version": "" + }, + "scope": "Cluster", + "singularResource": "noderesourceslice", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] + }, { "resource": "podschedulingcontexts", "responseKind": { @@ -1926,6 +1946,26 @@ "watch" ] }, + { + "resource": "resourceclaimparameters", + "responseKind": { + "group": "", + "kind": "ResourceClaimParameters", + "version": "" + }, + "scope": "Namespaced", + "singularResource": "resourceclaimparameters", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] + }, { "resource": "resourceclaims", "responseKind": { @@ -2000,6 +2040,26 @@ "update", "watch" ] + }, + { + "resource": "resourceclassparameters", + "responseKind": { + "group": "", + "kind": "ResourceClassParameters", + "version": "" + }, + "scope": "Namespaced", + "singularResource": "resourceclassparameters", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] } ], "version": "v1alpha2" diff --git a/api/discovery/apis__resource.k8s.io__v1alpha2.json b/api/discovery/apis__resource.k8s.io__v1alpha2.json index c5981a2a1c9..4538e4d685a 100644 --- a/api/discovery/apis__resource.k8s.io__v1alpha2.json +++ b/api/discovery/apis__resource.k8s.io__v1alpha2.json @@ -3,6 +3,23 @@ "groupVersion": "resource.k8s.io/v1alpha2", "kind": "APIResourceList", "resources": [ + { + "kind": "NodeResourceSlice", + "name": "noderesourceslices", + "namespaced": false, + "singularName": "noderesourceslice", + "storageVersionHash": "KmjmPdo2jrQ=", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] + }, { "kind": "PodSchedulingContext", "name": "podschedulingcontexts", @@ -31,6 +48,23 @@ "update" ] }, + { + "kind": "ResourceClaimParameters", + "name": "resourceclaimparameters", + "namespaced": true, + "singularName": "resourceclaimparameters", + "storageVersionHash": "DWM408h+ZHE=", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] + }, { "kind": "ResourceClaim", "name": "resourceclaims", @@ -92,6 +126,23 @@ "update", "watch" ] + }, + { + "kind": "ResourceClassParameters", + "name": "resourceclassparameters", + "namespaced": true, + "singularName": "resourceclassparameters", + "storageVersionHash": "MDq5XoTnXWQ=", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] } ] } diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 6cb537d6157..acf7b480b1f 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -14820,6 +14820,110 @@ }, "type": "object" }, + "io.k8s.api.resource.v1alpha2.DriverAllocationResult": { + "description": "DriverAllocationResult contains vendor parameters and the allocation result for one request.", + "properties": { + "vendorRequestParameters": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.runtime.RawExtension", + "description": "VendorRequestParameters are the per-request configuration parameters from the time that the claim was allocated." + } + }, + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.DriverRequests": { + "description": "DriverRequests describes all resources that are needed from one particular driver.", + "properties": { + "driverName": { + "description": "DriverName is the name used by the DRA driver kubelet plugin.", + "type": "string" + }, + "requests": { + "description": "Requests describes all resources that are needed from the driver.", + "items": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceRequest" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "vendorParameters": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.runtime.RawExtension", + "description": "VendorParameters are arbitrary setup parameters for all requests of the claim. They are ignored while allocating the claim." + } + }, + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.NodeResourceSlice": { + "description": "NodeResourceSlice provides information about available resources on individual nodes.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "driverName": { + "description": "DriverName identifies the DRA driver providing the capacity information. A field selector can be used to list only NodeResourceSlice objects with a certain driver name.", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta", + "description": "Standard object metadata" + }, + "nodeName": { + "description": "NodeName identifies the node where the capacity is available. A field selector can be used to list only NodeResourceSlice objects with a certain node name.", + "type": "string" + } + }, + "required": [ + "nodeName", + "driverName" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "resource.k8s.io", + "kind": "NodeResourceSlice", + "version": "v1alpha2" + } + ] + }, + "io.k8s.api.resource.v1alpha2.NodeResourceSliceList": { + "description": "NodeResourceSliceList is a collection of NodeResourceSlices.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "Items is the list of node resource capacity objects.", + "items": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta", + "description": "Standard list metadata" + } + }, + "required": [ + "items" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "resource.k8s.io", + "kind": "NodeResourceSliceList", + "version": "v1alpha2" + } + ] + }, "io.k8s.api.resource.v1alpha2.PodSchedulingContext": { "description": "PodSchedulingContext objects hold information that is needed to schedule a Pod with ResourceClaims that use \"WaitForFirstConsumer\" allocation mode.\n\nThis is an alpha type and requires enabling the DynamicResourceAllocation feature gate.", "properties": { @@ -15024,6 +15128,82 @@ } ] }, + "io.k8s.api.resource.v1alpha2.ResourceClaimParameters": { + "description": "ResourceClaimParameters defines resource requests for a ResourceClaim in an in-tree format understood by Kubernetes.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "driverRequests": { + "description": "DriverRequests describes all resources that are needed for the allocated claim. A single claim may use resources coming from different drivers. For each driver, this array has at most one entry which then may have one or more per-driver requests.\n\nMay be empty, in which case the claim can always be allocated.", + "items": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.DriverRequests" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "generatedFrom": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClaimParametersReference", + "description": "If this object was created from some other resource, then this links back to that resource. This field is used to find the in-tree representation of the claim parameters when the parameter reference of the claim refers to some unknown type." + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta", + "description": "Standard object metadata" + }, + "shareable": { + "description": "Shareable indicates whether the allocated claim is meant to be shareable by multiple consumers at the same time.", + "type": "boolean" + } + }, + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + ] + }, + "io.k8s.api.resource.v1alpha2.ResourceClaimParametersList": { + "description": "ResourceClaimParametersList is a collection of ResourceClaimParameters.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "Items is the list of node resource capacity objects.", + "items": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta", + "description": "Standard list metadata" + } + }, + "required": [ + "items" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "resource.k8s.io", + "kind": "ResourceClaimParametersList", + "version": "v1alpha2" + } + ] + }, "io.k8s.api.resource.v1alpha2.ResourceClaimParametersReference": { "description": "ResourceClaimParametersReference contains enough information to let you locate the parameters for a ResourceClaim. The object must be in the same namespace as the ResourceClaim.", "properties": { @@ -15223,6 +15403,10 @@ "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClassParametersReference", "description": "ParametersRef references an arbitrary separate object that may hold parameters that will be used by the driver when allocating a resource that uses this class. A dynamic resource driver can distinguish between parameters stored here and and those stored in ResourceClaimSpec." }, + "structuredParameters": { + "description": "If and only if allocation of claims using this class is handled via structured parameters, then StructuredParameters must be set to true.", + "type": "boolean" + }, "suitableNodes": { "$ref": "#/definitions/io.k8s.api.core.v1.NodeSelector", "description": "Only nodes matching the selector will be considered by the scheduler when trying to find a Node that fits a Pod when that Pod uses a ResourceClaim that has not been allocated yet.\n\nSetting this field is optional. If null, all nodes are candidates." @@ -15275,6 +15459,86 @@ } ] }, + "io.k8s.api.resource.v1alpha2.ResourceClassParameters": { + "description": "ResourceClassParameters defines resource requests for a ResourceClass in an in-tree format understood by Kubernetes.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "filters": { + "description": "Filters describes additional contraints that must be met when using the class.", + "items": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceFilter" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "generatedFrom": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClassParametersReference", + "description": "If this object was created from some other resource, then this links back to that resource. This field is used to find the in-tree representation of the class parameters when the parameter reference of the class refers to some unknown type." + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta", + "description": "Standard object metadata" + }, + "vendorParameters": { + "description": "VendorParameters are arbitrary setup parameters for all claims using this class. They are ignored while allocating the claim. There must not be more than one entry per driver.", + "items": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.VendorParameters" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + } + }, + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + ] + }, + "io.k8s.api.resource.v1alpha2.ResourceClassParametersList": { + "description": "ResourceClassParametersList is a collection of ResourceClassParameters.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "Items is the list of node resource capacity objects.", + "items": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta", + "description": "Standard list metadata" + } + }, + "required": [ + "items" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "resource.k8s.io", + "kind": "ResourceClassParametersList", + "version": "v1alpha2" + } + ] + }, "io.k8s.api.resource.v1alpha2.ResourceClassParametersReference": { "description": "ResourceClassParametersReference contains enough information to let you locate the parameters for a ResourceClass.", "properties": { @@ -15301,6 +15565,16 @@ ], "type": "object" }, + "io.k8s.api.resource.v1alpha2.ResourceFilter": { + "description": "ResourceFilter is a filter for resources from one particular driver.", + "properties": { + "driverName": { + "description": "DriverName is the name used by the DRA driver kubelet plugin.", + "type": "string" + } + }, + "type": "object" + }, "io.k8s.api.resource.v1alpha2.ResourceHandle": { "description": "ResourceHandle holds opaque resource data for processing by a specific kubelet plugin.", "properties": { @@ -15311,6 +15585,64 @@ "driverName": { "description": "DriverName specifies the name of the resource driver whose kubelet plugin should be invoked to process this ResourceHandle's data once it lands on a node. This may differ from the DriverName set in ResourceClaimStatus this ResourceHandle is embedded in.", "type": "string" + }, + "structuredData": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.StructuredResourceHandle", + "description": "If StructuredData is set, then it needs to be used instead of Data." + } + }, + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.ResourceRequest": { + "description": "ResourceRequest is a request for resources from one particular driver.", + "properties": { + "vendorParameters": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.runtime.RawExtension", + "description": "VendorParameters are arbitrary setup parameters for the requested resource. They are ignored while allocating a claim." + } + }, + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.StructuredResourceHandle": { + "description": "StructuredResourceHandle is the in-tree representation of the allocation result.", + "properties": { + "nodeName": { + "description": "NodeName is the name of the node providing the necessary resources.", + "type": "string" + }, + "results": { + "description": "Results lists all allocated driver resources.", + "items": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.DriverAllocationResult" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "vendorClaimParameters": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.runtime.RawExtension", + "description": "VendorClaimParameters are the per-claim configuration parameters from the resource claim parameters at the time that the claim was allocated." + }, + "vendorClassParameters": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.runtime.RawExtension", + "description": "VendorClassParameters are the per-claim configuration parameters from the resource class at the time that the claim was allocated." + } + }, + "required": [ + "nodeName", + "results" + ], + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.VendorParameters": { + "description": "VendorParameters are opaque parameters for one particular driver.", + "properties": { + "driverName": { + "description": "DriverName is the name used by the DRA driver kubelet plugin.", + "type": "string" + }, + "parameters": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.runtime.RawExtension", + "description": "Parameters can be arbitrary setup parameters. They are ignored while allocating a claim." } }, "type": "object" @@ -70306,6 +70638,491 @@ } } }, + "/apis/resource.k8s.io/v1alpha2/namespaces/{namespace}/resourceclaimparameters": { + "delete": { + "consumes": [ + "*/*" + ], + "description": "delete collection of ResourceClaimParameters", + "operationId": "deleteResourceV1alpha2CollectionNamespacedResourceClaimParameters", + "parameters": [ + { + "$ref": "#/parameters/body-2Y1dVQaQ" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "$ref": "#/parameters/orphanDependents-uRB25kX5" + }, + { + "$ref": "#/parameters/propagationPolicy-6jk3prlO" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "deletecollection", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + }, + "get": { + "consumes": [ + "*/*" + ], + "description": "list or watch objects of kind ResourceClaimParameters", + "operationId": "listResourceV1alpha2NamespacedResourceClaimParameters", + "parameters": [ + { + "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + }, + { + "$ref": "#/parameters/watch-XNNPZGbK" + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf", + "application/json;stream=watch", + "application/vnd.kubernetes.protobuf;stream=watch" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClaimParametersList" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "list", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "$ref": "#/parameters/namespace-vgWSWtn3" + }, + { + "$ref": "#/parameters/pretty-tJGM1-ng" + } + ], + "post": { + "consumes": [ + "*/*" + ], + "description": "create ResourceClaimParameters", + "operationId": "createResourceV1alpha2NamespacedResourceClaimParameters", + "parameters": [ + { + "in": "body", + "name": "body", + "required": true, + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/fieldManager-Qy4HdaTW" + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "type": "string", + "uniqueItems": true + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "202": { + "description": "Accepted", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "post", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + } + }, + "/apis/resource.k8s.io/v1alpha2/namespaces/{namespace}/resourceclaimparameters/{name}": { + "delete": { + "consumes": [ + "*/*" + ], + "description": "delete ResourceClaimParameters", + "operationId": "deleteResourceV1alpha2NamespacedResourceClaimParameters", + "parameters": [ + { + "$ref": "#/parameters/body-2Y1dVQaQ" + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" + }, + { + "$ref": "#/parameters/orphanDependents-uRB25kX5" + }, + { + "$ref": "#/parameters/propagationPolicy-6jk3prlO" + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "202": { + "description": "Accepted", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "delete", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + }, + "get": { + "consumes": [ + "*/*" + ], + "description": "read the specified ResourceClaimParameters", + "operationId": "readResourceV1alpha2NamespacedResourceClaimParameters", + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "get", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "name of the ResourceClaimParameters", + "in": "path", + "name": "name", + "required": true, + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/namespace-vgWSWtn3" + }, + { + "$ref": "#/parameters/pretty-tJGM1-ng" + } + ], + "patch": { + "consumes": [ + "application/json-patch+json", + "application/merge-patch+json", + "application/strategic-merge-patch+json", + "application/apply-patch+yaml" + ], + "description": "partially update the specified ResourceClaimParameters", + "operationId": "patchResourceV1alpha2NamespacedResourceClaimParameters", + "parameters": [ + { + "$ref": "#/parameters/body-78PwaGsr" + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/fieldManager-7c6nTn1T" + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/force-tOGGb0Yi" + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "patch", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + }, + "put": { + "consumes": [ + "*/*" + ], + "description": "replace the specified ResourceClaimParameters", + "operationId": "replaceResourceV1alpha2NamespacedResourceClaimParameters", + "parameters": [ + { + "in": "body", + "name": "body", + "required": true, + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/fieldManager-Qy4HdaTW" + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "type": "string", + "uniqueItems": true + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "put", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + } + }, "/apis/resource.k8s.io/v1alpha2/namespaces/{namespace}/resourceclaims": { "delete": { "consumes": [ @@ -71466,6 +72283,970 @@ } } }, + "/apis/resource.k8s.io/v1alpha2/namespaces/{namespace}/resourceclassparameters": { + "delete": { + "consumes": [ + "*/*" + ], + "description": "delete collection of ResourceClassParameters", + "operationId": "deleteResourceV1alpha2CollectionNamespacedResourceClassParameters", + "parameters": [ + { + "$ref": "#/parameters/body-2Y1dVQaQ" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "$ref": "#/parameters/orphanDependents-uRB25kX5" + }, + { + "$ref": "#/parameters/propagationPolicy-6jk3prlO" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "deletecollection", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + }, + "get": { + "consumes": [ + "*/*" + ], + "description": "list or watch objects of kind ResourceClassParameters", + "operationId": "listResourceV1alpha2NamespacedResourceClassParameters", + "parameters": [ + { + "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + }, + { + "$ref": "#/parameters/watch-XNNPZGbK" + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf", + "application/json;stream=watch", + "application/vnd.kubernetes.protobuf;stream=watch" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClassParametersList" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "list", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "$ref": "#/parameters/namespace-vgWSWtn3" + }, + { + "$ref": "#/parameters/pretty-tJGM1-ng" + } + ], + "post": { + "consumes": [ + "*/*" + ], + "description": "create ResourceClassParameters", + "operationId": "createResourceV1alpha2NamespacedResourceClassParameters", + "parameters": [ + { + "in": "body", + "name": "body", + "required": true, + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/fieldManager-Qy4HdaTW" + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "type": "string", + "uniqueItems": true + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "202": { + "description": "Accepted", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "post", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + } + }, + "/apis/resource.k8s.io/v1alpha2/namespaces/{namespace}/resourceclassparameters/{name}": { + "delete": { + "consumes": [ + "*/*" + ], + "description": "delete ResourceClassParameters", + "operationId": "deleteResourceV1alpha2NamespacedResourceClassParameters", + "parameters": [ + { + "$ref": "#/parameters/body-2Y1dVQaQ" + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" + }, + { + "$ref": "#/parameters/orphanDependents-uRB25kX5" + }, + { + "$ref": "#/parameters/propagationPolicy-6jk3prlO" + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "202": { + "description": "Accepted", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "delete", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + }, + "get": { + "consumes": [ + "*/*" + ], + "description": "read the specified ResourceClassParameters", + "operationId": "readResourceV1alpha2NamespacedResourceClassParameters", + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "get", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "name of the ResourceClassParameters", + "in": "path", + "name": "name", + "required": true, + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/namespace-vgWSWtn3" + }, + { + "$ref": "#/parameters/pretty-tJGM1-ng" + } + ], + "patch": { + "consumes": [ + "application/json-patch+json", + "application/merge-patch+json", + "application/strategic-merge-patch+json", + "application/apply-patch+yaml" + ], + "description": "partially update the specified ResourceClassParameters", + "operationId": "patchResourceV1alpha2NamespacedResourceClassParameters", + "parameters": [ + { + "$ref": "#/parameters/body-78PwaGsr" + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/fieldManager-7c6nTn1T" + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/force-tOGGb0Yi" + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "patch", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + }, + "put": { + "consumes": [ + "*/*" + ], + "description": "replace the specified ResourceClassParameters", + "operationId": "replaceResourceV1alpha2NamespacedResourceClassParameters", + "parameters": [ + { + "in": "body", + "name": "body", + "required": true, + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/fieldManager-Qy4HdaTW" + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "type": "string", + "uniqueItems": true + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "put", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + } + }, + "/apis/resource.k8s.io/v1alpha2/noderesourceslices": { + "delete": { + "consumes": [ + "*/*" + ], + "description": "delete collection of NodeResourceSlice", + "operationId": "deleteResourceV1alpha2CollectionNodeResourceSlice", + "parameters": [ + { + "$ref": "#/parameters/body-2Y1dVQaQ" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "$ref": "#/parameters/orphanDependents-uRB25kX5" + }, + { + "$ref": "#/parameters/propagationPolicy-6jk3prlO" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "deletecollection", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "NodeResourceSlice", + "version": "v1alpha2" + } + }, + "get": { + "consumes": [ + "*/*" + ], + "description": "list or watch objects of kind NodeResourceSlice", + "operationId": "listResourceV1alpha2NodeResourceSlice", + "parameters": [ + { + "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + }, + { + "$ref": "#/parameters/watch-XNNPZGbK" + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf", + "application/json;stream=watch", + "application/vnd.kubernetes.protobuf;stream=watch" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSliceList" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "list", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "NodeResourceSlice", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "$ref": "#/parameters/pretty-tJGM1-ng" + } + ], + "post": { + "consumes": [ + "*/*" + ], + "description": "create a NodeResourceSlice", + "operationId": "createResourceV1alpha2NodeResourceSlice", + "parameters": [ + { + "in": "body", + "name": "body", + "required": true, + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/fieldManager-Qy4HdaTW" + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "type": "string", + "uniqueItems": true + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "202": { + "description": "Accepted", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "post", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "NodeResourceSlice", + "version": "v1alpha2" + } + } + }, + "/apis/resource.k8s.io/v1alpha2/noderesourceslices/{name}": { + "delete": { + "consumes": [ + "*/*" + ], + "description": "delete a NodeResourceSlice", + "operationId": "deleteResourceV1alpha2NodeResourceSlice", + "parameters": [ + { + "$ref": "#/parameters/body-2Y1dVQaQ" + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" + }, + { + "$ref": "#/parameters/orphanDependents-uRB25kX5" + }, + { + "$ref": "#/parameters/propagationPolicy-6jk3prlO" + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "202": { + "description": "Accepted", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "delete", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "NodeResourceSlice", + "version": "v1alpha2" + } + }, + "get": { + "consumes": [ + "*/*" + ], + "description": "read the specified NodeResourceSlice", + "operationId": "readResourceV1alpha2NodeResourceSlice", + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "get", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "NodeResourceSlice", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "name of the NodeResourceSlice", + "in": "path", + "name": "name", + "required": true, + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/pretty-tJGM1-ng" + } + ], + "patch": { + "consumes": [ + "application/json-patch+json", + "application/merge-patch+json", + "application/strategic-merge-patch+json", + "application/apply-patch+yaml" + ], + "description": "partially update the specified NodeResourceSlice", + "operationId": "patchResourceV1alpha2NodeResourceSlice", + "parameters": [ + { + "$ref": "#/parameters/body-78PwaGsr" + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/fieldManager-7c6nTn1T" + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/force-tOGGb0Yi" + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "patch", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "NodeResourceSlice", + "version": "v1alpha2" + } + }, + "put": { + "consumes": [ + "*/*" + ], + "description": "replace the specified NodeResourceSlice", + "operationId": "replaceResourceV1alpha2NodeResourceSlice", + "parameters": [ + { + "in": "body", + "name": "body", + "required": true, + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/fieldManager-Qy4HdaTW" + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "type": "string", + "uniqueItems": true + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "put", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "NodeResourceSlice", + "version": "v1alpha2" + } + } + }, "/apis/resource.k8s.io/v1alpha2/podschedulingcontexts": { "get": { "consumes": [ @@ -71540,6 +73321,80 @@ } ] }, + "/apis/resource.k8s.io/v1alpha2/resourceclaimparameters": { + "get": { + "consumes": [ + "*/*" + ], + "description": "list or watch objects of kind ResourceClaimParameters", + "operationId": "listResourceV1alpha2ResourceClaimParametersForAllNamespaces", + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf", + "application/json;stream=watch", + "application/vnd.kubernetes.protobuf;stream=watch" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClaimParametersList" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "list", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "$ref": "#/parameters/pretty-tJGM1-ng" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + }, + { + "$ref": "#/parameters/watch-XNNPZGbK" + } + ] + }, "/apis/resource.k8s.io/v1alpha2/resourceclaims": { "get": { "consumes": [ @@ -72167,6 +74022,80 @@ } } }, + "/apis/resource.k8s.io/v1alpha2/resourceclassparameters": { + "get": { + "consumes": [ + "*/*" + ], + "description": "list or watch objects of kind ResourceClassParameters", + "operationId": "listResourceV1alpha2ResourceClassParametersForAllNamespaces", + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf", + "application/json;stream=watch", + "application/vnd.kubernetes.protobuf;stream=watch" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceClassParametersList" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "list", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "$ref": "#/parameters/pretty-tJGM1-ng" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + }, + { + "$ref": "#/parameters/watch-XNNPZGbK" + } + ] + }, "/apis/resource.k8s.io/v1alpha2/watch/namespaces/{namespace}/podschedulingcontexts": { "get": { "consumes": [ @@ -72329,6 +74258,168 @@ } ] }, + "/apis/resource.k8s.io/v1alpha2/watch/namespaces/{namespace}/resourceclaimparameters": { + "get": { + "consumes": [ + "*/*" + ], + "description": "watch individual changes to a list of ResourceClaimParameters. deprecated: use the 'watch' parameter with a list operation instead.", + "operationId": "watchResourceV1alpha2NamespacedResourceClaimParametersList", + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf", + "application/json;stream=watch", + "application/vnd.kubernetes.protobuf;stream=watch" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "watchlist", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "$ref": "#/parameters/namespace-vgWSWtn3" + }, + { + "$ref": "#/parameters/pretty-tJGM1-ng" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + }, + { + "$ref": "#/parameters/watch-XNNPZGbK" + } + ] + }, + "/apis/resource.k8s.io/v1alpha2/watch/namespaces/{namespace}/resourceclaimparameters/{name}": { + "get": { + "consumes": [ + "*/*" + ], + "description": "watch changes to an object of kind ResourceClaimParameters. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", + "operationId": "watchResourceV1alpha2NamespacedResourceClaimParameters", + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf", + "application/json;stream=watch", + "application/vnd.kubernetes.protobuf;stream=watch" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "watch", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "description": "name of the ResourceClaimParameters", + "in": "path", + "name": "name", + "required": true, + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/namespace-vgWSWtn3" + }, + { + "$ref": "#/parameters/pretty-tJGM1-ng" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + }, + { + "$ref": "#/parameters/watch-XNNPZGbK" + } + ] + }, "/apis/resource.k8s.io/v1alpha2/watch/namespaces/{namespace}/resourceclaims": { "get": { "consumes": [ @@ -72653,6 +74744,324 @@ } ] }, + "/apis/resource.k8s.io/v1alpha2/watch/namespaces/{namespace}/resourceclassparameters": { + "get": { + "consumes": [ + "*/*" + ], + "description": "watch individual changes to a list of ResourceClassParameters. deprecated: use the 'watch' parameter with a list operation instead.", + "operationId": "watchResourceV1alpha2NamespacedResourceClassParametersList", + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf", + "application/json;stream=watch", + "application/vnd.kubernetes.protobuf;stream=watch" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "watchlist", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "$ref": "#/parameters/namespace-vgWSWtn3" + }, + { + "$ref": "#/parameters/pretty-tJGM1-ng" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + }, + { + "$ref": "#/parameters/watch-XNNPZGbK" + } + ] + }, + "/apis/resource.k8s.io/v1alpha2/watch/namespaces/{namespace}/resourceclassparameters/{name}": { + "get": { + "consumes": [ + "*/*" + ], + "description": "watch changes to an object of kind ResourceClassParameters. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", + "operationId": "watchResourceV1alpha2NamespacedResourceClassParameters", + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf", + "application/json;stream=watch", + "application/vnd.kubernetes.protobuf;stream=watch" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "watch", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "description": "name of the ResourceClassParameters", + "in": "path", + "name": "name", + "required": true, + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/namespace-vgWSWtn3" + }, + { + "$ref": "#/parameters/pretty-tJGM1-ng" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + }, + { + "$ref": "#/parameters/watch-XNNPZGbK" + } + ] + }, + "/apis/resource.k8s.io/v1alpha2/watch/noderesourceslices": { + "get": { + "consumes": [ + "*/*" + ], + "description": "watch individual changes to a list of NodeResourceSlice. deprecated: use the 'watch' parameter with a list operation instead.", + "operationId": "watchResourceV1alpha2NodeResourceSliceList", + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf", + "application/json;stream=watch", + "application/vnd.kubernetes.protobuf;stream=watch" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "watchlist", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "NodeResourceSlice", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "$ref": "#/parameters/pretty-tJGM1-ng" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + }, + { + "$ref": "#/parameters/watch-XNNPZGbK" + } + ] + }, + "/apis/resource.k8s.io/v1alpha2/watch/noderesourceslices/{name}": { + "get": { + "consumes": [ + "*/*" + ], + "description": "watch changes to an object of kind NodeResourceSlice. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", + "operationId": "watchResourceV1alpha2NodeResourceSlice", + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf", + "application/json;stream=watch", + "application/vnd.kubernetes.protobuf;stream=watch" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "watch", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "NodeResourceSlice", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "description": "name of the NodeResourceSlice", + "in": "path", + "name": "name", + "required": true, + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/pretty-tJGM1-ng" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + }, + { + "$ref": "#/parameters/watch-XNNPZGbK" + } + ] + }, "/apis/resource.k8s.io/v1alpha2/watch/podschedulingcontexts": { "get": { "consumes": [ @@ -72727,6 +75136,80 @@ } ] }, + "/apis/resource.k8s.io/v1alpha2/watch/resourceclaimparameters": { + "get": { + "consumes": [ + "*/*" + ], + "description": "watch individual changes to a list of ResourceClaimParameters. deprecated: use the 'watch' parameter with a list operation instead.", + "operationId": "watchResourceV1alpha2ResourceClaimParametersListForAllNamespaces", + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf", + "application/json;stream=watch", + "application/vnd.kubernetes.protobuf;stream=watch" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "watchlist", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "$ref": "#/parameters/pretty-tJGM1-ng" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + }, + { + "$ref": "#/parameters/watch-XNNPZGbK" + } + ] + }, "/apis/resource.k8s.io/v1alpha2/watch/resourceclaims": { "get": { "consumes": [ @@ -73031,6 +75514,80 @@ } ] }, + "/apis/resource.k8s.io/v1alpha2/watch/resourceclassparameters": { + "get": { + "consumes": [ + "*/*" + ], + "description": "watch individual changes to a list of ResourceClassParameters. deprecated: use the 'watch' parameter with a list operation instead.", + "operationId": "watchResourceV1alpha2ResourceClassParametersListForAllNamespaces", + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf", + "application/json;stream=watch", + "application/vnd.kubernetes.protobuf;stream=watch" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "watchlist", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "$ref": "#/parameters/pretty-tJGM1-ng" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + }, + { + "$ref": "#/parameters/watch-XNNPZGbK" + } + ] + }, "/apis/scheduling.k8s.io/": { "get": { "consumes": [ diff --git a/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha2_openapi.json b/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha2_openapi.json index 42cf776b86f..63fd58bc24a 100644 --- a/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha2_openapi.json +++ b/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha2_openapi.json @@ -117,6 +117,140 @@ }, "type": "object" }, + "io.k8s.api.resource.v1alpha2.DriverAllocationResult": { + "description": "DriverAllocationResult contains vendor parameters and the allocation result for one request.", + "properties": { + "vendorRequestParameters": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.runtime.RawExtension" + } + ], + "description": "VendorRequestParameters are the per-request configuration parameters from the time that the claim was allocated." + } + }, + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.DriverRequests": { + "description": "DriverRequests describes all resources that are needed from one particular driver.", + "properties": { + "driverName": { + "description": "DriverName is the name used by the DRA driver kubelet plugin.", + "type": "string" + }, + "requests": { + "description": "Requests describes all resources that are needed from the driver.", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceRequest" + } + ], + "default": {} + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "vendorParameters": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.runtime.RawExtension" + } + ], + "description": "VendorParameters are arbitrary setup parameters for all requests of the claim. They are ignored while allocating the claim." + } + }, + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.NodeResourceSlice": { + "description": "NodeResourceSlice provides information about available resources on individual nodes.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "driverName": { + "default": "", + "description": "DriverName identifies the DRA driver providing the capacity information. A field selector can be used to list only NodeResourceSlice objects with a certain driver name.", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta" + } + ], + "default": {}, + "description": "Standard object metadata" + }, + "nodeName": { + "default": "", + "description": "NodeName identifies the node where the capacity is available. A field selector can be used to list only NodeResourceSlice objects with a certain node name.", + "type": "string" + } + }, + "required": [ + "nodeName", + "driverName" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "resource.k8s.io", + "kind": "NodeResourceSlice", + "version": "v1alpha2" + } + ] + }, + "io.k8s.api.resource.v1alpha2.NodeResourceSliceList": { + "description": "NodeResourceSliceList is a collection of NodeResourceSlices.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "Items is the list of node resource capacity objects.", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + ], + "default": {} + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + ], + "default": {}, + "description": "Standard list metadata" + } + }, + "required": [ + "items" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "resource.k8s.io", + "kind": "NodeResourceSliceList", + "version": "v1alpha2" + } + ] + }, "io.k8s.api.resource.v1alpha2.PodSchedulingContext": { "description": "PodSchedulingContext objects hold information that is needed to schedule a Pod with ResourceClaims that use \"WaitForFirstConsumer\" allocation mode.\n\nThis is an alpha type and requires enabling the DynamicResourceAllocation feature gate.", "properties": { @@ -380,6 +514,106 @@ } ] }, + "io.k8s.api.resource.v1alpha2.ResourceClaimParameters": { + "description": "ResourceClaimParameters defines resource requests for a ResourceClaim in an in-tree format understood by Kubernetes.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "driverRequests": { + "description": "DriverRequests describes all resources that are needed for the allocated claim. A single claim may use resources coming from different drivers. For each driver, this array has at most one entry which then may have one or more per-driver requests.\n\nMay be empty, in which case the claim can always be allocated.", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.DriverRequests" + } + ], + "default": {} + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "generatedFrom": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParametersReference" + } + ], + "description": "If this object was created from some other resource, then this links back to that resource. This field is used to find the in-tree representation of the claim parameters when the parameter reference of the claim refers to some unknown type." + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta" + } + ], + "default": {}, + "description": "Standard object metadata" + }, + "shareable": { + "description": "Shareable indicates whether the allocated claim is meant to be shareable by multiple consumers at the same time.", + "type": "boolean" + } + }, + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + ] + }, + "io.k8s.api.resource.v1alpha2.ResourceClaimParametersList": { + "description": "ResourceClaimParametersList is a collection of ResourceClaimParameters.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "Items is the list of node resource capacity objects.", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + ], + "default": {} + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + ], + "default": {}, + "description": "Standard list metadata" + } + }, + "required": [ + "items" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "resource.k8s.io", + "kind": "ResourceClaimParametersList", + "version": "v1alpha2" + } + ] + }, "io.k8s.api.resource.v1alpha2.ResourceClaimParametersReference": { "description": "ResourceClaimParametersReference contains enough information to let you locate the parameters for a ResourceClaim. The object must be in the same namespace as the ResourceClaim.", "properties": { @@ -636,6 +870,10 @@ ], "description": "ParametersRef references an arbitrary separate object that may hold parameters that will be used by the driver when allocating a resource that uses this class. A dynamic resource driver can distinguish between parameters stored here and and those stored in ResourceClaimSpec." }, + "structuredParameters": { + "description": "If and only if allocation of claims using this class is handled via structured parameters, then StructuredParameters must be set to true.", + "type": "boolean" + }, "suitableNodes": { "allOf": [ { @@ -702,6 +940,115 @@ } ] }, + "io.k8s.api.resource.v1alpha2.ResourceClassParameters": { + "description": "ResourceClassParameters defines resource requests for a ResourceClass in an in-tree format understood by Kubernetes.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "filters": { + "description": "Filters describes additional contraints that must be met when using the class.", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceFilter" + } + ], + "default": {} + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "generatedFrom": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParametersReference" + } + ], + "description": "If this object was created from some other resource, then this links back to that resource. This field is used to find the in-tree representation of the class parameters when the parameter reference of the class refers to some unknown type." + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta" + } + ], + "default": {}, + "description": "Standard object metadata" + }, + "vendorParameters": { + "description": "VendorParameters are arbitrary setup parameters for all claims using this class. They are ignored while allocating the claim. There must not be more than one entry per driver.", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.VendorParameters" + } + ], + "default": {} + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + } + }, + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + ] + }, + "io.k8s.api.resource.v1alpha2.ResourceClassParametersList": { + "description": "ResourceClassParametersList is a collection of ResourceClassParameters.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "Items is the list of node resource capacity objects.", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + ], + "default": {} + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + ], + "default": {}, + "description": "Standard list metadata" + } + }, + "required": [ + "items" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "resource.k8s.io", + "kind": "ResourceClassParametersList", + "version": "v1alpha2" + } + ] + }, "io.k8s.api.resource.v1alpha2.ResourceClassParametersReference": { "description": "ResourceClassParametersReference contains enough information to let you locate the parameters for a ResourceClass.", "properties": { @@ -730,6 +1077,16 @@ ], "type": "object" }, + "io.k8s.api.resource.v1alpha2.ResourceFilter": { + "description": "ResourceFilter is a filter for resources from one particular driver.", + "properties": { + "driverName": { + "description": "DriverName is the name used by the DRA driver kubelet plugin.", + "type": "string" + } + }, + "type": "object" + }, "io.k8s.api.resource.v1alpha2.ResourceHandle": { "description": "ResourceHandle holds opaque resource data for processing by a specific kubelet plugin.", "properties": { @@ -740,6 +1097,90 @@ "driverName": { "description": "DriverName specifies the name of the resource driver whose kubelet plugin should be invoked to process this ResourceHandle's data once it lands on a node. This may differ from the DriverName set in ResourceClaimStatus this ResourceHandle is embedded in.", "type": "string" + }, + "structuredData": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.StructuredResourceHandle" + } + ], + "description": "If StructuredData is set, then it needs to be used instead of Data." + } + }, + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.ResourceRequest": { + "description": "ResourceRequest is a request for resources from one particular driver.", + "properties": { + "vendorParameters": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.runtime.RawExtension" + } + ], + "description": "VendorParameters are arbitrary setup parameters for the requested resource. They are ignored while allocating a claim." + } + }, + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.StructuredResourceHandle": { + "description": "StructuredResourceHandle is the in-tree representation of the allocation result.", + "properties": { + "nodeName": { + "default": "", + "description": "NodeName is the name of the node providing the necessary resources.", + "type": "string" + }, + "results": { + "description": "Results lists all allocated driver resources.", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.DriverAllocationResult" + } + ], + "default": {} + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "vendorClaimParameters": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.runtime.RawExtension" + } + ], + "description": "VendorClaimParameters are the per-claim configuration parameters from the resource claim parameters at the time that the claim was allocated." + }, + "vendorClassParameters": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.runtime.RawExtension" + } + ], + "description": "VendorClassParameters are the per-claim configuration parameters from the resource class at the time that the claim was allocated." + } + }, + "required": [ + "nodeName", + "results" + ], + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.VendorParameters": { + "description": "VendorParameters are opaque parameters for one particular driver.", + "properties": { + "driverName": { + "description": "DriverName is the name used by the DRA driver kubelet plugin.", + "type": "string" + }, + "parameters": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.runtime.RawExtension" + } + ], + "description": "Parameters can be arbitrary setup parameters. They are ignored while allocating a claim." } }, "type": "object" @@ -3047,6 +3488,837 @@ } } }, + "/apis/resource.k8s.io/v1alpha2/namespaces/{namespace}/resourceclaimparameters": { + "delete": { + "description": "delete collection of ResourceClaimParameters", + "operationId": "deleteResourceV1alpha2CollectionNamespacedResourceClaimParameters", + "parameters": [ + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "in": "query", + "name": "gracePeriodSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "in": "query", + "name": "orphanDependents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "in": "query", + "name": "propagationPolicy", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "in": "query", + "name": "sendInitialEvents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "deletecollection", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + }, + "get": { + "description": "list or watch objects of kind ResourceClaimParameters", + "operationId": "listResourceV1alpha2NamespacedResourceClaimParameters", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "in": "query", + "name": "sendInitialEvents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParametersList" + } + }, + "application/json;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParametersList" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParametersList" + } + }, + "application/vnd.kubernetes.protobuf;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParametersList" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParametersList" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "list", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "post": { + "description": "create ResourceClaimParameters", + "operationId": "createResourceV1alpha2NamespacedResourceClaimParameters", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + } + }, + "description": "Created" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "post", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + } + }, + "/apis/resource.k8s.io/v1alpha2/namespaces/{namespace}/resourceclaimparameters/{name}": { + "delete": { + "description": "delete ResourceClaimParameters", + "operationId": "deleteResourceV1alpha2NamespacedResourceClaimParameters", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "in": "query", + "name": "gracePeriodSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "in": "query", + "name": "orphanDependents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "in": "query", + "name": "propagationPolicy", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + } + }, + "description": "OK" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "delete", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + }, + "get": { + "description": "read the specified ResourceClaimParameters", + "operationId": "readResourceV1alpha2NamespacedResourceClaimParameters", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "get", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "name of the ResourceClaimParameters", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "patch": { + "description": "partially update the specified ResourceClaimParameters", + "operationId": "patchResourceV1alpha2NamespacedResourceClaimParameters", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch).", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Force is going to \"force\" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests.", + "in": "query", + "name": "force", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/apply-patch+yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/json-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/merge-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/strategic-merge-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + } + }, + "description": "Created" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "patch", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + }, + "put": { + "description": "replace the specified ResourceClaimParameters", + "operationId": "replaceResourceV1alpha2NamespacedResourceClaimParameters", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParameters" + } + } + }, + "description": "Created" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "put", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + } + }, "/apis/resource.k8s.io/v1alpha2/namespaces/{namespace}/resourceclaims": { "delete": { "description": "delete collection of ResourceClaim", @@ -4998,6 +6270,1648 @@ } } }, + "/apis/resource.k8s.io/v1alpha2/namespaces/{namespace}/resourceclassparameters": { + "delete": { + "description": "delete collection of ResourceClassParameters", + "operationId": "deleteResourceV1alpha2CollectionNamespacedResourceClassParameters", + "parameters": [ + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "in": "query", + "name": "gracePeriodSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "in": "query", + "name": "orphanDependents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "in": "query", + "name": "propagationPolicy", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "in": "query", + "name": "sendInitialEvents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "deletecollection", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + }, + "get": { + "description": "list or watch objects of kind ResourceClassParameters", + "operationId": "listResourceV1alpha2NamespacedResourceClassParameters", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "in": "query", + "name": "sendInitialEvents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParametersList" + } + }, + "application/json;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParametersList" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParametersList" + } + }, + "application/vnd.kubernetes.protobuf;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParametersList" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParametersList" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "list", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "post": { + "description": "create ResourceClassParameters", + "operationId": "createResourceV1alpha2NamespacedResourceClassParameters", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + } + }, + "description": "Created" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "post", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + } + }, + "/apis/resource.k8s.io/v1alpha2/namespaces/{namespace}/resourceclassparameters/{name}": { + "delete": { + "description": "delete ResourceClassParameters", + "operationId": "deleteResourceV1alpha2NamespacedResourceClassParameters", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "in": "query", + "name": "gracePeriodSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "in": "query", + "name": "orphanDependents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "in": "query", + "name": "propagationPolicy", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + } + }, + "description": "OK" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "delete", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + }, + "get": { + "description": "read the specified ResourceClassParameters", + "operationId": "readResourceV1alpha2NamespacedResourceClassParameters", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "get", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "name of the ResourceClassParameters", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "patch": { + "description": "partially update the specified ResourceClassParameters", + "operationId": "patchResourceV1alpha2NamespacedResourceClassParameters", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch).", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Force is going to \"force\" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests.", + "in": "query", + "name": "force", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/apply-patch+yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/json-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/merge-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/strategic-merge-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + } + }, + "description": "Created" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "patch", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + }, + "put": { + "description": "replace the specified ResourceClassParameters", + "operationId": "replaceResourceV1alpha2NamespacedResourceClassParameters", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParameters" + } + } + }, + "description": "Created" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "put", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + } + }, + "/apis/resource.k8s.io/v1alpha2/noderesourceslices": { + "delete": { + "description": "delete collection of NodeResourceSlice", + "operationId": "deleteResourceV1alpha2CollectionNodeResourceSlice", + "parameters": [ + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "in": "query", + "name": "gracePeriodSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "in": "query", + "name": "orphanDependents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "in": "query", + "name": "propagationPolicy", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "in": "query", + "name": "sendInitialEvents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "deletecollection", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "NodeResourceSlice", + "version": "v1alpha2" + } + }, + "get": { + "description": "list or watch objects of kind NodeResourceSlice", + "operationId": "listResourceV1alpha2NodeResourceSlice", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "in": "query", + "name": "sendInitialEvents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSliceList" + } + }, + "application/json;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSliceList" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSliceList" + } + }, + "application/vnd.kubernetes.protobuf;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSliceList" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSliceList" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "list", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "NodeResourceSlice", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "post": { + "description": "create a NodeResourceSlice", + "operationId": "createResourceV1alpha2NodeResourceSlice", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + } + }, + "description": "Created" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "post", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "NodeResourceSlice", + "version": "v1alpha2" + } + } + }, + "/apis/resource.k8s.io/v1alpha2/noderesourceslices/{name}": { + "delete": { + "description": "delete a NodeResourceSlice", + "operationId": "deleteResourceV1alpha2NodeResourceSlice", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "in": "query", + "name": "gracePeriodSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "in": "query", + "name": "orphanDependents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "in": "query", + "name": "propagationPolicy", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + } + }, + "description": "OK" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "delete", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "NodeResourceSlice", + "version": "v1alpha2" + } + }, + "get": { + "description": "read the specified NodeResourceSlice", + "operationId": "readResourceV1alpha2NodeResourceSlice", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "get", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "NodeResourceSlice", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "name of the NodeResourceSlice", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "patch": { + "description": "partially update the specified NodeResourceSlice", + "operationId": "patchResourceV1alpha2NodeResourceSlice", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch).", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Force is going to \"force\" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests.", + "in": "query", + "name": "force", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/apply-patch+yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/json-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/merge-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/strategic-merge-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + } + }, + "description": "Created" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "patch", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "NodeResourceSlice", + "version": "v1alpha2" + } + }, + "put": { + "description": "replace the specified NodeResourceSlice", + "operationId": "replaceResourceV1alpha2NodeResourceSlice", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" + } + } + }, + "description": "Created" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "put", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "NodeResourceSlice", + "version": "v1alpha2" + } + } + }, "/apis/resource.k8s.io/v1alpha2/podschedulingcontexts": { "get": { "description": "list or watch objects of kind PodSchedulingContext", @@ -5149,6 +8063,157 @@ } ] }, + "/apis/resource.k8s.io/v1alpha2/resourceclaimparameters": { + "get": { + "description": "list or watch objects of kind ResourceClaimParameters", + "operationId": "listResourceV1alpha2ResourceClaimParametersForAllNamespaces", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParametersList" + } + }, + "application/json;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParametersList" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParametersList" + } + }, + "application/vnd.kubernetes.protobuf;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParametersList" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClaimParametersList" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "list", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "in": "query", + "name": "sendInitialEvents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ] + }, "/apis/resource.k8s.io/v1alpha2/resourceclaims": { "get": { "description": "list or watch objects of kind ResourceClaim", @@ -6262,6 +9327,157 @@ } } }, + "/apis/resource.k8s.io/v1alpha2/resourceclassparameters": { + "get": { + "description": "list or watch objects of kind ResourceClassParameters", + "operationId": "listResourceV1alpha2ResourceClassParametersForAllNamespaces", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParametersList" + } + }, + "application/json;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParametersList" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParametersList" + } + }, + "application/vnd.kubernetes.protobuf;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParametersList" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceClassParametersList" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "list", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "in": "query", + "name": "sendInitialEvents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ] + }, "/apis/resource.k8s.io/v1alpha2/watch/namespaces/{namespace}/podschedulingcontexts": { "get": { "description": "watch individual changes to a list of PodSchedulingContext. deprecated: use the 'watch' parameter with a list operation instead.", @@ -6594,6 +9810,338 @@ } ] }, + "/apis/resource.k8s.io/v1alpha2/watch/namespaces/{namespace}/resourceclaimparameters": { + "get": { + "description": "watch individual changes to a list of ResourceClaimParameters. deprecated: use the 'watch' parameter with a list operation instead.", + "operationId": "watchResourceV1alpha2NamespacedResourceClaimParametersList", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/json;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/vnd.kubernetes.protobuf;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "watchlist", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "in": "query", + "name": "sendInitialEvents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ] + }, + "/apis/resource.k8s.io/v1alpha2/watch/namespaces/{namespace}/resourceclaimparameters/{name}": { + "get": { + "description": "watch changes to an object of kind ResourceClaimParameters. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", + "operationId": "watchResourceV1alpha2NamespacedResourceClaimParameters", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/json;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/vnd.kubernetes.protobuf;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "watch", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "name of the ResourceClaimParameters", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "in": "query", + "name": "sendInitialEvents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ] + }, "/apis/resource.k8s.io/v1alpha2/watch/namespaces/{namespace}/resourceclaims": { "get": { "description": "watch individual changes to a list of ResourceClaim. deprecated: use the 'watch' parameter with a list operation instead.", @@ -7258,6 +10806,650 @@ } ] }, + "/apis/resource.k8s.io/v1alpha2/watch/namespaces/{namespace}/resourceclassparameters": { + "get": { + "description": "watch individual changes to a list of ResourceClassParameters. deprecated: use the 'watch' parameter with a list operation instead.", + "operationId": "watchResourceV1alpha2NamespacedResourceClassParametersList", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/json;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/vnd.kubernetes.protobuf;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "watchlist", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "in": "query", + "name": "sendInitialEvents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ] + }, + "/apis/resource.k8s.io/v1alpha2/watch/namespaces/{namespace}/resourceclassparameters/{name}": { + "get": { + "description": "watch changes to an object of kind ResourceClassParameters. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", + "operationId": "watchResourceV1alpha2NamespacedResourceClassParameters", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/json;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/vnd.kubernetes.protobuf;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "watch", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "name of the ResourceClassParameters", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "in": "query", + "name": "sendInitialEvents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ] + }, + "/apis/resource.k8s.io/v1alpha2/watch/noderesourceslices": { + "get": { + "description": "watch individual changes to a list of NodeResourceSlice. deprecated: use the 'watch' parameter with a list operation instead.", + "operationId": "watchResourceV1alpha2NodeResourceSliceList", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/json;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/vnd.kubernetes.protobuf;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "watchlist", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "NodeResourceSlice", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "in": "query", + "name": "sendInitialEvents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ] + }, + "/apis/resource.k8s.io/v1alpha2/watch/noderesourceslices/{name}": { + "get": { + "description": "watch changes to an object of kind NodeResourceSlice. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", + "operationId": "watchResourceV1alpha2NodeResourceSlice", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/json;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/vnd.kubernetes.protobuf;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "watch", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "NodeResourceSlice", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "name of the NodeResourceSlice", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "in": "query", + "name": "sendInitialEvents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ] + }, "/apis/resource.k8s.io/v1alpha2/watch/podschedulingcontexts": { "get": { "description": "watch individual changes to a list of PodSchedulingContext. deprecated: use the 'watch' parameter with a list operation instead.", @@ -7409,6 +11601,157 @@ } ] }, + "/apis/resource.k8s.io/v1alpha2/watch/resourceclaimparameters": { + "get": { + "description": "watch individual changes to a list of ResourceClaimParameters. deprecated: use the 'watch' parameter with a list operation instead.", + "operationId": "watchResourceV1alpha2ResourceClaimParametersListForAllNamespaces", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/json;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/vnd.kubernetes.protobuf;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "watchlist", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClaimParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "in": "query", + "name": "sendInitialEvents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ] + }, "/apis/resource.k8s.io/v1alpha2/watch/resourceclaims": { "get": { "description": "watch individual changes to a list of ResourceClaim. deprecated: use the 'watch' parameter with a list operation instead.", @@ -8022,6 +12365,157 @@ } } ] + }, + "/apis/resource.k8s.io/v1alpha2/watch/resourceclassparameters": { + "get": { + "description": "watch individual changes to a list of ResourceClassParameters. deprecated: use the 'watch' parameter with a list operation instead.", + "operationId": "watchResourceV1alpha2ResourceClassParametersListForAllNamespaces", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/json;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/vnd.kubernetes.protobuf;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "watchlist", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceClassParameters", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "in": "query", + "name": "sendInitialEvents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ] } } } diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh index 7b65a50807e..88246510868 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -37,7 +37,7 @@ API_KNOWN_VIOLATIONS_DIR="${API_KNOWN_VIOLATIONS_DIR:-"${KUBE_ROOT}/api/api-rule OUT_DIR="_output" BOILERPLATE_FILENAME="hack/boilerplate/boilerplate.generatego.txt" APPLYCONFIG_PKG="k8s.io/client-go/applyconfigurations" -PLURAL_EXCEPTIONS="Endpoints:Endpoints" +PLURAL_EXCEPTIONS="Endpoints:Endpoints,ResourceClaimParameters:ResourceClaimParameters,ResourceClassParameters:ResourceClassParameters" # Any time we call sort, we want it in the same locale. export LC_ALL="C" diff --git a/pkg/apis/resource/register.go b/pkg/apis/resource/register.go index ba20bf6ccb7..0f1a5b17029 100644 --- a/pkg/apis/resource/register.go +++ b/pkg/apis/resource/register.go @@ -60,6 +60,12 @@ func addKnownTypes(scheme *runtime.Scheme) error { &ResourceClaimTemplateList{}, &PodSchedulingContext{}, &PodSchedulingContextList{}, + &NodeResourceSlice{}, + &NodeResourceSliceList{}, + &ResourceClaimParameters{}, + &ResourceClaimParametersList{}, + &ResourceClassParameters{}, + &ResourceClassParametersList{}, ) return nil diff --git a/pkg/apis/resource/types.go b/pkg/apis/resource/types.go index bfcd1c46662..10ed93bc0a1 100644 --- a/pkg/apis/resource/types.go +++ b/pkg/apis/resource/types.go @@ -18,6 +18,7 @@ package resource import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/kubernetes/pkg/apis/core" ) @@ -185,11 +186,47 @@ type ResourceHandle struct { // future, but not reduced. // +optional Data string + + // If StructuredData is set, then it needs to be used instead of Data. + StructuredData *StructuredResourceHandle } // ResourceHandleDataMaxSize represents the maximum size of resourceHandle.data. const ResourceHandleDataMaxSize = 16 * 1024 +// StructuredResourceHandle is the in-tree representation of the allocation result. +type StructuredResourceHandle struct { + // VendorClassParameters are the per-claim configuration parameters + // from the resource class at the time that the claim was allocated. + VendorClassParameters runtime.Object + + // VendorClaimParameters are the per-claim configuration parameters + // from the resource claim parameters at the time that the claim was + // allocated. + VendorClaimParameters runtime.Object + + // NodeName is the name of the node providing the necessary resources. + NodeName string + + // Results lists all allocated driver resources. + Results []DriverAllocationResult +} + +// DriverAllocationResult contains vendor parameters and the allocation result for +// one request. +type DriverAllocationResult struct { + // VendorRequestParameters are the per-request configuration parameters + // from the time that the claim was allocated. + VendorRequestParameters runtime.Object + + AllocationResultModel +} + +// AllocationResultModel must have one and only one field set. +type AllocationResultModel struct { + // TODO: implement one structured parameter model +} + // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // ResourceClaimList is a collection of claims. @@ -323,6 +360,10 @@ type ResourceClass struct { // Setting this field is optional. If null, all nodes are candidates. // +optional SuitableNodes *core.NodeSelector + + // If and only if allocation of claims using this class is handled + // via structured parameters, then StructuredParameters must be set to true. + StructuredParameters *bool } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -434,3 +475,168 @@ type ResourceClaimTemplateList struct { // Items is the list of resource claim templates. Items []ResourceClaimTemplate } + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// NodeResourceSlice provides information about available +// resources on individual nodes. +type NodeResourceSlice struct { + metav1.TypeMeta + // Standard object metadata + metav1.ObjectMeta + + // NodeName identifies the node where the capacity is available. + // A field selector can be used to list only NodeResourceSlice + // objects with a certain node name. + NodeName string + + // DriverName identifies the DRA driver providing the capacity information. + // A field selector can be used to list only NodeResourceSlice + // objects with a certain driver name. + DriverName string + + NodeResourceModel +} + +// NodeResourceModel must have one and only one field set. +type NodeResourceModel struct { + // TODO: implement one structured parameter model +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// NodeResourceSliceList is a collection of NodeResourceSlices. +type NodeResourceSliceList struct { + metav1.TypeMeta + // Standard list metadata + metav1.ListMeta + + // Items is the list of node resource capacity objects. + Items []NodeResourceSlice +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ResourceClaimParameters defines resource requests for a ResourceClaim in an +// in-tree format understood by Kubernetes. +type ResourceClaimParameters struct { + metav1.TypeMeta + // Standard object metadata + metav1.ObjectMeta + + // If this object was created from some other resource, then this links + // back to that resource. This field is used to find the in-tree representation + // of the claim parameters when the parameter reference of the claim refers + // to some unknown type. + GeneratedFrom *ResourceClaimParametersReference + + // Shareable indicates whether the allocated claim is meant to be shareable + // by multiple consumers at the same time. + Shareable bool + + // DriverRequests describes all resources that are needed for the + // allocated claim. A single claim may use resources coming from + // different drivers. For each driver, this array has at most one + // entry which then may have one or more per-driver requests. + // + // May be empty, in which case the claim can always be allocated. + DriverRequests []DriverRequests +} + +// DriverRequests describes all resources that are needed from one particular driver. +type DriverRequests struct { + // DriverName is the name used by the DRA driver kubelet plugin. + DriverName string + + // VendorParameters are arbitrary setup parameters for all requests of the + // claim. They are ignored while allocating the claim. + VendorParameters runtime.Object + + // Requests describes all resources that are needed from the driver. + Requests []ResourceRequest +} + +// ResourceRequest is a request for resources from one particular driver. +type ResourceRequest struct { + // VendorParameters are arbitrary setup parameters for the requested + // resource. They are ignored while allocating a claim. + VendorParameters runtime.Object + + ResourceRequestModel +} + +// ResourceRequestModel must have one and only one field set. +type ResourceRequestModel struct { + // TODO: implement one structured parameter model +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ResourceClaimParametersList is a collection of ResourceClaimParameters. +type ResourceClaimParametersList struct { + metav1.TypeMeta + // Standard list metadata + metav1.ListMeta + + // Items is the list of node resource capacity objects. + Items []ResourceClaimParameters +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ResourceClassParameters defines resource requests for a ResourceClass in an +// in-tree format understood by Kubernetes. +type ResourceClassParameters struct { + metav1.TypeMeta + // Standard object metadata + metav1.ObjectMeta + + // If this object was created from some other resource, then this links + // back to that resource. This field is used to find the in-tree representation + // of the class parameters when the parameter reference of the class refers + // to some unknown type. + GeneratedFrom *ResourceClassParametersReference + + // VendorParameters are arbitrary setup parameters for all claims using + // this class. They are ignored while allocating the claim. There must + // not be more than one entry per driver. + VendorParameters []VendorParameters + + // Filters describes additional contraints that must be met when using the class. + Filters []ResourceFilter +} + +// ResourceFilter is a filter for resources from one particular driver. +type ResourceFilter struct { + // DriverName is the name used by the DRA driver kubelet plugin. + DriverName string + + ResourceFilterModel +} + +// ResourceFilterModel must have one and only one field set. +type ResourceFilterModel struct { + // TODO: implement one structured parameter model +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ResourceClassParametersList is a collection of ResourceClassParameters. +type ResourceClassParametersList struct { + metav1.TypeMeta + // Standard list metadata + metav1.ListMeta + + // Items is the list of node resource capacity objects. + Items []ResourceClassParameters +} + +// VendorParameters are opaque parameters for one particular driver. +type VendorParameters struct { + // DriverName is the name used by the DRA driver kubelet plugin. + DriverName string + + // Parameters can be arbitrary setup parameters. They are ignored while + // allocating a claim. + Parameters runtime.Object +} diff --git a/pkg/apis/resource/v1alpha2/conversion.go b/pkg/apis/resource/v1alpha2/conversion.go index 397d2a1fb08..5e35ad6dee0 100644 --- a/pkg/apis/resource/v1alpha2/conversion.go +++ b/pkg/apis/resource/v1alpha2/conversion.go @@ -17,9 +17,23 @@ limitations under the License. package v1alpha2 import ( + "fmt" + "k8s.io/apimachinery/pkg/runtime" ) func addConversionFuncs(scheme *runtime.Scheme) error { + if err := scheme.AddFieldLabelConversionFunc(SchemeGroupVersion.WithKind("NodeResourceSlice"), + func(label, value string) (string, string, error) { + switch label { + case "metadata.name", "nodeName", "driverName": + return label, value, nil + default: + return "", "", fmt.Errorf("field label not supported for %s: %s", SchemeGroupVersion.WithKind("NodeResourceSlice"), label) + } + }); err != nil { + return err + } + return nil } diff --git a/pkg/apis/resource/v1alpha2/zz_generated.conversion.go b/pkg/apis/resource/v1alpha2/zz_generated.conversion.go index c1902ee804e..107da311342 100644 --- a/pkg/apis/resource/v1alpha2/zz_generated.conversion.go +++ b/pkg/apis/resource/v1alpha2/zz_generated.conversion.go @@ -50,6 +50,66 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*v1alpha2.AllocationResultModel)(nil), (*resource.AllocationResultModel)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_AllocationResultModel_To_resource_AllocationResultModel(a.(*v1alpha2.AllocationResultModel), b.(*resource.AllocationResultModel), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.AllocationResultModel)(nil), (*v1alpha2.AllocationResultModel)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_AllocationResultModel_To_v1alpha2_AllocationResultModel(a.(*resource.AllocationResultModel), b.(*v1alpha2.AllocationResultModel), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.DriverAllocationResult)(nil), (*resource.DriverAllocationResult)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_DriverAllocationResult_To_resource_DriverAllocationResult(a.(*v1alpha2.DriverAllocationResult), b.(*resource.DriverAllocationResult), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.DriverAllocationResult)(nil), (*v1alpha2.DriverAllocationResult)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_DriverAllocationResult_To_v1alpha2_DriverAllocationResult(a.(*resource.DriverAllocationResult), b.(*v1alpha2.DriverAllocationResult), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.DriverRequests)(nil), (*resource.DriverRequests)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_DriverRequests_To_resource_DriverRequests(a.(*v1alpha2.DriverRequests), b.(*resource.DriverRequests), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.DriverRequests)(nil), (*v1alpha2.DriverRequests)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_DriverRequests_To_v1alpha2_DriverRequests(a.(*resource.DriverRequests), b.(*v1alpha2.DriverRequests), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.NodeResourceModel)(nil), (*resource.NodeResourceModel)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_NodeResourceModel_To_resource_NodeResourceModel(a.(*v1alpha2.NodeResourceModel), b.(*resource.NodeResourceModel), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.NodeResourceModel)(nil), (*v1alpha2.NodeResourceModel)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_NodeResourceModel_To_v1alpha2_NodeResourceModel(a.(*resource.NodeResourceModel), b.(*v1alpha2.NodeResourceModel), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.NodeResourceSlice)(nil), (*resource.NodeResourceSlice)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_NodeResourceSlice_To_resource_NodeResourceSlice(a.(*v1alpha2.NodeResourceSlice), b.(*resource.NodeResourceSlice), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.NodeResourceSlice)(nil), (*v1alpha2.NodeResourceSlice)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_NodeResourceSlice_To_v1alpha2_NodeResourceSlice(a.(*resource.NodeResourceSlice), b.(*v1alpha2.NodeResourceSlice), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.NodeResourceSliceList)(nil), (*resource.NodeResourceSliceList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_NodeResourceSliceList_To_resource_NodeResourceSliceList(a.(*v1alpha2.NodeResourceSliceList), b.(*resource.NodeResourceSliceList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.NodeResourceSliceList)(nil), (*v1alpha2.NodeResourceSliceList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_NodeResourceSliceList_To_v1alpha2_NodeResourceSliceList(a.(*resource.NodeResourceSliceList), b.(*v1alpha2.NodeResourceSliceList), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*v1alpha2.PodSchedulingContext)(nil), (*resource.PodSchedulingContext)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha2_PodSchedulingContext_To_resource_PodSchedulingContext(a.(*v1alpha2.PodSchedulingContext), b.(*resource.PodSchedulingContext), scope) }); err != nil { @@ -120,6 +180,26 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*v1alpha2.ResourceClaimParameters)(nil), (*resource.ResourceClaimParameters)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_ResourceClaimParameters_To_resource_ResourceClaimParameters(a.(*v1alpha2.ResourceClaimParameters), b.(*resource.ResourceClaimParameters), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.ResourceClaimParameters)(nil), (*v1alpha2.ResourceClaimParameters)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_ResourceClaimParameters_To_v1alpha2_ResourceClaimParameters(a.(*resource.ResourceClaimParameters), b.(*v1alpha2.ResourceClaimParameters), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.ResourceClaimParametersList)(nil), (*resource.ResourceClaimParametersList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_ResourceClaimParametersList_To_resource_ResourceClaimParametersList(a.(*v1alpha2.ResourceClaimParametersList), b.(*resource.ResourceClaimParametersList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.ResourceClaimParametersList)(nil), (*v1alpha2.ResourceClaimParametersList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_ResourceClaimParametersList_To_v1alpha2_ResourceClaimParametersList(a.(*resource.ResourceClaimParametersList), b.(*v1alpha2.ResourceClaimParametersList), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*v1alpha2.ResourceClaimParametersReference)(nil), (*resource.ResourceClaimParametersReference)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha2_ResourceClaimParametersReference_To_resource_ResourceClaimParametersReference(a.(*v1alpha2.ResourceClaimParametersReference), b.(*resource.ResourceClaimParametersReference), scope) }); err != nil { @@ -210,6 +290,26 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*v1alpha2.ResourceClassParameters)(nil), (*resource.ResourceClassParameters)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_ResourceClassParameters_To_resource_ResourceClassParameters(a.(*v1alpha2.ResourceClassParameters), b.(*resource.ResourceClassParameters), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.ResourceClassParameters)(nil), (*v1alpha2.ResourceClassParameters)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_ResourceClassParameters_To_v1alpha2_ResourceClassParameters(a.(*resource.ResourceClassParameters), b.(*v1alpha2.ResourceClassParameters), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.ResourceClassParametersList)(nil), (*resource.ResourceClassParametersList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_ResourceClassParametersList_To_resource_ResourceClassParametersList(a.(*v1alpha2.ResourceClassParametersList), b.(*resource.ResourceClassParametersList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.ResourceClassParametersList)(nil), (*v1alpha2.ResourceClassParametersList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_ResourceClassParametersList_To_v1alpha2_ResourceClassParametersList(a.(*resource.ResourceClassParametersList), b.(*v1alpha2.ResourceClassParametersList), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*v1alpha2.ResourceClassParametersReference)(nil), (*resource.ResourceClassParametersReference)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha2_ResourceClassParametersReference_To_resource_ResourceClassParametersReference(a.(*v1alpha2.ResourceClassParametersReference), b.(*resource.ResourceClassParametersReference), scope) }); err != nil { @@ -220,6 +320,26 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*v1alpha2.ResourceFilter)(nil), (*resource.ResourceFilter)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_ResourceFilter_To_resource_ResourceFilter(a.(*v1alpha2.ResourceFilter), b.(*resource.ResourceFilter), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.ResourceFilter)(nil), (*v1alpha2.ResourceFilter)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_ResourceFilter_To_v1alpha2_ResourceFilter(a.(*resource.ResourceFilter), b.(*v1alpha2.ResourceFilter), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.ResourceFilterModel)(nil), (*resource.ResourceFilterModel)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_ResourceFilterModel_To_resource_ResourceFilterModel(a.(*v1alpha2.ResourceFilterModel), b.(*resource.ResourceFilterModel), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.ResourceFilterModel)(nil), (*v1alpha2.ResourceFilterModel)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_ResourceFilterModel_To_v1alpha2_ResourceFilterModel(a.(*resource.ResourceFilterModel), b.(*v1alpha2.ResourceFilterModel), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*v1alpha2.ResourceHandle)(nil), (*resource.ResourceHandle)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha2_ResourceHandle_To_resource_ResourceHandle(a.(*v1alpha2.ResourceHandle), b.(*resource.ResourceHandle), scope) }); err != nil { @@ -230,11 +350,61 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*v1alpha2.ResourceRequest)(nil), (*resource.ResourceRequest)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_ResourceRequest_To_resource_ResourceRequest(a.(*v1alpha2.ResourceRequest), b.(*resource.ResourceRequest), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.ResourceRequest)(nil), (*v1alpha2.ResourceRequest)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_ResourceRequest_To_v1alpha2_ResourceRequest(a.(*resource.ResourceRequest), b.(*v1alpha2.ResourceRequest), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.ResourceRequestModel)(nil), (*resource.ResourceRequestModel)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_ResourceRequestModel_To_resource_ResourceRequestModel(a.(*v1alpha2.ResourceRequestModel), b.(*resource.ResourceRequestModel), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.ResourceRequestModel)(nil), (*v1alpha2.ResourceRequestModel)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_ResourceRequestModel_To_v1alpha2_ResourceRequestModel(a.(*resource.ResourceRequestModel), b.(*v1alpha2.ResourceRequestModel), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.StructuredResourceHandle)(nil), (*resource.StructuredResourceHandle)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_StructuredResourceHandle_To_resource_StructuredResourceHandle(a.(*v1alpha2.StructuredResourceHandle), b.(*resource.StructuredResourceHandle), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.StructuredResourceHandle)(nil), (*v1alpha2.StructuredResourceHandle)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_StructuredResourceHandle_To_v1alpha2_StructuredResourceHandle(a.(*resource.StructuredResourceHandle), b.(*v1alpha2.StructuredResourceHandle), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.VendorParameters)(nil), (*resource.VendorParameters)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_VendorParameters_To_resource_VendorParameters(a.(*v1alpha2.VendorParameters), b.(*resource.VendorParameters), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.VendorParameters)(nil), (*v1alpha2.VendorParameters)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_VendorParameters_To_v1alpha2_VendorParameters(a.(*resource.VendorParameters), b.(*v1alpha2.VendorParameters), scope) + }); err != nil { + return err + } return nil } func autoConvert_v1alpha2_AllocationResult_To_resource_AllocationResult(in *v1alpha2.AllocationResult, out *resource.AllocationResult, s conversion.Scope) error { - out.ResourceHandles = *(*[]resource.ResourceHandle)(unsafe.Pointer(&in.ResourceHandles)) + if in.ResourceHandles != nil { + in, out := &in.ResourceHandles, &out.ResourceHandles + *out = make([]resource.ResourceHandle, len(*in)) + for i := range *in { + if err := Convert_v1alpha2_ResourceHandle_To_resource_ResourceHandle(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.ResourceHandles = nil + } out.AvailableOnNodes = (*core.NodeSelector)(unsafe.Pointer(in.AvailableOnNodes)) out.Shareable = in.Shareable return nil @@ -246,7 +416,17 @@ func Convert_v1alpha2_AllocationResult_To_resource_AllocationResult(in *v1alpha2 } func autoConvert_resource_AllocationResult_To_v1alpha2_AllocationResult(in *resource.AllocationResult, out *v1alpha2.AllocationResult, s conversion.Scope) error { - out.ResourceHandles = *(*[]v1alpha2.ResourceHandle)(unsafe.Pointer(&in.ResourceHandles)) + if in.ResourceHandles != nil { + in, out := &in.ResourceHandles, &out.ResourceHandles + *out = make([]v1alpha2.ResourceHandle, len(*in)) + for i := range *in { + if err := Convert_resource_ResourceHandle_To_v1alpha2_ResourceHandle(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.ResourceHandles = nil + } out.AvailableOnNodes = (*v1.NodeSelector)(unsafe.Pointer(in.AvailableOnNodes)) out.Shareable = in.Shareable return nil @@ -257,6 +437,172 @@ func Convert_resource_AllocationResult_To_v1alpha2_AllocationResult(in *resource return autoConvert_resource_AllocationResult_To_v1alpha2_AllocationResult(in, out, s) } +func autoConvert_v1alpha2_AllocationResultModel_To_resource_AllocationResultModel(in *v1alpha2.AllocationResultModel, out *resource.AllocationResultModel, s conversion.Scope) error { + return nil +} + +// Convert_v1alpha2_AllocationResultModel_To_resource_AllocationResultModel is an autogenerated conversion function. +func Convert_v1alpha2_AllocationResultModel_To_resource_AllocationResultModel(in *v1alpha2.AllocationResultModel, out *resource.AllocationResultModel, s conversion.Scope) error { + return autoConvert_v1alpha2_AllocationResultModel_To_resource_AllocationResultModel(in, out, s) +} + +func autoConvert_resource_AllocationResultModel_To_v1alpha2_AllocationResultModel(in *resource.AllocationResultModel, out *v1alpha2.AllocationResultModel, s conversion.Scope) error { + return nil +} + +// Convert_resource_AllocationResultModel_To_v1alpha2_AllocationResultModel is an autogenerated conversion function. +func Convert_resource_AllocationResultModel_To_v1alpha2_AllocationResultModel(in *resource.AllocationResultModel, out *v1alpha2.AllocationResultModel, s conversion.Scope) error { + return autoConvert_resource_AllocationResultModel_To_v1alpha2_AllocationResultModel(in, out, s) +} + +func autoConvert_v1alpha2_DriverAllocationResult_To_resource_DriverAllocationResult(in *v1alpha2.DriverAllocationResult, out *resource.DriverAllocationResult, s conversion.Scope) error { + if err := runtime.Convert_runtime_RawExtension_To_runtime_Object(&in.VendorRequestParameters, &out.VendorRequestParameters, s); err != nil { + return err + } + if err := Convert_v1alpha2_AllocationResultModel_To_resource_AllocationResultModel(&in.AllocationResultModel, &out.AllocationResultModel, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha2_DriverAllocationResult_To_resource_DriverAllocationResult is an autogenerated conversion function. +func Convert_v1alpha2_DriverAllocationResult_To_resource_DriverAllocationResult(in *v1alpha2.DriverAllocationResult, out *resource.DriverAllocationResult, s conversion.Scope) error { + return autoConvert_v1alpha2_DriverAllocationResult_To_resource_DriverAllocationResult(in, out, s) +} + +func autoConvert_resource_DriverAllocationResult_To_v1alpha2_DriverAllocationResult(in *resource.DriverAllocationResult, out *v1alpha2.DriverAllocationResult, s conversion.Scope) error { + if err := runtime.Convert_runtime_Object_To_runtime_RawExtension(&in.VendorRequestParameters, &out.VendorRequestParameters, s); err != nil { + return err + } + if err := Convert_resource_AllocationResultModel_To_v1alpha2_AllocationResultModel(&in.AllocationResultModel, &out.AllocationResultModel, s); err != nil { + return err + } + return nil +} + +// Convert_resource_DriverAllocationResult_To_v1alpha2_DriverAllocationResult is an autogenerated conversion function. +func Convert_resource_DriverAllocationResult_To_v1alpha2_DriverAllocationResult(in *resource.DriverAllocationResult, out *v1alpha2.DriverAllocationResult, s conversion.Scope) error { + return autoConvert_resource_DriverAllocationResult_To_v1alpha2_DriverAllocationResult(in, out, s) +} + +func autoConvert_v1alpha2_DriverRequests_To_resource_DriverRequests(in *v1alpha2.DriverRequests, out *resource.DriverRequests, s conversion.Scope) error { + out.DriverName = in.DriverName + if err := runtime.Convert_runtime_RawExtension_To_runtime_Object(&in.VendorParameters, &out.VendorParameters, s); err != nil { + return err + } + if in.Requests != nil { + in, out := &in.Requests, &out.Requests + *out = make([]resource.ResourceRequest, len(*in)) + for i := range *in { + if err := Convert_v1alpha2_ResourceRequest_To_resource_ResourceRequest(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Requests = nil + } + return nil +} + +// Convert_v1alpha2_DriverRequests_To_resource_DriverRequests is an autogenerated conversion function. +func Convert_v1alpha2_DriverRequests_To_resource_DriverRequests(in *v1alpha2.DriverRequests, out *resource.DriverRequests, s conversion.Scope) error { + return autoConvert_v1alpha2_DriverRequests_To_resource_DriverRequests(in, out, s) +} + +func autoConvert_resource_DriverRequests_To_v1alpha2_DriverRequests(in *resource.DriverRequests, out *v1alpha2.DriverRequests, s conversion.Scope) error { + out.DriverName = in.DriverName + if err := runtime.Convert_runtime_Object_To_runtime_RawExtension(&in.VendorParameters, &out.VendorParameters, s); err != nil { + return err + } + if in.Requests != nil { + in, out := &in.Requests, &out.Requests + *out = make([]v1alpha2.ResourceRequest, len(*in)) + for i := range *in { + if err := Convert_resource_ResourceRequest_To_v1alpha2_ResourceRequest(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Requests = nil + } + return nil +} + +// Convert_resource_DriverRequests_To_v1alpha2_DriverRequests is an autogenerated conversion function. +func Convert_resource_DriverRequests_To_v1alpha2_DriverRequests(in *resource.DriverRequests, out *v1alpha2.DriverRequests, s conversion.Scope) error { + return autoConvert_resource_DriverRequests_To_v1alpha2_DriverRequests(in, out, s) +} + +func autoConvert_v1alpha2_NodeResourceModel_To_resource_NodeResourceModel(in *v1alpha2.NodeResourceModel, out *resource.NodeResourceModel, s conversion.Scope) error { + return nil +} + +// Convert_v1alpha2_NodeResourceModel_To_resource_NodeResourceModel is an autogenerated conversion function. +func Convert_v1alpha2_NodeResourceModel_To_resource_NodeResourceModel(in *v1alpha2.NodeResourceModel, out *resource.NodeResourceModel, s conversion.Scope) error { + return autoConvert_v1alpha2_NodeResourceModel_To_resource_NodeResourceModel(in, out, s) +} + +func autoConvert_resource_NodeResourceModel_To_v1alpha2_NodeResourceModel(in *resource.NodeResourceModel, out *v1alpha2.NodeResourceModel, s conversion.Scope) error { + return nil +} + +// Convert_resource_NodeResourceModel_To_v1alpha2_NodeResourceModel is an autogenerated conversion function. +func Convert_resource_NodeResourceModel_To_v1alpha2_NodeResourceModel(in *resource.NodeResourceModel, out *v1alpha2.NodeResourceModel, s conversion.Scope) error { + return autoConvert_resource_NodeResourceModel_To_v1alpha2_NodeResourceModel(in, out, s) +} + +func autoConvert_v1alpha2_NodeResourceSlice_To_resource_NodeResourceSlice(in *v1alpha2.NodeResourceSlice, out *resource.NodeResourceSlice, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + out.NodeName = in.NodeName + out.DriverName = in.DriverName + if err := Convert_v1alpha2_NodeResourceModel_To_resource_NodeResourceModel(&in.NodeResourceModel, &out.NodeResourceModel, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha2_NodeResourceSlice_To_resource_NodeResourceSlice is an autogenerated conversion function. +func Convert_v1alpha2_NodeResourceSlice_To_resource_NodeResourceSlice(in *v1alpha2.NodeResourceSlice, out *resource.NodeResourceSlice, s conversion.Scope) error { + return autoConvert_v1alpha2_NodeResourceSlice_To_resource_NodeResourceSlice(in, out, s) +} + +func autoConvert_resource_NodeResourceSlice_To_v1alpha2_NodeResourceSlice(in *resource.NodeResourceSlice, out *v1alpha2.NodeResourceSlice, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + out.NodeName = in.NodeName + out.DriverName = in.DriverName + if err := Convert_resource_NodeResourceModel_To_v1alpha2_NodeResourceModel(&in.NodeResourceModel, &out.NodeResourceModel, s); err != nil { + return err + } + return nil +} + +// Convert_resource_NodeResourceSlice_To_v1alpha2_NodeResourceSlice is an autogenerated conversion function. +func Convert_resource_NodeResourceSlice_To_v1alpha2_NodeResourceSlice(in *resource.NodeResourceSlice, out *v1alpha2.NodeResourceSlice, s conversion.Scope) error { + return autoConvert_resource_NodeResourceSlice_To_v1alpha2_NodeResourceSlice(in, out, s) +} + +func autoConvert_v1alpha2_NodeResourceSliceList_To_resource_NodeResourceSliceList(in *v1alpha2.NodeResourceSliceList, out *resource.NodeResourceSliceList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]resource.NodeResourceSlice)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_v1alpha2_NodeResourceSliceList_To_resource_NodeResourceSliceList is an autogenerated conversion function. +func Convert_v1alpha2_NodeResourceSliceList_To_resource_NodeResourceSliceList(in *v1alpha2.NodeResourceSliceList, out *resource.NodeResourceSliceList, s conversion.Scope) error { + return autoConvert_v1alpha2_NodeResourceSliceList_To_resource_NodeResourceSliceList(in, out, s) +} + +func autoConvert_resource_NodeResourceSliceList_To_v1alpha2_NodeResourceSliceList(in *resource.NodeResourceSliceList, out *v1alpha2.NodeResourceSliceList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]v1alpha2.NodeResourceSlice)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_resource_NodeResourceSliceList_To_v1alpha2_NodeResourceSliceList is an autogenerated conversion function. +func Convert_resource_NodeResourceSliceList_To_v1alpha2_NodeResourceSliceList(in *resource.NodeResourceSliceList, out *v1alpha2.NodeResourceSliceList, s conversion.Scope) error { + return autoConvert_resource_NodeResourceSliceList_To_v1alpha2_NodeResourceSliceList(in, out, s) +} + func autoConvert_v1alpha2_PodSchedulingContext_To_resource_PodSchedulingContext(in *v1alpha2.PodSchedulingContext, out *resource.PodSchedulingContext, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta if err := Convert_v1alpha2_PodSchedulingContextSpec_To_resource_PodSchedulingContextSpec(&in.Spec, &out.Spec, s); err != nil { @@ -413,7 +759,17 @@ func Convert_resource_ResourceClaimConsumerReference_To_v1alpha2_ResourceClaimCo func autoConvert_v1alpha2_ResourceClaimList_To_resource_ResourceClaimList(in *v1alpha2.ResourceClaimList, out *resource.ResourceClaimList, s conversion.Scope) error { out.ListMeta = in.ListMeta - out.Items = *(*[]resource.ResourceClaim)(unsafe.Pointer(&in.Items)) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]resource.ResourceClaim, len(*in)) + for i := range *in { + if err := Convert_v1alpha2_ResourceClaim_To_resource_ResourceClaim(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } return nil } @@ -424,7 +780,17 @@ func Convert_v1alpha2_ResourceClaimList_To_resource_ResourceClaimList(in *v1alph func autoConvert_resource_ResourceClaimList_To_v1alpha2_ResourceClaimList(in *resource.ResourceClaimList, out *v1alpha2.ResourceClaimList, s conversion.Scope) error { out.ListMeta = in.ListMeta - out.Items = *(*[]v1alpha2.ResourceClaim)(unsafe.Pointer(&in.Items)) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1alpha2.ResourceClaim, len(*in)) + for i := range *in { + if err := Convert_resource_ResourceClaim_To_v1alpha2_ResourceClaim(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } return nil } @@ -433,6 +799,94 @@ func Convert_resource_ResourceClaimList_To_v1alpha2_ResourceClaimList(in *resour return autoConvert_resource_ResourceClaimList_To_v1alpha2_ResourceClaimList(in, out, s) } +func autoConvert_v1alpha2_ResourceClaimParameters_To_resource_ResourceClaimParameters(in *v1alpha2.ResourceClaimParameters, out *resource.ResourceClaimParameters, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + out.GeneratedFrom = (*resource.ResourceClaimParametersReference)(unsafe.Pointer(in.GeneratedFrom)) + out.Shareable = in.Shareable + if in.DriverRequests != nil { + in, out := &in.DriverRequests, &out.DriverRequests + *out = make([]resource.DriverRequests, len(*in)) + for i := range *in { + if err := Convert_v1alpha2_DriverRequests_To_resource_DriverRequests(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.DriverRequests = nil + } + return nil +} + +// Convert_v1alpha2_ResourceClaimParameters_To_resource_ResourceClaimParameters is an autogenerated conversion function. +func Convert_v1alpha2_ResourceClaimParameters_To_resource_ResourceClaimParameters(in *v1alpha2.ResourceClaimParameters, out *resource.ResourceClaimParameters, s conversion.Scope) error { + return autoConvert_v1alpha2_ResourceClaimParameters_To_resource_ResourceClaimParameters(in, out, s) +} + +func autoConvert_resource_ResourceClaimParameters_To_v1alpha2_ResourceClaimParameters(in *resource.ResourceClaimParameters, out *v1alpha2.ResourceClaimParameters, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + out.GeneratedFrom = (*v1alpha2.ResourceClaimParametersReference)(unsafe.Pointer(in.GeneratedFrom)) + out.Shareable = in.Shareable + if in.DriverRequests != nil { + in, out := &in.DriverRequests, &out.DriverRequests + *out = make([]v1alpha2.DriverRequests, len(*in)) + for i := range *in { + if err := Convert_resource_DriverRequests_To_v1alpha2_DriverRequests(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.DriverRequests = nil + } + return nil +} + +// Convert_resource_ResourceClaimParameters_To_v1alpha2_ResourceClaimParameters is an autogenerated conversion function. +func Convert_resource_ResourceClaimParameters_To_v1alpha2_ResourceClaimParameters(in *resource.ResourceClaimParameters, out *v1alpha2.ResourceClaimParameters, s conversion.Scope) error { + return autoConvert_resource_ResourceClaimParameters_To_v1alpha2_ResourceClaimParameters(in, out, s) +} + +func autoConvert_v1alpha2_ResourceClaimParametersList_To_resource_ResourceClaimParametersList(in *v1alpha2.ResourceClaimParametersList, out *resource.ResourceClaimParametersList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]resource.ResourceClaimParameters, len(*in)) + for i := range *in { + if err := Convert_v1alpha2_ResourceClaimParameters_To_resource_ResourceClaimParameters(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha2_ResourceClaimParametersList_To_resource_ResourceClaimParametersList is an autogenerated conversion function. +func Convert_v1alpha2_ResourceClaimParametersList_To_resource_ResourceClaimParametersList(in *v1alpha2.ResourceClaimParametersList, out *resource.ResourceClaimParametersList, s conversion.Scope) error { + return autoConvert_v1alpha2_ResourceClaimParametersList_To_resource_ResourceClaimParametersList(in, out, s) +} + +func autoConvert_resource_ResourceClaimParametersList_To_v1alpha2_ResourceClaimParametersList(in *resource.ResourceClaimParametersList, out *v1alpha2.ResourceClaimParametersList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1alpha2.ResourceClaimParameters, len(*in)) + for i := range *in { + if err := Convert_resource_ResourceClaimParameters_To_v1alpha2_ResourceClaimParameters(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_resource_ResourceClaimParametersList_To_v1alpha2_ResourceClaimParametersList is an autogenerated conversion function. +func Convert_resource_ResourceClaimParametersList_To_v1alpha2_ResourceClaimParametersList(in *resource.ResourceClaimParametersList, out *v1alpha2.ResourceClaimParametersList, s conversion.Scope) error { + return autoConvert_resource_ResourceClaimParametersList_To_v1alpha2_ResourceClaimParametersList(in, out, s) +} + func autoConvert_v1alpha2_ResourceClaimParametersReference_To_resource_ResourceClaimParametersReference(in *v1alpha2.ResourceClaimParametersReference, out *resource.ResourceClaimParametersReference, s conversion.Scope) error { out.APIGroup = in.APIGroup out.Kind = in.Kind @@ -505,7 +959,15 @@ func Convert_resource_ResourceClaimSpec_To_v1alpha2_ResourceClaimSpec(in *resour func autoConvert_v1alpha2_ResourceClaimStatus_To_resource_ResourceClaimStatus(in *v1alpha2.ResourceClaimStatus, out *resource.ResourceClaimStatus, s conversion.Scope) error { out.DriverName = in.DriverName - out.Allocation = (*resource.AllocationResult)(unsafe.Pointer(in.Allocation)) + if in.Allocation != nil { + in, out := &in.Allocation, &out.Allocation + *out = new(resource.AllocationResult) + if err := Convert_v1alpha2_AllocationResult_To_resource_AllocationResult(*in, *out, s); err != nil { + return err + } + } else { + out.Allocation = nil + } out.ReservedFor = *(*[]resource.ResourceClaimConsumerReference)(unsafe.Pointer(&in.ReservedFor)) out.DeallocationRequested = in.DeallocationRequested return nil @@ -518,7 +980,15 @@ func Convert_v1alpha2_ResourceClaimStatus_To_resource_ResourceClaimStatus(in *v1 func autoConvert_resource_ResourceClaimStatus_To_v1alpha2_ResourceClaimStatus(in *resource.ResourceClaimStatus, out *v1alpha2.ResourceClaimStatus, s conversion.Scope) error { out.DriverName = in.DriverName - out.Allocation = (*v1alpha2.AllocationResult)(unsafe.Pointer(in.Allocation)) + if in.Allocation != nil { + in, out := &in.Allocation, &out.Allocation + *out = new(v1alpha2.AllocationResult) + if err := Convert_resource_AllocationResult_To_v1alpha2_AllocationResult(*in, *out, s); err != nil { + return err + } + } else { + out.Allocation = nil + } out.ReservedFor = *(*[]v1alpha2.ResourceClaimConsumerReference)(unsafe.Pointer(&in.ReservedFor)) out.DeallocationRequested = in.DeallocationRequested return nil @@ -608,6 +1078,7 @@ func autoConvert_v1alpha2_ResourceClass_To_resource_ResourceClass(in *v1alpha2.R out.DriverName = in.DriverName out.ParametersRef = (*resource.ResourceClassParametersReference)(unsafe.Pointer(in.ParametersRef)) out.SuitableNodes = (*core.NodeSelector)(unsafe.Pointer(in.SuitableNodes)) + out.StructuredParameters = (*bool)(unsafe.Pointer(in.StructuredParameters)) return nil } @@ -621,6 +1092,7 @@ func autoConvert_resource_ResourceClass_To_v1alpha2_ResourceClass(in *resource.R out.DriverName = in.DriverName out.ParametersRef = (*v1alpha2.ResourceClassParametersReference)(unsafe.Pointer(in.ParametersRef)) out.SuitableNodes = (*v1.NodeSelector)(unsafe.Pointer(in.SuitableNodes)) + out.StructuredParameters = (*bool)(unsafe.Pointer(in.StructuredParameters)) return nil } @@ -651,6 +1123,94 @@ func Convert_resource_ResourceClassList_To_v1alpha2_ResourceClassList(in *resour return autoConvert_resource_ResourceClassList_To_v1alpha2_ResourceClassList(in, out, s) } +func autoConvert_v1alpha2_ResourceClassParameters_To_resource_ResourceClassParameters(in *v1alpha2.ResourceClassParameters, out *resource.ResourceClassParameters, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + out.GeneratedFrom = (*resource.ResourceClassParametersReference)(unsafe.Pointer(in.GeneratedFrom)) + if in.VendorParameters != nil { + in, out := &in.VendorParameters, &out.VendorParameters + *out = make([]resource.VendorParameters, len(*in)) + for i := range *in { + if err := Convert_v1alpha2_VendorParameters_To_resource_VendorParameters(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.VendorParameters = nil + } + out.Filters = *(*[]resource.ResourceFilter)(unsafe.Pointer(&in.Filters)) + return nil +} + +// Convert_v1alpha2_ResourceClassParameters_To_resource_ResourceClassParameters is an autogenerated conversion function. +func Convert_v1alpha2_ResourceClassParameters_To_resource_ResourceClassParameters(in *v1alpha2.ResourceClassParameters, out *resource.ResourceClassParameters, s conversion.Scope) error { + return autoConvert_v1alpha2_ResourceClassParameters_To_resource_ResourceClassParameters(in, out, s) +} + +func autoConvert_resource_ResourceClassParameters_To_v1alpha2_ResourceClassParameters(in *resource.ResourceClassParameters, out *v1alpha2.ResourceClassParameters, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + out.GeneratedFrom = (*v1alpha2.ResourceClassParametersReference)(unsafe.Pointer(in.GeneratedFrom)) + if in.VendorParameters != nil { + in, out := &in.VendorParameters, &out.VendorParameters + *out = make([]v1alpha2.VendorParameters, len(*in)) + for i := range *in { + if err := Convert_resource_VendorParameters_To_v1alpha2_VendorParameters(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.VendorParameters = nil + } + out.Filters = *(*[]v1alpha2.ResourceFilter)(unsafe.Pointer(&in.Filters)) + return nil +} + +// Convert_resource_ResourceClassParameters_To_v1alpha2_ResourceClassParameters is an autogenerated conversion function. +func Convert_resource_ResourceClassParameters_To_v1alpha2_ResourceClassParameters(in *resource.ResourceClassParameters, out *v1alpha2.ResourceClassParameters, s conversion.Scope) error { + return autoConvert_resource_ResourceClassParameters_To_v1alpha2_ResourceClassParameters(in, out, s) +} + +func autoConvert_v1alpha2_ResourceClassParametersList_To_resource_ResourceClassParametersList(in *v1alpha2.ResourceClassParametersList, out *resource.ResourceClassParametersList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]resource.ResourceClassParameters, len(*in)) + for i := range *in { + if err := Convert_v1alpha2_ResourceClassParameters_To_resource_ResourceClassParameters(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha2_ResourceClassParametersList_To_resource_ResourceClassParametersList is an autogenerated conversion function. +func Convert_v1alpha2_ResourceClassParametersList_To_resource_ResourceClassParametersList(in *v1alpha2.ResourceClassParametersList, out *resource.ResourceClassParametersList, s conversion.Scope) error { + return autoConvert_v1alpha2_ResourceClassParametersList_To_resource_ResourceClassParametersList(in, out, s) +} + +func autoConvert_resource_ResourceClassParametersList_To_v1alpha2_ResourceClassParametersList(in *resource.ResourceClassParametersList, out *v1alpha2.ResourceClassParametersList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1alpha2.ResourceClassParameters, len(*in)) + for i := range *in { + if err := Convert_resource_ResourceClassParameters_To_v1alpha2_ResourceClassParameters(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_resource_ResourceClassParametersList_To_v1alpha2_ResourceClassParametersList is an autogenerated conversion function. +func Convert_resource_ResourceClassParametersList_To_v1alpha2_ResourceClassParametersList(in *resource.ResourceClassParametersList, out *v1alpha2.ResourceClassParametersList, s conversion.Scope) error { + return autoConvert_resource_ResourceClassParametersList_To_v1alpha2_ResourceClassParametersList(in, out, s) +} + func autoConvert_v1alpha2_ResourceClassParametersReference_To_resource_ResourceClassParametersReference(in *v1alpha2.ResourceClassParametersReference, out *resource.ResourceClassParametersReference, s conversion.Scope) error { out.APIGroup = in.APIGroup out.Kind = in.Kind @@ -677,9 +1237,62 @@ func Convert_resource_ResourceClassParametersReference_To_v1alpha2_ResourceClass return autoConvert_resource_ResourceClassParametersReference_To_v1alpha2_ResourceClassParametersReference(in, out, s) } +func autoConvert_v1alpha2_ResourceFilter_To_resource_ResourceFilter(in *v1alpha2.ResourceFilter, out *resource.ResourceFilter, s conversion.Scope) error { + out.DriverName = in.DriverName + if err := Convert_v1alpha2_ResourceFilterModel_To_resource_ResourceFilterModel(&in.ResourceFilterModel, &out.ResourceFilterModel, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha2_ResourceFilter_To_resource_ResourceFilter is an autogenerated conversion function. +func Convert_v1alpha2_ResourceFilter_To_resource_ResourceFilter(in *v1alpha2.ResourceFilter, out *resource.ResourceFilter, s conversion.Scope) error { + return autoConvert_v1alpha2_ResourceFilter_To_resource_ResourceFilter(in, out, s) +} + +func autoConvert_resource_ResourceFilter_To_v1alpha2_ResourceFilter(in *resource.ResourceFilter, out *v1alpha2.ResourceFilter, s conversion.Scope) error { + out.DriverName = in.DriverName + if err := Convert_resource_ResourceFilterModel_To_v1alpha2_ResourceFilterModel(&in.ResourceFilterModel, &out.ResourceFilterModel, s); err != nil { + return err + } + return nil +} + +// Convert_resource_ResourceFilter_To_v1alpha2_ResourceFilter is an autogenerated conversion function. +func Convert_resource_ResourceFilter_To_v1alpha2_ResourceFilter(in *resource.ResourceFilter, out *v1alpha2.ResourceFilter, s conversion.Scope) error { + return autoConvert_resource_ResourceFilter_To_v1alpha2_ResourceFilter(in, out, s) +} + +func autoConvert_v1alpha2_ResourceFilterModel_To_resource_ResourceFilterModel(in *v1alpha2.ResourceFilterModel, out *resource.ResourceFilterModel, s conversion.Scope) error { + return nil +} + +// Convert_v1alpha2_ResourceFilterModel_To_resource_ResourceFilterModel is an autogenerated conversion function. +func Convert_v1alpha2_ResourceFilterModel_To_resource_ResourceFilterModel(in *v1alpha2.ResourceFilterModel, out *resource.ResourceFilterModel, s conversion.Scope) error { + return autoConvert_v1alpha2_ResourceFilterModel_To_resource_ResourceFilterModel(in, out, s) +} + +func autoConvert_resource_ResourceFilterModel_To_v1alpha2_ResourceFilterModel(in *resource.ResourceFilterModel, out *v1alpha2.ResourceFilterModel, s conversion.Scope) error { + return nil +} + +// Convert_resource_ResourceFilterModel_To_v1alpha2_ResourceFilterModel is an autogenerated conversion function. +func Convert_resource_ResourceFilterModel_To_v1alpha2_ResourceFilterModel(in *resource.ResourceFilterModel, out *v1alpha2.ResourceFilterModel, s conversion.Scope) error { + return autoConvert_resource_ResourceFilterModel_To_v1alpha2_ResourceFilterModel(in, out, s) +} + func autoConvert_v1alpha2_ResourceHandle_To_resource_ResourceHandle(in *v1alpha2.ResourceHandle, out *resource.ResourceHandle, s conversion.Scope) error { out.DriverName = in.DriverName out.Data = in.Data + if in.StructuredData != nil { + in, out := &in.StructuredData, &out.StructuredData + *out = new(resource.StructuredResourceHandle) + if err := Convert_v1alpha2_StructuredResourceHandle_To_resource_StructuredResourceHandle(*in, *out, s); err != nil { + return err + } + } else { + out.StructuredData = nil + } return nil } @@ -691,6 +1304,15 @@ func Convert_v1alpha2_ResourceHandle_To_resource_ResourceHandle(in *v1alpha2.Res func autoConvert_resource_ResourceHandle_To_v1alpha2_ResourceHandle(in *resource.ResourceHandle, out *v1alpha2.ResourceHandle, s conversion.Scope) error { out.DriverName = in.DriverName out.Data = in.Data + if in.StructuredData != nil { + in, out := &in.StructuredData, &out.StructuredData + *out = new(v1alpha2.StructuredResourceHandle) + if err := Convert_resource_StructuredResourceHandle_To_v1alpha2_StructuredResourceHandle(*in, *out, s); err != nil { + return err + } + } else { + out.StructuredData = nil + } return nil } @@ -698,3 +1320,131 @@ func autoConvert_resource_ResourceHandle_To_v1alpha2_ResourceHandle(in *resource func Convert_resource_ResourceHandle_To_v1alpha2_ResourceHandle(in *resource.ResourceHandle, out *v1alpha2.ResourceHandle, s conversion.Scope) error { return autoConvert_resource_ResourceHandle_To_v1alpha2_ResourceHandle(in, out, s) } + +func autoConvert_v1alpha2_ResourceRequest_To_resource_ResourceRequest(in *v1alpha2.ResourceRequest, out *resource.ResourceRequest, s conversion.Scope) error { + if err := runtime.Convert_runtime_RawExtension_To_runtime_Object(&in.VendorParameters, &out.VendorParameters, s); err != nil { + return err + } + if err := Convert_v1alpha2_ResourceRequestModel_To_resource_ResourceRequestModel(&in.ResourceRequestModel, &out.ResourceRequestModel, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha2_ResourceRequest_To_resource_ResourceRequest is an autogenerated conversion function. +func Convert_v1alpha2_ResourceRequest_To_resource_ResourceRequest(in *v1alpha2.ResourceRequest, out *resource.ResourceRequest, s conversion.Scope) error { + return autoConvert_v1alpha2_ResourceRequest_To_resource_ResourceRequest(in, out, s) +} + +func autoConvert_resource_ResourceRequest_To_v1alpha2_ResourceRequest(in *resource.ResourceRequest, out *v1alpha2.ResourceRequest, s conversion.Scope) error { + if err := runtime.Convert_runtime_Object_To_runtime_RawExtension(&in.VendorParameters, &out.VendorParameters, s); err != nil { + return err + } + if err := Convert_resource_ResourceRequestModel_To_v1alpha2_ResourceRequestModel(&in.ResourceRequestModel, &out.ResourceRequestModel, s); err != nil { + return err + } + return nil +} + +// Convert_resource_ResourceRequest_To_v1alpha2_ResourceRequest is an autogenerated conversion function. +func Convert_resource_ResourceRequest_To_v1alpha2_ResourceRequest(in *resource.ResourceRequest, out *v1alpha2.ResourceRequest, s conversion.Scope) error { + return autoConvert_resource_ResourceRequest_To_v1alpha2_ResourceRequest(in, out, s) +} + +func autoConvert_v1alpha2_ResourceRequestModel_To_resource_ResourceRequestModel(in *v1alpha2.ResourceRequestModel, out *resource.ResourceRequestModel, s conversion.Scope) error { + return nil +} + +// Convert_v1alpha2_ResourceRequestModel_To_resource_ResourceRequestModel is an autogenerated conversion function. +func Convert_v1alpha2_ResourceRequestModel_To_resource_ResourceRequestModel(in *v1alpha2.ResourceRequestModel, out *resource.ResourceRequestModel, s conversion.Scope) error { + return autoConvert_v1alpha2_ResourceRequestModel_To_resource_ResourceRequestModel(in, out, s) +} + +func autoConvert_resource_ResourceRequestModel_To_v1alpha2_ResourceRequestModel(in *resource.ResourceRequestModel, out *v1alpha2.ResourceRequestModel, s conversion.Scope) error { + return nil +} + +// Convert_resource_ResourceRequestModel_To_v1alpha2_ResourceRequestModel is an autogenerated conversion function. +func Convert_resource_ResourceRequestModel_To_v1alpha2_ResourceRequestModel(in *resource.ResourceRequestModel, out *v1alpha2.ResourceRequestModel, s conversion.Scope) error { + return autoConvert_resource_ResourceRequestModel_To_v1alpha2_ResourceRequestModel(in, out, s) +} + +func autoConvert_v1alpha2_StructuredResourceHandle_To_resource_StructuredResourceHandle(in *v1alpha2.StructuredResourceHandle, out *resource.StructuredResourceHandle, s conversion.Scope) error { + if err := runtime.Convert_runtime_RawExtension_To_runtime_Object(&in.VendorClassParameters, &out.VendorClassParameters, s); err != nil { + return err + } + if err := runtime.Convert_runtime_RawExtension_To_runtime_Object(&in.VendorClaimParameters, &out.VendorClaimParameters, s); err != nil { + return err + } + out.NodeName = in.NodeName + if in.Results != nil { + in, out := &in.Results, &out.Results + *out = make([]resource.DriverAllocationResult, len(*in)) + for i := range *in { + if err := Convert_v1alpha2_DriverAllocationResult_To_resource_DriverAllocationResult(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Results = nil + } + return nil +} + +// Convert_v1alpha2_StructuredResourceHandle_To_resource_StructuredResourceHandle is an autogenerated conversion function. +func Convert_v1alpha2_StructuredResourceHandle_To_resource_StructuredResourceHandle(in *v1alpha2.StructuredResourceHandle, out *resource.StructuredResourceHandle, s conversion.Scope) error { + return autoConvert_v1alpha2_StructuredResourceHandle_To_resource_StructuredResourceHandle(in, out, s) +} + +func autoConvert_resource_StructuredResourceHandle_To_v1alpha2_StructuredResourceHandle(in *resource.StructuredResourceHandle, out *v1alpha2.StructuredResourceHandle, s conversion.Scope) error { + if err := runtime.Convert_runtime_Object_To_runtime_RawExtension(&in.VendorClassParameters, &out.VendorClassParameters, s); err != nil { + return err + } + if err := runtime.Convert_runtime_Object_To_runtime_RawExtension(&in.VendorClaimParameters, &out.VendorClaimParameters, s); err != nil { + return err + } + out.NodeName = in.NodeName + if in.Results != nil { + in, out := &in.Results, &out.Results + *out = make([]v1alpha2.DriverAllocationResult, len(*in)) + for i := range *in { + if err := Convert_resource_DriverAllocationResult_To_v1alpha2_DriverAllocationResult(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Results = nil + } + return nil +} + +// Convert_resource_StructuredResourceHandle_To_v1alpha2_StructuredResourceHandle is an autogenerated conversion function. +func Convert_resource_StructuredResourceHandle_To_v1alpha2_StructuredResourceHandle(in *resource.StructuredResourceHandle, out *v1alpha2.StructuredResourceHandle, s conversion.Scope) error { + return autoConvert_resource_StructuredResourceHandle_To_v1alpha2_StructuredResourceHandle(in, out, s) +} + +func autoConvert_v1alpha2_VendorParameters_To_resource_VendorParameters(in *v1alpha2.VendorParameters, out *resource.VendorParameters, s conversion.Scope) error { + out.DriverName = in.DriverName + if err := runtime.Convert_runtime_RawExtension_To_runtime_Object(&in.Parameters, &out.Parameters, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha2_VendorParameters_To_resource_VendorParameters is an autogenerated conversion function. +func Convert_v1alpha2_VendorParameters_To_resource_VendorParameters(in *v1alpha2.VendorParameters, out *resource.VendorParameters, s conversion.Scope) error { + return autoConvert_v1alpha2_VendorParameters_To_resource_VendorParameters(in, out, s) +} + +func autoConvert_resource_VendorParameters_To_v1alpha2_VendorParameters(in *resource.VendorParameters, out *v1alpha2.VendorParameters, s conversion.Scope) error { + out.DriverName = in.DriverName + if err := runtime.Convert_runtime_Object_To_runtime_RawExtension(&in.Parameters, &out.Parameters, s); err != nil { + return err + } + return nil +} + +// Convert_resource_VendorParameters_To_v1alpha2_VendorParameters is an autogenerated conversion function. +func Convert_resource_VendorParameters_To_v1alpha2_VendorParameters(in *resource.VendorParameters, out *v1alpha2.VendorParameters, s conversion.Scope) error { + return autoConvert_resource_VendorParameters_To_v1alpha2_VendorParameters(in, out, s) +} diff --git a/pkg/apis/resource/validation/validation.go b/pkg/apis/resource/validation/validation.go index 17077667393..4e67edbde2f 100644 --- a/pkg/apis/resource/validation/validation.go +++ b/pkg/apis/resource/validation/validation.go @@ -17,6 +17,7 @@ limitations under the License. package validation import ( + apiequality "k8s.io/apimachinery/pkg/api/equality" apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" @@ -41,7 +42,7 @@ func validateResourceClaimSpec(spec *resource.ResourceClaimSpec, fldPath *field. for _, msg := range corevalidation.ValidateClassName(spec.ResourceClassName, false) { allErrs = append(allErrs, field.Invalid(fldPath.Child("resourceClassName"), spec.ResourceClassName, msg)) } - allErrs = append(allErrs, validateResourceClaimParameters(spec.ParametersRef, fldPath.Child("parametersRef"))...) + allErrs = append(allErrs, validateResourceClaimParametersRef(spec.ParametersRef, fldPath.Child("parametersRef"))...) if !supportedAllocationModes.Has(string(spec.AllocationMode)) { allErrs = append(allErrs, field.NotSupported(fldPath.Child("allocationMode"), spec.AllocationMode, supportedAllocationModes.List())) } @@ -54,7 +55,7 @@ var supportedAllocationModes = sets.NewString(string(resource.AllocationModeImme // function for Kind and Name in both types, but generics cannot be used to // access common fields in structs. -func validateResourceClaimParameters(ref *resource.ResourceClaimParametersReference, fldPath *field.Path) field.ErrorList { +func validateResourceClaimParametersRef(ref *resource.ResourceClaimParametersReference, fldPath *field.Path) field.ErrorList { var allErrs field.ErrorList if ref != nil { if ref.Kind == "" { @@ -200,6 +201,12 @@ func validateResourceHandles(resourceHandles []resource.ResourceHandle, maxSize if len(resourceHandle.Data) > resource.ResourceHandleDataMaxSize { allErrs = append(allErrs, field.TooLongMaxLength(idxPath.Child("data"), len(resourceHandle.Data), resource.ResourceHandleDataMaxSize)) } + if resourceHandle.StructuredData != nil { + allErrs = append(allErrs, validateStructuredResourceHandle(resourceHandle.StructuredData, idxPath.Child("structuredData"))...) + } + if len(resourceHandle.Data) > 0 && resourceHandle.StructuredData != nil { + allErrs = append(allErrs, field.Invalid(idxPath, nil, "data and structuredData are mutually exclusive")) + } } if len(resourceHandles) > maxSize { // Dumping the entire field into the error message is likely to be too long, @@ -210,6 +217,37 @@ func validateResourceHandles(resourceHandles []resource.ResourceHandle, maxSize return allErrs } +func validateStructuredResourceHandle(handle *resource.StructuredResourceHandle, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + allErrs = append(allErrs, validateNodeName(handle.NodeName, fldPath.Child("nodeName"))...) + allErrs = append(allErrs, validateDriverAllocationResults(handle.Results, fldPath.Child("results"))...) + return allErrs +} + +func validateDriverAllocationResults(results []resource.DriverAllocationResult, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + for index, result := range results { + idxPath := fldPath.Index(index) + allErrs = append(allErrs, validateAllocationResultModel(&result.AllocationResultModel, idxPath)...) + } + return allErrs +} + +func validateAllocationResultModel(model *resource.AllocationResultModel, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + entries := sets.New[string]() + // TODO: implement one structured parameter model + switch len(entries) { + case 0: + // allErrs = append(allErrs, field.Required(fldPath, "exactly one structured model field must be set")) + case 1: + // Okay. + default: + allErrs = append(allErrs, field.Invalid(fldPath, sets.List(entries), "exactly one field must be set, not several")) + } + return allErrs +} + func validateResourceClaimUserReference(ref resource.ResourceClaimConsumerReference, fldPath *field.Path) field.ErrorList { var allErrs field.ErrorList if ref.Resource == "" { @@ -345,3 +383,170 @@ func validateNodeName(name string, fldPath *field.Path) field.ErrorList { } return allErrs } + +// ValidateNodeResourceSlice tests if a NodeResourceSlice object is valid. +func ValidateNodeResourceSlice(nodeResourceSlice *resource.NodeResourceSlice) field.ErrorList { + allErrs := corevalidation.ValidateObjectMeta(&nodeResourceSlice.ObjectMeta, false, apimachineryvalidation.NameIsDNSSubdomain, field.NewPath("metadata")) + allErrs = append(allErrs, validateNodeName(nodeResourceSlice.NodeName, field.NewPath("nodeName"))...) + allErrs = append(allErrs, validateResourceDriverName(nodeResourceSlice.DriverName, field.NewPath("driverName"))...) + allErrs = append(allErrs, validateNodeResourceModel(&nodeResourceSlice.NodeResourceModel, nil)...) + return allErrs +} + +func validateNodeResourceModel(model *resource.NodeResourceModel, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + entries := sets.New[string]() + // TODO: implement one structured parameter model + switch len(entries) { + case 0: + // allErrs = append(allErrs, field.Required(fldPath, "exactly one structured model field must be set")) + case 1: + // Okay. + default: + allErrs = append(allErrs, field.Invalid(fldPath, sets.List(entries), "exactly one field must be set, not several")) + } + return allErrs +} + +// ValidateNodeResourceSlice tests if a NodeResourceSlice update is valid. +func ValidateNodeResourceSliceUpdate(nodeResourceSlice, oldNodeResourceSlice *resource.NodeResourceSlice) field.ErrorList { + allErrs := corevalidation.ValidateObjectMetaUpdate(&nodeResourceSlice.ObjectMeta, &oldNodeResourceSlice.ObjectMeta, field.NewPath("metadata")) + allErrs = append(allErrs, ValidateNodeResourceSlice(nodeResourceSlice)...) + allErrs = append(allErrs, apimachineryvalidation.ValidateImmutableField(nodeResourceSlice.NodeName, oldNodeResourceSlice.NodeName, field.NewPath("nodeName"))...) + allErrs = append(allErrs, apimachineryvalidation.ValidateImmutableField(nodeResourceSlice.DriverName, oldNodeResourceSlice.DriverName, field.NewPath("driverName"))...) + return allErrs +} + +// ValidateResourceClaimParameters tests if a ResourceClaimParameters object is valid for creation. +func ValidateResourceClaimParameters(parameters *resource.ResourceClaimParameters) field.ErrorList { + return validateResourceClaimParameters(parameters, false) +} + +func validateResourceClaimParameters(parameters *resource.ResourceClaimParameters, requestStored bool) field.ErrorList { + allErrs := corevalidation.ValidateObjectMeta(¶meters.ObjectMeta, true, apimachineryvalidation.NameIsDNSSubdomain, field.NewPath("metadata")) + allErrs = append(allErrs, validateResourceClaimParametersRef(parameters.GeneratedFrom, field.NewPath("generatedFrom"))...) + allErrs = append(allErrs, validateDriverRequests(parameters.DriverRequests, field.NewPath("driverRequests"), requestStored)...) + return allErrs +} + +func validateDriverRequests(requests []resource.DriverRequests, fldPath *field.Path, requestStored bool) field.ErrorList { + var allErrs field.ErrorList + driverNames := sets.New[string]() + for i, request := range requests { + idxPath := fldPath.Index(i) + driverName := request.DriverName + allErrs = append(allErrs, validateResourceDriverName(driverName, idxPath.Child("driverName"))...) + if driverNames.Has(driverName) { + allErrs = append(allErrs, field.Duplicate(idxPath.Child("driverName"), driverName)) + } else { + driverNames.Insert(driverName) + } + allErrs = append(allErrs, validateResourceRequests(request.Requests, idxPath.Child("requests"), requestStored)...) + } + return allErrs +} + +func validateResourceRequests(requests []resource.ResourceRequest, fldPath *field.Path, requestStored bool) field.ErrorList { + var allErrs field.ErrorList + for i, request := range requests { + idxPath := fldPath.Index(i) + allErrs = append(allErrs, validateResourceRequestModel(&request.ResourceRequestModel, idxPath, requestStored)...) + } + if len(requests) == 0 { + // We could allow this, it just doesn't make sense: the entire entry would get ignored and thus + // should have been left out entirely. + allErrs = append(allErrs, field.Required(fldPath, "empty entries with no requests are not allowed")) + } + return allErrs +} + +func validateResourceRequestModel(model *resource.ResourceRequestModel, fldPath *field.Path, requestStored bool) field.ErrorList { + var allErrs field.ErrorList + entries := sets.New[string]() + // TODO: implement one structured parameter model + switch len(entries) { + case 0: + // allErrs = append(allErrs, field.Required(fldPath, "exactly one structured model field must be set")) + case 1: + // Okay. + default: + allErrs = append(allErrs, field.Invalid(fldPath, sets.List(entries), "exactly one field must be set, not several")) + } + return allErrs +} + +// ValidateResourceClaimParameters tests if a ResourceClaimParameters update is valid. +func ValidateResourceClaimParametersUpdate(resourceClaimParameters, oldResourceClaimParameters *resource.ResourceClaimParameters) field.ErrorList { + allErrs := corevalidation.ValidateObjectMetaUpdate(&resourceClaimParameters.ObjectMeta, &oldResourceClaimParameters.ObjectMeta, field.NewPath("metadata")) + requestStored := apiequality.Semantic.DeepEqual(oldResourceClaimParameters.DriverRequests, resourceClaimParameters.DriverRequests) + allErrs = append(allErrs, validateResourceClaimParameters(resourceClaimParameters, requestStored)...) + return allErrs +} + +// ValidateResourceClassParameters tests if a ResourceClassParameters object is valid for creation. +func ValidateResourceClassParameters(parameters *resource.ResourceClassParameters) field.ErrorList { + return validateResourceClassParameters(parameters, false) +} + +func validateResourceClassParameters(parameters *resource.ResourceClassParameters, filtersStored bool) field.ErrorList { + allErrs := corevalidation.ValidateObjectMeta(¶meters.ObjectMeta, true, apimachineryvalidation.NameIsDNSSubdomain, field.NewPath("metadata")) + allErrs = append(allErrs, validateClassParameters(parameters.GeneratedFrom, field.NewPath("generatedFrom"))...) + allErrs = append(allErrs, validateResourceFilters(parameters.Filters, field.NewPath("filters"), filtersStored)...) + allErrs = append(allErrs, validateVendorParameters(parameters.VendorParameters, field.NewPath("vendorParameters"))...) + return allErrs +} + +func validateResourceFilters(filters []resource.ResourceFilter, fldPath *field.Path, filtersStored bool) field.ErrorList { + var allErrs field.ErrorList + driverNames := sets.New[string]() + for i, filter := range filters { + idxPath := fldPath.Index(i) + driverName := filter.DriverName + allErrs = append(allErrs, validateResourceDriverName(driverName, idxPath.Child("driverName"))...) + if driverNames.Has(driverName) { + allErrs = append(allErrs, field.Duplicate(idxPath.Child("driverName"), driverName)) + } else { + driverNames.Insert(driverName) + } + allErrs = append(allErrs, validateResourceFilterModel(&filter.ResourceFilterModel, idxPath, filtersStored)...) + } + return allErrs +} + +func validateResourceFilterModel(model *resource.ResourceFilterModel, fldPath *field.Path, filtersStored bool) field.ErrorList { + var allErrs field.ErrorList + entries := sets.New[string]() + // TODO: implement one structured parameter model + switch len(entries) { + case 0: + // allErrs = append(allErrs, field.Required(fldPath, "exactly one structured model field must be set")) + case 1: + // Okay. + default: + allErrs = append(allErrs, field.Invalid(fldPath, sets.List(entries), "exactly one field must be set, not several")) + } + return allErrs +} + +func validateVendorParameters(parameters []resource.VendorParameters, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + driverNames := sets.New[string]() + for i, parameters := range parameters { + idxPath := fldPath.Index(i) + driverName := parameters.DriverName + allErrs = append(allErrs, validateResourceDriverName(driverName, idxPath.Child("driverName"))...) + if driverNames.Has(driverName) { + allErrs = append(allErrs, field.Duplicate(idxPath.Child("driverName"), driverName)) + } else { + driverNames.Insert(driverName) + } + } + return allErrs +} + +// ValidateResourceClassParameters tests if a ResourceClassParameters update is valid. +func ValidateResourceClassParametersUpdate(resourceClassParameters, oldResourceClassParameters *resource.ResourceClassParameters) field.ErrorList { + allErrs := corevalidation.ValidateObjectMetaUpdate(&resourceClassParameters.ObjectMeta, &oldResourceClassParameters.ObjectMeta, field.NewPath("metadata")) + allErrs = append(allErrs, ValidateResourceClassParameters(resourceClassParameters)...) + return allErrs +} diff --git a/pkg/apis/resource/validation/validation_noderesourceslice_test.go b/pkg/apis/resource/validation/validation_noderesourceslice_test.go new file mode 100644 index 00000000000..c10cbdf01a9 --- /dev/null +++ b/pkg/apis/resource/validation/validation_noderesourceslice_test.go @@ -0,0 +1,256 @@ +/* +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 validation + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/kubernetes/pkg/apis/resource" + "k8s.io/utils/ptr" +) + +func testNodeResourceSlice(name, nodeName, driverName string) *resource.NodeResourceSlice { + return &resource.NodeResourceSlice{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + NodeName: nodeName, + DriverName: driverName, + NodeResourceModel: resource.NodeResourceModel{ + // TODO: implement one structured parameter model + }, + } +} + +func TestValidateNodeResourceSlice(t *testing.T) { + goodName := "foo" + badName := "!@#$%^" + driverName := "test.example.com" + now := metav1.Now() + badValue := "spaces not allowed" + + scenarios := map[string]struct { + slice *resource.NodeResourceSlice + wantFailures field.ErrorList + }{ + "good": { + slice: testNodeResourceSlice(goodName, goodName, driverName), + }, + "missing-name": { + wantFailures: field.ErrorList{field.Required(field.NewPath("metadata", "name"), "name or generateName is required")}, + slice: testNodeResourceSlice("", goodName, driverName), + }, + "bad-name": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("metadata", "name"), badName, "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')")}, + slice: testNodeResourceSlice(badName, goodName, driverName), + }, + "generate-name": { + slice: func() *resource.NodeResourceSlice { + slice := testNodeResourceSlice(goodName, goodName, driverName) + slice.GenerateName = "prefix-" + return slice + }(), + }, + "uid": { + slice: func() *resource.NodeResourceSlice { + slice := testNodeResourceSlice(goodName, goodName, driverName) + slice.UID = "ac051fac-2ead-46d9-b8b4-4e0fbeb7455d" + return slice + }(), + }, + "resource-version": { + slice: func() *resource.NodeResourceSlice { + slice := testNodeResourceSlice(goodName, goodName, driverName) + slice.ResourceVersion = "1" + return slice + }(), + }, + "generation": { + slice: func() *resource.NodeResourceSlice { + slice := testNodeResourceSlice(goodName, goodName, driverName) + slice.Generation = 100 + return slice + }(), + }, + "creation-timestamp": { + slice: func() *resource.NodeResourceSlice { + slice := testNodeResourceSlice(goodName, goodName, driverName) + slice.CreationTimestamp = now + return slice + }(), + }, + "deletion-grace-period-seconds": { + slice: func() *resource.NodeResourceSlice { + slice := testNodeResourceSlice(goodName, goodName, driverName) + slice.DeletionGracePeriodSeconds = ptr.To[int64](10) + return slice + }(), + }, + "owner-references": { + slice: func() *resource.NodeResourceSlice { + slice := testNodeResourceSlice(goodName, goodName, driverName) + slice.OwnerReferences = []metav1.OwnerReference{ + { + APIVersion: "v1", + Kind: "pod", + Name: "foo", + UID: "ac051fac-2ead-46d9-b8b4-4e0fbeb7455d", + }, + } + return slice + }(), + }, + "finalizers": { + slice: func() *resource.NodeResourceSlice { + slice := testNodeResourceSlice(goodName, goodName, driverName) + slice.Finalizers = []string{ + "example.com/foo", + } + return slice + }(), + }, + "managed-fields": { + slice: func() *resource.NodeResourceSlice { + slice := testNodeResourceSlice(goodName, goodName, driverName) + slice.ManagedFields = []metav1.ManagedFieldsEntry{ + { + FieldsType: "FieldsV1", + Operation: "Apply", + APIVersion: "apps/v1", + Manager: "foo", + }, + } + return slice + }(), + }, + "good-labels": { + slice: func() *resource.NodeResourceSlice { + slice := testNodeResourceSlice(goodName, goodName, driverName) + slice.Labels = map[string]string{ + "apps.kubernetes.io/name": "test", + } + return slice + }(), + }, + "bad-labels": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("metadata", "labels"), badValue, "a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyValue', or 'my_value', or '12345', regex used for validation is '(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?')")}, + slice: func() *resource.NodeResourceSlice { + slice := testNodeResourceSlice(goodName, goodName, driverName) + slice.Labels = map[string]string{ + "hello-world": badValue, + } + return slice + }(), + }, + "good-annotations": { + slice: func() *resource.NodeResourceSlice { + slice := testNodeResourceSlice(goodName, goodName, driverName) + slice.Annotations = map[string]string{ + "foo": "bar", + } + return slice + }(), + }, + "bad-annotations": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("metadata", "annotations"), badName, "name part must consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')")}, + slice: func() *resource.NodeResourceSlice { + slice := testNodeResourceSlice(goodName, goodName, driverName) + slice.Annotations = map[string]string{ + badName: "hello world", + } + return slice + }(), + }, + "bad-nodename": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("nodeName"), badName, "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')")}, + slice: testNodeResourceSlice(goodName, badName, driverName), + }, + "bad-drivername": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("driverName"), badName, "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')")}, + slice: testNodeResourceSlice(goodName, goodName, badName), + }, + + // TODO: implement one structured parameter model + // "empty-model": { + // wantFailures: field.ErrorList{field.Required(nil, "exactly one structured model field must be set")}, + // slice: func() *resource.NodeResourceSlice { + // slice := testNodeResourceSlice(goodName, goodName, driverName) + // slice.NodeResourceModel = resource.NodeResourceModel{} + // return slice + // }(), + // }, + } + + for name, scenario := range scenarios { + t.Run(name, func(t *testing.T) { + errs := ValidateNodeResourceSlice(scenario.slice) + assert.Equal(t, scenario.wantFailures, errs) + }) + } +} + +func TestValidateNodeResourceSliceUpdate(t *testing.T) { + name := "valid" + validNodeResourceSlice := testNodeResourceSlice(name, name, name) + + scenarios := map[string]struct { + oldNodeResourceSlice *resource.NodeResourceSlice + update func(slice *resource.NodeResourceSlice) *resource.NodeResourceSlice + wantFailures field.ErrorList + }{ + "valid-no-op-update": { + oldNodeResourceSlice: validNodeResourceSlice, + update: func(slice *resource.NodeResourceSlice) *resource.NodeResourceSlice { return slice }, + }, + "invalid-name-update": { + oldNodeResourceSlice: validNodeResourceSlice, + update: func(slice *resource.NodeResourceSlice) *resource.NodeResourceSlice { + slice.Name += "-update" + return slice + }, + wantFailures: field.ErrorList{field.Invalid(field.NewPath("metadata", "name"), name+"-update", "field is immutable")}, + }, + "invalid-update-nodename": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("nodeName"), name+"-updated", "field is immutable")}, + oldNodeResourceSlice: validNodeResourceSlice, + update: func(slice *resource.NodeResourceSlice) *resource.NodeResourceSlice { + slice.NodeName += "-updated" + return slice + }, + }, + "invalid-update-drivername": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("driverName"), name+"-updated", "field is immutable")}, + oldNodeResourceSlice: validNodeResourceSlice, + update: func(slice *resource.NodeResourceSlice) *resource.NodeResourceSlice { + slice.DriverName += "-updated" + return slice + }, + }, + } + + for name, scenario := range scenarios { + t.Run(name, func(t *testing.T) { + scenario.oldNodeResourceSlice.ResourceVersion = "1" + errs := ValidateNodeResourceSliceUpdate(scenario.update(scenario.oldNodeResourceSlice.DeepCopy()), scenario.oldNodeResourceSlice) + assert.Equal(t, scenario.wantFailures, errs) + }) + } +} diff --git a/pkg/apis/resource/validation/validation_resourceclaim_test.go b/pkg/apis/resource/validation/validation_resourceclaim_test.go index 962336e3a5d..956377cdbda 100644 --- a/pkg/apis/resource/validation/validation_resourceclaim_test.go +++ b/pkg/apis/resource/validation/validation_resourceclaim_test.go @@ -380,6 +380,81 @@ func TestValidateClaimStatusUpdate(t *testing.T) { return claim }, }, + "valid-add-empty-allocation-structured": { + oldClaim: validClaim, + update: func(claim *resource.ResourceClaim) *resource.ResourceClaim { + claim.Status.DriverName = "valid" + claim.Status.Allocation = &resource.AllocationResult{ + ResourceHandles: []resource.ResourceHandle{ + { + DriverName: "valid", + StructuredData: &resource.StructuredResourceHandle{ + NodeName: "worker", + }, + }, + }, + } + return claim + }, + }, + "invalid-add-allocation-structured": { + wantFailures: field.ErrorList{ + field.Invalid(field.NewPath("status", "allocation", "resourceHandles").Index(0).Child("structuredData", "nodeName"), "", "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')"), + }, + oldClaim: validClaim, + update: func(claim *resource.ResourceClaim) *resource.ResourceClaim { + claim.Status.DriverName = "valid" + claim.Status.Allocation = &resource.AllocationResult{ + ResourceHandles: []resource.ResourceHandle{ + { + DriverName: "valid", + StructuredData: &resource.StructuredResourceHandle{ + Results: []resource.DriverAllocationResult{ + // TODO: empty AllocationResultMode + }, + }, + }, + }, + } + return claim + }, + }, + "valid-add-allocation-structured": { + oldClaim: validClaim, + update: func(claim *resource.ResourceClaim) *resource.ResourceClaim { + claim.Status.DriverName = "valid" + claim.Status.Allocation = &resource.AllocationResult{ + ResourceHandles: []resource.ResourceHandle{ + { + DriverName: "valid", + StructuredData: &resource.StructuredResourceHandle{ + NodeName: "worker", + }, + }, + }, + } + return claim + }, + }, + "invalid-duplicated-data": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("status", "allocation", "resourceHandles").Index(0), nil, "data and structuredData are mutually exclusive")}, + oldClaim: validClaim, + update: func(claim *resource.ResourceClaim) *resource.ResourceClaim { + claim.Status.DriverName = "valid" + claim.Status.Allocation = &resource.AllocationResult{ + ResourceHandles: []resource.ResourceHandle{ + { + DriverName: "valid", + Data: "something", + StructuredData: &resource.StructuredResourceHandle{ + NodeName: "worker", + }, + }, + }, + } + return claim + }, + }, "invalid-allocation-resourceHandles": { wantFailures: field.ErrorList{field.TooLongMaxLength(field.NewPath("status", "allocation", "resourceHandles"), resource.AllocationResultResourceHandlesMaxSize+1, resource.AllocationResultResourceHandlesMaxSize)}, oldClaim: validClaim, @@ -413,7 +488,7 @@ func TestValidateClaimStatusUpdate(t *testing.T) { }, }, "invalid-allocation-resource-handle-data": { - wantFailures: field.ErrorList{field.TooLongMaxLength(field.NewPath("status", "allocation", "resourceHandles[0]", "data"), resource.ResourceHandleDataMaxSize+1, resource.ResourceHandleDataMaxSize)}, + wantFailures: field.ErrorList{field.TooLongMaxLength(field.NewPath("status", "allocation", "resourceHandles").Index(0).Child("data"), resource.ResourceHandleDataMaxSize+1, resource.ResourceHandleDataMaxSize)}, oldClaim: validClaim, update: func(claim *resource.ResourceClaim) *resource.ResourceClaim { claim.Status.DriverName = "valid" diff --git a/pkg/apis/resource/validation/validation_resourceclaimparameters_test.go b/pkg/apis/resource/validation/validation_resourceclaimparameters_test.go new file mode 100644 index 00000000000..d38e1246626 --- /dev/null +++ b/pkg/apis/resource/validation/validation_resourceclaimparameters_test.go @@ -0,0 +1,308 @@ +/* +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 validation + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/kubernetes/pkg/apis/resource" + "k8s.io/utils/ptr" +) + +func testResourceClaimParameters(name, namespace string, requests []resource.DriverRequests) *resource.ResourceClaimParameters { + return &resource.ResourceClaimParameters{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + DriverRequests: requests, + } +} + +var goodRequests []resource.DriverRequests + +func TestValidateResourceClaimParameters(t *testing.T) { + goodName := "foo" + badName := "!@#$%^" + badValue := "spaces not allowed" + now := metav1.Now() + + scenarios := map[string]struct { + parameters *resource.ResourceClaimParameters + wantFailures field.ErrorList + }{ + "good": { + parameters: testResourceClaimParameters(goodName, goodName, goodRequests), + }, + "missing-name": { + wantFailures: field.ErrorList{field.Required(field.NewPath("metadata", "name"), "name or generateName is required")}, + parameters: testResourceClaimParameters("", goodName, goodRequests), + }, + "missing-namespace": { + wantFailures: field.ErrorList{field.Required(field.NewPath("metadata", "namespace"), "")}, + parameters: testResourceClaimParameters(goodName, "", goodRequests), + }, + "bad-name": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("metadata", "name"), badName, "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')")}, + parameters: testResourceClaimParameters(badName, goodName, goodRequests), + }, + "bad-namespace": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("metadata", "namespace"), badName, "a lowercase RFC 1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')")}, + parameters: testResourceClaimParameters(goodName, badName, goodRequests), + }, + "generate-name": { + parameters: func() *resource.ResourceClaimParameters { + parameters := testResourceClaimParameters(goodName, goodName, goodRequests) + parameters.GenerateName = "prefix-" + return parameters + }(), + }, + "uid": { + parameters: func() *resource.ResourceClaimParameters { + parameters := testResourceClaimParameters(goodName, goodName, goodRequests) + parameters.UID = "ac051fac-2ead-46d9-b8b4-4e0fbeb7455d" + return parameters + }(), + }, + "resource-version": { + parameters: func() *resource.ResourceClaimParameters { + parameters := testResourceClaimParameters(goodName, goodName, goodRequests) + parameters.ResourceVersion = "1" + return parameters + }(), + }, + "generation": { + parameters: func() *resource.ResourceClaimParameters { + parameters := testResourceClaimParameters(goodName, goodName, goodRequests) + parameters.Generation = 100 + return parameters + }(), + }, + "creation-timestamp": { + parameters: func() *resource.ResourceClaimParameters { + parameters := testResourceClaimParameters(goodName, goodName, goodRequests) + parameters.CreationTimestamp = now + return parameters + }(), + }, + "deletion-grace-period-seconds": { + parameters: func() *resource.ResourceClaimParameters { + parameters := testResourceClaimParameters(goodName, goodName, goodRequests) + parameters.DeletionGracePeriodSeconds = ptr.To[int64](10) + return parameters + }(), + }, + "owner-references": { + parameters: func() *resource.ResourceClaimParameters { + parameters := testResourceClaimParameters(goodName, goodName, goodRequests) + parameters.OwnerReferences = []metav1.OwnerReference{ + { + APIVersion: "v1", + Kind: "pod", + Name: "foo", + UID: "ac051fac-2ead-46d9-b8b4-4e0fbeb7455d", + }, + } + return parameters + }(), + }, + "finalizers": { + parameters: func() *resource.ResourceClaimParameters { + parameters := testResourceClaimParameters(goodName, goodName, goodRequests) + parameters.Finalizers = []string{ + "example.com/foo", + } + return parameters + }(), + }, + "managed-fields": { + parameters: func() *resource.ResourceClaimParameters { + parameters := testResourceClaimParameters(goodName, goodName, goodRequests) + parameters.ManagedFields = []metav1.ManagedFieldsEntry{ + { + FieldsType: "FieldsV1", + Operation: "Apply", + APIVersion: "apps/v1", + Manager: "foo", + }, + } + return parameters + }(), + }, + "good-labels": { + parameters: func() *resource.ResourceClaimParameters { + parameters := testResourceClaimParameters(goodName, goodName, goodRequests) + parameters.Labels = map[string]string{ + "apps.kubernetes.io/name": "test", + } + return parameters + }(), + }, + "bad-labels": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("metadata", "labels"), badValue, "a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyValue', or 'my_value', or '12345', regex used for validation is '(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?')")}, + parameters: func() *resource.ResourceClaimParameters { + parameters := testResourceClaimParameters(goodName, goodName, goodRequests) + parameters.Labels = map[string]string{ + "hello-world": badValue, + } + return parameters + }(), + }, + "good-annotations": { + parameters: func() *resource.ResourceClaimParameters { + parameters := testResourceClaimParameters(goodName, goodName, goodRequests) + parameters.Annotations = map[string]string{ + "foo": "bar", + } + return parameters + }(), + }, + "bad-annotations": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("metadata", "annotations"), badName, "name part must consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')")}, + parameters: func() *resource.ResourceClaimParameters { + parameters := testResourceClaimParameters(goodName, goodName, goodRequests) + parameters.Annotations = map[string]string{ + badName: "hello world", + } + return parameters + }(), + }, + + // TODO: implement one structured parameter model + // "empty-model": { + // wantFailures: field.ErrorList{field.Required(field.NewPath("driverRequests").Index(0).Child("requests").Index(0), "exactly one structured model field must be set")}, + // parameters: func() *resource.ResourceClaimParameters { + // parameters := testResourceClaimParameters(goodName, goodName, goodRequests) + // parameters.DriverRequests = []resource.DriverRequests{{DriverName: goodName, Requests: []resource.ResourceRequest{{}}}} + // return parameters + // }(), + // }, + + "empty-requests": { + wantFailures: field.ErrorList{field.Required(field.NewPath("driverRequests").Index(0).Child("requests"), "empty entries with no requests are not allowed")}, + parameters: func() *resource.ResourceClaimParameters { + parameters := testResourceClaimParameters(goodName, goodName, goodRequests) + parameters.DriverRequests = []resource.DriverRequests{{DriverName: goodName}} + return parameters + }(), + }, + + "invalid-driver": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("driverRequests").Index(1).Child("driverName"), badName, "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')")}, + parameters: func() *resource.ResourceClaimParameters { + parameters := testResourceClaimParameters(goodName, goodName, goodRequests) + parameters.DriverRequests = []resource.DriverRequests{ + { + DriverName: goodName, + Requests: []resource.ResourceRequest{ + { + ResourceRequestModel: resource.ResourceRequestModel{ + // TODO: implement one structured parameter model + }, + }, + }, + }, + { + DriverName: badName, + Requests: []resource.ResourceRequest{ + { + ResourceRequestModel: resource.ResourceRequestModel{ + // TODO: implement one structured parameter model + }, + }, + }, + }, + } + return parameters + }(), + }, + + "duplicate-driver": { + wantFailures: field.ErrorList{field.Duplicate(field.NewPath("driverRequests").Index(1).Child("driverName"), goodName)}, + parameters: func() *resource.ResourceClaimParameters { + parameters := testResourceClaimParameters(goodName, goodName, goodRequests) + parameters.DriverRequests = []resource.DriverRequests{ + { + DriverName: goodName, + Requests: []resource.ResourceRequest{ + { + ResourceRequestModel: resource.ResourceRequestModel{ + // TODO: implement one structured parameter model + + }, + }, + }, + }, + { + DriverName: goodName, + Requests: []resource.ResourceRequest{ + { + ResourceRequestModel: resource.ResourceRequestModel{ + // TODO: implement one structured parameter model + }, + }, + }, + }, + } + return parameters + }(), + }, + } + + for name, scenario := range scenarios { + t.Run(name, func(t *testing.T) { + errs := ValidateResourceClaimParameters(scenario.parameters) + assert.Equal(t, scenario.wantFailures, errs) + }) + } +} + +func TestValidateResourceClaimParametersUpdate(t *testing.T) { + name := "valid" + validResourceClaimParameters := testResourceClaimParameters(name, name, nil) + + scenarios := map[string]struct { + oldResourceClaimParameters *resource.ResourceClaimParameters + update func(claim *resource.ResourceClaimParameters) *resource.ResourceClaimParameters + wantFailures field.ErrorList + }{ + "valid-no-op-update": { + oldResourceClaimParameters: validResourceClaimParameters, + update: func(claim *resource.ResourceClaimParameters) *resource.ResourceClaimParameters { return claim }, + }, + "invalid-name-update": { + oldResourceClaimParameters: validResourceClaimParameters, + update: func(claim *resource.ResourceClaimParameters) *resource.ResourceClaimParameters { + claim.Name += "-update" + return claim + }, + wantFailures: field.ErrorList{field.Invalid(field.NewPath("metadata", "name"), name+"-update", "field is immutable")}, + }, + } + + for name, scenario := range scenarios { + t.Run(name, func(t *testing.T) { + scenario.oldResourceClaimParameters.ResourceVersion = "1" + errs := ValidateResourceClaimParametersUpdate(scenario.update(scenario.oldResourceClaimParameters.DeepCopy()), scenario.oldResourceClaimParameters) + assert.Equal(t, scenario.wantFailures, errs) + }) + } +} diff --git a/pkg/apis/resource/validation/validation_resourceclassparameters_test.go b/pkg/apis/resource/validation/validation_resourceclassparameters_test.go new file mode 100644 index 00000000000..c828196f865 --- /dev/null +++ b/pkg/apis/resource/validation/validation_resourceclassparameters_test.go @@ -0,0 +1,312 @@ +/* +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 validation + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/kubernetes/pkg/apis/resource" + "k8s.io/utils/ptr" +) + +func testResourceClassParameters(name, namespace string, filters []resource.ResourceFilter) *resource.ResourceClassParameters { + return &resource.ResourceClassParameters{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Filters: filters, + } +} + +var goodFilters []resource.ResourceFilter + +func TestValidateResourceClassParameters(t *testing.T) { + goodName := "foo" + badName := "!@#$%^" + badValue := "spaces not allowed" + now := metav1.Now() + + scenarios := map[string]struct { + parameters *resource.ResourceClassParameters + wantFailures field.ErrorList + }{ + "good": { + parameters: testResourceClassParameters(goodName, goodName, goodFilters), + }, + "missing-name": { + wantFailures: field.ErrorList{field.Required(field.NewPath("metadata", "name"), "name or generateName is required")}, + parameters: testResourceClassParameters("", goodName, goodFilters), + }, + "missing-namespace": { + wantFailures: field.ErrorList{field.Required(field.NewPath("metadata", "namespace"), "")}, + parameters: testResourceClassParameters(goodName, "", goodFilters), + }, + "bad-name": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("metadata", "name"), badName, "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')")}, + parameters: testResourceClassParameters(badName, goodName, goodFilters), + }, + "bad-namespace": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("metadata", "namespace"), badName, "a lowercase RFC 1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')")}, + parameters: testResourceClassParameters(goodName, badName, goodFilters), + }, + "generate-name": { + parameters: func() *resource.ResourceClassParameters { + parameters := testResourceClassParameters(goodName, goodName, goodFilters) + parameters.GenerateName = "prefix-" + return parameters + }(), + }, + "uid": { + parameters: func() *resource.ResourceClassParameters { + parameters := testResourceClassParameters(goodName, goodName, goodFilters) + parameters.UID = "ac051fac-2ead-46d9-b8b4-4e0fbeb7455d" + return parameters + }(), + }, + "resource-version": { + parameters: func() *resource.ResourceClassParameters { + parameters := testResourceClassParameters(goodName, goodName, goodFilters) + parameters.ResourceVersion = "1" + return parameters + }(), + }, + "generation": { + parameters: func() *resource.ResourceClassParameters { + parameters := testResourceClassParameters(goodName, goodName, goodFilters) + parameters.Generation = 100 + return parameters + }(), + }, + "creation-timestamp": { + parameters: func() *resource.ResourceClassParameters { + parameters := testResourceClassParameters(goodName, goodName, goodFilters) + parameters.CreationTimestamp = now + return parameters + }(), + }, + "deletion-grace-period-seconds": { + parameters: func() *resource.ResourceClassParameters { + parameters := testResourceClassParameters(goodName, goodName, goodFilters) + parameters.DeletionGracePeriodSeconds = ptr.To[int64](10) + return parameters + }(), + }, + "owner-references": { + parameters: func() *resource.ResourceClassParameters { + parameters := testResourceClassParameters(goodName, goodName, goodFilters) + parameters.OwnerReferences = []metav1.OwnerReference{ + { + APIVersion: "v1", + Kind: "pod", + Name: "foo", + UID: "ac051fac-2ead-46d9-b8b4-4e0fbeb7455d", + }, + } + return parameters + }(), + }, + "finalizers": { + parameters: func() *resource.ResourceClassParameters { + parameters := testResourceClassParameters(goodName, goodName, goodFilters) + parameters.Finalizers = []string{ + "example.com/foo", + } + return parameters + }(), + }, + "managed-fields": { + parameters: func() *resource.ResourceClassParameters { + parameters := testResourceClassParameters(goodName, goodName, goodFilters) + parameters.ManagedFields = []metav1.ManagedFieldsEntry{ + { + FieldsType: "FieldsV1", + Operation: "Apply", + APIVersion: "apps/v1", + Manager: "foo", + }, + } + return parameters + }(), + }, + "good-labels": { + parameters: func() *resource.ResourceClassParameters { + parameters := testResourceClassParameters(goodName, goodName, goodFilters) + parameters.Labels = map[string]string{ + "apps.kubernetes.io/name": "test", + } + return parameters + }(), + }, + "bad-labels": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("metadata", "labels"), badValue, "a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyValue', or 'my_value', or '12345', regex used for validation is '(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?')")}, + parameters: func() *resource.ResourceClassParameters { + parameters := testResourceClassParameters(goodName, goodName, goodFilters) + parameters.Labels = map[string]string{ + "hello-world": badValue, + } + return parameters + }(), + }, + "good-annotations": { + parameters: func() *resource.ResourceClassParameters { + parameters := testResourceClassParameters(goodName, goodName, goodFilters) + parameters.Annotations = map[string]string{ + "foo": "bar", + } + return parameters + }(), + }, + "bad-annotations": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("metadata", "annotations"), badName, "name part must consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')")}, + parameters: func() *resource.ResourceClassParameters { + parameters := testResourceClassParameters(goodName, goodName, goodFilters) + parameters.Annotations = map[string]string{ + badName: "hello world", + } + return parameters + }(), + }, + + // TODO: implement one structured parameter model + // "empty-model": { + // wantFailures: field.ErrorList{field.Required(field.NewPath("filters").Index(0), "exactly one structured model field must be set")}, + // parameters: func() *resource.ResourceClassParameters { + // parameters := testResourceClassParameters(goodName, goodName, goodFilters) + // parameters.Filters = []resource.ResourceFilter{{DriverName: goodName}} + // return parameters + // }(), + // }, + + "filters-invalid-driver": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("filters").Index(1).Child("driverName"), badName, "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')")}, + parameters: func() *resource.ResourceClassParameters { + parameters := testResourceClassParameters(goodName, goodName, goodFilters) + parameters.Filters = []resource.ResourceFilter{ + { + DriverName: goodName, + ResourceFilterModel: resource.ResourceFilterModel{ + // TODO: implement one structured parameter model + }, + }, + { + DriverName: badName, + ResourceFilterModel: resource.ResourceFilterModel{ + // TODO: implement one structured parameter model + }, + }, + } + return parameters + }(), + }, + + "filters-duplicate-driver": { + wantFailures: field.ErrorList{field.Duplicate(field.NewPath("filters").Index(1).Child("driverName"), goodName)}, + parameters: func() *resource.ResourceClassParameters { + parameters := testResourceClassParameters(goodName, goodName, goodFilters) + parameters.Filters = []resource.ResourceFilter{ + { + DriverName: goodName, + ResourceFilterModel: resource.ResourceFilterModel{ + // TODO: implement one structured parameter model + }, + }, + { + DriverName: goodName, + ResourceFilterModel: resource.ResourceFilterModel{}, + }, + } + return parameters + }(), + }, + + "parameters-invalid-driver": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("vendorParameters").Index(1).Child("driverName"), badName, "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')")}, + parameters: func() *resource.ResourceClassParameters { + parameters := testResourceClassParameters(goodName, goodName, goodFilters) + parameters.VendorParameters = []resource.VendorParameters{ + { + DriverName: goodName, + }, + { + DriverName: badName, + }, + } + return parameters + }(), + }, + + "parameters-duplicate-driver": { + wantFailures: field.ErrorList{field.Duplicate(field.NewPath("vendorParameters").Index(1).Child("driverName"), goodName)}, + parameters: func() *resource.ResourceClassParameters { + parameters := testResourceClassParameters(goodName, goodName, goodFilters) + parameters.VendorParameters = []resource.VendorParameters{ + { + DriverName: goodName, + }, + { + DriverName: goodName, + }, + } + return parameters + }(), + }, + } + + for name, scenario := range scenarios { + t.Run(name, func(t *testing.T) { + errs := ValidateResourceClassParameters(scenario.parameters) + assert.Equal(t, scenario.wantFailures, errs) + }) + } +} + +func TestValidateResourceClassParametersUpdate(t *testing.T) { + name := "valid" + validResourceClassParameters := testResourceClassParameters(name, name, nil) + + scenarios := map[string]struct { + oldResourceClassParameters *resource.ResourceClassParameters + update func(class *resource.ResourceClassParameters) *resource.ResourceClassParameters + wantFailures field.ErrorList + }{ + "valid-no-op-update": { + oldResourceClassParameters: validResourceClassParameters, + update: func(class *resource.ResourceClassParameters) *resource.ResourceClassParameters { return class }, + }, + "invalid-name-update": { + oldResourceClassParameters: validResourceClassParameters, + update: func(class *resource.ResourceClassParameters) *resource.ResourceClassParameters { + class.Name += "-update" + return class + }, + wantFailures: field.ErrorList{field.Invalid(field.NewPath("metadata", "name"), name+"-update", "field is immutable")}, + }, + } + + for name, scenario := range scenarios { + t.Run(name, func(t *testing.T) { + scenario.oldResourceClassParameters.ResourceVersion = "1" + errs := ValidateResourceClassParametersUpdate(scenario.update(scenario.oldResourceClassParameters.DeepCopy()), scenario.oldResourceClassParameters) + assert.Equal(t, scenario.wantFailures, errs) + }) + } +} diff --git a/pkg/apis/resource/zz_generated.deepcopy.go b/pkg/apis/resource/zz_generated.deepcopy.go index e50a188b5f2..24114076648 100644 --- a/pkg/apis/resource/zz_generated.deepcopy.go +++ b/pkg/apis/resource/zz_generated.deepcopy.go @@ -32,7 +32,9 @@ func (in *AllocationResult) DeepCopyInto(out *AllocationResult) { if in.ResourceHandles != nil { in, out := &in.ResourceHandles, &out.ResourceHandles *out = make([]ResourceHandle, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } if in.AvailableOnNodes != nil { in, out := &in.AvailableOnNodes, &out.AvailableOnNodes @@ -52,6 +54,144 @@ func (in *AllocationResult) DeepCopy() *AllocationResult { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AllocationResultModel) DeepCopyInto(out *AllocationResultModel) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AllocationResultModel. +func (in *AllocationResultModel) DeepCopy() *AllocationResultModel { + if in == nil { + return nil + } + out := new(AllocationResultModel) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DriverAllocationResult) DeepCopyInto(out *DriverAllocationResult) { + *out = *in + if in.VendorRequestParameters != nil { + out.VendorRequestParameters = in.VendorRequestParameters.DeepCopyObject() + } + out.AllocationResultModel = in.AllocationResultModel + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DriverAllocationResult. +func (in *DriverAllocationResult) DeepCopy() *DriverAllocationResult { + if in == nil { + return nil + } + out := new(DriverAllocationResult) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DriverRequests) DeepCopyInto(out *DriverRequests) { + *out = *in + if in.VendorParameters != nil { + out.VendorParameters = in.VendorParameters.DeepCopyObject() + } + if in.Requests != nil { + in, out := &in.Requests, &out.Requests + *out = make([]ResourceRequest, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DriverRequests. +func (in *DriverRequests) DeepCopy() *DriverRequests { + if in == nil { + return nil + } + out := new(DriverRequests) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeResourceModel) DeepCopyInto(out *NodeResourceModel) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeResourceModel. +func (in *NodeResourceModel) DeepCopy() *NodeResourceModel { + if in == nil { + return nil + } + out := new(NodeResourceModel) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeResourceSlice) DeepCopyInto(out *NodeResourceSlice) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.NodeResourceModel = in.NodeResourceModel + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeResourceSlice. +func (in *NodeResourceSlice) DeepCopy() *NodeResourceSlice { + if in == nil { + return nil + } + out := new(NodeResourceSlice) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NodeResourceSlice) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeResourceSliceList) DeepCopyInto(out *NodeResourceSliceList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]NodeResourceSlice, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeResourceSliceList. +func (in *NodeResourceSliceList) DeepCopy() *NodeResourceSliceList { + if in == nil { + return nil + } + out := new(NodeResourceSliceList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NodeResourceSliceList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PodSchedulingContext) DeepCopyInto(out *PodSchedulingContext) { *out = *in @@ -234,6 +374,77 @@ func (in *ResourceClaimList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClaimParameters) DeepCopyInto(out *ResourceClaimParameters) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.GeneratedFrom != nil { + in, out := &in.GeneratedFrom, &out.GeneratedFrom + *out = new(ResourceClaimParametersReference) + **out = **in + } + if in.DriverRequests != nil { + in, out := &in.DriverRequests, &out.DriverRequests + *out = make([]DriverRequests, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClaimParameters. +func (in *ResourceClaimParameters) DeepCopy() *ResourceClaimParameters { + if in == nil { + return nil + } + out := new(ResourceClaimParameters) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ResourceClaimParameters) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClaimParametersList) DeepCopyInto(out *ResourceClaimParametersList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ResourceClaimParameters, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClaimParametersList. +func (in *ResourceClaimParametersList) DeepCopy() *ResourceClaimParametersList { + if in == nil { + return nil + } + out := new(ResourceClaimParametersList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ResourceClaimParametersList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ResourceClaimParametersReference) DeepCopyInto(out *ResourceClaimParametersReference) { *out = *in @@ -411,6 +622,11 @@ func (in *ResourceClass) DeepCopyInto(out *ResourceClass) { *out = new(core.NodeSelector) (*in).DeepCopyInto(*out) } + if in.StructuredParameters != nil { + in, out := &in.StructuredParameters, &out.StructuredParameters + *out = new(bool) + **out = **in + } return } @@ -465,6 +681,82 @@ func (in *ResourceClassList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClassParameters) DeepCopyInto(out *ResourceClassParameters) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.GeneratedFrom != nil { + in, out := &in.GeneratedFrom, &out.GeneratedFrom + *out = new(ResourceClassParametersReference) + **out = **in + } + if in.VendorParameters != nil { + in, out := &in.VendorParameters, &out.VendorParameters + *out = make([]VendorParameters, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Filters != nil { + in, out := &in.Filters, &out.Filters + *out = make([]ResourceFilter, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClassParameters. +func (in *ResourceClassParameters) DeepCopy() *ResourceClassParameters { + if in == nil { + return nil + } + out := new(ResourceClassParameters) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ResourceClassParameters) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClassParametersList) DeepCopyInto(out *ResourceClassParametersList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ResourceClassParameters, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClassParametersList. +func (in *ResourceClassParametersList) DeepCopy() *ResourceClassParametersList { + if in == nil { + return nil + } + out := new(ResourceClassParametersList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ResourceClassParametersList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ResourceClassParametersReference) DeepCopyInto(out *ResourceClassParametersReference) { *out = *in @@ -481,9 +773,47 @@ func (in *ResourceClassParametersReference) DeepCopy() *ResourceClassParametersR return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceFilter) DeepCopyInto(out *ResourceFilter) { + *out = *in + out.ResourceFilterModel = in.ResourceFilterModel + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceFilter. +func (in *ResourceFilter) DeepCopy() *ResourceFilter { + if in == nil { + return nil + } + out := new(ResourceFilter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceFilterModel) DeepCopyInto(out *ResourceFilterModel) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceFilterModel. +func (in *ResourceFilterModel) DeepCopy() *ResourceFilterModel { + if in == nil { + return nil + } + out := new(ResourceFilterModel) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ResourceHandle) DeepCopyInto(out *ResourceHandle) { *out = *in + if in.StructuredData != nil { + in, out := &in.StructuredData, &out.StructuredData + *out = new(StructuredResourceHandle) + (*in).DeepCopyInto(*out) + } return } @@ -496,3 +826,87 @@ func (in *ResourceHandle) DeepCopy() *ResourceHandle { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceRequest) DeepCopyInto(out *ResourceRequest) { + *out = *in + if in.VendorParameters != nil { + out.VendorParameters = in.VendorParameters.DeepCopyObject() + } + out.ResourceRequestModel = in.ResourceRequestModel + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceRequest. +func (in *ResourceRequest) DeepCopy() *ResourceRequest { + if in == nil { + return nil + } + out := new(ResourceRequest) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceRequestModel) DeepCopyInto(out *ResourceRequestModel) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceRequestModel. +func (in *ResourceRequestModel) DeepCopy() *ResourceRequestModel { + if in == nil { + return nil + } + out := new(ResourceRequestModel) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StructuredResourceHandle) DeepCopyInto(out *StructuredResourceHandle) { + *out = *in + if in.VendorClassParameters != nil { + out.VendorClassParameters = in.VendorClassParameters.DeepCopyObject() + } + if in.VendorClaimParameters != nil { + out.VendorClaimParameters = in.VendorClaimParameters.DeepCopyObject() + } + if in.Results != nil { + in, out := &in.Results, &out.Results + *out = make([]DriverAllocationResult, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructuredResourceHandle. +func (in *StructuredResourceHandle) DeepCopy() *StructuredResourceHandle { + if in == nil { + return nil + } + out := new(StructuredResourceHandle) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VendorParameters) DeepCopyInto(out *VendorParameters) { + *out = *in + if in.Parameters != nil { + out.Parameters = in.Parameters.DeepCopyObject() + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VendorParameters. +func (in *VendorParameters) DeepCopy() *VendorParameters { + if in == nil { + return nil + } + out := new(VendorParameters) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index ff8edb86e5a..4f6614f9ddc 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -868,6 +868,12 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "k8s.io/api/rbac/v1beta1.RoleRef": schema_k8sio_api_rbac_v1beta1_RoleRef(ref), "k8s.io/api/rbac/v1beta1.Subject": schema_k8sio_api_rbac_v1beta1_Subject(ref), "k8s.io/api/resource/v1alpha2.AllocationResult": schema_k8sio_api_resource_v1alpha2_AllocationResult(ref), + "k8s.io/api/resource/v1alpha2.AllocationResultModel": schema_k8sio_api_resource_v1alpha2_AllocationResultModel(ref), + "k8s.io/api/resource/v1alpha2.DriverAllocationResult": schema_k8sio_api_resource_v1alpha2_DriverAllocationResult(ref), + "k8s.io/api/resource/v1alpha2.DriverRequests": schema_k8sio_api_resource_v1alpha2_DriverRequests(ref), + "k8s.io/api/resource/v1alpha2.NodeResourceModel": schema_k8sio_api_resource_v1alpha2_NodeResourceModel(ref), + "k8s.io/api/resource/v1alpha2.NodeResourceSlice": schema_k8sio_api_resource_v1alpha2_NodeResourceSlice(ref), + "k8s.io/api/resource/v1alpha2.NodeResourceSliceList": schema_k8sio_api_resource_v1alpha2_NodeResourceSliceList(ref), "k8s.io/api/resource/v1alpha2.PodSchedulingContext": schema_k8sio_api_resource_v1alpha2_PodSchedulingContext(ref), "k8s.io/api/resource/v1alpha2.PodSchedulingContextList": schema_k8sio_api_resource_v1alpha2_PodSchedulingContextList(ref), "k8s.io/api/resource/v1alpha2.PodSchedulingContextSpec": schema_k8sio_api_resource_v1alpha2_PodSchedulingContextSpec(ref), @@ -875,6 +881,8 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "k8s.io/api/resource/v1alpha2.ResourceClaim": schema_k8sio_api_resource_v1alpha2_ResourceClaim(ref), "k8s.io/api/resource/v1alpha2.ResourceClaimConsumerReference": schema_k8sio_api_resource_v1alpha2_ResourceClaimConsumerReference(ref), "k8s.io/api/resource/v1alpha2.ResourceClaimList": schema_k8sio_api_resource_v1alpha2_ResourceClaimList(ref), + "k8s.io/api/resource/v1alpha2.ResourceClaimParameters": schema_k8sio_api_resource_v1alpha2_ResourceClaimParameters(ref), + "k8s.io/api/resource/v1alpha2.ResourceClaimParametersList": schema_k8sio_api_resource_v1alpha2_ResourceClaimParametersList(ref), "k8s.io/api/resource/v1alpha2.ResourceClaimParametersReference": schema_k8sio_api_resource_v1alpha2_ResourceClaimParametersReference(ref), "k8s.io/api/resource/v1alpha2.ResourceClaimSchedulingStatus": schema_k8sio_api_resource_v1alpha2_ResourceClaimSchedulingStatus(ref), "k8s.io/api/resource/v1alpha2.ResourceClaimSpec": schema_k8sio_api_resource_v1alpha2_ResourceClaimSpec(ref), @@ -884,8 +892,16 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "k8s.io/api/resource/v1alpha2.ResourceClaimTemplateSpec": schema_k8sio_api_resource_v1alpha2_ResourceClaimTemplateSpec(ref), "k8s.io/api/resource/v1alpha2.ResourceClass": schema_k8sio_api_resource_v1alpha2_ResourceClass(ref), "k8s.io/api/resource/v1alpha2.ResourceClassList": schema_k8sio_api_resource_v1alpha2_ResourceClassList(ref), + "k8s.io/api/resource/v1alpha2.ResourceClassParameters": schema_k8sio_api_resource_v1alpha2_ResourceClassParameters(ref), + "k8s.io/api/resource/v1alpha2.ResourceClassParametersList": schema_k8sio_api_resource_v1alpha2_ResourceClassParametersList(ref), "k8s.io/api/resource/v1alpha2.ResourceClassParametersReference": schema_k8sio_api_resource_v1alpha2_ResourceClassParametersReference(ref), + "k8s.io/api/resource/v1alpha2.ResourceFilter": schema_k8sio_api_resource_v1alpha2_ResourceFilter(ref), + "k8s.io/api/resource/v1alpha2.ResourceFilterModel": schema_k8sio_api_resource_v1alpha2_ResourceFilterModel(ref), "k8s.io/api/resource/v1alpha2.ResourceHandle": schema_k8sio_api_resource_v1alpha2_ResourceHandle(ref), + "k8s.io/api/resource/v1alpha2.ResourceRequest": schema_k8sio_api_resource_v1alpha2_ResourceRequest(ref), + "k8s.io/api/resource/v1alpha2.ResourceRequestModel": schema_k8sio_api_resource_v1alpha2_ResourceRequestModel(ref), + "k8s.io/api/resource/v1alpha2.StructuredResourceHandle": schema_k8sio_api_resource_v1alpha2_StructuredResourceHandle(ref), + "k8s.io/api/resource/v1alpha2.VendorParameters": schema_k8sio_api_resource_v1alpha2_VendorParameters(ref), "k8s.io/api/scheduling/v1.PriorityClass": schema_k8sio_api_scheduling_v1_PriorityClass(ref), "k8s.io/api/scheduling/v1.PriorityClassList": schema_k8sio_api_scheduling_v1_PriorityClassList(ref), "k8s.io/api/scheduling/v1alpha1.PriorityClass": schema_k8sio_api_scheduling_v1alpha1_PriorityClass(ref), @@ -44711,6 +44727,200 @@ func schema_k8sio_api_resource_v1alpha2_AllocationResult(ref common.ReferenceCal } } +func schema_k8sio_api_resource_v1alpha2_AllocationResultModel(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "AllocationResultModel must have one and only one field set.", + Type: []string{"object"}, + }, + }, + } +} + +func schema_k8sio_api_resource_v1alpha2_DriverAllocationResult(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "DriverAllocationResult contains vendor parameters and the allocation result for one request.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "vendorRequestParameters": { + SchemaProps: spec.SchemaProps{ + Description: "VendorRequestParameters are the per-request configuration parameters from the time that the claim was allocated.", + Ref: ref("k8s.io/apimachinery/pkg/runtime.RawExtension"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "k8s.io/apimachinery/pkg/runtime.RawExtension"}, + } +} + +func schema_k8sio_api_resource_v1alpha2_DriverRequests(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "DriverRequests describes all resources that are needed from one particular driver.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "driverName": { + SchemaProps: spec.SchemaProps{ + Description: "DriverName is the name used by the DRA driver kubelet plugin.", + Type: []string{"string"}, + Format: "", + }, + }, + "vendorParameters": { + SchemaProps: spec.SchemaProps{ + Description: "VendorParameters are arbitrary setup parameters for all requests of the claim. They are ignored while allocating the claim.", + Ref: ref("k8s.io/apimachinery/pkg/runtime.RawExtension"), + }, + }, + "requests": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Requests describes all resources that are needed from the driver.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/resource/v1alpha2.ResourceRequest"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "k8s.io/api/resource/v1alpha2.ResourceRequest", "k8s.io/apimachinery/pkg/runtime.RawExtension"}, + } +} + +func schema_k8sio_api_resource_v1alpha2_NodeResourceModel(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "NodeResourceModel must have one and only one field set.", + Type: []string{"object"}, + }, + }, + } +} + +func schema_k8sio_api_resource_v1alpha2_NodeResourceSlice(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "NodeResourceSlice provides information about available resources on individual nodes.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Description: "Standard object metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "nodeName": { + SchemaProps: spec.SchemaProps{ + Description: "NodeName identifies the node where the capacity is available. A field selector can be used to list only NodeResourceSlice objects with a certain node name.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "driverName": { + SchemaProps: spec.SchemaProps{ + Description: "DriverName identifies the DRA driver providing the capacity information. A field selector can be used to list only NodeResourceSlice objects with a certain driver name.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"nodeName", "driverName"}, + }, + }, + Dependencies: []string{ + "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_k8sio_api_resource_v1alpha2_NodeResourceSliceList(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "NodeResourceSliceList is a collection of NodeResourceSlices.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Description: "Standard list metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), + }, + }, + "items": { + SchemaProps: spec.SchemaProps{ + Description: "Items is the list of node resource capacity objects.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/resource/v1alpha2.NodeResourceSlice"), + }, + }, + }, + }, + }, + }, + Required: []string{"items"}, + }, + }, + Dependencies: []string{ + "k8s.io/api/resource/v1alpha2.NodeResourceSlice", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + func schema_k8sio_api_resource_v1alpha2_PodSchedulingContext(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -45037,6 +45247,125 @@ func schema_k8sio_api_resource_v1alpha2_ResourceClaimList(ref common.ReferenceCa } } +func schema_k8sio_api_resource_v1alpha2_ResourceClaimParameters(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ResourceClaimParameters defines resource requests for a ResourceClaim in an in-tree format understood by Kubernetes.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Description: "Standard object metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "generatedFrom": { + SchemaProps: spec.SchemaProps{ + Description: "If this object was created from some other resource, then this links back to that resource. This field is used to find the in-tree representation of the claim parameters when the parameter reference of the claim refers to some unknown type.", + Ref: ref("k8s.io/api/resource/v1alpha2.ResourceClaimParametersReference"), + }, + }, + "shareable": { + SchemaProps: spec.SchemaProps{ + Description: "Shareable indicates whether the allocated claim is meant to be shareable by multiple consumers at the same time.", + Type: []string{"boolean"}, + Format: "", + }, + }, + "driverRequests": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "DriverRequests describes all resources that are needed for the allocated claim. A single claim may use resources coming from different drivers. For each driver, this array has at most one entry which then may have one or more per-driver requests.\n\nMay be empty, in which case the claim can always be allocated.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/resource/v1alpha2.DriverRequests"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "k8s.io/api/resource/v1alpha2.DriverRequests", "k8s.io/api/resource/v1alpha2.ResourceClaimParametersReference", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_k8sio_api_resource_v1alpha2_ResourceClaimParametersList(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ResourceClaimParametersList is a collection of ResourceClaimParameters.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Description: "Standard list metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), + }, + }, + "items": { + SchemaProps: spec.SchemaProps{ + Description: "Items is the list of node resource capacity objects.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/resource/v1alpha2.ResourceClaimParameters"), + }, + }, + }, + }, + }, + }, + Required: []string{"items"}, + }, + }, + Dependencies: []string{ + "k8s.io/api/resource/v1alpha2.ResourceClaimParameters", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + func schema_k8sio_api_resource_v1alpha2_ResourceClaimParametersReference(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -45383,6 +45712,13 @@ func schema_k8sio_api_resource_v1alpha2_ResourceClass(ref common.ReferenceCallba Ref: ref("k8s.io/api/core/v1.NodeSelector"), }, }, + "structuredParameters": { + SchemaProps: spec.SchemaProps{ + Description: "If and only if allocation of claims using this class is handled via structured parameters, then StructuredParameters must be set to true.", + Type: []string{"boolean"}, + Format: "", + }, + }, }, Required: []string{"driverName"}, }, @@ -45443,6 +45779,137 @@ func schema_k8sio_api_resource_v1alpha2_ResourceClassList(ref common.ReferenceCa } } +func schema_k8sio_api_resource_v1alpha2_ResourceClassParameters(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ResourceClassParameters defines resource requests for a ResourceClass in an in-tree format understood by Kubernetes.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Description: "Standard object metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "generatedFrom": { + SchemaProps: spec.SchemaProps{ + Description: "If this object was created from some other resource, then this links back to that resource. This field is used to find the in-tree representation of the class parameters when the parameter reference of the class refers to some unknown type.", + Ref: ref("k8s.io/api/resource/v1alpha2.ResourceClassParametersReference"), + }, + }, + "vendorParameters": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "VendorParameters are arbitrary setup parameters for all claims using this class. They are ignored while allocating the claim. There must not be more than one entry per driver.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/resource/v1alpha2.VendorParameters"), + }, + }, + }, + }, + }, + "filters": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Filters describes additional contraints that must be met when using the class.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/resource/v1alpha2.ResourceFilter"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "k8s.io/api/resource/v1alpha2.ResourceClassParametersReference", "k8s.io/api/resource/v1alpha2.ResourceFilter", "k8s.io/api/resource/v1alpha2.VendorParameters", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_k8sio_api_resource_v1alpha2_ResourceClassParametersList(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ResourceClassParametersList is a collection of ResourceClassParameters.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Description: "Standard list metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), + }, + }, + "items": { + SchemaProps: spec.SchemaProps{ + Description: "Items is the list of node resource capacity objects.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/resource/v1alpha2.ResourceClassParameters"), + }, + }, + }, + }, + }, + }, + Required: []string{"items"}, + }, + }, + Dependencies: []string{ + "k8s.io/api/resource/v1alpha2.ResourceClassParameters", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + func schema_k8sio_api_resource_v1alpha2_ResourceClassParametersReference(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -45487,6 +45954,37 @@ func schema_k8sio_api_resource_v1alpha2_ResourceClassParametersReference(ref com } } +func schema_k8sio_api_resource_v1alpha2_ResourceFilter(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ResourceFilter is a filter for resources from one particular driver.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "driverName": { + SchemaProps: spec.SchemaProps{ + Description: "DriverName is the name used by the DRA driver kubelet plugin.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + +func schema_k8sio_api_resource_v1alpha2_ResourceFilterModel(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ResourceFilterModel must have one and only one field set.", + Type: []string{"object"}, + }, + }, + } +} + func schema_k8sio_api_resource_v1alpha2_ResourceHandle(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -45508,9 +46006,132 @@ func schema_k8sio_api_resource_v1alpha2_ResourceHandle(ref common.ReferenceCallb Format: "", }, }, + "structuredData": { + SchemaProps: spec.SchemaProps{ + Description: "If StructuredData is set, then it needs to be used instead of Data.", + Ref: ref("k8s.io/api/resource/v1alpha2.StructuredResourceHandle"), + }, + }, }, }, }, + Dependencies: []string{ + "k8s.io/api/resource/v1alpha2.StructuredResourceHandle"}, + } +} + +func schema_k8sio_api_resource_v1alpha2_ResourceRequest(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ResourceRequest is a request for resources from one particular driver.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "vendorParameters": { + SchemaProps: spec.SchemaProps{ + Description: "VendorParameters are arbitrary setup parameters for the requested resource. They are ignored while allocating a claim.", + Ref: ref("k8s.io/apimachinery/pkg/runtime.RawExtension"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "k8s.io/apimachinery/pkg/runtime.RawExtension"}, + } +} + +func schema_k8sio_api_resource_v1alpha2_ResourceRequestModel(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ResourceRequestModel must have one and only one field set.", + Type: []string{"object"}, + }, + }, + } +} + +func schema_k8sio_api_resource_v1alpha2_StructuredResourceHandle(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "StructuredResourceHandle is the in-tree representation of the allocation result.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "vendorClassParameters": { + SchemaProps: spec.SchemaProps{ + Description: "VendorClassParameters are the per-claim configuration parameters from the resource class at the time that the claim was allocated.", + Ref: ref("k8s.io/apimachinery/pkg/runtime.RawExtension"), + }, + }, + "vendorClaimParameters": { + SchemaProps: spec.SchemaProps{ + Description: "VendorClaimParameters are the per-claim configuration parameters from the resource claim parameters at the time that the claim was allocated.", + Ref: ref("k8s.io/apimachinery/pkg/runtime.RawExtension"), + }, + }, + "nodeName": { + SchemaProps: spec.SchemaProps{ + Description: "NodeName is the name of the node providing the necessary resources.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "results": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Results lists all allocated driver resources.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/resource/v1alpha2.DriverAllocationResult"), + }, + }, + }, + }, + }, + }, + Required: []string{"nodeName", "results"}, + }, + }, + Dependencies: []string{ + "k8s.io/api/resource/v1alpha2.DriverAllocationResult", "k8s.io/apimachinery/pkg/runtime.RawExtension"}, + } +} + +func schema_k8sio_api_resource_v1alpha2_VendorParameters(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "VendorParameters are opaque parameters for one particular driver.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "driverName": { + SchemaProps: spec.SchemaProps{ + Description: "DriverName is the name used by the DRA driver kubelet plugin.", + Type: []string{"string"}, + Format: "", + }, + }, + "parameters": { + SchemaProps: spec.SchemaProps{ + Description: "Parameters can be arbitrary setup parameters. They are ignored while allocating a claim.", + Ref: ref("k8s.io/apimachinery/pkg/runtime.RawExtension"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "k8s.io/apimachinery/pkg/runtime.RawExtension"}, } } diff --git a/pkg/printers/internalversion/printers.go b/pkg/printers/internalversion/printers.go index 15b27f73b92..6dbc72061d7 100644 --- a/pkg/printers/internalversion/printers.go +++ b/pkg/printers/internalversion/printers.go @@ -656,6 +656,31 @@ func AddHandlers(h printers.PrintHandler) { _ = h.TableHandler(podSchedulingCtxColumnDefinitions, printPodSchedulingContext) _ = h.TableHandler(podSchedulingCtxColumnDefinitions, printPodSchedulingContextList) + resourceClaimParametersColumnDefinitions := []metav1.TableColumnDefinition{ + {Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]}, + {Name: "GeneratedFrom", Type: "string", Description: resourcev1alpha2.ResourceClaimParameters{}.SwaggerDoc()["generatedFrom"]}, + {Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]}, + } + _ = h.TableHandler(resourceClaimParametersColumnDefinitions, printResourceClaimParameters) + _ = h.TableHandler(resourceClaimParametersColumnDefinitions, printResourceClaimParametersList) + + resourceClassParametersColumnDefinitions := []metav1.TableColumnDefinition{ + {Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]}, + {Name: "GeneratedFrom", Type: "string", Description: resourcev1alpha2.ResourceClassParameters{}.SwaggerDoc()["generatedFrom"]}, + {Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]}, + } + _ = h.TableHandler(resourceClassParametersColumnDefinitions, printResourceClassParameters) + _ = h.TableHandler(resourceClassParametersColumnDefinitions, printResourceClassParametersList) + + nodeResourceCapacityColumnDefinitions := []metav1.TableColumnDefinition{ + {Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]}, + {Name: "Node", Type: "string", Description: resourcev1alpha2.NodeResourceSlice{}.SwaggerDoc()["nodeName"]}, + {Name: "Driver", Type: "string", Description: resourcev1alpha2.NodeResourceSlice{}.SwaggerDoc()["driverName"]}, + {Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]}, + } + _ = h.TableHandler(nodeResourceCapacityColumnDefinitions, printNodeResourceSlice) + _ = h.TableHandler(nodeResourceCapacityColumnDefinitions, printNodeResourceSliceList) + serviceCIDRColumnDefinitions := []metav1.TableColumnDefinition{ {Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]}, {Name: "CIDRs", Type: "string", Description: networkingv1alpha1.ServiceCIDRSpec{}.SwaggerDoc()["cidrs"]}, @@ -3046,6 +3071,77 @@ func printPodSchedulingContextList(list *resource.PodSchedulingContextList, opti return rows, nil } +func printResourceClaimParameters(obj *resource.ResourceClaimParameters, options printers.GenerateOptions) ([]metav1.TableRow, error) { + row := metav1.TableRow{ + Object: runtime.RawExtension{Object: obj}, + } + generatedFrom := "" + if obj.GeneratedFrom != nil { + generatedFrom = fmt.Sprintf("%s.%s %s", obj.GeneratedFrom.Kind, obj.GeneratedFrom.APIGroup, obj.GeneratedFrom.Name) + } + row.Cells = append(row.Cells, obj.Name, generatedFrom, translateTimestampSince(obj.CreationTimestamp)) + + return []metav1.TableRow{row}, nil +} + +func printResourceClaimParametersList(list *resource.ResourceClaimParametersList, options printers.GenerateOptions) ([]metav1.TableRow, error) { + rows := make([]metav1.TableRow, 0, len(list.Items)) + for i := range list.Items { + r, err := printResourceClaimParameters(&list.Items[i], options) + if err != nil { + return nil, err + } + rows = append(rows, r...) + } + return rows, nil +} + +func printResourceClassParameters(obj *resource.ResourceClassParameters, options printers.GenerateOptions) ([]metav1.TableRow, error) { + row := metav1.TableRow{ + Object: runtime.RawExtension{Object: obj}, + } + generatedFrom := "" + if obj.GeneratedFrom != nil { + generatedFrom = fmt.Sprintf("%s.%s %s", obj.GeneratedFrom.Kind, obj.GeneratedFrom.APIGroup, obj.GeneratedFrom.Name) + } + row.Cells = append(row.Cells, obj.Name, generatedFrom, translateTimestampSince(obj.CreationTimestamp)) + + return []metav1.TableRow{row}, nil +} + +func printResourceClassParametersList(list *resource.ResourceClassParametersList, options printers.GenerateOptions) ([]metav1.TableRow, error) { + rows := make([]metav1.TableRow, 0, len(list.Items)) + for i := range list.Items { + r, err := printResourceClassParameters(&list.Items[i], options) + if err != nil { + return nil, err + } + rows = append(rows, r...) + } + return rows, nil +} + +func printNodeResourceSlice(obj *resource.NodeResourceSlice, options printers.GenerateOptions) ([]metav1.TableRow, error) { + row := metav1.TableRow{ + Object: runtime.RawExtension{Object: obj}, + } + row.Cells = append(row.Cells, obj.Name, obj.NodeName, obj.DriverName, translateTimestampSince(obj.CreationTimestamp)) + + return []metav1.TableRow{row}, nil +} + +func printNodeResourceSliceList(list *resource.NodeResourceSliceList, options printers.GenerateOptions) ([]metav1.TableRow, error) { + rows := make([]metav1.TableRow, 0, len(list.Items)) + for i := range list.Items { + r, err := printNodeResourceSlice(&list.Items[i], options) + if err != nil { + return nil, err + } + rows = append(rows, r...) + } + return rows, nil +} + func printBoolPtr(value *bool) string { if value != nil { return printBool(*value) diff --git a/pkg/registry/resource/noderesourceslice/storage/storage.go b/pkg/registry/resource/noderesourceslice/storage/storage.go new file mode 100644 index 00000000000..b6f16d97a60 --- /dev/null +++ b/pkg/registry/resource/noderesourceslice/storage/storage.go @@ -0,0 +1,62 @@ +/* +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 storage + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/registry/generic" + genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" + "k8s.io/kubernetes/pkg/apis/resource" + "k8s.io/kubernetes/pkg/printers" + printersinternal "k8s.io/kubernetes/pkg/printers/internalversion" + printerstorage "k8s.io/kubernetes/pkg/printers/storage" + "k8s.io/kubernetes/pkg/registry/resource/noderesourceslice" +) + +// REST implements a RESTStorage for NodeResourceSlice. +type REST struct { + *genericregistry.Store +} + +// NewREST returns a RESTStorage object that will work against NodeResourceSlice. +func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { + store := &genericregistry.Store{ + NewFunc: func() runtime.Object { return &resource.NodeResourceSlice{} }, + NewListFunc: func() runtime.Object { return &resource.NodeResourceSliceList{} }, + PredicateFunc: noderesourceslice.Match, + DefaultQualifiedResource: resource.Resource("noderesourceslices"), + SingularQualifiedResource: resource.Resource("noderesourceslice"), + + CreateStrategy: noderesourceslice.Strategy, + UpdateStrategy: noderesourceslice.Strategy, + DeleteStrategy: noderesourceslice.Strategy, + ReturnDeletedObject: true, + + TableConvertor: printerstorage.TableConvertor{TableGenerator: printers.NewTableGenerator().With(printersinternal.AddHandlers)}, + } + options := &generic.StoreOptions{ + RESTOptions: optsGetter, + AttrFunc: noderesourceslice.GetAttrs, + TriggerFunc: noderesourceslice.TriggerFunc, + Indexers: noderesourceslice.Indexers(), + } + if err := store.CompleteWithOptions(options); err != nil { + return nil, err + } + + return &REST{store}, nil +} diff --git a/pkg/registry/resource/noderesourceslice/storage/storage_test.go b/pkg/registry/resource/noderesourceslice/storage/storage_test.go new file mode 100644 index 00000000000..c4ef982b430 --- /dev/null +++ b/pkg/registry/resource/noderesourceslice/storage/storage_test.go @@ -0,0 +1,146 @@ +/* +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 storage + +import ( + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/registry/generic" + genericregistrytest "k8s.io/apiserver/pkg/registry/generic/testing" + etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing" + "k8s.io/kubernetes/pkg/apis/resource" + _ "k8s.io/kubernetes/pkg/apis/resource/install" + "k8s.io/kubernetes/pkg/registry/registrytest" +) + +func newStorage(t *testing.T) (*REST, *etcd3testing.EtcdTestServer) { + etcdStorage, server := registrytest.NewEtcdStorage(t, resource.GroupName) + restOptions := generic.RESTOptions{ + StorageConfig: etcdStorage, + Decorator: generic.UndecoratedStorage, + DeleteCollectionWorkers: 1, + ResourcePrefix: "noderesourceslices", + } + resourceClassStorage, err := NewREST(restOptions) + if err != nil { + t.Fatalf("unexpected error from REST storage: %v", err) + } + return resourceClassStorage, server +} + +func validNewNodeResourceSlice(name string) *resource.NodeResourceSlice { + return &resource.NodeResourceSlice{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + NodeName: name, + DriverName: "cdi.example.com", + } +} + +func TestCreate(t *testing.T) { + storage, server := newStorage(t) + defer server.Terminate(t) + defer storage.Store.DestroyFunc() + test := genericregistrytest.New(t, storage.Store).ClusterScope() + resourceClass := validNewNodeResourceSlice("foo") + resourceClass.ObjectMeta = metav1.ObjectMeta{GenerateName: "foo"} + test.TestCreate( + // valid + resourceClass, + // invalid + &resource.NodeResourceSlice{ + ObjectMeta: metav1.ObjectMeta{Name: "*BadName!"}, + }, + ) +} + +func TestUpdate(t *testing.T) { + storage, server := newStorage(t) + defer server.Terminate(t) + defer storage.Store.DestroyFunc() + test := genericregistrytest.New(t, storage.Store).ClusterScope() + test.TestUpdate( + // valid + validNewNodeResourceSlice("foo"), + // updateFunc + func(obj runtime.Object) runtime.Object { + object := obj.(*resource.NodeResourceSlice) + object.Labels = map[string]string{"foo": "bar"} + return object + }, + // invalid update + func(obj runtime.Object) runtime.Object { + object := obj.(*resource.NodeResourceSlice) + object.DriverName = "" + return object + }, + ) + +} + +func TestDelete(t *testing.T) { + storage, server := newStorage(t) + defer server.Terminate(t) + defer storage.Store.DestroyFunc() + test := genericregistrytest.New(t, storage.Store).ClusterScope().ReturnDeletedObject() + test.TestDelete(validNewNodeResourceSlice("foo")) +} + +func TestGet(t *testing.T) { + storage, server := newStorage(t) + defer server.Terminate(t) + defer storage.Store.DestroyFunc() + test := genericregistrytest.New(t, storage.Store).ClusterScope() + test.TestGet(validNewNodeResourceSlice("foo")) +} + +func TestList(t *testing.T) { + storage, server := newStorage(t) + defer server.Terminate(t) + defer storage.Store.DestroyFunc() + test := genericregistrytest.New(t, storage.Store).ClusterScope() + test.TestList(validNewNodeResourceSlice("foo")) +} + +func TestWatch(t *testing.T) { + storage, server := newStorage(t) + defer server.Terminate(t) + defer storage.Store.DestroyFunc() + test := genericregistrytest.New(t, storage.Store).ClusterScope() + test.TestWatch( + validNewNodeResourceSlice("foo"), + // matching labels + []labels.Set{}, + // not matching labels + []labels.Set{ + {"foo": "bar"}, + }, + // matching fields + []fields.Set{ + {"metadata.name": "foo"}, + }, + // not matching fields + []fields.Set{ + {"metadata.name": "bar"}, + }, + ) +} diff --git a/pkg/registry/resource/noderesourceslice/strategy.go b/pkg/registry/resource/noderesourceslice/strategy.go new file mode 100644 index 00000000000..3f6ec715669 --- /dev/null +++ b/pkg/registry/resource/noderesourceslice/strategy.go @@ -0,0 +1,139 @@ +/* +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 noderesourceslice + +import ( + "context" + "fmt" + + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/apiserver/pkg/registry/generic" + "k8s.io/apiserver/pkg/storage" + "k8s.io/apiserver/pkg/storage/names" + "k8s.io/client-go/tools/cache" + "k8s.io/kubernetes/pkg/api/legacyscheme" + "k8s.io/kubernetes/pkg/apis/resource" + "k8s.io/kubernetes/pkg/apis/resource/validation" +) + +// nodeResourceSliceStrategy implements behavior for NodeResourceSlice objects +type nodeResourceSliceStrategy struct { + runtime.ObjectTyper + names.NameGenerator +} + +var Strategy = nodeResourceSliceStrategy{legacyscheme.Scheme, names.SimpleNameGenerator} + +func (nodeResourceSliceStrategy) NamespaceScoped() bool { + return false +} + +func (nodeResourceSliceStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { +} + +func (nodeResourceSliceStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { + slice := obj.(*resource.NodeResourceSlice) + return validation.ValidateNodeResourceSlice(slice) +} + +func (nodeResourceSliceStrategy) WarningsOnCreate(ctx context.Context, obj runtime.Object) []string { + return nil +} + +func (nodeResourceSliceStrategy) Canonicalize(obj runtime.Object) { +} + +func (nodeResourceSliceStrategy) AllowCreateOnUpdate() bool { + return false +} + +func (nodeResourceSliceStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { +} + +func (nodeResourceSliceStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { + return validation.ValidateNodeResourceSliceUpdate(obj.(*resource.NodeResourceSlice), old.(*resource.NodeResourceSlice)) +} + +func (nodeResourceSliceStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.Object) []string { + return nil +} + +func (nodeResourceSliceStrategy) AllowUnconditionalUpdate() bool { + return true +} + +var TriggerFunc = map[string]storage.IndexerFunc{ + // Only one index is supported: + // https://github.com/kubernetes/kubernetes/blob/3aa8c59fec0bf339e67ca80ea7905c817baeca85/staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher.go#L346-L350 + "nodeName": nodeNameTriggerFunc, +} + +func nodeNameTriggerFunc(obj runtime.Object) string { + return obj.(*resource.NodeResourceSlice).NodeName +} + +// Indexers returns the indexers for NodeResourceSlice. +func Indexers() *cache.Indexers { + return &cache.Indexers{ + storage.FieldIndex("nodeName"): nodeNameIndexFunc, + } +} + +func nodeNameIndexFunc(obj interface{}) ([]string, error) { + slice, ok := obj.(*resource.NodeResourceSlice) + if !ok { + return nil, fmt.Errorf("not a NodeResourceSlice") + } + return []string{slice.NodeName}, nil +} + +// GetAttrs returns labels and fields of a given object for filtering purposes. +func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) { + slice, ok := obj.(*resource.NodeResourceSlice) + if !ok { + return nil, nil, fmt.Errorf("not a NodeResourceSlice") + } + return labels.Set(slice.ObjectMeta.Labels), toSelectableFields(slice), nil +} + +// Match returns a generic matcher for a given label and field selector. +func Match(label labels.Selector, field fields.Selector) storage.SelectionPredicate { + return storage.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: GetAttrs, + IndexFields: []string{"nodeName"}, + } +} + +// toSelectableFields returns a field set that represents the object +// TODO: fields are not labels, and the validation rules for them do not apply. +func toSelectableFields(slice *resource.NodeResourceSlice) fields.Set { + // The purpose of allocation with a given number of elements is to reduce + // amount of allocations needed to create the fields.Set. If you add any + // field here or the number of object-meta related fields changes, this should + // be adjusted. + fields := make(fields.Set, 3) + fields["nodeName"] = slice.NodeName + fields["driverName"] = slice.DriverName + + // Adds one field. + return generic.AddObjectMetaFieldsSet(fields, &slice.ObjectMeta, false) +} diff --git a/pkg/registry/resource/noderesourceslice/strategy_test.go b/pkg/registry/resource/noderesourceslice/strategy_test.go new file mode 100644 index 00000000000..56a6e0e9bb0 --- /dev/null +++ b/pkg/registry/resource/noderesourceslice/strategy_test.go @@ -0,0 +1,82 @@ +/* +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 noderesourceslice + +import ( + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + genericapirequest "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/kubernetes/pkg/apis/resource" +) + +var slice = &resource.NodeResourceSlice{ + ObjectMeta: metav1.ObjectMeta{ + Name: "valid-class", + }, + NodeName: "valid-node-name", + DriverName: "testdriver.example.com", +} + +func TestClassStrategy(t *testing.T) { + if Strategy.NamespaceScoped() { + t.Errorf("NodeResourceSlice must not be namespace scoped") + } + if Strategy.AllowCreateOnUpdate() { + t.Errorf("NodeResourceSlice should not allow create on update") + } +} + +func TestClassStrategyCreate(t *testing.T) { + ctx := genericapirequest.NewDefaultContext() + slice := slice.DeepCopy() + + Strategy.PrepareForCreate(ctx, slice) + errs := Strategy.Validate(ctx, slice) + if len(errs) != 0 { + t.Errorf("unexpected error validating for create %v", errs) + } +} + +func TestClassStrategyUpdate(t *testing.T) { + t.Run("no-changes-okay", func(t *testing.T) { + ctx := genericapirequest.NewDefaultContext() + slice := slice.DeepCopy() + newClass := slice.DeepCopy() + newClass.ResourceVersion = "4" + + Strategy.PrepareForUpdate(ctx, newClass, slice) + errs := Strategy.ValidateUpdate(ctx, newClass, slice) + if len(errs) != 0 { + t.Errorf("unexpected validation errors: %v", errs) + } + }) + + t.Run("name-change-not-allowed", func(t *testing.T) { + ctx := genericapirequest.NewDefaultContext() + slice := slice.DeepCopy() + newClass := slice.DeepCopy() + newClass.Name = "valid-class-2" + newClass.ResourceVersion = "4" + + Strategy.PrepareForUpdate(ctx, newClass, slice) + errs := Strategy.ValidateUpdate(ctx, newClass, slice) + if len(errs) == 0 { + t.Errorf("expected a validation error") + } + }) +} diff --git a/pkg/registry/resource/resourceclaimparameters/storage/storage.go b/pkg/registry/resource/resourceclaimparameters/storage/storage.go new file mode 100644 index 00000000000..820411fede9 --- /dev/null +++ b/pkg/registry/resource/resourceclaimparameters/storage/storage.go @@ -0,0 +1,57 @@ +/* +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 storage + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/registry/generic" + genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" + "k8s.io/kubernetes/pkg/apis/resource" + "k8s.io/kubernetes/pkg/printers" + printersinternal "k8s.io/kubernetes/pkg/printers/internalversion" + printerstorage "k8s.io/kubernetes/pkg/printers/storage" + "k8s.io/kubernetes/pkg/registry/resource/resourceclaimparameters" +) + +// REST implements a RESTStorage for ResourceClaimParameters. +type REST struct { + *genericregistry.Store +} + +// NewREST returns a RESTStorage object that will work against ResourceClaimParameters. +func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { + store := &genericregistry.Store{ + NewFunc: func() runtime.Object { return &resource.ResourceClaimParameters{} }, + NewListFunc: func() runtime.Object { return &resource.ResourceClaimParametersList{} }, + PredicateFunc: resourceclaimparameters.Match, + DefaultQualifiedResource: resource.Resource("resourceclaimparameters"), + SingularQualifiedResource: resource.Resource("resourceclaimparameters"), + + CreateStrategy: resourceclaimparameters.Strategy, + UpdateStrategy: resourceclaimparameters.Strategy, + DeleteStrategy: resourceclaimparameters.Strategy, + ReturnDeletedObject: true, + + TableConvertor: printerstorage.TableConvertor{TableGenerator: printers.NewTableGenerator().With(printersinternal.AddHandlers)}, + } + options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: resourceclaimparameters.GetAttrs} + if err := store.CompleteWithOptions(options); err != nil { + return nil, err + } + + return &REST{store}, nil +} diff --git a/pkg/registry/resource/resourceclaimparameters/storage/storage_test.go b/pkg/registry/resource/resourceclaimparameters/storage/storage_test.go new file mode 100644 index 00000000000..c5ff63e9d5f --- /dev/null +++ b/pkg/registry/resource/resourceclaimparameters/storage/storage_test.go @@ -0,0 +1,145 @@ +/* +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 storage + +import ( + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/registry/generic" + genericregistrytest "k8s.io/apiserver/pkg/registry/generic/testing" + etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing" + "k8s.io/kubernetes/pkg/apis/resource" + _ "k8s.io/kubernetes/pkg/apis/resource/install" + "k8s.io/kubernetes/pkg/registry/registrytest" +) + +func newStorage(t *testing.T) (*REST, *etcd3testing.EtcdTestServer) { + etcdStorage, server := registrytest.NewEtcdStorage(t, resource.GroupName) + restOptions := generic.RESTOptions{ + StorageConfig: etcdStorage, + Decorator: generic.UndecoratedStorage, + DeleteCollectionWorkers: 1, + ResourcePrefix: "resourceclaimparameters", + } + resourceClassStorage, err := NewREST(restOptions) + if err != nil { + t.Fatalf("unexpected error from REST storage: %v", err) + } + return resourceClassStorage, server +} + +func validNewResourceClaimParameters(name string) *resource.ResourceClaimParameters { + return &resource.ResourceClaimParameters{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: metav1.NamespaceDefault, + }, + } +} + +func TestCreate(t *testing.T) { + storage, server := newStorage(t) + defer server.Terminate(t) + defer storage.Store.DestroyFunc() + test := genericregistrytest.New(t, storage.Store) + resourceClass := validNewResourceClaimParameters("foo") + resourceClass.ObjectMeta = metav1.ObjectMeta{} + test.TestCreate( + // valid + resourceClass, + // invalid + &resource.ResourceClaimParameters{ + ObjectMeta: metav1.ObjectMeta{Name: "*BadName!"}, + }, + ) +} + +func TestUpdate(t *testing.T) { + storage, server := newStorage(t) + defer server.Terminate(t) + defer storage.Store.DestroyFunc() + test := genericregistrytest.New(t, storage.Store) + test.TestUpdate( + // valid + validNewResourceClaimParameters("foo"), + // updateFunc + func(obj runtime.Object) runtime.Object { + object := obj.(*resource.ResourceClaimParameters) + object.Labels = map[string]string{"foo": "bar"} + return object + }, + // invalid update + func(obj runtime.Object) runtime.Object { + object := obj.(*resource.ResourceClaimParameters) + object.Labels = map[string]string{"&$^^#%@": "1"} + return object + }, + ) + +} + +func TestDelete(t *testing.T) { + storage, server := newStorage(t) + defer server.Terminate(t) + defer storage.Store.DestroyFunc() + test := genericregistrytest.New(t, storage.Store).ReturnDeletedObject() + test.TestDelete(validNewResourceClaimParameters("foo")) +} + +func TestGet(t *testing.T) { + storage, server := newStorage(t) + defer server.Terminate(t) + defer storage.Store.DestroyFunc() + test := genericregistrytest.New(t, storage.Store) + test.TestGet(validNewResourceClaimParameters("foo")) +} + +func TestList(t *testing.T) { + storage, server := newStorage(t) + defer server.Terminate(t) + defer storage.Store.DestroyFunc() + test := genericregistrytest.New(t, storage.Store) + test.TestList(validNewResourceClaimParameters("foo")) +} + +func TestWatch(t *testing.T) { + storage, server := newStorage(t) + defer server.Terminate(t) + defer storage.Store.DestroyFunc() + test := genericregistrytest.New(t, storage.Store) + test.TestWatch( + validNewResourceClaimParameters("foo"), + // matching labels + []labels.Set{}, + // not matching labels + []labels.Set{ + {"foo": "bar"}, + }, + // matching fields + []fields.Set{ + {"metadata.name": "foo"}, + }, + // not matching fields + []fields.Set{ + {"metadata.name": "bar"}, + }, + ) +} diff --git a/pkg/registry/resource/resourceclaimparameters/strategy.go b/pkg/registry/resource/resourceclaimparameters/strategy.go new file mode 100644 index 00000000000..9b17f14f228 --- /dev/null +++ b/pkg/registry/resource/resourceclaimparameters/strategy.go @@ -0,0 +1,103 @@ +/* +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 resourceclaimparameters + +import ( + "context" + "errors" + + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/apiserver/pkg/registry/generic" + "k8s.io/apiserver/pkg/storage" + "k8s.io/apiserver/pkg/storage/names" + "k8s.io/kubernetes/pkg/api/legacyscheme" + "k8s.io/kubernetes/pkg/apis/resource" + "k8s.io/kubernetes/pkg/apis/resource/validation" +) + +// resourceClaimParametersStrategy implements behavior for ResourceClaimParameters objects +type resourceClaimParametersStrategy struct { + runtime.ObjectTyper + names.NameGenerator +} + +var Strategy = resourceClaimParametersStrategy{legacyscheme.Scheme, names.SimpleNameGenerator} + +func (resourceClaimParametersStrategy) NamespaceScoped() bool { + return true +} + +func (resourceClaimParametersStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { +} + +func (resourceClaimParametersStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { + resourceClaimParameters := obj.(*resource.ResourceClaimParameters) + return validation.ValidateResourceClaimParameters(resourceClaimParameters) +} + +func (resourceClaimParametersStrategy) WarningsOnCreate(ctx context.Context, obj runtime.Object) []string { + return nil +} + +func (resourceClaimParametersStrategy) Canonicalize(obj runtime.Object) { +} + +func (resourceClaimParametersStrategy) AllowCreateOnUpdate() bool { + return false +} + +func (resourceClaimParametersStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { +} + +func (resourceClaimParametersStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { + return validation.ValidateResourceClaimParametersUpdate(obj.(*resource.ResourceClaimParameters), old.(*resource.ResourceClaimParameters)) +} + +func (resourceClaimParametersStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.Object) []string { + return nil +} + +func (resourceClaimParametersStrategy) AllowUnconditionalUpdate() bool { + return true +} + +// Match returns a generic matcher for a given label and field selector. +func Match(label labels.Selector, field fields.Selector) storage.SelectionPredicate { + return storage.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: GetAttrs, + } +} + +// GetAttrs returns labels and fields of a given object for filtering purposes. +func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) { + parameters, ok := obj.(*resource.ResourceClaimParameters) + if !ok { + return nil, nil, errors.New("not a resourceclaim") + } + return labels.Set(parameters.Labels), toSelectableFields(parameters), nil +} + +// toSelectableFields returns a field set that represents the object +func toSelectableFields(claim *resource.ResourceClaimParameters) fields.Set { + fields := generic.ObjectMetaFieldsSet(&claim.ObjectMeta, true) + return fields +} diff --git a/pkg/registry/resource/resourceclaimparameters/strategy_test.go b/pkg/registry/resource/resourceclaimparameters/strategy_test.go new file mode 100644 index 00000000000..931b4a8316a --- /dev/null +++ b/pkg/registry/resource/resourceclaimparameters/strategy_test.go @@ -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 resourceclaimparameters + +import ( + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + genericapirequest "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/kubernetes/pkg/apis/resource" +) + +var resourceClaimParameters = &resource.ResourceClaimParameters{ + ObjectMeta: metav1.ObjectMeta{ + Name: "valid", + Namespace: "ns", + }, +} + +func TestClassStrategy(t *testing.T) { + if !Strategy.NamespaceScoped() { + t.Errorf("ResourceClaimParameters must be namespace scoped") + } + if Strategy.AllowCreateOnUpdate() { + t.Errorf("ResourceClaimParameters should not allow create on update") + } +} + +func TestClassStrategyCreate(t *testing.T) { + ctx := genericapirequest.NewDefaultContext() + resourceClaimParameters := resourceClaimParameters.DeepCopy() + + Strategy.PrepareForCreate(ctx, resourceClaimParameters) + errs := Strategy.Validate(ctx, resourceClaimParameters) + if len(errs) != 0 { + t.Errorf("unexpected error validating for create %v", errs) + } +} + +func TestClassStrategyUpdate(t *testing.T) { + t.Run("no-changes-okay", func(t *testing.T) { + ctx := genericapirequest.NewDefaultContext() + resourceClaimParameters := resourceClaimParameters.DeepCopy() + newObj := resourceClaimParameters.DeepCopy() + newObj.ResourceVersion = "4" + + Strategy.PrepareForUpdate(ctx, newObj, resourceClaimParameters) + errs := Strategy.ValidateUpdate(ctx, newObj, resourceClaimParameters) + if len(errs) != 0 { + t.Errorf("unexpected validation errors: %v", errs) + } + }) + + t.Run("name-change-not-allowed", func(t *testing.T) { + ctx := genericapirequest.NewDefaultContext() + resourceClaimParameters := resourceClaimParameters.DeepCopy() + newObj := resourceClaimParameters.DeepCopy() + newObj.Name += "-2" + newObj.ResourceVersion = "4" + + Strategy.PrepareForUpdate(ctx, newObj, resourceClaimParameters) + errs := Strategy.ValidateUpdate(ctx, newObj, resourceClaimParameters) + if len(errs) == 0 { + t.Errorf("expected a validation error") + } + }) +} diff --git a/pkg/registry/resource/resourceclassparameters/storage/storage.go b/pkg/registry/resource/resourceclassparameters/storage/storage.go new file mode 100644 index 00000000000..1603b27c34a --- /dev/null +++ b/pkg/registry/resource/resourceclassparameters/storage/storage.go @@ -0,0 +1,57 @@ +/* +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 storage + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/registry/generic" + genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" + "k8s.io/kubernetes/pkg/apis/resource" + "k8s.io/kubernetes/pkg/printers" + printersinternal "k8s.io/kubernetes/pkg/printers/internalversion" + printerstorage "k8s.io/kubernetes/pkg/printers/storage" + "k8s.io/kubernetes/pkg/registry/resource/resourceclassparameters" +) + +// REST implements a RESTStorage for ResourceClassParameters. +type REST struct { + *genericregistry.Store +} + +// NewREST returns a RESTStorage object that will work against ResourceClassParameters. +func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { + store := &genericregistry.Store{ + NewFunc: func() runtime.Object { return &resource.ResourceClassParameters{} }, + NewListFunc: func() runtime.Object { return &resource.ResourceClassParametersList{} }, + PredicateFunc: resourceclassparameters.Match, + DefaultQualifiedResource: resource.Resource("resourceclassparameters"), + SingularQualifiedResource: resource.Resource("resourceclassparameters"), + + CreateStrategy: resourceclassparameters.Strategy, + UpdateStrategy: resourceclassparameters.Strategy, + DeleteStrategy: resourceclassparameters.Strategy, + ReturnDeletedObject: true, + + TableConvertor: printerstorage.TableConvertor{TableGenerator: printers.NewTableGenerator().With(printersinternal.AddHandlers)}, + } + options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: resourceclassparameters.GetAttrs} + if err := store.CompleteWithOptions(options); err != nil { + return nil, err + } + + return &REST{store}, nil +} diff --git a/pkg/registry/resource/resourceclassparameters/storage/storage_test.go b/pkg/registry/resource/resourceclassparameters/storage/storage_test.go new file mode 100644 index 00000000000..40fd3e5ed17 --- /dev/null +++ b/pkg/registry/resource/resourceclassparameters/storage/storage_test.go @@ -0,0 +1,145 @@ +/* +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 storage + +import ( + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/registry/generic" + genericregistrytest "k8s.io/apiserver/pkg/registry/generic/testing" + etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing" + "k8s.io/kubernetes/pkg/apis/resource" + _ "k8s.io/kubernetes/pkg/apis/resource/install" + "k8s.io/kubernetes/pkg/registry/registrytest" +) + +func newStorage(t *testing.T) (*REST, *etcd3testing.EtcdTestServer) { + etcdStorage, server := registrytest.NewEtcdStorage(t, resource.GroupName) + restOptions := generic.RESTOptions{ + StorageConfig: etcdStorage, + Decorator: generic.UndecoratedStorage, + DeleteCollectionWorkers: 1, + ResourcePrefix: "resourceclassparameters", + } + resourceClassStorage, err := NewREST(restOptions) + if err != nil { + t.Fatalf("unexpected error from REST storage: %v", err) + } + return resourceClassStorage, server +} + +func validNewResourceClaimParameters(name string) *resource.ResourceClaimParameters { + return &resource.ResourceClaimParameters{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: metav1.NamespaceDefault, + }, + } +} + +func TestCreate(t *testing.T) { + storage, server := newStorage(t) + defer server.Terminate(t) + defer storage.Store.DestroyFunc() + test := genericregistrytest.New(t, storage.Store) + resourceClass := validNewResourceClaimParameters("foo") + resourceClass.ObjectMeta = metav1.ObjectMeta{} + test.TestCreate( + // valid + resourceClass, + // invalid + &resource.ResourceClaimParameters{ + ObjectMeta: metav1.ObjectMeta{Name: "*BadName!"}, + }, + ) +} + +func TestUpdate(t *testing.T) { + storage, server := newStorage(t) + defer server.Terminate(t) + defer storage.Store.DestroyFunc() + test := genericregistrytest.New(t, storage.Store) + test.TestUpdate( + // valid + validNewResourceClaimParameters("foo"), + // updateFunc + func(obj runtime.Object) runtime.Object { + object := obj.(*resource.ResourceClaimParameters) + object.Labels = map[string]string{"foo": "bar"} + return object + }, + // invalid update + func(obj runtime.Object) runtime.Object { + object := obj.(*resource.ResourceClaimParameters) + object.Labels = map[string]string{"&$^^#%@": "1"} + return object + }, + ) + +} + +func TestDelete(t *testing.T) { + storage, server := newStorage(t) + defer server.Terminate(t) + defer storage.Store.DestroyFunc() + test := genericregistrytest.New(t, storage.Store).ReturnDeletedObject() + test.TestDelete(validNewResourceClaimParameters("foo")) +} + +func TestGet(t *testing.T) { + storage, server := newStorage(t) + defer server.Terminate(t) + defer storage.Store.DestroyFunc() + test := genericregistrytest.New(t, storage.Store) + test.TestGet(validNewResourceClaimParameters("foo")) +} + +func TestList(t *testing.T) { + storage, server := newStorage(t) + defer server.Terminate(t) + defer storage.Store.DestroyFunc() + test := genericregistrytest.New(t, storage.Store) + test.TestList(validNewResourceClaimParameters("foo")) +} + +func TestWatch(t *testing.T) { + storage, server := newStorage(t) + defer server.Terminate(t) + defer storage.Store.DestroyFunc() + test := genericregistrytest.New(t, storage.Store) + test.TestWatch( + validNewResourceClaimParameters("foo"), + // matching labels + []labels.Set{}, + // not matching labels + []labels.Set{ + {"foo": "bar"}, + }, + // matching fields + []fields.Set{ + {"metadata.name": "foo"}, + }, + // not matching fields + []fields.Set{ + {"metadata.name": "bar"}, + }, + ) +} diff --git a/pkg/registry/resource/resourceclassparameters/strategy.go b/pkg/registry/resource/resourceclassparameters/strategy.go new file mode 100644 index 00000000000..a1cd1b968cd --- /dev/null +++ b/pkg/registry/resource/resourceclassparameters/strategy.go @@ -0,0 +1,103 @@ +/* +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 resourceclassparameters + +import ( + "context" + "errors" + + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/apiserver/pkg/registry/generic" + "k8s.io/apiserver/pkg/storage" + "k8s.io/apiserver/pkg/storage/names" + "k8s.io/kubernetes/pkg/api/legacyscheme" + "k8s.io/kubernetes/pkg/apis/resource" + "k8s.io/kubernetes/pkg/apis/resource/validation" +) + +// resourceClassParametersStrategy implements behavior for ResourceClassParameters objects +type resourceClassParametersStrategy struct { + runtime.ObjectTyper + names.NameGenerator +} + +var Strategy = resourceClassParametersStrategy{legacyscheme.Scheme, names.SimpleNameGenerator} + +func (resourceClassParametersStrategy) NamespaceScoped() bool { + return true +} + +func (resourceClassParametersStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { +} + +func (resourceClassParametersStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { + resourceClassParameters := obj.(*resource.ResourceClassParameters) + return validation.ValidateResourceClassParameters(resourceClassParameters) +} + +func (resourceClassParametersStrategy) WarningsOnCreate(ctx context.Context, obj runtime.Object) []string { + return nil +} + +func (resourceClassParametersStrategy) Canonicalize(obj runtime.Object) { +} + +func (resourceClassParametersStrategy) AllowCreateOnUpdate() bool { + return false +} + +func (resourceClassParametersStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { +} + +func (resourceClassParametersStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { + return validation.ValidateResourceClassParametersUpdate(obj.(*resource.ResourceClassParameters), old.(*resource.ResourceClassParameters)) +} + +func (resourceClassParametersStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.Object) []string { + return nil +} + +func (resourceClassParametersStrategy) AllowUnconditionalUpdate() bool { + return true +} + +// Match returns a generic matcher for a given label and field selector. +func Match(label labels.Selector, field fields.Selector) storage.SelectionPredicate { + return storage.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: GetAttrs, + } +} + +// GetAttrs returns labels and fields of a given object for filtering purposes. +func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) { + parameters, ok := obj.(*resource.ResourceClassParameters) + if !ok { + return nil, nil, errors.New("not a resourceclassparameters") + } + return labels.Set(parameters.Labels), toSelectableFields(parameters), nil +} + +// toSelectableFields returns a field set that represents the object +func toSelectableFields(class *resource.ResourceClassParameters) fields.Set { + fields := generic.ObjectMetaFieldsSet(&class.ObjectMeta, true) + return fields +} diff --git a/pkg/registry/resource/resourceclassparameters/strategy_test.go b/pkg/registry/resource/resourceclassparameters/strategy_test.go new file mode 100644 index 00000000000..079f9279c9b --- /dev/null +++ b/pkg/registry/resource/resourceclassparameters/strategy_test.go @@ -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 resourceclassparameters + +import ( + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + genericapirequest "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/kubernetes/pkg/apis/resource" +) + +var resourceClassParameters = &resource.ResourceClassParameters{ + ObjectMeta: metav1.ObjectMeta{ + Name: "valid", + Namespace: "ns", + }, +} + +func TestClassStrategy(t *testing.T) { + if !Strategy.NamespaceScoped() { + t.Errorf("ResourceClassParameters must be namespace scoped") + } + if Strategy.AllowCreateOnUpdate() { + t.Errorf("ResourceClassParameters should not allow create on update") + } +} + +func TestClassStrategyCreate(t *testing.T) { + ctx := genericapirequest.NewDefaultContext() + resourceClassParameters := resourceClassParameters.DeepCopy() + + Strategy.PrepareForCreate(ctx, resourceClassParameters) + errs := Strategy.Validate(ctx, resourceClassParameters) + if len(errs) != 0 { + t.Errorf("unexpected error validating for create %v", errs) + } +} + +func TestClassStrategyUpdate(t *testing.T) { + t.Run("no-changes-okay", func(t *testing.T) { + ctx := genericapirequest.NewDefaultContext() + resourceClassParameters := resourceClassParameters.DeepCopy() + newObj := resourceClassParameters.DeepCopy() + newObj.ResourceVersion = "4" + + Strategy.PrepareForUpdate(ctx, newObj, resourceClassParameters) + errs := Strategy.ValidateUpdate(ctx, newObj, resourceClassParameters) + if len(errs) != 0 { + t.Errorf("unexpected validation errors: %v", errs) + } + }) + + t.Run("name-change-not-allowed", func(t *testing.T) { + ctx := genericapirequest.NewDefaultContext() + resourceClassParameters := resourceClassParameters.DeepCopy() + newObj := resourceClassParameters.DeepCopy() + newObj.Name += "-2" + newObj.ResourceVersion = "4" + + Strategy.PrepareForUpdate(ctx, newObj, resourceClassParameters) + errs := Strategy.ValidateUpdate(ctx, newObj, resourceClassParameters) + if len(errs) == 0 { + t.Errorf("expected a validation error") + } + }) +} diff --git a/pkg/registry/resource/rest/storage_resource.go b/pkg/registry/resource/rest/storage_resource.go index 4756b01381d..28a2eaaecc5 100644 --- a/pkg/registry/resource/rest/storage_resource.go +++ b/pkg/registry/resource/rest/storage_resource.go @@ -24,10 +24,13 @@ import ( serverstorage "k8s.io/apiserver/pkg/server/storage" "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/apis/resource" + noderesourceslicestore "k8s.io/kubernetes/pkg/registry/resource/noderesourceslice/storage" podschedulingcontextsstore "k8s.io/kubernetes/pkg/registry/resource/podschedulingcontext/storage" resourceclaimstore "k8s.io/kubernetes/pkg/registry/resource/resourceclaim/storage" + resourceclaimparametersstore "k8s.io/kubernetes/pkg/registry/resource/resourceclaimparameters/storage" resourceclaimtemplatestore "k8s.io/kubernetes/pkg/registry/resource/resourceclaimtemplate/storage" resourceclassstore "k8s.io/kubernetes/pkg/registry/resource/resourceclass/storage" + resourceclassparametersstore "k8s.io/kubernetes/pkg/registry/resource/resourceclassparameters/storage" ) type RESTStorageProvider struct{} @@ -83,6 +86,30 @@ func (p RESTStorageProvider) v1alpha2Storage(apiResourceConfigSource serverstora storage[resource+"/status"] = podSchedulingStatusStorage } + if resource := "resourceclaimparameters"; apiResourceConfigSource.ResourceEnabled(resourcev1alpha2.SchemeGroupVersion.WithResource(resource)) { + resourceClaimParametersStorage, err := resourceclaimparametersstore.NewREST(restOptionsGetter) + if err != nil { + return nil, err + } + storage[resource] = resourceClaimParametersStorage + } + + if resource := "resourceclassparameters"; apiResourceConfigSource.ResourceEnabled(resourcev1alpha2.SchemeGroupVersion.WithResource(resource)) { + resourceClassParametersStorage, err := resourceclassparametersstore.NewREST(restOptionsGetter) + if err != nil { + return nil, err + } + storage[resource] = resourceClassParametersStorage + } + + if resource := "noderesourceslices"; apiResourceConfigSource.ResourceEnabled(resourcev1alpha2.SchemeGroupVersion.WithResource(resource)) { + nodeResourceSliceStorage, err := noderesourceslicestore.NewREST(restOptionsGetter) + if err != nil { + return nil, err + } + storage[resource] = nodeResourceSliceStorage + } + return storage, nil } diff --git a/staging/src/k8s.io/api/resource/v1alpha2/generated.pb.go b/staging/src/k8s.io/api/resource/v1alpha2/generated.pb.go index fb3880f96c6..c40cd0ff88a 100644 --- a/staging/src/k8s.io/api/resource/v1alpha2/generated.pb.go +++ b/staging/src/k8s.io/api/resource/v1alpha2/generated.pb.go @@ -74,10 +74,178 @@ func (m *AllocationResult) XXX_DiscardUnknown() { var xxx_messageInfo_AllocationResult proto.InternalMessageInfo +func (m *AllocationResultModel) Reset() { *m = AllocationResultModel{} } +func (*AllocationResultModel) ProtoMessage() {} +func (*AllocationResultModel) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{1} +} +func (m *AllocationResultModel) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AllocationResultModel) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *AllocationResultModel) XXX_Merge(src proto.Message) { + xxx_messageInfo_AllocationResultModel.Merge(m, src) +} +func (m *AllocationResultModel) XXX_Size() int { + return m.Size() +} +func (m *AllocationResultModel) XXX_DiscardUnknown() { + xxx_messageInfo_AllocationResultModel.DiscardUnknown(m) +} + +var xxx_messageInfo_AllocationResultModel proto.InternalMessageInfo + +func (m *DriverAllocationResult) Reset() { *m = DriverAllocationResult{} } +func (*DriverAllocationResult) ProtoMessage() {} +func (*DriverAllocationResult) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{2} +} +func (m *DriverAllocationResult) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DriverAllocationResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *DriverAllocationResult) XXX_Merge(src proto.Message) { + xxx_messageInfo_DriverAllocationResult.Merge(m, src) +} +func (m *DriverAllocationResult) XXX_Size() int { + return m.Size() +} +func (m *DriverAllocationResult) XXX_DiscardUnknown() { + xxx_messageInfo_DriverAllocationResult.DiscardUnknown(m) +} + +var xxx_messageInfo_DriverAllocationResult proto.InternalMessageInfo + +func (m *DriverRequests) Reset() { *m = DriverRequests{} } +func (*DriverRequests) ProtoMessage() {} +func (*DriverRequests) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{3} +} +func (m *DriverRequests) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DriverRequests) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *DriverRequests) XXX_Merge(src proto.Message) { + xxx_messageInfo_DriverRequests.Merge(m, src) +} +func (m *DriverRequests) XXX_Size() int { + return m.Size() +} +func (m *DriverRequests) XXX_DiscardUnknown() { + xxx_messageInfo_DriverRequests.DiscardUnknown(m) +} + +var xxx_messageInfo_DriverRequests proto.InternalMessageInfo + +func (m *NodeResourceModel) Reset() { *m = NodeResourceModel{} } +func (*NodeResourceModel) ProtoMessage() {} +func (*NodeResourceModel) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{4} +} +func (m *NodeResourceModel) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NodeResourceModel) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *NodeResourceModel) XXX_Merge(src proto.Message) { + xxx_messageInfo_NodeResourceModel.Merge(m, src) +} +func (m *NodeResourceModel) XXX_Size() int { + return m.Size() +} +func (m *NodeResourceModel) XXX_DiscardUnknown() { + xxx_messageInfo_NodeResourceModel.DiscardUnknown(m) +} + +var xxx_messageInfo_NodeResourceModel proto.InternalMessageInfo + +func (m *NodeResourceSlice) Reset() { *m = NodeResourceSlice{} } +func (*NodeResourceSlice) ProtoMessage() {} +func (*NodeResourceSlice) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{5} +} +func (m *NodeResourceSlice) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NodeResourceSlice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *NodeResourceSlice) XXX_Merge(src proto.Message) { + xxx_messageInfo_NodeResourceSlice.Merge(m, src) +} +func (m *NodeResourceSlice) XXX_Size() int { + return m.Size() +} +func (m *NodeResourceSlice) XXX_DiscardUnknown() { + xxx_messageInfo_NodeResourceSlice.DiscardUnknown(m) +} + +var xxx_messageInfo_NodeResourceSlice proto.InternalMessageInfo + +func (m *NodeResourceSliceList) Reset() { *m = NodeResourceSliceList{} } +func (*NodeResourceSliceList) ProtoMessage() {} +func (*NodeResourceSliceList) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{6} +} +func (m *NodeResourceSliceList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NodeResourceSliceList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *NodeResourceSliceList) XXX_Merge(src proto.Message) { + xxx_messageInfo_NodeResourceSliceList.Merge(m, src) +} +func (m *NodeResourceSliceList) XXX_Size() int { + return m.Size() +} +func (m *NodeResourceSliceList) XXX_DiscardUnknown() { + xxx_messageInfo_NodeResourceSliceList.DiscardUnknown(m) +} + +var xxx_messageInfo_NodeResourceSliceList proto.InternalMessageInfo + func (m *PodSchedulingContext) Reset() { *m = PodSchedulingContext{} } func (*PodSchedulingContext) ProtoMessage() {} func (*PodSchedulingContext) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{1} + return fileDescriptor_4312f5b44a31ec02, []int{7} } func (m *PodSchedulingContext) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -105,7 +273,7 @@ var xxx_messageInfo_PodSchedulingContext proto.InternalMessageInfo func (m *PodSchedulingContextList) Reset() { *m = PodSchedulingContextList{} } func (*PodSchedulingContextList) ProtoMessage() {} func (*PodSchedulingContextList) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{2} + return fileDescriptor_4312f5b44a31ec02, []int{8} } func (m *PodSchedulingContextList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -133,7 +301,7 @@ var xxx_messageInfo_PodSchedulingContextList proto.InternalMessageInfo func (m *PodSchedulingContextSpec) Reset() { *m = PodSchedulingContextSpec{} } func (*PodSchedulingContextSpec) ProtoMessage() {} func (*PodSchedulingContextSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{3} + return fileDescriptor_4312f5b44a31ec02, []int{9} } func (m *PodSchedulingContextSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -161,7 +329,7 @@ var xxx_messageInfo_PodSchedulingContextSpec proto.InternalMessageInfo func (m *PodSchedulingContextStatus) Reset() { *m = PodSchedulingContextStatus{} } func (*PodSchedulingContextStatus) ProtoMessage() {} func (*PodSchedulingContextStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{4} + return fileDescriptor_4312f5b44a31ec02, []int{10} } func (m *PodSchedulingContextStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -189,7 +357,7 @@ var xxx_messageInfo_PodSchedulingContextStatus proto.InternalMessageInfo func (m *ResourceClaim) Reset() { *m = ResourceClaim{} } func (*ResourceClaim) ProtoMessage() {} func (*ResourceClaim) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{5} + return fileDescriptor_4312f5b44a31ec02, []int{11} } func (m *ResourceClaim) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -217,7 +385,7 @@ var xxx_messageInfo_ResourceClaim proto.InternalMessageInfo func (m *ResourceClaimConsumerReference) Reset() { *m = ResourceClaimConsumerReference{} } func (*ResourceClaimConsumerReference) ProtoMessage() {} func (*ResourceClaimConsumerReference) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{6} + return fileDescriptor_4312f5b44a31ec02, []int{12} } func (m *ResourceClaimConsumerReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -245,7 +413,7 @@ var xxx_messageInfo_ResourceClaimConsumerReference proto.InternalMessageInfo func (m *ResourceClaimList) Reset() { *m = ResourceClaimList{} } func (*ResourceClaimList) ProtoMessage() {} func (*ResourceClaimList) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{7} + return fileDescriptor_4312f5b44a31ec02, []int{13} } func (m *ResourceClaimList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -270,10 +438,66 @@ func (m *ResourceClaimList) XXX_DiscardUnknown() { var xxx_messageInfo_ResourceClaimList proto.InternalMessageInfo +func (m *ResourceClaimParameters) Reset() { *m = ResourceClaimParameters{} } +func (*ResourceClaimParameters) ProtoMessage() {} +func (*ResourceClaimParameters) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{14} +} +func (m *ResourceClaimParameters) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceClaimParameters) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceClaimParameters) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceClaimParameters.Merge(m, src) +} +func (m *ResourceClaimParameters) XXX_Size() int { + return m.Size() +} +func (m *ResourceClaimParameters) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceClaimParameters.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceClaimParameters proto.InternalMessageInfo + +func (m *ResourceClaimParametersList) Reset() { *m = ResourceClaimParametersList{} } +func (*ResourceClaimParametersList) ProtoMessage() {} +func (*ResourceClaimParametersList) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{15} +} +func (m *ResourceClaimParametersList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceClaimParametersList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceClaimParametersList) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceClaimParametersList.Merge(m, src) +} +func (m *ResourceClaimParametersList) XXX_Size() int { + return m.Size() +} +func (m *ResourceClaimParametersList) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceClaimParametersList.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceClaimParametersList proto.InternalMessageInfo + func (m *ResourceClaimParametersReference) Reset() { *m = ResourceClaimParametersReference{} } func (*ResourceClaimParametersReference) ProtoMessage() {} func (*ResourceClaimParametersReference) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{8} + return fileDescriptor_4312f5b44a31ec02, []int{16} } func (m *ResourceClaimParametersReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -301,7 +525,7 @@ var xxx_messageInfo_ResourceClaimParametersReference proto.InternalMessageInfo func (m *ResourceClaimSchedulingStatus) Reset() { *m = ResourceClaimSchedulingStatus{} } func (*ResourceClaimSchedulingStatus) ProtoMessage() {} func (*ResourceClaimSchedulingStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{9} + return fileDescriptor_4312f5b44a31ec02, []int{17} } func (m *ResourceClaimSchedulingStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -329,7 +553,7 @@ var xxx_messageInfo_ResourceClaimSchedulingStatus proto.InternalMessageInfo func (m *ResourceClaimSpec) Reset() { *m = ResourceClaimSpec{} } func (*ResourceClaimSpec) ProtoMessage() {} func (*ResourceClaimSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{10} + return fileDescriptor_4312f5b44a31ec02, []int{18} } func (m *ResourceClaimSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -357,7 +581,7 @@ var xxx_messageInfo_ResourceClaimSpec proto.InternalMessageInfo func (m *ResourceClaimStatus) Reset() { *m = ResourceClaimStatus{} } func (*ResourceClaimStatus) ProtoMessage() {} func (*ResourceClaimStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{11} + return fileDescriptor_4312f5b44a31ec02, []int{19} } func (m *ResourceClaimStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -385,7 +609,7 @@ var xxx_messageInfo_ResourceClaimStatus proto.InternalMessageInfo func (m *ResourceClaimTemplate) Reset() { *m = ResourceClaimTemplate{} } func (*ResourceClaimTemplate) ProtoMessage() {} func (*ResourceClaimTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{12} + return fileDescriptor_4312f5b44a31ec02, []int{20} } func (m *ResourceClaimTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -413,7 +637,7 @@ var xxx_messageInfo_ResourceClaimTemplate proto.InternalMessageInfo func (m *ResourceClaimTemplateList) Reset() { *m = ResourceClaimTemplateList{} } func (*ResourceClaimTemplateList) ProtoMessage() {} func (*ResourceClaimTemplateList) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{13} + return fileDescriptor_4312f5b44a31ec02, []int{21} } func (m *ResourceClaimTemplateList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -441,7 +665,7 @@ var xxx_messageInfo_ResourceClaimTemplateList proto.InternalMessageInfo func (m *ResourceClaimTemplateSpec) Reset() { *m = ResourceClaimTemplateSpec{} } func (*ResourceClaimTemplateSpec) ProtoMessage() {} func (*ResourceClaimTemplateSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{14} + return fileDescriptor_4312f5b44a31ec02, []int{22} } func (m *ResourceClaimTemplateSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -469,7 +693,7 @@ var xxx_messageInfo_ResourceClaimTemplateSpec proto.InternalMessageInfo func (m *ResourceClass) Reset() { *m = ResourceClass{} } func (*ResourceClass) ProtoMessage() {} func (*ResourceClass) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{15} + return fileDescriptor_4312f5b44a31ec02, []int{23} } func (m *ResourceClass) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -497,7 +721,7 @@ var xxx_messageInfo_ResourceClass proto.InternalMessageInfo func (m *ResourceClassList) Reset() { *m = ResourceClassList{} } func (*ResourceClassList) ProtoMessage() {} func (*ResourceClassList) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{16} + return fileDescriptor_4312f5b44a31ec02, []int{24} } func (m *ResourceClassList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -522,10 +746,66 @@ func (m *ResourceClassList) XXX_DiscardUnknown() { var xxx_messageInfo_ResourceClassList proto.InternalMessageInfo +func (m *ResourceClassParameters) Reset() { *m = ResourceClassParameters{} } +func (*ResourceClassParameters) ProtoMessage() {} +func (*ResourceClassParameters) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{25} +} +func (m *ResourceClassParameters) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceClassParameters) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceClassParameters) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceClassParameters.Merge(m, src) +} +func (m *ResourceClassParameters) XXX_Size() int { + return m.Size() +} +func (m *ResourceClassParameters) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceClassParameters.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceClassParameters proto.InternalMessageInfo + +func (m *ResourceClassParametersList) Reset() { *m = ResourceClassParametersList{} } +func (*ResourceClassParametersList) ProtoMessage() {} +func (*ResourceClassParametersList) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{26} +} +func (m *ResourceClassParametersList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceClassParametersList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceClassParametersList) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceClassParametersList.Merge(m, src) +} +func (m *ResourceClassParametersList) XXX_Size() int { + return m.Size() +} +func (m *ResourceClassParametersList) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceClassParametersList.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceClassParametersList proto.InternalMessageInfo + func (m *ResourceClassParametersReference) Reset() { *m = ResourceClassParametersReference{} } func (*ResourceClassParametersReference) ProtoMessage() {} func (*ResourceClassParametersReference) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{17} + return fileDescriptor_4312f5b44a31ec02, []int{27} } func (m *ResourceClassParametersReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -550,10 +830,66 @@ func (m *ResourceClassParametersReference) XXX_DiscardUnknown() { var xxx_messageInfo_ResourceClassParametersReference proto.InternalMessageInfo +func (m *ResourceFilter) Reset() { *m = ResourceFilter{} } +func (*ResourceFilter) ProtoMessage() {} +func (*ResourceFilter) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{28} +} +func (m *ResourceFilter) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceFilter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceFilter) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceFilter.Merge(m, src) +} +func (m *ResourceFilter) XXX_Size() int { + return m.Size() +} +func (m *ResourceFilter) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceFilter.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceFilter proto.InternalMessageInfo + +func (m *ResourceFilterModel) Reset() { *m = ResourceFilterModel{} } +func (*ResourceFilterModel) ProtoMessage() {} +func (*ResourceFilterModel) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{29} +} +func (m *ResourceFilterModel) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceFilterModel) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceFilterModel) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceFilterModel.Merge(m, src) +} +func (m *ResourceFilterModel) XXX_Size() int { + return m.Size() +} +func (m *ResourceFilterModel) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceFilterModel.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceFilterModel proto.InternalMessageInfo + func (m *ResourceHandle) Reset() { *m = ResourceHandle{} } func (*ResourceHandle) ProtoMessage() {} func (*ResourceHandle) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{18} + return fileDescriptor_4312f5b44a31ec02, []int{30} } func (m *ResourceHandle) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -578,8 +914,126 @@ func (m *ResourceHandle) XXX_DiscardUnknown() { var xxx_messageInfo_ResourceHandle proto.InternalMessageInfo +func (m *ResourceRequest) Reset() { *m = ResourceRequest{} } +func (*ResourceRequest) ProtoMessage() {} +func (*ResourceRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{31} +} +func (m *ResourceRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceRequest.Merge(m, src) +} +func (m *ResourceRequest) XXX_Size() int { + return m.Size() +} +func (m *ResourceRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceRequest proto.InternalMessageInfo + +func (m *ResourceRequestModel) Reset() { *m = ResourceRequestModel{} } +func (*ResourceRequestModel) ProtoMessage() {} +func (*ResourceRequestModel) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{32} +} +func (m *ResourceRequestModel) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceRequestModel) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceRequestModel) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceRequestModel.Merge(m, src) +} +func (m *ResourceRequestModel) XXX_Size() int { + return m.Size() +} +func (m *ResourceRequestModel) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceRequestModel.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceRequestModel proto.InternalMessageInfo + +func (m *StructuredResourceHandle) Reset() { *m = StructuredResourceHandle{} } +func (*StructuredResourceHandle) ProtoMessage() {} +func (*StructuredResourceHandle) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{33} +} +func (m *StructuredResourceHandle) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *StructuredResourceHandle) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *StructuredResourceHandle) XXX_Merge(src proto.Message) { + xxx_messageInfo_StructuredResourceHandle.Merge(m, src) +} +func (m *StructuredResourceHandle) XXX_Size() int { + return m.Size() +} +func (m *StructuredResourceHandle) XXX_DiscardUnknown() { + xxx_messageInfo_StructuredResourceHandle.DiscardUnknown(m) +} + +var xxx_messageInfo_StructuredResourceHandle proto.InternalMessageInfo + +func (m *VendorParameters) Reset() { *m = VendorParameters{} } +func (*VendorParameters) ProtoMessage() {} +func (*VendorParameters) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{34} +} +func (m *VendorParameters) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *VendorParameters) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *VendorParameters) XXX_Merge(src proto.Message) { + xxx_messageInfo_VendorParameters.Merge(m, src) +} +func (m *VendorParameters) XXX_Size() int { + return m.Size() +} +func (m *VendorParameters) XXX_DiscardUnknown() { + xxx_messageInfo_VendorParameters.DiscardUnknown(m) +} + +var xxx_messageInfo_VendorParameters proto.InternalMessageInfo + func init() { proto.RegisterType((*AllocationResult)(nil), "k8s.io.api.resource.v1alpha2.AllocationResult") + proto.RegisterType((*AllocationResultModel)(nil), "k8s.io.api.resource.v1alpha2.AllocationResultModel") + proto.RegisterType((*DriverAllocationResult)(nil), "k8s.io.api.resource.v1alpha2.DriverAllocationResult") + proto.RegisterType((*DriverRequests)(nil), "k8s.io.api.resource.v1alpha2.DriverRequests") + proto.RegisterType((*NodeResourceModel)(nil), "k8s.io.api.resource.v1alpha2.NodeResourceModel") + proto.RegisterType((*NodeResourceSlice)(nil), "k8s.io.api.resource.v1alpha2.NodeResourceSlice") + proto.RegisterType((*NodeResourceSliceList)(nil), "k8s.io.api.resource.v1alpha2.NodeResourceSliceList") proto.RegisterType((*PodSchedulingContext)(nil), "k8s.io.api.resource.v1alpha2.PodSchedulingContext") proto.RegisterType((*PodSchedulingContextList)(nil), "k8s.io.api.resource.v1alpha2.PodSchedulingContextList") proto.RegisterType((*PodSchedulingContextSpec)(nil), "k8s.io.api.resource.v1alpha2.PodSchedulingContextSpec") @@ -587,6 +1041,8 @@ func init() { proto.RegisterType((*ResourceClaim)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaim") proto.RegisterType((*ResourceClaimConsumerReference)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimConsumerReference") proto.RegisterType((*ResourceClaimList)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimList") + proto.RegisterType((*ResourceClaimParameters)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimParameters") + proto.RegisterType((*ResourceClaimParametersList)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimParametersList") proto.RegisterType((*ResourceClaimParametersReference)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimParametersReference") proto.RegisterType((*ResourceClaimSchedulingStatus)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimSchedulingStatus") proto.RegisterType((*ResourceClaimSpec)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimSpec") @@ -596,8 +1052,16 @@ func init() { proto.RegisterType((*ResourceClaimTemplateSpec)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimTemplateSpec") proto.RegisterType((*ResourceClass)(nil), "k8s.io.api.resource.v1alpha2.ResourceClass") proto.RegisterType((*ResourceClassList)(nil), "k8s.io.api.resource.v1alpha2.ResourceClassList") + proto.RegisterType((*ResourceClassParameters)(nil), "k8s.io.api.resource.v1alpha2.ResourceClassParameters") + proto.RegisterType((*ResourceClassParametersList)(nil), "k8s.io.api.resource.v1alpha2.ResourceClassParametersList") proto.RegisterType((*ResourceClassParametersReference)(nil), "k8s.io.api.resource.v1alpha2.ResourceClassParametersReference") + proto.RegisterType((*ResourceFilter)(nil), "k8s.io.api.resource.v1alpha2.ResourceFilter") + proto.RegisterType((*ResourceFilterModel)(nil), "k8s.io.api.resource.v1alpha2.ResourceFilterModel") proto.RegisterType((*ResourceHandle)(nil), "k8s.io.api.resource.v1alpha2.ResourceHandle") + proto.RegisterType((*ResourceRequest)(nil), "k8s.io.api.resource.v1alpha2.ResourceRequest") + proto.RegisterType((*ResourceRequestModel)(nil), "k8s.io.api.resource.v1alpha2.ResourceRequestModel") + proto.RegisterType((*StructuredResourceHandle)(nil), "k8s.io.api.resource.v1alpha2.StructuredResourceHandle") + proto.RegisterType((*VendorParameters)(nil), "k8s.io.api.resource.v1alpha2.VendorParameters") } func init() { @@ -605,84 +1069,121 @@ func init() { } var fileDescriptor_4312f5b44a31ec02 = []byte{ - // 1218 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x58, 0x4f, 0x6f, 0xe3, 0x44, - 0x14, 0xaf, 0x93, 0x74, 0xd5, 0x4e, 0xdb, 0xb4, 0x75, 0x5b, 0xc8, 0x56, 0xbb, 0x49, 0xf0, 0xa9, - 0x12, 0xc5, 0xd9, 0x06, 0xb4, 0x54, 0xfc, 0x93, 0xea, 0x56, 0x2c, 0x15, 0x6c, 0x37, 0x4c, 0xa8, - 0xd8, 0x22, 0x84, 0x76, 0x6a, 0x4f, 0x13, 0x53, 0xff, 0xc3, 0x33, 0x2e, 0xac, 0xb8, 0xec, 0x47, - 0xd8, 0x03, 0x07, 0x38, 0x71, 0xe4, 0x0b, 0xf0, 0x0d, 0x10, 0x52, 0x8f, 0x45, 0x70, 0xd8, 0x53, - 0x44, 0xc3, 0x47, 0xe0, 0xc4, 0x9e, 0xd0, 0x4c, 0x6c, 0xc7, 0xe3, 0xc4, 0xa1, 0xe9, 0x21, 0x62, - 0x4f, 0xed, 0xcc, 0xfb, 0xbd, 0xdf, 0xfb, 0x37, 0xef, 0xcd, 0x38, 0x60, 0xf3, 0x74, 0x9b, 0xa8, - 0xa6, 0x5b, 0x43, 0x9e, 0x59, 0xf3, 0x31, 0x71, 0x03, 0x5f, 0xc7, 0xb5, 0xb3, 0x2d, 0x64, 0x79, - 0x6d, 0x54, 0xaf, 0xb5, 0xb0, 0x83, 0x7d, 0x44, 0xb1, 0xa1, 0x7a, 0xbe, 0x4b, 0x5d, 0xf9, 0x56, - 0x0f, 0xad, 0x22, 0xcf, 0x54, 0x23, 0xb4, 0x1a, 0xa1, 0xd7, 0x5f, 0x6b, 0x99, 0xb4, 0x1d, 0x1c, - 0xab, 0xba, 0x6b, 0xd7, 0x5a, 0x6e, 0xcb, 0xad, 0x71, 0xa5, 0xe3, 0xe0, 0x84, 0xaf, 0xf8, 0x82, - 0xff, 0xd7, 0x23, 0x5b, 0x57, 0x12, 0xa6, 0x75, 0xd7, 0x67, 0x66, 0xd3, 0x06, 0xd7, 0xdf, 0xe8, - 0x63, 0x6c, 0xa4, 0xb7, 0x4d, 0x07, 0xfb, 0x8f, 0x6b, 0xde, 0x69, 0x8b, 0x6d, 0x90, 0x9a, 0x8d, - 0x29, 0x1a, 0xa6, 0x55, 0xcb, 0xd2, 0xf2, 0x03, 0x87, 0x9a, 0x36, 0x1e, 0x50, 0xb8, 0xfb, 0x5f, - 0x0a, 0x44, 0x6f, 0x63, 0x1b, 0xa5, 0xf5, 0x94, 0xef, 0x73, 0x60, 0x69, 0xc7, 0xb2, 0x5c, 0x1d, - 0x51, 0xd3, 0x75, 0x20, 0x26, 0x81, 0x45, 0x65, 0x17, 0x2c, 0x46, 0xb9, 0xf9, 0x00, 0x39, 0x86, - 0x85, 0x49, 0x49, 0xaa, 0xe6, 0x37, 0xe6, 0xea, 0x9b, 0xea, 0xa8, 0xf4, 0xa9, 0x50, 0x50, 0xd2, - 0x5e, 0x3e, 0xef, 0x54, 0xa6, 0xba, 0x9d, 0xca, 0xa2, 0xb8, 0x4f, 0x60, 0x9a, 0x5d, 0x3e, 0x06, - 0x4b, 0xe8, 0x0c, 0x99, 0x16, 0x3a, 0xb6, 0xf0, 0x03, 0xe7, 0xc0, 0x35, 0x30, 0x29, 0xe5, 0xaa, - 0xd2, 0xc6, 0x5c, 0xbd, 0x9a, 0xb4, 0xc8, 0x72, 0xac, 0x9e, 0x6d, 0xa9, 0x0c, 0xd0, 0xc4, 0x16, - 0xd6, 0xa9, 0xeb, 0x6b, 0xab, 0xdd, 0x4e, 0x65, 0x69, 0x27, 0xa5, 0x0d, 0x07, 0xf8, 0xe4, 0x1a, - 0x98, 0x25, 0x6d, 0xe4, 0x63, 0xb6, 0x57, 0xca, 0x57, 0xa5, 0x8d, 0x19, 0x6d, 0x39, 0x74, 0x70, - 0xb6, 0x19, 0x09, 0x60, 0x1f, 0xa3, 0xfc, 0x9c, 0x03, 0xab, 0x0d, 0xd7, 0x68, 0xea, 0x6d, 0x6c, - 0x04, 0x96, 0xe9, 0xb4, 0x76, 0x5d, 0x87, 0xe2, 0x6f, 0xa8, 0xfc, 0x08, 0xcc, 0xb0, 0xba, 0x19, - 0x88, 0xa2, 0x92, 0xc4, 0xbd, 0xbc, 0x93, 0xf0, 0x32, 0x4e, 0xbf, 0xea, 0x9d, 0xb6, 0xd8, 0x06, - 0x51, 0x19, 0x9a, 0xf9, 0xfd, 0xe0, 0xf8, 0x4b, 0xac, 0xd3, 0xfb, 0x98, 0x22, 0x4d, 0x0e, 0x4d, - 0x83, 0xfe, 0x1e, 0x8c, 0x59, 0xe5, 0x87, 0xa0, 0x40, 0x3c, 0xac, 0x87, 0x39, 0xb8, 0x3b, 0x3a, - 0xeb, 0xc3, 0x7c, 0x6c, 0x7a, 0x58, 0xd7, 0xe6, 0x43, 0x1b, 0x05, 0xb6, 0x82, 0x9c, 0x51, 0x7e, - 0x04, 0x6e, 0x10, 0x8a, 0x68, 0x40, 0x78, 0x0a, 0xe6, 0xea, 0xdb, 0xd7, 0xe0, 0xe6, 0xfa, 0x5a, - 0x31, 0x64, 0xbf, 0xd1, 0x5b, 0xc3, 0x90, 0x57, 0xf9, 0x4d, 0x02, 0xa5, 0x61, 0x6a, 0x1f, 0x99, - 0x84, 0xca, 0x9f, 0x0f, 0xa4, 0x4e, 0xbd, 0x5a, 0xea, 0x98, 0x36, 0x4f, 0xdc, 0x52, 0x68, 0x76, - 0x26, 0xda, 0x49, 0xa4, 0xed, 0x53, 0x30, 0x6d, 0x52, 0x6c, 0xb3, 0xb3, 0xc3, 0x4e, 0x6b, 0x7d, - 0xfc, 0xd8, 0xb4, 0x85, 0x90, 0x7e, 0x7a, 0x9f, 0x11, 0xc1, 0x1e, 0x9f, 0xf2, 0x34, 0x23, 0x26, - 0x96, 0x58, 0x79, 0x1b, 0xcc, 0x13, 0x7e, 0x18, 0xb1, 0xc1, 0x4e, 0x1a, 0x8f, 0x6b, 0x56, 0x5b, - 0x0d, 0x89, 0xe6, 0x9b, 0x09, 0x19, 0x14, 0x90, 0xf2, 0x5b, 0xa0, 0xe8, 0xb9, 0x14, 0x3b, 0xd4, - 0x44, 0x56, 0x74, 0xe8, 0xf3, 0x1b, 0xb3, 0x9a, 0xdc, 0xed, 0x54, 0x8a, 0x0d, 0x41, 0x02, 0x53, - 0x48, 0xe5, 0x07, 0x09, 0xac, 0x67, 0x57, 0x47, 0xfe, 0x16, 0x14, 0xa3, 0x88, 0x77, 0x2d, 0x64, - 0xda, 0x51, 0x07, 0xbf, 0x7d, 0xb5, 0x0e, 0xe6, 0x3a, 0x7d, 0xee, 0xb0, 0xe4, 0x2f, 0x85, 0x31, - 0x15, 0x05, 0x18, 0x81, 0x29, 0x53, 0xca, 0x8f, 0x39, 0xb0, 0x20, 0x40, 0x26, 0xd0, 0x32, 0x1f, - 0x0b, 0x2d, 0x53, 0x1b, 0x27, 0xcc, 0xac, 0x5e, 0x39, 0x4a, 0xf5, 0xca, 0xd6, 0x38, 0xa4, 0xa3, - 0x9b, 0xa4, 0x2b, 0x81, 0xb2, 0x80, 0xdf, 0x75, 0x1d, 0x12, 0xd8, 0xd8, 0x87, 0xf8, 0x04, 0xfb, - 0xd8, 0xd1, 0xb1, 0xbc, 0x09, 0x66, 0x90, 0x67, 0xde, 0xf3, 0xdd, 0xc0, 0x0b, 0x8f, 0x54, 0x7c, - 0xf4, 0x77, 0x1a, 0xfb, 0x7c, 0x1f, 0xc6, 0x08, 0x86, 0x8e, 0x3c, 0xe2, 0xde, 0x26, 0xd0, 0x91, - 0x1d, 0x18, 0x23, 0xe4, 0x2a, 0x28, 0x38, 0xc8, 0xc6, 0xa5, 0x02, 0x47, 0xc6, 0xb1, 0x1f, 0x20, - 0x1b, 0x43, 0x2e, 0x91, 0x35, 0x90, 0x0f, 0x4c, 0xa3, 0x34, 0xcd, 0x01, 0x77, 0x42, 0x40, 0xfe, - 0x70, 0x7f, 0xef, 0x79, 0xa7, 0xf2, 0x4a, 0xd6, 0x5d, 0x43, 0x1f, 0x7b, 0x98, 0xa8, 0x87, 0xfb, - 0x7b, 0x90, 0x29, 0x2b, 0xbf, 0x48, 0x60, 0x59, 0x08, 0x72, 0x02, 0x23, 0xa0, 0x21, 0x8e, 0x80, - 0x57, 0xc7, 0x28, 0x59, 0x46, 0xef, 0x7f, 0x27, 0x81, 0xaa, 0x80, 0x6b, 0x20, 0x1f, 0xd9, 0x98, - 0x62, 0x9f, 0x5c, 0xb7, 0x58, 0x55, 0x50, 0x38, 0x35, 0x1d, 0x83, 0x9f, 0xd5, 0x44, 0xfa, 0x3f, - 0x34, 0x1d, 0x03, 0x72, 0x49, 0x5c, 0xa0, 0x7c, 0x56, 0x81, 0x94, 0x27, 0x12, 0xb8, 0x3d, 0xb2, - 0x5b, 0x63, 0x0e, 0x29, 0xb3, 0xc8, 0xef, 0x82, 0xc5, 0xc0, 0x21, 0x81, 0x49, 0xd9, 0x7d, 0x97, - 0x1c, 0x40, 0x2b, 0xec, 0xd6, 0x3e, 0x14, 0x45, 0x30, 0x8d, 0x55, 0x7e, 0xca, 0xa5, 0xea, 0xcb, - 0xc7, 0xe1, 0x3d, 0xb0, 0x9c, 0x18, 0x07, 0x84, 0x1c, 0xf4, 0x7d, 0xb8, 0x19, 0xfa, 0x90, 0xd4, - 0xea, 0x01, 0xe0, 0xa0, 0x8e, 0xfc, 0x35, 0x58, 0xf0, 0x92, 0xa9, 0x0e, 0x5b, 0xfb, 0xbd, 0x31, - 0x4a, 0x3a, 0xa4, 0x54, 0xda, 0x72, 0xb7, 0x53, 0x59, 0x10, 0x04, 0x50, 0xb4, 0x23, 0x37, 0x40, - 0x11, 0xc5, 0x4f, 0xa2, 0xfb, 0x6c, 0xa4, 0xf7, 0xca, 0xb0, 0x11, 0x8d, 0xbf, 0x1d, 0x41, 0xfa, - 0x7c, 0x60, 0x07, 0xa6, 0xf4, 0x95, 0xbf, 0x73, 0x60, 0x65, 0xc8, 0x78, 0x90, 0xeb, 0x00, 0x18, - 0xbe, 0x79, 0x86, 0xfd, 0x44, 0x92, 0xe2, 0x31, 0xb7, 0x17, 0x4b, 0x60, 0x02, 0x25, 0x7f, 0x01, - 0x40, 0x9f, 0x3d, 0xcc, 0x89, 0x3a, 0x3a, 0x27, 0xe9, 0x07, 0x9e, 0x56, 0x64, 0xfc, 0x89, 0xdd, - 0x04, 0xa3, 0x4c, 0xc0, 0x9c, 0x8f, 0x09, 0xf6, 0xcf, 0xb0, 0xf1, 0xbe, 0xeb, 0x97, 0xf2, 0xbc, - 0x8f, 0xde, 0x19, 0x23, 0xe9, 0x03, 0xa3, 0x4c, 0x5b, 0x09, 0x43, 0x9a, 0x83, 0x7d, 0x62, 0x98, - 0xb4, 0x22, 0x37, 0xc1, 0x9a, 0x81, 0x51, 0xc2, 0xcd, 0xaf, 0x02, 0x4c, 0x28, 0x36, 0xf8, 0x84, - 0x9a, 0xd1, 0x6e, 0x87, 0x04, 0x6b, 0x7b, 0xc3, 0x40, 0x70, 0xb8, 0xae, 0xf2, 0x87, 0x04, 0xd6, - 0x04, 0xcf, 0x3e, 0xc1, 0xb6, 0x67, 0x21, 0x8a, 0x27, 0x70, 0x1d, 0x1d, 0x09, 0xd7, 0xd1, 0x9b, - 0x63, 0xa4, 0x2f, 0x72, 0x32, 0xeb, 0x5a, 0x52, 0x7e, 0x97, 0xc0, 0xcd, 0xa1, 0x1a, 0x13, 0x18, - 0xaf, 0x0f, 0xc5, 0xf1, 0xfa, 0xfa, 0x35, 0xe2, 0xca, 0x18, 0xb3, 0x17, 0x59, 0x51, 0x35, 0x7b, - 0xcf, 0xd6, 0x17, 0xef, 0xfd, 0xa0, 0xfc, 0x23, 0x3e, 0x83, 0x08, 0x99, 0x40, 0x18, 0xe2, 0x44, - 0xc9, 0x5d, 0x69, 0xa2, 0x0c, 0x0c, 0xda, 0xfc, 0x98, 0x83, 0x96, 0x90, 0xeb, 0x0d, 0xda, 0x23, - 0xb0, 0x20, 0xde, 0x3e, 0x85, 0x2b, 0x7e, 0xf3, 0x71, 0xea, 0xa6, 0x70, 0x3b, 0x89, 0x4c, 0xe9, - 0xb7, 0x07, 0x21, 0xff, 0xe7, 0xb7, 0x07, 0x21, 0x19, 0x4d, 0xf1, 0xab, 0xf8, 0xf6, 0x18, 0x9a, - 0xe7, 0xc9, 0xbf, 0x3d, 0xd8, 0xa7, 0x34, 0xfb, 0x4b, 0x3c, 0xa4, 0x47, 0x6f, 0xc8, 0xf8, 0x53, - 0xfa, 0x20, 0x12, 0xc0, 0x3e, 0x46, 0x39, 0x01, 0x45, 0xf1, 0x37, 0x80, 0x6b, 0xdd, 0x7c, 0x55, - 0x50, 0xe0, 0x95, 0x4b, 0xb9, 0xbe, 0x87, 0x28, 0x82, 0x5c, 0xa2, 0x69, 0xe7, 0x97, 0xe5, 0xa9, - 0x8b, 0xcb, 0xf2, 0xd4, 0xb3, 0xcb, 0xf2, 0xd4, 0x93, 0x6e, 0x59, 0x3a, 0xef, 0x96, 0xa5, 0x8b, - 0x6e, 0x59, 0x7a, 0xd6, 0x2d, 0x4b, 0x7f, 0x76, 0xcb, 0xd2, 0xd3, 0xbf, 0xca, 0x53, 0x9f, 0xdd, - 0x1a, 0xf5, 0x8b, 0xd1, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x24, 0xee, 0x5c, 0x4a, 0x50, 0x12, - 0x00, 0x00, + // 1822 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x1a, 0xcd, 0x6f, 0x1b, 0x4b, + 0x3d, 0x6b, 0x3b, 0xaf, 0xe9, 0x2f, 0x8d, 0x93, 0x6c, 0x92, 0xc6, 0x2f, 0xaf, 0xcf, 0x36, 0x7b, + 0x8a, 0x44, 0xbb, 0x7e, 0xc9, 0x2b, 0xa5, 0xe2, 0x4b, 0xca, 0x36, 0xb4, 0x44, 0xb4, 0x69, 0x18, + 0xf7, 0x1b, 0x04, 0xdd, 0x78, 0xa7, 0xc9, 0x92, 0xf5, 0xee, 0xb2, 0xb3, 0x4e, 0x5b, 0x71, 0xa9, + 0x10, 0x07, 0x2e, 0x48, 0x95, 0x40, 0x08, 0x4e, 0x1c, 0x11, 0x17, 0x2e, 0xf0, 0x1f, 0x54, 0xa8, + 0x95, 0xb8, 0xb4, 0x02, 0x89, 0x8a, 0x43, 0x44, 0xcd, 0x9f, 0xc0, 0xad, 0x27, 0x34, 0xe3, 0xd9, + 0xf5, 0xce, 0x7e, 0x38, 0x5e, 0xf3, 0x6a, 0xb5, 0xa7, 0x64, 0x67, 0x7e, 0x1f, 0xf3, 0xfb, 0xfe, + 0xfd, 0x66, 0x0c, 0x67, 0x0f, 0x2e, 0x12, 0xd5, 0x74, 0x1a, 0xba, 0x6b, 0x36, 0x3c, 0x4c, 0x9c, + 0x8e, 0xd7, 0xc2, 0x8d, 0xc3, 0x35, 0xdd, 0x72, 0xf7, 0xf5, 0xf5, 0xc6, 0x1e, 0xb6, 0xb1, 0xa7, + 0xfb, 0xd8, 0x50, 0x5d, 0xcf, 0xf1, 0x1d, 0xf9, 0x4c, 0x0f, 0x5a, 0xd5, 0x5d, 0x53, 0x0d, 0xa0, + 0xd5, 0x00, 0x7a, 0xe5, 0xdc, 0x9e, 0xe9, 0xef, 0x77, 0x76, 0xd5, 0x96, 0xd3, 0x6e, 0xec, 0x39, + 0x7b, 0x4e, 0x83, 0x21, 0xed, 0x76, 0x1e, 0xb0, 0x2f, 0xf6, 0xc1, 0xfe, 0xeb, 0x11, 0x5b, 0x51, + 0x22, 0xac, 0x5b, 0x8e, 0x47, 0xd9, 0xc6, 0x19, 0xae, 0x9c, 0xef, 0xc3, 0xb4, 0xf5, 0xd6, 0xbe, + 0x69, 0x63, 0xef, 0x71, 0xc3, 0x3d, 0xd8, 0xa3, 0x0b, 0xa4, 0xd1, 0xc6, 0xbe, 0x9e, 0x86, 0xd5, + 0xc8, 0xc2, 0xf2, 0x3a, 0xb6, 0x6f, 0xb6, 0x71, 0x02, 0xe1, 0xc2, 0x71, 0x08, 0xa4, 0xb5, 0x8f, + 0xdb, 0x7a, 0x1c, 0x4f, 0xf9, 0x6d, 0x01, 0xe6, 0x36, 0x2c, 0xcb, 0x69, 0xe9, 0xbe, 0xe9, 0xd8, + 0x08, 0x93, 0x8e, 0xe5, 0xcb, 0x0e, 0xcc, 0x06, 0xba, 0xf9, 0x8e, 0x6e, 0x1b, 0x16, 0x26, 0x15, + 0xa9, 0x5e, 0x5c, 0x9d, 0x5e, 0x3f, 0xab, 0x0e, 0x52, 0x9f, 0x8a, 0x04, 0x24, 0x6d, 0xf9, 0xc5, + 0x51, 0x6d, 0xa2, 0x7b, 0x54, 0x9b, 0x15, 0xd7, 0x09, 0x8a, 0x53, 0x97, 0x77, 0x61, 0x4e, 0x3f, + 0xd4, 0x4d, 0x4b, 0xdf, 0xb5, 0xf0, 0x75, 0x7b, 0xdb, 0x31, 0x30, 0xa9, 0x14, 0xea, 0xd2, 0xea, + 0xf4, 0x7a, 0x3d, 0xca, 0x91, 0xea, 0x58, 0x3d, 0x5c, 0x53, 0x29, 0x40, 0x13, 0x5b, 0xb8, 0xe5, + 0x3b, 0x9e, 0xb6, 0xd8, 0x3d, 0xaa, 0xcd, 0x6d, 0xc4, 0xb0, 0x51, 0x82, 0x9e, 0xdc, 0x80, 0x93, + 0x64, 0x5f, 0xf7, 0x30, 0x5d, 0xab, 0x14, 0xeb, 0xd2, 0xea, 0x94, 0x36, 0xcf, 0x0f, 0x78, 0xb2, + 0x19, 0x6c, 0xa0, 0x3e, 0x8c, 0xb2, 0x0c, 0x4b, 0x71, 0xcd, 0x5c, 0x73, 0x0c, 0x6c, 0x29, 0x7f, + 0x2a, 0xc0, 0xe9, 0x4d, 0xcf, 0x3c, 0xc4, 0x5e, 0x42, 0x73, 0xbf, 0x90, 0x60, 0xf9, 0x10, 0xdb, + 0x86, 0xe3, 0x21, 0xfc, 0x93, 0x0e, 0x26, 0xfe, 0x8e, 0xee, 0xe9, 0x6d, 0xec, 0x63, 0x8f, 0xaa, + 0x90, 0x0a, 0x74, 0x2e, 0x22, 0x50, 0x68, 0x29, 0xd5, 0x3d, 0xd8, 0x53, 0xb9, 0xa5, 0x54, 0xa4, + 0x3f, 0xfc, 0xf6, 0x23, 0x1f, 0xdb, 0xc4, 0x74, 0x6c, 0xad, 0xc6, 0x8f, 0xb8, 0x7c, 0x2b, 0x9d, + 0x2a, 0xca, 0x62, 0x47, 0x8f, 0xb2, 0xa4, 0xa7, 0x9d, 0x9f, 0x6b, 0xf6, 0xf3, 0xc1, 0xb6, 0x4c, + 0x15, 0x5d, 0xfb, 0x94, 0x1f, 0x27, 0x5d, 0x33, 0x28, 0x9d, 0xa1, 0xf2, 0x9b, 0x02, 0x94, 0x7b, + 0x0a, 0xe3, 0xc7, 0x24, 0xf2, 0x3a, 0x80, 0xc1, 0x56, 0xb6, 0xf5, 0x36, 0x66, 0xaa, 0x39, 0xa9, + 0xc9, 0x9c, 0x38, 0x6c, 0x86, 0x3b, 0x28, 0x02, 0x25, 0x13, 0x98, 0xeb, 0x09, 0x1b, 0x51, 0x6a, + 0x61, 0x14, 0xa5, 0x56, 0x38, 0xa3, 0xb9, 0x5b, 0x31, 0x72, 0x28, 0xc1, 0x40, 0xfe, 0x3e, 0x4c, + 0x79, 0xfc, 0xd0, 0x95, 0x22, 0x0b, 0x82, 0x73, 0xc3, 0x05, 0x01, 0x17, 0x55, 0x9b, 0xe3, 0xcc, + 0xa6, 0x02, 0xd9, 0x51, 0x48, 0x50, 0x59, 0x80, 0x79, 0xea, 0x9c, 0x01, 0x4a, 0x4f, 0x5b, 0xaf, + 0x0a, 0xe2, 0x6a, 0xd3, 0x32, 0x5b, 0x58, 0xbe, 0x0f, 0x53, 0x34, 0x59, 0x18, 0xba, 0xaf, 0x73, + 0x4f, 0xfa, 0x2c, 0x53, 0x68, 0x9a, 0x5a, 0x54, 0x0a, 0x4d, 0x83, 0xe5, 0xfa, 0xee, 0x8f, 0x71, + 0xcb, 0xbf, 0x86, 0x7d, 0xbd, 0xaf, 0xe0, 0xfe, 0x1a, 0x0a, 0xa9, 0xca, 0x67, 0x61, 0xca, 0x76, + 0x0c, 0xcc, 0x0c, 0x52, 0x60, 0x06, 0x09, 0x8f, 0xbe, 0xcd, 0xd7, 0x51, 0x08, 0x11, 0x33, 0x60, + 0x71, 0x28, 0x03, 0x3e, 0x82, 0x79, 0x3b, 0x2e, 0x6e, 0xa5, 0xc4, 0x84, 0x69, 0x0c, 0x56, 0x6a, + 0x42, 0x4b, 0xda, 0xc7, 0x9c, 0x57, 0x52, 0x81, 0x28, 0xc9, 0x44, 0xf9, 0x9b, 0x04, 0x4b, 0x09, + 0x9d, 0x5e, 0x35, 0x89, 0x2f, 0xff, 0x20, 0xa1, 0x57, 0x75, 0x38, 0xbd, 0x52, 0x6c, 0xa6, 0xd5, + 0x50, 0x4b, 0xc1, 0x4a, 0x44, 0xa7, 0x37, 0x60, 0xd2, 0xf4, 0x71, 0x9b, 0xfa, 0x69, 0x31, 0x9f, + 0x94, 0xec, 0x84, 0xda, 0x0c, 0xa7, 0x3d, 0xb9, 0x45, 0xa9, 0xa0, 0x1e, 0x31, 0xe5, 0x2f, 0x05, + 0x58, 0xdc, 0x71, 0x8c, 0x66, 0x6b, 0x1f, 0x1b, 0x1d, 0xcb, 0xb4, 0xf7, 0x2e, 0x39, 0xb6, 0x8f, + 0x1f, 0xf9, 0x63, 0x70, 0x92, 0x3b, 0x50, 0x22, 0x2e, 0x6e, 0xf1, 0xb8, 0xbb, 0x30, 0x58, 0x9e, + 0xb4, 0x33, 0x36, 0x5d, 0xdc, 0xd2, 0x4e, 0x71, 0x1e, 0x25, 0xfa, 0x85, 0x18, 0x45, 0xf9, 0x3e, + 0x7c, 0x44, 0x7c, 0xdd, 0xef, 0x10, 0xe6, 0x4c, 0xd3, 0xeb, 0x17, 0x47, 0xa0, 0xcd, 0xf0, 0xb5, + 0x32, 0xa7, 0xfe, 0x51, 0xef, 0x1b, 0x71, 0xba, 0xca, 0x2b, 0x09, 0x2a, 0x69, 0x68, 0x63, 0xf0, + 0x83, 0xdb, 0xa2, 0x1f, 0xac, 0xe7, 0x97, 0x2d, 0xc3, 0x15, 0x9e, 0x66, 0xc8, 0x44, 0x15, 0x2b, + 0x5f, 0x84, 0x53, 0x84, 0x95, 0x49, 0x6c, 0x50, 0xd7, 0xe2, 0x69, 0x76, 0x91, 0x13, 0x3a, 0xd5, + 0x8c, 0xec, 0x21, 0x01, 0x52, 0xfe, 0x1a, 0x94, 0x5d, 0xc7, 0xc7, 0xb6, 0x6f, 0xea, 0x56, 0x50, + 0x8e, 0x8b, 0x34, 0xc2, 0xbb, 0x47, 0xb5, 0xf2, 0x8e, 0xb0, 0x83, 0x62, 0x90, 0xca, 0xef, 0x24, + 0x58, 0xc9, 0xb6, 0x8e, 0xfc, 0x53, 0x28, 0x07, 0x12, 0x5f, 0xb2, 0x74, 0xb3, 0x1d, 0xf4, 0x16, + 0x5f, 0x1f, 0x2e, 0xad, 0x32, 0x9c, 0x3e, 0x6d, 0x6e, 0xf2, 0xd3, 0x5c, 0xa6, 0xb2, 0x00, 0x46, + 0x50, 0x8c, 0x95, 0xf2, 0xfb, 0x02, 0xcc, 0x08, 0x20, 0x63, 0x08, 0x99, 0xef, 0x09, 0x21, 0xd3, + 0xc8, 0x23, 0x66, 0x56, 0xac, 0xdc, 0x8d, 0xc5, 0xca, 0x5a, 0x1e, 0xa2, 0x83, 0x83, 0xa4, 0x2b, + 0x41, 0x55, 0x80, 0xbf, 0xe4, 0xd8, 0xa4, 0xd3, 0xa6, 0xa5, 0xfb, 0x01, 0xf6, 0xb0, 0xdd, 0xc2, + 0xb4, 0x50, 0xe8, 0xae, 0x79, 0xc5, 0x73, 0x3a, 0x2e, 0x77, 0xa9, 0xd0, 0xf5, 0x37, 0x76, 0xb6, + 0xd8, 0x3a, 0x0a, 0x21, 0x28, 0x74, 0x70, 0x22, 0x5e, 0x26, 0x22, 0x15, 0x91, 0x97, 0xca, 0x10, + 0x42, 0xae, 0x43, 0xc9, 0xa6, 0x05, 0xa5, 0xc4, 0x20, 0x43, 0xd9, 0x59, 0x29, 0x61, 0x3b, 0xb2, + 0x06, 0xc5, 0x8e, 0x69, 0x54, 0x26, 0x19, 0xc0, 0x67, 0x1c, 0xa0, 0x78, 0x73, 0x6b, 0xf3, 0xed, + 0x51, 0xed, 0x4b, 0x59, 0x5d, 0xb0, 0xff, 0xd8, 0xc5, 0x44, 0xbd, 0xb9, 0xb5, 0x89, 0x28, 0xb2, + 0xf2, 0x4c, 0x82, 0x79, 0x41, 0xc8, 0x31, 0xa4, 0x80, 0x1d, 0x31, 0x05, 0x7c, 0x39, 0x87, 0xc9, + 0x32, 0x62, 0xff, 0x57, 0x45, 0x58, 0x16, 0xe0, 0x22, 0x6d, 0xcb, 0xbb, 0x77, 0xeb, 0x87, 0x30, + 0x13, 0x0e, 0x13, 0x97, 0x3d, 0xa7, 0xcd, 0xfd, 0xfb, 0x5b, 0x39, 0xe4, 0x8a, 0x34, 0x5e, 0x81, + 0x73, 0x69, 0xf3, 0xdd, 0xa3, 0xda, 0xcc, 0x95, 0x28, 0x61, 0x24, 0xf2, 0xc9, 0xdd, 0xc8, 0xcb, + 0x16, 0x94, 0x0d, 0xa1, 0xfb, 0xac, 0x94, 0x86, 0x99, 0x66, 0xc4, 0x8e, 0xb5, 0x9f, 0x62, 0xc4, + 0x75, 0x14, 0xa3, 0xad, 0xfc, 0x53, 0x82, 0x4f, 0x32, 0xa4, 0x1c, 0x83, 0x97, 0xdd, 0x13, 0xbd, + 0xec, 0x2b, 0x23, 0x59, 0x23, 0xc3, 0xdf, 0x7e, 0x2d, 0x41, 0xfd, 0x38, 0xfb, 0xe5, 0x4c, 0x0e, + 0x75, 0x28, 0x1d, 0x98, 0xb6, 0xc1, 0xfb, 0xcd, 0x30, 0xdc, 0xbf, 0x6b, 0xda, 0x06, 0x62, 0x3b, + 0x61, 0x42, 0x28, 0x66, 0x25, 0x04, 0xe5, 0x89, 0x04, 0x9f, 0x0e, 0xac, 0x0e, 0x21, 0x0d, 0x29, + 0x33, 0xa9, 0x7c, 0x13, 0x66, 0x3b, 0x36, 0xe9, 0x98, 0x3e, 0x75, 0x98, 0x68, 0xc1, 0x5b, 0xa0, + 0xf3, 0xeb, 0x4d, 0x71, 0x0b, 0xc5, 0x61, 0x95, 0x3f, 0x14, 0x62, 0xf9, 0x84, 0x95, 0xdf, 0x2b, + 0x30, 0x1f, 0x29, 0x3f, 0x84, 0x44, 0x46, 0x9d, 0xb0, 0x7b, 0x45, 0x71, 0x00, 0x94, 0xc4, 0xa1, + 0xa1, 0xe6, 0x46, 0x55, 0xfd, 0x45, 0x86, 0x9a, 0xb0, 0x81, 0x44, 0x3e, 0xf2, 0x0e, 0x94, 0xfb, + 0x13, 0x1d, 0xed, 0xa4, 0xb9, 0x19, 0x56, 0x83, 0x58, 0xd8, 0x10, 0x76, 0xdf, 0x26, 0x56, 0x50, + 0x0c, 0x5f, 0xf9, 0x6f, 0x01, 0x16, 0x52, 0xca, 0xd1, 0x48, 0xf3, 0xe0, 0x0f, 0x01, 0xfa, 0xd4, + 0xb9, 0x4e, 0xd4, 0x7c, 0x53, 0xad, 0x56, 0xa6, 0xf4, 0x23, 0xab, 0x11, 0x8a, 0x32, 0x81, 0x69, + 0x0f, 0x13, 0xec, 0x1d, 0x62, 0xe3, 0xb2, 0xe3, 0xf1, 0xe9, 0xef, 0x1b, 0x39, 0x94, 0x9e, 0x28, + 0x9d, 0xda, 0x02, 0x17, 0x69, 0x1a, 0xf5, 0x09, 0xa3, 0x28, 0x17, 0xb9, 0x09, 0x4b, 0x06, 0x8e, + 0x8e, 0xd1, 0x2c, 0xad, 0x60, 0x83, 0x55, 0xc4, 0xa9, 0xfe, 0x00, 0xbe, 0x99, 0x06, 0x84, 0xd2, + 0x71, 0x95, 0x7f, 0x48, 0xb0, 0x24, 0x9c, 0xec, 0x06, 0x6e, 0xbb, 0x96, 0xee, 0x8f, 0x63, 0xac, + 0xbc, 0x2b, 0xb4, 0x3f, 0x5f, 0xcd, 0xa1, 0xbe, 0xe0, 0x90, 0x59, 0x6d, 0x90, 0xf2, 0x77, 0x09, + 0x3e, 0x4e, 0xc5, 0x18, 0x43, 0xa2, 0xbd, 0x23, 0x26, 0xda, 0xcf, 0x47, 0x90, 0x2b, 0x23, 0xcd, + 0xbe, 0xcc, 0x92, 0xaa, 0xd9, 0x1b, 0x93, 0x3e, 0xbc, 0x7e, 0x55, 0x79, 0x5e, 0x14, 0xda, 0x6e, + 0x32, 0x8e, 0xfe, 0x44, 0xcc, 0x28, 0x85, 0xa1, 0x32, 0x4a, 0x22, 0xd1, 0x16, 0x73, 0x26, 0x5a, + 0x42, 0x46, 0x4b, 0xb4, 0x77, 0x61, 0x46, 0xac, 0x3e, 0xa5, 0x21, 0x6f, 0x3f, 0x19, 0xe9, 0xa6, + 0x50, 0x9d, 0x44, 0x4a, 0xf2, 0x55, 0x58, 0x24, 0xbe, 0xd7, 0x69, 0xf9, 0x1d, 0x0f, 0x1b, 0x91, + 0x9b, 0xb3, 0x49, 0x96, 0x4f, 0x2a, 0xdd, 0xa3, 0xda, 0x62, 0x33, 0x65, 0x1f, 0xa5, 0x62, 0xc5, + 0x3b, 0x67, 0x42, 0xde, 0xe7, 0xce, 0x99, 0x64, 0x75, 0x32, 0xcf, 0xc4, 0xce, 0x39, 0x6a, 0xb5, + 0x0f, 0xa1, 0x73, 0x1e, 0xe0, 0x65, 0x03, 0x3b, 0x67, 0x3f, 0xe5, 0x02, 0xb5, 0x57, 0xd5, 0x8e, + 0x29, 0x9b, 0xf1, 0x7b, 0xd2, 0x5c, 0x37, 0xa8, 0xb7, 0xe1, 0xc4, 0x03, 0xd3, 0x62, 0xcc, 0x4a, + 0x79, 0x5e, 0x11, 0x2e, 0x33, 0x24, 0x6d, 0x96, 0xb3, 0x3a, 0xd1, 0xfb, 0x26, 0x28, 0xa0, 0x16, + 0xef, 0xb4, 0xa3, 0x5a, 0x79, 0x9f, 0x3b, 0xed, 0xe8, 0x39, 0x33, 0xfc, 0xf3, 0xaf, 0x62, 0xa7, + 0x9d, 0x6a, 0xef, 0xf1, 0x77, 0xda, 0x74, 0xf2, 0xa2, 0x7f, 0x89, 0xab, 0xb7, 0x82, 0x09, 0x3d, + 0x9c, 0xbc, 0xb6, 0x83, 0x0d, 0xd4, 0x87, 0x51, 0x9e, 0x4b, 0x50, 0x16, 0xcd, 0x39, 0x52, 0xa3, + 0xf7, 0x44, 0x82, 0x05, 0x4f, 0x20, 0x13, 0x7d, 0xc8, 0x58, 0xcb, 0xe3, 0x4e, 0xbd, 0xcb, 0xe3, + 0x4f, 0x38, 0xc3, 0x85, 0x94, 0x4d, 0x94, 0xc6, 0x4a, 0x59, 0x82, 0x34, 0x58, 0xe5, 0x5f, 0x11, + 0x01, 0x7b, 0x8f, 0x59, 0x23, 0x09, 0x58, 0x87, 0x12, 0xf3, 0xd2, 0x98, 0x71, 0x36, 0x75, 0x5f, + 0x47, 0x6c, 0x47, 0xf6, 0xa0, 0xdc, 0xcf, 0xc7, 0x74, 0x9d, 0xe5, 0xef, 0x63, 0x6f, 0x60, 0xfb, + 0x99, 0x3d, 0xf6, 0x36, 0xc7, 0x2e, 0xf2, 0x9a, 0x02, 0x45, 0x14, 0xe3, 0xa0, 0xfc, 0xb2, 0x00, + 0xb3, 0xb1, 0xd7, 0x8c, 0xd4, 0x37, 0x18, 0xe9, 0x5d, 0xbf, 0xc1, 0xfc, 0x5c, 0x82, 0x45, 0x4f, + 0x3c, 0x48, 0xd4, 0x01, 0xd6, 0x73, 0x3d, 0xc8, 0xf4, 0x3c, 0xe0, 0x0c, 0x67, 0xbf, 0x98, 0xb6, + 0x8b, 0x52, 0xb9, 0x29, 0xa7, 0x21, 0x15, 0x5a, 0xf9, 0x73, 0x11, 0x2a, 0x59, 0x8a, 0x96, 0x7f, + 0x26, 0xc1, 0x52, 0x4f, 0xa0, 0x58, 0x20, 0x8f, 0xa6, 0xb6, 0xb0, 0xff, 0xbf, 0x95, 0x46, 0x13, + 0xa5, 0xb3, 0x12, 0x0f, 0x11, 0x1d, 0x06, 0x47, 0x7b, 0x3f, 0x4b, 0x1e, 0x42, 0x18, 0x30, 0xd3, + 0x59, 0x09, 0xef, 0x4b, 0xa5, 0x63, 0xdf, 0x97, 0x7e, 0x04, 0x27, 0x3c, 0x36, 0xa2, 0xd1, 0x4e, + 0x85, 0x26, 0xd8, 0xf3, 0xc3, 0xdc, 0xd6, 0x24, 0xe6, 0xbb, 0xb0, 0x7a, 0xf4, 0xbe, 0x09, 0x0a, + 0xa8, 0x2a, 0x7f, 0x94, 0x20, 0xe1, 0x7b, 0x23, 0x05, 0xaf, 0x0e, 0xe0, 0xfe, 0x9f, 0x0a, 0x0d, + 0x59, 0x44, 0xb4, 0x18, 0x21, 0xaa, 0x69, 0x2f, 0xde, 0x54, 0x27, 0x5e, 0xbe, 0xa9, 0x4e, 0xbc, + 0x7e, 0x53, 0x9d, 0x78, 0xd2, 0xad, 0x4a, 0x2f, 0xba, 0x55, 0xe9, 0x65, 0xb7, 0x2a, 0xbd, 0xee, + 0x56, 0xa5, 0x7f, 0x77, 0xab, 0xd2, 0xd3, 0xff, 0x54, 0x27, 0xee, 0x9d, 0x19, 0xf4, 0x4b, 0x88, + 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x11, 0xc0, 0x9d, 0x25, 0x28, 0x21, 0x00, 0x00, } func (m *AllocationResult) Marshal() (dAtA []byte, err error) { @@ -742,6 +1243,247 @@ func (m *AllocationResult) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *AllocationResultModel) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AllocationResultModel) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AllocationResultModel) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *DriverAllocationResult) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DriverAllocationResult) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DriverAllocationResult) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.AllocationResultModel.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.VendorRequestParameters.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *DriverRequests) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DriverRequests) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DriverRequests) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Requests) > 0 { + for iNdEx := len(m.Requests) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Requests[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + { + size, err := m.VendorParameters.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(m.DriverName) + copy(dAtA[i:], m.DriverName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.DriverName))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *NodeResourceModel) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NodeResourceModel) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NodeResourceModel) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *NodeResourceSlice) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NodeResourceSlice) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NodeResourceSlice) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.NodeResourceModel.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + i -= len(m.DriverName) + copy(dAtA[i:], m.DriverName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.DriverName))) + i-- + dAtA[i] = 0x1a + i -= len(m.NodeName) + copy(dAtA[i:], m.NodeName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.NodeName))) + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *NodeResourceSliceList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NodeResourceSliceList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NodeResourceSliceList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *PodSchedulingContext) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1059,6 +1801,120 @@ func (m *ResourceClaimList) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ResourceClaimParameters) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceClaimParameters) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClaimParameters) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.DriverRequests) > 0 { + for iNdEx := len(m.DriverRequests) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.DriverRequests[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + i-- + if m.Shareable { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + if m.GeneratedFrom != nil { + { + size, err := m.GeneratedFrom.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourceClaimParametersList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceClaimParametersList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClaimParametersList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *ResourceClaimParametersReference) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1394,6 +2250,16 @@ func (m *ResourceClass) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.StructuredParameters != nil { + i-- + if *m.StructuredParameters { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x28 + } if m.SuitableNodes != nil { { size, err := m.SuitableNodes.MarshalToSizedBuffer(dAtA[:i]) @@ -1483,6 +2349,126 @@ func (m *ResourceClassList) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ResourceClassParameters) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceClassParameters) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClassParameters) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Filters) > 0 { + for iNdEx := len(m.Filters) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Filters[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if len(m.VendorParameters) > 0 { + for iNdEx := len(m.VendorParameters) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.VendorParameters[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if m.GeneratedFrom != nil { + { + size, err := m.GeneratedFrom.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourceClassParametersList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceClassParametersList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClassParametersList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *ResourceClassParametersReference) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1526,6 +2512,67 @@ func (m *ResourceClassParametersReference) MarshalToSizedBuffer(dAtA []byte) (in return len(dAtA) - i, nil } +func (m *ResourceFilter) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceFilter) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceFilter) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.ResourceFilterModel.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(m.DriverName) + copy(dAtA[i:], m.DriverName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.DriverName))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourceFilterModel) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceFilterModel) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceFilterModel) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func (m *ResourceHandle) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1546,6 +2593,18 @@ func (m *ResourceHandle) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.StructuredData != nil { + { + size, err := m.StructuredData.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } i -= len(m.Data) copy(dAtA[i:], m.Data) i = encodeVarintGenerated(dAtA, i, uint64(len(m.Data))) @@ -1559,6 +2618,172 @@ func (m *ResourceHandle) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ResourceRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.ResourceRequestModel.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.VendorParameters.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourceRequestModel) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceRequestModel) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceRequestModel) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *StructuredResourceHandle) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *StructuredResourceHandle) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *StructuredResourceHandle) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Results) > 0 { + for iNdEx := len(m.Results) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Results[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } + i -= len(m.NodeName) + copy(dAtA[i:], m.NodeName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.NodeName))) + i-- + dAtA[i] = 0x22 + { + size, err := m.VendorClaimParameters.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.VendorClassParameters.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *VendorParameters) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *VendorParameters) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *VendorParameters) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Parameters.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(m.DriverName) + copy(dAtA[i:], m.DriverName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.DriverName))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { offset -= sovGenerated(v) base := offset @@ -1590,6 +2815,90 @@ func (m *AllocationResult) Size() (n int) { return n } +func (m *AllocationResultModel) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *DriverAllocationResult) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.VendorRequestParameters.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.AllocationResultModel.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *DriverRequests) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.DriverName) + n += 1 + l + sovGenerated(uint64(l)) + l = m.VendorParameters.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Requests) > 0 { + for _, e := range m.Requests { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *NodeResourceModel) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *NodeResourceSlice) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.NodeName) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.DriverName) + n += 1 + l + sovGenerated(uint64(l)) + l = m.NodeResourceModel.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *NodeResourceSliceList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + func (m *PodSchedulingContext) Size() (n int) { if m == nil { return 0 @@ -1703,6 +3012,45 @@ func (m *ResourceClaimList) Size() (n int) { return n } +func (m *ResourceClaimParameters) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if m.GeneratedFrom != nil { + l = m.GeneratedFrom.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + n += 2 + if len(m.DriverRequests) > 0 { + for _, e := range m.DriverRequests { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ResourceClaimParametersList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + func (m *ResourceClaimParametersReference) Size() (n int) { if m == nil { return 0 @@ -1835,6 +3183,9 @@ func (m *ResourceClass) Size() (n int) { l = m.SuitableNodes.Size() n += 1 + l + sovGenerated(uint64(l)) } + if m.StructuredParameters != nil { + n += 2 + } return n } @@ -1855,6 +3206,50 @@ func (m *ResourceClassList) Size() (n int) { return n } +func (m *ResourceClassParameters) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if m.GeneratedFrom != nil { + l = m.GeneratedFrom.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if len(m.VendorParameters) > 0 { + for _, e := range m.VendorParameters { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.Filters) > 0 { + for _, e := range m.Filters { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ResourceClassParametersList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + func (m *ResourceClassParametersReference) Size() (n int) { if m == nil { return 0 @@ -1872,6 +3267,28 @@ func (m *ResourceClassParametersReference) Size() (n int) { return n } +func (m *ResourceFilter) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.DriverName) + n += 1 + l + sovGenerated(uint64(l)) + l = m.ResourceFilterModel.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ResourceFilterModel) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func (m *ResourceHandle) Size() (n int) { if m == nil { return 0 @@ -1882,6 +3299,66 @@ func (m *ResourceHandle) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = len(m.Data) n += 1 + l + sovGenerated(uint64(l)) + if m.StructuredData != nil { + l = m.StructuredData.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *ResourceRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.VendorParameters.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.ResourceRequestModel.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ResourceRequestModel) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *StructuredResourceHandle) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.VendorClassParameters.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.VendorClaimParameters.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.NodeName) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Results) > 0 { + for _, e := range m.Results { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *VendorParameters) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.DriverName) + n += 1 + l + sovGenerated(uint64(l)) + l = m.Parameters.Size() + n += 1 + l + sovGenerated(uint64(l)) return n } @@ -1908,6 +3385,81 @@ func (this *AllocationResult) String() string { }, "") return s } +func (this *AllocationResultModel) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&AllocationResultModel{`, + `}`, + }, "") + return s +} +func (this *DriverAllocationResult) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&DriverAllocationResult{`, + `VendorRequestParameters:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.VendorRequestParameters), "RawExtension", "runtime.RawExtension", 1), `&`, ``, 1) + `,`, + `AllocationResultModel:` + strings.Replace(strings.Replace(this.AllocationResultModel.String(), "AllocationResultModel", "AllocationResultModel", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *DriverRequests) String() string { + if this == nil { + return "nil" + } + repeatedStringForRequests := "[]ResourceRequest{" + for _, f := range this.Requests { + repeatedStringForRequests += strings.Replace(strings.Replace(f.String(), "ResourceRequest", "ResourceRequest", 1), `&`, ``, 1) + "," + } + repeatedStringForRequests += "}" + s := strings.Join([]string{`&DriverRequests{`, + `DriverName:` + fmt.Sprintf("%v", this.DriverName) + `,`, + `VendorParameters:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.VendorParameters), "RawExtension", "runtime.RawExtension", 1), `&`, ``, 1) + `,`, + `Requests:` + repeatedStringForRequests + `,`, + `}`, + }, "") + return s +} +func (this *NodeResourceModel) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NodeResourceModel{`, + `}`, + }, "") + return s +} +func (this *NodeResourceSlice) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NodeResourceSlice{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v11.ObjectMeta", 1), `&`, ``, 1) + `,`, + `NodeName:` + fmt.Sprintf("%v", this.NodeName) + `,`, + `DriverName:` + fmt.Sprintf("%v", this.DriverName) + `,`, + `NodeResourceModel:` + strings.Replace(strings.Replace(this.NodeResourceModel.String(), "NodeResourceModel", "NodeResourceModel", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *NodeResourceSliceList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]NodeResourceSlice{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "NodeResourceSlice", "NodeResourceSlice", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&NodeResourceSliceList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v11.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} func (this *PodSchedulingContext) String() string { if this == nil { return "nil" @@ -2003,6 +3555,40 @@ func (this *ResourceClaimList) String() string { }, "") return s } +func (this *ResourceClaimParameters) String() string { + if this == nil { + return "nil" + } + repeatedStringForDriverRequests := "[]DriverRequests{" + for _, f := range this.DriverRequests { + repeatedStringForDriverRequests += strings.Replace(strings.Replace(f.String(), "DriverRequests", "DriverRequests", 1), `&`, ``, 1) + "," + } + repeatedStringForDriverRequests += "}" + s := strings.Join([]string{`&ResourceClaimParameters{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v11.ObjectMeta", 1), `&`, ``, 1) + `,`, + `GeneratedFrom:` + strings.Replace(this.GeneratedFrom.String(), "ResourceClaimParametersReference", "ResourceClaimParametersReference", 1) + `,`, + `Shareable:` + fmt.Sprintf("%v", this.Shareable) + `,`, + `DriverRequests:` + repeatedStringForDriverRequests + `,`, + `}`, + }, "") + return s +} +func (this *ResourceClaimParametersList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]ResourceClaimParameters{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ResourceClaimParameters", "ResourceClaimParameters", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&ResourceClaimParametersList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v11.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} func (this *ResourceClaimParametersReference) String() string { if this == nil { return "nil" @@ -2103,6 +3689,7 @@ func (this *ResourceClass) String() string { `DriverName:` + fmt.Sprintf("%v", this.DriverName) + `,`, `ParametersRef:` + strings.Replace(this.ParametersRef.String(), "ResourceClassParametersReference", "ResourceClassParametersReference", 1) + `,`, `SuitableNodes:` + strings.Replace(fmt.Sprintf("%v", this.SuitableNodes), "NodeSelector", "v1.NodeSelector", 1) + `,`, + `StructuredParameters:` + valueToStringGenerated(this.StructuredParameters) + `,`, `}`, }, "") return s @@ -2123,6 +3710,45 @@ func (this *ResourceClassList) String() string { }, "") return s } +func (this *ResourceClassParameters) String() string { + if this == nil { + return "nil" + } + repeatedStringForVendorParameters := "[]VendorParameters{" + for _, f := range this.VendorParameters { + repeatedStringForVendorParameters += strings.Replace(strings.Replace(f.String(), "VendorParameters", "VendorParameters", 1), `&`, ``, 1) + "," + } + repeatedStringForVendorParameters += "}" + repeatedStringForFilters := "[]ResourceFilter{" + for _, f := range this.Filters { + repeatedStringForFilters += strings.Replace(strings.Replace(f.String(), "ResourceFilter", "ResourceFilter", 1), `&`, ``, 1) + "," + } + repeatedStringForFilters += "}" + s := strings.Join([]string{`&ResourceClassParameters{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v11.ObjectMeta", 1), `&`, ``, 1) + `,`, + `GeneratedFrom:` + strings.Replace(this.GeneratedFrom.String(), "ResourceClassParametersReference", "ResourceClassParametersReference", 1) + `,`, + `VendorParameters:` + repeatedStringForVendorParameters + `,`, + `Filters:` + repeatedStringForFilters + `,`, + `}`, + }, "") + return s +} +func (this *ResourceClassParametersList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]ResourceClassParameters{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ResourceClassParameters", "ResourceClassParameters", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&ResourceClassParametersList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v11.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} func (this *ResourceClassParametersReference) String() string { if this == nil { return "nil" @@ -2136,6 +3762,26 @@ func (this *ResourceClassParametersReference) String() string { }, "") return s } +func (this *ResourceFilter) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ResourceFilter{`, + `DriverName:` + fmt.Sprintf("%v", this.DriverName) + `,`, + `ResourceFilterModel:` + strings.Replace(strings.Replace(this.ResourceFilterModel.String(), "ResourceFilterModel", "ResourceFilterModel", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *ResourceFilterModel) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ResourceFilterModel{`, + `}`, + }, "") + return s +} func (this *ResourceHandle) String() string { if this == nil { return "nil" @@ -2143,6 +3789,56 @@ func (this *ResourceHandle) String() string { s := strings.Join([]string{`&ResourceHandle{`, `DriverName:` + fmt.Sprintf("%v", this.DriverName) + `,`, `Data:` + fmt.Sprintf("%v", this.Data) + `,`, + `StructuredData:` + strings.Replace(this.StructuredData.String(), "StructuredResourceHandle", "StructuredResourceHandle", 1) + `,`, + `}`, + }, "") + return s +} +func (this *ResourceRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ResourceRequest{`, + `VendorParameters:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.VendorParameters), "RawExtension", "runtime.RawExtension", 1), `&`, ``, 1) + `,`, + `ResourceRequestModel:` + strings.Replace(strings.Replace(this.ResourceRequestModel.String(), "ResourceRequestModel", "ResourceRequestModel", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *ResourceRequestModel) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ResourceRequestModel{`, + `}`, + }, "") + return s +} +func (this *StructuredResourceHandle) String() string { + if this == nil { + return "nil" + } + repeatedStringForResults := "[]DriverAllocationResult{" + for _, f := range this.Results { + repeatedStringForResults += strings.Replace(strings.Replace(f.String(), "DriverAllocationResult", "DriverAllocationResult", 1), `&`, ``, 1) + "," + } + repeatedStringForResults += "}" + s := strings.Join([]string{`&StructuredResourceHandle{`, + `VendorClassParameters:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.VendorClassParameters), "RawExtension", "runtime.RawExtension", 1), `&`, ``, 1) + `,`, + `VendorClaimParameters:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.VendorClaimParameters), "RawExtension", "runtime.RawExtension", 1), `&`, ``, 1) + `,`, + `NodeName:` + fmt.Sprintf("%v", this.NodeName) + `,`, + `Results:` + repeatedStringForResults + `,`, + `}`, + }, "") + return s +} +func (this *VendorParameters) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&VendorParameters{`, + `DriverName:` + fmt.Sprintf("%v", this.DriverName) + `,`, + `Parameters:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Parameters), "RawExtension", "runtime.RawExtension", 1), `&`, ``, 1) + `,`, `}`, }, "") return s @@ -2295,6 +3991,668 @@ func (m *AllocationResult) Unmarshal(dAtA []byte) error { } return nil } +func (m *AllocationResultModel) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AllocationResultModel: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AllocationResultModel: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DriverAllocationResult) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DriverAllocationResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DriverAllocationResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VendorRequestParameters", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.VendorRequestParameters.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AllocationResultModel", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.AllocationResultModel.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DriverRequests) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DriverRequests: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DriverRequests: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DriverName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DriverName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VendorParameters", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.VendorParameters.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Requests", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Requests = append(m.Requests, ResourceRequest{}) + if err := m.Requests[len(m.Requests)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NodeResourceModel) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NodeResourceModel: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NodeResourceModel: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NodeResourceSlice) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NodeResourceSlice: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NodeResourceSlice: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NodeName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DriverName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DriverName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeResourceModel", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.NodeResourceModel.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NodeResourceSliceList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NodeResourceSliceList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NodeResourceSliceList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, NodeResourceSlice{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *PodSchedulingContext) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -3203,6 +5561,296 @@ func (m *ResourceClaimList) Unmarshal(dAtA []byte) error { } return nil } +func (m *ResourceClaimParameters) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceClaimParameters: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceClaimParameters: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GeneratedFrom", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.GeneratedFrom == nil { + m.GeneratedFrom = &ResourceClaimParametersReference{} + } + if err := m.GeneratedFrom.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Shareable", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Shareable = bool(v != 0) + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DriverRequests", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DriverRequests = append(m.DriverRequests, DriverRequests{}) + if err := m.DriverRequests[len(m.DriverRequests)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceClaimParametersList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceClaimParametersList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceClaimParametersList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, ResourceClaimParameters{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *ResourceClaimParametersReference) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -4300,6 +6948,27 @@ func (m *ResourceClass) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StructuredParameters", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.StructuredParameters = &b default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -4438,6 +7107,310 @@ func (m *ResourceClassList) Unmarshal(dAtA []byte) error { } return nil } +func (m *ResourceClassParameters) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceClassParameters: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceClassParameters: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GeneratedFrom", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.GeneratedFrom == nil { + m.GeneratedFrom = &ResourceClassParametersReference{} + } + if err := m.GeneratedFrom.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VendorParameters", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.VendorParameters = append(m.VendorParameters, VendorParameters{}) + if err := m.VendorParameters[len(m.VendorParameters)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Filters", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Filters = append(m.Filters, ResourceFilter{}) + if err := m.Filters[len(m.Filters)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceClassParametersList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceClassParametersList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceClassParametersList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, ResourceClassParameters{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *ResourceClassParametersReference) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -4616,6 +7589,171 @@ func (m *ResourceClassParametersReference) Unmarshal(dAtA []byte) error { } return nil } +func (m *ResourceFilter) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceFilter: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceFilter: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DriverName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DriverName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceFilterModel", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ResourceFilterModel.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceFilterModel) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceFilterModel: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceFilterModel: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *ResourceHandle) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -4709,6 +7847,505 @@ func (m *ResourceHandle) Unmarshal(dAtA []byte) error { } m.Data = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StructuredData", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.StructuredData == nil { + m.StructuredData = &StructuredResourceHandle{} + } + if err := m.StructuredData.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VendorParameters", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.VendorParameters.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceRequestModel", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ResourceRequestModel.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceRequestModel) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceRequestModel: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceRequestModel: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *StructuredResourceHandle) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: StructuredResourceHandle: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StructuredResourceHandle: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VendorClassParameters", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.VendorClassParameters.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VendorClaimParameters", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.VendorClaimParameters.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NodeName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Results", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Results = append(m.Results, DriverAllocationResult{}) + if err := m.Results[len(m.Results)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *VendorParameters) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: VendorParameters: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: VendorParameters: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DriverName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DriverName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Parameters", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Parameters.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/staging/src/k8s.io/api/resource/v1alpha2/generated.proto b/staging/src/k8s.io/api/resource/v1alpha2/generated.proto index c9f1ec1c0ff..2248d551d9d 100644 --- a/staging/src/k8s.io/api/resource/v1alpha2/generated.proto +++ b/staging/src/k8s.io/api/resource/v1alpha2/generated.proto @@ -63,6 +63,72 @@ message AllocationResult { optional bool shareable = 3; } +// AllocationResultModel must have one and only one field set. +message AllocationResultModel { +} + +// DriverAllocationResult contains vendor parameters and the allocation result for +// one request. +message DriverAllocationResult { + // VendorRequestParameters are the per-request configuration parameters + // from the time that the claim was allocated. + // + // +optional + optional k8s.io.apimachinery.pkg.runtime.RawExtension vendorRequestParameters = 1; + + optional AllocationResultModel allocationResultModel = 2; +} + +// DriverRequests describes all resources that are needed from one particular driver. +message DriverRequests { + // DriverName is the name used by the DRA driver kubelet plugin. + optional string driverName = 1; + + // VendorParameters are arbitrary setup parameters for all requests of the + // claim. They are ignored while allocating the claim. + // + // +optional + optional k8s.io.apimachinery.pkg.runtime.RawExtension vendorParameters = 2; + + // Requests describes all resources that are needed from the driver. + // +listType=atomic + repeated ResourceRequest requests = 3; +} + +// NodeResourceModel must have one and only one field set. +message NodeResourceModel { +} + +// NodeResourceSlice provides information about available +// resources on individual nodes. +message NodeResourceSlice { + // Standard object metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // NodeName identifies the node where the capacity is available. + // A field selector can be used to list only NodeResourceSlice + // objects with a certain node name. + optional string nodeName = 2; + + // DriverName identifies the DRA driver providing the capacity information. + // A field selector can be used to list only NodeResourceSlice + // objects with a certain driver name. + optional string driverName = 3; + + optional NodeResourceModel nodeResourceModel = 4; +} + +// NodeResourceSliceList is a collection of NodeResourceSlices. +message NodeResourceSliceList { + // Standard list metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // Items is the list of node resource capacity objects. + repeated NodeResourceSlice items = 2; +} + // PodSchedulingContext objects hold information that is needed to schedule // a Pod with ResourceClaims that use "WaitForFirstConsumer" allocation // mode. @@ -176,6 +242,45 @@ message ResourceClaimList { repeated ResourceClaim items = 2; } +// ResourceClaimParameters defines resource requests for a ResourceClaim in an +// in-tree format understood by Kubernetes. +message ResourceClaimParameters { + // Standard object metadata + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // If this object was created from some other resource, then this links + // back to that resource. This field is used to find the in-tree representation + // of the claim parameters when the parameter reference of the claim refers + // to some unknown type. + // +optional + optional ResourceClaimParametersReference generatedFrom = 2; + + // Shareable indicates whether the allocated claim is meant to be shareable + // by multiple consumers at the same time. + // +optional + optional bool shareable = 3; + + // DriverRequests describes all resources that are needed for the + // allocated claim. A single claim may use resources coming from + // different drivers. For each driver, this array has at most one + // entry which then may have one or more per-driver requests. + // + // May be empty, in which case the claim can always be allocated. + // + // +listType=atomic + repeated DriverRequests driverRequests = 4; +} + +// ResourceClaimParametersList is a collection of ResourceClaimParameters. +message ResourceClaimParametersList { + // Standard list metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // Items is the list of node resource capacity objects. + repeated ResourceClaimParameters items = 2; +} + // ResourceClaimParametersReference contains enough information to let you // locate the parameters for a ResourceClaim. The object must be in the same // namespace as the ResourceClaim. @@ -344,6 +449,11 @@ message ResourceClass { // Setting this field is optional. If null, all nodes are candidates. // +optional optional k8s.io.api.core.v1.NodeSelector suitableNodes = 4; + + // If and only if allocation of claims using this class is handled + // via structured parameters, then StructuredParameters must be set to true. + // +optional + optional bool structuredParameters = 5; } // ResourceClassList is a collection of classes. @@ -356,6 +466,43 @@ message ResourceClassList { repeated ResourceClass items = 2; } +// ResourceClassParameters defines resource requests for a ResourceClass in an +// in-tree format understood by Kubernetes. +message ResourceClassParameters { + // Standard object metadata + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // If this object was created from some other resource, then this links + // back to that resource. This field is used to find the in-tree representation + // of the class parameters when the parameter reference of the class refers + // to some unknown type. + // +optional + optional ResourceClassParametersReference generatedFrom = 2; + + // VendorParameters are arbitrary setup parameters for all claims using + // this class. They are ignored while allocating the claim. There must + // not be more than one entry per driver. + // + // +listType=atomic + // +optional + repeated VendorParameters vendorParameters = 3; + + // Filters describes additional contraints that must be met when using the class. + // + // +listType=atomic + repeated ResourceFilter filters = 4; +} + +// ResourceClassParametersList is a collection of ResourceClassParameters. +message ResourceClassParametersList { + // Standard list metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // Items is the list of node resource capacity objects. + repeated ResourceClassParameters items = 2; +} + // ResourceClassParametersReference contains enough information to let you // locate the parameters for a ResourceClass. message ResourceClassParametersReference { @@ -379,6 +526,18 @@ message ResourceClassParametersReference { optional string namespace = 4; } +// ResourceFilter is a filter for resources from one particular driver. +message ResourceFilter { + // DriverName is the name used by the DRA driver kubelet plugin. + optional string driverName = 1; + + optional ResourceFilterModel resourceFilterModel = 2; +} + +// ResourceFilterModel must have one and only one field set. +message ResourceFilterModel { +} + // ResourceHandle holds opaque resource data for processing by a specific kubelet plugin. message ResourceHandle { // DriverName specifies the name of the resource driver whose kubelet @@ -398,5 +557,61 @@ message ResourceHandle { // future, but not reduced. // +optional optional string data = 2; + + // If StructuredData is set, then it needs to be used instead of Data. + // + // +optional + optional StructuredResourceHandle structuredData = 5; +} + +// ResourceRequest is a request for resources from one particular driver. +message ResourceRequest { + // VendorParameters are arbitrary setup parameters for the requested + // resource. They are ignored while allocating a claim. + // + // +optional + optional k8s.io.apimachinery.pkg.runtime.RawExtension vendorParameters = 1; + + optional ResourceRequestModel resourceRequestModel = 2; +} + +// ResourceRequestModel must have one and only one field set. +message ResourceRequestModel { +} + +// StructuredResourceHandle is the in-tree representation of the allocation result. +message StructuredResourceHandle { + // VendorClassParameters are the per-claim configuration parameters + // from the resource class at the time that the claim was allocated. + // + // +optional + optional k8s.io.apimachinery.pkg.runtime.RawExtension vendorClassParameters = 1; + + // VendorClaimParameters are the per-claim configuration parameters + // from the resource claim parameters at the time that the claim was + // allocated. + // + // +optional + optional k8s.io.apimachinery.pkg.runtime.RawExtension vendorClaimParameters = 2; + + // NodeName is the name of the node providing the necessary resources. + optional string nodeName = 4; + + // Results lists all allocated driver resources. + // + // +listType=atomic + repeated DriverAllocationResult results = 5; +} + +// VendorParameters are opaque parameters for one particular driver. +message VendorParameters { + // DriverName is the name used by the DRA driver kubelet plugin. + optional string driverName = 1; + + // Parameters can be arbitrary setup parameters. They are ignored while + // allocating a claim. + // + // +optional + optional k8s.io.apimachinery.pkg.runtime.RawExtension parameters = 2; } diff --git a/staging/src/k8s.io/api/resource/v1alpha2/register.go b/staging/src/k8s.io/api/resource/v1alpha2/register.go index 6e0d7ceb988..0d948096bc5 100644 --- a/staging/src/k8s.io/api/resource/v1alpha2/register.go +++ b/staging/src/k8s.io/api/resource/v1alpha2/register.go @@ -52,6 +52,12 @@ func addKnownTypes(scheme *runtime.Scheme) error { &ResourceClaimTemplateList{}, &PodSchedulingContext{}, &PodSchedulingContextList{}, + &NodeResourceSlice{}, + &NodeResourceSliceList{}, + &ResourceClaimParameters{}, + &ResourceClaimParametersList{}, + &ResourceClassParameters{}, + &ResourceClassParametersList{}, ) // Add common types diff --git a/staging/src/k8s.io/api/resource/v1alpha2/types.go b/staging/src/k8s.io/api/resource/v1alpha2/types.go index f862cd960b4..7fcbba38511 100644 --- a/staging/src/k8s.io/api/resource/v1alpha2/types.go +++ b/staging/src/k8s.io/api/resource/v1alpha2/types.go @@ -19,9 +19,16 @@ package v1alpha2 import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" ) +const ( + // Finalizer is the finalizer that gets set for claims + // which were allocated through a builtin controller. + Finalizer = "dra.k8s.io/delete-protection" +) + // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.26 @@ -192,11 +199,57 @@ type ResourceHandle struct { // future, but not reduced. // +optional Data string `json:"data,omitempty" protobuf:"bytes,2,opt,name=data"` + + // If StructuredData is set, then it needs to be used instead of Data. + // + // +optional + StructuredData *StructuredResourceHandle `json:"structuredData,omitempty" protobuf:"bytes,5,opt,name=structuredData"` } // ResourceHandleDataMaxSize represents the maximum size of resourceHandle.data. const ResourceHandleDataMaxSize = 16 * 1024 +// StructuredResourceHandle is the in-tree representation of the allocation result. +type StructuredResourceHandle struct { + // VendorClassParameters are the per-claim configuration parameters + // from the resource class at the time that the claim was allocated. + // + // +optional + VendorClassParameters runtime.RawExtension `json:"vendorClassParameters,omitempty" protobuf:"bytes,1,opt,name=vendorClassParameters"` + + // VendorClaimParameters are the per-claim configuration parameters + // from the resource claim parameters at the time that the claim was + // allocated. + // + // +optional + VendorClaimParameters runtime.RawExtension `json:"vendorClaimParameters,omitempty" protobuf:"bytes,2,opt,name=vendorClaimParameters"` + + // NodeName is the name of the node providing the necessary resources. + NodeName string `json:"nodeName" protobuf:"bytes,4,name=nodeName"` + + // Results lists all allocated driver resources. + // + // +listType=atomic + Results []DriverAllocationResult `json:"results" protobuf:"bytes,5,name=results"` +} + +// DriverAllocationResult contains vendor parameters and the allocation result for +// one request. +type DriverAllocationResult struct { + // VendorRequestParameters are the per-request configuration parameters + // from the time that the claim was allocated. + // + // +optional + VendorRequestParameters runtime.RawExtension `json:"vendorRequestParameters,omitempty" protobuf:"bytes,1,opt,name=vendorRequestParameters"` + + AllocationResultModel `json:",inline" protobuf:"bytes,2,name=allocationResultModel"` +} + +// AllocationResultModel must have one and only one field set. +type AllocationResultModel struct { + // TODO: implement one structured parameter model +} + // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.26 @@ -347,6 +400,11 @@ type ResourceClass struct { // Setting this field is optional. If null, all nodes are candidates. // +optional SuitableNodes *v1.NodeSelector `json:"suitableNodes,omitempty" protobuf:"bytes,4,opt,name=suitableNodes"` + + // If and only if allocation of claims using this class is handled + // via structured parameters, then StructuredParameters must be set to true. + // +optional + StructuredParameters *bool `json:"structuredParameters,omitempty" protobuf:"bytes,5,opt,name=structuredParameters"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -462,3 +520,199 @@ type ResourceClaimTemplateList struct { // Items is the list of resource claim templates. Items []ResourceClaimTemplate `json:"items" protobuf:"bytes,2,rep,name=items"` } + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.30 + +// NodeResourceSlice provides information about available +// resources on individual nodes. +type NodeResourceSlice struct { + metav1.TypeMeta `json:",inline"` + // Standard object metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // NodeName identifies the node where the capacity is available. + // A field selector can be used to list only NodeResourceSlice + // objects with a certain node name. + NodeName string `json:"nodeName" protobuf:"bytes,2,name=nodeName"` + + // DriverName identifies the DRA driver providing the capacity information. + // A field selector can be used to list only NodeResourceSlice + // objects with a certain driver name. + DriverName string `json:"driverName" protobuf:"bytes,3,name=driverName"` + + NodeResourceModel `json:",inline" protobuf:"bytes,4,name=nodeResourceModel"` +} + +// NodeResourceModel must have one and only one field set. +type NodeResourceModel struct { + // TODO: implement one structured parameter model +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.30 + +// NodeResourceSliceList is a collection of NodeResourceSlices. +type NodeResourceSliceList struct { + metav1.TypeMeta `json:",inline"` + // Standard list metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Items is the list of node resource capacity objects. + Items []NodeResourceSlice `json:"items" protobuf:"bytes,2,rep,name=items"` +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.30 + +// ResourceClaimParameters defines resource requests for a ResourceClaim in an +// in-tree format understood by Kubernetes. +type ResourceClaimParameters struct { + metav1.TypeMeta `json:",inline"` + // Standard object metadata + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // If this object was created from some other resource, then this links + // back to that resource. This field is used to find the in-tree representation + // of the claim parameters when the parameter reference of the claim refers + // to some unknown type. + // +optional + GeneratedFrom *ResourceClaimParametersReference `json:"generatedFrom,omitempty" protobuf:"bytes,2,opt,name=generatedFrom"` + + // Shareable indicates whether the allocated claim is meant to be shareable + // by multiple consumers at the same time. + // +optional + Shareable bool `json:"shareable,omitempty" protobuf:"bytes,3,opt,name=shareable"` + + // DriverRequests describes all resources that are needed for the + // allocated claim. A single claim may use resources coming from + // different drivers. For each driver, this array has at most one + // entry which then may have one or more per-driver requests. + // + // May be empty, in which case the claim can always be allocated. + // + // +listType=atomic + DriverRequests []DriverRequests `json:"driverRequests,omitempty" protobuf:"bytes,4,opt,name=driverRequests"` +} + +// DriverRequests describes all resources that are needed from one particular driver. +type DriverRequests struct { + // DriverName is the name used by the DRA driver kubelet plugin. + DriverName string `json:"driverName,omitempty" protobuf:"bytes,1,opt,name=driverName"` + + // VendorParameters are arbitrary setup parameters for all requests of the + // claim. They are ignored while allocating the claim. + // + // +optional + VendorParameters runtime.RawExtension `json:"vendorParameters,omitempty" protobuf:"bytes,2,opt,name=vendorParameters"` + + // Requests describes all resources that are needed from the driver. + // +listType=atomic + Requests []ResourceRequest `json:"requests,omitempty" protobuf:"bytes,3,opt,name=requests"` +} + +// ResourceRequest is a request for resources from one particular driver. +type ResourceRequest struct { + // VendorParameters are arbitrary setup parameters for the requested + // resource. They are ignored while allocating a claim. + // + // +optional + VendorParameters runtime.RawExtension `json:"vendorParameters,omitempty" protobuf:"bytes,1,opt,name=vendorParameters"` + + ResourceRequestModel `json:",inline" protobuf:"bytes,2,name=resourceRequestModel"` +} + +// ResourceRequestModel must have one and only one field set. +type ResourceRequestModel struct { + // TODO: implement one structured parameter model +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.30 + +// ResourceClaimParametersList is a collection of ResourceClaimParameters. +type ResourceClaimParametersList struct { + metav1.TypeMeta `json:",inline"` + // Standard list metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Items is the list of node resource capacity objects. + Items []ResourceClaimParameters `json:"items" protobuf:"bytes,2,rep,name=items"` +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.30 + +// ResourceClassParameters defines resource requests for a ResourceClass in an +// in-tree format understood by Kubernetes. +type ResourceClassParameters struct { + metav1.TypeMeta `json:",inline"` + // Standard object metadata + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // If this object was created from some other resource, then this links + // back to that resource. This field is used to find the in-tree representation + // of the class parameters when the parameter reference of the class refers + // to some unknown type. + // +optional + GeneratedFrom *ResourceClassParametersReference `json:"generatedFrom,omitempty" protobuf:"bytes,2,opt,name=generatedFrom"` + + // VendorParameters are arbitrary setup parameters for all claims using + // this class. They are ignored while allocating the claim. There must + // not be more than one entry per driver. + // + // +listType=atomic + // +optional + VendorParameters []VendorParameters `json:"vendorParameters,omitempty" protobuf:"bytes,3,opt,name=vendorParameters"` + + // Filters describes additional contraints that must be met when using the class. + // + // +listType=atomic + Filters []ResourceFilter `json:"filters,omitempty" protobuf:"bytes,4,opt,name=filters"` +} + +// ResourceFilter is a filter for resources from one particular driver. +type ResourceFilter struct { + // DriverName is the name used by the DRA driver kubelet plugin. + DriverName string `json:"driverName,omitempty" protobuf:"bytes,1,opt,name=driverName"` + + ResourceFilterModel `json:",inline" protobuf:"bytes,2,name=resourceFilterModel"` +} + +// ResourceFilterModel must have one and only one field set. +type ResourceFilterModel struct { + // TODO: implement one structured parameter model +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.30 + +// ResourceClassParametersList is a collection of ResourceClassParameters. +type ResourceClassParametersList struct { + metav1.TypeMeta `json:",inline"` + // Standard list metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Items is the list of node resource capacity objects. + Items []ResourceClassParameters `json:"items" protobuf:"bytes,2,rep,name=items"` +} + +// VendorParameters are opaque parameters for one particular driver. +type VendorParameters struct { + // DriverName is the name used by the DRA driver kubelet plugin. + DriverName string `json:"driverName,omitempty" protobuf:"bytes,1,opt,name=driverName"` + + // Parameters can be arbitrary setup parameters. They are ignored while + // allocating a claim. + // + // +optional + Parameters runtime.RawExtension `json:"parameters,omitempty" protobuf:"bytes,2,opt,name=parameters"` +} diff --git a/staging/src/k8s.io/api/resource/v1alpha2/types_swagger_doc_generated.go b/staging/src/k8s.io/api/resource/v1alpha2/types_swagger_doc_generated.go index 474be8c85ce..e46c6e06ddb 100644 --- a/staging/src/k8s.io/api/resource/v1alpha2/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/resource/v1alpha2/types_swagger_doc_generated.go @@ -38,6 +38,63 @@ func (AllocationResult) SwaggerDoc() map[string]string { return map_AllocationResult } +var map_AllocationResultModel = map[string]string{ + "": "AllocationResultModel must have one and only one field set.", +} + +func (AllocationResultModel) SwaggerDoc() map[string]string { + return map_AllocationResultModel +} + +var map_DriverAllocationResult = map[string]string{ + "": "DriverAllocationResult contains vendor parameters and the allocation result for one request.", + "vendorRequestParameters": "VendorRequestParameters are the per-request configuration parameters from the time that the claim was allocated.", +} + +func (DriverAllocationResult) SwaggerDoc() map[string]string { + return map_DriverAllocationResult +} + +var map_DriverRequests = map[string]string{ + "": "DriverRequests describes all resources that are needed from one particular driver.", + "driverName": "DriverName is the name used by the DRA driver kubelet plugin.", + "vendorParameters": "VendorParameters are arbitrary setup parameters for all requests of the claim. They are ignored while allocating the claim.", + "requests": "Requests describes all resources that are needed from the driver.", +} + +func (DriverRequests) SwaggerDoc() map[string]string { + return map_DriverRequests +} + +var map_NodeResourceModel = map[string]string{ + "": "NodeResourceModel must have one and only one field set.", +} + +func (NodeResourceModel) SwaggerDoc() map[string]string { + return map_NodeResourceModel +} + +var map_NodeResourceSlice = map[string]string{ + "": "NodeResourceSlice provides information about available resources on individual nodes.", + "metadata": "Standard object metadata", + "nodeName": "NodeName identifies the node where the capacity is available. A field selector can be used to list only NodeResourceSlice objects with a certain node name.", + "driverName": "DriverName identifies the DRA driver providing the capacity information. A field selector can be used to list only NodeResourceSlice objects with a certain driver name.", +} + +func (NodeResourceSlice) SwaggerDoc() map[string]string { + return map_NodeResourceSlice +} + +var map_NodeResourceSliceList = map[string]string{ + "": "NodeResourceSliceList is a collection of NodeResourceSlices.", + "metadata": "Standard list metadata", + "items": "Items is the list of node resource capacity objects.", +} + +func (NodeResourceSliceList) SwaggerDoc() map[string]string { + return map_NodeResourceSliceList +} + var map_PodSchedulingContext = map[string]string{ "": "PodSchedulingContext objects hold information that is needed to schedule a Pod with ResourceClaims that use \"WaitForFirstConsumer\" allocation mode.\n\nThis is an alpha type and requires enabling the DynamicResourceAllocation feature gate.", "metadata": "Standard object metadata", @@ -111,6 +168,28 @@ func (ResourceClaimList) SwaggerDoc() map[string]string { return map_ResourceClaimList } +var map_ResourceClaimParameters = map[string]string{ + "": "ResourceClaimParameters defines resource requests for a ResourceClaim in an in-tree format understood by Kubernetes.", + "metadata": "Standard object metadata", + "generatedFrom": "If this object was created from some other resource, then this links back to that resource. This field is used to find the in-tree representation of the claim parameters when the parameter reference of the claim refers to some unknown type.", + "shareable": "Shareable indicates whether the allocated claim is meant to be shareable by multiple consumers at the same time.", + "driverRequests": "DriverRequests describes all resources that are needed for the allocated claim. A single claim may use resources coming from different drivers. For each driver, this array has at most one entry which then may have one or more per-driver requests.\n\nMay be empty, in which case the claim can always be allocated.", +} + +func (ResourceClaimParameters) SwaggerDoc() map[string]string { + return map_ResourceClaimParameters +} + +var map_ResourceClaimParametersList = map[string]string{ + "": "ResourceClaimParametersList is a collection of ResourceClaimParameters.", + "metadata": "Standard list metadata", + "items": "Items is the list of node resource capacity objects.", +} + +func (ResourceClaimParametersList) SwaggerDoc() map[string]string { + return map_ResourceClaimParametersList +} + var map_ResourceClaimParametersReference = map[string]string{ "": "ResourceClaimParametersReference contains enough information to let you locate the parameters for a ResourceClaim. The object must be in the same namespace as the ResourceClaim.", "apiGroup": "APIGroup is the group for the resource being referenced. It is empty for the core API. This matches the group in the APIVersion that is used when creating the resources.", @@ -186,11 +265,12 @@ func (ResourceClaimTemplateSpec) SwaggerDoc() map[string]string { } var map_ResourceClass = map[string]string{ - "": "ResourceClass is used by administrators to influence how resources are allocated.\n\nThis is an alpha type and requires enabling the DynamicResourceAllocation feature gate.", - "metadata": "Standard object metadata", - "driverName": "DriverName defines the name of the dynamic resource driver that is used for allocation of a ResourceClaim that uses this class.\n\nResource drivers have a unique name in forward domain order (acme.example.com).", - "parametersRef": "ParametersRef references an arbitrary separate object that may hold parameters that will be used by the driver when allocating a resource that uses this class. A dynamic resource driver can distinguish between parameters stored here and and those stored in ResourceClaimSpec.", - "suitableNodes": "Only nodes matching the selector will be considered by the scheduler when trying to find a Node that fits a Pod when that Pod uses a ResourceClaim that has not been allocated yet.\n\nSetting this field is optional. If null, all nodes are candidates.", + "": "ResourceClass is used by administrators to influence how resources are allocated.\n\nThis is an alpha type and requires enabling the DynamicResourceAllocation feature gate.", + "metadata": "Standard object metadata", + "driverName": "DriverName defines the name of the dynamic resource driver that is used for allocation of a ResourceClaim that uses this class.\n\nResource drivers have a unique name in forward domain order (acme.example.com).", + "parametersRef": "ParametersRef references an arbitrary separate object that may hold parameters that will be used by the driver when allocating a resource that uses this class. A dynamic resource driver can distinguish between parameters stored here and and those stored in ResourceClaimSpec.", + "suitableNodes": "Only nodes matching the selector will be considered by the scheduler when trying to find a Node that fits a Pod when that Pod uses a ResourceClaim that has not been allocated yet.\n\nSetting this field is optional. If null, all nodes are candidates.", + "structuredParameters": "If and only if allocation of claims using this class is handled via structured parameters, then StructuredParameters must be set to true.", } func (ResourceClass) SwaggerDoc() map[string]string { @@ -207,6 +287,28 @@ func (ResourceClassList) SwaggerDoc() map[string]string { return map_ResourceClassList } +var map_ResourceClassParameters = map[string]string{ + "": "ResourceClassParameters defines resource requests for a ResourceClass in an in-tree format understood by Kubernetes.", + "metadata": "Standard object metadata", + "generatedFrom": "If this object was created from some other resource, then this links back to that resource. This field is used to find the in-tree representation of the class parameters when the parameter reference of the class refers to some unknown type.", + "vendorParameters": "VendorParameters are arbitrary setup parameters for all claims using this class. They are ignored while allocating the claim. There must not be more than one entry per driver.", + "filters": "Filters describes additional contraints that must be met when using the class.", +} + +func (ResourceClassParameters) SwaggerDoc() map[string]string { + return map_ResourceClassParameters +} + +var map_ResourceClassParametersList = map[string]string{ + "": "ResourceClassParametersList is a collection of ResourceClassParameters.", + "metadata": "Standard list metadata", + "items": "Items is the list of node resource capacity objects.", +} + +func (ResourceClassParametersList) SwaggerDoc() map[string]string { + return map_ResourceClassParametersList +} + var map_ResourceClassParametersReference = map[string]string{ "": "ResourceClassParametersReference contains enough information to let you locate the parameters for a ResourceClass.", "apiGroup": "APIGroup is the group for the resource being referenced. It is empty for the core API. This matches the group in the APIVersion that is used when creating the resources.", @@ -219,14 +321,71 @@ func (ResourceClassParametersReference) SwaggerDoc() map[string]string { return map_ResourceClassParametersReference } +var map_ResourceFilter = map[string]string{ + "": "ResourceFilter is a filter for resources from one particular driver.", + "driverName": "DriverName is the name used by the DRA driver kubelet plugin.", +} + +func (ResourceFilter) SwaggerDoc() map[string]string { + return map_ResourceFilter +} + +var map_ResourceFilterModel = map[string]string{ + "": "ResourceFilterModel must have one and only one field set.", +} + +func (ResourceFilterModel) SwaggerDoc() map[string]string { + return map_ResourceFilterModel +} + var map_ResourceHandle = map[string]string{ - "": "ResourceHandle holds opaque resource data for processing by a specific kubelet plugin.", - "driverName": "DriverName specifies the name of the resource driver whose kubelet plugin should be invoked to process this ResourceHandle's data once it lands on a node. This may differ from the DriverName set in ResourceClaimStatus this ResourceHandle is embedded in.", - "data": "Data contains the opaque data associated with this ResourceHandle. It is set by the controller component of the resource driver whose name matches the DriverName set in the ResourceClaimStatus this ResourceHandle is embedded in. It is set at allocation time and is intended for processing by the kubelet plugin whose name matches the DriverName set in this ResourceHandle.\n\nThe maximum size of this field is 16KiB. This may get increased in the future, but not reduced.", + "": "ResourceHandle holds opaque resource data for processing by a specific kubelet plugin.", + "driverName": "DriverName specifies the name of the resource driver whose kubelet plugin should be invoked to process this ResourceHandle's data once it lands on a node. This may differ from the DriverName set in ResourceClaimStatus this ResourceHandle is embedded in.", + "data": "Data contains the opaque data associated with this ResourceHandle. It is set by the controller component of the resource driver whose name matches the DriverName set in the ResourceClaimStatus this ResourceHandle is embedded in. It is set at allocation time and is intended for processing by the kubelet plugin whose name matches the DriverName set in this ResourceHandle.\n\nThe maximum size of this field is 16KiB. This may get increased in the future, but not reduced.", + "structuredData": "If StructuredData is set, then it needs to be used instead of Data.", } func (ResourceHandle) SwaggerDoc() map[string]string { return map_ResourceHandle } +var map_ResourceRequest = map[string]string{ + "": "ResourceRequest is a request for resources from one particular driver.", + "vendorParameters": "VendorParameters are arbitrary setup parameters for the requested resource. They are ignored while allocating a claim.", +} + +func (ResourceRequest) SwaggerDoc() map[string]string { + return map_ResourceRequest +} + +var map_ResourceRequestModel = map[string]string{ + "": "ResourceRequestModel must have one and only one field set.", +} + +func (ResourceRequestModel) SwaggerDoc() map[string]string { + return map_ResourceRequestModel +} + +var map_StructuredResourceHandle = map[string]string{ + "": "StructuredResourceHandle is the in-tree representation of the allocation result.", + "vendorClassParameters": "VendorClassParameters are the per-claim configuration parameters from the resource class at the time that the claim was allocated.", + "vendorClaimParameters": "VendorClaimParameters are the per-claim configuration parameters from the resource claim parameters at the time that the claim was allocated.", + "nodeName": "NodeName is the name of the node providing the necessary resources.", + "results": "Results lists all allocated driver resources.", +} + +func (StructuredResourceHandle) SwaggerDoc() map[string]string { + return map_StructuredResourceHandle +} + +var map_VendorParameters = map[string]string{ + "": "VendorParameters are opaque parameters for one particular driver.", + "driverName": "DriverName is the name used by the DRA driver kubelet plugin.", + "parameters": "Parameters can be arbitrary setup parameters. They are ignored while allocating a claim.", +} + +func (VendorParameters) SwaggerDoc() map[string]string { + return map_VendorParameters +} + // AUTO-GENERATED FUNCTIONS END HERE diff --git a/staging/src/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go b/staging/src/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go index 89d521bf05a..76a11096e7a 100644 --- a/staging/src/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go @@ -32,7 +32,9 @@ func (in *AllocationResult) DeepCopyInto(out *AllocationResult) { if in.ResourceHandles != nil { in, out := &in.ResourceHandles, &out.ResourceHandles *out = make([]ResourceHandle, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } if in.AvailableOnNodes != nil { in, out := &in.AvailableOnNodes, &out.AvailableOnNodes @@ -52,6 +54,140 @@ func (in *AllocationResult) DeepCopy() *AllocationResult { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AllocationResultModel) DeepCopyInto(out *AllocationResultModel) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AllocationResultModel. +func (in *AllocationResultModel) DeepCopy() *AllocationResultModel { + if in == nil { + return nil + } + out := new(AllocationResultModel) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DriverAllocationResult) DeepCopyInto(out *DriverAllocationResult) { + *out = *in + in.VendorRequestParameters.DeepCopyInto(&out.VendorRequestParameters) + out.AllocationResultModel = in.AllocationResultModel + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DriverAllocationResult. +func (in *DriverAllocationResult) DeepCopy() *DriverAllocationResult { + if in == nil { + return nil + } + out := new(DriverAllocationResult) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DriverRequests) DeepCopyInto(out *DriverRequests) { + *out = *in + in.VendorParameters.DeepCopyInto(&out.VendorParameters) + if in.Requests != nil { + in, out := &in.Requests, &out.Requests + *out = make([]ResourceRequest, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DriverRequests. +func (in *DriverRequests) DeepCopy() *DriverRequests { + if in == nil { + return nil + } + out := new(DriverRequests) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeResourceModel) DeepCopyInto(out *NodeResourceModel) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeResourceModel. +func (in *NodeResourceModel) DeepCopy() *NodeResourceModel { + if in == nil { + return nil + } + out := new(NodeResourceModel) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeResourceSlice) DeepCopyInto(out *NodeResourceSlice) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.NodeResourceModel = in.NodeResourceModel + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeResourceSlice. +func (in *NodeResourceSlice) DeepCopy() *NodeResourceSlice { + if in == nil { + return nil + } + out := new(NodeResourceSlice) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NodeResourceSlice) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeResourceSliceList) DeepCopyInto(out *NodeResourceSliceList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]NodeResourceSlice, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeResourceSliceList. +func (in *NodeResourceSliceList) DeepCopy() *NodeResourceSliceList { + if in == nil { + return nil + } + out := new(NodeResourceSliceList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NodeResourceSliceList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PodSchedulingContext) DeepCopyInto(out *PodSchedulingContext) { *out = *in @@ -234,6 +370,77 @@ func (in *ResourceClaimList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClaimParameters) DeepCopyInto(out *ResourceClaimParameters) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.GeneratedFrom != nil { + in, out := &in.GeneratedFrom, &out.GeneratedFrom + *out = new(ResourceClaimParametersReference) + **out = **in + } + if in.DriverRequests != nil { + in, out := &in.DriverRequests, &out.DriverRequests + *out = make([]DriverRequests, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClaimParameters. +func (in *ResourceClaimParameters) DeepCopy() *ResourceClaimParameters { + if in == nil { + return nil + } + out := new(ResourceClaimParameters) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ResourceClaimParameters) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClaimParametersList) DeepCopyInto(out *ResourceClaimParametersList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ResourceClaimParameters, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClaimParametersList. +func (in *ResourceClaimParametersList) DeepCopy() *ResourceClaimParametersList { + if in == nil { + return nil + } + out := new(ResourceClaimParametersList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ResourceClaimParametersList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ResourceClaimParametersReference) DeepCopyInto(out *ResourceClaimParametersReference) { *out = *in @@ -411,6 +618,11 @@ func (in *ResourceClass) DeepCopyInto(out *ResourceClass) { *out = new(v1.NodeSelector) (*in).DeepCopyInto(*out) } + if in.StructuredParameters != nil { + in, out := &in.StructuredParameters, &out.StructuredParameters + *out = new(bool) + **out = **in + } return } @@ -465,6 +677,82 @@ func (in *ResourceClassList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClassParameters) DeepCopyInto(out *ResourceClassParameters) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.GeneratedFrom != nil { + in, out := &in.GeneratedFrom, &out.GeneratedFrom + *out = new(ResourceClassParametersReference) + **out = **in + } + if in.VendorParameters != nil { + in, out := &in.VendorParameters, &out.VendorParameters + *out = make([]VendorParameters, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Filters != nil { + in, out := &in.Filters, &out.Filters + *out = make([]ResourceFilter, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClassParameters. +func (in *ResourceClassParameters) DeepCopy() *ResourceClassParameters { + if in == nil { + return nil + } + out := new(ResourceClassParameters) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ResourceClassParameters) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClassParametersList) DeepCopyInto(out *ResourceClassParametersList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ResourceClassParameters, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClassParametersList. +func (in *ResourceClassParametersList) DeepCopy() *ResourceClassParametersList { + if in == nil { + return nil + } + out := new(ResourceClassParametersList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ResourceClassParametersList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ResourceClassParametersReference) DeepCopyInto(out *ResourceClassParametersReference) { *out = *in @@ -481,9 +769,47 @@ func (in *ResourceClassParametersReference) DeepCopy() *ResourceClassParametersR return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceFilter) DeepCopyInto(out *ResourceFilter) { + *out = *in + out.ResourceFilterModel = in.ResourceFilterModel + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceFilter. +func (in *ResourceFilter) DeepCopy() *ResourceFilter { + if in == nil { + return nil + } + out := new(ResourceFilter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceFilterModel) DeepCopyInto(out *ResourceFilterModel) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceFilterModel. +func (in *ResourceFilterModel) DeepCopy() *ResourceFilterModel { + if in == nil { + return nil + } + out := new(ResourceFilterModel) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ResourceHandle) DeepCopyInto(out *ResourceHandle) { *out = *in + if in.StructuredData != nil { + in, out := &in.StructuredData, &out.StructuredData + *out = new(StructuredResourceHandle) + (*in).DeepCopyInto(*out) + } return } @@ -496,3 +822,79 @@ func (in *ResourceHandle) DeepCopy() *ResourceHandle { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceRequest) DeepCopyInto(out *ResourceRequest) { + *out = *in + in.VendorParameters.DeepCopyInto(&out.VendorParameters) + out.ResourceRequestModel = in.ResourceRequestModel + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceRequest. +func (in *ResourceRequest) DeepCopy() *ResourceRequest { + if in == nil { + return nil + } + out := new(ResourceRequest) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceRequestModel) DeepCopyInto(out *ResourceRequestModel) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceRequestModel. +func (in *ResourceRequestModel) DeepCopy() *ResourceRequestModel { + if in == nil { + return nil + } + out := new(ResourceRequestModel) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StructuredResourceHandle) DeepCopyInto(out *StructuredResourceHandle) { + *out = *in + in.VendorClassParameters.DeepCopyInto(&out.VendorClassParameters) + in.VendorClaimParameters.DeepCopyInto(&out.VendorClaimParameters) + if in.Results != nil { + in, out := &in.Results, &out.Results + *out = make([]DriverAllocationResult, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructuredResourceHandle. +func (in *StructuredResourceHandle) DeepCopy() *StructuredResourceHandle { + if in == nil { + return nil + } + out := new(StructuredResourceHandle) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VendorParameters) DeepCopyInto(out *VendorParameters) { + *out = *in + in.Parameters.DeepCopyInto(&out.Parameters) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VendorParameters. +func (in *VendorParameters) DeepCopy() *VendorParameters { + if in == nil { + return nil + } + out := new(VendorParameters) + in.DeepCopyInto(out) + return out +} diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.json b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.json new file mode 100644 index 00000000000..08001a055a1 --- /dev/null +++ b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.json @@ -0,0 +1,48 @@ +{ + "kind": "NodeResourceSlice", + "apiVersion": "resource.k8s.io/v1alpha2", + "metadata": { + "name": "nameValue", + "generateName": "generateNameValue", + "namespace": "namespaceValue", + "selfLink": "selfLinkValue", + "uid": "uidValue", + "resourceVersion": "resourceVersionValue", + "generation": 7, + "creationTimestamp": "2008-01-01T01:01:01Z", + "deletionTimestamp": "2009-01-01T01:01:01Z", + "deletionGracePeriodSeconds": 10, + "labels": { + "labelsKey": "labelsValue" + }, + "annotations": { + "annotationsKey": "annotationsValue" + }, + "ownerReferences": [ + { + "apiVersion": "apiVersionValue", + "kind": "kindValue", + "name": "nameValue", + "uid": "uidValue", + "controller": true, + "blockOwnerDeletion": true + } + ], + "finalizers": [ + "finalizersValue" + ], + "managedFields": [ + { + "manager": "managerValue", + "operation": "operationValue", + "apiVersion": "apiVersionValue", + "time": "2004-01-01T01:01:01Z", + "fieldsType": "fieldsTypeValue", + "fieldsV1": {}, + "subresource": "subresourceValue" + } + ] + }, + "nodeName": "nodeNameValue", + "driverName": "driverNameValue" +} \ No newline at end of file diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.pb b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.pb new file mode 100644 index 0000000000000000000000000000000000000000..bf5c7af2076035ca5ea50f555c72140d70794a34 GIT binary patch literal 447 zcmZ8dyH3ME5Of|A@j-0IqKI6&j6?uSNET&EKoJ6zf^Hpe!r{x=y0arCh?0iCpym_! z1El-|qM+sv;BqDp(ap~8&dyE}N`oAbwm_K{Vu;-&lwF!0PLF|QcM!O(ej4M|U-z2P zA-YdB@=+xwhY1dV73j9c$WcI!{T1a|%dX5|SdREjiEMO1d7?Kuje^D+1^cVZ0~C^` zT(jX$uhCe%e7)5j<4mE~?{|eR$!(jM3?gLm9B1xs3H3(g6AL&`bI6s5ZaZ7Gp1D6E zWpNJu_*059%TkN{5_40-5_3vZh4wOYJz>HW=1fT}Nd&9V zI?BYA!j)95lvt1%mReMtnV+X*rIcEcm|KvOs+XLft6yfQq@$FbnU?|-cP=e1$aM}y?9m8aKrilR70fddC2_b|WdK<}Od+XI|*_BLE;~(f> z^xRL#9|ZglO%FNy58BZxc0%d7w>NKQ-@JJ{jjYGsv#vp#6(+&nG_pOBy`3F_)D!3j z`^5p&i8 zrLr7y5^?R$i`vb6IcCkNP}Sn_*+1X7Ic$R#FO9tOBj2<~LV*-t$)MBu=ErO&1qEX? zjtE+rF7IF45C4|obi=RZ@2!s4Coz;mdv&X;WCnFsn=ei}wum=LxKIz+E}8jYvO-r& z{^`Bz^9P@`hepiMY~l}wES~e{Tlj$E4WwFPFUeB+V*ZAgNf3Wp*gQ*1JH%Oy2_MY4 kK`liBmJf~=#8RjQVN#rdpwK0jjYT+N|7B0$g&z0*0FC49d;kCd literal 0 HcmV?d00001 diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaimParameters.yaml b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaimParameters.yaml new file mode 100644 index 00000000000..5baff21f8dc --- /dev/null +++ b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaimParameters.yaml @@ -0,0 +1,56 @@ +apiVersion: resource.k8s.io/v1alpha2 +driverRequests: +- driverName: driverNameValue + requests: + - vendorParameters: + apiVersion: example.com/v1 + kind: CustomType + spec: + replicas: 1 + status: + available: 1 + vendorParameters: + apiVersion: example.com/v1 + kind: CustomType + spec: + replicas: 1 + status: + available: 1 +generatedFrom: + apiGroup: apiGroupValue + kind: kindValue + name: nameValue +kind: ResourceClaimParameters +metadata: + annotations: + annotationsKey: annotationsValue + creationTimestamp: "2008-01-01T01:01:01Z" + deletionGracePeriodSeconds: 10 + deletionTimestamp: "2009-01-01T01:01:01Z" + finalizers: + - finalizersValue + generateName: generateNameValue + generation: 7 + labels: + labelsKey: labelsValue + managedFields: + - apiVersion: apiVersionValue + fieldsType: fieldsTypeValue + fieldsV1: {} + manager: managerValue + operation: operationValue + subresource: subresourceValue + time: "2004-01-01T01:01:01Z" + name: nameValue + namespace: namespaceValue + ownerReferences: + - apiVersion: apiVersionValue + blockOwnerDeletion: true + controller: true + kind: kindValue + name: nameValue + uid: uidValue + resourceVersion: resourceVersionValue + selfLink: selfLinkValue + uid: uidValue +shareable: true diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClass.json b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClass.json index 90738786b4b..16461a7efc1 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClass.json +++ b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClass.json @@ -73,5 +73,6 @@ ] } ] - } + }, + "structuredParameters": true } \ No newline at end of file diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClass.pb b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClass.pb index 99f93ce8e173f493d93bd864453fef5ec0515316..772cd16f80a8f82e173e7d9b15b50af345a12ee1 100644 GIT binary patch delta 20 bcmdnWvYlmu0aGK(Mx+0XY#NMG3`z_DLZ}4_ delta 18 ZcmdnavXy0m0n>lxjYj_&S)>@07yv!P1zZ3C diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClass.yaml b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClass.yaml index 8dce3e3cbbc..80e93c7cd9f 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClass.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClass.yaml @@ -38,6 +38,7 @@ parametersRef: kind: kindValue name: nameValue namespace: namespaceValue +structuredParameters: true suitableNodes: nodeSelectorTerms: - matchExpressions: diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClassParameters.json b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClassParameters.json new file mode 100644 index 00000000000..84177997e24 --- /dev/null +++ b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClassParameters.json @@ -0,0 +1,72 @@ +{ + "kind": "ResourceClassParameters", + "apiVersion": "resource.k8s.io/v1alpha2", + "metadata": { + "name": "nameValue", + "generateName": "generateNameValue", + "namespace": "namespaceValue", + "selfLink": "selfLinkValue", + "uid": "uidValue", + "resourceVersion": "resourceVersionValue", + "generation": 7, + "creationTimestamp": "2008-01-01T01:01:01Z", + "deletionTimestamp": "2009-01-01T01:01:01Z", + "deletionGracePeriodSeconds": 10, + "labels": { + "labelsKey": "labelsValue" + }, + "annotations": { + "annotationsKey": "annotationsValue" + }, + "ownerReferences": [ + { + "apiVersion": "apiVersionValue", + "kind": "kindValue", + "name": "nameValue", + "uid": "uidValue", + "controller": true, + "blockOwnerDeletion": true + } + ], + "finalizers": [ + "finalizersValue" + ], + "managedFields": [ + { + "manager": "managerValue", + "operation": "operationValue", + "apiVersion": "apiVersionValue", + "time": "2004-01-01T01:01:01Z", + "fieldsType": "fieldsTypeValue", + "fieldsV1": {}, + "subresource": "subresourceValue" + } + ] + }, + "generatedFrom": { + "apiGroup": "apiGroupValue", + "kind": "kindValue", + "name": "nameValue", + "namespace": "namespaceValue" + }, + "vendorParameters": [ + { + "driverName": "driverNameValue", + "parameters": { + "apiVersion": "example.com/v1", + "kind": "CustomType", + "spec": { + "replicas": 1 + }, + "status": { + "available": 1 + } + } + } + ], + "filters": [ + { + "driverName": "driverNameValue" + } + ] +} \ No newline at end of file diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClassParameters.pb b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClassParameters.pb new file mode 100644 index 0000000000000000000000000000000000000000..e2c1b15ff5d233ec6ebf43662aa33753e33b91ee GIT binary patch literal 616 zcmZuu%}(1u5OyFE$rh5-Ac1_`BdS74g%tS+2c#AugsL2R8`}dcS+7^Sc3K+c1$YZ? zmHG&MgG#&u;=q|VfbqKdQRwa4Z)U&w=9^*Pdh8S1F=(^G#MmA7ZC7M_qkWM23VQzb z`M=7M1Z&U0K#DmU>;I~=hZWXT^d5jL(0_l43Jv6VI;DbES+yGCs)cV@louyL4c(93 zMj;Z1dRx=^1Ckb*a%_L?u+g}`d-_xFc%KRVe*R17jD6c-O$iZ7`vq_OcNKI$BF?c6hvhS?zc|5<{8TuQ$3%CaklS@#L^$i)faF3-y3)keOqX6}lSo zfA32{2j5vcF=B*fb_+jY(U{K{;~~c%kZOtDI7{i?`~xpzA^xbad6t&mh_f1F9*(&| hEkz8Lhx-#^DdB=JDULwU1tgY*3EzA>*b6-Fy#g7F)c*hg literal 0 HcmV?d00001 diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClassParameters.yaml b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClassParameters.yaml new file mode 100644 index 00000000000..41aebd40234 --- /dev/null +++ b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClassParameters.yaml @@ -0,0 +1,50 @@ +apiVersion: resource.k8s.io/v1alpha2 +filters: +- driverName: driverNameValue +generatedFrom: + apiGroup: apiGroupValue + kind: kindValue + name: nameValue + namespace: namespaceValue +kind: ResourceClassParameters +metadata: + annotations: + annotationsKey: annotationsValue + creationTimestamp: "2008-01-01T01:01:01Z" + deletionGracePeriodSeconds: 10 + deletionTimestamp: "2009-01-01T01:01:01Z" + finalizers: + - finalizersValue + generateName: generateNameValue + generation: 7 + labels: + labelsKey: labelsValue + managedFields: + - apiVersion: apiVersionValue + fieldsType: fieldsTypeValue + fieldsV1: {} + manager: managerValue + operation: operationValue + subresource: subresourceValue + time: "2004-01-01T01:01:01Z" + name: nameValue + namespace: namespaceValue + ownerReferences: + - apiVersion: apiVersionValue + blockOwnerDeletion: true + controller: true + kind: kindValue + name: nameValue + uid: uidValue + resourceVersion: resourceVersionValue + selfLink: selfLinkValue + uid: uidValue +vendorParameters: +- driverName: driverNameValue + parameters: + apiVersion: example.com/v1 + kind: CustomType + spec: + replicas: 1 + status: + available: 1 diff --git a/staging/src/k8s.io/api/testdata/v1.28.0/resource.k8s.io.v1alpha2.ResourceClass.after_roundtrip.pb b/staging/src/k8s.io/api/testdata/v1.28.0/resource.k8s.io.v1alpha2.ResourceClass.after_roundtrip.pb new file mode 100644 index 0000000000000000000000000000000000000000..99f93ce8e173f493d93bd864453fef5ec0515316 GIT binary patch literal 565 zcma)2OG?8)7)~ExIyG$!E=rbJ2zF7mPzWyTLQs)XqziYG_HP|Coe48dpo$mp7Op*l zHxPOUapBq<)ai_UP+YkC{^$3ILusKyR1+Y1D*DifL)jqwC_BM4xx-D*>Hbd6D3;Qj z7tlu@l^7mF57QL9y%8`FcmmhUmS0&+WrF)=C2%Cr;T2)AzNp(N8EDkpU$XWq1W$sg*xcAhDsDiK;2ho-F(?<@?)j0_EXz zHZQnVQ#}JZkT=uBBy(Cs`NyZWE7NF|gbuYj5F`V!j7yo7qmji#q54 a*)dGbm1DGWBi%1&3pQiS`{$l-1=bH#7Q`C> literal 0 HcmV?d00001 diff --git a/staging/src/k8s.io/api/testdata/v1.29.0/resource.k8s.io.v1alpha2.ResourceClass.after_roundtrip.pb b/staging/src/k8s.io/api/testdata/v1.29.0/resource.k8s.io.v1alpha2.ResourceClass.after_roundtrip.pb new file mode 100644 index 0000000000000000000000000000000000000000..99f93ce8e173f493d93bd864453fef5ec0515316 GIT binary patch literal 565 zcma)2OG?8)7)~ExIyG$!E=rbJ2zF7mPzWyTLQs)XqziYG_HP|Coe48dpo$mp7Op*l zHxPOUapBq<)ai_UP+YkC{^$3ILusKyR1+Y1D*DifL)jqwC_BM4xx-D*>Hbd6D3;Qj z7tlu@l^7mF57QL9y%8`FcmmhUmS0&+WrF)=C2%Cr;T2)AzNp(N8EDkpU$XWq1W$sg*xcAhDsDiK;2ho-F(?<@?)j0_EXz zHZQnVQ#}JZkT=uBBy(Cs`NyZWE7NF|gbuYj5F`V!j7yo7qmji#q54 a*)dGbm1DGWBi%1&3pQiS`{$l-1=bH#7Q`C> literal 0 HcmV?d00001 diff --git a/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go b/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go index d1946cfb1ab..d1f8a5b5240 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go @@ -11945,6 +11945,48 @@ var schemaYAML = typed.YAMLObject(`types: - name: shareable type: scalar: boolean +- name: io.k8s.api.resource.v1alpha2.DriverAllocationResult + map: + fields: + - name: vendorRequestParameters + type: + namedType: __untyped_atomic_ +- name: io.k8s.api.resource.v1alpha2.DriverRequests + map: + fields: + - name: driverName + type: + scalar: string + - name: requests + type: + list: + elementType: + namedType: io.k8s.api.resource.v1alpha2.ResourceRequest + elementRelationship: atomic + - name: vendorParameters + type: + namedType: __untyped_atomic_ +- name: io.k8s.api.resource.v1alpha2.NodeResourceSlice + map: + fields: + - name: apiVersion + type: + scalar: string + - name: driverName + type: + scalar: string + default: "" + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: nodeName + type: + scalar: string + default: "" - name: io.k8s.api.resource.v1alpha2.PodSchedulingContext map: fields: @@ -12028,6 +12070,31 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" +- name: io.k8s.api.resource.v1alpha2.ResourceClaimParameters + map: + fields: + - name: apiVersion + type: + scalar: string + - name: driverRequests + type: + list: + elementType: + namedType: io.k8s.api.resource.v1alpha2.DriverRequests + elementRelationship: atomic + - name: generatedFrom + type: + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimParametersReference + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: shareable + type: + scalar: boolean - name: io.k8s.api.resource.v1alpha2.ResourceClaimParametersReference map: fields: @@ -12135,9 +12202,40 @@ var schemaYAML = typed.YAMLObject(`types: - name: parametersRef type: namedType: io.k8s.api.resource.v1alpha2.ResourceClassParametersReference + - name: structuredParameters + type: + scalar: boolean - name: suitableNodes type: namedType: io.k8s.api.core.v1.NodeSelector +- name: io.k8s.api.resource.v1alpha2.ResourceClassParameters + map: + fields: + - name: apiVersion + type: + scalar: string + - name: filters + type: + list: + elementType: + namedType: io.k8s.api.resource.v1alpha2.ResourceFilter + elementRelationship: atomic + - name: generatedFrom + type: + namedType: io.k8s.api.resource.v1alpha2.ResourceClassParametersReference + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: vendorParameters + type: + list: + elementType: + namedType: io.k8s.api.resource.v1alpha2.VendorParameters + elementRelationship: atomic - name: io.k8s.api.resource.v1alpha2.ResourceClassParametersReference map: fields: @@ -12155,6 +12253,12 @@ var schemaYAML = typed.YAMLObject(`types: - name: namespace type: scalar: string +- name: io.k8s.api.resource.v1alpha2.ResourceFilter + map: + fields: + - name: driverName + type: + scalar: string - name: io.k8s.api.resource.v1alpha2.ResourceHandle map: fields: @@ -12164,6 +12268,43 @@ var schemaYAML = typed.YAMLObject(`types: - name: driverName type: scalar: string + - name: structuredData + type: + namedType: io.k8s.api.resource.v1alpha2.StructuredResourceHandle +- name: io.k8s.api.resource.v1alpha2.ResourceRequest + map: + fields: + - name: vendorParameters + type: + namedType: __untyped_atomic_ +- name: io.k8s.api.resource.v1alpha2.StructuredResourceHandle + map: + fields: + - name: nodeName + type: + scalar: string + default: "" + - name: results + type: + list: + elementType: + namedType: io.k8s.api.resource.v1alpha2.DriverAllocationResult + elementRelationship: atomic + - name: vendorClaimParameters + type: + namedType: __untyped_atomic_ + - name: vendorClassParameters + type: + namedType: __untyped_atomic_ +- name: io.k8s.api.resource.v1alpha2.VendorParameters + map: + fields: + - name: driverName + type: + scalar: string + - name: parameters + type: + namedType: __untyped_atomic_ - name: io.k8s.api.scheduling.v1.PriorityClass map: fields: diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/driverallocationresult.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/driverallocationresult.go new file mode 100644 index 00000000000..3b0403cca51 --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/driverallocationresult.go @@ -0,0 +1,45 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + v1alpha2 "k8s.io/api/resource/v1alpha2" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DriverAllocationResultApplyConfiguration represents an declarative configuration of the DriverAllocationResult type for use +// with apply. +type DriverAllocationResultApplyConfiguration struct { + VendorRequestParameters *runtime.RawExtension `json:"vendorRequestParameters,omitempty"` + v1alpha2.AllocationResultModel `json:",inline"` +} + +// DriverAllocationResultApplyConfiguration constructs an declarative configuration of the DriverAllocationResult type for use with +// apply. +func DriverAllocationResult() *DriverAllocationResultApplyConfiguration { + return &DriverAllocationResultApplyConfiguration{} +} + +// WithVendorRequestParameters sets the VendorRequestParameters field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the VendorRequestParameters field is set to the value of the last call. +func (b *DriverAllocationResultApplyConfiguration) WithVendorRequestParameters(value runtime.RawExtension) *DriverAllocationResultApplyConfiguration { + b.VendorRequestParameters = &value + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/driverrequests.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/driverrequests.go new file mode 100644 index 00000000000..8052915784a --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/driverrequests.go @@ -0,0 +1,66 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DriverRequestsApplyConfiguration represents an declarative configuration of the DriverRequests type for use +// with apply. +type DriverRequestsApplyConfiguration struct { + DriverName *string `json:"driverName,omitempty"` + VendorParameters *runtime.RawExtension `json:"vendorParameters,omitempty"` + Requests []ResourceRequestApplyConfiguration `json:"requests,omitempty"` +} + +// DriverRequestsApplyConfiguration constructs an declarative configuration of the DriverRequests type for use with +// apply. +func DriverRequests() *DriverRequestsApplyConfiguration { + return &DriverRequestsApplyConfiguration{} +} + +// WithDriverName sets the DriverName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DriverName field is set to the value of the last call. +func (b *DriverRequestsApplyConfiguration) WithDriverName(value string) *DriverRequestsApplyConfiguration { + b.DriverName = &value + return b +} + +// WithVendorParameters sets the VendorParameters field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the VendorParameters field is set to the value of the last call. +func (b *DriverRequestsApplyConfiguration) WithVendorParameters(value runtime.RawExtension) *DriverRequestsApplyConfiguration { + b.VendorParameters = &value + return b +} + +// WithRequests adds the given value to the Requests field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Requests field. +func (b *DriverRequestsApplyConfiguration) WithRequests(values ...*ResourceRequestApplyConfiguration) *DriverRequestsApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithRequests") + } + b.Requests = append(b.Requests, *values[i]) + } + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/noderesourceslice.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/noderesourceslice.go new file mode 100644 index 00000000000..a20245489a8 --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/noderesourceslice.go @@ -0,0 +1,257 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + v1alpha2 "k8s.io/api/resource/v1alpha2" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + managedfields "k8s.io/apimachinery/pkg/util/managedfields" + internal "k8s.io/client-go/applyconfigurations/internal" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// NodeResourceSliceApplyConfiguration represents an declarative configuration of the NodeResourceSlice type for use +// with apply. +type NodeResourceSliceApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + NodeName *string `json:"nodeName,omitempty"` + DriverName *string `json:"driverName,omitempty"` + v1alpha2.NodeResourceModel `json:",inline"` +} + +// NodeResourceSlice constructs an declarative configuration of the NodeResourceSlice type for use with +// apply. +func NodeResourceSlice(name string) *NodeResourceSliceApplyConfiguration { + b := &NodeResourceSliceApplyConfiguration{} + b.WithName(name) + b.WithKind("NodeResourceSlice") + b.WithAPIVersion("resource.k8s.io/v1alpha2") + return b +} + +// ExtractNodeResourceSlice extracts the applied configuration owned by fieldManager from +// nodeResourceSlice. If no managedFields are found in nodeResourceSlice for fieldManager, a +// NodeResourceSliceApplyConfiguration is returned with only the Name, Namespace (if applicable), +// APIVersion and Kind populated. It is possible that no managed fields were found for because other +// field managers have taken ownership of all the fields previously owned by fieldManager, or because +// the fieldManager never owned fields any fields. +// nodeResourceSlice must be a unmodified NodeResourceSlice API object that was retrieved from the Kubernetes API. +// ExtractNodeResourceSlice provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +// Experimental! +func ExtractNodeResourceSlice(nodeResourceSlice *v1alpha2.NodeResourceSlice, fieldManager string) (*NodeResourceSliceApplyConfiguration, error) { + return extractNodeResourceSlice(nodeResourceSlice, fieldManager, "") +} + +// ExtractNodeResourceSliceStatus is the same as ExtractNodeResourceSlice except +// that it extracts the status subresource applied configuration. +// Experimental! +func ExtractNodeResourceSliceStatus(nodeResourceSlice *v1alpha2.NodeResourceSlice, fieldManager string) (*NodeResourceSliceApplyConfiguration, error) { + return extractNodeResourceSlice(nodeResourceSlice, fieldManager, "status") +} + +func extractNodeResourceSlice(nodeResourceSlice *v1alpha2.NodeResourceSlice, fieldManager string, subresource string) (*NodeResourceSliceApplyConfiguration, error) { + b := &NodeResourceSliceApplyConfiguration{} + err := managedfields.ExtractInto(nodeResourceSlice, internal.Parser().Type("io.k8s.api.resource.v1alpha2.NodeResourceSlice"), fieldManager, b, subresource) + if err != nil { + return nil, err + } + b.WithName(nodeResourceSlice.Name) + + b.WithKind("NodeResourceSlice") + b.WithAPIVersion("resource.k8s.io/v1alpha2") + return b, nil +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *NodeResourceSliceApplyConfiguration) WithKind(value string) *NodeResourceSliceApplyConfiguration { + b.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *NodeResourceSliceApplyConfiguration) WithAPIVersion(value string) *NodeResourceSliceApplyConfiguration { + b.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *NodeResourceSliceApplyConfiguration) WithName(value string) *NodeResourceSliceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *NodeResourceSliceApplyConfiguration) WithGenerateName(value string) *NodeResourceSliceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *NodeResourceSliceApplyConfiguration) WithNamespace(value string) *NodeResourceSliceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *NodeResourceSliceApplyConfiguration) WithUID(value types.UID) *NodeResourceSliceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *NodeResourceSliceApplyConfiguration) WithResourceVersion(value string) *NodeResourceSliceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *NodeResourceSliceApplyConfiguration) WithGeneration(value int64) *NodeResourceSliceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *NodeResourceSliceApplyConfiguration) WithCreationTimestamp(value metav1.Time) *NodeResourceSliceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *NodeResourceSliceApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *NodeResourceSliceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *NodeResourceSliceApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *NodeResourceSliceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *NodeResourceSliceApplyConfiguration) WithLabels(entries map[string]string) *NodeResourceSliceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Labels == nil && len(entries) > 0 { + b.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *NodeResourceSliceApplyConfiguration) WithAnnotations(entries map[string]string) *NodeResourceSliceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Annotations == nil && len(entries) > 0 { + b.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *NodeResourceSliceApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *NodeResourceSliceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.OwnerReferences = append(b.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *NodeResourceSliceApplyConfiguration) WithFinalizers(values ...string) *NodeResourceSliceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.Finalizers = append(b.Finalizers, values[i]) + } + return b +} + +func (b *NodeResourceSliceApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithNodeName sets the NodeName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the NodeName field is set to the value of the last call. +func (b *NodeResourceSliceApplyConfiguration) WithNodeName(value string) *NodeResourceSliceApplyConfiguration { + b.NodeName = &value + return b +} + +// WithDriverName sets the DriverName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DriverName field is set to the value of the last call. +func (b *NodeResourceSliceApplyConfiguration) WithDriverName(value string) *NodeResourceSliceApplyConfiguration { + b.DriverName = &value + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimparameters.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimparameters.go new file mode 100644 index 00000000000..ea13570e335 --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimparameters.go @@ -0,0 +1,272 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + managedfields "k8s.io/apimachinery/pkg/util/managedfields" + internal "k8s.io/client-go/applyconfigurations/internal" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ResourceClaimParametersApplyConfiguration represents an declarative configuration of the ResourceClaimParameters type for use +// with apply. +type ResourceClaimParametersApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + GeneratedFrom *ResourceClaimParametersReferenceApplyConfiguration `json:"generatedFrom,omitempty"` + Shareable *bool `json:"shareable,omitempty"` + DriverRequests []DriverRequestsApplyConfiguration `json:"driverRequests,omitempty"` +} + +// ResourceClaimParameters constructs an declarative configuration of the ResourceClaimParameters type for use with +// apply. +func ResourceClaimParameters(name, namespace string) *ResourceClaimParametersApplyConfiguration { + b := &ResourceClaimParametersApplyConfiguration{} + b.WithName(name) + b.WithNamespace(namespace) + b.WithKind("ResourceClaimParameters") + b.WithAPIVersion("resource.k8s.io/v1alpha2") + return b +} + +// ExtractResourceClaimParameters extracts the applied configuration owned by fieldManager from +// resourceClaimParameters. If no managedFields are found in resourceClaimParameters for fieldManager, a +// ResourceClaimParametersApplyConfiguration is returned with only the Name, Namespace (if applicable), +// APIVersion and Kind populated. It is possible that no managed fields were found for because other +// field managers have taken ownership of all the fields previously owned by fieldManager, or because +// the fieldManager never owned fields any fields. +// resourceClaimParameters must be a unmodified ResourceClaimParameters API object that was retrieved from the Kubernetes API. +// ExtractResourceClaimParameters provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +// Experimental! +func ExtractResourceClaimParameters(resourceClaimParameters *resourcev1alpha2.ResourceClaimParameters, fieldManager string) (*ResourceClaimParametersApplyConfiguration, error) { + return extractResourceClaimParameters(resourceClaimParameters, fieldManager, "") +} + +// ExtractResourceClaimParametersStatus is the same as ExtractResourceClaimParameters except +// that it extracts the status subresource applied configuration. +// Experimental! +func ExtractResourceClaimParametersStatus(resourceClaimParameters *resourcev1alpha2.ResourceClaimParameters, fieldManager string) (*ResourceClaimParametersApplyConfiguration, error) { + return extractResourceClaimParameters(resourceClaimParameters, fieldManager, "status") +} + +func extractResourceClaimParameters(resourceClaimParameters *resourcev1alpha2.ResourceClaimParameters, fieldManager string, subresource string) (*ResourceClaimParametersApplyConfiguration, error) { + b := &ResourceClaimParametersApplyConfiguration{} + err := managedfields.ExtractInto(resourceClaimParameters, internal.Parser().Type("io.k8s.api.resource.v1alpha2.ResourceClaimParameters"), fieldManager, b, subresource) + if err != nil { + return nil, err + } + b.WithName(resourceClaimParameters.Name) + b.WithNamespace(resourceClaimParameters.Namespace) + + b.WithKind("ResourceClaimParameters") + b.WithAPIVersion("resource.k8s.io/v1alpha2") + return b, nil +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *ResourceClaimParametersApplyConfiguration) WithKind(value string) *ResourceClaimParametersApplyConfiguration { + b.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *ResourceClaimParametersApplyConfiguration) WithAPIVersion(value string) *ResourceClaimParametersApplyConfiguration { + b.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ResourceClaimParametersApplyConfiguration) WithName(value string) *ResourceClaimParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *ResourceClaimParametersApplyConfiguration) WithGenerateName(value string) *ResourceClaimParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ResourceClaimParametersApplyConfiguration) WithNamespace(value string) *ResourceClaimParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *ResourceClaimParametersApplyConfiguration) WithUID(value types.UID) *ResourceClaimParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *ResourceClaimParametersApplyConfiguration) WithResourceVersion(value string) *ResourceClaimParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *ResourceClaimParametersApplyConfiguration) WithGeneration(value int64) *ResourceClaimParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *ResourceClaimParametersApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ResourceClaimParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *ResourceClaimParametersApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ResourceClaimParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *ResourceClaimParametersApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ResourceClaimParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *ResourceClaimParametersApplyConfiguration) WithLabels(entries map[string]string) *ResourceClaimParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Labels == nil && len(entries) > 0 { + b.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *ResourceClaimParametersApplyConfiguration) WithAnnotations(entries map[string]string) *ResourceClaimParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Annotations == nil && len(entries) > 0 { + b.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *ResourceClaimParametersApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *ResourceClaimParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.OwnerReferences = append(b.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *ResourceClaimParametersApplyConfiguration) WithFinalizers(values ...string) *ResourceClaimParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.Finalizers = append(b.Finalizers, values[i]) + } + return b +} + +func (b *ResourceClaimParametersApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithGeneratedFrom sets the GeneratedFrom field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GeneratedFrom field is set to the value of the last call. +func (b *ResourceClaimParametersApplyConfiguration) WithGeneratedFrom(value *ResourceClaimParametersReferenceApplyConfiguration) *ResourceClaimParametersApplyConfiguration { + b.GeneratedFrom = value + return b +} + +// WithShareable sets the Shareable field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Shareable field is set to the value of the last call. +func (b *ResourceClaimParametersApplyConfiguration) WithShareable(value bool) *ResourceClaimParametersApplyConfiguration { + b.Shareable = &value + return b +} + +// WithDriverRequests adds the given value to the DriverRequests field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the DriverRequests field. +func (b *ResourceClaimParametersApplyConfiguration) WithDriverRequests(values ...*DriverRequestsApplyConfiguration) *ResourceClaimParametersApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithDriverRequests") + } + b.DriverRequests = append(b.DriverRequests, *values[i]) + } + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclass.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclass.go index 724c9e88e00..364fda9d006 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclass.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclass.go @@ -36,6 +36,7 @@ type ResourceClassApplyConfiguration struct { DriverName *string `json:"driverName,omitempty"` ParametersRef *ResourceClassParametersReferenceApplyConfiguration `json:"parametersRef,omitempty"` SuitableNodes *corev1.NodeSelectorApplyConfiguration `json:"suitableNodes,omitempty"` + StructuredParameters *bool `json:"structuredParameters,omitempty"` } // ResourceClass constructs an declarative configuration of the ResourceClass type for use with @@ -264,3 +265,11 @@ func (b *ResourceClassApplyConfiguration) WithSuitableNodes(value *corev1.NodeSe b.SuitableNodes = value return b } + +// WithStructuredParameters sets the StructuredParameters field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the StructuredParameters field is set to the value of the last call. +func (b *ResourceClassApplyConfiguration) WithStructuredParameters(value bool) *ResourceClassApplyConfiguration { + b.StructuredParameters = &value + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclassparameters.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclassparameters.go new file mode 100644 index 00000000000..028d0d612d9 --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclassparameters.go @@ -0,0 +1,277 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + managedfields "k8s.io/apimachinery/pkg/util/managedfields" + internal "k8s.io/client-go/applyconfigurations/internal" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ResourceClassParametersApplyConfiguration represents an declarative configuration of the ResourceClassParameters type for use +// with apply. +type ResourceClassParametersApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + GeneratedFrom *ResourceClassParametersReferenceApplyConfiguration `json:"generatedFrom,omitempty"` + VendorParameters []VendorParametersApplyConfiguration `json:"vendorParameters,omitempty"` + Filters []ResourceFilterApplyConfiguration `json:"filters,omitempty"` +} + +// ResourceClassParameters constructs an declarative configuration of the ResourceClassParameters type for use with +// apply. +func ResourceClassParameters(name, namespace string) *ResourceClassParametersApplyConfiguration { + b := &ResourceClassParametersApplyConfiguration{} + b.WithName(name) + b.WithNamespace(namespace) + b.WithKind("ResourceClassParameters") + b.WithAPIVersion("resource.k8s.io/v1alpha2") + return b +} + +// ExtractResourceClassParameters extracts the applied configuration owned by fieldManager from +// resourceClassParameters. If no managedFields are found in resourceClassParameters for fieldManager, a +// ResourceClassParametersApplyConfiguration is returned with only the Name, Namespace (if applicable), +// APIVersion and Kind populated. It is possible that no managed fields were found for because other +// field managers have taken ownership of all the fields previously owned by fieldManager, or because +// the fieldManager never owned fields any fields. +// resourceClassParameters must be a unmodified ResourceClassParameters API object that was retrieved from the Kubernetes API. +// ExtractResourceClassParameters provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +// Experimental! +func ExtractResourceClassParameters(resourceClassParameters *resourcev1alpha2.ResourceClassParameters, fieldManager string) (*ResourceClassParametersApplyConfiguration, error) { + return extractResourceClassParameters(resourceClassParameters, fieldManager, "") +} + +// ExtractResourceClassParametersStatus is the same as ExtractResourceClassParameters except +// that it extracts the status subresource applied configuration. +// Experimental! +func ExtractResourceClassParametersStatus(resourceClassParameters *resourcev1alpha2.ResourceClassParameters, fieldManager string) (*ResourceClassParametersApplyConfiguration, error) { + return extractResourceClassParameters(resourceClassParameters, fieldManager, "status") +} + +func extractResourceClassParameters(resourceClassParameters *resourcev1alpha2.ResourceClassParameters, fieldManager string, subresource string) (*ResourceClassParametersApplyConfiguration, error) { + b := &ResourceClassParametersApplyConfiguration{} + err := managedfields.ExtractInto(resourceClassParameters, internal.Parser().Type("io.k8s.api.resource.v1alpha2.ResourceClassParameters"), fieldManager, b, subresource) + if err != nil { + return nil, err + } + b.WithName(resourceClassParameters.Name) + b.WithNamespace(resourceClassParameters.Namespace) + + b.WithKind("ResourceClassParameters") + b.WithAPIVersion("resource.k8s.io/v1alpha2") + return b, nil +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *ResourceClassParametersApplyConfiguration) WithKind(value string) *ResourceClassParametersApplyConfiguration { + b.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *ResourceClassParametersApplyConfiguration) WithAPIVersion(value string) *ResourceClassParametersApplyConfiguration { + b.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ResourceClassParametersApplyConfiguration) WithName(value string) *ResourceClassParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *ResourceClassParametersApplyConfiguration) WithGenerateName(value string) *ResourceClassParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ResourceClassParametersApplyConfiguration) WithNamespace(value string) *ResourceClassParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *ResourceClassParametersApplyConfiguration) WithUID(value types.UID) *ResourceClassParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *ResourceClassParametersApplyConfiguration) WithResourceVersion(value string) *ResourceClassParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *ResourceClassParametersApplyConfiguration) WithGeneration(value int64) *ResourceClassParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *ResourceClassParametersApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ResourceClassParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *ResourceClassParametersApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ResourceClassParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *ResourceClassParametersApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ResourceClassParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *ResourceClassParametersApplyConfiguration) WithLabels(entries map[string]string) *ResourceClassParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Labels == nil && len(entries) > 0 { + b.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *ResourceClassParametersApplyConfiguration) WithAnnotations(entries map[string]string) *ResourceClassParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Annotations == nil && len(entries) > 0 { + b.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *ResourceClassParametersApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *ResourceClassParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.OwnerReferences = append(b.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *ResourceClassParametersApplyConfiguration) WithFinalizers(values ...string) *ResourceClassParametersApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.Finalizers = append(b.Finalizers, values[i]) + } + return b +} + +func (b *ResourceClassParametersApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithGeneratedFrom sets the GeneratedFrom field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GeneratedFrom field is set to the value of the last call. +func (b *ResourceClassParametersApplyConfiguration) WithGeneratedFrom(value *ResourceClassParametersReferenceApplyConfiguration) *ResourceClassParametersApplyConfiguration { + b.GeneratedFrom = value + return b +} + +// WithVendorParameters adds the given value to the VendorParameters field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the VendorParameters field. +func (b *ResourceClassParametersApplyConfiguration) WithVendorParameters(values ...*VendorParametersApplyConfiguration) *ResourceClassParametersApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithVendorParameters") + } + b.VendorParameters = append(b.VendorParameters, *values[i]) + } + return b +} + +// WithFilters adds the given value to the Filters field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Filters field. +func (b *ResourceClassParametersApplyConfiguration) WithFilters(values ...*ResourceFilterApplyConfiguration) *ResourceClassParametersApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithFilters") + } + b.Filters = append(b.Filters, *values[i]) + } + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcefilter.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcefilter.go new file mode 100644 index 00000000000..2fd4ef89f16 --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcefilter.go @@ -0,0 +1,44 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + v1alpha2 "k8s.io/api/resource/v1alpha2" +) + +// ResourceFilterApplyConfiguration represents an declarative configuration of the ResourceFilter type for use +// with apply. +type ResourceFilterApplyConfiguration struct { + DriverName *string `json:"driverName,omitempty"` + v1alpha2.ResourceFilterModel `json:",inline"` +} + +// ResourceFilterApplyConfiguration constructs an declarative configuration of the ResourceFilter type for use with +// apply. +func ResourceFilter() *ResourceFilterApplyConfiguration { + return &ResourceFilterApplyConfiguration{} +} + +// WithDriverName sets the DriverName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DriverName field is set to the value of the last call. +func (b *ResourceFilterApplyConfiguration) WithDriverName(value string) *ResourceFilterApplyConfiguration { + b.DriverName = &value + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcehandle.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcehandle.go index 028cbaa1a7e..b4f3da735d0 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcehandle.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcehandle.go @@ -21,8 +21,9 @@ package v1alpha2 // ResourceHandleApplyConfiguration represents an declarative configuration of the ResourceHandle type for use // with apply. type ResourceHandleApplyConfiguration struct { - DriverName *string `json:"driverName,omitempty"` - Data *string `json:"data,omitempty"` + DriverName *string `json:"driverName,omitempty"` + Data *string `json:"data,omitempty"` + StructuredData *StructuredResourceHandleApplyConfiguration `json:"structuredData,omitempty"` } // ResourceHandleApplyConfiguration constructs an declarative configuration of the ResourceHandle type for use with @@ -46,3 +47,11 @@ func (b *ResourceHandleApplyConfiguration) WithData(value string) *ResourceHandl b.Data = &value return b } + +// WithStructuredData sets the StructuredData field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the StructuredData field is set to the value of the last call. +func (b *ResourceHandleApplyConfiguration) WithStructuredData(value *StructuredResourceHandleApplyConfiguration) *ResourceHandleApplyConfiguration { + b.StructuredData = value + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcerequest.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcerequest.go new file mode 100644 index 00000000000..971eace5be1 --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcerequest.go @@ -0,0 +1,45 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + v1alpha2 "k8s.io/api/resource/v1alpha2" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// ResourceRequestApplyConfiguration represents an declarative configuration of the ResourceRequest type for use +// with apply. +type ResourceRequestApplyConfiguration struct { + VendorParameters *runtime.RawExtension `json:"vendorParameters,omitempty"` + v1alpha2.ResourceRequestModel `json:",inline"` +} + +// ResourceRequestApplyConfiguration constructs an declarative configuration of the ResourceRequest type for use with +// apply. +func ResourceRequest() *ResourceRequestApplyConfiguration { + return &ResourceRequestApplyConfiguration{} +} + +// WithVendorParameters sets the VendorParameters field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the VendorParameters field is set to the value of the last call. +func (b *ResourceRequestApplyConfiguration) WithVendorParameters(value runtime.RawExtension) *ResourceRequestApplyConfiguration { + b.VendorParameters = &value + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/structuredresourcehandle.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/structuredresourcehandle.go new file mode 100644 index 00000000000..e6efcbfef3c --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/structuredresourcehandle.go @@ -0,0 +1,75 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// StructuredResourceHandleApplyConfiguration represents an declarative configuration of the StructuredResourceHandle type for use +// with apply. +type StructuredResourceHandleApplyConfiguration struct { + VendorClassParameters *runtime.RawExtension `json:"vendorClassParameters,omitempty"` + VendorClaimParameters *runtime.RawExtension `json:"vendorClaimParameters,omitempty"` + NodeName *string `json:"nodeName,omitempty"` + Results []DriverAllocationResultApplyConfiguration `json:"results,omitempty"` +} + +// StructuredResourceHandleApplyConfiguration constructs an declarative configuration of the StructuredResourceHandle type for use with +// apply. +func StructuredResourceHandle() *StructuredResourceHandleApplyConfiguration { + return &StructuredResourceHandleApplyConfiguration{} +} + +// WithVendorClassParameters sets the VendorClassParameters field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the VendorClassParameters field is set to the value of the last call. +func (b *StructuredResourceHandleApplyConfiguration) WithVendorClassParameters(value runtime.RawExtension) *StructuredResourceHandleApplyConfiguration { + b.VendorClassParameters = &value + return b +} + +// WithVendorClaimParameters sets the VendorClaimParameters field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the VendorClaimParameters field is set to the value of the last call. +func (b *StructuredResourceHandleApplyConfiguration) WithVendorClaimParameters(value runtime.RawExtension) *StructuredResourceHandleApplyConfiguration { + b.VendorClaimParameters = &value + return b +} + +// WithNodeName sets the NodeName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the NodeName field is set to the value of the last call. +func (b *StructuredResourceHandleApplyConfiguration) WithNodeName(value string) *StructuredResourceHandleApplyConfiguration { + b.NodeName = &value + return b +} + +// WithResults adds the given value to the Results field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Results field. +func (b *StructuredResourceHandleApplyConfiguration) WithResults(values ...*DriverAllocationResultApplyConfiguration) *StructuredResourceHandleApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithResults") + } + b.Results = append(b.Results, *values[i]) + } + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/vendorparameters.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/vendorparameters.go new file mode 100644 index 00000000000..f7a8ff9ecef --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/vendorparameters.go @@ -0,0 +1,52 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// VendorParametersApplyConfiguration represents an declarative configuration of the VendorParameters type for use +// with apply. +type VendorParametersApplyConfiguration struct { + DriverName *string `json:"driverName,omitempty"` + Parameters *runtime.RawExtension `json:"parameters,omitempty"` +} + +// VendorParametersApplyConfiguration constructs an declarative configuration of the VendorParameters type for use with +// apply. +func VendorParameters() *VendorParametersApplyConfiguration { + return &VendorParametersApplyConfiguration{} +} + +// WithDriverName sets the DriverName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DriverName field is set to the value of the last call. +func (b *VendorParametersApplyConfiguration) WithDriverName(value string) *VendorParametersApplyConfiguration { + b.DriverName = &value + return b +} + +// WithParameters sets the Parameters field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Parameters field is set to the value of the last call. +func (b *VendorParametersApplyConfiguration) WithParameters(value runtime.RawExtension) *VendorParametersApplyConfiguration { + b.Parameters = &value + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/utils.go b/staging/src/k8s.io/client-go/applyconfigurations/utils.go index 34677697497..847c94f8fac 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/utils.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/utils.go @@ -1523,6 +1523,12 @@ func ForKind(kind schema.GroupVersionKind) interface{} { // Group=resource.k8s.io, Version=v1alpha2 case v1alpha2.SchemeGroupVersion.WithKind("AllocationResult"): return &resourcev1alpha2.AllocationResultApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("DriverAllocationResult"): + return &resourcev1alpha2.DriverAllocationResultApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("DriverRequests"): + return &resourcev1alpha2.DriverRequestsApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("NodeResourceSlice"): + return &resourcev1alpha2.NodeResourceSliceApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("PodSchedulingContext"): return &resourcev1alpha2.PodSchedulingContextApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("PodSchedulingContextSpec"): @@ -1533,6 +1539,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &resourcev1alpha2.ResourceClaimApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("ResourceClaimConsumerReference"): return &resourcev1alpha2.ResourceClaimConsumerReferenceApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("ResourceClaimParameters"): + return &resourcev1alpha2.ResourceClaimParametersApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("ResourceClaimParametersReference"): return &resourcev1alpha2.ResourceClaimParametersReferenceApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("ResourceClaimSchedulingStatus"): @@ -1547,10 +1555,20 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &resourcev1alpha2.ResourceClaimTemplateSpecApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("ResourceClass"): return &resourcev1alpha2.ResourceClassApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("ResourceClassParameters"): + return &resourcev1alpha2.ResourceClassParametersApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("ResourceClassParametersReference"): return &resourcev1alpha2.ResourceClassParametersReferenceApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("ResourceFilter"): + return &resourcev1alpha2.ResourceFilterApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("ResourceHandle"): return &resourcev1alpha2.ResourceHandleApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("ResourceRequest"): + return &resourcev1alpha2.ResourceRequestApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("StructuredResourceHandle"): + return &resourcev1alpha2.StructuredResourceHandleApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("VendorParameters"): + return &resourcev1alpha2.VendorParametersApplyConfiguration{} // Group=scheduling.k8s.io, Version=v1 case schedulingv1.SchemeGroupVersion.WithKind("PriorityClass"): diff --git a/staging/src/k8s.io/client-go/informers/generic.go b/staging/src/k8s.io/client-go/informers/generic.go index 1e76cefd1a5..37e928e8dd3 100644 --- a/staging/src/k8s.io/client-go/informers/generic.go +++ b/staging/src/k8s.io/client-go/informers/generic.go @@ -362,14 +362,20 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource return &genericInformer{resource: resource.GroupResource(), informer: f.Rbac().V1beta1().RoleBindings().Informer()}, nil // Group=resource.k8s.io, Version=v1alpha2 + case v1alpha2.SchemeGroupVersion.WithResource("noderesourceslices"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().NodeResourceSlices().Informer()}, nil case v1alpha2.SchemeGroupVersion.WithResource("podschedulingcontexts"): return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().PodSchedulingContexts().Informer()}, nil case v1alpha2.SchemeGroupVersion.WithResource("resourceclaims"): return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().ResourceClaims().Informer()}, nil + case v1alpha2.SchemeGroupVersion.WithResource("resourceclaimparameters"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().ResourceClaimParameters().Informer()}, nil case v1alpha2.SchemeGroupVersion.WithResource("resourceclaimtemplates"): return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().ResourceClaimTemplates().Informer()}, nil case v1alpha2.SchemeGroupVersion.WithResource("resourceclasses"): return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().ResourceClasses().Informer()}, nil + case v1alpha2.SchemeGroupVersion.WithResource("resourceclassparameters"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().ResourceClassParameters().Informer()}, nil // Group=scheduling.k8s.io, Version=v1 case schedulingv1.SchemeGroupVersion.WithResource("priorityclasses"): diff --git a/staging/src/k8s.io/client-go/informers/resource/v1alpha2/interface.go b/staging/src/k8s.io/client-go/informers/resource/v1alpha2/interface.go index 23f817c62eb..29d4a7c6630 100644 --- a/staging/src/k8s.io/client-go/informers/resource/v1alpha2/interface.go +++ b/staging/src/k8s.io/client-go/informers/resource/v1alpha2/interface.go @@ -24,14 +24,20 @@ import ( // Interface provides access to all the informers in this group version. type Interface interface { + // NodeResourceSlices returns a NodeResourceSliceInformer. + NodeResourceSlices() NodeResourceSliceInformer // PodSchedulingContexts returns a PodSchedulingContextInformer. PodSchedulingContexts() PodSchedulingContextInformer // ResourceClaims returns a ResourceClaimInformer. ResourceClaims() ResourceClaimInformer + // ResourceClaimParameters returns a ResourceClaimParametersInformer. + ResourceClaimParameters() ResourceClaimParametersInformer // ResourceClaimTemplates returns a ResourceClaimTemplateInformer. ResourceClaimTemplates() ResourceClaimTemplateInformer // ResourceClasses returns a ResourceClassInformer. ResourceClasses() ResourceClassInformer + // ResourceClassParameters returns a ResourceClassParametersInformer. + ResourceClassParameters() ResourceClassParametersInformer } type version struct { @@ -45,6 +51,11 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} } +// NodeResourceSlices returns a NodeResourceSliceInformer. +func (v *version) NodeResourceSlices() NodeResourceSliceInformer { + return &nodeResourceSliceInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + // PodSchedulingContexts returns a PodSchedulingContextInformer. func (v *version) PodSchedulingContexts() PodSchedulingContextInformer { return &podSchedulingContextInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} @@ -55,6 +66,11 @@ func (v *version) ResourceClaims() ResourceClaimInformer { return &resourceClaimInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} } +// ResourceClaimParameters returns a ResourceClaimParametersInformer. +func (v *version) ResourceClaimParameters() ResourceClaimParametersInformer { + return &resourceClaimParametersInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + // ResourceClaimTemplates returns a ResourceClaimTemplateInformer. func (v *version) ResourceClaimTemplates() ResourceClaimTemplateInformer { return &resourceClaimTemplateInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} @@ -64,3 +80,8 @@ func (v *version) ResourceClaimTemplates() ResourceClaimTemplateInformer { func (v *version) ResourceClasses() ResourceClassInformer { return &resourceClassInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} } + +// ResourceClassParameters returns a ResourceClassParametersInformer. +func (v *version) ResourceClassParameters() ResourceClassParametersInformer { + return &resourceClassParametersInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/staging/src/k8s.io/client-go/informers/resource/v1alpha2/noderesourceslice.go b/staging/src/k8s.io/client-go/informers/resource/v1alpha2/noderesourceslice.go new file mode 100644 index 00000000000..e4e6197d182 --- /dev/null +++ b/staging/src/k8s.io/client-go/informers/resource/v1alpha2/noderesourceslice.go @@ -0,0 +1,89 @@ +/* +Copyright 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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "context" + time "time" + + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha2 "k8s.io/client-go/listers/resource/v1alpha2" + cache "k8s.io/client-go/tools/cache" +) + +// NodeResourceSliceInformer provides access to a shared informer and lister for +// NodeResourceSlices. +type NodeResourceSliceInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha2.NodeResourceSliceLister +} + +type nodeResourceSliceInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewNodeResourceSliceInformer constructs a new informer for NodeResourceSlice type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewNodeResourceSliceInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredNodeResourceSliceInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredNodeResourceSliceInformer constructs a new informer for NodeResourceSlice type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredNodeResourceSliceInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ResourceV1alpha2().NodeResourceSlices().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ResourceV1alpha2().NodeResourceSlices().Watch(context.TODO(), options) + }, + }, + &resourcev1alpha2.NodeResourceSlice{}, + resyncPeriod, + indexers, + ) +} + +func (f *nodeResourceSliceInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredNodeResourceSliceInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *nodeResourceSliceInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&resourcev1alpha2.NodeResourceSlice{}, f.defaultInformer) +} + +func (f *nodeResourceSliceInformer) Lister() v1alpha2.NodeResourceSliceLister { + return v1alpha2.NewNodeResourceSliceLister(f.Informer().GetIndexer()) +} diff --git a/staging/src/k8s.io/client-go/informers/resource/v1alpha2/resourceclaimparameters.go b/staging/src/k8s.io/client-go/informers/resource/v1alpha2/resourceclaimparameters.go new file mode 100644 index 00000000000..3064ac9f559 --- /dev/null +++ b/staging/src/k8s.io/client-go/informers/resource/v1alpha2/resourceclaimparameters.go @@ -0,0 +1,90 @@ +/* +Copyright 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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "context" + time "time" + + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha2 "k8s.io/client-go/listers/resource/v1alpha2" + cache "k8s.io/client-go/tools/cache" +) + +// ResourceClaimParametersInformer provides access to a shared informer and lister for +// ResourceClaimParameters. +type ResourceClaimParametersInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha2.ResourceClaimParametersLister +} + +type resourceClaimParametersInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewResourceClaimParametersInformer constructs a new informer for ResourceClaimParameters type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewResourceClaimParametersInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredResourceClaimParametersInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredResourceClaimParametersInformer constructs a new informer for ResourceClaimParameters type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredResourceClaimParametersInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ResourceV1alpha2().ResourceClaimParameters(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ResourceV1alpha2().ResourceClaimParameters(namespace).Watch(context.TODO(), options) + }, + }, + &resourcev1alpha2.ResourceClaimParameters{}, + resyncPeriod, + indexers, + ) +} + +func (f *resourceClaimParametersInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredResourceClaimParametersInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *resourceClaimParametersInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&resourcev1alpha2.ResourceClaimParameters{}, f.defaultInformer) +} + +func (f *resourceClaimParametersInformer) Lister() v1alpha2.ResourceClaimParametersLister { + return v1alpha2.NewResourceClaimParametersLister(f.Informer().GetIndexer()) +} diff --git a/staging/src/k8s.io/client-go/informers/resource/v1alpha2/resourceclassparameters.go b/staging/src/k8s.io/client-go/informers/resource/v1alpha2/resourceclassparameters.go new file mode 100644 index 00000000000..71fbefe1620 --- /dev/null +++ b/staging/src/k8s.io/client-go/informers/resource/v1alpha2/resourceclassparameters.go @@ -0,0 +1,90 @@ +/* +Copyright 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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "context" + time "time" + + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha2 "k8s.io/client-go/listers/resource/v1alpha2" + cache "k8s.io/client-go/tools/cache" +) + +// ResourceClassParametersInformer provides access to a shared informer and lister for +// ResourceClassParameters. +type ResourceClassParametersInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha2.ResourceClassParametersLister +} + +type resourceClassParametersInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewResourceClassParametersInformer constructs a new informer for ResourceClassParameters type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewResourceClassParametersInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredResourceClassParametersInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredResourceClassParametersInformer constructs a new informer for ResourceClassParameters type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredResourceClassParametersInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ResourceV1alpha2().ResourceClassParameters(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ResourceV1alpha2().ResourceClassParameters(namespace).Watch(context.TODO(), options) + }, + }, + &resourcev1alpha2.ResourceClassParameters{}, + resyncPeriod, + indexers, + ) +} + +func (f *resourceClassParametersInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredResourceClassParametersInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *resourceClassParametersInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&resourcev1alpha2.ResourceClassParameters{}, f.defaultInformer) +} + +func (f *resourceClassParametersInformer) Lister() v1alpha2.ResourceClassParametersLister { + return v1alpha2.NewResourceClassParametersLister(f.Informer().GetIndexer()) +} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_noderesourceslice.go b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_noderesourceslice.go new file mode 100644 index 00000000000..13ec45b6f4b --- /dev/null +++ b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_noderesourceslice.go @@ -0,0 +1,145 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + json "encoding/json" + "fmt" + + v1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" + testing "k8s.io/client-go/testing" +) + +// FakeNodeResourceSlices implements NodeResourceSliceInterface +type FakeNodeResourceSlices struct { + Fake *FakeResourceV1alpha2 +} + +var noderesourceslicesResource = v1alpha2.SchemeGroupVersion.WithResource("noderesourceslices") + +var noderesourceslicesKind = v1alpha2.SchemeGroupVersion.WithKind("NodeResourceSlice") + +// Get takes name of the nodeResourceSlice, and returns the corresponding nodeResourceSlice object, and an error if there is any. +func (c *FakeNodeResourceSlices) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.NodeResourceSlice, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootGetAction(noderesourceslicesResource, name), &v1alpha2.NodeResourceSlice{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.NodeResourceSlice), err +} + +// List takes label and field selectors, and returns the list of NodeResourceSlices that match those selectors. +func (c *FakeNodeResourceSlices) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.NodeResourceSliceList, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootListAction(noderesourceslicesResource, noderesourceslicesKind, opts), &v1alpha2.NodeResourceSliceList{}) + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha2.NodeResourceSliceList{ListMeta: obj.(*v1alpha2.NodeResourceSliceList).ListMeta} + for _, item := range obj.(*v1alpha2.NodeResourceSliceList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested nodeResourceSlices. +func (c *FakeNodeResourceSlices) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewRootWatchAction(noderesourceslicesResource, opts)) +} + +// Create takes the representation of a nodeResourceSlice and creates it. Returns the server's representation of the nodeResourceSlice, and an error, if there is any. +func (c *FakeNodeResourceSlices) Create(ctx context.Context, nodeResourceSlice *v1alpha2.NodeResourceSlice, opts v1.CreateOptions) (result *v1alpha2.NodeResourceSlice, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootCreateAction(noderesourceslicesResource, nodeResourceSlice), &v1alpha2.NodeResourceSlice{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.NodeResourceSlice), err +} + +// Update takes the representation of a nodeResourceSlice and updates it. Returns the server's representation of the nodeResourceSlice, and an error, if there is any. +func (c *FakeNodeResourceSlices) Update(ctx context.Context, nodeResourceSlice *v1alpha2.NodeResourceSlice, opts v1.UpdateOptions) (result *v1alpha2.NodeResourceSlice, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateAction(noderesourceslicesResource, nodeResourceSlice), &v1alpha2.NodeResourceSlice{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.NodeResourceSlice), err +} + +// Delete takes name of the nodeResourceSlice and deletes it. Returns an error if one occurs. +func (c *FakeNodeResourceSlices) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewRootDeleteActionWithOptions(noderesourceslicesResource, name, opts), &v1alpha2.NodeResourceSlice{}) + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeNodeResourceSlices) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewRootDeleteCollectionAction(noderesourceslicesResource, listOpts) + + _, err := c.Fake.Invokes(action, &v1alpha2.NodeResourceSliceList{}) + return err +} + +// Patch applies the patch and returns the patched nodeResourceSlice. +func (c *FakeNodeResourceSlices) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.NodeResourceSlice, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(noderesourceslicesResource, name, pt, data, subresources...), &v1alpha2.NodeResourceSlice{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.NodeResourceSlice), err +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied nodeResourceSlice. +func (c *FakeNodeResourceSlices) Apply(ctx context.Context, nodeResourceSlice *resourcev1alpha2.NodeResourceSliceApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.NodeResourceSlice, err error) { + if nodeResourceSlice == nil { + return nil, fmt.Errorf("nodeResourceSlice provided to Apply must not be nil") + } + data, err := json.Marshal(nodeResourceSlice) + if err != nil { + return nil, err + } + name := nodeResourceSlice.Name + if name == nil { + return nil, fmt.Errorf("nodeResourceSlice.Name must be provided to Apply") + } + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(noderesourceslicesResource, *name, types.ApplyPatchType, data), &v1alpha2.NodeResourceSlice{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.NodeResourceSlice), err +} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resource_client.go b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resource_client.go index 20538773208..c26af9ecd14 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resource_client.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resource_client.go @@ -28,6 +28,10 @@ type FakeResourceV1alpha2 struct { *testing.Fake } +func (c *FakeResourceV1alpha2) NodeResourceSlices() v1alpha2.NodeResourceSliceInterface { + return &FakeNodeResourceSlices{c} +} + func (c *FakeResourceV1alpha2) PodSchedulingContexts(namespace string) v1alpha2.PodSchedulingContextInterface { return &FakePodSchedulingContexts{c, namespace} } @@ -36,6 +40,10 @@ func (c *FakeResourceV1alpha2) ResourceClaims(namespace string) v1alpha2.Resourc return &FakeResourceClaims{c, namespace} } +func (c *FakeResourceV1alpha2) ResourceClaimParameters(namespace string) v1alpha2.ResourceClaimParametersInterface { + return &FakeResourceClaimParameters{c, namespace} +} + func (c *FakeResourceV1alpha2) ResourceClaimTemplates(namespace string) v1alpha2.ResourceClaimTemplateInterface { return &FakeResourceClaimTemplates{c, namespace} } @@ -44,6 +52,10 @@ func (c *FakeResourceV1alpha2) ResourceClasses() v1alpha2.ResourceClassInterface return &FakeResourceClasses{c} } +func (c *FakeResourceV1alpha2) ResourceClassParameters(namespace string) v1alpha2.ResourceClassParametersInterface { + return &FakeResourceClassParameters{c, namespace} +} + // RESTClient returns a RESTClient that is used to communicate // with API server by this client implementation. func (c *FakeResourceV1alpha2) RESTClient() rest.Interface { diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resourceclaimparameters.go b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resourceclaimparameters.go new file mode 100644 index 00000000000..da32b5caec5 --- /dev/null +++ b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resourceclaimparameters.go @@ -0,0 +1,154 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + json "encoding/json" + "fmt" + + v1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" + testing "k8s.io/client-go/testing" +) + +// FakeResourceClaimParameters implements ResourceClaimParametersInterface +type FakeResourceClaimParameters struct { + Fake *FakeResourceV1alpha2 + ns string +} + +var resourceclaimparametersResource = v1alpha2.SchemeGroupVersion.WithResource("resourceclaimparameters") + +var resourceclaimparametersKind = v1alpha2.SchemeGroupVersion.WithKind("ResourceClaimParameters") + +// Get takes name of the resourceClaimParameters, and returns the corresponding resourceClaimParameters object, and an error if there is any. +func (c *FakeResourceClaimParameters) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ResourceClaimParameters, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(resourceclaimparametersResource, c.ns, name), &v1alpha2.ResourceClaimParameters{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ResourceClaimParameters), err +} + +// List takes label and field selectors, and returns the list of ResourceClaimParameters that match those selectors. +func (c *FakeResourceClaimParameters) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ResourceClaimParametersList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(resourceclaimparametersResource, resourceclaimparametersKind, c.ns, opts), &v1alpha2.ResourceClaimParametersList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha2.ResourceClaimParametersList{ListMeta: obj.(*v1alpha2.ResourceClaimParametersList).ListMeta} + for _, item := range obj.(*v1alpha2.ResourceClaimParametersList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested resourceClaimParameters. +func (c *FakeResourceClaimParameters) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(resourceclaimparametersResource, c.ns, opts)) + +} + +// Create takes the representation of a resourceClaimParameters and creates it. Returns the server's representation of the resourceClaimParameters, and an error, if there is any. +func (c *FakeResourceClaimParameters) Create(ctx context.Context, resourceClaimParameters *v1alpha2.ResourceClaimParameters, opts v1.CreateOptions) (result *v1alpha2.ResourceClaimParameters, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(resourceclaimparametersResource, c.ns, resourceClaimParameters), &v1alpha2.ResourceClaimParameters{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ResourceClaimParameters), err +} + +// Update takes the representation of a resourceClaimParameters and updates it. Returns the server's representation of the resourceClaimParameters, and an error, if there is any. +func (c *FakeResourceClaimParameters) Update(ctx context.Context, resourceClaimParameters *v1alpha2.ResourceClaimParameters, opts v1.UpdateOptions) (result *v1alpha2.ResourceClaimParameters, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(resourceclaimparametersResource, c.ns, resourceClaimParameters), &v1alpha2.ResourceClaimParameters{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ResourceClaimParameters), err +} + +// Delete takes name of the resourceClaimParameters and deletes it. Returns an error if one occurs. +func (c *FakeResourceClaimParameters) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(resourceclaimparametersResource, c.ns, name, opts), &v1alpha2.ResourceClaimParameters{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeResourceClaimParameters) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(resourceclaimparametersResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1alpha2.ResourceClaimParametersList{}) + return err +} + +// Patch applies the patch and returns the patched resourceClaimParameters. +func (c *FakeResourceClaimParameters) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClaimParameters, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(resourceclaimparametersResource, c.ns, name, pt, data, subresources...), &v1alpha2.ResourceClaimParameters{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ResourceClaimParameters), err +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied resourceClaimParameters. +func (c *FakeResourceClaimParameters) Apply(ctx context.Context, resourceClaimParameters *resourcev1alpha2.ResourceClaimParametersApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaimParameters, err error) { + if resourceClaimParameters == nil { + return nil, fmt.Errorf("resourceClaimParameters provided to Apply must not be nil") + } + data, err := json.Marshal(resourceClaimParameters) + if err != nil { + return nil, err + } + name := resourceClaimParameters.Name + if name == nil { + return nil, fmt.Errorf("resourceClaimParameters.Name must be provided to Apply") + } + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(resourceclaimparametersResource, c.ns, *name, types.ApplyPatchType, data), &v1alpha2.ResourceClaimParameters{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ResourceClaimParameters), err +} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resourceclassparameters.go b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resourceclassparameters.go new file mode 100644 index 00000000000..c11762963f2 --- /dev/null +++ b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resourceclassparameters.go @@ -0,0 +1,154 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + json "encoding/json" + "fmt" + + v1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" + testing "k8s.io/client-go/testing" +) + +// FakeResourceClassParameters implements ResourceClassParametersInterface +type FakeResourceClassParameters struct { + Fake *FakeResourceV1alpha2 + ns string +} + +var resourceclassparametersResource = v1alpha2.SchemeGroupVersion.WithResource("resourceclassparameters") + +var resourceclassparametersKind = v1alpha2.SchemeGroupVersion.WithKind("ResourceClassParameters") + +// Get takes name of the resourceClassParameters, and returns the corresponding resourceClassParameters object, and an error if there is any. +func (c *FakeResourceClassParameters) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ResourceClassParameters, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(resourceclassparametersResource, c.ns, name), &v1alpha2.ResourceClassParameters{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ResourceClassParameters), err +} + +// List takes label and field selectors, and returns the list of ResourceClassParameters that match those selectors. +func (c *FakeResourceClassParameters) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ResourceClassParametersList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(resourceclassparametersResource, resourceclassparametersKind, c.ns, opts), &v1alpha2.ResourceClassParametersList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha2.ResourceClassParametersList{ListMeta: obj.(*v1alpha2.ResourceClassParametersList).ListMeta} + for _, item := range obj.(*v1alpha2.ResourceClassParametersList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested resourceClassParameters. +func (c *FakeResourceClassParameters) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(resourceclassparametersResource, c.ns, opts)) + +} + +// Create takes the representation of a resourceClassParameters and creates it. Returns the server's representation of the resourceClassParameters, and an error, if there is any. +func (c *FakeResourceClassParameters) Create(ctx context.Context, resourceClassParameters *v1alpha2.ResourceClassParameters, opts v1.CreateOptions) (result *v1alpha2.ResourceClassParameters, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(resourceclassparametersResource, c.ns, resourceClassParameters), &v1alpha2.ResourceClassParameters{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ResourceClassParameters), err +} + +// Update takes the representation of a resourceClassParameters and updates it. Returns the server's representation of the resourceClassParameters, and an error, if there is any. +func (c *FakeResourceClassParameters) Update(ctx context.Context, resourceClassParameters *v1alpha2.ResourceClassParameters, opts v1.UpdateOptions) (result *v1alpha2.ResourceClassParameters, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(resourceclassparametersResource, c.ns, resourceClassParameters), &v1alpha2.ResourceClassParameters{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ResourceClassParameters), err +} + +// Delete takes name of the resourceClassParameters and deletes it. Returns an error if one occurs. +func (c *FakeResourceClassParameters) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(resourceclassparametersResource, c.ns, name, opts), &v1alpha2.ResourceClassParameters{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeResourceClassParameters) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(resourceclassparametersResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1alpha2.ResourceClassParametersList{}) + return err +} + +// Patch applies the patch and returns the patched resourceClassParameters. +func (c *FakeResourceClassParameters) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClassParameters, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(resourceclassparametersResource, c.ns, name, pt, data, subresources...), &v1alpha2.ResourceClassParameters{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ResourceClassParameters), err +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied resourceClassParameters. +func (c *FakeResourceClassParameters) Apply(ctx context.Context, resourceClassParameters *resourcev1alpha2.ResourceClassParametersApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClassParameters, err error) { + if resourceClassParameters == nil { + return nil, fmt.Errorf("resourceClassParameters provided to Apply must not be nil") + } + data, err := json.Marshal(resourceClassParameters) + if err != nil { + return nil, err + } + name := resourceClassParameters.Name + if name == nil { + return nil, fmt.Errorf("resourceClassParameters.Name must be provided to Apply") + } + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(resourceclassparametersResource, c.ns, *name, types.ApplyPatchType, data), &v1alpha2.ResourceClassParameters{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ResourceClassParameters), err +} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/generated_expansion.go b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/generated_expansion.go index 2c02e9ce74e..abb4d70045c 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/generated_expansion.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/generated_expansion.go @@ -18,10 +18,16 @@ limitations under the License. package v1alpha2 +type NodeResourceSliceExpansion interface{} + type PodSchedulingContextExpansion interface{} type ResourceClaimExpansion interface{} +type ResourceClaimParametersExpansion interface{} + type ResourceClaimTemplateExpansion interface{} type ResourceClassExpansion interface{} + +type ResourceClassParametersExpansion interface{} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/noderesourceslice.go b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/noderesourceslice.go new file mode 100644 index 00000000000..491f63e7c48 --- /dev/null +++ b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/noderesourceslice.go @@ -0,0 +1,197 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// NodeResourceSlicesGetter has a method to return a NodeResourceSliceInterface. +// A group's client should implement this interface. +type NodeResourceSlicesGetter interface { + NodeResourceSlices() NodeResourceSliceInterface +} + +// NodeResourceSliceInterface has methods to work with NodeResourceSlice resources. +type NodeResourceSliceInterface interface { + Create(ctx context.Context, nodeResourceSlice *v1alpha2.NodeResourceSlice, opts v1.CreateOptions) (*v1alpha2.NodeResourceSlice, error) + Update(ctx context.Context, nodeResourceSlice *v1alpha2.NodeResourceSlice, opts v1.UpdateOptions) (*v1alpha2.NodeResourceSlice, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha2.NodeResourceSlice, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha2.NodeResourceSliceList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.NodeResourceSlice, err error) + Apply(ctx context.Context, nodeResourceSlice *resourcev1alpha2.NodeResourceSliceApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.NodeResourceSlice, err error) + NodeResourceSliceExpansion +} + +// nodeResourceSlices implements NodeResourceSliceInterface +type nodeResourceSlices struct { + client rest.Interface +} + +// newNodeResourceSlices returns a NodeResourceSlices +func newNodeResourceSlices(c *ResourceV1alpha2Client) *nodeResourceSlices { + return &nodeResourceSlices{ + client: c.RESTClient(), + } +} + +// Get takes name of the nodeResourceSlice, and returns the corresponding nodeResourceSlice object, and an error if there is any. +func (c *nodeResourceSlices) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.NodeResourceSlice, err error) { + result = &v1alpha2.NodeResourceSlice{} + err = c.client.Get(). + Resource("noderesourceslices"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of NodeResourceSlices that match those selectors. +func (c *nodeResourceSlices) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.NodeResourceSliceList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha2.NodeResourceSliceList{} + err = c.client.Get(). + Resource("noderesourceslices"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested nodeResourceSlices. +func (c *nodeResourceSlices) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("noderesourceslices"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a nodeResourceSlice and creates it. Returns the server's representation of the nodeResourceSlice, and an error, if there is any. +func (c *nodeResourceSlices) Create(ctx context.Context, nodeResourceSlice *v1alpha2.NodeResourceSlice, opts v1.CreateOptions) (result *v1alpha2.NodeResourceSlice, err error) { + result = &v1alpha2.NodeResourceSlice{} + err = c.client.Post(). + Resource("noderesourceslices"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(nodeResourceSlice). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a nodeResourceSlice and updates it. Returns the server's representation of the nodeResourceSlice, and an error, if there is any. +func (c *nodeResourceSlices) Update(ctx context.Context, nodeResourceSlice *v1alpha2.NodeResourceSlice, opts v1.UpdateOptions) (result *v1alpha2.NodeResourceSlice, err error) { + result = &v1alpha2.NodeResourceSlice{} + err = c.client.Put(). + Resource("noderesourceslices"). + Name(nodeResourceSlice.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(nodeResourceSlice). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the nodeResourceSlice and deletes it. Returns an error if one occurs. +func (c *nodeResourceSlices) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Resource("noderesourceslices"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *nodeResourceSlices) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("noderesourceslices"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched nodeResourceSlice. +func (c *nodeResourceSlices) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.NodeResourceSlice, err error) { + result = &v1alpha2.NodeResourceSlice{} + err = c.client.Patch(pt). + Resource("noderesourceslices"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied nodeResourceSlice. +func (c *nodeResourceSlices) Apply(ctx context.Context, nodeResourceSlice *resourcev1alpha2.NodeResourceSliceApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.NodeResourceSlice, err error) { + if nodeResourceSlice == nil { + return nil, fmt.Errorf("nodeResourceSlice provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(nodeResourceSlice) + if err != nil { + return nil, err + } + name := nodeResourceSlice.Name + if name == nil { + return nil, fmt.Errorf("nodeResourceSlice.Name must be provided to Apply") + } + result = &v1alpha2.NodeResourceSlice{} + err = c.client.Patch(types.ApplyPatchType). + Resource("noderesourceslices"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resource_client.go b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resource_client.go index d5795fd6286..2a5c3585554 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resource_client.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resource_client.go @@ -28,10 +28,13 @@ import ( type ResourceV1alpha2Interface interface { RESTClient() rest.Interface + NodeResourceSlicesGetter PodSchedulingContextsGetter ResourceClaimsGetter + ResourceClaimParametersGetter ResourceClaimTemplatesGetter ResourceClassesGetter + ResourceClassParametersGetter } // ResourceV1alpha2Client is used to interact with features provided by the resource.k8s.io group. @@ -39,6 +42,10 @@ type ResourceV1alpha2Client struct { restClient rest.Interface } +func (c *ResourceV1alpha2Client) NodeResourceSlices() NodeResourceSliceInterface { + return newNodeResourceSlices(c) +} + func (c *ResourceV1alpha2Client) PodSchedulingContexts(namespace string) PodSchedulingContextInterface { return newPodSchedulingContexts(c, namespace) } @@ -47,6 +54,10 @@ func (c *ResourceV1alpha2Client) ResourceClaims(namespace string) ResourceClaimI return newResourceClaims(c, namespace) } +func (c *ResourceV1alpha2Client) ResourceClaimParameters(namespace string) ResourceClaimParametersInterface { + return newResourceClaimParameters(c, namespace) +} + func (c *ResourceV1alpha2Client) ResourceClaimTemplates(namespace string) ResourceClaimTemplateInterface { return newResourceClaimTemplates(c, namespace) } @@ -55,6 +66,10 @@ func (c *ResourceV1alpha2Client) ResourceClasses() ResourceClassInterface { return newResourceClasses(c) } +func (c *ResourceV1alpha2Client) ResourceClassParameters(namespace string) ResourceClassParametersInterface { + return newResourceClassParameters(c, namespace) +} + // NewForConfig creates a new ResourceV1alpha2Client for the given config. // NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), // where httpClient was generated with rest.HTTPClientFor(c). diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaimparameters.go b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaimparameters.go new file mode 100644 index 00000000000..d08afcb611b --- /dev/null +++ b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaimparameters.go @@ -0,0 +1,208 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// ResourceClaimParametersGetter has a method to return a ResourceClaimParametersInterface. +// A group's client should implement this interface. +type ResourceClaimParametersGetter interface { + ResourceClaimParameters(namespace string) ResourceClaimParametersInterface +} + +// ResourceClaimParametersInterface has methods to work with ResourceClaimParameters resources. +type ResourceClaimParametersInterface interface { + Create(ctx context.Context, resourceClaimParameters *v1alpha2.ResourceClaimParameters, opts v1.CreateOptions) (*v1alpha2.ResourceClaimParameters, error) + Update(ctx context.Context, resourceClaimParameters *v1alpha2.ResourceClaimParameters, opts v1.UpdateOptions) (*v1alpha2.ResourceClaimParameters, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha2.ResourceClaimParameters, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha2.ResourceClaimParametersList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClaimParameters, err error) + Apply(ctx context.Context, resourceClaimParameters *resourcev1alpha2.ResourceClaimParametersApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaimParameters, err error) + ResourceClaimParametersExpansion +} + +// resourceClaimParameters implements ResourceClaimParametersInterface +type resourceClaimParameters struct { + client rest.Interface + ns string +} + +// newResourceClaimParameters returns a ResourceClaimParameters +func newResourceClaimParameters(c *ResourceV1alpha2Client, namespace string) *resourceClaimParameters { + return &resourceClaimParameters{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the resourceClaimParameters, and returns the corresponding resourceClaimParameters object, and an error if there is any. +func (c *resourceClaimParameters) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ResourceClaimParameters, err error) { + result = &v1alpha2.ResourceClaimParameters{} + err = c.client.Get(). + Namespace(c.ns). + Resource("resourceclaimparameters"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ResourceClaimParameters that match those selectors. +func (c *resourceClaimParameters) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ResourceClaimParametersList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha2.ResourceClaimParametersList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("resourceclaimparameters"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested resourceClaimParameters. +func (c *resourceClaimParameters) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("resourceclaimparameters"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a resourceClaimParameters and creates it. Returns the server's representation of the resourceClaimParameters, and an error, if there is any. +func (c *resourceClaimParameters) Create(ctx context.Context, resourceClaimParameters *v1alpha2.ResourceClaimParameters, opts v1.CreateOptions) (result *v1alpha2.ResourceClaimParameters, err error) { + result = &v1alpha2.ResourceClaimParameters{} + err = c.client.Post(). + Namespace(c.ns). + Resource("resourceclaimparameters"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(resourceClaimParameters). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a resourceClaimParameters and updates it. Returns the server's representation of the resourceClaimParameters, and an error, if there is any. +func (c *resourceClaimParameters) Update(ctx context.Context, resourceClaimParameters *v1alpha2.ResourceClaimParameters, opts v1.UpdateOptions) (result *v1alpha2.ResourceClaimParameters, err error) { + result = &v1alpha2.ResourceClaimParameters{} + err = c.client.Put(). + Namespace(c.ns). + Resource("resourceclaimparameters"). + Name(resourceClaimParameters.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(resourceClaimParameters). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the resourceClaimParameters and deletes it. Returns an error if one occurs. +func (c *resourceClaimParameters) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("resourceclaimparameters"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *resourceClaimParameters) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("resourceclaimparameters"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched resourceClaimParameters. +func (c *resourceClaimParameters) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClaimParameters, err error) { + result = &v1alpha2.ResourceClaimParameters{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("resourceclaimparameters"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied resourceClaimParameters. +func (c *resourceClaimParameters) Apply(ctx context.Context, resourceClaimParameters *resourcev1alpha2.ResourceClaimParametersApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaimParameters, err error) { + if resourceClaimParameters == nil { + return nil, fmt.Errorf("resourceClaimParameters provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(resourceClaimParameters) + if err != nil { + return nil, err + } + name := resourceClaimParameters.Name + if name == nil { + return nil, fmt.Errorf("resourceClaimParameters.Name must be provided to Apply") + } + result = &v1alpha2.ResourceClaimParameters{} + err = c.client.Patch(types.ApplyPatchType). + Namespace(c.ns). + Resource("resourceclaimparameters"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclassparameters.go b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclassparameters.go new file mode 100644 index 00000000000..8ac9be0784a --- /dev/null +++ b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclassparameters.go @@ -0,0 +1,208 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// ResourceClassParametersGetter has a method to return a ResourceClassParametersInterface. +// A group's client should implement this interface. +type ResourceClassParametersGetter interface { + ResourceClassParameters(namespace string) ResourceClassParametersInterface +} + +// ResourceClassParametersInterface has methods to work with ResourceClassParameters resources. +type ResourceClassParametersInterface interface { + Create(ctx context.Context, resourceClassParameters *v1alpha2.ResourceClassParameters, opts v1.CreateOptions) (*v1alpha2.ResourceClassParameters, error) + Update(ctx context.Context, resourceClassParameters *v1alpha2.ResourceClassParameters, opts v1.UpdateOptions) (*v1alpha2.ResourceClassParameters, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha2.ResourceClassParameters, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha2.ResourceClassParametersList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClassParameters, err error) + Apply(ctx context.Context, resourceClassParameters *resourcev1alpha2.ResourceClassParametersApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClassParameters, err error) + ResourceClassParametersExpansion +} + +// resourceClassParameters implements ResourceClassParametersInterface +type resourceClassParameters struct { + client rest.Interface + ns string +} + +// newResourceClassParameters returns a ResourceClassParameters +func newResourceClassParameters(c *ResourceV1alpha2Client, namespace string) *resourceClassParameters { + return &resourceClassParameters{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the resourceClassParameters, and returns the corresponding resourceClassParameters object, and an error if there is any. +func (c *resourceClassParameters) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ResourceClassParameters, err error) { + result = &v1alpha2.ResourceClassParameters{} + err = c.client.Get(). + Namespace(c.ns). + Resource("resourceclassparameters"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ResourceClassParameters that match those selectors. +func (c *resourceClassParameters) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ResourceClassParametersList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha2.ResourceClassParametersList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("resourceclassparameters"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested resourceClassParameters. +func (c *resourceClassParameters) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("resourceclassparameters"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a resourceClassParameters and creates it. Returns the server's representation of the resourceClassParameters, and an error, if there is any. +func (c *resourceClassParameters) Create(ctx context.Context, resourceClassParameters *v1alpha2.ResourceClassParameters, opts v1.CreateOptions) (result *v1alpha2.ResourceClassParameters, err error) { + result = &v1alpha2.ResourceClassParameters{} + err = c.client.Post(). + Namespace(c.ns). + Resource("resourceclassparameters"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(resourceClassParameters). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a resourceClassParameters and updates it. Returns the server's representation of the resourceClassParameters, and an error, if there is any. +func (c *resourceClassParameters) Update(ctx context.Context, resourceClassParameters *v1alpha2.ResourceClassParameters, opts v1.UpdateOptions) (result *v1alpha2.ResourceClassParameters, err error) { + result = &v1alpha2.ResourceClassParameters{} + err = c.client.Put(). + Namespace(c.ns). + Resource("resourceclassparameters"). + Name(resourceClassParameters.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(resourceClassParameters). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the resourceClassParameters and deletes it. Returns an error if one occurs. +func (c *resourceClassParameters) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("resourceclassparameters"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *resourceClassParameters) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("resourceclassparameters"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched resourceClassParameters. +func (c *resourceClassParameters) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClassParameters, err error) { + result = &v1alpha2.ResourceClassParameters{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("resourceclassparameters"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied resourceClassParameters. +func (c *resourceClassParameters) Apply(ctx context.Context, resourceClassParameters *resourcev1alpha2.ResourceClassParametersApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClassParameters, err error) { + if resourceClassParameters == nil { + return nil, fmt.Errorf("resourceClassParameters provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(resourceClassParameters) + if err != nil { + return nil, err + } + name := resourceClassParameters.Name + if name == nil { + return nil, fmt.Errorf("resourceClassParameters.Name must be provided to Apply") + } + result = &v1alpha2.ResourceClassParameters{} + err = c.client.Patch(types.ApplyPatchType). + Namespace(c.ns). + Resource("resourceclassparameters"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/staging/src/k8s.io/client-go/listers/resource/v1alpha2/expansion_generated.go b/staging/src/k8s.io/client-go/listers/resource/v1alpha2/expansion_generated.go index 3b16e44290c..dd8a21755ff 100644 --- a/staging/src/k8s.io/client-go/listers/resource/v1alpha2/expansion_generated.go +++ b/staging/src/k8s.io/client-go/listers/resource/v1alpha2/expansion_generated.go @@ -18,6 +18,10 @@ limitations under the License. package v1alpha2 +// NodeResourceSliceListerExpansion allows custom methods to be added to +// NodeResourceSliceLister. +type NodeResourceSliceListerExpansion interface{} + // PodSchedulingContextListerExpansion allows custom methods to be added to // PodSchedulingContextLister. type PodSchedulingContextListerExpansion interface{} @@ -34,6 +38,14 @@ type ResourceClaimListerExpansion interface{} // ResourceClaimNamespaceLister. type ResourceClaimNamespaceListerExpansion interface{} +// ResourceClaimParametersListerExpansion allows custom methods to be added to +// ResourceClaimParametersLister. +type ResourceClaimParametersListerExpansion interface{} + +// ResourceClaimParametersNamespaceListerExpansion allows custom methods to be added to +// ResourceClaimParametersNamespaceLister. +type ResourceClaimParametersNamespaceListerExpansion interface{} + // ResourceClaimTemplateListerExpansion allows custom methods to be added to // ResourceClaimTemplateLister. type ResourceClaimTemplateListerExpansion interface{} @@ -45,3 +57,11 @@ type ResourceClaimTemplateNamespaceListerExpansion interface{} // ResourceClassListerExpansion allows custom methods to be added to // ResourceClassLister. type ResourceClassListerExpansion interface{} + +// ResourceClassParametersListerExpansion allows custom methods to be added to +// ResourceClassParametersLister. +type ResourceClassParametersListerExpansion interface{} + +// ResourceClassParametersNamespaceListerExpansion allows custom methods to be added to +// ResourceClassParametersNamespaceLister. +type ResourceClassParametersNamespaceListerExpansion interface{} diff --git a/staging/src/k8s.io/client-go/listers/resource/v1alpha2/noderesourceslice.go b/staging/src/k8s.io/client-go/listers/resource/v1alpha2/noderesourceslice.go new file mode 100644 index 00000000000..f5853499a02 --- /dev/null +++ b/staging/src/k8s.io/client-go/listers/resource/v1alpha2/noderesourceslice.go @@ -0,0 +1,68 @@ +/* +Copyright 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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + v1alpha2 "k8s.io/api/resource/v1alpha2" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// NodeResourceSliceLister helps list NodeResourceSlices. +// All objects returned here must be treated as read-only. +type NodeResourceSliceLister interface { + // List lists all NodeResourceSlices in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha2.NodeResourceSlice, err error) + // Get retrieves the NodeResourceSlice from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha2.NodeResourceSlice, error) + NodeResourceSliceListerExpansion +} + +// nodeResourceSliceLister implements the NodeResourceSliceLister interface. +type nodeResourceSliceLister struct { + indexer cache.Indexer +} + +// NewNodeResourceSliceLister returns a new NodeResourceSliceLister. +func NewNodeResourceSliceLister(indexer cache.Indexer) NodeResourceSliceLister { + return &nodeResourceSliceLister{indexer: indexer} +} + +// List lists all NodeResourceSlices in the indexer. +func (s *nodeResourceSliceLister) List(selector labels.Selector) (ret []*v1alpha2.NodeResourceSlice, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.NodeResourceSlice)) + }) + return ret, err +} + +// Get retrieves the NodeResourceSlice from the index for a given name. +func (s *nodeResourceSliceLister) Get(name string) (*v1alpha2.NodeResourceSlice, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha2.Resource("noderesourceslice"), name) + } + return obj.(*v1alpha2.NodeResourceSlice), nil +} diff --git a/staging/src/k8s.io/client-go/listers/resource/v1alpha2/resourceclaimparameters.go b/staging/src/k8s.io/client-go/listers/resource/v1alpha2/resourceclaimparameters.go new file mode 100644 index 00000000000..1a561ef7a58 --- /dev/null +++ b/staging/src/k8s.io/client-go/listers/resource/v1alpha2/resourceclaimparameters.go @@ -0,0 +1,99 @@ +/* +Copyright 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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + v1alpha2 "k8s.io/api/resource/v1alpha2" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ResourceClaimParametersLister helps list ResourceClaimParameters. +// All objects returned here must be treated as read-only. +type ResourceClaimParametersLister interface { + // List lists all ResourceClaimParameters in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha2.ResourceClaimParameters, err error) + // ResourceClaimParameters returns an object that can list and get ResourceClaimParameters. + ResourceClaimParameters(namespace string) ResourceClaimParametersNamespaceLister + ResourceClaimParametersListerExpansion +} + +// resourceClaimParametersLister implements the ResourceClaimParametersLister interface. +type resourceClaimParametersLister struct { + indexer cache.Indexer +} + +// NewResourceClaimParametersLister returns a new ResourceClaimParametersLister. +func NewResourceClaimParametersLister(indexer cache.Indexer) ResourceClaimParametersLister { + return &resourceClaimParametersLister{indexer: indexer} +} + +// List lists all ResourceClaimParameters in the indexer. +func (s *resourceClaimParametersLister) List(selector labels.Selector) (ret []*v1alpha2.ResourceClaimParameters, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.ResourceClaimParameters)) + }) + return ret, err +} + +// ResourceClaimParameters returns an object that can list and get ResourceClaimParameters. +func (s *resourceClaimParametersLister) ResourceClaimParameters(namespace string) ResourceClaimParametersNamespaceLister { + return resourceClaimParametersNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ResourceClaimParametersNamespaceLister helps list and get ResourceClaimParameters. +// All objects returned here must be treated as read-only. +type ResourceClaimParametersNamespaceLister interface { + // List lists all ResourceClaimParameters in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha2.ResourceClaimParameters, err error) + // Get retrieves the ResourceClaimParameters from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha2.ResourceClaimParameters, error) + ResourceClaimParametersNamespaceListerExpansion +} + +// resourceClaimParametersNamespaceLister implements the ResourceClaimParametersNamespaceLister +// interface. +type resourceClaimParametersNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ResourceClaimParameters in the indexer for a given namespace. +func (s resourceClaimParametersNamespaceLister) List(selector labels.Selector) (ret []*v1alpha2.ResourceClaimParameters, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.ResourceClaimParameters)) + }) + return ret, err +} + +// Get retrieves the ResourceClaimParameters from the indexer for a given namespace and name. +func (s resourceClaimParametersNamespaceLister) Get(name string) (*v1alpha2.ResourceClaimParameters, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha2.Resource("resourceclaimparameters"), name) + } + return obj.(*v1alpha2.ResourceClaimParameters), nil +} diff --git a/staging/src/k8s.io/client-go/listers/resource/v1alpha2/resourceclassparameters.go b/staging/src/k8s.io/client-go/listers/resource/v1alpha2/resourceclassparameters.go new file mode 100644 index 00000000000..26fb95e6d22 --- /dev/null +++ b/staging/src/k8s.io/client-go/listers/resource/v1alpha2/resourceclassparameters.go @@ -0,0 +1,99 @@ +/* +Copyright 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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + v1alpha2 "k8s.io/api/resource/v1alpha2" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ResourceClassParametersLister helps list ResourceClassParameters. +// All objects returned here must be treated as read-only. +type ResourceClassParametersLister interface { + // List lists all ResourceClassParameters in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha2.ResourceClassParameters, err error) + // ResourceClassParameters returns an object that can list and get ResourceClassParameters. + ResourceClassParameters(namespace string) ResourceClassParametersNamespaceLister + ResourceClassParametersListerExpansion +} + +// resourceClassParametersLister implements the ResourceClassParametersLister interface. +type resourceClassParametersLister struct { + indexer cache.Indexer +} + +// NewResourceClassParametersLister returns a new ResourceClassParametersLister. +func NewResourceClassParametersLister(indexer cache.Indexer) ResourceClassParametersLister { + return &resourceClassParametersLister{indexer: indexer} +} + +// List lists all ResourceClassParameters in the indexer. +func (s *resourceClassParametersLister) List(selector labels.Selector) (ret []*v1alpha2.ResourceClassParameters, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.ResourceClassParameters)) + }) + return ret, err +} + +// ResourceClassParameters returns an object that can list and get ResourceClassParameters. +func (s *resourceClassParametersLister) ResourceClassParameters(namespace string) ResourceClassParametersNamespaceLister { + return resourceClassParametersNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ResourceClassParametersNamespaceLister helps list and get ResourceClassParameters. +// All objects returned here must be treated as read-only. +type ResourceClassParametersNamespaceLister interface { + // List lists all ResourceClassParameters in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha2.ResourceClassParameters, err error) + // Get retrieves the ResourceClassParameters from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha2.ResourceClassParameters, error) + ResourceClassParametersNamespaceListerExpansion +} + +// resourceClassParametersNamespaceLister implements the ResourceClassParametersNamespaceLister +// interface. +type resourceClassParametersNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ResourceClassParameters in the indexer for a given namespace. +func (s resourceClassParametersNamespaceLister) List(selector labels.Selector) (ret []*v1alpha2.ResourceClassParameters, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.ResourceClassParameters)) + }) + return ret, err +} + +// Get retrieves the ResourceClassParameters from the indexer for a given namespace and name. +func (s resourceClassParametersNamespaceLister) Get(name string) (*v1alpha2.ResourceClassParameters, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha2.Resource("resourceclassparameters"), name) + } + return obj.(*v1alpha2.ResourceClassParameters), nil +} diff --git a/test/integration/etcd/data.go b/test/integration/etcd/data.go index 9148909da6e..f3014e4e57e 100644 --- a/test/integration/etcd/data.go +++ b/test/integration/etcd/data.go @@ -446,6 +446,18 @@ func GetEtcdStorageDataForNamespace(namespace string) map[schema.GroupVersionRes Stub: `{"metadata": {"name": "pod1name"}, "spec": {"selectedNode": "node1name", "potentialNodes": ["node1name", "node2name"]}}`, ExpectedEtcdPath: "/registry/podschedulingcontexts/" + namespace + "/pod1name", }, + gvr("resource.k8s.io", "v1alpha2", "resourceclassparameters"): { + Stub: `{"metadata": {"name": "class1parameters"}}`, + ExpectedEtcdPath: "/registry/resourceclassparameters/" + namespace + "/class1parameters", + }, + gvr("resource.k8s.io", "v1alpha2", "resourceclaimparameters"): { + Stub: `{"metadata": {"name": "claim1parameters"}}`, + ExpectedEtcdPath: "/registry/resourceclaimparameters/" + namespace + "/claim1parameters", + }, + gvr("resource.k8s.io", "v1alpha2", "noderesourceslices"): { + Stub: `{"metadata": {"name": "node1slice"}, "nodeName": "worker1", "driverName": "dra.example.com"}`, // TODO: add one structured parameter model + ExpectedEtcdPath: "/registry/noderesourceslices/node1slice", + }, // -- // k8s.io/apiserver/pkg/apis/apiserverinternal/v1alpha1 From 2e34e187c9941c31ae7da099d5e16838523ce399 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Wed, 24 Jan 2024 17:51:40 +0100 Subject: [PATCH 03/18] node authorizer: lock down access for NodeResourceSlice The kubelet running on one node should not be allowed to access NodeResourceSlice objects belonging to some other node, as defined by the NodeResourceSlice.NodeName field. --- pkg/kubeapiserver/authorizer/config.go | 8 ++ plugin/pkg/auth/authorizer/node/graph.go | 33 ++++++ .../auth/authorizer/node/graph_populator.go | 40 ++++++- .../auth/authorizer/node/node_authorizer.go | 43 +++++++- .../authorizer/node/node_authorizer_test.go | 104 +++++++++++++++--- 5 files changed, 212 insertions(+), 16 deletions(-) diff --git a/pkg/kubeapiserver/authorizer/config.go b/pkg/kubeapiserver/authorizer/config.go index 06bc0b9d373..3a0e101c54c 100644 --- a/pkg/kubeapiserver/authorizer/config.go +++ b/pkg/kubeapiserver/authorizer/config.go @@ -31,9 +31,12 @@ import ( "k8s.io/apiserver/pkg/apis/apiserver/load" "k8s.io/apiserver/pkg/apis/apiserver/validation" "k8s.io/apiserver/pkg/authorization/authorizer" + utilfeature "k8s.io/apiserver/pkg/util/feature" versionedinformers "k8s.io/client-go/informers" + resourcev1alpha2informers "k8s.io/client-go/informers/resource/v1alpha2" "k8s.io/kubernetes/pkg/auth/authorizer/abac" "k8s.io/kubernetes/pkg/auth/nodeidentifier" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes" "k8s.io/kubernetes/plugin/pkg/auth/authorizer/node" "k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac" @@ -90,6 +93,10 @@ func (config Config) New(ctx context.Context, serverID string) (authorizer.Autho // Keep cases in sync with constant list in k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes/modes.go. switch configuredAuthorizer.Type { case authzconfig.AuthorizerType(modes.ModeNode): + var slices resourcev1alpha2informers.NodeResourceSliceInformer + if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) { + slices = config.VersionedInformerFactory.Resource().V1alpha2().NodeResourceSlices() + } node.RegisterMetrics() graph := node.NewGraph() node.AddGraphEventHandlers( @@ -98,6 +105,7 @@ func (config Config) New(ctx context.Context, serverID string) (authorizer.Autho config.VersionedInformerFactory.Core().V1().Pods(), config.VersionedInformerFactory.Core().V1().PersistentVolumes(), config.VersionedInformerFactory.Storage().V1().VolumeAttachments(), + slices, // Nil check in AddGraphEventHandlers can be removed when always creating this. ) r.nodeAuthorizer = node.NewAuthorizer(graph, nodeidentifier.NewDefaultNodeIdentifier(), bootstrappolicy.NodeRules()) diff --git a/plugin/pkg/auth/authorizer/node/graph.go b/plugin/pkg/auth/authorizer/node/graph.go index 85a4b808426..64596fb9714 100644 --- a/plugin/pkg/auth/authorizer/node/graph.go +++ b/plugin/pkg/auth/authorizer/node/graph.go @@ -114,6 +114,7 @@ type vertexType byte const ( configMapVertexType vertexType = iota + sliceVertexType nodeVertexType podVertexType pvcVertexType @@ -126,6 +127,7 @@ const ( var vertexTypes = map[vertexType]string{ configMapVertexType: "configmap", + sliceVertexType: "noderesourceslice", nodeVertexType: "node", podVertexType: "pod", pvcVertexType: "pvc", @@ -492,3 +494,34 @@ func (g *Graph) DeleteVolumeAttachment(name string) { defer g.lock.Unlock() g.deleteVertex_locked(vaVertexType, "", name) } + +// AddNodeResourceSlice sets up edges for the following relationships: +// +// node resource slice -> node +func (g *Graph) AddNodeResourceSlice(sliceName, nodeName string) { + start := time.Now() + defer func() { + graphActionsDuration.WithLabelValues("AddNodeResourceSlice").Observe(time.Since(start).Seconds()) + }() + g.lock.Lock() + defer g.lock.Unlock() + + // clear existing edges + g.deleteVertex_locked(sliceVertexType, "", sliceName) + + // if we have a node, establish new edges + if len(nodeName) > 0 { + sliceVertex := g.getOrCreateVertex_locked(sliceVertexType, "", sliceName) + nodeVertex := g.getOrCreateVertex_locked(nodeVertexType, "", nodeName) + g.graph.SetEdge(newDestinationEdge(sliceVertex, nodeVertex, nodeVertex)) + } +} +func (g *Graph) DeleteNodeResourceSlice(sliceName string) { + start := time.Now() + defer func() { + graphActionsDuration.WithLabelValues("DeleteNodeResourceSlice").Observe(time.Since(start).Seconds()) + }() + g.lock.Lock() + defer g.lock.Unlock() + g.deleteVertex_locked(sliceVertexType, "", sliceName) +} diff --git a/plugin/pkg/auth/authorizer/node/graph_populator.go b/plugin/pkg/auth/authorizer/node/graph_populator.go index 52a808ef788..96ff92c77e3 100644 --- a/plugin/pkg/auth/authorizer/node/graph_populator.go +++ b/plugin/pkg/auth/authorizer/node/graph_populator.go @@ -22,9 +22,11 @@ import ( "k8s.io/klog/v2" corev1 "k8s.io/api/core/v1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" storagev1 "k8s.io/api/storage/v1" "k8s.io/apimachinery/pkg/util/wait" corev1informers "k8s.io/client-go/informers/core/v1" + resourcev1alpha2informers "k8s.io/client-go/informers/resource/v1alpha2" storageinformers "k8s.io/client-go/informers/storage/v1" "k8s.io/client-go/tools/cache" ) @@ -39,6 +41,7 @@ func AddGraphEventHandlers( pods corev1informers.PodInformer, pvs corev1informers.PersistentVolumeInformer, attachments storageinformers.VolumeAttachmentInformer, + slices resourcev1alpha2informers.NodeResourceSliceInformer, ) { g := &graphPopulator{ graph: graph, @@ -62,8 +65,20 @@ func AddGraphEventHandlers( DeleteFunc: g.deleteVolumeAttachment, }) - go cache.WaitForNamedCacheSync("node_authorizer", wait.NeverStop, - podHandler.HasSynced, pvsHandler.HasSynced, attachHandler.HasSynced) + synced := []cache.InformerSynced{ + podHandler.HasSynced, pvsHandler.HasSynced, attachHandler.HasSynced, + } + + if slices != nil { + sliceHandler, _ := slices.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: g.addNodeResourceSlice, + UpdateFunc: nil, // Not needed, NodeName is immutable. + DeleteFunc: g.deleteNodeResourceSlice, + }) + synced = append(synced, sliceHandler.HasSynced) + } + + go cache.WaitForNamedCacheSync("node_authorizer", wait.NeverStop, synced...) } func (g *graphPopulator) addPod(obj interface{}) { @@ -184,3 +199,24 @@ func (g *graphPopulator) deleteVolumeAttachment(obj interface{}) { } g.graph.DeleteVolumeAttachment(attachment.Name) } + +func (g *graphPopulator) addNodeResourceSlice(obj interface{}) { + slice, ok := obj.(*resourcev1alpha2.NodeResourceSlice) + if !ok { + klog.Infof("unexpected type %T", obj) + return + } + g.graph.AddNodeResourceSlice(slice.Name, slice.NodeName) +} + +func (g *graphPopulator) deleteNodeResourceSlice(obj interface{}) { + if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); ok { + obj = tombstone.Obj + } + slice, ok := obj.(*resourcev1alpha2.NodeResourceSlice) + if !ok { + klog.Infof("unexpected type %T", obj) + return + } + g.graph.DeleteNodeResourceSlice(slice.Name) +} diff --git a/plugin/pkg/auth/authorizer/node/node_authorizer.go b/plugin/pkg/auth/authorizer/node/node_authorizer.go index b03467ffd73..d983ed8c3cf 100644 --- a/plugin/pkg/auth/authorizer/node/node_authorizer.go +++ b/plugin/pkg/auth/authorizer/node/node_authorizer.go @@ -50,7 +50,12 @@ import ( // node <- pod <- pvc <- pv // node <- pod <- pvc <- pv <- secret // node <- pod <- ResourceClaim -// 4. For other resources, authorize all nodes uniformly using statically defined rules +// 4. If a request is for a noderesourceslice, then authorize access if there is an +// edge from the existing slice object to the node, which is the case if the +// existing object has the node in its NodeName field. For create, the access gets +// granted because the noderestriction admission plugin checks that the NodeName +// is set to the node. +// 5. For other resources, authorize all nodes uniformly using statically defined rules type NodeAuthorizer struct { graph *Graph identifier nodeidentifier.NodeIdentifier @@ -76,6 +81,7 @@ func NewAuthorizer(graph *Graph, identifier nodeidentifier.NodeIdentifier, rules var ( configMapResource = api.Resource("configmaps") secretResource = api.Resource("secrets") + nodeResourceSlice = resourceapi.Resource("noderesourceslices") pvcResource = api.Resource("persistentvolumeclaims") pvResource = api.Resource("persistentvolumes") resourceClaimResource = resourceapi.Resource("resourceclaims") @@ -130,6 +136,8 @@ func (r *NodeAuthorizer) Authorize(ctx context.Context, attrs authorizer.Attribu return r.authorizeLease(nodeName, attrs) case csiNodeResource: return r.authorizeCSINode(nodeName, attrs) + case nodeResourceSlice: + return r.authorizeNodeResourceSlice(nodeName, attrs) } } @@ -294,6 +302,39 @@ func (r *NodeAuthorizer) authorizeCSINode(nodeName string, attrs authorizer.Attr return authorizer.DecisionAllow, "", nil } +// authorizeNodeResourceSlice authorizes node requests to NodeResourceSlice resource.k8s.io/noderesourceslices +func (r *NodeAuthorizer) authorizeNodeResourceSlice(nodeName string, attrs authorizer.Attributes) (authorizer.Decision, string, error) { + if len(attrs.GetSubresource()) > 0 { + klog.V(2).Infof("NODE DENY: '%s' %#v", nodeName, attrs) + return authorizer.DecisionNoOpinion, "cannot authorize NodeResourceSlice subresources", nil + } + + // allowed verbs: get, create, update, patch, delete + verb := attrs.GetVerb() + switch verb { + case "get", "create", "update", "patch", "delete": + // Okay, but check individual object permission below. + case "watch", "list": + // Okay. The kubelet is trusted to use a filter for its own objects. + return authorizer.DecisionAllow, "", nil + default: + klog.V(2).Infof("NODE DENY: '%s' %#v", nodeName, attrs) + return authorizer.DecisionNoOpinion, "can only get, create, update, patch, or delete a NodeResourceSlice", nil + } + + // The request must come from a node with the same name as the NodeResourceSlice.NodeName field. + // + // For create, the noderestriction admission plugin is performing this check. + // Here we don't have access to the content of the new object. + if verb == "create" { + return authorizer.DecisionAllow, "", nil + } + + // For any other verb, checking the existing object must have established that access + // is allowed by recording a graph edge. + return r.authorize(nodeName, sliceVertexType, attrs) +} + // hasPathFrom returns true if there is a directed path from the specified type/namespace/name to the specified Node func (r *NodeAuthorizer) hasPathFrom(nodeName string, startingType vertexType, startingNamespace, startingName string) (bool, error) { r.graph.lock.RLock() diff --git a/plugin/pkg/auth/authorizer/node/node_authorizer_test.go b/plugin/pkg/auth/authorizer/node/node_authorizer_test.go index b3f02581cee..a427b16967c 100644 --- a/plugin/pkg/auth/authorizer/node/node_authorizer_test.go +++ b/plugin/pkg/auth/authorizer/node/node_authorizer_test.go @@ -28,6 +28,7 @@ import ( "time" corev1 "k8s.io/api/core/v1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" storagev1 "k8s.io/api/storage/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apiserver/pkg/authentication/user" @@ -55,9 +56,10 @@ func TestAuthorizer(t *testing.T) { uniqueResourceClaimsPerPod: 1, uniqueResourceClaimTemplatesPerPod: 1, uniqueResourceClaimTemplatesWithClaimPerPod: 1, + nodeResourceCapacitiesPerNode: 2, } - nodes, pods, pvs, attachments := generate(opts) - populate(g, nodes, pods, pvs, attachments) + nodes, pods, pvs, attachments, slices := generate(opts) + populate(g, nodes, pods, pvs, attachments, slices) identifier := nodeidentifier.NewDefaultNodeIdentifier() authz := NewAuthorizer(g, identifier, bootstrappolicy.NodeRules()) @@ -336,6 +338,67 @@ func TestAuthorizer(t *testing.T) { attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "csinodes", APIGroup: "storage.k8s.io", Name: "node0"}, expect: authorizer.DecisionAllow, }, + // NodeResourceSlice + { + name: "disallowed NodeResourceSlice with subresource", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "noderesourceslices", Subresource: "status", APIGroup: "resource.k8s.io", Name: "slice0-node0"}, + expect: authorizer.DecisionNoOpinion, + }, + { + name: "disallowed get another node's NodeResourceSlice", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "noderesourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node1"}, + expect: authorizer.DecisionNoOpinion, + }, + { + name: "disallowed update another node's NodeResourceSlice", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "update", Resource: "noderesourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node1"}, + expect: authorizer.DecisionNoOpinion, + }, + { + name: "disallowed patch another node's NodeResourceSlice", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "patch", Resource: "noderesourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node1"}, + expect: authorizer.DecisionNoOpinion, + }, + { + name: "disallowed delete another node's NodeResourceSlice", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "noderesourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node1"}, + expect: authorizer.DecisionNoOpinion, + }, + { + name: "allowed list NodeResourceSlices", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "list", Resource: "noderesourceslices", APIGroup: "resource.k8s.io"}, + expect: authorizer.DecisionAllow, + }, + { + name: "allowed watch NodeResourceSlices", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "watch", Resource: "noderesourceslices", APIGroup: "resource.k8s.io"}, + expect: authorizer.DecisionAllow, + }, + { + name: "allowed get NodeResourceSlice", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "noderesourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node0"}, + expect: authorizer.DecisionAllow, + }, + { + name: "allowed create NodeResourceSlice", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "create", Resource: "noderesourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node0"}, + expect: authorizer.DecisionAllow, + }, + { + name: "allowed update NodeResourceSlice", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "update", Resource: "noderesourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node0"}, + expect: authorizer.DecisionAllow, + }, + { + name: "allowed patch NodeResourceSlice", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "patch", Resource: "noderesourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node0"}, + expect: authorizer.DecisionAllow, + }, + { + name: "allowed delete NodeResourceSlice", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "noderesourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node0"}, + expect: authorizer.DecisionAllow, + }, } for _, tc := range tests { @@ -497,6 +560,8 @@ type sampleDataOpts struct { uniqueResourceClaimsPerPod int uniqueResourceClaimTemplatesPerPod int uniqueResourceClaimTemplatesWithClaimPerPod int + + nodeResourceCapacitiesPerNode int } func BenchmarkPopulationAllocation(b *testing.B) { @@ -513,12 +578,12 @@ func BenchmarkPopulationAllocation(b *testing.B) { uniquePVCsPerPod: 1, } - nodes, pods, pvs, attachments := generate(opts) + nodes, pods, pvs, attachments, slices := generate(opts) b.ResetTimer() for i := 0; i < b.N; i++ { g := NewGraph() - populate(g, nodes, pods, pvs, attachments) + populate(g, nodes, pods, pvs, attachments, slices) } } @@ -544,14 +609,14 @@ func BenchmarkPopulationRetention(b *testing.B) { uniquePVCsPerPod: 1, } - nodes, pods, pvs, attachments := generate(opts) + nodes, pods, pvs, attachments, slices := generate(opts) // Garbage collect before the first iteration runtime.GC() b.ResetTimer() for i := 0; i < b.N; i++ { g := NewGraph() - populate(g, nodes, pods, pvs, attachments) + populate(g, nodes, pods, pvs, attachments, slices) if i == 0 { f, _ := os.Create("BenchmarkPopulationRetention.profile") @@ -582,9 +647,9 @@ func BenchmarkWriteIndexMaintenance(b *testing.B) { sharedPVCsPerPod: 0, uniquePVCsPerPod: 1, } - nodes, pods, pvs, attachments := generate(opts) + nodes, pods, pvs, attachments, slices := generate(opts) g := NewGraph() - populate(g, nodes, pods, pvs, attachments) + populate(g, nodes, pods, pvs, attachments, slices) // Garbage collect before the first iteration runtime.GC() b.ResetTimer() @@ -616,8 +681,8 @@ func BenchmarkAuthorization(b *testing.B) { sharedPVCsPerPod: 0, uniquePVCsPerPod: 1, } - nodes, pods, pvs, attachments := generate(opts) - populate(g, nodes, pods, pvs, attachments) + nodes, pods, pvs, attachments, slices := generate(opts) + populate(g, nodes, pods, pvs, attachments, slices) identifier := nodeidentifier.NewDefaultNodeIdentifier() authz := NewAuthorizer(g, identifier, bootstrappolicy.NodeRules()) @@ -766,7 +831,7 @@ func BenchmarkAuthorization(b *testing.B) { } } -func populate(graph *Graph, nodes []*corev1.Node, pods []*corev1.Pod, pvs []*corev1.PersistentVolume, attachments []*storagev1.VolumeAttachment) { +func populate(graph *Graph, nodes []*corev1.Node, pods []*corev1.Pod, pvs []*corev1.PersistentVolume, attachments []*storagev1.VolumeAttachment, slices []*resourcev1alpha2.NodeResourceSlice) { p := &graphPopulator{} p.graph = graph for _, pod := range pods { @@ -778,6 +843,9 @@ func populate(graph *Graph, nodes []*corev1.Node, pods []*corev1.Pod, pvs []*cor for _, attachment := range attachments { p.addVolumeAttachment(attachment) } + for _, slice := range slices { + p.addNodeResourceSlice(slice) + } } func randomSubset(a, b int) []int { @@ -791,11 +859,12 @@ func randomSubset(a, b int) []int { // the secret/configmap/pvc/node references in the pod and pv objects are named to indicate the connections between the objects. // for example, secret0-pod0-node0 is a secret referenced by pod0 which is bound to node0. // when populated into the graph, the node authorizer should allow node0 to access that secret, but not node1. -func generate(opts *sampleDataOpts) ([]*corev1.Node, []*corev1.Pod, []*corev1.PersistentVolume, []*storagev1.VolumeAttachment) { +func generate(opts *sampleDataOpts) ([]*corev1.Node, []*corev1.Pod, []*corev1.PersistentVolume, []*storagev1.VolumeAttachment, []*resourcev1alpha2.NodeResourceSlice) { nodes := make([]*corev1.Node, 0, opts.nodes) pods := make([]*corev1.Pod, 0, opts.nodes*opts.podsPerNode) pvs := make([]*corev1.PersistentVolume, 0, (opts.nodes*opts.podsPerNode*opts.uniquePVCsPerPod)+(opts.sharedPVCsPerPod*opts.namespaces)) attachments := make([]*storagev1.VolumeAttachment, 0, opts.nodes*opts.attachmentsPerNode) + slices := make([]*resourcev1alpha2.NodeResourceSlice, 0, opts.nodes*opts.nodeResourceCapacitiesPerNode) rand.Seed(12345) @@ -821,8 +890,17 @@ func generate(opts *sampleDataOpts) ([]*corev1.Node, []*corev1.Pod, []*corev1.Pe ObjectMeta: metav1.ObjectMeta{Name: nodeName}, Spec: corev1.NodeSpec{}, }) + + for p := 0; p <= opts.nodeResourceCapacitiesPerNode; p++ { + name := fmt.Sprintf("slice%d-%s", p, nodeName) + slice := &resourcev1alpha2.NodeResourceSlice{ + ObjectMeta: metav1.ObjectMeta{Name: name}, + NodeName: nodeName, + } + slices = append(slices, slice) + } } - return nodes, pods, pvs, attachments + return nodes, pods, pvs, attachments, slices } func generatePod(name, namespace, nodeName, svcAccountName string, opts *sampleDataOpts) (*corev1.Pod, []*corev1.PersistentVolume) { From a92d2a4cea6c8807386f94b9d2f9637151e3a4fd Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Wed, 24 Jan 2024 18:41:21 +0100 Subject: [PATCH 04/18] noderestriction admission: lock down create of NodeResourceSlice The proper value of NodeName must be checked here for create because the node authorizer cannot do it. --- .../admission/noderestriction/admission.go | 51 +++++++++--- .../noderestriction/admission_test.go | 82 +++++++++++++++++++ 2 files changed, 120 insertions(+), 13 deletions(-) diff --git a/plugin/pkg/admission/noderestriction/admission.go b/plugin/pkg/admission/noderestriction/admission.go index dc8ac71dcde..e00bb6141ed 100644 --- a/plugin/pkg/admission/noderestriction/admission.go +++ b/plugin/pkg/admission/noderestriction/admission.go @@ -18,6 +18,7 @@ package noderestriction import ( "context" + "errors" "fmt" "io" "strings" @@ -25,7 +26,7 @@ import ( "github.com/google/go-cmp/cmp" v1 "k8s.io/api/core/v1" apiequality "k8s.io/apimachinery/pkg/api/equality" - "k8s.io/apimachinery/pkg/api/errors" + apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/sets" @@ -40,6 +41,7 @@ import ( coordapi "k8s.io/kubernetes/pkg/apis/coordination" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/policy" + "k8s.io/kubernetes/pkg/apis/resource" storage "k8s.io/kubernetes/pkg/apis/storage" "k8s.io/kubernetes/pkg/auth/nodeidentifier" "k8s.io/kubernetes/pkg/features" @@ -71,7 +73,8 @@ type Plugin struct { podsGetter corev1lister.PodLister nodesGetter corev1lister.NodeLister - expansionRecoveryEnabled bool + expansionRecoveryEnabled bool + dynamicResourceAllocationEnabled bool } var ( @@ -83,6 +86,7 @@ var ( // InspectFeatureGates allows setting bools without taking a dep on a global variable func (p *Plugin) InspectFeatureGates(featureGates featuregate.FeatureGate) { p.expansionRecoveryEnabled = featureGates.Enabled(features.RecoverVolumeExpansionFailure) + p.dynamicResourceAllocationEnabled = featureGates.Enabled(features.DynamicResourceAllocation) } // SetExternalKubeInformerFactory registers an informer factory into Plugin @@ -106,12 +110,13 @@ func (p *Plugin) ValidateInitialization() error { } var ( - podResource = api.Resource("pods") - nodeResource = api.Resource("nodes") - pvcResource = api.Resource("persistentvolumeclaims") - svcacctResource = api.Resource("serviceaccounts") - leaseResource = coordapi.Resource("leases") - csiNodeResource = storage.Resource("csinodes") + podResource = api.Resource("pods") + nodeResource = api.Resource("nodes") + pvcResource = api.Resource("persistentvolumeclaims") + svcacctResource = api.Resource("serviceaccounts") + leaseResource = coordapi.Resource("leases") + csiNodeResource = storage.Resource("csinodes") + nodeResourceSliceResource = resource.Resource("noderesourceslices") ) // Admit checks the admission policy and triggers corresponding actions @@ -163,6 +168,9 @@ func (p *Plugin) Admit(ctx context.Context, a admission.Attributes, o admission. case csiNodeResource: return p.admitCSINode(nodeName, a) + case nodeResourceSliceResource: + return p.admitNodeResourceSlice(nodeName, a) + default: return nil } @@ -178,7 +186,7 @@ func (p *Plugin) admitPod(nodeName string, a admission.Attributes) error { case admission.Delete: // get the existing pod existingPod, err := p.podsGetter.Pods(a.GetNamespace()).Get(a.GetName()) - if errors.IsNotFound(err) { + if apierrors.IsNotFound(err) { return err } if err != nil { @@ -233,7 +241,7 @@ func (p *Plugin) admitPodCreate(nodeName string, a admission.Attributes) error { // Verify the node UID. node, err := p.nodesGetter.Get(nodeName) - if errors.IsNotFound(err) { + if apierrors.IsNotFound(err) { return err } if err != nil { @@ -351,7 +359,7 @@ func (p *Plugin) admitPodEviction(nodeName string, a admission.Attributes) error } // get the existing pod existingPod, err := p.podsGetter.Pods(a.GetNamespace()).Get(podName) - if errors.IsNotFound(err) { + if apierrors.IsNotFound(err) { return err } if err != nil { @@ -412,7 +420,7 @@ func (p *Plugin) admitPVCStatus(nodeName string, a admission.Attributes) error { // ensure no metadata changed. nodes should not be able to relabel, add finalizers/owners, etc if !apiequality.Semantic.DeepEqual(oldPVC, newPVC) { - return admission.NewForbidden(a, fmt.Errorf("node %q is not allowed to update fields other than status.capacity and status.conditions: %v", nodeName, cmp.Diff(oldPVC, newPVC))) + return admission.NewForbidden(a, fmt.Errorf("node %q is not allowed to update fields other than status.quantity and status.conditions: %v", nodeName, cmp.Diff(oldPVC, newPVC))) } return nil @@ -564,7 +572,7 @@ func (p *Plugin) admitServiceAccount(nodeName string, a admission.Attributes) er return admission.NewForbidden(a, fmt.Errorf("node requested token with a pod binding without a uid")) } pod, err := p.podsGetter.Pods(a.GetNamespace()).Get(ref.Name) - if errors.IsNotFound(err) { + if apierrors.IsNotFound(err) { return err } if err != nil { @@ -630,3 +638,20 @@ func (p *Plugin) admitCSINode(nodeName string, a admission.Attributes) error { return nil } + +func (p *Plugin) admitNodeResourceSlice(nodeName string, a admission.Attributes) error { + // The create request must come from a node with the same name as the NodeName field. + // Other requests gets checked by the node authorizer. + if a.GetOperation() == admission.Create { + slice, ok := a.GetObject().(*resource.NodeResourceSlice) + if !ok { + return admission.NewForbidden(a, fmt.Errorf("unexpected type %T", a.GetObject())) + } + + if slice.NodeName != nodeName { + return admission.NewForbidden(a, errors.New("can only create NodeResourceSlice with the same NodeName as the requesting node")) + } + } + + return nil +} diff --git a/plugin/pkg/admission/noderestriction/admission_test.go b/plugin/pkg/admission/noderestriction/admission_test.go index 8bfd0bfd0ea..dd8b4ee04ac 100644 --- a/plugin/pkg/admission/noderestriction/admission_test.go +++ b/plugin/pkg/admission/noderestriction/admission_test.go @@ -44,6 +44,7 @@ import ( "k8s.io/kubernetes/pkg/apis/coordination" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/policy" + resourceapi "k8s.io/kubernetes/pkg/apis/resource" storage "k8s.io/kubernetes/pkg/apis/storage" "k8s.io/kubernetes/pkg/auth/nodeidentifier" "k8s.io/utils/pointer" @@ -1601,3 +1602,84 @@ func createPodAttributes(pod *api.Pod, user user.Info) admission.Attributes { podKind := api.Kind("Pod").WithVersion("v1") return admission.NewAttributesRecord(pod, nil, podKind, pod.Namespace, pod.Name, podResource, "", admission.Create, &metav1.CreateOptions{}, false, user) } + +func TestAdmitNodeResourceSlice(t *testing.T) { + apiResource := resourceapi.SchemeGroupVersion.WithResource("noderesourceslices") + nodename := "mynode" + mynode := &user.DefaultInfo{Name: "system:node:" + nodename, Groups: []string{"system:nodes"}} + err := "can only create NodeResourceSlice with the same NodeName as the requesting node" + + sliceNode := &resourceapi.NodeResourceSlice{ + ObjectMeta: metav1.ObjectMeta{ + Name: "something", + }, + NodeName: nodename, + } + sliceOtherNode := &resourceapi.NodeResourceSlice{ + ObjectMeta: metav1.ObjectMeta{ + Name: "something", + }, + NodeName: nodename + "-other", + } + + tests := map[string]struct { + operation admission.Operation + obj runtime.Object + featureEnabled bool + expectError string + }{ + "create allowed, enabled": { + operation: admission.Create, + obj: sliceNode, + featureEnabled: true, + expectError: "", + }, + "create disallowed, enabled": { + operation: admission.Create, + obj: sliceOtherNode, + featureEnabled: true, + expectError: err, + }, + "create allowed, disabled": { + operation: admission.Create, + obj: sliceNode, + featureEnabled: false, + expectError: "", + }, + "create disallowed, disabled": { + operation: admission.Create, + obj: sliceOtherNode, + featureEnabled: false, + expectError: err, + }, + "update allowed, same node": { + operation: admission.Update, + obj: sliceNode, + featureEnabled: true, + expectError: "", + }, + "update allowed, other node": { + operation: admission.Update, + obj: sliceOtherNode, + featureEnabled: true, + expectError: "", + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + attributes := admission.NewAttributesRecord( + test.obj, nil, schema.GroupVersionKind{}, + "", "foo", apiResource, "", test.operation, &metav1.CreateOptions{}, false, mynode) + defer featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.DynamicResourceAllocation, test.featureEnabled)() + a := &admitTestCase{ + name: name, + attributes: attributes, + features: feature.DefaultFeatureGate, + err: test.expectError, + } + a.run(t) + }) + + } +} From 096e9489050e7bed0c33d00ca4b6d6031e44e247 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Fri, 16 Feb 2024 11:50:48 +0100 Subject: [PATCH 05/18] dra scheduler: support structured parameters When a claim uses structured parameters, as indicated by the resource class flag, the scheduler is responsible for allocating it. To do this it needs to gather information about available node resources by watching NodeResourceSlices and then match the in-tree claim parameters against those resources. --- pkg/scheduler/eventhandlers.go | 18 + .../dynamicresources/dynamicresources.go | 662 ++++++++++++++++-- .../dynamicresources/dynamicresources_test.go | 6 +- .../dynamicresources/structuredparameters.go | 134 ++++ pkg/scheduler/framework/types.go | 26 +- pkg/scheduler/scheduler_test.go | 30 +- .../authorizer/rbac/bootstrappolicy/policy.go | 4 +- .../resourceclaim/resourceclaim.go | 14 + 8 files changed, 799 insertions(+), 95 deletions(-) create mode 100644 pkg/scheduler/framework/plugins/dynamicresources/structuredparameters.go diff --git a/pkg/scheduler/eventhandlers.go b/pkg/scheduler/eventhandlers.go index 5bf149ebf72..b2a0f331f53 100644 --- a/pkg/scheduler/eventhandlers.go +++ b/pkg/scheduler/eventhandlers.go @@ -472,6 +472,24 @@ func addAllEventHandlers( } handlers = append(handlers, handlerRegistration) } + case framework.ResourceClaimParameters: + if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) { + if handlerRegistration, err = informerFactory.Resource().V1alpha2().ResourceClaimParameters().Informer().AddEventHandler( + buildEvtResHandler(at, framework.ResourceClaimParameters, "ResourceClaimParameters"), + ); err != nil { + return err + } + handlers = append(handlers, handlerRegistration) + } + case framework.ResourceClassParameters: + if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) { + if handlerRegistration, err = informerFactory.Resource().V1alpha2().ResourceClassParameters().Informer().AddEventHandler( + buildEvtResHandler(at, framework.ResourceClassParameters, "ResourceClassParameters"), + ); err != nil { + return err + } + handlers = append(handlers, handlerRegistration) + } case framework.StorageClass: if at&framework.Add != 0 { if handlerRegistration, err = informerFactory.Storage().V1().StorageClasses().Informer().AddEventHandler( diff --git a/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go b/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go index 6373ee16640..9cfa96e88fe 100644 --- a/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go +++ b/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go @@ -18,8 +18,10 @@ package dynamicresources import ( "context" + "encoding/json" "errors" "fmt" + "slices" "sort" "sync" @@ -30,6 +32,7 @@ import ( apiequality "k8s.io/apimachinery/pkg/api/equality" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" @@ -43,6 +46,7 @@ import ( "k8s.io/kubernetes/pkg/scheduler/framework" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" + "k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding" schedutil "k8s.io/kubernetes/pkg/scheduler/util" "k8s.io/utils/ptr" ) @@ -70,37 +74,52 @@ type stateData struct { // Empty if the Pod has no claims. claims []*resourcev1alpha2.ResourceClaim + // podSchedulingState keeps track of the PodSchedulingContext + // (if one exists) and the changes made to it. + podSchedulingState podSchedulingState + + // resourceModel contains the information about available and allocated resources when using + // structured parameters and the pod needs this information. + resources resources + + // mutex must be locked while accessing any of the fields below. + mutex sync.Mutex + // The indices of all claims that: // - are allocated - // - use delayed allocation + // - use delayed allocation or the builtin controller // - were not available on at least one node // // Set in parallel during Filter, so write access there must be // protected by the mutex. Used by PostFilter. unavailableClaims sets.Set[int] - // podSchedulingState keeps track of the PodSchedulingContext - // (if one exists) and the changes made to it. - podSchedulingState podSchedulingState - - mutex sync.Mutex - informationsForClaim []informationForClaim } +func (d *stateData) Clone() framework.StateData { + return d +} + type informationForClaim struct { // The availableOnNode node filter of the claim converted from the // v1 API to nodeaffinity.NodeSelector by PreFilter for repeated // evaluation in Filter. Nil for claim which don't have it. availableOnNode *nodeaffinity.NodeSelector + // The status of the claim got from the // schedulingCtx by PreFilter for repeated // evaluation in Filter. Nil for claim which don't have it. status *resourcev1alpha2.ResourceClaimSchedulingStatus -} -func (d *stateData) Clone() framework.StateData { - return d + // structuredParameters is true if the claim is handled via the builtin + // controller. + structuredParameters bool + controller *claimController + + // Set by Reserved, published by PreBind. + allocation *resourcev1alpha2.AllocationResult + allocationDriverName string } type podSchedulingState struct { @@ -256,23 +275,90 @@ type dynamicResources struct { claimLister resourcev1alpha2listers.ResourceClaimLister classLister resourcev1alpha2listers.ResourceClassLister podSchedulingContextLister resourcev1alpha2listers.PodSchedulingContextLister + claimParametersLister resourcev1alpha2listers.ResourceClaimParametersLister + classParametersLister resourcev1alpha2listers.ResourceClassParametersLister + nodeResourceSliceLister resourcev1alpha2listers.NodeResourceSliceLister + claimNameLookup *resourceclaim.Lookup + + // claimAssumeCache enables temporarily storing a newer claim object + // while the scheduler has allocated it and the corresponding object + // update from the apiserver has not been processed by the claim + // informer callbacks. Claims get added here in Reserve and removed by + // the informer callback (based on the "newer than" comparison in the + // assume cache) or when the API call in PreBind fails. + // + // It uses cache.MetaNamespaceKeyFunc to generate object names, which + // therefore are "/". + // + // This is necessary to ensure that reconstructing the resource usage + // at the start of a pod scheduling cycle doesn't reuse the resources + // assigned to such a claim. Alternatively, claim allocation state + // could also get tracked across pod scheduling cycles, but that + // - adds complexity (need to carefully sync state with informer events + // for claims and NodeResourceSlices) + // - would make integration with cluster autoscaler harder because it would need + // to trigger informer callbacks. + // + // When implementing cluster autoscaler support, this assume cache or + // something like it (see https://github.com/kubernetes/kubernetes/pull/112202) + // might have to be managed by the cluster autoscaler. + claimAssumeCache volumebinding.AssumeCache + + // inFlightAllocations is map from claim UUIDs to true for those claims + // for which allocation was triggered during a scheduling cycle and the + // corresponding claim status update call in PreBind has not been done + // yet. If another pod needs the claim, the pod is treated as "not + // schedulable yet". The cluster event for the claim status update will + // make it schedulable. + // + // This mechanism avoids the following problem: + // - Pod A triggers allocation for claim X. + // - Pod B shares access to that claim and gets scheduled because + // the claim is assumed to be allocated. + // - PreBind for pod B is called first, tries to update reservedFor and + // fails because the claim is not really allocated yet. + // + // We could avoid the ordering problem by allowing either pod A or pod B + // to set the allocation. But that is more complicated and leads to another + // problem: + // - Pod A and B get scheduled as above. + // - PreBind for pod A gets called first, then fails with a temporary API error. + // It removes the updated claim from the assume cache because of that. + // - PreBind for pod B gets called next and succeeds with adding the + // allocation and its own reservedFor entry. + // - The assume cache is now not reflecting that the claim is allocated, + // which could lead to reusing the same resource for some other claim. + // + // A sync.Map is used because in practice sharing of a claim between + // pods is expected to be rare compared to per-pod claim, so we end up + // hitting the "multiple goroutines read, write, and overwrite entries + // for disjoint sets of keys" case that sync.Map is optimized for. + inFlightAllocations sync.Map } // New initializes a new plugin and returns it. -func New(_ context.Context, plArgs runtime.Object, fh framework.Handle, fts feature.Features) (framework.Plugin, error) { +func New(ctx context.Context, plArgs runtime.Object, fh framework.Handle, fts feature.Features) (framework.Plugin, error) { if !fts.EnableDynamicResourceAllocation { // Disabled, won't do anything. return &dynamicResources{}, nil } - return &dynamicResources{ + logger := klog.FromContext(ctx) + pl := &dynamicResources{ enabled: true, fh: fh, clientset: fh.ClientSet(), claimLister: fh.SharedInformerFactory().Resource().V1alpha2().ResourceClaims().Lister(), classLister: fh.SharedInformerFactory().Resource().V1alpha2().ResourceClasses().Lister(), podSchedulingContextLister: fh.SharedInformerFactory().Resource().V1alpha2().PodSchedulingContexts().Lister(), - }, nil + claimParametersLister: fh.SharedInformerFactory().Resource().V1alpha2().ResourceClaimParameters().Lister(), + classParametersLister: fh.SharedInformerFactory().Resource().V1alpha2().ResourceClassParameters().Lister(), + nodeResourceSliceLister: fh.SharedInformerFactory().Resource().V1alpha2().NodeResourceSlices().Lister(), + claimNameLookup: resourceclaim.NewNameLookup(fh.ClientSet()), + claimAssumeCache: volumebinding.NewAssumeCache(logger, fh.SharedInformerFactory().Resource().V1alpha2().ResourceClaims().Informer(), "claim", "", nil), + } + + return pl, nil } var _ framework.PreEnqueuePlugin = &dynamicResources{} @@ -296,7 +382,13 @@ func (pl *dynamicResources) EventsToRegister() []framework.ClusterEventWithHint if !pl.enabled { return nil } + events := []framework.ClusterEventWithHint{ + // Changes for claim or class parameters creation may make pods + // schedulable which depend on claims using those parameters. + {Event: framework.ClusterEvent{Resource: framework.ResourceClaimParameters, ActionType: framework.Add | framework.Update}, QueueingHintFn: pl.isSchedulableAfterClaimParametersChange}, + {Event: framework.ClusterEvent{Resource: framework.ResourceClassParameters, ActionType: framework.Add | framework.Update}, QueueingHintFn: pl.isSchedulableAfterClassParametersChange}, + // Allocation is tracked in ResourceClaims, so any changes may make the pods schedulable. {Event: framework.ClusterEvent{Resource: framework.ResourceClaim, ActionType: framework.Add | framework.Update}, QueueingHintFn: pl.isSchedulableAfterClaimChange}, // When a driver has provided additional information, a pod waiting for that information @@ -321,6 +413,149 @@ func (pl *dynamicResources) PreEnqueue(ctx context.Context, pod *v1.Pod) (status return nil } +// isSchedulableAfterClaimParametersChange is invoked for add and update claim parameters events reported by +// an informer. It checks whether that change made a previously unschedulable +// pod schedulable. It errs on the side of letting a pod scheduling attempt +// happen. The delete claim event will not invoke it, so newObj will never be nil. +func (pl *dynamicResources) isSchedulableAfterClaimParametersChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { + originalParameters, modifiedParameters, err := schedutil.As[*resourcev1alpha2.ResourceClaimParameters](oldObj, newObj) + if err != nil { + // Shouldn't happen. + return framework.Queue, fmt.Errorf("unexpected object in isSchedulableAfterClaimParametersChange: %w", err) + } + + usesParameters := false + if err := pl.foreachPodResourceClaim(pod, func(_ string, claim *resourcev1alpha2.ResourceClaim) { + ref := claim.Spec.ParametersRef + if ref == nil { + return + } + + // Using in-tree parameters directly? + if ref.APIGroup == resourcev1alpha2.SchemeGroupVersion.Group && + ref.Kind == "ResourceClaimParameters" { + if modifiedParameters.Name == ref.Name { + usesParameters = true + } + return + } + + // Need to look for translated parameters. + generatedFrom := modifiedParameters.GeneratedFrom + if generatedFrom == nil { + return + } + if generatedFrom.APIGroup == ref.APIGroup && + generatedFrom.Kind == ref.Kind && + generatedFrom.Name == ref.Name { + usesParameters = true + } + }); err != nil { + // This is not an unexpected error: we know that + // foreachPodResourceClaim only returns errors for "not + // schedulable". + logger.V(4).Info("pod is not schedulable", "pod", klog.KObj(pod), "claim", klog.KObj(modifiedParameters), "reason", err.Error()) + return framework.QueueSkip, nil + } + + if !usesParameters { + // This were not the parameters the pod was waiting for. + logger.V(6).Info("unrelated claim parameters got modified", "pod", klog.KObj(pod), "claimParameters", klog.KObj(modifiedParameters)) + return framework.QueueSkip, nil + } + + if originalParameters == nil { + logger.V(4).Info("claim parameters for pod got created", "pod", klog.KObj(pod), "claimParameters", klog.KObj(modifiedParameters)) + return framework.Queue, nil + } + + // Modifications may or may not be relevant. If the entire + // requests are as before, then something else must have changed + // and we don't care. + if apiequality.Semantic.DeepEqual(&originalParameters.DriverRequests, &modifiedParameters.DriverRequests) { + logger.V(6).Info("claim parameters for pod got modified where the pod doesn't care", "pod", klog.KObj(pod), "claimParameters", klog.KObj(modifiedParameters)) + return framework.QueueSkip, nil + } + + logger.V(4).Info("requests in claim parameters for pod got updated", "pod", klog.KObj(pod), "claimParameters", klog.KObj(modifiedParameters)) + return framework.Queue, nil +} + +// isSchedulableAfterClassParametersChange is invoked for add and update class parameters events reported by +// an informer. It checks whether that change made a previously unschedulable +// pod schedulable. It errs on the side of letting a pod scheduling attempt +// happen. The delete class event will not invoke it, so newObj will never be nil. +func (pl *dynamicResources) isSchedulableAfterClassParametersChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { + originalParameters, modifiedParameters, err := schedutil.As[*resourcev1alpha2.ResourceClassParameters](oldObj, newObj) + if err != nil { + // Shouldn't happen. + return framework.Queue, fmt.Errorf("unexpected object in isSchedulableAfterClassParametersChange: %w", err) + } + + usesParameters := false + if err := pl.foreachPodResourceClaim(pod, func(_ string, claim *resourcev1alpha2.ResourceClaim) { + class, err := pl.classLister.Get(claim.Spec.ResourceClassName) + if err != nil { + if !apierrors.IsNotFound(err) { + logger.Error(err, "look up resource class") + } + return + } + ref := class.ParametersRef + if ref == nil { + return + } + + // Using in-tree parameters directly? + if ref.APIGroup == resourcev1alpha2.SchemeGroupVersion.Group && + ref.Kind == "ResourceClassParameters" { + if modifiedParameters.Name == ref.Name { + usesParameters = true + } + return + } + + // Need to look for translated parameters. + generatedFrom := modifiedParameters.GeneratedFrom + if generatedFrom == nil { + return + } + if generatedFrom.APIGroup == ref.APIGroup && + generatedFrom.Kind == ref.Kind && + generatedFrom.Name == ref.Name { + usesParameters = true + } + }); err != nil { + // This is not an unexpected error: we know that + // foreachPodResourceClaim only returns errors for "not + // schedulable". + logger.V(4).Info("pod is not schedulable", "pod", klog.KObj(pod), "classParameters", klog.KObj(modifiedParameters), "reason", err.Error()) + return framework.QueueSkip, nil + } + + if !usesParameters { + // This were not the parameters the pod was waiting for. + logger.V(6).Info("unrelated class parameters got modified", "pod", klog.KObj(pod), "classParameters", klog.KObj(modifiedParameters)) + return framework.QueueSkip, nil + } + + if originalParameters == nil { + logger.V(4).Info("class parameters for pod got created", "pod", klog.KObj(pod), "class", klog.KObj(modifiedParameters)) + return framework.Queue, nil + } + + // Modifications may or may not be relevant. If the entire + // requests are as before, then something else must have changed + // and we don't care. + if apiequality.Semantic.DeepEqual(&originalParameters.Filters, &modifiedParameters.Filters) { + logger.V(6).Info("class parameters for pod got modified where the pod doesn't care", "pod", klog.KObj(pod), "classParameters", klog.KObj(modifiedParameters)) + return framework.QueueSkip, nil + } + + logger.V(4).Info("filters in class parameters for pod got updated", "pod", klog.KObj(pod), "classParameters", klog.KObj(modifiedParameters)) + return framework.Queue, nil +} + // isSchedulableAfterClaimChange is invoked for add and update claim events reported by // an informer. It checks whether that change made a previously unschedulable // pod schedulable. It errs on the side of letting a pod scheduling attempt @@ -345,6 +580,33 @@ func (pl *dynamicResources) isSchedulableAfterClaimChange(logger klog.Logger, po return framework.QueueSkip, nil } + if originalClaim != nil && + resourceclaim.IsAllocatedWithStructuredParameters(originalClaim) && + modifiedClaim.Status.Allocation == nil { + // A claim with structured parameters was deallocated. This might have made + // resources available for other pods. + // + // TODO (https://github.com/kubernetes/kubernetes/issues/123697): + // check that the pending claims depend on structured parameters (depends on refactoring foreachPodResourceClaim, see other TODO). + // + // There is a small race here: + // - The dynamicresources plugin allocates claim A and updates the assume cache. + // - A second pod gets marked as unschedulable based on that assume cache. + // - Before the informer cache here catches up, the pod runs, terminates and + // the claim gets deallocated without ever sending the claim status with + // allocation to the scheduler. + // - The comparison below is for a *very* old claim with no allocation and the + // new claim where the allocation is already removed again, so no + // RemovedClaimAllocation event gets emitted. + // + // This is extremely unlikely and thus a fix is not needed for alpha in Kubernetes 1.30. + // TODO (https://github.com/kubernetes/kubernetes/issues/123698): The solution is to somehow integrate the assume cache + // into the event mechanism. This can be tackled together with adding autoscaler + // support, which also needs to do something with the assume cache. + logger.V(6).Info("claim with structured parameters got deallocated", "pod", klog.KObj(pod), "claim", klog.KObj(modifiedClaim)) + return framework.Queue, nil + } + if !usesClaim { // This was not the claim the pod was waiting for. logger.V(6).Info("unrelated claim got modified", "pod", klog.KObj(pod), "claim", klog.KObj(modifiedClaim)) @@ -526,7 +788,7 @@ func (pl *dynamicResources) podResourceClaims(pod *v1.Pod) ([]*resourcev1alpha2. // It calls an optional handler for those claims that it finds. func (pl *dynamicResources) foreachPodResourceClaim(pod *v1.Pod, cb func(podResourceName string, claim *resourcev1alpha2.ResourceClaim)) error { for _, resource := range pod.Spec.ResourceClaims { - claimName, mustCheckOwner, err := resourceclaim.Name(pod, &resource) + claimName, mustCheckOwner, err := pl.claimNameLookup.Name(pod, &resource) if err != nil { return err } @@ -578,24 +840,21 @@ func (pl *dynamicResources) PreFilter(ctx context.Context, state *framework.Cycl return nil, statusUnschedulable(logger, err.Error()) } logger.V(5).Info("pod resource claims", "pod", klog.KObj(pod), "resourceclaims", klog.KObjSlice(claims)) + // If the pod does not reference any claim, // DynamicResources Filter has nothing to do with the Pod. if len(claims) == 0 { return nil, framework.NewStatus(framework.Skip) } - // Fetch s.podSchedulingState.schedulingCtx, it's going to be needed when checking claims. + // Fetch PodSchedulingContext, it's going to be needed when checking claims. if err := s.podSchedulingState.init(ctx, pod, pl.podSchedulingContextLister); err != nil { return nil, statusError(logger, err) } s.informationsForClaim = make([]informationForClaim, len(claims)) + needResourceInformation := false for index, claim := range claims { - if claim.Spec.AllocationMode == resourcev1alpha2.AllocationModeImmediate && - claim.Status.Allocation == nil { - // This will get resolved by the resource driver. - return nil, statusUnschedulable(logger, "unallocated immediate resourceclaim", "pod", klog.KObj(pod), "resourceclaim", klog.KObj(claim)) - } if claim.Status.DeallocationRequested { // This will get resolved by the resource driver. return nil, statusUnschedulable(logger, "resourceclaim must be reallocated", "pod", klog.KObj(pod), "resourceclaim", klog.KObj(claim)) @@ -606,16 +865,20 @@ func (pl *dynamicResources) PreFilter(ctx context.Context, state *framework.Cycl // Resource is in use. The pod has to wait. return nil, statusUnschedulable(logger, "resourceclaim in use", "pod", klog.KObj(pod), "resourceclaim", klog.KObj(claim)) } - if claim.Status.Allocation != nil && - claim.Status.Allocation.AvailableOnNodes != nil { - nodeSelector, err := nodeaffinity.NewNodeSelector(claim.Status.Allocation.AvailableOnNodes) - if err != nil { - return nil, statusError(logger, err) + + if claim.Status.Allocation != nil { + if claim.Status.Allocation.AvailableOnNodes != nil { + nodeSelector, err := nodeaffinity.NewNodeSelector(claim.Status.Allocation.AvailableOnNodes) + if err != nil { + return nil, statusError(logger, err) + } + s.informationsForClaim[index].availableOnNode = nodeSelector } - s.informationsForClaim[index].availableOnNode = nodeSelector - } - if claim.Status.Allocation == nil && - claim.Spec.AllocationMode == resourcev1alpha2.AllocationModeWaitForFirstConsumer { + + // The claim was allocated by the scheduler if it has the finalizer that is + // reserved for Kubernetes. + s.informationsForClaim[index].structuredParameters = slices.Contains(claim.Finalizers, resourcev1alpha2.Finalizer) + } else { // The ResourceClass might have a node filter. This is // useful for trimming the initial set of potential // nodes before we ask the driver(s) for information @@ -638,16 +901,140 @@ func (pl *dynamicResources) PreFilter(ctx context.Context, state *framework.Cycl } s.informationsForClaim[index].availableOnNode = selector } - // Now we need information from drivers. s.informationsForClaim[index].status = statusForClaim(s.podSchedulingState.schedulingCtx, pod.Spec.ResourceClaims[index].Name) + + if class.StructuredParameters != nil && *class.StructuredParameters { + s.informationsForClaim[index].structuredParameters = true + + // Allocation in flight? Better wait for that + // to finish, see inFlightAllocations + // documentation for details. + if _, found := pl.inFlightAllocations.Load(claim.UID); found { + return nil, statusUnschedulable(logger, fmt.Sprintf("resource claim %s is in the process of being allocated", klog.KObj(claim))) + } + + // We need the claim and class parameters. If + // they don't exist yet, the pod has to wait. + // + // TODO (https://github.com/kubernetes/kubernetes/issues/123697): + // check this already in foreachPodResourceClaim, together with setting up informationsForClaim. + // Then PreEnqueue will also check for existence of parameters. + classParameters, claimParameters, status := pl.lookupParameters(logger, class, claim) + if status != nil { + return nil, status + } + controller, err := newClaimController(logger, class, classParameters, claimParameters) + if err != nil { + return nil, statusError(logger, err) + } + s.informationsForClaim[index].controller = controller + needResourceInformation = true + } else if claim.Spec.AllocationMode == resourcev1alpha2.AllocationModeImmediate { + // This will get resolved by the resource driver. + return nil, statusUnschedulable(logger, "unallocated immediate resourceclaim", "pod", klog.KObj(pod), "resourceclaim", klog.KObj(claim)) + } } } + if needResourceInformation { + // Doing this over and over again for each pod could be avoided + // by parsing once when creating the plugin and then updating + // that state in informer callbacks. But that would cause + // problems for using the plugin in the Cluster Autoscaler. If + // this step here turns out to be expensive, we may have to + // maintain and update state more persistently. + resources, err := newResourceModel(logger, pl.nodeResourceSliceLister, pl.claimAssumeCache) + if err != nil { + return nil, statusError(logger, err) + } + s.resources = resources + } + s.claims = claims - state.Write(stateKey, s) return nil, nil } +func (pl *dynamicResources) lookupParameters(logger klog.Logger, class *resourcev1alpha2.ResourceClass, claim *resourcev1alpha2.ResourceClaim) (classParameters *resourcev1alpha2.ResourceClassParameters, claimParameters *resourcev1alpha2.ResourceClaimParameters, status *framework.Status) { + classParameters, status = pl.lookupClassParameters(logger, class) + if status != nil { + return + } + claimParameters, status = pl.lookupClaimParameters(logger, claim) + return +} + +func (pl *dynamicResources) lookupClassParameters(logger klog.Logger, class *resourcev1alpha2.ResourceClass) (*resourcev1alpha2.ResourceClassParameters, *framework.Status) { + if class.ParametersRef == nil { + return nil, nil + } + + if class.ParametersRef.APIGroup == resourcev1alpha2.SchemeGroupVersion.Group && + class.ParametersRef.Kind == "ResourceClassParameters" { + // Use the parameters which were referenced directly. + parameters, err := pl.classParametersLister.ResourceClassParameters(class.ParametersRef.Namespace).Get(class.ParametersRef.Name) + if err != nil { + if apierrors.IsNotFound(err) { + return nil, statusUnschedulable(logger, fmt.Sprintf("class parameters %s not found", klog.KRef(class.ParametersRef.Namespace, class.ParametersRef.Name))) + } + return nil, statusError(logger, fmt.Errorf("get class parameters %s: %v", klog.KRef(class.Namespace, class.ParametersRef.Name), err)) + } + return parameters, nil + } + + // TODO (https://github.com/kubernetes/kubernetes/issues/123731): use an indexer + allParameters, err := pl.classParametersLister.ResourceClassParameters(class.Namespace).List(labels.Everything()) + if err != nil { + return nil, statusError(logger, fmt.Errorf("listing class parameters failed: %v", err)) + } + for _, parameters := range allParameters { + if parameters.GeneratedFrom == nil { + continue + } + if parameters.GeneratedFrom.APIGroup == class.ParametersRef.APIGroup && + parameters.GeneratedFrom.Kind == class.ParametersRef.Kind && + parameters.GeneratedFrom.Name == class.ParametersRef.Name && + parameters.GeneratedFrom.Namespace == class.ParametersRef.Namespace { + return parameters, nil + } + } + return nil, statusUnschedulable(logger, fmt.Sprintf("generated class parameters for %s.%s %s not found", class.ParametersRef.Kind, class.ParametersRef.APIGroup, klog.KRef(class.Namespace, class.ParametersRef.Name))) +} + +func (pl *dynamicResources) lookupClaimParameters(logger klog.Logger, claim *resourcev1alpha2.ResourceClaim) (*resourcev1alpha2.ResourceClaimParameters, *framework.Status) { + if claim.Spec.ParametersRef == nil { + return nil, nil + } + if claim.Spec.ParametersRef.APIGroup == resourcev1alpha2.SchemeGroupVersion.Group && + claim.Spec.ParametersRef.Kind == "ResourceClaimParameters" { + // Use the parameters which were referenced directly. + parameters, err := pl.claimParametersLister.ResourceClaimParameters(claim.Namespace).Get(claim.Spec.ParametersRef.Name) + if err != nil { + if apierrors.IsNotFound(err) { + return nil, statusUnschedulable(logger, fmt.Sprintf("claim parameters %s not found", klog.KRef(claim.Namespace, claim.Spec.ParametersRef.Name))) + } + return nil, statusError(logger, fmt.Errorf("get claim parameters %s: %v", klog.KRef(claim.Namespace, claim.Spec.ParametersRef.Name), err)) + } + return parameters, nil + } + + // TODO (https://github.com/kubernetes/kubernetes/issues/123731): use an indexer + allParameters, err := pl.claimParametersLister.ResourceClaimParameters(claim.Namespace).List(labels.Everything()) + if err != nil { + return nil, statusError(logger, fmt.Errorf("listing claim parameters failed: %v", err)) + } + for _, parameters := range allParameters { + if parameters.GeneratedFrom == nil { + continue + } + if parameters.GeneratedFrom.APIGroup == claim.Spec.ParametersRef.APIGroup && + parameters.GeneratedFrom.Kind == claim.Spec.ParametersRef.Kind && + parameters.GeneratedFrom.Name == claim.Spec.ParametersRef.Name { + return parameters, nil + } + } + return nil, statusUnschedulable(logger, fmt.Sprintf("generated claim parameters for %s.%s %s not found", claim.Spec.ParametersRef.Kind, claim.Spec.ParametersRef.APIGroup, klog.KRef(claim.Namespace, claim.Spec.ParametersRef.Name))) +} + // PreFilterExtensions returns prefilter extensions, pod add and remove. func (pl *dynamicResources) PreFilterExtensions() framework.PreFilterExtensions { return nil @@ -703,22 +1090,39 @@ func (pl *dynamicResources) Filter(ctx context.Context, cs *framework.CycleState case claim.Status.DeallocationRequested: // We shouldn't get here. PreFilter already checked this. return statusUnschedulable(logger, "resourceclaim must be reallocated", "pod", klog.KObj(pod), "node", klog.KObj(node), "resourceclaim", klog.KObj(claim)) - case claim.Spec.AllocationMode == resourcev1alpha2.AllocationModeWaitForFirstConsumer: + case claim.Spec.AllocationMode == resourcev1alpha2.AllocationModeWaitForFirstConsumer || + state.informationsForClaim[index].structuredParameters: if selector := state.informationsForClaim[index].availableOnNode; selector != nil { if matches := selector.Match(node); !matches { return statusUnschedulable(logger, "excluded by resource class node filter", "pod", klog.KObj(pod), "node", klog.KObj(node), "resourceclassName", claim.Spec.ResourceClassName) } } - if status := state.informationsForClaim[index].status; status != nil { - for _, unsuitableNode := range status.UnsuitableNodes { - if node.Name == unsuitableNode { - return statusUnschedulable(logger, "resourceclaim cannot be allocated for the node (unsuitable)", "pod", klog.KObj(pod), "node", klog.KObj(node), "resourceclaim", klog.KObj(claim), "unsuitablenodes", status.UnsuitableNodes) + // Can the builtin controller tell us whether the node is suitable? + if state.informationsForClaim[index].structuredParameters { + suitable, err := state.informationsForClaim[index].controller.nodeIsSuitable(ctx, node.Name, state.resources) + if err != nil { + // An error indicates that something wasn't configured correctly, for example + // writing a CEL expression which doesn't handle a map lookup error. Normally + // this should never fail. We could return an error here, but then the pod + // would get retried. Instead we ignore the node. + return statusUnschedulable(logger, fmt.Sprintf("checking structured parameters failed: %v", err), "pod", klog.KObj(pod), "node", klog.KObj(node), "resourceclaim", klog.KObj(claim)) + } + if !suitable { + return statusUnschedulable(logger, "resourceclaim cannot be allocated for the node (unsuitable)", "pod", klog.KObj(pod), "node", klog.KObj(node), "resourceclaim", klog.KObj(claim)) + } + } else { + if status := state.informationsForClaim[index].status; status != nil { + for _, unsuitableNode := range status.UnsuitableNodes { + if node.Name == unsuitableNode { + return statusUnschedulable(logger, "resourceclaim cannot be allocated for the node (unsuitable)", "pod", klog.KObj(pod), "node", klog.KObj(node), "resourceclaim", klog.KObj(claim), "unsuitablenodes", status.UnsuitableNodes) + } } } } default: - // This should have been delayed allocation. Immediate - // allocation was already checked for in PreFilter. + // This claim should have been handled above. + // Immediate allocation with control plane controller + // was already checked for in PreFilter. return statusError(logger, fmt.Errorf("internal error, unexpected allocation mode %v", claim.Spec.AllocationMode)) } } @@ -736,7 +1140,11 @@ func (pl *dynamicResources) Filter(ctx context.Context, cs *framework.CycleState // delayed allocation. Claims with immediate allocation // would just get allocated again for a random node, // which is unlikely to help the pod. - if claim.Spec.AllocationMode == resourcev1alpha2.AllocationModeWaitForFirstConsumer { + // + // Claims with builtin controller are handled like + // claims with delayed allocation. + if claim.Spec.AllocationMode == resourcev1alpha2.AllocationModeWaitForFirstConsumer || + state.informationsForClaim[index].controller != nil { state.unavailableClaims.Insert(index) } } @@ -769,12 +1177,19 @@ func (pl *dynamicResources) PostFilter(ctx context.Context, cs *framework.CycleS claim := state.claims[index] if len(claim.Status.ReservedFor) == 0 || len(claim.Status.ReservedFor) == 1 && claim.Status.ReservedFor[0].UID == pod.UID { + // Is the claim is handled by the builtin controller? + // Then we can simply clear the allocation. Once the + // claim informer catches up, the controllers will + // be notified about this change. + clearAllocation := state.informationsForClaim[index].controller != nil + // Before we tell a driver to deallocate a claim, we // have to stop telling it to allocate. Otherwise, // depending on timing, it will deallocate the claim, // see a PodSchedulingContext with selected node, and // allocate again for that same node. - if state.podSchedulingState.schedulingCtx != nil && + if !clearAllocation && + state.podSchedulingState.schedulingCtx != nil && state.podSchedulingState.schedulingCtx.Spec.SelectedNode != "" { state.podSchedulingState.selectedNode = ptr.To("") if err := state.podSchedulingState.publish(ctx, pod, pl.clientset); err != nil { @@ -782,9 +1197,13 @@ func (pl *dynamicResources) PostFilter(ctx context.Context, cs *framework.CycleS } } - claim := state.claims[index].DeepCopy() - claim.Status.DeallocationRequested = true + claim := claim.DeepCopy() claim.Status.ReservedFor = nil + if clearAllocation { + claim.Status.Allocation = nil + } else { + claim.Status.DeallocationRequested = true + } logger.V(5).Info("Requesting deallocation of ResourceClaim", "pod", klog.KObj(pod), "resourceclaim", klog.KObj(claim)) if _, err := pl.clientset.ResourceV1alpha2().ResourceClaims(claim.Namespace).UpdateStatus(ctx, claim, metav1.UpdateOptions{}); err != nil { return nil, statusError(logger, err) @@ -815,14 +1234,15 @@ func (pl *dynamicResources) PreScore(ctx context.Context, cs *framework.CycleSta logger := klog.FromContext(ctx) pending := false - for _, claim := range state.claims { - if claim.Status.Allocation == nil { + for index, claim := range state.claims { + if claim.Status.Allocation == nil && + state.informationsForClaim[index].controller == nil { pending = true break } } if !pending { - logger.V(5).Info("no pending claims", "pod", klog.KObj(pod)) + logger.V(5).Info("no pending claims with control plane controller", "pod", klog.KObj(pod)) return nil } @@ -889,7 +1309,7 @@ func haveNode(nodeNames []string, nodeName string) bool { } // Reserve reserves claims for the pod. -func (pl *dynamicResources) Reserve(ctx context.Context, cs *framework.CycleState, pod *v1.Pod, nodeName string) *framework.Status { +func (pl *dynamicResources) Reserve(ctx context.Context, cs *framework.CycleState, pod *v1.Pod, nodeName string) (status *framework.Status) { if !pl.enabled { return nil } @@ -903,6 +1323,7 @@ func (pl *dynamicResources) Reserve(ctx context.Context, cs *framework.CycleStat numDelayedAllocationPending := 0 numClaimsWithStatusInfo := 0 + claimsWithBuiltinController := make([]int, 0, len(state.claims)) logger := klog.FromContext(ctx) for index, claim := range state.claims { if claim.Status.Allocation != nil { @@ -914,7 +1335,13 @@ func (pl *dynamicResources) Reserve(ctx context.Context, cs *framework.CycleStat continue } - // Must be delayed allocation. + // Do we have the builtin controller? + if state.informationsForClaim[index].controller != nil { + claimsWithBuiltinController = append(claimsWithBuiltinController, index) + continue + } + + // Must be delayed allocation with control plane controller. numDelayedAllocationPending++ // Did the driver provide information that steered node @@ -924,12 +1351,12 @@ func (pl *dynamicResources) Reserve(ctx context.Context, cs *framework.CycleStat } } - if numDelayedAllocationPending == 0 { + if numDelayedAllocationPending == 0 && len(claimsWithBuiltinController) == 0 { // Nothing left to do. return nil } - if !state.preScored { + if !state.preScored && numDelayedAllocationPending > 0 { // There was only one candidate that passed the Filters and // therefore PreScore was not called. // @@ -944,11 +1371,36 @@ func (pl *dynamicResources) Reserve(ctx context.Context, cs *framework.CycleStat } } + // Prepare allocation of claims handled by the schedulder. + for _, index := range claimsWithBuiltinController { + claim := state.claims[index] + driverName, allocation, err := state.informationsForClaim[index].controller.allocate(ctx, nodeName, state.resources) + if err != nil { + // We checked before that the node is suitable. This shouldn't have failed, + // so treat this as an error. + return statusError(logger, fmt.Errorf("claim allocation failed unexpectedly: %v", err)) + } + state.informationsForClaim[index].allocation = allocation + state.informationsForClaim[index].allocationDriverName = driverName + pl.inFlightAllocations.Store(claim.UID, true) + claim = claim.DeepCopy() + claim.Status.DriverName = driverName + claim.Status.Allocation = allocation + if err := pl.claimAssumeCache.Assume(claim); err != nil { + return statusError(logger, fmt.Errorf("update claim assume cache: %v", err)) + } + logger.V(5).Info("Reserved resource in allocation result", "claim", klog.KObj(claim), "driver", driverName, "allocation", allocation) + } + // When there is only one pending resource, we can go ahead with // requesting allocation even when we don't have the information from // the driver yet. Otherwise we wait for information before blindly // making a decision that might have to be reversed later. - if numDelayedAllocationPending == 1 || numClaimsWithStatusInfo == numDelayedAllocationPending { + // + // If all pending claims are handled with the builtin controller, + // there is no need for a PodSchedulingContext change. + if numDelayedAllocationPending == 1 && len(claimsWithBuiltinController) == 0 || + numClaimsWithStatusInfo+len(claimsWithBuiltinController) == numDelayedAllocationPending && len(claimsWithBuiltinController) < numDelayedAllocationPending { // TODO: can we increase the chance that the scheduler picks // the same node as before when allocation is on-going, // assuming that that node still fits the pod? Picking a @@ -970,6 +1422,13 @@ func (pl *dynamicResources) Reserve(ctx context.Context, cs *framework.CycleStat return nil } + // If all pending claims are handled with the builtin controller, then + // we can allow the pod to proceed. Allocating and reserving the claims + // will be done in PreBind. + if numDelayedAllocationPending == 0 { + return nil + } + // More than one pending claim and not enough information about all of them. // // TODO: can or should we ensure that schedulingCtx gets aborted while @@ -1016,7 +1475,15 @@ func (pl *dynamicResources) Unreserve(ctx context.Context, cs *framework.CycleSt } } - for _, claim := range state.claims { + for index, claim := range state.claims { + // If allocation was in-flight, then it's not anymore and we need to revert the + // claim object in the assume cache to what it was before. + if state.informationsForClaim[index].controller != nil { + if _, found := pl.inFlightAllocations.LoadAndDelete(state.claims[index].UID); found { + pl.claimAssumeCache.Restore(claim.Namespace + "/" + claim.Name) + } + } + if claim.Status.Allocation != nil && resourceclaim.IsReservedForPod(pod, claim) { // Remove pod from ReservedFor. A strategic-merge-patch is used @@ -1038,7 +1505,10 @@ func (pl *dynamicResources) Unreserve(ctx context.Context, cs *framework.CycleSt // PreBind gets called in a separate goroutine after it has been determined // that the pod should get bound to this node. Because Reserve did not actually -// reserve claims, we need to do it now. If that fails, we return an error and +// reserve claims, we need to do it now. For claims with the builtin controller, +// we also handle the allocation. +// +// If anything fails, we return an error and // the pod will have to go into the backoff queue. The scheduler will call // Unreserve as part of the error handling. func (pl *dynamicResources) PreBind(ctx context.Context, cs *framework.CycleState, pod *v1.Pod, nodeName string) *framework.Status { @@ -1056,6 +1526,7 @@ func (pl *dynamicResources) PreBind(ctx context.Context, cs *framework.CycleStat logger := klog.FromContext(ctx) // Was publishing delayed? If yes, do it now and then cause binding to stop. + // This will not happen if all claims get handled by builtin controllers. if state.podSchedulingState.isDirty() { if err := state.podSchedulingState.publish(ctx, pod, pl.clientset); err != nil { return statusError(logger, err) @@ -1065,23 +1536,7 @@ func (pl *dynamicResources) PreBind(ctx context.Context, cs *framework.CycleStat for index, claim := range state.claims { if !resourceclaim.IsReservedForPod(pod, claim) { - // The claim might be stale, for example because the claim can get shared and some - // other goroutine has updated it in the meantime. We therefore cannot use - // SSA here to add the pod because then we would have to send the entire slice - // or use different field manager strings for each entry. - // - // With a strategic-merge-patch, we can simply send one new entry. The apiserver - // validation will catch if two goroutines try to do that at the same time and - // the claim cannot be shared. - patch := fmt.Sprintf(`{"metadata": {"uid": %q}, "status": { "reservedFor": [ {"resource": "pods", "name": %q, "uid": %q} ] }}`, - claim.UID, - pod.Name, - pod.UID, - ) - logger.V(5).Info("reserve", "pod", klog.KObj(pod), "node", klog.ObjectRef{Name: nodeName}, "resourceclaim", klog.KObj(claim)) - claim, err := pl.clientset.ResourceV1alpha2().ResourceClaims(claim.Namespace).Patch(ctx, claim.Name, types.StrategicMergePatchType, []byte(patch), metav1.PatchOptions{}, "status") - logger.V(5).Info("reserved", "pod", klog.KObj(pod), "node", klog.ObjectRef{Name: nodeName}, "resourceclaim", klog.Format(claim)) - // TODO: metric for update errors. + claim, err := pl.bindClaim(ctx, state, index, pod, nodeName) if err != nil { return statusError(logger, err) } @@ -1093,6 +1548,75 @@ func (pl *dynamicResources) PreBind(ctx context.Context, cs *framework.CycleStat return nil } +// bindClaim gets called by PreBind for claim which is not reserved for the pod yet. +// It might not even be allocated. bindClaim then ensures that the allocation +// and reservation are recorded. This finishes the work started in Reserve. +func (pl *dynamicResources) bindClaim(ctx context.Context, state *stateData, index int, pod *v1.Pod, nodeName string) (patchedClaim *resourcev1alpha2.ResourceClaim, finalErr error) { + logger := klog.FromContext(ctx) + claim := state.claims[index] + allocationPatch := "" + + allocation := state.informationsForClaim[index].allocation + logger.V(5).Info("preparing claim status patch", "claim", klog.KObj(state.claims[index]), "allocation", allocation) + + // Do we need to store an allocation result from Reserve? + if allocation != nil { + buffer, err := json.Marshal(allocation) + if err != nil { + return nil, fmt.Errorf("marshaling AllocationResult failed: %v", err) + } + allocationPatch = fmt.Sprintf(`"driverName": %q, "allocation": %s, `, state.informationsForClaim[index].allocationDriverName, string(buffer)) + + // The finalizer needs to be added in a normal update. Using a simple update is fine + // because we don't expect concurrent modifications while the claim is not allocated + // yet. If there are any, we want to fail. + // + // If we were interrupted in the past, it might already be set and we simply continue. + if !slices.Contains(claim.Finalizers, resourcev1alpha2.Finalizer) { + claim := state.claims[index].DeepCopy() + claim.Finalizers = append(claim.Finalizers, resourcev1alpha2.Finalizer) + if _, err := pl.clientset.ResourceV1alpha2().ResourceClaims(claim.Namespace).Update(ctx, claim, metav1.UpdateOptions{}); err != nil { + return nil, fmt.Errorf("add finalizer: %v", err) + } + } + } + + // The claim might be stale, for example because the claim can get shared and some + // other goroutine has updated it in the meantime. We therefore cannot use + // SSA here to add the pod because then we would have to send the entire slice + // or use different field manager strings for each entry. + // + // With a strategic-merge-patch, we can simply send one new entry. The apiserver + // validation will catch if two goroutines try to do that at the same time and + // the claim cannot be shared. + // + // Note that this also works when the allocation result gets added twice because + // two pods both started using a shared claim: the first pod to get here adds the + // allocation result. The second pod then only adds itself to reservedFor. + patch := fmt.Sprintf(`{"metadata": {"uid": %q}, "status": {%s "reservedFor": [ {"resource": "pods", "name": %q, "uid": %q} ] }}`, + claim.UID, + allocationPatch, + pod.Name, + pod.UID, + ) + if loggerV := logger.V(6); loggerV.Enabled() { + logger.V(5).Info("reserve", "pod", klog.KObj(pod), "node", klog.ObjectRef{Name: nodeName}, "resourceclaim", klog.KObj(claim), "patch", patch) + } else { + logger.V(5).Info("reserve", "pod", klog.KObj(pod), "node", klog.ObjectRef{Name: nodeName}, "resourceclaim", klog.KObj(claim)) + } + claim, err := pl.clientset.ResourceV1alpha2().ResourceClaims(claim.Namespace).Patch(ctx, claim.Name, types.StrategicMergePatchType, []byte(patch), metav1.PatchOptions{}, "status") + logger.V(5).Info("reserved", "pod", klog.KObj(pod), "node", klog.ObjectRef{Name: nodeName}, "resourceclaim", klog.Format(claim), "err", err) + if allocationPatch != "" { + // The scheduler was handling allocation. Now that has + // completed, either successfully or with a failure. + if err != nil { + pl.claimAssumeCache.Restore(claim.Namespace + "/" + claim.Name) + } + pl.inFlightAllocations.Delete(claim.UID) + } + return claim, err +} + // PostBind is called after a pod is successfully bound to a node. Now we are // sure that a PodSchedulingContext object, if it exists, is definitely not going to // be needed anymore and can delete it. This is a one-shot thing, there won't diff --git a/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources_test.go b/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources_test.go index 4704f60a65b..070ece83920 100644 --- a/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources_test.go +++ b/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources_test.go @@ -309,8 +309,9 @@ func TestPlugin(t *testing.T) { }, }, "waiting-for-immediate-allocation": { - pod: podWithClaimName, - claims: []*resourcev1alpha2.ResourceClaim{pendingImmediateClaim}, + pod: podWithClaimName, + claims: []*resourcev1alpha2.ResourceClaim{pendingImmediateClaim}, + classes: []*resourcev1alpha2.ResourceClass{resourceClass}, want: want{ prefilter: result{ status: framework.NewStatus(framework.UnschedulableAndUnresolvable, `unallocated immediate resourceclaim`), @@ -812,7 +813,6 @@ func setup(t *testing.T, nodes []*v1.Node, claims []*resourcev1alpha2.ResourceCl tc.client = fake.NewSimpleClientset() reactor := createReactor(tc.client.Tracker()) tc.client.PrependReactor("*", "*", reactor) - tc.informerFactory = informers.NewSharedInformerFactory(tc.client, 0) opts := []runtime.Option{ diff --git a/pkg/scheduler/framework/plugins/dynamicresources/structuredparameters.go b/pkg/scheduler/framework/plugins/dynamicresources/structuredparameters.go new file mode 100644 index 00000000000..e8a5d0a4522 --- /dev/null +++ b/pkg/scheduler/framework/plugins/dynamicresources/structuredparameters.go @@ -0,0 +1,134 @@ +/* +Copyright 2024 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 dynamicresources + +import ( + "context" + "fmt" + + v1 "k8s.io/api/core/v1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" + "k8s.io/apimachinery/pkg/labels" + resourcev1alpha2listers "k8s.io/client-go/listers/resource/v1alpha2" + "k8s.io/klog/v2" + "k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding" +) + +// resources is a map "node name" -> "driver name" -> available and +// allocated resources per structured parameter model. +type resources map[string]map[string]resourceModels + +// resourceModels may have more than one entry because it is valid for a driver to +// use more than one structured parameter model. +type resourceModels struct { + // TODO: add some structured parameter model +} + +// newResourceModel parses the available information about resources. Objects +// with an unknown structured parameter model silently ignored. An error gets +// logged later when parameters required for a pod depend on such an unknown +// model. +func newResourceModel(logger klog.Logger, nodeResourceSliceLister resourcev1alpha2listers.NodeResourceSliceLister, claimAssumeCache volumebinding.AssumeCache) (resources, error) { + model := make(resources) + + slices, err := nodeResourceSliceLister.List(labels.Everything()) + if err != nil { + return nil, fmt.Errorf("list node resource slices: %w", err) + } + for _, slice := range slices { + if model[slice.NodeName] == nil { + model[slice.NodeName] = make(map[string]resourceModels) + } + resource := model[slice.NodeName][slice.DriverName] + // TODO: add some structured parameter model + model[slice.NodeName][slice.DriverName] = resource + } + + objs := claimAssumeCache.List(nil) + for _, obj := range objs { + claim, ok := obj.(*resourcev1alpha2.ResourceClaim) + if !ok { + return nil, fmt.Errorf("got unexpected object of type %T from claim assume cache", obj) + } + if claim.Status.Allocation == nil { + continue + } + for _, handle := range claim.Status.Allocation.ResourceHandles { + structured := handle.StructuredData + if structured == nil { + continue + } + if model[structured.NodeName] == nil { + model[structured.NodeName] = make(map[string]resourceModels) + } + // resource := model[structured.NodeName][handle.DriverName] + // TODO: add some structured parameter model + // for _, result := range structured.Results { + // // Call AddAllocation for each known model. Each call itself needs to check for nil. + // } + } + } + + return model, nil +} + +func newClaimController(logger klog.Logger, class *resourcev1alpha2.ResourceClass, classParameters *resourcev1alpha2.ResourceClassParameters, claimParameters *resourcev1alpha2.ResourceClaimParameters) (*claimController, error) { + // Each node driver is separate from the others. Each driver may have + // multiple requests which need to be allocated together, so here + // we have to collect them per model. + // TODO: implement some structured parameters model + + c := &claimController{ + class: class, + classParameters: classParameters, + claimParameters: claimParameters, + } + return c, nil +} + +// claimController currently wraps exactly one structured parameter model. + +type claimController struct { + class *resourcev1alpha2.ResourceClass + classParameters *resourcev1alpha2.ResourceClassParameters + claimParameters *resourcev1alpha2.ResourceClaimParameters + // TODO: implement some structured parameters model +} + +func (c claimController) nodeIsSuitable(ctx context.Context, nodeName string, resources resources) (bool, error) { + // TODO: implement some structured parameters model + return true, nil +} + +func (c claimController) allocate(ctx context.Context, nodeName string, resources resources) (string, *resourcev1alpha2.AllocationResult, error) { + allocation := &resourcev1alpha2.AllocationResult{ + Shareable: c.claimParameters.Shareable, + AvailableOnNodes: &v1.NodeSelector{ + NodeSelectorTerms: []v1.NodeSelectorTerm{ + { + MatchExpressions: []v1.NodeSelectorRequirement{ + {Key: "kubernetes.io/hostname", Operator: v1.NodeSelectorOpIn, Values: []string{nodeName}}, + }, + }, + }, + }, + } + + // TODO: implement some structured parameters model + + return c.class.DriverName, allocation, nil +} diff --git a/pkg/scheduler/framework/types.go b/pkg/scheduler/framework/types.go index cc839b3e3ee..8bd4b86f680 100644 --- a/pkg/scheduler/framework/types.go +++ b/pkg/scheduler/framework/types.go @@ -72,17 +72,19 @@ const ( // - a Pod that is deleted // - a Pod that was assumed, but gets un-assumed due to some errors in the binding cycle. // - an existing Pod that was unscheduled but gets scheduled to a Node. - Pod GVK = "Pod" - Node GVK = "Node" - PersistentVolume GVK = "PersistentVolume" - PersistentVolumeClaim GVK = "PersistentVolumeClaim" - CSINode GVK = "storage.k8s.io/CSINode" - CSIDriver GVK = "storage.k8s.io/CSIDriver" - CSIStorageCapacity GVK = "storage.k8s.io/CSIStorageCapacity" - StorageClass GVK = "storage.k8s.io/StorageClass" - PodSchedulingContext GVK = "PodSchedulingContext" - ResourceClaim GVK = "ResourceClaim" - ResourceClass GVK = "ResourceClass" + Pod GVK = "Pod" + Node GVK = "Node" + PersistentVolume GVK = "PersistentVolume" + PersistentVolumeClaim GVK = "PersistentVolumeClaim" + CSINode GVK = "storage.k8s.io/CSINode" + CSIDriver GVK = "storage.k8s.io/CSIDriver" + CSIStorageCapacity GVK = "storage.k8s.io/CSIStorageCapacity" + StorageClass GVK = "storage.k8s.io/StorageClass" + PodSchedulingContext GVK = "PodSchedulingContext" + ResourceClaim GVK = "ResourceClaim" + ResourceClass GVK = "ResourceClass" + ResourceClaimParameters GVK = "ResourceClaimParameters" + ResourceClassParameters GVK = "ResourceClassParameters" // WildCard is a special GVK to match all resources. // e.g., If you register `{Resource: "*", ActionType: All}` in EventsToRegister, @@ -176,6 +178,8 @@ func UnrollWildCardResource() []ClusterEventWithHint { {Event: ClusterEvent{Resource: PodSchedulingContext, ActionType: All}}, {Event: ClusterEvent{Resource: ResourceClaim, ActionType: All}}, {Event: ClusterEvent{Resource: ResourceClass, ActionType: All}}, + {Event: ClusterEvent{Resource: ResourceClaimParameters, ActionType: All}}, + {Event: ClusterEvent{Resource: ResourceClassParameters, ActionType: All}}, } } diff --git a/pkg/scheduler/scheduler_test.go b/pkg/scheduler/scheduler_test.go index 6297e439884..3ebe9c7600a 100644 --- a/pkg/scheduler/scheduler_test.go +++ b/pkg/scheduler/scheduler_test.go @@ -644,6 +644,12 @@ func Test_buildQueueingHintMap(t *testing.T) { {Resource: framework.ResourceClass, ActionType: framework.All}: { {PluginName: filterWithoutEnqueueExtensions, QueueingHintFn: defaultQueueingHintFn}, }, + {Resource: framework.ResourceClaimParameters, ActionType: framework.All}: { + {PluginName: filterWithoutEnqueueExtensions, QueueingHintFn: defaultQueueingHintFn}, + }, + {Resource: framework.ResourceClassParameters, ActionType: framework.All}: { + {PluginName: filterWithoutEnqueueExtensions, QueueingHintFn: defaultQueueingHintFn}, + }, }, }, { @@ -768,17 +774,19 @@ func Test_UnionedGVKs(t *testing.T) { Disabled: []schedulerapi.Plugin{{Name: "*"}}, // disable default plugins }, want: map[framework.GVK]framework.ActionType{ - framework.Pod: framework.All, - framework.Node: framework.All, - framework.CSINode: framework.All, - framework.CSIDriver: framework.All, - framework.CSIStorageCapacity: framework.All, - framework.PersistentVolume: framework.All, - framework.PersistentVolumeClaim: framework.All, - framework.StorageClass: framework.All, - framework.PodSchedulingContext: framework.All, - framework.ResourceClaim: framework.All, - framework.ResourceClass: framework.All, + framework.Pod: framework.All, + framework.Node: framework.All, + framework.CSINode: framework.All, + framework.CSIDriver: framework.All, + framework.CSIStorageCapacity: framework.All, + framework.PersistentVolume: framework.All, + framework.PersistentVolumeClaim: framework.All, + framework.StorageClass: framework.All, + framework.PodSchedulingContext: framework.All, + framework.ResourceClaim: framework.All, + framework.ResourceClass: framework.All, + framework.ResourceClaimParameters: framework.All, + framework.ResourceClassParameters: framework.All, }, }, { diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go index 496d3d80b10..58ac1a15712 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go @@ -576,11 +576,13 @@ func ClusterRoles() []rbacv1.ClusterRole { // Needed for dynamic resource allocation. if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) { kubeSchedulerRules = append(kubeSchedulerRules, - rbacv1helpers.NewRule(Read...).Groups(resourceGroup).Resources("resourceclaims", "resourceclasses").RuleOrDie(), + rbacv1helpers.NewRule(Read...).Groups(resourceGroup).Resources("resourceclasses").RuleOrDie(), + rbacv1helpers.NewRule(ReadUpdate...).Groups(resourceGroup).Resources("resourceclaims").RuleOrDie(), rbacv1helpers.NewRule(ReadUpdate...).Groups(resourceGroup).Resources("resourceclaims/status").RuleOrDie(), rbacv1helpers.NewRule(ReadWrite...).Groups(resourceGroup).Resources("podschedulingcontexts").RuleOrDie(), rbacv1helpers.NewRule(Read...).Groups(resourceGroup).Resources("podschedulingcontexts/status").RuleOrDie(), rbacv1helpers.NewRule(ReadUpdate...).Groups(legacyGroup).Resources("pods/finalizers").RuleOrDie(), + rbacv1helpers.NewRule(Read...).Groups(resourceGroup).Resources("noderesourceslices", "resourceclassparameters", "resourceclaimparameters").RuleOrDie(), ) } roles = append(roles, rbacv1.ClusterRole{ diff --git a/staging/src/k8s.io/dynamic-resource-allocation/resourceclaim/resourceclaim.go b/staging/src/k8s.io/dynamic-resource-allocation/resourceclaim/resourceclaim.go index e3b8b35ac6b..5c1042329be 100644 --- a/staging/src/k8s.io/dynamic-resource-allocation/resourceclaim/resourceclaim.go +++ b/staging/src/k8s.io/dynamic-resource-allocation/resourceclaim/resourceclaim.go @@ -183,3 +183,17 @@ func CanBeReserved(claim *resourcev1alpha2.ResourceClaim) bool { return claim.Status.Allocation.Shareable || len(claim.Status.ReservedFor) == 0 } + +// IsAllocatedWithStructuredParameters checks whether the claim is allocated +// and the allocation was done with structured parameters. +func IsAllocatedWithStructuredParameters(claim *resourcev1alpha2.ResourceClaim) bool { + if claim.Status.Allocation == nil { + return false + } + for _, handle := range claim.Status.Allocation.ResourceHandles { + if handle.StructuredData != nil { + return true + } + } + return false +} From d4d5ade7f5be047472f8d9572c7f01f142951a2d Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Fri, 23 Feb 2024 15:22:02 +0100 Subject: [PATCH 06/18] dra: add "named resources" structured parameter model Like the current device plugin interface, a DRA driver using this model announces a list of resource instances. In contrast to device plugins, this list is made available to the scheduler together with attributes that can be used to select suitable instances when they are not all alike. Because this is the first structured parameter model, some checks that previously were not possible, in particular "is one structured parameter field set", now gets enabled. Adding another structured parameter model will be similar. The applyconfigs code generator assumes that all types in an API are defined in a single package. If it wasn't for that, it would be possible to place the "named resources" types in separate packages, which makes their names in the Go code more natural and provides an indication of their stability level because the package name could include a version. --- api/api-rules/violation_exceptions.list | 6 + api/openapi-spec/swagger.json | 166 ++ ...is__resource.k8s.io__v1alpha2_openapi.json | 222 ++ pkg/apis/resource/namedresources.go | 114 + .../namedresources/validation/validation.go | 157 ++ .../validation/validation_test.go | 149 ++ pkg/apis/resource/types.go | 12 +- .../v1alpha2/zz_generated.conversion.go | 297 ++ pkg/apis/resource/validation/validation.go | 29 +- .../validation_noderesourceslice_test.go | 23 +- .../validation_resourceclaim_test.go | 12 +- ...validation_resourceclaimparameters_test.go | 26 +- ...validation_resourceclassparameters_test.go | 35 +- pkg/apis/resource/zz_generated.deepcopy.go | 231 +- pkg/generated/openapi/zz_generated.openapi.go | 410 ++- .../noderesourceslice/storage/storage_test.go | 3 + .../noderesourceslice/strategy_test.go | 3 + .../storage/storage_test.go | 22 +- .../namedresources/namedresourcesmodel.go | 150 ++ .../dynamicresources/structuredparameters.go | 123 +- staging/publishing/import-restrictions.yaml | 3 + staging/publishing/rules.yaml | 2 + .../api/resource/v1alpha2/generated.pb.go | 2382 ++++++++++++++++- .../api/resource/v1alpha2/generated.proto | 122 + .../api/resource/v1alpha2/namedresources.go | 137 + .../src/k8s.io/api/resource/v1alpha2/types.go | 20 +- .../v1alpha2/types_swagger_doc_generated.go | 12 +- .../v1alpha2/zz_generated.deepcopy.go | 231 +- ...rce.k8s.io.v1alpha2.NodeResourceSlice.json | 28 +- ...ource.k8s.io.v1alpha2.NodeResourceSlice.pb | Bin 447 -> 519 bytes ...rce.k8s.io.v1alpha2.NodeResourceSlice.yaml | 15 + ...esource.k8s.io.v1alpha2.ResourceClaim.json | 3 + .../resource.k8s.io.v1alpha2.ResourceClaim.pb | Bin 1018 -> 1031 bytes ...esource.k8s.io.v1alpha2.ResourceClaim.yaml | 4 +- ...s.io.v1alpha2.ResourceClaimParameters.json | 3 + ...k8s.io.v1alpha2.ResourceClaimParameters.pb | Bin 688 -> 705 bytes ...s.io.v1alpha2.ResourceClaimParameters.yaml | 4 +- ...s.io.v1alpha2.ResourceClassParameters.json | 5 +- ...k8s.io.v1alpha2.ResourceClassParameters.pb | Bin 616 -> 633 bytes ...s.io.v1alpha2.ResourceClassParameters.yaml | 2 + ....v1alpha2.ResourceClass.after_roundtrip.pb | Bin 565 -> 0 bytes ....v1alpha2.ResourceClass.after_roundtrip.pb | Bin 565 -> 0 bytes .../applyconfigurations/internal/internal.go | 98 + .../v1alpha2/allocationresultmodel.go | 39 + .../v1alpha2/driverallocationresult.go | 13 +- .../namedresourcesallocationresult.go | 39 + .../v1alpha2/namedresourcesattribute.go | 92 + .../v1alpha2/namedresourcesattributevalue.go | 88 + .../resource/v1alpha2/namedresourcesfilter.go | 39 + .../v1alpha2/namedresourcesinstance.go | 53 + .../v1alpha2/namedresourcesintslice.go | 41 + .../v1alpha2/namedresourcesrequest.go | 39 + .../v1alpha2/namedresourcesresources.go | 44 + .../v1alpha2/namedresourcesstringslice.go | 41 + .../resource/v1alpha2/noderesourcemodel.go | 39 + .../resource/v1alpha2/noderesourceslice.go | 26 +- .../resource/v1alpha2/resourcefilter.go | 16 +- .../resource/v1alpha2/resourcefiltermodel.go | 39 + .../resource/v1alpha2/resourcerequest.go | 13 +- .../resource/v1alpha2/resourcerequestmodel.go | 39 + .../client-go/applyconfigurations/utils.go | 26 + .../k8s.io/dynamic-resource-allocation/go.mod | 8 + .../k8s.io/dynamic-resource-allocation/go.sum | 59 +- .../structured/namedresources/cel/compile.go | 206 ++ .../namedresources/cel/compile_test.go | 155 ++ test/integration/etcd/data.go | 2 +- 66 files changed, 6143 insertions(+), 274 deletions(-) create mode 100644 pkg/apis/resource/namedresources.go create mode 100644 pkg/apis/resource/structured/namedresources/validation/validation.go create mode 100644 pkg/apis/resource/structured/namedresources/validation/validation_test.go create mode 100644 pkg/scheduler/framework/plugins/dynamicresources/structured/namedresources/namedresourcesmodel.go create mode 100644 staging/src/k8s.io/api/resource/v1alpha2/namedresources.go delete mode 100644 staging/src/k8s.io/api/testdata/v1.28.0/resource.k8s.io.v1alpha2.ResourceClass.after_roundtrip.pb delete mode 100644 staging/src/k8s.io/api/testdata/v1.29.0/resource.k8s.io.v1alpha2.ResourceClass.after_roundtrip.pb create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/allocationresultmodel.go create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesallocationresult.go create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesattribute.go create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesattributevalue.go create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesfilter.go create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesinstance.go create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesintslice.go create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesrequest.go create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesresources.go create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesstringslice.go create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/noderesourcemodel.go create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcefiltermodel.go create mode 100644 staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcerequestmodel.go create mode 100644 staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/compile.go create mode 100644 staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/compile_test.go diff --git a/api/api-rules/violation_exceptions.list b/api/api-rules/violation_exceptions.list index a3a2cf750bf..ad6ea5d5ff7 100644 --- a/api/api-rules/violation_exceptions.list +++ b/api/api-rules/violation_exceptions.list @@ -51,6 +51,12 @@ API rule violation: names_match,k8s.io/api/core/v1,RBDVolumeSource,RadosUser API rule violation: names_match,k8s.io/api/core/v1,VolumeSource,CephFS API rule violation: names_match,k8s.io/api/core/v1,VolumeSource,StorageOS API rule violation: names_match,k8s.io/api/networking/v1alpha1,ServiceCIDRSpec,CIDRs +API rule violation: names_match,k8s.io/api/resource/v1alpha2,NamedResourcesAttributeValue,BoolValue +API rule violation: names_match,k8s.io/api/resource/v1alpha2,NamedResourcesAttributeValue,IntSliceValue +API rule violation: names_match,k8s.io/api/resource/v1alpha2,NamedResourcesAttributeValue,IntValue +API rule violation: names_match,k8s.io/api/resource/v1alpha2,NamedResourcesAttributeValue,QuantityValue +API rule violation: names_match,k8s.io/api/resource/v1alpha2,NamedResourcesAttributeValue,StringSliceValue +API rule violation: names_match,k8s.io/api/resource/v1alpha2,NamedResourcesAttributeValue,StringValue API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,Ref API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,Schema API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,XEmbeddedResource diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index acf7b480b1f..98b12379620 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -14823,6 +14823,10 @@ "io.k8s.api.resource.v1alpha2.DriverAllocationResult": { "description": "DriverAllocationResult contains vendor parameters and the allocation result for one request.", "properties": { + "namedResources": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NamedResourcesAllocationResult", + "description": "NamedResources describes the allocation result when using the named resources model." + }, "vendorRequestParameters": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.runtime.RawExtension", "description": "VendorRequestParameters are the per-request configuration parameters from the time that the claim was allocated." @@ -14852,6 +14856,156 @@ }, "type": "object" }, + "io.k8s.api.resource.v1alpha2.NamedResourcesAllocationResult": { + "description": "NamedResourcesAllocationResult is used in AllocationResultModel.", + "properties": { + "name": { + "description": "Name is the name of the selected resource instance.", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.NamedResourcesAttribute": { + "description": "NamedResourcesAttribute is a combination of an attribute name and its value.", + "properties": { + "bool": { + "description": "BoolValue is a true/false value.", + "type": "boolean" + }, + "int": { + "description": "IntValue is a 64-bit integer.", + "format": "int64", + "type": "integer" + }, + "intSlice": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NamedResourcesIntSlice", + "description": "IntSliceValue is an array of 64-bit integers." + }, + "name": { + "description": "Name is unique identifier among all resource instances managed by the driver on the node. It must be a DNS subdomain.", + "type": "string" + }, + "quantity": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.api.resource.Quantity", + "description": "QuantityValue is a quantity." + }, + "string": { + "description": "StringValue is a string.", + "type": "string" + }, + "stringSlice": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NamedResourcesStringSlice", + "description": "StringSliceValue is an array of strings." + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.NamedResourcesFilter": { + "description": "NamedResourcesFilter is used in ResourceFilterModel.", + "properties": { + "selector": { + "description": "Selector is a CEL expression which must evaluate to true if a resource instance is suitable. The language is as defined in https://kubernetes.io/docs/reference/using-api/cel/\n\nIn addition, for each type NamedResourcesin AttributeValue there is a map that resolves to the corresponding value of the instance under evaluation. For example:\n\n attributes.quantity[\"a\"].isGreaterThan(quantity(\"0\")) &&\n attributes.stringslice[\"b\"].isSorted()", + "type": "string" + } + }, + "required": [ + "selector" + ], + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.NamedResourcesInstance": { + "description": "NamedResourcesInstance represents one individual hardware instance that can be selected based on its attributes.", + "properties": { + "attributes": { + "description": "Attributes defines the attributes of this resource instance. The name of each attribute must be unique.", + "items": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NamedResourcesAttribute" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "name": { + "description": "Name is unique identifier among all resource instances managed by the driver on the node. It must be a DNS subdomain.", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.NamedResourcesIntSlice": { + "description": "NamedResourcesIntSlice contains a slice of 64-bit integers.", + "properties": { + "ints": { + "description": "Ints is the slice of 64-bit integers.", + "items": { + "format": "int64", + "type": "integer" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + } + }, + "required": [ + "ints" + ], + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.NamedResourcesRequest": { + "description": "NamedResourcesRequest is used in ResourceRequestModel.", + "properties": { + "selector": { + "description": "Selector is a CEL expression which must evaluate to true if a resource instance is suitable. The language is as defined in https://kubernetes.io/docs/reference/using-api/cel/\n\nIn addition, for each type NamedResourcesin AttributeValue there is a map that resolves to the corresponding value of the instance under evaluation. For example:\n\n attributes.quantity[\"a\"].isGreaterThan(quantity(\"0\")) &&\n attributes.stringslice[\"b\"].isSorted()", + "type": "string" + } + }, + "required": [ + "selector" + ], + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.NamedResourcesResources": { + "description": "NamedResourcesResources is used in NodeResourceModel.", + "properties": { + "instances": { + "description": "The list of all individual resources instances currently available.", + "items": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NamedResourcesInstance" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + } + }, + "required": [ + "instances" + ], + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.NamedResourcesStringSlice": { + "description": "NamedResourcesStringSlice contains a slice of strings.", + "properties": { + "strings": { + "description": "Strings is the slice of strings.", + "items": { + "type": "string" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + } + }, + "required": [ + "strings" + ], + "type": "object" + }, "io.k8s.api.resource.v1alpha2.NodeResourceSlice": { "description": "NodeResourceSlice provides information about available resources on individual nodes.", "properties": { @@ -14871,6 +15025,10 @@ "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta", "description": "Standard object metadata" }, + "namedResources": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NamedResourcesResources", + "description": "NamedResources describes available resources using the named resources model." + }, "nodeName": { "description": "NodeName identifies the node where the capacity is available. A field selector can be used to list only NodeResourceSlice objects with a certain node name.", "type": "string" @@ -15571,6 +15729,10 @@ "driverName": { "description": "DriverName is the name used by the DRA driver kubelet plugin.", "type": "string" + }, + "namedResources": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NamedResourcesFilter", + "description": "NamedResources describes a resource filter using the named resources model." } }, "type": "object" @@ -15596,6 +15758,10 @@ "io.k8s.api.resource.v1alpha2.ResourceRequest": { "description": "ResourceRequest is a request for resources from one particular driver.", "properties": { + "namedResources": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NamedResourcesRequest", + "description": "NamedResources describes a request for resources with the named resources model." + }, "vendorParameters": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.runtime.RawExtension", "description": "VendorParameters are arbitrary setup parameters for the requested resource. They are ignored while allocating a claim." diff --git a/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha2_openapi.json b/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha2_openapi.json index 63fd58bc24a..eb9fed5e5d1 100644 --- a/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha2_openapi.json +++ b/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha2_openapi.json @@ -120,6 +120,14 @@ "io.k8s.api.resource.v1alpha2.DriverAllocationResult": { "description": "DriverAllocationResult contains vendor parameters and the allocation result for one request.", "properties": { + "namedResources": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NamedResourcesAllocationResult" + } + ], + "description": "NamedResources describes the allocation result when using the named resources model." + }, "vendorRequestParameters": { "allOf": [ { @@ -162,6 +170,185 @@ }, "type": "object" }, + "io.k8s.api.resource.v1alpha2.NamedResourcesAllocationResult": { + "description": "NamedResourcesAllocationResult is used in AllocationResultModel.", + "properties": { + "name": { + "default": "", + "description": "Name is the name of the selected resource instance.", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.NamedResourcesAttribute": { + "description": "NamedResourcesAttribute is a combination of an attribute name and its value.", + "properties": { + "bool": { + "description": "BoolValue is a true/false value.", + "type": "boolean" + }, + "int": { + "description": "IntValue is a 64-bit integer.", + "format": "int64", + "type": "integer" + }, + "intSlice": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NamedResourcesIntSlice" + } + ], + "description": "IntSliceValue is an array of 64-bit integers." + }, + "name": { + "default": "", + "description": "Name is unique identifier among all resource instances managed by the driver on the node. It must be a DNS subdomain.", + "type": "string" + }, + "quantity": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.api.resource.Quantity" + } + ], + "description": "QuantityValue is a quantity." + }, + "string": { + "description": "StringValue is a string.", + "type": "string" + }, + "stringSlice": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NamedResourcesStringSlice" + } + ], + "description": "StringSliceValue is an array of strings." + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.NamedResourcesFilter": { + "description": "NamedResourcesFilter is used in ResourceFilterModel.", + "properties": { + "selector": { + "default": "", + "description": "Selector is a CEL expression which must evaluate to true if a resource instance is suitable. The language is as defined in https://kubernetes.io/docs/reference/using-api/cel/\n\nIn addition, for each type NamedResourcesin AttributeValue there is a map that resolves to the corresponding value of the instance under evaluation. For example:\n\n attributes.quantity[\"a\"].isGreaterThan(quantity(\"0\")) &&\n attributes.stringslice[\"b\"].isSorted()", + "type": "string" + } + }, + "required": [ + "selector" + ], + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.NamedResourcesInstance": { + "description": "NamedResourcesInstance represents one individual hardware instance that can be selected based on its attributes.", + "properties": { + "attributes": { + "description": "Attributes defines the attributes of this resource instance. The name of each attribute must be unique.", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NamedResourcesAttribute" + } + ], + "default": {} + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "name": { + "default": "", + "description": "Name is unique identifier among all resource instances managed by the driver on the node. It must be a DNS subdomain.", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.NamedResourcesIntSlice": { + "description": "NamedResourcesIntSlice contains a slice of 64-bit integers.", + "properties": { + "ints": { + "description": "Ints is the slice of 64-bit integers.", + "items": { + "default": 0, + "format": "int64", + "type": "integer" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + } + }, + "required": [ + "ints" + ], + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.NamedResourcesRequest": { + "description": "NamedResourcesRequest is used in ResourceRequestModel.", + "properties": { + "selector": { + "default": "", + "description": "Selector is a CEL expression which must evaluate to true if a resource instance is suitable. The language is as defined in https://kubernetes.io/docs/reference/using-api/cel/\n\nIn addition, for each type NamedResourcesin AttributeValue there is a map that resolves to the corresponding value of the instance under evaluation. For example:\n\n attributes.quantity[\"a\"].isGreaterThan(quantity(\"0\")) &&\n attributes.stringslice[\"b\"].isSorted()", + "type": "string" + } + }, + "required": [ + "selector" + ], + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.NamedResourcesResources": { + "description": "NamedResourcesResources is used in NodeResourceModel.", + "properties": { + "instances": { + "description": "The list of all individual resources instances currently available.", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NamedResourcesInstance" + } + ], + "default": {} + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + } + }, + "required": [ + "instances" + ], + "type": "object" + }, + "io.k8s.api.resource.v1alpha2.NamedResourcesStringSlice": { + "description": "NamedResourcesStringSlice contains a slice of strings.", + "properties": { + "strings": { + "description": "Strings is the slice of strings.", + "items": { + "default": "", + "type": "string" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + } + }, + "required": [ + "strings" + ], + "type": "object" + }, "io.k8s.api.resource.v1alpha2.NodeResourceSlice": { "description": "NodeResourceSlice provides information about available resources on individual nodes.", "properties": { @@ -187,6 +374,14 @@ "default": {}, "description": "Standard object metadata" }, + "namedResources": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NamedResourcesResources" + } + ], + "description": "NamedResources describes available resources using the named resources model." + }, "nodeName": { "default": "", "description": "NodeName identifies the node where the capacity is available. A field selector can be used to list only NodeResourceSlice objects with a certain node name.", @@ -1083,6 +1278,14 @@ "driverName": { "description": "DriverName is the name used by the DRA driver kubelet plugin.", "type": "string" + }, + "namedResources": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NamedResourcesFilter" + } + ], + "description": "NamedResources describes a resource filter using the named resources model." } }, "type": "object" @@ -1112,6 +1315,14 @@ "io.k8s.api.resource.v1alpha2.ResourceRequest": { "description": "ResourceRequest is a request for resources from one particular driver.", "properties": { + "namedResources": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NamedResourcesRequest" + } + ], + "description": "NamedResources describes a request for resources with the named resources model." + }, "vendorParameters": { "allOf": [ { @@ -1185,6 +1396,17 @@ }, "type": "object" }, + "io.k8s.apimachinery.pkg.api.resource.Quantity": { + "description": "Quantity is a fixed-point representation of a number. It provides convenient marshaling/unmarshaling in JSON and YAML, in addition to String() and AsInt64() accessors.\n\nThe serialization format is:\n\n``` ::= \n\n\t(Note that may be empty, from the \"\" case in .)\n\n ::= 0 | 1 | ... | 9 ::= | ::= | . | . | . ::= \"+\" | \"-\" ::= | ::= | | ::= Ki | Mi | Gi | Ti | Pi | Ei\n\n\t(International System of units; See: http://physics.nist.gov/cuu/Units/binary.html)\n\n ::= m | \"\" | k | M | G | T | P | E\n\n\t(Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.)\n\n ::= \"e\" | \"E\" ```\n\nNo matter which of the three exponent forms is used, no quantity may represent a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal places. Numbers larger or more precise will be capped or rounded up. (E.g.: 0.1m will rounded up to 1m.) This may be extended in the future if we require larger or smaller quantities.\n\nWhen a Quantity is parsed from a string, it will remember the type of suffix it had, and will use the same type again when it is serialized.\n\nBefore serializing, Quantity will be put in \"canonical form\". This means that Exponent/suffix will be adjusted up or down (with a corresponding increase or decrease in Mantissa) such that:\n\n- No precision is lost - No fractional digits will be emitted - The exponent (or suffix) is as large as possible.\n\nThe sign will be omitted unless the number is negative.\n\nExamples:\n\n- 1.5 will be serialized as \"1500m\" - 1.5Gi will be serialized as \"1536Mi\"\n\nNote that the quantity will NEVER be internally represented by a floating point number. That is the whole point of this exercise.\n\nNon-canonical values will still parse as long as they are well formed, but will be re-emitted in their canonical form. (So always use canonical form, or don't diff.)\n\nThis format is intended to make it difficult to use these numbers without writing some sort of special handling code in the hopes that that will cause implementors to also use a fixed point implementation.", + "oneOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, "io.k8s.apimachinery.pkg.apis.meta.v1.APIResource": { "description": "APIResource specifies the name of a resource and whether it is namespaced.", "properties": { diff --git a/pkg/apis/resource/namedresources.go b/pkg/apis/resource/namedresources.go new file mode 100644 index 00000000000..e64d2796a0e --- /dev/null +++ b/pkg/apis/resource/namedresources.go @@ -0,0 +1,114 @@ +/* +Copyright 2024 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 resource + +import "k8s.io/apimachinery/pkg/api/resource" + +// NamedResourcesResources is used in NodeResourceModel. +type NamedResourcesResources struct { + // The list of all individual resources instances currently available. + Instances []NamedResourcesInstance +} + +// NamedResourcesInstance represents one individual hardware instance that can be selected based +// on its attributes. +type NamedResourcesInstance struct { + // Name is unique identifier among all resource instances managed by + // the driver on the node. It must be a DNS subdomain. + Name string + + // Attributes defines the attributes of this resource instance. + // The name of each attribute must be unique. + Attributes []NamedResourcesAttribute +} + +// NamedResourcesAttribute is a combination of an attribute name and its value. +type NamedResourcesAttribute struct { + // Name is unique identifier among all resource instances managed by + // the driver on the node. It must be a DNS subdomain. + Name string + + NamedResourcesAttributeValue +} + +// NamedResourcesAttributeValue must have one and only one field set. +type NamedResourcesAttributeValue struct { + // QuantityValue is a quantity. + QuantityValue *resource.Quantity + // BoolValue is a true/false value. + BoolValue *bool + // IntValue is a 64-bit integer. + IntValue *int64 + // IntSliceValue is an array of 64-bit integers. + IntSliceValue *NamedResourcesIntSlice + // StringValue is a string. + StringValue *string + // StringSliceValue is an array of strings. + StringSliceValue *NamedResourcesStringSlice + // TODO: VersionValue *SemVersion +} + +// NamedResourcesIntSlice contains a slice of 64-bit integers. +type NamedResourcesIntSlice struct { + // Ints is the slice of 64-bit integers. + Ints []int64 +} + +// NamedResourcesStringSlice contains a slice of strings. +type NamedResourcesStringSlice struct { + // Strings is the slice of strings. + Strings []string +} + +// TODO +// +// A wrapper around https://pkg.go.dev/github.com/blang/semver/v4#Version which +// is encoded as a string. During decoding, it validates that the string +// can be parsed using tolerant parsing (currently trims spaces, removes a "v" prefix, +// adds a 0 patch number to versions with only major and minor components specified, +// and removes leading 0s). +// type SemVersion struct { +// semver.Version +//} + +// NamedResourcesRequest is used in ResourceRequestModel. +type NamedResourcesRequest struct { + // Selector is a CEL expression which must evaluate to true if a + // resource instance is suitable. The language is as defined in + // https://kubernetes.io/docs/reference/using-api/cel/ + // + // In addition, for each type NamedResourcesin AttributeValue there is a map that + // resolves to the corresponding value of the instance under evaluation. + // For example: + // + // attributes.quantity["a"].isGreaterThan(quantity("0")) && + // attributes.stringslice["b"].isSorted() + Selector string +} + +// NamedResourcesFilter is used in ResourceFilterModel. +type NamedResourcesFilter struct { + // Selector is a selector like the one in Request. It must be true for + // a resource instance to be suitable for a claim using the class. + Selector string +} + +// NamedResourcesAllocationResult is used in AllocationResultModel. +type NamedResourcesAllocationResult struct { + // Name is the name of the selected resource instance. + Name string +} diff --git a/pkg/apis/resource/structured/namedresources/validation/validation.go b/pkg/apis/resource/structured/namedresources/validation/validation.go new file mode 100644 index 00000000000..a9f703753e8 --- /dev/null +++ b/pkg/apis/resource/structured/namedresources/validation/validation.go @@ -0,0 +1,157 @@ +/* +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 validation + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/apiserver/pkg/cel" + "k8s.io/apiserver/pkg/cel/environment" + namedresourcescel "k8s.io/dynamic-resource-allocation/structured/namedresources/cel" + corevalidation "k8s.io/kubernetes/pkg/apis/core/validation" + "k8s.io/kubernetes/pkg/apis/resource" +) + +var ( + validateInstanceName = corevalidation.ValidateDNS1123Subdomain + validateAttributeName = corevalidation.ValidateDNS1123Subdomain +) + +type Options struct { + // StoredExpressions must be true if and only if validating CEL + // expressions that were already stored persistently. This makes + // validation more permissive by enabling CEL definitions that are not + // valid yet for new expressions. + StoredExpressions bool +} + +func ValidateResources(resources *resource.NamedResourcesResources, fldPath *field.Path) field.ErrorList { + allErrs := validateInstances(resources.Instances, fldPath.Child("instances")) + return allErrs +} + +func validateInstances(instances []resource.NamedResourcesInstance, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + instanceNames := sets.New[string]() + for i, instance := range instances { + idxPath := fldPath.Index(i) + instanceName := instance.Name + allErrs = append(allErrs, validateInstanceName(instanceName, idxPath.Child("name"))...) + if instanceNames.Has(instanceName) { + allErrs = append(allErrs, field.Duplicate(idxPath.Child("name"), instanceName)) + } else { + instanceNames.Insert(instanceName) + } + allErrs = append(allErrs, validateAttributes(instance.Attributes, idxPath.Child("attributes"))...) + } + return allErrs +} + +func validateAttributes(attributes []resource.NamedResourcesAttribute, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + attributeNames := sets.New[string]() + for i, attribute := range attributes { + idxPath := fldPath.Index(i) + attributeName := attribute.Name + allErrs = append(allErrs, validateAttributeName(attributeName, idxPath.Child("name"))...) + if attributeNames.Has(attributeName) { + allErrs = append(allErrs, field.Duplicate(idxPath.Child("name"), attributeName)) + } else { + attributeNames.Insert(attributeName) + } + + entries := sets.New[string]() + if attribute.QuantityValue != nil { + entries.Insert("quantity") + } + if attribute.BoolValue != nil { + entries.Insert("bool") + } + if attribute.IntValue != nil { + entries.Insert("int") + } + if attribute.IntSliceValue != nil { + entries.Insert("intSlice") + } + if attribute.StringValue != nil { + entries.Insert("string") + } + if attribute.StringSliceValue != nil { + entries.Insert("stringSlice") + } + // TODO: VersionValue + + switch len(entries) { + case 0: + allErrs = append(allErrs, field.Required(idxPath, "exactly one value must be set")) + case 1: + // Okay. + default: + allErrs = append(allErrs, field.Invalid(idxPath, sets.List(entries), "exactly one field must be set, not several")) + } + } + return allErrs +} + +func ValidateRequest(opts Options, request *resource.NamedResourcesRequest, fldPath *field.Path) field.ErrorList { + return validateSelector(opts, request.Selector, fldPath.Child("selector")) +} + +func ValidateFilter(opts Options, filter *resource.NamedResourcesFilter, fldPath *field.Path) field.ErrorList { + return validateSelector(opts, filter.Selector, fldPath.Child("selector")) +} + +func validateSelector(opts Options, selector string, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + if selector == "" { + allErrs = append(allErrs, field.Required(fldPath, "")) + } else { + // TODO (https://github.com/kubernetes/kubernetes/issues/123687): + // when this API gets promoted to beta, we have to + // validate new and stored expressions differently. + // While it is alpha, new expressions are allowed to + // use everything that is currently available. + // envType := environment.NewExpressions + // if opts.StoredExpressions { + // envType = environment.StoredExpressions + // } + envType := environment.StoredExpressions + result := namedresourcescel.Compiler.CompileCELExpression(selector, envType) + if result.Error != nil { + allErrs = append(allErrs, convertCELErrorToValidationError(fldPath, selector, result.Error)) + } + } + return allErrs +} + +func convertCELErrorToValidationError(fldPath *field.Path, expression string, err *cel.Error) *field.Error { + switch err.Type { + case cel.ErrorTypeRequired: + return field.Required(fldPath, err.Detail) + case cel.ErrorTypeInvalid: + return field.Invalid(fldPath, expression, err.Detail) + case cel.ErrorTypeInternal: + return field.InternalError(fldPath, err) + } + return field.InternalError(fldPath, fmt.Errorf("unsupported error type: %w", err)) +} + +func ValidateAllocationResult(result *resource.NamedResourcesAllocationResult, fldPath *field.Path) field.ErrorList { + return validateInstanceName(result.Name, fldPath.Child("name")) +} diff --git a/pkg/apis/resource/structured/namedresources/validation/validation_test.go b/pkg/apis/resource/structured/namedresources/validation/validation_test.go new file mode 100644 index 00000000000..22f8f57196e --- /dev/null +++ b/pkg/apis/resource/structured/namedresources/validation/validation_test.go @@ -0,0 +1,149 @@ +/* +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 validation + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/util/validation/field" + resourceapi "k8s.io/kubernetes/pkg/apis/resource" + "k8s.io/utils/ptr" +) + +func testResources(instances []resourceapi.NamedResourcesInstance) *resourceapi.NamedResourcesResources { + resources := &resourceapi.NamedResourcesResources{ + Instances: instances, + } + return resources +} + +func TestValidateResources(t *testing.T) { + goodName := "foo" + badName := "!@#$%^" + quantity := resource.MustParse("1") + + scenarios := map[string]struct { + resources *resourceapi.NamedResourcesResources + wantFailures field.ErrorList + }{ + "empty": { + resources: testResources(nil), + }, + "good": { + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName}}), + }, + "bad-name": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("instances").Index(0).Child("name"), badName, "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')")}, + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: badName}}), + }, + "duplicate-name": { + wantFailures: field.ErrorList{field.Duplicate(field.NewPath("instances").Index(1).Child("name"), goodName)}, + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName}, {Name: goodName}}), + }, + "quantity": { + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{QuantityValue: &quantity}}}}}), + }, + "bool": { + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{BoolValue: ptr.To(true)}}}}}), + }, + "int": { + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{IntValue: ptr.To(int64(1))}}}}}), + }, + "int-slice": { + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{IntSliceValue: &resourceapi.NamedResourcesIntSlice{Ints: []int64{1, 2, 3}}}}}}}), + }, + "string": { + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{StringValue: ptr.To("hello")}}}}}), + }, + "string-slice": { + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{StringSliceValue: &resourceapi.NamedResourcesStringSlice{Strings: []string{"hello"}}}}}}}), + }, + // TODO: semver + "empty-attribute": { + wantFailures: field.ErrorList{field.Required(field.NewPath("instances").Index(0).Child("attributes").Index(0), "exactly one value must be set")}, + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName}}}}), + }, + "duplicate-value": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("instances").Index(0).Child("attributes").Index(0), []string{"bool", "int"}, "exactly one field must be set, not several")}, + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{BoolValue: ptr.To(true), IntValue: ptr.To(int64(1))}}}}}), + }, + } + + for name, scenario := range scenarios { + t.Run(name, func(t *testing.T) { + errs := ValidateResources(scenario.resources, nil) + assert.Equal(t, scenario.wantFailures, errs) + }) + } +} + +func TestValidateSelector(t *testing.T) { + scenarios := map[string]struct { + selector string + wantFailures field.ErrorList + }{ + "okay": { + selector: "true", + }, + "empty": { + selector: "", + wantFailures: field.ErrorList{field.Required(nil, "")}, + }, + "undefined": { + selector: "nosuchvar", + wantFailures: field.ErrorList{field.Invalid(nil, "nosuchvar", "compilation failed: ERROR: :1:1: undeclared reference to 'nosuchvar' (in container '')\n | nosuchvar\n | ^")}, + }, + "wrong-type": { + selector: "1", + wantFailures: field.ErrorList{field.Invalid(nil, "1", "must evaluate to bool")}, + }, + "quantity": { + selector: `attributes.quantity["name"].isGreaterThan(quantity("0"))`, + }, + "bool": { + selector: `attributes.bool["name"]`, + }, + "int": { + selector: `attributes.int["name"] > 0`, + }, + "intslice": { + selector: `attributes.intslice["name"].isSorted()`, + }, + "string": { + selector: `attributes.string["name"] == "fish"`, + }, + "stringslice": { + selector: `attributes.stringslice["name"].isSorted()`, + }, + // TODO: semver + } + + for name, scenario := range scenarios { + t.Run(name, func(t *testing.T) { + // At the moment, there's no difference between stored and new expressions. + // This uses the stricter validation. + opts := Options{ + StoredExpressions: false, + } + errs := validateSelector(opts, scenario.selector, nil) + assert.Equal(t, scenario.wantFailures, errs) + }) + } +} diff --git a/pkg/apis/resource/types.go b/pkg/apis/resource/types.go index 10ed93bc0a1..a667b0ab71e 100644 --- a/pkg/apis/resource/types.go +++ b/pkg/apis/resource/types.go @@ -224,7 +224,8 @@ type DriverAllocationResult struct { // AllocationResultModel must have one and only one field set. type AllocationResultModel struct { - // TODO: implement one structured parameter model + // NamedResources describes the allocation result when using the named resources model. + NamedResources *NamedResourcesAllocationResult } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -500,7 +501,8 @@ type NodeResourceSlice struct { // NodeResourceModel must have one and only one field set. type NodeResourceModel struct { - // TODO: implement one structured parameter model + // NamedResources describes available resources using the named resources model. + NamedResources *NamedResourcesResources } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -567,7 +569,8 @@ type ResourceRequest struct { // ResourceRequestModel must have one and only one field set. type ResourceRequestModel struct { - // TODO: implement one structured parameter model + // NamedResources describes a request for resources with the named resources model. + NamedResources *NamedResourcesRequest } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -616,7 +619,8 @@ type ResourceFilter struct { // ResourceFilterModel must have one and only one field set. type ResourceFilterModel struct { - // TODO: implement one structured parameter model + // NamedResources describes a resource filter using the named resources model. + NamedResources *NamedResourcesFilter } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/apis/resource/v1alpha2/zz_generated.conversion.go b/pkg/apis/resource/v1alpha2/zz_generated.conversion.go index 107da311342..0562983865a 100644 --- a/pkg/apis/resource/v1alpha2/zz_generated.conversion.go +++ b/pkg/apis/resource/v1alpha2/zz_generated.conversion.go @@ -26,6 +26,7 @@ import ( v1 "k8s.io/api/core/v1" v1alpha2 "k8s.io/api/resource/v1alpha2" + apiresource "k8s.io/apimachinery/pkg/api/resource" conversion "k8s.io/apimachinery/pkg/conversion" runtime "k8s.io/apimachinery/pkg/runtime" types "k8s.io/apimachinery/pkg/types" @@ -80,6 +81,96 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*v1alpha2.NamedResourcesAllocationResult)(nil), (*resource.NamedResourcesAllocationResult)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_NamedResourcesAllocationResult_To_resource_NamedResourcesAllocationResult(a.(*v1alpha2.NamedResourcesAllocationResult), b.(*resource.NamedResourcesAllocationResult), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.NamedResourcesAllocationResult)(nil), (*v1alpha2.NamedResourcesAllocationResult)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_NamedResourcesAllocationResult_To_v1alpha2_NamedResourcesAllocationResult(a.(*resource.NamedResourcesAllocationResult), b.(*v1alpha2.NamedResourcesAllocationResult), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.NamedResourcesAttribute)(nil), (*resource.NamedResourcesAttribute)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_NamedResourcesAttribute_To_resource_NamedResourcesAttribute(a.(*v1alpha2.NamedResourcesAttribute), b.(*resource.NamedResourcesAttribute), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.NamedResourcesAttribute)(nil), (*v1alpha2.NamedResourcesAttribute)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_NamedResourcesAttribute_To_v1alpha2_NamedResourcesAttribute(a.(*resource.NamedResourcesAttribute), b.(*v1alpha2.NamedResourcesAttribute), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.NamedResourcesAttributeValue)(nil), (*resource.NamedResourcesAttributeValue)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_NamedResourcesAttributeValue_To_resource_NamedResourcesAttributeValue(a.(*v1alpha2.NamedResourcesAttributeValue), b.(*resource.NamedResourcesAttributeValue), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.NamedResourcesAttributeValue)(nil), (*v1alpha2.NamedResourcesAttributeValue)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_NamedResourcesAttributeValue_To_v1alpha2_NamedResourcesAttributeValue(a.(*resource.NamedResourcesAttributeValue), b.(*v1alpha2.NamedResourcesAttributeValue), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.NamedResourcesFilter)(nil), (*resource.NamedResourcesFilter)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_NamedResourcesFilter_To_resource_NamedResourcesFilter(a.(*v1alpha2.NamedResourcesFilter), b.(*resource.NamedResourcesFilter), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.NamedResourcesFilter)(nil), (*v1alpha2.NamedResourcesFilter)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_NamedResourcesFilter_To_v1alpha2_NamedResourcesFilter(a.(*resource.NamedResourcesFilter), b.(*v1alpha2.NamedResourcesFilter), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.NamedResourcesInstance)(nil), (*resource.NamedResourcesInstance)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_NamedResourcesInstance_To_resource_NamedResourcesInstance(a.(*v1alpha2.NamedResourcesInstance), b.(*resource.NamedResourcesInstance), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.NamedResourcesInstance)(nil), (*v1alpha2.NamedResourcesInstance)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_NamedResourcesInstance_To_v1alpha2_NamedResourcesInstance(a.(*resource.NamedResourcesInstance), b.(*v1alpha2.NamedResourcesInstance), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.NamedResourcesIntSlice)(nil), (*resource.NamedResourcesIntSlice)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_NamedResourcesIntSlice_To_resource_NamedResourcesIntSlice(a.(*v1alpha2.NamedResourcesIntSlice), b.(*resource.NamedResourcesIntSlice), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.NamedResourcesIntSlice)(nil), (*v1alpha2.NamedResourcesIntSlice)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_NamedResourcesIntSlice_To_v1alpha2_NamedResourcesIntSlice(a.(*resource.NamedResourcesIntSlice), b.(*v1alpha2.NamedResourcesIntSlice), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.NamedResourcesRequest)(nil), (*resource.NamedResourcesRequest)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_NamedResourcesRequest_To_resource_NamedResourcesRequest(a.(*v1alpha2.NamedResourcesRequest), b.(*resource.NamedResourcesRequest), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.NamedResourcesRequest)(nil), (*v1alpha2.NamedResourcesRequest)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_NamedResourcesRequest_To_v1alpha2_NamedResourcesRequest(a.(*resource.NamedResourcesRequest), b.(*v1alpha2.NamedResourcesRequest), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.NamedResourcesResources)(nil), (*resource.NamedResourcesResources)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_NamedResourcesResources_To_resource_NamedResourcesResources(a.(*v1alpha2.NamedResourcesResources), b.(*resource.NamedResourcesResources), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.NamedResourcesResources)(nil), (*v1alpha2.NamedResourcesResources)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_NamedResourcesResources_To_v1alpha2_NamedResourcesResources(a.(*resource.NamedResourcesResources), b.(*v1alpha2.NamedResourcesResources), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.NamedResourcesStringSlice)(nil), (*resource.NamedResourcesStringSlice)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_NamedResourcesStringSlice_To_resource_NamedResourcesStringSlice(a.(*v1alpha2.NamedResourcesStringSlice), b.(*resource.NamedResourcesStringSlice), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.NamedResourcesStringSlice)(nil), (*v1alpha2.NamedResourcesStringSlice)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_NamedResourcesStringSlice_To_v1alpha2_NamedResourcesStringSlice(a.(*resource.NamedResourcesStringSlice), b.(*v1alpha2.NamedResourcesStringSlice), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*v1alpha2.NodeResourceModel)(nil), (*resource.NodeResourceModel)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha2_NodeResourceModel_To_resource_NodeResourceModel(a.(*v1alpha2.NodeResourceModel), b.(*resource.NodeResourceModel), scope) }); err != nil { @@ -438,6 +529,7 @@ func Convert_resource_AllocationResult_To_v1alpha2_AllocationResult(in *resource } func autoConvert_v1alpha2_AllocationResultModel_To_resource_AllocationResultModel(in *v1alpha2.AllocationResultModel, out *resource.AllocationResultModel, s conversion.Scope) error { + out.NamedResources = (*resource.NamedResourcesAllocationResult)(unsafe.Pointer(in.NamedResources)) return nil } @@ -447,6 +539,7 @@ func Convert_v1alpha2_AllocationResultModel_To_resource_AllocationResultModel(in } func autoConvert_resource_AllocationResultModel_To_v1alpha2_AllocationResultModel(in *resource.AllocationResultModel, out *v1alpha2.AllocationResultModel, s conversion.Scope) error { + out.NamedResources = (*v1alpha2.NamedResourcesAllocationResult)(unsafe.Pointer(in.NamedResources)) return nil } @@ -533,7 +626,206 @@ func Convert_resource_DriverRequests_To_v1alpha2_DriverRequests(in *resource.Dri return autoConvert_resource_DriverRequests_To_v1alpha2_DriverRequests(in, out, s) } +func autoConvert_v1alpha2_NamedResourcesAllocationResult_To_resource_NamedResourcesAllocationResult(in *v1alpha2.NamedResourcesAllocationResult, out *resource.NamedResourcesAllocationResult, s conversion.Scope) error { + out.Name = in.Name + return nil +} + +// Convert_v1alpha2_NamedResourcesAllocationResult_To_resource_NamedResourcesAllocationResult is an autogenerated conversion function. +func Convert_v1alpha2_NamedResourcesAllocationResult_To_resource_NamedResourcesAllocationResult(in *v1alpha2.NamedResourcesAllocationResult, out *resource.NamedResourcesAllocationResult, s conversion.Scope) error { + return autoConvert_v1alpha2_NamedResourcesAllocationResult_To_resource_NamedResourcesAllocationResult(in, out, s) +} + +func autoConvert_resource_NamedResourcesAllocationResult_To_v1alpha2_NamedResourcesAllocationResult(in *resource.NamedResourcesAllocationResult, out *v1alpha2.NamedResourcesAllocationResult, s conversion.Scope) error { + out.Name = in.Name + return nil +} + +// Convert_resource_NamedResourcesAllocationResult_To_v1alpha2_NamedResourcesAllocationResult is an autogenerated conversion function. +func Convert_resource_NamedResourcesAllocationResult_To_v1alpha2_NamedResourcesAllocationResult(in *resource.NamedResourcesAllocationResult, out *v1alpha2.NamedResourcesAllocationResult, s conversion.Scope) error { + return autoConvert_resource_NamedResourcesAllocationResult_To_v1alpha2_NamedResourcesAllocationResult(in, out, s) +} + +func autoConvert_v1alpha2_NamedResourcesAttribute_To_resource_NamedResourcesAttribute(in *v1alpha2.NamedResourcesAttribute, out *resource.NamedResourcesAttribute, s conversion.Scope) error { + out.Name = in.Name + if err := Convert_v1alpha2_NamedResourcesAttributeValue_To_resource_NamedResourcesAttributeValue(&in.NamedResourcesAttributeValue, &out.NamedResourcesAttributeValue, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha2_NamedResourcesAttribute_To_resource_NamedResourcesAttribute is an autogenerated conversion function. +func Convert_v1alpha2_NamedResourcesAttribute_To_resource_NamedResourcesAttribute(in *v1alpha2.NamedResourcesAttribute, out *resource.NamedResourcesAttribute, s conversion.Scope) error { + return autoConvert_v1alpha2_NamedResourcesAttribute_To_resource_NamedResourcesAttribute(in, out, s) +} + +func autoConvert_resource_NamedResourcesAttribute_To_v1alpha2_NamedResourcesAttribute(in *resource.NamedResourcesAttribute, out *v1alpha2.NamedResourcesAttribute, s conversion.Scope) error { + out.Name = in.Name + if err := Convert_resource_NamedResourcesAttributeValue_To_v1alpha2_NamedResourcesAttributeValue(&in.NamedResourcesAttributeValue, &out.NamedResourcesAttributeValue, s); err != nil { + return err + } + return nil +} + +// Convert_resource_NamedResourcesAttribute_To_v1alpha2_NamedResourcesAttribute is an autogenerated conversion function. +func Convert_resource_NamedResourcesAttribute_To_v1alpha2_NamedResourcesAttribute(in *resource.NamedResourcesAttribute, out *v1alpha2.NamedResourcesAttribute, s conversion.Scope) error { + return autoConvert_resource_NamedResourcesAttribute_To_v1alpha2_NamedResourcesAttribute(in, out, s) +} + +func autoConvert_v1alpha2_NamedResourcesAttributeValue_To_resource_NamedResourcesAttributeValue(in *v1alpha2.NamedResourcesAttributeValue, out *resource.NamedResourcesAttributeValue, s conversion.Scope) error { + out.QuantityValue = (*apiresource.Quantity)(unsafe.Pointer(in.QuantityValue)) + out.BoolValue = (*bool)(unsafe.Pointer(in.BoolValue)) + out.IntValue = (*int64)(unsafe.Pointer(in.IntValue)) + out.IntSliceValue = (*resource.NamedResourcesIntSlice)(unsafe.Pointer(in.IntSliceValue)) + out.StringValue = (*string)(unsafe.Pointer(in.StringValue)) + out.StringSliceValue = (*resource.NamedResourcesStringSlice)(unsafe.Pointer(in.StringSliceValue)) + return nil +} + +// Convert_v1alpha2_NamedResourcesAttributeValue_To_resource_NamedResourcesAttributeValue is an autogenerated conversion function. +func Convert_v1alpha2_NamedResourcesAttributeValue_To_resource_NamedResourcesAttributeValue(in *v1alpha2.NamedResourcesAttributeValue, out *resource.NamedResourcesAttributeValue, s conversion.Scope) error { + return autoConvert_v1alpha2_NamedResourcesAttributeValue_To_resource_NamedResourcesAttributeValue(in, out, s) +} + +func autoConvert_resource_NamedResourcesAttributeValue_To_v1alpha2_NamedResourcesAttributeValue(in *resource.NamedResourcesAttributeValue, out *v1alpha2.NamedResourcesAttributeValue, s conversion.Scope) error { + out.QuantityValue = (*apiresource.Quantity)(unsafe.Pointer(in.QuantityValue)) + out.BoolValue = (*bool)(unsafe.Pointer(in.BoolValue)) + out.IntValue = (*int64)(unsafe.Pointer(in.IntValue)) + out.IntSliceValue = (*v1alpha2.NamedResourcesIntSlice)(unsafe.Pointer(in.IntSliceValue)) + out.StringValue = (*string)(unsafe.Pointer(in.StringValue)) + out.StringSliceValue = (*v1alpha2.NamedResourcesStringSlice)(unsafe.Pointer(in.StringSliceValue)) + return nil +} + +// Convert_resource_NamedResourcesAttributeValue_To_v1alpha2_NamedResourcesAttributeValue is an autogenerated conversion function. +func Convert_resource_NamedResourcesAttributeValue_To_v1alpha2_NamedResourcesAttributeValue(in *resource.NamedResourcesAttributeValue, out *v1alpha2.NamedResourcesAttributeValue, s conversion.Scope) error { + return autoConvert_resource_NamedResourcesAttributeValue_To_v1alpha2_NamedResourcesAttributeValue(in, out, s) +} + +func autoConvert_v1alpha2_NamedResourcesFilter_To_resource_NamedResourcesFilter(in *v1alpha2.NamedResourcesFilter, out *resource.NamedResourcesFilter, s conversion.Scope) error { + out.Selector = in.Selector + return nil +} + +// Convert_v1alpha2_NamedResourcesFilter_To_resource_NamedResourcesFilter is an autogenerated conversion function. +func Convert_v1alpha2_NamedResourcesFilter_To_resource_NamedResourcesFilter(in *v1alpha2.NamedResourcesFilter, out *resource.NamedResourcesFilter, s conversion.Scope) error { + return autoConvert_v1alpha2_NamedResourcesFilter_To_resource_NamedResourcesFilter(in, out, s) +} + +func autoConvert_resource_NamedResourcesFilter_To_v1alpha2_NamedResourcesFilter(in *resource.NamedResourcesFilter, out *v1alpha2.NamedResourcesFilter, s conversion.Scope) error { + out.Selector = in.Selector + return nil +} + +// Convert_resource_NamedResourcesFilter_To_v1alpha2_NamedResourcesFilter is an autogenerated conversion function. +func Convert_resource_NamedResourcesFilter_To_v1alpha2_NamedResourcesFilter(in *resource.NamedResourcesFilter, out *v1alpha2.NamedResourcesFilter, s conversion.Scope) error { + return autoConvert_resource_NamedResourcesFilter_To_v1alpha2_NamedResourcesFilter(in, out, s) +} + +func autoConvert_v1alpha2_NamedResourcesInstance_To_resource_NamedResourcesInstance(in *v1alpha2.NamedResourcesInstance, out *resource.NamedResourcesInstance, s conversion.Scope) error { + out.Name = in.Name + out.Attributes = *(*[]resource.NamedResourcesAttribute)(unsafe.Pointer(&in.Attributes)) + return nil +} + +// Convert_v1alpha2_NamedResourcesInstance_To_resource_NamedResourcesInstance is an autogenerated conversion function. +func Convert_v1alpha2_NamedResourcesInstance_To_resource_NamedResourcesInstance(in *v1alpha2.NamedResourcesInstance, out *resource.NamedResourcesInstance, s conversion.Scope) error { + return autoConvert_v1alpha2_NamedResourcesInstance_To_resource_NamedResourcesInstance(in, out, s) +} + +func autoConvert_resource_NamedResourcesInstance_To_v1alpha2_NamedResourcesInstance(in *resource.NamedResourcesInstance, out *v1alpha2.NamedResourcesInstance, s conversion.Scope) error { + out.Name = in.Name + out.Attributes = *(*[]v1alpha2.NamedResourcesAttribute)(unsafe.Pointer(&in.Attributes)) + return nil +} + +// Convert_resource_NamedResourcesInstance_To_v1alpha2_NamedResourcesInstance is an autogenerated conversion function. +func Convert_resource_NamedResourcesInstance_To_v1alpha2_NamedResourcesInstance(in *resource.NamedResourcesInstance, out *v1alpha2.NamedResourcesInstance, s conversion.Scope) error { + return autoConvert_resource_NamedResourcesInstance_To_v1alpha2_NamedResourcesInstance(in, out, s) +} + +func autoConvert_v1alpha2_NamedResourcesIntSlice_To_resource_NamedResourcesIntSlice(in *v1alpha2.NamedResourcesIntSlice, out *resource.NamedResourcesIntSlice, s conversion.Scope) error { + out.Ints = *(*[]int64)(unsafe.Pointer(&in.Ints)) + return nil +} + +// Convert_v1alpha2_NamedResourcesIntSlice_To_resource_NamedResourcesIntSlice is an autogenerated conversion function. +func Convert_v1alpha2_NamedResourcesIntSlice_To_resource_NamedResourcesIntSlice(in *v1alpha2.NamedResourcesIntSlice, out *resource.NamedResourcesIntSlice, s conversion.Scope) error { + return autoConvert_v1alpha2_NamedResourcesIntSlice_To_resource_NamedResourcesIntSlice(in, out, s) +} + +func autoConvert_resource_NamedResourcesIntSlice_To_v1alpha2_NamedResourcesIntSlice(in *resource.NamedResourcesIntSlice, out *v1alpha2.NamedResourcesIntSlice, s conversion.Scope) error { + out.Ints = *(*[]int64)(unsafe.Pointer(&in.Ints)) + return nil +} + +// Convert_resource_NamedResourcesIntSlice_To_v1alpha2_NamedResourcesIntSlice is an autogenerated conversion function. +func Convert_resource_NamedResourcesIntSlice_To_v1alpha2_NamedResourcesIntSlice(in *resource.NamedResourcesIntSlice, out *v1alpha2.NamedResourcesIntSlice, s conversion.Scope) error { + return autoConvert_resource_NamedResourcesIntSlice_To_v1alpha2_NamedResourcesIntSlice(in, out, s) +} + +func autoConvert_v1alpha2_NamedResourcesRequest_To_resource_NamedResourcesRequest(in *v1alpha2.NamedResourcesRequest, out *resource.NamedResourcesRequest, s conversion.Scope) error { + out.Selector = in.Selector + return nil +} + +// Convert_v1alpha2_NamedResourcesRequest_To_resource_NamedResourcesRequest is an autogenerated conversion function. +func Convert_v1alpha2_NamedResourcesRequest_To_resource_NamedResourcesRequest(in *v1alpha2.NamedResourcesRequest, out *resource.NamedResourcesRequest, s conversion.Scope) error { + return autoConvert_v1alpha2_NamedResourcesRequest_To_resource_NamedResourcesRequest(in, out, s) +} + +func autoConvert_resource_NamedResourcesRequest_To_v1alpha2_NamedResourcesRequest(in *resource.NamedResourcesRequest, out *v1alpha2.NamedResourcesRequest, s conversion.Scope) error { + out.Selector = in.Selector + return nil +} + +// Convert_resource_NamedResourcesRequest_To_v1alpha2_NamedResourcesRequest is an autogenerated conversion function. +func Convert_resource_NamedResourcesRequest_To_v1alpha2_NamedResourcesRequest(in *resource.NamedResourcesRequest, out *v1alpha2.NamedResourcesRequest, s conversion.Scope) error { + return autoConvert_resource_NamedResourcesRequest_To_v1alpha2_NamedResourcesRequest(in, out, s) +} + +func autoConvert_v1alpha2_NamedResourcesResources_To_resource_NamedResourcesResources(in *v1alpha2.NamedResourcesResources, out *resource.NamedResourcesResources, s conversion.Scope) error { + out.Instances = *(*[]resource.NamedResourcesInstance)(unsafe.Pointer(&in.Instances)) + return nil +} + +// Convert_v1alpha2_NamedResourcesResources_To_resource_NamedResourcesResources is an autogenerated conversion function. +func Convert_v1alpha2_NamedResourcesResources_To_resource_NamedResourcesResources(in *v1alpha2.NamedResourcesResources, out *resource.NamedResourcesResources, s conversion.Scope) error { + return autoConvert_v1alpha2_NamedResourcesResources_To_resource_NamedResourcesResources(in, out, s) +} + +func autoConvert_resource_NamedResourcesResources_To_v1alpha2_NamedResourcesResources(in *resource.NamedResourcesResources, out *v1alpha2.NamedResourcesResources, s conversion.Scope) error { + out.Instances = *(*[]v1alpha2.NamedResourcesInstance)(unsafe.Pointer(&in.Instances)) + return nil +} + +// Convert_resource_NamedResourcesResources_To_v1alpha2_NamedResourcesResources is an autogenerated conversion function. +func Convert_resource_NamedResourcesResources_To_v1alpha2_NamedResourcesResources(in *resource.NamedResourcesResources, out *v1alpha2.NamedResourcesResources, s conversion.Scope) error { + return autoConvert_resource_NamedResourcesResources_To_v1alpha2_NamedResourcesResources(in, out, s) +} + +func autoConvert_v1alpha2_NamedResourcesStringSlice_To_resource_NamedResourcesStringSlice(in *v1alpha2.NamedResourcesStringSlice, out *resource.NamedResourcesStringSlice, s conversion.Scope) error { + out.Strings = *(*[]string)(unsafe.Pointer(&in.Strings)) + return nil +} + +// Convert_v1alpha2_NamedResourcesStringSlice_To_resource_NamedResourcesStringSlice is an autogenerated conversion function. +func Convert_v1alpha2_NamedResourcesStringSlice_To_resource_NamedResourcesStringSlice(in *v1alpha2.NamedResourcesStringSlice, out *resource.NamedResourcesStringSlice, s conversion.Scope) error { + return autoConvert_v1alpha2_NamedResourcesStringSlice_To_resource_NamedResourcesStringSlice(in, out, s) +} + +func autoConvert_resource_NamedResourcesStringSlice_To_v1alpha2_NamedResourcesStringSlice(in *resource.NamedResourcesStringSlice, out *v1alpha2.NamedResourcesStringSlice, s conversion.Scope) error { + out.Strings = *(*[]string)(unsafe.Pointer(&in.Strings)) + return nil +} + +// Convert_resource_NamedResourcesStringSlice_To_v1alpha2_NamedResourcesStringSlice is an autogenerated conversion function. +func Convert_resource_NamedResourcesStringSlice_To_v1alpha2_NamedResourcesStringSlice(in *resource.NamedResourcesStringSlice, out *v1alpha2.NamedResourcesStringSlice, s conversion.Scope) error { + return autoConvert_resource_NamedResourcesStringSlice_To_v1alpha2_NamedResourcesStringSlice(in, out, s) +} + func autoConvert_v1alpha2_NodeResourceModel_To_resource_NodeResourceModel(in *v1alpha2.NodeResourceModel, out *resource.NodeResourceModel, s conversion.Scope) error { + out.NamedResources = (*resource.NamedResourcesResources)(unsafe.Pointer(in.NamedResources)) return nil } @@ -543,6 +835,7 @@ func Convert_v1alpha2_NodeResourceModel_To_resource_NodeResourceModel(in *v1alph } func autoConvert_resource_NodeResourceModel_To_v1alpha2_NodeResourceModel(in *resource.NodeResourceModel, out *v1alpha2.NodeResourceModel, s conversion.Scope) error { + out.NamedResources = (*v1alpha2.NamedResourcesResources)(unsafe.Pointer(in.NamedResources)) return nil } @@ -1264,6 +1557,7 @@ func Convert_resource_ResourceFilter_To_v1alpha2_ResourceFilter(in *resource.Res } func autoConvert_v1alpha2_ResourceFilterModel_To_resource_ResourceFilterModel(in *v1alpha2.ResourceFilterModel, out *resource.ResourceFilterModel, s conversion.Scope) error { + out.NamedResources = (*resource.NamedResourcesFilter)(unsafe.Pointer(in.NamedResources)) return nil } @@ -1273,6 +1567,7 @@ func Convert_v1alpha2_ResourceFilterModel_To_resource_ResourceFilterModel(in *v1 } func autoConvert_resource_ResourceFilterModel_To_v1alpha2_ResourceFilterModel(in *resource.ResourceFilterModel, out *v1alpha2.ResourceFilterModel, s conversion.Scope) error { + out.NamedResources = (*v1alpha2.NamedResourcesFilter)(unsafe.Pointer(in.NamedResources)) return nil } @@ -1352,6 +1647,7 @@ func Convert_resource_ResourceRequest_To_v1alpha2_ResourceRequest(in *resource.R } func autoConvert_v1alpha2_ResourceRequestModel_To_resource_ResourceRequestModel(in *v1alpha2.ResourceRequestModel, out *resource.ResourceRequestModel, s conversion.Scope) error { + out.NamedResources = (*resource.NamedResourcesRequest)(unsafe.Pointer(in.NamedResources)) return nil } @@ -1361,6 +1657,7 @@ func Convert_v1alpha2_ResourceRequestModel_To_resource_ResourceRequestModel(in * } func autoConvert_resource_ResourceRequestModel_To_v1alpha2_ResourceRequestModel(in *resource.ResourceRequestModel, out *v1alpha2.ResourceRequestModel, s conversion.Scope) error { + out.NamedResources = (*v1alpha2.NamedResourcesRequest)(unsafe.Pointer(in.NamedResources)) return nil } diff --git a/pkg/apis/resource/validation/validation.go b/pkg/apis/resource/validation/validation.go index 4e67edbde2f..713501de9c1 100644 --- a/pkg/apis/resource/validation/validation.go +++ b/pkg/apis/resource/validation/validation.go @@ -24,6 +24,7 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" corevalidation "k8s.io/kubernetes/pkg/apis/core/validation" "k8s.io/kubernetes/pkg/apis/resource" + namedresourcesvalidation "k8s.io/kubernetes/pkg/apis/resource/structured/namedresources/validation" ) // validateResourceDriverName reuses the validation of a CSI driver because @@ -236,10 +237,13 @@ func validateDriverAllocationResults(results []resource.DriverAllocationResult, func validateAllocationResultModel(model *resource.AllocationResultModel, fldPath *field.Path) field.ErrorList { var allErrs field.ErrorList entries := sets.New[string]() - // TODO: implement one structured parameter model + if model.NamedResources != nil { + entries.Insert("namedResources") + allErrs = append(allErrs, namedresourcesvalidation.ValidateAllocationResult(model.NamedResources, fldPath.Child("namedResources"))...) + } switch len(entries) { case 0: - // allErrs = append(allErrs, field.Required(fldPath, "exactly one structured model field must be set")) + allErrs = append(allErrs, field.Required(fldPath, "exactly one structured model field must be set")) case 1: // Okay. default: @@ -396,10 +400,13 @@ func ValidateNodeResourceSlice(nodeResourceSlice *resource.NodeResourceSlice) fi func validateNodeResourceModel(model *resource.NodeResourceModel, fldPath *field.Path) field.ErrorList { var allErrs field.ErrorList entries := sets.New[string]() - // TODO: implement one structured parameter model + if model.NamedResources != nil { + entries.Insert("namedResources") + allErrs = append(allErrs, namedresourcesvalidation.ValidateResources(model.NamedResources, fldPath.Child("namedResources"))...) + } switch len(entries) { case 0: - // allErrs = append(allErrs, field.Required(fldPath, "exactly one structured model field must be set")) + allErrs = append(allErrs, field.Required(fldPath, "exactly one structured model field must be set")) case 1: // Okay. default: @@ -463,10 +470,13 @@ func validateResourceRequests(requests []resource.ResourceRequest, fldPath *fiel func validateResourceRequestModel(model *resource.ResourceRequestModel, fldPath *field.Path, requestStored bool) field.ErrorList { var allErrs field.ErrorList entries := sets.New[string]() - // TODO: implement one structured parameter model + if model.NamedResources != nil { + entries.Insert("namedResources") + allErrs = append(allErrs, namedresourcesvalidation.ValidateRequest(namedresourcesvalidation.Options{StoredExpressions: requestStored}, model.NamedResources, fldPath.Child("namedResources"))...) + } switch len(entries) { case 0: - // allErrs = append(allErrs, field.Required(fldPath, "exactly one structured model field must be set")) + allErrs = append(allErrs, field.Required(fldPath, "exactly one structured model field must be set")) case 1: // Okay. default: @@ -516,10 +526,13 @@ func validateResourceFilters(filters []resource.ResourceFilter, fldPath *field.P func validateResourceFilterModel(model *resource.ResourceFilterModel, fldPath *field.Path, filtersStored bool) field.ErrorList { var allErrs field.ErrorList entries := sets.New[string]() - // TODO: implement one structured parameter model + if model.NamedResources != nil { + entries.Insert("namedResources") + allErrs = append(allErrs, namedresourcesvalidation.ValidateFilter(namedresourcesvalidation.Options{StoredExpressions: filtersStored}, model.NamedResources, fldPath.Child("namedResources"))...) + } switch len(entries) { case 0: - // allErrs = append(allErrs, field.Required(fldPath, "exactly one structured model field must be set")) + allErrs = append(allErrs, field.Required(fldPath, "exactly one structured model field must be set")) case 1: // Okay. default: diff --git a/pkg/apis/resource/validation/validation_noderesourceslice_test.go b/pkg/apis/resource/validation/validation_noderesourceslice_test.go index c10cbdf01a9..e0ada2e7ec3 100644 --- a/pkg/apis/resource/validation/validation_noderesourceslice_test.go +++ b/pkg/apis/resource/validation/validation_noderesourceslice_test.go @@ -32,10 +32,10 @@ func testNodeResourceSlice(name, nodeName, driverName string) *resource.NodeReso ObjectMeta: metav1.ObjectMeta{ Name: name, }, - NodeName: nodeName, - DriverName: driverName, + NodeName: nodeName, + DriverName: driverName, NodeResourceModel: resource.NodeResourceModel{ - // TODO: implement one structured parameter model + NamedResources: &resource.NamedResourcesResources{}, }, } } @@ -188,15 +188,14 @@ func TestValidateNodeResourceSlice(t *testing.T) { slice: testNodeResourceSlice(goodName, goodName, badName), }, - // TODO: implement one structured parameter model - // "empty-model": { - // wantFailures: field.ErrorList{field.Required(nil, "exactly one structured model field must be set")}, - // slice: func() *resource.NodeResourceSlice { - // slice := testNodeResourceSlice(goodName, goodName, driverName) - // slice.NodeResourceModel = resource.NodeResourceModel{} - // return slice - // }(), - // }, + "empty-model": { + wantFailures: field.ErrorList{field.Required(nil, "exactly one structured model field must be set")}, + slice: func() *resource.NodeResourceSlice { + slice := testNodeResourceSlice(goodName, goodName, driverName) + slice.NodeResourceModel = resource.NodeResourceModel{} + return slice + }(), + }, } for name, scenario := range scenarios { diff --git a/pkg/apis/resource/validation/validation_resourceclaim_test.go b/pkg/apis/resource/validation/validation_resourceclaim_test.go index 956377cdbda..d4582e479da 100644 --- a/pkg/apis/resource/validation/validation_resourceclaim_test.go +++ b/pkg/apis/resource/validation/validation_resourceclaim_test.go @@ -400,6 +400,7 @@ func TestValidateClaimStatusUpdate(t *testing.T) { "invalid-add-allocation-structured": { wantFailures: field.ErrorList{ field.Invalid(field.NewPath("status", "allocation", "resourceHandles").Index(0).Child("structuredData", "nodeName"), "", "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')"), + field.Required(field.NewPath("status", "allocation", "resourceHandles").Index(0).Child("structuredData", "results").Index(1), "exactly one structured model field must be set"), }, oldClaim: validClaim, update: func(claim *resource.ResourceClaim) *resource.ResourceClaim { @@ -410,7 +411,16 @@ func TestValidateClaimStatusUpdate(t *testing.T) { DriverName: "valid", StructuredData: &resource.StructuredResourceHandle{ Results: []resource.DriverAllocationResult{ - // TODO: empty AllocationResultMode + { + AllocationResultModel: resource.AllocationResultModel{ + NamedResources: &resource.NamedResourcesAllocationResult{ + Name: "some-resource-instance", + }, + }, + }, + { + AllocationResultModel: resource.AllocationResultModel{}, // invalid + }, }, }, }, diff --git a/pkg/apis/resource/validation/validation_resourceclaimparameters_test.go b/pkg/apis/resource/validation/validation_resourceclaimparameters_test.go index d38e1246626..f4af43f8b46 100644 --- a/pkg/apis/resource/validation/validation_resourceclaimparameters_test.go +++ b/pkg/apis/resource/validation/validation_resourceclaimparameters_test.go @@ -186,15 +186,14 @@ func TestValidateResourceClaimParameters(t *testing.T) { }(), }, - // TODO: implement one structured parameter model - // "empty-model": { - // wantFailures: field.ErrorList{field.Required(field.NewPath("driverRequests").Index(0).Child("requests").Index(0), "exactly one structured model field must be set")}, - // parameters: func() *resource.ResourceClaimParameters { - // parameters := testResourceClaimParameters(goodName, goodName, goodRequests) - // parameters.DriverRequests = []resource.DriverRequests{{DriverName: goodName, Requests: []resource.ResourceRequest{{}}}} - // return parameters - // }(), - // }, + "empty-model": { + wantFailures: field.ErrorList{field.Required(field.NewPath("driverRequests").Index(0).Child("requests").Index(0), "exactly one structured model field must be set")}, + parameters: func() *resource.ResourceClaimParameters { + parameters := testResourceClaimParameters(goodName, goodName, goodRequests) + parameters.DriverRequests = []resource.DriverRequests{{DriverName: goodName, Requests: []resource.ResourceRequest{{}}}} + return parameters + }(), + }, "empty-requests": { wantFailures: field.ErrorList{field.Required(field.NewPath("driverRequests").Index(0).Child("requests"), "empty entries with no requests are not allowed")}, @@ -215,7 +214,7 @@ func TestValidateResourceClaimParameters(t *testing.T) { Requests: []resource.ResourceRequest{ { ResourceRequestModel: resource.ResourceRequestModel{ - // TODO: implement one structured parameter model + NamedResources: &resource.NamedResourcesRequest{Selector: "true"}, }, }, }, @@ -225,7 +224,7 @@ func TestValidateResourceClaimParameters(t *testing.T) { Requests: []resource.ResourceRequest{ { ResourceRequestModel: resource.ResourceRequestModel{ - // TODO: implement one structured parameter model + NamedResources: &resource.NamedResourcesRequest{Selector: "true"}, }, }, }, @@ -245,8 +244,7 @@ func TestValidateResourceClaimParameters(t *testing.T) { Requests: []resource.ResourceRequest{ { ResourceRequestModel: resource.ResourceRequestModel{ - // TODO: implement one structured parameter model - + NamedResources: &resource.NamedResourcesRequest{Selector: "true"}, }, }, }, @@ -256,7 +254,7 @@ func TestValidateResourceClaimParameters(t *testing.T) { Requests: []resource.ResourceRequest{ { ResourceRequestModel: resource.ResourceRequestModel{ - // TODO: implement one structured parameter model + NamedResources: &resource.NamedResourcesRequest{Selector: "true"}, }, }, }, diff --git a/pkg/apis/resource/validation/validation_resourceclassparameters_test.go b/pkg/apis/resource/validation/validation_resourceclassparameters_test.go index c828196f865..8286bf44d32 100644 --- a/pkg/apis/resource/validation/validation_resourceclassparameters_test.go +++ b/pkg/apis/resource/validation/validation_resourceclassparameters_test.go @@ -186,15 +186,14 @@ func TestValidateResourceClassParameters(t *testing.T) { }(), }, - // TODO: implement one structured parameter model - // "empty-model": { - // wantFailures: field.ErrorList{field.Required(field.NewPath("filters").Index(0), "exactly one structured model field must be set")}, - // parameters: func() *resource.ResourceClassParameters { - // parameters := testResourceClassParameters(goodName, goodName, goodFilters) - // parameters.Filters = []resource.ResourceFilter{{DriverName: goodName}} - // return parameters - // }(), - // }, + "empty-model": { + wantFailures: field.ErrorList{field.Required(field.NewPath("filters").Index(0), "exactly one structured model field must be set")}, + parameters: func() *resource.ResourceClassParameters { + parameters := testResourceClassParameters(goodName, goodName, goodFilters) + parameters.Filters = []resource.ResourceFilter{{DriverName: goodName}} + return parameters + }(), + }, "filters-invalid-driver": { wantFailures: field.ErrorList{field.Invalid(field.NewPath("filters").Index(1).Child("driverName"), badName, "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')")}, @@ -202,15 +201,15 @@ func TestValidateResourceClassParameters(t *testing.T) { parameters := testResourceClassParameters(goodName, goodName, goodFilters) parameters.Filters = []resource.ResourceFilter{ { - DriverName: goodName, + DriverName: goodName, ResourceFilterModel: resource.ResourceFilterModel{ - // TODO: implement one structured parameter model + NamedResources: &resource.NamedResourcesFilter{Selector: "true"}, }, }, { - DriverName: badName, + DriverName: badName, ResourceFilterModel: resource.ResourceFilterModel{ - // TODO: implement one structured parameter model + NamedResources: &resource.NamedResourcesFilter{Selector: "true"}, }, }, } @@ -224,14 +223,16 @@ func TestValidateResourceClassParameters(t *testing.T) { parameters := testResourceClassParameters(goodName, goodName, goodFilters) parameters.Filters = []resource.ResourceFilter{ { - DriverName: goodName, + DriverName: goodName, ResourceFilterModel: resource.ResourceFilterModel{ - // TODO: implement one structured parameter model + NamedResources: &resource.NamedResourcesFilter{Selector: "true"}, }, }, { - DriverName: goodName, - ResourceFilterModel: resource.ResourceFilterModel{}, + DriverName: goodName, + ResourceFilterModel: resource.ResourceFilterModel{ + NamedResources: &resource.NamedResourcesFilter{Selector: "true"}, + }, }, } return parameters diff --git a/pkg/apis/resource/zz_generated.deepcopy.go b/pkg/apis/resource/zz_generated.deepcopy.go index 24114076648..44d2aa3bc94 100644 --- a/pkg/apis/resource/zz_generated.deepcopy.go +++ b/pkg/apis/resource/zz_generated.deepcopy.go @@ -57,6 +57,11 @@ func (in *AllocationResult) DeepCopy() *AllocationResult { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AllocationResultModel) DeepCopyInto(out *AllocationResultModel) { *out = *in + if in.NamedResources != nil { + in, out := &in.NamedResources, &out.NamedResources + *out = new(NamedResourcesAllocationResult) + **out = **in + } return } @@ -76,7 +81,7 @@ func (in *DriverAllocationResult) DeepCopyInto(out *DriverAllocationResult) { if in.VendorRequestParameters != nil { out.VendorRequestParameters = in.VendorRequestParameters.DeepCopyObject() } - out.AllocationResultModel = in.AllocationResultModel + in.AllocationResultModel.DeepCopyInto(&out.AllocationResultModel) return } @@ -116,9 +121,213 @@ func (in *DriverRequests) DeepCopy() *DriverRequests { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedResourcesAllocationResult) DeepCopyInto(out *NamedResourcesAllocationResult) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedResourcesAllocationResult. +func (in *NamedResourcesAllocationResult) DeepCopy() *NamedResourcesAllocationResult { + if in == nil { + return nil + } + out := new(NamedResourcesAllocationResult) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedResourcesAttribute) DeepCopyInto(out *NamedResourcesAttribute) { + *out = *in + in.NamedResourcesAttributeValue.DeepCopyInto(&out.NamedResourcesAttributeValue) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedResourcesAttribute. +func (in *NamedResourcesAttribute) DeepCopy() *NamedResourcesAttribute { + if in == nil { + return nil + } + out := new(NamedResourcesAttribute) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedResourcesAttributeValue) DeepCopyInto(out *NamedResourcesAttributeValue) { + *out = *in + if in.QuantityValue != nil { + in, out := &in.QuantityValue, &out.QuantityValue + x := (*in).DeepCopy() + *out = &x + } + if in.BoolValue != nil { + in, out := &in.BoolValue, &out.BoolValue + *out = new(bool) + **out = **in + } + if in.IntValue != nil { + in, out := &in.IntValue, &out.IntValue + *out = new(int64) + **out = **in + } + if in.IntSliceValue != nil { + in, out := &in.IntSliceValue, &out.IntSliceValue + *out = new(NamedResourcesIntSlice) + (*in).DeepCopyInto(*out) + } + if in.StringValue != nil { + in, out := &in.StringValue, &out.StringValue + *out = new(string) + **out = **in + } + if in.StringSliceValue != nil { + in, out := &in.StringSliceValue, &out.StringSliceValue + *out = new(NamedResourcesStringSlice) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedResourcesAttributeValue. +func (in *NamedResourcesAttributeValue) DeepCopy() *NamedResourcesAttributeValue { + if in == nil { + return nil + } + out := new(NamedResourcesAttributeValue) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedResourcesFilter) DeepCopyInto(out *NamedResourcesFilter) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedResourcesFilter. +func (in *NamedResourcesFilter) DeepCopy() *NamedResourcesFilter { + if in == nil { + return nil + } + out := new(NamedResourcesFilter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedResourcesInstance) DeepCopyInto(out *NamedResourcesInstance) { + *out = *in + if in.Attributes != nil { + in, out := &in.Attributes, &out.Attributes + *out = make([]NamedResourcesAttribute, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedResourcesInstance. +func (in *NamedResourcesInstance) DeepCopy() *NamedResourcesInstance { + if in == nil { + return nil + } + out := new(NamedResourcesInstance) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedResourcesIntSlice) DeepCopyInto(out *NamedResourcesIntSlice) { + *out = *in + if in.Ints != nil { + in, out := &in.Ints, &out.Ints + *out = make([]int64, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedResourcesIntSlice. +func (in *NamedResourcesIntSlice) DeepCopy() *NamedResourcesIntSlice { + if in == nil { + return nil + } + out := new(NamedResourcesIntSlice) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedResourcesRequest) DeepCopyInto(out *NamedResourcesRequest) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedResourcesRequest. +func (in *NamedResourcesRequest) DeepCopy() *NamedResourcesRequest { + if in == nil { + return nil + } + out := new(NamedResourcesRequest) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedResourcesResources) DeepCopyInto(out *NamedResourcesResources) { + *out = *in + if in.Instances != nil { + in, out := &in.Instances, &out.Instances + *out = make([]NamedResourcesInstance, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedResourcesResources. +func (in *NamedResourcesResources) DeepCopy() *NamedResourcesResources { + if in == nil { + return nil + } + out := new(NamedResourcesResources) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedResourcesStringSlice) DeepCopyInto(out *NamedResourcesStringSlice) { + *out = *in + if in.Strings != nil { + in, out := &in.Strings, &out.Strings + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedResourcesStringSlice. +func (in *NamedResourcesStringSlice) DeepCopy() *NamedResourcesStringSlice { + if in == nil { + return nil + } + out := new(NamedResourcesStringSlice) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NodeResourceModel) DeepCopyInto(out *NodeResourceModel) { *out = *in + if in.NamedResources != nil { + in, out := &in.NamedResources, &out.NamedResources + *out = new(NamedResourcesResources) + (*in).DeepCopyInto(*out) + } return } @@ -137,7 +346,7 @@ func (in *NodeResourceSlice) DeepCopyInto(out *NodeResourceSlice) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.NodeResourceModel = in.NodeResourceModel + in.NodeResourceModel.DeepCopyInto(&out.NodeResourceModel) return } @@ -701,7 +910,9 @@ func (in *ResourceClassParameters) DeepCopyInto(out *ResourceClassParameters) { if in.Filters != nil { in, out := &in.Filters, &out.Filters *out = make([]ResourceFilter, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } return } @@ -776,7 +987,7 @@ func (in *ResourceClassParametersReference) DeepCopy() *ResourceClassParametersR // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ResourceFilter) DeepCopyInto(out *ResourceFilter) { *out = *in - out.ResourceFilterModel = in.ResourceFilterModel + in.ResourceFilterModel.DeepCopyInto(&out.ResourceFilterModel) return } @@ -793,6 +1004,11 @@ func (in *ResourceFilter) DeepCopy() *ResourceFilter { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ResourceFilterModel) DeepCopyInto(out *ResourceFilterModel) { *out = *in + if in.NamedResources != nil { + in, out := &in.NamedResources, &out.NamedResources + *out = new(NamedResourcesFilter) + **out = **in + } return } @@ -833,7 +1049,7 @@ func (in *ResourceRequest) DeepCopyInto(out *ResourceRequest) { if in.VendorParameters != nil { out.VendorParameters = in.VendorParameters.DeepCopyObject() } - out.ResourceRequestModel = in.ResourceRequestModel + in.ResourceRequestModel.DeepCopyInto(&out.ResourceRequestModel) return } @@ -850,6 +1066,11 @@ func (in *ResourceRequest) DeepCopy() *ResourceRequest { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ResourceRequestModel) DeepCopyInto(out *ResourceRequestModel) { *out = *in + if in.NamedResources != nil { + in, out := &in.NamedResources, &out.NamedResources + *out = new(NamedResourcesRequest) + **out = **in + } return } diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index 4f6614f9ddc..eccec33d32f 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -871,6 +871,15 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "k8s.io/api/resource/v1alpha2.AllocationResultModel": schema_k8sio_api_resource_v1alpha2_AllocationResultModel(ref), "k8s.io/api/resource/v1alpha2.DriverAllocationResult": schema_k8sio_api_resource_v1alpha2_DriverAllocationResult(ref), "k8s.io/api/resource/v1alpha2.DriverRequests": schema_k8sio_api_resource_v1alpha2_DriverRequests(ref), + "k8s.io/api/resource/v1alpha2.NamedResourcesAllocationResult": schema_k8sio_api_resource_v1alpha2_NamedResourcesAllocationResult(ref), + "k8s.io/api/resource/v1alpha2.NamedResourcesAttribute": schema_k8sio_api_resource_v1alpha2_NamedResourcesAttribute(ref), + "k8s.io/api/resource/v1alpha2.NamedResourcesAttributeValue": schema_k8sio_api_resource_v1alpha2_NamedResourcesAttributeValue(ref), + "k8s.io/api/resource/v1alpha2.NamedResourcesFilter": schema_k8sio_api_resource_v1alpha2_NamedResourcesFilter(ref), + "k8s.io/api/resource/v1alpha2.NamedResourcesInstance": schema_k8sio_api_resource_v1alpha2_NamedResourcesInstance(ref), + "k8s.io/api/resource/v1alpha2.NamedResourcesIntSlice": schema_k8sio_api_resource_v1alpha2_NamedResourcesIntSlice(ref), + "k8s.io/api/resource/v1alpha2.NamedResourcesRequest": schema_k8sio_api_resource_v1alpha2_NamedResourcesRequest(ref), + "k8s.io/api/resource/v1alpha2.NamedResourcesResources": schema_k8sio_api_resource_v1alpha2_NamedResourcesResources(ref), + "k8s.io/api/resource/v1alpha2.NamedResourcesStringSlice": schema_k8sio_api_resource_v1alpha2_NamedResourcesStringSlice(ref), "k8s.io/api/resource/v1alpha2.NodeResourceModel": schema_k8sio_api_resource_v1alpha2_NodeResourceModel(ref), "k8s.io/api/resource/v1alpha2.NodeResourceSlice": schema_k8sio_api_resource_v1alpha2_NodeResourceSlice(ref), "k8s.io/api/resource/v1alpha2.NodeResourceSliceList": schema_k8sio_api_resource_v1alpha2_NodeResourceSliceList(ref), @@ -44733,8 +44742,18 @@ func schema_k8sio_api_resource_v1alpha2_AllocationResultModel(ref common.Referen SchemaProps: spec.SchemaProps{ Description: "AllocationResultModel must have one and only one field set.", Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "namedResources": { + SchemaProps: spec.SchemaProps{ + Description: "NamedResources describes the allocation result when using the named resources model.", + Ref: ref("k8s.io/api/resource/v1alpha2.NamedResourcesAllocationResult"), + }, + }, + }, }, }, + Dependencies: []string{ + "k8s.io/api/resource/v1alpha2.NamedResourcesAllocationResult"}, } } @@ -44751,11 +44770,17 @@ func schema_k8sio_api_resource_v1alpha2_DriverAllocationResult(ref common.Refere Ref: ref("k8s.io/apimachinery/pkg/runtime.RawExtension"), }, }, + "namedResources": { + SchemaProps: spec.SchemaProps{ + Description: "NamedResources describes the allocation result when using the named resources model.", + Ref: ref("k8s.io/api/resource/v1alpha2.NamedResourcesAllocationResult"), + }, + }, }, }, }, Dependencies: []string{ - "k8s.io/apimachinery/pkg/runtime.RawExtension"}, + "k8s.io/api/resource/v1alpha2.NamedResourcesAllocationResult", "k8s.io/apimachinery/pkg/runtime.RawExtension"}, } } @@ -44806,14 +44831,353 @@ func schema_k8sio_api_resource_v1alpha2_DriverRequests(ref common.ReferenceCallb } } +func schema_k8sio_api_resource_v1alpha2_NamedResourcesAllocationResult(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "NamedResourcesAllocationResult is used in AllocationResultModel.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Name is the name of the selected resource instance.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"name"}, + }, + }, + } +} + +func schema_k8sio_api_resource_v1alpha2_NamedResourcesAttribute(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "NamedResourcesAttribute is a combination of an attribute name and its value.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Name is unique identifier among all resource instances managed by the driver on the node. It must be a DNS subdomain.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "quantity": { + SchemaProps: spec.SchemaProps{ + Description: "QuantityValue is a quantity.", + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + }, + }, + "bool": { + SchemaProps: spec.SchemaProps{ + Description: "BoolValue is a true/false value.", + Type: []string{"boolean"}, + Format: "", + }, + }, + "int": { + SchemaProps: spec.SchemaProps{ + Description: "IntValue is a 64-bit integer.", + Type: []string{"integer"}, + Format: "int64", + }, + }, + "intSlice": { + SchemaProps: spec.SchemaProps{ + Description: "IntSliceValue is an array of 64-bit integers.", + Ref: ref("k8s.io/api/resource/v1alpha2.NamedResourcesIntSlice"), + }, + }, + "string": { + SchemaProps: spec.SchemaProps{ + Description: "StringValue is a string.", + Type: []string{"string"}, + Format: "", + }, + }, + "stringSlice": { + SchemaProps: spec.SchemaProps{ + Description: "StringSliceValue is an array of strings.", + Ref: ref("k8s.io/api/resource/v1alpha2.NamedResourcesStringSlice"), + }, + }, + }, + Required: []string{"name"}, + }, + }, + Dependencies: []string{ + "k8s.io/api/resource/v1alpha2.NamedResourcesIntSlice", "k8s.io/api/resource/v1alpha2.NamedResourcesStringSlice", "k8s.io/apimachinery/pkg/api/resource.Quantity"}, + } +} + +func schema_k8sio_api_resource_v1alpha2_NamedResourcesAttributeValue(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "NamedResourcesAttributeValue must have one and only one field set.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "quantity": { + SchemaProps: spec.SchemaProps{ + Description: "QuantityValue is a quantity.", + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + }, + }, + "bool": { + SchemaProps: spec.SchemaProps{ + Description: "BoolValue is a true/false value.", + Type: []string{"boolean"}, + Format: "", + }, + }, + "int": { + SchemaProps: spec.SchemaProps{ + Description: "IntValue is a 64-bit integer.", + Type: []string{"integer"}, + Format: "int64", + }, + }, + "intSlice": { + SchemaProps: spec.SchemaProps{ + Description: "IntSliceValue is an array of 64-bit integers.", + Ref: ref("k8s.io/api/resource/v1alpha2.NamedResourcesIntSlice"), + }, + }, + "string": { + SchemaProps: spec.SchemaProps{ + Description: "StringValue is a string.", + Type: []string{"string"}, + Format: "", + }, + }, + "stringSlice": { + SchemaProps: spec.SchemaProps{ + Description: "StringSliceValue is an array of strings.", + Ref: ref("k8s.io/api/resource/v1alpha2.NamedResourcesStringSlice"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "k8s.io/api/resource/v1alpha2.NamedResourcesIntSlice", "k8s.io/api/resource/v1alpha2.NamedResourcesStringSlice", "k8s.io/apimachinery/pkg/api/resource.Quantity"}, + } +} + +func schema_k8sio_api_resource_v1alpha2_NamedResourcesFilter(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "NamedResourcesFilter is used in ResourceFilterModel.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "selector": { + SchemaProps: spec.SchemaProps{ + Description: "Selector is a CEL expression which must evaluate to true if a resource instance is suitable. The language is as defined in https://kubernetes.io/docs/reference/using-api/cel/\n\nIn addition, for each type NamedResourcesin AttributeValue there is a map that resolves to the corresponding value of the instance under evaluation. For example:\n\n attributes.quantity[\"a\"].isGreaterThan(quantity(\"0\")) &&\n attributes.stringslice[\"b\"].isSorted()", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"selector"}, + }, + }, + } +} + +func schema_k8sio_api_resource_v1alpha2_NamedResourcesInstance(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "NamedResourcesInstance represents one individual hardware instance that can be selected based on its attributes.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Name is unique identifier among all resource instances managed by the driver on the node. It must be a DNS subdomain.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "attributes": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Attributes defines the attributes of this resource instance. The name of each attribute must be unique.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/resource/v1alpha2.NamedResourcesAttribute"), + }, + }, + }, + }, + }, + }, + Required: []string{"name"}, + }, + }, + Dependencies: []string{ + "k8s.io/api/resource/v1alpha2.NamedResourcesAttribute"}, + } +} + +func schema_k8sio_api_resource_v1alpha2_NamedResourcesIntSlice(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "NamedResourcesIntSlice contains a slice of 64-bit integers.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "ints": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Ints is the slice of 64-bit integers.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + }, + }, + }, + }, + Required: []string{"ints"}, + }, + }, + } +} + +func schema_k8sio_api_resource_v1alpha2_NamedResourcesRequest(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "NamedResourcesRequest is used in ResourceRequestModel.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "selector": { + SchemaProps: spec.SchemaProps{ + Description: "Selector is a CEL expression which must evaluate to true if a resource instance is suitable. The language is as defined in https://kubernetes.io/docs/reference/using-api/cel/\n\nIn addition, for each type NamedResourcesin AttributeValue there is a map that resolves to the corresponding value of the instance under evaluation. For example:\n\n attributes.quantity[\"a\"].isGreaterThan(quantity(\"0\")) &&\n attributes.stringslice[\"b\"].isSorted()", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"selector"}, + }, + }, + } +} + +func schema_k8sio_api_resource_v1alpha2_NamedResourcesResources(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "NamedResourcesResources is used in NodeResourceModel.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "instances": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "The list of all individual resources instances currently available.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/resource/v1alpha2.NamedResourcesInstance"), + }, + }, + }, + }, + }, + }, + Required: []string{"instances"}, + }, + }, + Dependencies: []string{ + "k8s.io/api/resource/v1alpha2.NamedResourcesInstance"}, + } +} + +func schema_k8sio_api_resource_v1alpha2_NamedResourcesStringSlice(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "NamedResourcesStringSlice contains a slice of strings.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "strings": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Strings is the slice of strings.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + }, + Required: []string{"strings"}, + }, + }, + } +} + func schema_k8sio_api_resource_v1alpha2_NodeResourceModel(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ Description: "NodeResourceModel must have one and only one field set.", Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "namedResources": { + SchemaProps: spec.SchemaProps{ + Description: "NamedResources describes available resources using the named resources model.", + Ref: ref("k8s.io/api/resource/v1alpha2.NamedResourcesResources"), + }, + }, + }, }, }, + Dependencies: []string{ + "k8s.io/api/resource/v1alpha2.NamedResourcesResources"}, } } @@ -44861,12 +45225,18 @@ func schema_k8sio_api_resource_v1alpha2_NodeResourceSlice(ref common.ReferenceCa Format: "", }, }, + "namedResources": { + SchemaProps: spec.SchemaProps{ + Description: "NamedResources describes available resources using the named resources model.", + Ref: ref("k8s.io/api/resource/v1alpha2.NamedResourcesResources"), + }, + }, }, Required: []string{"nodeName", "driverName"}, }, }, Dependencies: []string{ - "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + "k8s.io/api/resource/v1alpha2.NamedResourcesResources", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, } } @@ -45968,9 +46338,17 @@ func schema_k8sio_api_resource_v1alpha2_ResourceFilter(ref common.ReferenceCallb Format: "", }, }, + "namedResources": { + SchemaProps: spec.SchemaProps{ + Description: "NamedResources describes a resource filter using the named resources model.", + Ref: ref("k8s.io/api/resource/v1alpha2.NamedResourcesFilter"), + }, + }, }, }, }, + Dependencies: []string{ + "k8s.io/api/resource/v1alpha2.NamedResourcesFilter"}, } } @@ -45980,8 +46358,18 @@ func schema_k8sio_api_resource_v1alpha2_ResourceFilterModel(ref common.Reference SchemaProps: spec.SchemaProps{ Description: "ResourceFilterModel must have one and only one field set.", Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "namedResources": { + SchemaProps: spec.SchemaProps{ + Description: "NamedResources describes a resource filter using the named resources model.", + Ref: ref("k8s.io/api/resource/v1alpha2.NamedResourcesFilter"), + }, + }, + }, }, }, + Dependencies: []string{ + "k8s.io/api/resource/v1alpha2.NamedResourcesFilter"}, } } @@ -46033,11 +46421,17 @@ func schema_k8sio_api_resource_v1alpha2_ResourceRequest(ref common.ReferenceCall Ref: ref("k8s.io/apimachinery/pkg/runtime.RawExtension"), }, }, + "namedResources": { + SchemaProps: spec.SchemaProps{ + Description: "NamedResources describes a request for resources with the named resources model.", + Ref: ref("k8s.io/api/resource/v1alpha2.NamedResourcesRequest"), + }, + }, }, }, }, Dependencies: []string{ - "k8s.io/apimachinery/pkg/runtime.RawExtension"}, + "k8s.io/api/resource/v1alpha2.NamedResourcesRequest", "k8s.io/apimachinery/pkg/runtime.RawExtension"}, } } @@ -46047,8 +46441,18 @@ func schema_k8sio_api_resource_v1alpha2_ResourceRequestModel(ref common.Referenc SchemaProps: spec.SchemaProps{ Description: "ResourceRequestModel must have one and only one field set.", Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "namedResources": { + SchemaProps: spec.SchemaProps{ + Description: "NamedResources describes a request for resources with the named resources model.", + Ref: ref("k8s.io/api/resource/v1alpha2.NamedResourcesRequest"), + }, + }, + }, }, }, + Dependencies: []string{ + "k8s.io/api/resource/v1alpha2.NamedResourcesRequest"}, } } diff --git a/pkg/registry/resource/noderesourceslice/storage/storage_test.go b/pkg/registry/resource/noderesourceslice/storage/storage_test.go index c4ef982b430..db88974bf0d 100644 --- a/pkg/registry/resource/noderesourceslice/storage/storage_test.go +++ b/pkg/registry/resource/noderesourceslice/storage/storage_test.go @@ -53,6 +53,9 @@ func validNewNodeResourceSlice(name string) *resource.NodeResourceSlice { }, NodeName: name, DriverName: "cdi.example.com", + NodeResourceModel: resource.NodeResourceModel{ + NamedResources: &resource.NamedResourcesResources{}, + }, } } diff --git a/pkg/registry/resource/noderesourceslice/strategy_test.go b/pkg/registry/resource/noderesourceslice/strategy_test.go index 56a6e0e9bb0..1e84c1905bb 100644 --- a/pkg/registry/resource/noderesourceslice/strategy_test.go +++ b/pkg/registry/resource/noderesourceslice/strategy_test.go @@ -30,6 +30,9 @@ var slice = &resource.NodeResourceSlice{ }, NodeName: "valid-node-name", DriverName: "testdriver.example.com", + NodeResourceModel: resource.NodeResourceModel{ + NamedResources: &resource.NamedResourcesResources{}, + }, } func TestClassStrategy(t *testing.T) { diff --git a/pkg/registry/resource/resourceclassparameters/storage/storage_test.go b/pkg/registry/resource/resourceclassparameters/storage/storage_test.go index 40fd3e5ed17..83e95449441 100644 --- a/pkg/registry/resource/resourceclassparameters/storage/storage_test.go +++ b/pkg/registry/resource/resourceclassparameters/storage/storage_test.go @@ -46,8 +46,8 @@ func newStorage(t *testing.T) (*REST, *etcd3testing.EtcdTestServer) { return resourceClassStorage, server } -func validNewResourceClaimParameters(name string) *resource.ResourceClaimParameters { - return &resource.ResourceClaimParameters{ +func validNewResourceClassParameters(name string) *resource.ResourceClassParameters { + return &resource.ResourceClassParameters{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: metav1.NamespaceDefault, @@ -60,13 +60,13 @@ func TestCreate(t *testing.T) { defer server.Terminate(t) defer storage.Store.DestroyFunc() test := genericregistrytest.New(t, storage.Store) - resourceClass := validNewResourceClaimParameters("foo") + resourceClass := validNewResourceClassParameters("foo") resourceClass.ObjectMeta = metav1.ObjectMeta{} test.TestCreate( // valid resourceClass, // invalid - &resource.ResourceClaimParameters{ + &resource.ResourceClassParameters{ ObjectMeta: metav1.ObjectMeta{Name: "*BadName!"}, }, ) @@ -79,16 +79,16 @@ func TestUpdate(t *testing.T) { test := genericregistrytest.New(t, storage.Store) test.TestUpdate( // valid - validNewResourceClaimParameters("foo"), + validNewResourceClassParameters("foo"), // updateFunc func(obj runtime.Object) runtime.Object { - object := obj.(*resource.ResourceClaimParameters) + object := obj.(*resource.ResourceClassParameters) object.Labels = map[string]string{"foo": "bar"} return object }, // invalid update func(obj runtime.Object) runtime.Object { - object := obj.(*resource.ResourceClaimParameters) + object := obj.(*resource.ResourceClassParameters) object.Labels = map[string]string{"&$^^#%@": "1"} return object }, @@ -101,7 +101,7 @@ func TestDelete(t *testing.T) { defer server.Terminate(t) defer storage.Store.DestroyFunc() test := genericregistrytest.New(t, storage.Store).ReturnDeletedObject() - test.TestDelete(validNewResourceClaimParameters("foo")) + test.TestDelete(validNewResourceClassParameters("foo")) } func TestGet(t *testing.T) { @@ -109,7 +109,7 @@ func TestGet(t *testing.T) { defer server.Terminate(t) defer storage.Store.DestroyFunc() test := genericregistrytest.New(t, storage.Store) - test.TestGet(validNewResourceClaimParameters("foo")) + test.TestGet(validNewResourceClassParameters("foo")) } func TestList(t *testing.T) { @@ -117,7 +117,7 @@ func TestList(t *testing.T) { defer server.Terminate(t) defer storage.Store.DestroyFunc() test := genericregistrytest.New(t, storage.Store) - test.TestList(validNewResourceClaimParameters("foo")) + test.TestList(validNewResourceClassParameters("foo")) } func TestWatch(t *testing.T) { @@ -126,7 +126,7 @@ func TestWatch(t *testing.T) { defer storage.Store.DestroyFunc() test := genericregistrytest.New(t, storage.Store) test.TestWatch( - validNewResourceClaimParameters("foo"), + validNewResourceClassParameters("foo"), // matching labels []labels.Set{}, // not matching labels diff --git a/pkg/scheduler/framework/plugins/dynamicresources/structured/namedresources/namedresourcesmodel.go b/pkg/scheduler/framework/plugins/dynamicresources/structured/namedresources/namedresourcesmodel.go new file mode 100644 index 00000000000..08ba8a32dd6 --- /dev/null +++ b/pkg/scheduler/framework/plugins/dynamicresources/structured/namedresources/namedresourcesmodel.go @@ -0,0 +1,150 @@ +/* +Copyright 2024 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 namedresources + +import ( + "context" + "errors" + "fmt" + "slices" + + resourceapi "k8s.io/api/resource/v1alpha2" + "k8s.io/apiserver/pkg/cel/environment" + "k8s.io/dynamic-resource-allocation/structured/namedresources/cel" +) + +type Model struct { + instances []instanceAllocation +} + +type instanceAllocation struct { + allocated bool + instance *resourceapi.NamedResourcesInstance +} + +// AddResources must be called first to create entries for all existing +// resource instances. The resources parameter may be nil. +func AddResources(m *Model, resources *resourceapi.NamedResourcesResources) { + if resources == nil { + return + } + + for i := range resources.Instances { + m.instances = append(m.instances, instanceAllocation{instance: &resources.Instances[i]}) + } +} + +// AddAllocation may get called after AddResources to mark some resource +// instances as allocated. The result parameter may be nil. +func AddAllocation(m *Model, result *resourceapi.NamedResourcesAllocationResult) { + if result == nil { + return + } + for i := range m.instances { + if m.instances[i].instance.Name == result.Name { + m.instances[i].allocated = true + break + } + } +} + +func NewClaimController(filter *resourceapi.NamedResourcesFilter, requests []*resourceapi.NamedResourcesRequest) (*Controller, error) { + c := &Controller{} + if filter != nil { + compilation := cel.Compiler.CompileCELExpression(filter.Selector, environment.StoredExpressions) + if compilation.Error != nil { + // Shouldn't happen because of validation. + return nil, fmt.Errorf("compile class filter CEL expression: %w", compilation.Error) + } + c.filter = &compilation + } + for _, request := range requests { + compilation := cel.Compiler.CompileCELExpression(request.Selector, environment.StoredExpressions) + if compilation.Error != nil { + // Shouldn't happen because of validation. + return nil, fmt.Errorf("compile request CEL expression: %w", compilation.Error) + } + c.requests = append(c.requests, compilation) + } + return c, nil +} + +type Controller struct { + filter *cel.CompilationResult + requests []cel.CompilationResult +} + +func (c *Controller) NodeIsSuitable(ctx context.Context, model Model) (bool, error) { + indices, err := c.allocate(ctx, model) + return len(indices) == len(c.requests), err +} + +func (c *Controller) Allocate(ctx context.Context, model Model) ([]*resourceapi.NamedResourcesAllocationResult, error) { + indices, err := c.allocate(ctx, model) + if err != nil { + return nil, err + } + if len(indices) != len(c.requests) { + return nil, errors.New("insufficient resources") + } + results := make([]*resourceapi.NamedResourcesAllocationResult, len(c.requests)) + for i := range c.requests { + results[i] = &resourceapi.NamedResourcesAllocationResult{Name: model.instances[indices[i]].instance.Name} + } + return results, nil +} + +func (c *Controller) allocate(ctx context.Context, model Model) ([]int, error) { + // Shallow copy, we need to modify the allocated boolean. + instances := slices.Clone(model.instances) + indices := make([]int, 0, len(c.requests)) + + for _, request := range c.requests { + for i, instance := range instances { + if instance.allocated { + continue + } + if c.filter != nil { + okay, err := c.filter.Evaluate(ctx, instance.instance.Attributes) + if err != nil { + return nil, fmt.Errorf("evaluate filter CEL expression: %w", err) + } + if !okay { + continue + } + } + okay, err := request.Evaluate(ctx, instance.instance.Attributes) + if err != nil { + return nil, fmt.Errorf("evaluate request CEL expression: %w", err) + } + if !okay { + continue + } + // Found a matching, unallocated instance. Let's use it. + // + // A more thorough search would include backtracking because + // allocating one "large" instances for a "small" request may + // make a following "large" request impossible to satisfy when + // only "small" instances are left. + instances[i].allocated = true + indices = append(indices, i) + break + } + } + return indices, nil + +} diff --git a/pkg/scheduler/framework/plugins/dynamicresources/structuredparameters.go b/pkg/scheduler/framework/plugins/dynamicresources/structuredparameters.go index e8a5d0a4522..72ae918b669 100644 --- a/pkg/scheduler/framework/plugins/dynamicresources/structuredparameters.go +++ b/pkg/scheduler/framework/plugins/dynamicresources/structuredparameters.go @@ -23,8 +23,10 @@ import ( v1 "k8s.io/api/core/v1" resourcev1alpha2 "k8s.io/api/resource/v1alpha2" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" resourcev1alpha2listers "k8s.io/client-go/listers/resource/v1alpha2" "k8s.io/klog/v2" + namedresourcesmodel "k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/structured/namedresources" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding" ) @@ -35,7 +37,7 @@ type resources map[string]map[string]resourceModels // resourceModels may have more than one entry because it is valid for a driver to // use more than one structured parameter model. type resourceModels struct { - // TODO: add some structured parameter model + namedresources namedresourcesmodel.Model } // newResourceModel parses the available information about resources. Objects @@ -54,7 +56,7 @@ func newResourceModel(logger klog.Logger, nodeResourceSliceLister resourcev1alph model[slice.NodeName] = make(map[string]resourceModels) } resource := model[slice.NodeName][slice.DriverName] - // TODO: add some structured parameter model + namedresourcesmodel.AddResources(&resource.namedresources, slice.NamedResources) model[slice.NodeName][slice.DriverName] = resource } @@ -75,11 +77,11 @@ func newResourceModel(logger klog.Logger, nodeResourceSliceLister resourcev1alph if model[structured.NodeName] == nil { model[structured.NodeName] = make(map[string]resourceModels) } - // resource := model[structured.NodeName][handle.DriverName] - // TODO: add some structured parameter model - // for _, result := range structured.Results { - // // Call AddAllocation for each known model. Each call itself needs to check for nil. - // } + resource := model[structured.NodeName][handle.DriverName] + for _, result := range structured.Results { + // Call AddAllocation for each known model. Each call itself needs to check for nil. + namedresourcesmodel.AddAllocation(&resource.namedresources, result.NamedResources) + } } } @@ -90,12 +92,52 @@ func newClaimController(logger klog.Logger, class *resourcev1alpha2.ResourceClas // Each node driver is separate from the others. Each driver may have // multiple requests which need to be allocated together, so here // we have to collect them per model. - // TODO: implement some structured parameters model + type perDriverRequests struct { + parameters []runtime.RawExtension + requests []*resourcev1alpha2.NamedResourcesRequest + } + namedresourcesRequests := make(map[string]perDriverRequests) + for i, request := range claimParameters.DriverRequests { + driverName := request.DriverName + p := namedresourcesRequests[driverName] + for e, request := range request.Requests { + switch { + case request.ResourceRequestModel.NamedResources != nil: + p.parameters = append(p.parameters, request.VendorParameters) + p.requests = append(p.requests, request.ResourceRequestModel.NamedResources) + default: + return nil, fmt.Errorf("claim parameters %s: driverRequersts[%d].requests[%d]: no supported structured parameters found", klog.KObj(claimParameters), i, e) + } + } + if len(p.requests) > 0 { + namedresourcesRequests[driverName] = p + } + } c := &claimController{ class: class, classParameters: classParameters, claimParameters: claimParameters, + namedresources: make(map[string]perDriverController, len(namedresourcesRequests)), + } + for driverName, perDriver := range namedresourcesRequests { + var filter *resourcev1alpha2.NamedResourcesFilter + if classParameters != nil { + for _, f := range classParameters.Filters { + if f.DriverName == driverName && f.ResourceFilterModel.NamedResources != nil { + filter = f.ResourceFilterModel.NamedResources + break + } + } + } + controller, err := namedresourcesmodel.NewClaimController(filter, perDriver.requests) + if err != nil { + return nil, fmt.Errorf("creating claim controller for named resources structured model: %w", err) + } + c.namedresources[driverName] = perDriverController{ + parameters: perDriver.parameters, + controller: controller, + } } return c, nil } @@ -106,11 +148,28 @@ type claimController struct { class *resourcev1alpha2.ResourceClass classParameters *resourcev1alpha2.ResourceClassParameters claimParameters *resourcev1alpha2.ResourceClaimParameters - // TODO: implement some structured parameters model + namedresources map[string]perDriverController +} + +type perDriverController struct { + parameters []runtime.RawExtension + controller *namedresourcesmodel.Controller } func (c claimController) nodeIsSuitable(ctx context.Context, nodeName string, resources resources) (bool, error) { - // TODO: implement some structured parameters model + nodeResources := resources[nodeName] + for driverName, perDriver := range c.namedresources { + okay, err := perDriver.controller.NodeIsSuitable(ctx, nodeResources[driverName].namedresources) + if err != nil { + // This is an error in the CEL expression which needs + // to be fixed. Better fail very visibly instead of + // ignoring the node. + return false, fmt.Errorf("checking node %q and resources of driver %q: %w", nodeName, driverName, err) + } + if !okay { + return false, nil + } + } return true, nil } @@ -128,7 +187,49 @@ func (c claimController) allocate(ctx context.Context, nodeName string, resource }, } - // TODO: implement some structured parameters model + nodeResources := resources[nodeName] + for driverName, perDriver := range c.namedresources { + // Must return one entry for each request. The entry may be nil. This way, + // the result can be correlated with the per-request parameters. + results, err := perDriver.controller.Allocate(ctx, nodeResources[driverName].namedresources) + if err != nil { + return "", nil, fmt.Errorf("allocating via named resources structured model: %w", err) + } + handle := resourcev1alpha2.ResourceHandle{ + DriverName: driverName, + StructuredData: &resourcev1alpha2.StructuredResourceHandle{ + NodeName: nodeName, + }, + } + for i, result := range results { + if result == nil { + continue + } + handle.StructuredData.Results = append(handle.StructuredData.Results, + resourcev1alpha2.DriverAllocationResult{ + VendorRequestParameters: perDriver.parameters[i], + AllocationResultModel: resourcev1alpha2.AllocationResultModel{ + NamedResources: result, + }, + }, + ) + } + if c.classParameters != nil { + for _, p := range c.classParameters.VendorParameters { + if p.DriverName == driverName { + handle.StructuredData.VendorClassParameters = p.Parameters + break + } + } + } + for _, request := range c.claimParameters.DriverRequests { + if request.DriverName == driverName { + handle.StructuredData.VendorClaimParameters = request.VendorParameters + break + } + } + allocation.ResourceHandles = append(allocation.ResourceHandles, handle) + } return c.class.DriverName, allocation, nil } diff --git a/staging/publishing/import-restrictions.yaml b/staging/publishing/import-restrictions.yaml index 517af45de7e..b6a18b67c68 100644 --- a/staging/publishing/import-restrictions.yaml +++ b/staging/publishing/import-restrictions.yaml @@ -250,6 +250,9 @@ allowedImports: - k8s.io/api - k8s.io/apimachinery + - k8s.io/apiserver/pkg/apis/cel + - k8s.io/apiserver/pkg/cel + - k8s.io/apiserver/pkg/cel/environment - k8s.io/client-go - k8s.io/dynamic-resource-allocation - k8s.io/klog diff --git a/staging/publishing/rules.yaml b/staging/publishing/rules.yaml index cc2f8426eb6..2c321480bcc 100644 --- a/staging/publishing/rules.yaml +++ b/staging/publishing/rules.yaml @@ -2265,6 +2265,8 @@ rules: branch: master - repository: component-base branch: master + - repository: kms + branch: master - repository: kubelet branch: master source: diff --git a/staging/src/k8s.io/api/resource/v1alpha2/generated.pb.go b/staging/src/k8s.io/api/resource/v1alpha2/generated.pb.go index c40cd0ff88a..82fb3c0f1c6 100644 --- a/staging/src/k8s.io/api/resource/v1alpha2/generated.pb.go +++ b/staging/src/k8s.io/api/resource/v1alpha2/generated.pb.go @@ -26,6 +26,7 @@ import ( proto "github.com/gogo/protobuf/proto" v1 "k8s.io/api/core/v1" + resource "k8s.io/apimachinery/pkg/api/resource" math "math" math_bits "math/bits" @@ -158,10 +159,262 @@ func (m *DriverRequests) XXX_DiscardUnknown() { var xxx_messageInfo_DriverRequests proto.InternalMessageInfo +func (m *NamedResourcesAllocationResult) Reset() { *m = NamedResourcesAllocationResult{} } +func (*NamedResourcesAllocationResult) ProtoMessage() {} +func (*NamedResourcesAllocationResult) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{4} +} +func (m *NamedResourcesAllocationResult) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NamedResourcesAllocationResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *NamedResourcesAllocationResult) XXX_Merge(src proto.Message) { + xxx_messageInfo_NamedResourcesAllocationResult.Merge(m, src) +} +func (m *NamedResourcesAllocationResult) XXX_Size() int { + return m.Size() +} +func (m *NamedResourcesAllocationResult) XXX_DiscardUnknown() { + xxx_messageInfo_NamedResourcesAllocationResult.DiscardUnknown(m) +} + +var xxx_messageInfo_NamedResourcesAllocationResult proto.InternalMessageInfo + +func (m *NamedResourcesAttribute) Reset() { *m = NamedResourcesAttribute{} } +func (*NamedResourcesAttribute) ProtoMessage() {} +func (*NamedResourcesAttribute) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{5} +} +func (m *NamedResourcesAttribute) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NamedResourcesAttribute) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *NamedResourcesAttribute) XXX_Merge(src proto.Message) { + xxx_messageInfo_NamedResourcesAttribute.Merge(m, src) +} +func (m *NamedResourcesAttribute) XXX_Size() int { + return m.Size() +} +func (m *NamedResourcesAttribute) XXX_DiscardUnknown() { + xxx_messageInfo_NamedResourcesAttribute.DiscardUnknown(m) +} + +var xxx_messageInfo_NamedResourcesAttribute proto.InternalMessageInfo + +func (m *NamedResourcesAttributeValue) Reset() { *m = NamedResourcesAttributeValue{} } +func (*NamedResourcesAttributeValue) ProtoMessage() {} +func (*NamedResourcesAttributeValue) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{6} +} +func (m *NamedResourcesAttributeValue) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NamedResourcesAttributeValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *NamedResourcesAttributeValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_NamedResourcesAttributeValue.Merge(m, src) +} +func (m *NamedResourcesAttributeValue) XXX_Size() int { + return m.Size() +} +func (m *NamedResourcesAttributeValue) XXX_DiscardUnknown() { + xxx_messageInfo_NamedResourcesAttributeValue.DiscardUnknown(m) +} + +var xxx_messageInfo_NamedResourcesAttributeValue proto.InternalMessageInfo + +func (m *NamedResourcesFilter) Reset() { *m = NamedResourcesFilter{} } +func (*NamedResourcesFilter) ProtoMessage() {} +func (*NamedResourcesFilter) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{7} +} +func (m *NamedResourcesFilter) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NamedResourcesFilter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *NamedResourcesFilter) XXX_Merge(src proto.Message) { + xxx_messageInfo_NamedResourcesFilter.Merge(m, src) +} +func (m *NamedResourcesFilter) XXX_Size() int { + return m.Size() +} +func (m *NamedResourcesFilter) XXX_DiscardUnknown() { + xxx_messageInfo_NamedResourcesFilter.DiscardUnknown(m) +} + +var xxx_messageInfo_NamedResourcesFilter proto.InternalMessageInfo + +func (m *NamedResourcesInstance) Reset() { *m = NamedResourcesInstance{} } +func (*NamedResourcesInstance) ProtoMessage() {} +func (*NamedResourcesInstance) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{8} +} +func (m *NamedResourcesInstance) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NamedResourcesInstance) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *NamedResourcesInstance) XXX_Merge(src proto.Message) { + xxx_messageInfo_NamedResourcesInstance.Merge(m, src) +} +func (m *NamedResourcesInstance) XXX_Size() int { + return m.Size() +} +func (m *NamedResourcesInstance) XXX_DiscardUnknown() { + xxx_messageInfo_NamedResourcesInstance.DiscardUnknown(m) +} + +var xxx_messageInfo_NamedResourcesInstance proto.InternalMessageInfo + +func (m *NamedResourcesIntSlice) Reset() { *m = NamedResourcesIntSlice{} } +func (*NamedResourcesIntSlice) ProtoMessage() {} +func (*NamedResourcesIntSlice) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{9} +} +func (m *NamedResourcesIntSlice) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NamedResourcesIntSlice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *NamedResourcesIntSlice) XXX_Merge(src proto.Message) { + xxx_messageInfo_NamedResourcesIntSlice.Merge(m, src) +} +func (m *NamedResourcesIntSlice) XXX_Size() int { + return m.Size() +} +func (m *NamedResourcesIntSlice) XXX_DiscardUnknown() { + xxx_messageInfo_NamedResourcesIntSlice.DiscardUnknown(m) +} + +var xxx_messageInfo_NamedResourcesIntSlice proto.InternalMessageInfo + +func (m *NamedResourcesRequest) Reset() { *m = NamedResourcesRequest{} } +func (*NamedResourcesRequest) ProtoMessage() {} +func (*NamedResourcesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{10} +} +func (m *NamedResourcesRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NamedResourcesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *NamedResourcesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_NamedResourcesRequest.Merge(m, src) +} +func (m *NamedResourcesRequest) XXX_Size() int { + return m.Size() +} +func (m *NamedResourcesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_NamedResourcesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_NamedResourcesRequest proto.InternalMessageInfo + +func (m *NamedResourcesResources) Reset() { *m = NamedResourcesResources{} } +func (*NamedResourcesResources) ProtoMessage() {} +func (*NamedResourcesResources) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{11} +} +func (m *NamedResourcesResources) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NamedResourcesResources) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *NamedResourcesResources) XXX_Merge(src proto.Message) { + xxx_messageInfo_NamedResourcesResources.Merge(m, src) +} +func (m *NamedResourcesResources) XXX_Size() int { + return m.Size() +} +func (m *NamedResourcesResources) XXX_DiscardUnknown() { + xxx_messageInfo_NamedResourcesResources.DiscardUnknown(m) +} + +var xxx_messageInfo_NamedResourcesResources proto.InternalMessageInfo + +func (m *NamedResourcesStringSlice) Reset() { *m = NamedResourcesStringSlice{} } +func (*NamedResourcesStringSlice) ProtoMessage() {} +func (*NamedResourcesStringSlice) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{12} +} +func (m *NamedResourcesStringSlice) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NamedResourcesStringSlice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *NamedResourcesStringSlice) XXX_Merge(src proto.Message) { + xxx_messageInfo_NamedResourcesStringSlice.Merge(m, src) +} +func (m *NamedResourcesStringSlice) XXX_Size() int { + return m.Size() +} +func (m *NamedResourcesStringSlice) XXX_DiscardUnknown() { + xxx_messageInfo_NamedResourcesStringSlice.DiscardUnknown(m) +} + +var xxx_messageInfo_NamedResourcesStringSlice proto.InternalMessageInfo + func (m *NodeResourceModel) Reset() { *m = NodeResourceModel{} } func (*NodeResourceModel) ProtoMessage() {} func (*NodeResourceModel) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{4} + return fileDescriptor_4312f5b44a31ec02, []int{13} } func (m *NodeResourceModel) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -189,7 +442,7 @@ var xxx_messageInfo_NodeResourceModel proto.InternalMessageInfo func (m *NodeResourceSlice) Reset() { *m = NodeResourceSlice{} } func (*NodeResourceSlice) ProtoMessage() {} func (*NodeResourceSlice) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{5} + return fileDescriptor_4312f5b44a31ec02, []int{14} } func (m *NodeResourceSlice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -217,7 +470,7 @@ var xxx_messageInfo_NodeResourceSlice proto.InternalMessageInfo func (m *NodeResourceSliceList) Reset() { *m = NodeResourceSliceList{} } func (*NodeResourceSliceList) ProtoMessage() {} func (*NodeResourceSliceList) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{6} + return fileDescriptor_4312f5b44a31ec02, []int{15} } func (m *NodeResourceSliceList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -245,7 +498,7 @@ var xxx_messageInfo_NodeResourceSliceList proto.InternalMessageInfo func (m *PodSchedulingContext) Reset() { *m = PodSchedulingContext{} } func (*PodSchedulingContext) ProtoMessage() {} func (*PodSchedulingContext) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{7} + return fileDescriptor_4312f5b44a31ec02, []int{16} } func (m *PodSchedulingContext) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -273,7 +526,7 @@ var xxx_messageInfo_PodSchedulingContext proto.InternalMessageInfo func (m *PodSchedulingContextList) Reset() { *m = PodSchedulingContextList{} } func (*PodSchedulingContextList) ProtoMessage() {} func (*PodSchedulingContextList) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{8} + return fileDescriptor_4312f5b44a31ec02, []int{17} } func (m *PodSchedulingContextList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -301,7 +554,7 @@ var xxx_messageInfo_PodSchedulingContextList proto.InternalMessageInfo func (m *PodSchedulingContextSpec) Reset() { *m = PodSchedulingContextSpec{} } func (*PodSchedulingContextSpec) ProtoMessage() {} func (*PodSchedulingContextSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{9} + return fileDescriptor_4312f5b44a31ec02, []int{18} } func (m *PodSchedulingContextSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -329,7 +582,7 @@ var xxx_messageInfo_PodSchedulingContextSpec proto.InternalMessageInfo func (m *PodSchedulingContextStatus) Reset() { *m = PodSchedulingContextStatus{} } func (*PodSchedulingContextStatus) ProtoMessage() {} func (*PodSchedulingContextStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{10} + return fileDescriptor_4312f5b44a31ec02, []int{19} } func (m *PodSchedulingContextStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -357,7 +610,7 @@ var xxx_messageInfo_PodSchedulingContextStatus proto.InternalMessageInfo func (m *ResourceClaim) Reset() { *m = ResourceClaim{} } func (*ResourceClaim) ProtoMessage() {} func (*ResourceClaim) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{11} + return fileDescriptor_4312f5b44a31ec02, []int{20} } func (m *ResourceClaim) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -385,7 +638,7 @@ var xxx_messageInfo_ResourceClaim proto.InternalMessageInfo func (m *ResourceClaimConsumerReference) Reset() { *m = ResourceClaimConsumerReference{} } func (*ResourceClaimConsumerReference) ProtoMessage() {} func (*ResourceClaimConsumerReference) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{12} + return fileDescriptor_4312f5b44a31ec02, []int{21} } func (m *ResourceClaimConsumerReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -413,7 +666,7 @@ var xxx_messageInfo_ResourceClaimConsumerReference proto.InternalMessageInfo func (m *ResourceClaimList) Reset() { *m = ResourceClaimList{} } func (*ResourceClaimList) ProtoMessage() {} func (*ResourceClaimList) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{13} + return fileDescriptor_4312f5b44a31ec02, []int{22} } func (m *ResourceClaimList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -441,7 +694,7 @@ var xxx_messageInfo_ResourceClaimList proto.InternalMessageInfo func (m *ResourceClaimParameters) Reset() { *m = ResourceClaimParameters{} } func (*ResourceClaimParameters) ProtoMessage() {} func (*ResourceClaimParameters) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{14} + return fileDescriptor_4312f5b44a31ec02, []int{23} } func (m *ResourceClaimParameters) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -469,7 +722,7 @@ var xxx_messageInfo_ResourceClaimParameters proto.InternalMessageInfo func (m *ResourceClaimParametersList) Reset() { *m = ResourceClaimParametersList{} } func (*ResourceClaimParametersList) ProtoMessage() {} func (*ResourceClaimParametersList) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{15} + return fileDescriptor_4312f5b44a31ec02, []int{24} } func (m *ResourceClaimParametersList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -497,7 +750,7 @@ var xxx_messageInfo_ResourceClaimParametersList proto.InternalMessageInfo func (m *ResourceClaimParametersReference) Reset() { *m = ResourceClaimParametersReference{} } func (*ResourceClaimParametersReference) ProtoMessage() {} func (*ResourceClaimParametersReference) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{16} + return fileDescriptor_4312f5b44a31ec02, []int{25} } func (m *ResourceClaimParametersReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -525,7 +778,7 @@ var xxx_messageInfo_ResourceClaimParametersReference proto.InternalMessageInfo func (m *ResourceClaimSchedulingStatus) Reset() { *m = ResourceClaimSchedulingStatus{} } func (*ResourceClaimSchedulingStatus) ProtoMessage() {} func (*ResourceClaimSchedulingStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{17} + return fileDescriptor_4312f5b44a31ec02, []int{26} } func (m *ResourceClaimSchedulingStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -553,7 +806,7 @@ var xxx_messageInfo_ResourceClaimSchedulingStatus proto.InternalMessageInfo func (m *ResourceClaimSpec) Reset() { *m = ResourceClaimSpec{} } func (*ResourceClaimSpec) ProtoMessage() {} func (*ResourceClaimSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{18} + return fileDescriptor_4312f5b44a31ec02, []int{27} } func (m *ResourceClaimSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -581,7 +834,7 @@ var xxx_messageInfo_ResourceClaimSpec proto.InternalMessageInfo func (m *ResourceClaimStatus) Reset() { *m = ResourceClaimStatus{} } func (*ResourceClaimStatus) ProtoMessage() {} func (*ResourceClaimStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{19} + return fileDescriptor_4312f5b44a31ec02, []int{28} } func (m *ResourceClaimStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -609,7 +862,7 @@ var xxx_messageInfo_ResourceClaimStatus proto.InternalMessageInfo func (m *ResourceClaimTemplate) Reset() { *m = ResourceClaimTemplate{} } func (*ResourceClaimTemplate) ProtoMessage() {} func (*ResourceClaimTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{20} + return fileDescriptor_4312f5b44a31ec02, []int{29} } func (m *ResourceClaimTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -637,7 +890,7 @@ var xxx_messageInfo_ResourceClaimTemplate proto.InternalMessageInfo func (m *ResourceClaimTemplateList) Reset() { *m = ResourceClaimTemplateList{} } func (*ResourceClaimTemplateList) ProtoMessage() {} func (*ResourceClaimTemplateList) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{21} + return fileDescriptor_4312f5b44a31ec02, []int{30} } func (m *ResourceClaimTemplateList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -665,7 +918,7 @@ var xxx_messageInfo_ResourceClaimTemplateList proto.InternalMessageInfo func (m *ResourceClaimTemplateSpec) Reset() { *m = ResourceClaimTemplateSpec{} } func (*ResourceClaimTemplateSpec) ProtoMessage() {} func (*ResourceClaimTemplateSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{22} + return fileDescriptor_4312f5b44a31ec02, []int{31} } func (m *ResourceClaimTemplateSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -693,7 +946,7 @@ var xxx_messageInfo_ResourceClaimTemplateSpec proto.InternalMessageInfo func (m *ResourceClass) Reset() { *m = ResourceClass{} } func (*ResourceClass) ProtoMessage() {} func (*ResourceClass) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{23} + return fileDescriptor_4312f5b44a31ec02, []int{32} } func (m *ResourceClass) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -721,7 +974,7 @@ var xxx_messageInfo_ResourceClass proto.InternalMessageInfo func (m *ResourceClassList) Reset() { *m = ResourceClassList{} } func (*ResourceClassList) ProtoMessage() {} func (*ResourceClassList) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{24} + return fileDescriptor_4312f5b44a31ec02, []int{33} } func (m *ResourceClassList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -749,7 +1002,7 @@ var xxx_messageInfo_ResourceClassList proto.InternalMessageInfo func (m *ResourceClassParameters) Reset() { *m = ResourceClassParameters{} } func (*ResourceClassParameters) ProtoMessage() {} func (*ResourceClassParameters) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{25} + return fileDescriptor_4312f5b44a31ec02, []int{34} } func (m *ResourceClassParameters) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -777,7 +1030,7 @@ var xxx_messageInfo_ResourceClassParameters proto.InternalMessageInfo func (m *ResourceClassParametersList) Reset() { *m = ResourceClassParametersList{} } func (*ResourceClassParametersList) ProtoMessage() {} func (*ResourceClassParametersList) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{26} + return fileDescriptor_4312f5b44a31ec02, []int{35} } func (m *ResourceClassParametersList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -805,7 +1058,7 @@ var xxx_messageInfo_ResourceClassParametersList proto.InternalMessageInfo func (m *ResourceClassParametersReference) Reset() { *m = ResourceClassParametersReference{} } func (*ResourceClassParametersReference) ProtoMessage() {} func (*ResourceClassParametersReference) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{27} + return fileDescriptor_4312f5b44a31ec02, []int{36} } func (m *ResourceClassParametersReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -833,7 +1086,7 @@ var xxx_messageInfo_ResourceClassParametersReference proto.InternalMessageInfo func (m *ResourceFilter) Reset() { *m = ResourceFilter{} } func (*ResourceFilter) ProtoMessage() {} func (*ResourceFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{28} + return fileDescriptor_4312f5b44a31ec02, []int{37} } func (m *ResourceFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -861,7 +1114,7 @@ var xxx_messageInfo_ResourceFilter proto.InternalMessageInfo func (m *ResourceFilterModel) Reset() { *m = ResourceFilterModel{} } func (*ResourceFilterModel) ProtoMessage() {} func (*ResourceFilterModel) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{29} + return fileDescriptor_4312f5b44a31ec02, []int{38} } func (m *ResourceFilterModel) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -889,7 +1142,7 @@ var xxx_messageInfo_ResourceFilterModel proto.InternalMessageInfo func (m *ResourceHandle) Reset() { *m = ResourceHandle{} } func (*ResourceHandle) ProtoMessage() {} func (*ResourceHandle) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{30} + return fileDescriptor_4312f5b44a31ec02, []int{39} } func (m *ResourceHandle) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -917,7 +1170,7 @@ var xxx_messageInfo_ResourceHandle proto.InternalMessageInfo func (m *ResourceRequest) Reset() { *m = ResourceRequest{} } func (*ResourceRequest) ProtoMessage() {} func (*ResourceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{31} + return fileDescriptor_4312f5b44a31ec02, []int{40} } func (m *ResourceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -945,7 +1198,7 @@ var xxx_messageInfo_ResourceRequest proto.InternalMessageInfo func (m *ResourceRequestModel) Reset() { *m = ResourceRequestModel{} } func (*ResourceRequestModel) ProtoMessage() {} func (*ResourceRequestModel) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{32} + return fileDescriptor_4312f5b44a31ec02, []int{41} } func (m *ResourceRequestModel) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -973,7 +1226,7 @@ var xxx_messageInfo_ResourceRequestModel proto.InternalMessageInfo func (m *StructuredResourceHandle) Reset() { *m = StructuredResourceHandle{} } func (*StructuredResourceHandle) ProtoMessage() {} func (*StructuredResourceHandle) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{33} + return fileDescriptor_4312f5b44a31ec02, []int{42} } func (m *StructuredResourceHandle) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1001,7 +1254,7 @@ var xxx_messageInfo_StructuredResourceHandle proto.InternalMessageInfo func (m *VendorParameters) Reset() { *m = VendorParameters{} } func (*VendorParameters) ProtoMessage() {} func (*VendorParameters) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{34} + return fileDescriptor_4312f5b44a31ec02, []int{43} } func (m *VendorParameters) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1031,6 +1284,15 @@ func init() { proto.RegisterType((*AllocationResultModel)(nil), "k8s.io.api.resource.v1alpha2.AllocationResultModel") proto.RegisterType((*DriverAllocationResult)(nil), "k8s.io.api.resource.v1alpha2.DriverAllocationResult") proto.RegisterType((*DriverRequests)(nil), "k8s.io.api.resource.v1alpha2.DriverRequests") + proto.RegisterType((*NamedResourcesAllocationResult)(nil), "k8s.io.api.resource.v1alpha2.NamedResourcesAllocationResult") + proto.RegisterType((*NamedResourcesAttribute)(nil), "k8s.io.api.resource.v1alpha2.NamedResourcesAttribute") + proto.RegisterType((*NamedResourcesAttributeValue)(nil), "k8s.io.api.resource.v1alpha2.NamedResourcesAttributeValue") + proto.RegisterType((*NamedResourcesFilter)(nil), "k8s.io.api.resource.v1alpha2.NamedResourcesFilter") + proto.RegisterType((*NamedResourcesInstance)(nil), "k8s.io.api.resource.v1alpha2.NamedResourcesInstance") + proto.RegisterType((*NamedResourcesIntSlice)(nil), "k8s.io.api.resource.v1alpha2.NamedResourcesIntSlice") + proto.RegisterType((*NamedResourcesRequest)(nil), "k8s.io.api.resource.v1alpha2.NamedResourcesRequest") + proto.RegisterType((*NamedResourcesResources)(nil), "k8s.io.api.resource.v1alpha2.NamedResourcesResources") + proto.RegisterType((*NamedResourcesStringSlice)(nil), "k8s.io.api.resource.v1alpha2.NamedResourcesStringSlice") proto.RegisterType((*NodeResourceModel)(nil), "k8s.io.api.resource.v1alpha2.NodeResourceModel") proto.RegisterType((*NodeResourceSlice)(nil), "k8s.io.api.resource.v1alpha2.NodeResourceSlice") proto.RegisterType((*NodeResourceSliceList)(nil), "k8s.io.api.resource.v1alpha2.NodeResourceSliceList") @@ -1069,121 +1331,147 @@ func init() { } var fileDescriptor_4312f5b44a31ec02 = []byte{ - // 1822 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x1a, 0xcd, 0x6f, 0x1b, 0x4b, - 0x3d, 0x6b, 0x3b, 0xaf, 0xe9, 0x2f, 0x8d, 0x93, 0x6c, 0x92, 0xc6, 0x2f, 0xaf, 0xcf, 0x36, 0x7b, - 0x8a, 0x44, 0xbb, 0x7e, 0xc9, 0x2b, 0xa5, 0xe2, 0x4b, 0xca, 0x36, 0xb4, 0x44, 0xb4, 0x69, 0x18, - 0xf7, 0x1b, 0x04, 0xdd, 0x78, 0xa7, 0xc9, 0x92, 0xf5, 0xee, 0xb2, 0xb3, 0x4e, 0x5b, 0x71, 0xa9, - 0x10, 0x07, 0x2e, 0x48, 0x95, 0x40, 0x08, 0x4e, 0x1c, 0x11, 0x17, 0x2e, 0xf0, 0x1f, 0x54, 0xa8, - 0x95, 0xb8, 0xb4, 0x02, 0x89, 0x8a, 0x43, 0x44, 0xcd, 0x9f, 0xc0, 0xad, 0x27, 0x34, 0xe3, 0xd9, - 0xf5, 0xce, 0x7e, 0x38, 0x5e, 0xf3, 0x6a, 0xb5, 0xa7, 0x64, 0x67, 0x7e, 0x1f, 0xf3, 0xfb, 0xfe, - 0xfd, 0x66, 0x0c, 0x67, 0x0f, 0x2e, 0x12, 0xd5, 0x74, 0x1a, 0xba, 0x6b, 0x36, 0x3c, 0x4c, 0x9c, - 0x8e, 0xd7, 0xc2, 0x8d, 0xc3, 0x35, 0xdd, 0x72, 0xf7, 0xf5, 0xf5, 0xc6, 0x1e, 0xb6, 0xb1, 0xa7, - 0xfb, 0xd8, 0x50, 0x5d, 0xcf, 0xf1, 0x1d, 0xf9, 0x4c, 0x0f, 0x5a, 0xd5, 0x5d, 0x53, 0x0d, 0xa0, - 0xd5, 0x00, 0x7a, 0xe5, 0xdc, 0x9e, 0xe9, 0xef, 0x77, 0x76, 0xd5, 0x96, 0xd3, 0x6e, 0xec, 0x39, - 0x7b, 0x4e, 0x83, 0x21, 0xed, 0x76, 0x1e, 0xb0, 0x2f, 0xf6, 0xc1, 0xfe, 0xeb, 0x11, 0x5b, 0x51, - 0x22, 0xac, 0x5b, 0x8e, 0x47, 0xd9, 0xc6, 0x19, 0xae, 0x9c, 0xef, 0xc3, 0xb4, 0xf5, 0xd6, 0xbe, - 0x69, 0x63, 0xef, 0x71, 0xc3, 0x3d, 0xd8, 0xa3, 0x0b, 0xa4, 0xd1, 0xc6, 0xbe, 0x9e, 0x86, 0xd5, - 0xc8, 0xc2, 0xf2, 0x3a, 0xb6, 0x6f, 0xb6, 0x71, 0x02, 0xe1, 0xc2, 0x71, 0x08, 0xa4, 0xb5, 0x8f, - 0xdb, 0x7a, 0x1c, 0x4f, 0xf9, 0x6d, 0x01, 0xe6, 0x36, 0x2c, 0xcb, 0x69, 0xe9, 0xbe, 0xe9, 0xd8, - 0x08, 0x93, 0x8e, 0xe5, 0xcb, 0x0e, 0xcc, 0x06, 0xba, 0xf9, 0x8e, 0x6e, 0x1b, 0x16, 0x26, 0x15, - 0xa9, 0x5e, 0x5c, 0x9d, 0x5e, 0x3f, 0xab, 0x0e, 0x52, 0x9f, 0x8a, 0x04, 0x24, 0x6d, 0xf9, 0xc5, - 0x51, 0x6d, 0xa2, 0x7b, 0x54, 0x9b, 0x15, 0xd7, 0x09, 0x8a, 0x53, 0x97, 0x77, 0x61, 0x4e, 0x3f, - 0xd4, 0x4d, 0x4b, 0xdf, 0xb5, 0xf0, 0x75, 0x7b, 0xdb, 0x31, 0x30, 0xa9, 0x14, 0xea, 0xd2, 0xea, - 0xf4, 0x7a, 0x3d, 0xca, 0x91, 0xea, 0x58, 0x3d, 0x5c, 0x53, 0x29, 0x40, 0x13, 0x5b, 0xb8, 0xe5, - 0x3b, 0x9e, 0xb6, 0xd8, 0x3d, 0xaa, 0xcd, 0x6d, 0xc4, 0xb0, 0x51, 0x82, 0x9e, 0xdc, 0x80, 0x93, - 0x64, 0x5f, 0xf7, 0x30, 0x5d, 0xab, 0x14, 0xeb, 0xd2, 0xea, 0x94, 0x36, 0xcf, 0x0f, 0x78, 0xb2, - 0x19, 0x6c, 0xa0, 0x3e, 0x8c, 0xb2, 0x0c, 0x4b, 0x71, 0xcd, 0x5c, 0x73, 0x0c, 0x6c, 0x29, 0x7f, - 0x2a, 0xc0, 0xe9, 0x4d, 0xcf, 0x3c, 0xc4, 0x5e, 0x42, 0x73, 0xbf, 0x90, 0x60, 0xf9, 0x10, 0xdb, - 0x86, 0xe3, 0x21, 0xfc, 0x93, 0x0e, 0x26, 0xfe, 0x8e, 0xee, 0xe9, 0x6d, 0xec, 0x63, 0x8f, 0xaa, - 0x90, 0x0a, 0x74, 0x2e, 0x22, 0x50, 0x68, 0x29, 0xd5, 0x3d, 0xd8, 0x53, 0xb9, 0xa5, 0x54, 0xa4, - 0x3f, 0xfc, 0xf6, 0x23, 0x1f, 0xdb, 0xc4, 0x74, 0x6c, 0xad, 0xc6, 0x8f, 0xb8, 0x7c, 0x2b, 0x9d, - 0x2a, 0xca, 0x62, 0x47, 0x8f, 0xb2, 0xa4, 0xa7, 0x9d, 0x9f, 0x6b, 0xf6, 0xf3, 0xc1, 0xb6, 0x4c, - 0x15, 0x5d, 0xfb, 0x94, 0x1f, 0x27, 0x5d, 0x33, 0x28, 0x9d, 0xa1, 0xf2, 0x9b, 0x02, 0x94, 0x7b, - 0x0a, 0xe3, 0xc7, 0x24, 0xf2, 0x3a, 0x80, 0xc1, 0x56, 0xb6, 0xf5, 0x36, 0x66, 0xaa, 0x39, 0xa9, - 0xc9, 0x9c, 0x38, 0x6c, 0x86, 0x3b, 0x28, 0x02, 0x25, 0x13, 0x98, 0xeb, 0x09, 0x1b, 0x51, 0x6a, - 0x61, 0x14, 0xa5, 0x56, 0x38, 0xa3, 0xb9, 0x5b, 0x31, 0x72, 0x28, 0xc1, 0x40, 0xfe, 0x3e, 0x4c, - 0x79, 0xfc, 0xd0, 0x95, 0x22, 0x0b, 0x82, 0x73, 0xc3, 0x05, 0x01, 0x17, 0x55, 0x9b, 0xe3, 0xcc, - 0xa6, 0x02, 0xd9, 0x51, 0x48, 0x50, 0x59, 0x80, 0x79, 0xea, 0x9c, 0x01, 0x4a, 0x4f, 0x5b, 0xaf, - 0x0a, 0xe2, 0x6a, 0xd3, 0x32, 0x5b, 0x58, 0xbe, 0x0f, 0x53, 0x34, 0x59, 0x18, 0xba, 0xaf, 0x73, - 0x4f, 0xfa, 0x2c, 0x53, 0x68, 0x9a, 0x5a, 0x54, 0x0a, 0x4d, 0x83, 0xe5, 0xfa, 0xee, 0x8f, 0x71, - 0xcb, 0xbf, 0x86, 0x7d, 0xbd, 0xaf, 0xe0, 0xfe, 0x1a, 0x0a, 0xa9, 0xca, 0x67, 0x61, 0xca, 0x76, - 0x0c, 0xcc, 0x0c, 0x52, 0x60, 0x06, 0x09, 0x8f, 0xbe, 0xcd, 0xd7, 0x51, 0x08, 0x11, 0x33, 0x60, - 0x71, 0x28, 0x03, 0x3e, 0x82, 0x79, 0x3b, 0x2e, 0x6e, 0xa5, 0xc4, 0x84, 0x69, 0x0c, 0x56, 0x6a, - 0x42, 0x4b, 0xda, 0xc7, 0x9c, 0x57, 0x52, 0x81, 0x28, 0xc9, 0x44, 0xf9, 0x9b, 0x04, 0x4b, 0x09, - 0x9d, 0x5e, 0x35, 0x89, 0x2f, 0xff, 0x20, 0xa1, 0x57, 0x75, 0x38, 0xbd, 0x52, 0x6c, 0xa6, 0xd5, - 0x50, 0x4b, 0xc1, 0x4a, 0x44, 0xa7, 0x37, 0x60, 0xd2, 0xf4, 0x71, 0x9b, 0xfa, 0x69, 0x31, 0x9f, - 0x94, 0xec, 0x84, 0xda, 0x0c, 0xa7, 0x3d, 0xb9, 0x45, 0xa9, 0xa0, 0x1e, 0x31, 0xe5, 0x2f, 0x05, - 0x58, 0xdc, 0x71, 0x8c, 0x66, 0x6b, 0x1f, 0x1b, 0x1d, 0xcb, 0xb4, 0xf7, 0x2e, 0x39, 0xb6, 0x8f, - 0x1f, 0xf9, 0x63, 0x70, 0x92, 0x3b, 0x50, 0x22, 0x2e, 0x6e, 0xf1, 0xb8, 0xbb, 0x30, 0x58, 0x9e, - 0xb4, 0x33, 0x36, 0x5d, 0xdc, 0xd2, 0x4e, 0x71, 0x1e, 0x25, 0xfa, 0x85, 0x18, 0x45, 0xf9, 0x3e, - 0x7c, 0x44, 0x7c, 0xdd, 0xef, 0x10, 0xe6, 0x4c, 0xd3, 0xeb, 0x17, 0x47, 0xa0, 0xcd, 0xf0, 0xb5, - 0x32, 0xa7, 0xfe, 0x51, 0xef, 0x1b, 0x71, 0xba, 0xca, 0x2b, 0x09, 0x2a, 0x69, 0x68, 0x63, 0xf0, - 0x83, 0xdb, 0xa2, 0x1f, 0xac, 0xe7, 0x97, 0x2d, 0xc3, 0x15, 0x9e, 0x66, 0xc8, 0x44, 0x15, 0x2b, - 0x5f, 0x84, 0x53, 0x84, 0x95, 0x49, 0x6c, 0x50, 0xd7, 0xe2, 0x69, 0x76, 0x91, 0x13, 0x3a, 0xd5, - 0x8c, 0xec, 0x21, 0x01, 0x52, 0xfe, 0x1a, 0x94, 0x5d, 0xc7, 0xc7, 0xb6, 0x6f, 0xea, 0x56, 0x50, - 0x8e, 0x8b, 0x34, 0xc2, 0xbb, 0x47, 0xb5, 0xf2, 0x8e, 0xb0, 0x83, 0x62, 0x90, 0xca, 0xef, 0x24, - 0x58, 0xc9, 0xb6, 0x8e, 0xfc, 0x53, 0x28, 0x07, 0x12, 0x5f, 0xb2, 0x74, 0xb3, 0x1d, 0xf4, 0x16, - 0x5f, 0x1f, 0x2e, 0xad, 0x32, 0x9c, 0x3e, 0x6d, 0x6e, 0xf2, 0xd3, 0x5c, 0xa6, 0xb2, 0x00, 0x46, - 0x50, 0x8c, 0x95, 0xf2, 0xfb, 0x02, 0xcc, 0x08, 0x20, 0x63, 0x08, 0x99, 0xef, 0x09, 0x21, 0xd3, - 0xc8, 0x23, 0x66, 0x56, 0xac, 0xdc, 0x8d, 0xc5, 0xca, 0x5a, 0x1e, 0xa2, 0x83, 0x83, 0xa4, 0x2b, - 0x41, 0x55, 0x80, 0xbf, 0xe4, 0xd8, 0xa4, 0xd3, 0xa6, 0xa5, 0xfb, 0x01, 0xf6, 0xb0, 0xdd, 0xc2, - 0xb4, 0x50, 0xe8, 0xae, 0x79, 0xc5, 0x73, 0x3a, 0x2e, 0x77, 0xa9, 0xd0, 0xf5, 0x37, 0x76, 0xb6, - 0xd8, 0x3a, 0x0a, 0x21, 0x28, 0x74, 0x70, 0x22, 0x5e, 0x26, 0x22, 0x15, 0x91, 0x97, 0xca, 0x10, - 0x42, 0xae, 0x43, 0xc9, 0xa6, 0x05, 0xa5, 0xc4, 0x20, 0x43, 0xd9, 0x59, 0x29, 0x61, 0x3b, 0xb2, - 0x06, 0xc5, 0x8e, 0x69, 0x54, 0x26, 0x19, 0xc0, 0x67, 0x1c, 0xa0, 0x78, 0x73, 0x6b, 0xf3, 0xed, - 0x51, 0xed, 0x4b, 0x59, 0x5d, 0xb0, 0xff, 0xd8, 0xc5, 0x44, 0xbd, 0xb9, 0xb5, 0x89, 0x28, 0xb2, - 0xf2, 0x4c, 0x82, 0x79, 0x41, 0xc8, 0x31, 0xa4, 0x80, 0x1d, 0x31, 0x05, 0x7c, 0x39, 0x87, 0xc9, - 0x32, 0x62, 0xff, 0x57, 0x45, 0x58, 0x16, 0xe0, 0x22, 0x6d, 0xcb, 0xbb, 0x77, 0xeb, 0x87, 0x30, - 0x13, 0x0e, 0x13, 0x97, 0x3d, 0xa7, 0xcd, 0xfd, 0xfb, 0x5b, 0x39, 0xe4, 0x8a, 0x34, 0x5e, 0x81, - 0x73, 0x69, 0xf3, 0xdd, 0xa3, 0xda, 0xcc, 0x95, 0x28, 0x61, 0x24, 0xf2, 0xc9, 0xdd, 0xc8, 0xcb, - 0x16, 0x94, 0x0d, 0xa1, 0xfb, 0xac, 0x94, 0x86, 0x99, 0x66, 0xc4, 0x8e, 0xb5, 0x9f, 0x62, 0xc4, - 0x75, 0x14, 0xa3, 0xad, 0xfc, 0x53, 0x82, 0x4f, 0x32, 0xa4, 0x1c, 0x83, 0x97, 0xdd, 0x13, 0xbd, - 0xec, 0x2b, 0x23, 0x59, 0x23, 0xc3, 0xdf, 0x7e, 0x2d, 0x41, 0xfd, 0x38, 0xfb, 0xe5, 0x4c, 0x0e, - 0x75, 0x28, 0x1d, 0x98, 0xb6, 0xc1, 0xfb, 0xcd, 0x30, 0xdc, 0xbf, 0x6b, 0xda, 0x06, 0x62, 0x3b, - 0x61, 0x42, 0x28, 0x66, 0x25, 0x04, 0xe5, 0x89, 0x04, 0x9f, 0x0e, 0xac, 0x0e, 0x21, 0x0d, 0x29, - 0x33, 0xa9, 0x7c, 0x13, 0x66, 0x3b, 0x36, 0xe9, 0x98, 0x3e, 0x75, 0x98, 0x68, 0xc1, 0x5b, 0xa0, - 0xf3, 0xeb, 0x4d, 0x71, 0x0b, 0xc5, 0x61, 0x95, 0x3f, 0x14, 0x62, 0xf9, 0x84, 0x95, 0xdf, 0x2b, - 0x30, 0x1f, 0x29, 0x3f, 0x84, 0x44, 0x46, 0x9d, 0xb0, 0x7b, 0x45, 0x71, 0x00, 0x94, 0xc4, 0xa1, - 0xa1, 0xe6, 0x46, 0x55, 0xfd, 0x45, 0x86, 0x9a, 0xb0, 0x81, 0x44, 0x3e, 0xf2, 0x0e, 0x94, 0xfb, - 0x13, 0x1d, 0xed, 0xa4, 0xb9, 0x19, 0x56, 0x83, 0x58, 0xd8, 0x10, 0x76, 0xdf, 0x26, 0x56, 0x50, - 0x0c, 0x5f, 0xf9, 0x6f, 0x01, 0x16, 0x52, 0xca, 0xd1, 0x48, 0xf3, 0xe0, 0x0f, 0x01, 0xfa, 0xd4, - 0xb9, 0x4e, 0xd4, 0x7c, 0x53, 0xad, 0x56, 0xa6, 0xf4, 0x23, 0xab, 0x11, 0x8a, 0x32, 0x81, 0x69, - 0x0f, 0x13, 0xec, 0x1d, 0x62, 0xe3, 0xb2, 0xe3, 0xf1, 0xe9, 0xef, 0x1b, 0x39, 0x94, 0x9e, 0x28, - 0x9d, 0xda, 0x02, 0x17, 0x69, 0x1a, 0xf5, 0x09, 0xa3, 0x28, 0x17, 0xb9, 0x09, 0x4b, 0x06, 0x8e, - 0x8e, 0xd1, 0x2c, 0xad, 0x60, 0x83, 0x55, 0xc4, 0xa9, 0xfe, 0x00, 0xbe, 0x99, 0x06, 0x84, 0xd2, - 0x71, 0x95, 0x7f, 0x48, 0xb0, 0x24, 0x9c, 0xec, 0x06, 0x6e, 0xbb, 0x96, 0xee, 0x8f, 0x63, 0xac, - 0xbc, 0x2b, 0xb4, 0x3f, 0x5f, 0xcd, 0xa1, 0xbe, 0xe0, 0x90, 0x59, 0x6d, 0x90, 0xf2, 0x77, 0x09, - 0x3e, 0x4e, 0xc5, 0x18, 0x43, 0xa2, 0xbd, 0x23, 0x26, 0xda, 0xcf, 0x47, 0x90, 0x2b, 0x23, 0xcd, - 0xbe, 0xcc, 0x92, 0xaa, 0xd9, 0x1b, 0x93, 0x3e, 0xbc, 0x7e, 0x55, 0x79, 0x5e, 0x14, 0xda, 0x6e, - 0x32, 0x8e, 0xfe, 0x44, 0xcc, 0x28, 0x85, 0xa1, 0x32, 0x4a, 0x22, 0xd1, 0x16, 0x73, 0x26, 0x5a, - 0x42, 0x46, 0x4b, 0xb4, 0x77, 0x61, 0x46, 0xac, 0x3e, 0xa5, 0x21, 0x6f, 0x3f, 0x19, 0xe9, 0xa6, - 0x50, 0x9d, 0x44, 0x4a, 0xf2, 0x55, 0x58, 0x24, 0xbe, 0xd7, 0x69, 0xf9, 0x1d, 0x0f, 0x1b, 0x91, - 0x9b, 0xb3, 0x49, 0x96, 0x4f, 0x2a, 0xdd, 0xa3, 0xda, 0x62, 0x33, 0x65, 0x1f, 0xa5, 0x62, 0xc5, - 0x3b, 0x67, 0x42, 0xde, 0xe7, 0xce, 0x99, 0x64, 0x75, 0x32, 0xcf, 0xc4, 0xce, 0x39, 0x6a, 0xb5, - 0x0f, 0xa1, 0x73, 0x1e, 0xe0, 0x65, 0x03, 0x3b, 0x67, 0x3f, 0xe5, 0x02, 0xb5, 0x57, 0xd5, 0x8e, - 0x29, 0x9b, 0xf1, 0x7b, 0xd2, 0x5c, 0x37, 0xa8, 0xb7, 0xe1, 0xc4, 0x03, 0xd3, 0x62, 0xcc, 0x4a, - 0x79, 0x5e, 0x11, 0x2e, 0x33, 0x24, 0x6d, 0x96, 0xb3, 0x3a, 0xd1, 0xfb, 0x26, 0x28, 0xa0, 0x16, - 0xef, 0xb4, 0xa3, 0x5a, 0x79, 0x9f, 0x3b, 0xed, 0xe8, 0x39, 0x33, 0xfc, 0xf3, 0xaf, 0x62, 0xa7, - 0x9d, 0x6a, 0xef, 0xf1, 0x77, 0xda, 0x74, 0xf2, 0xa2, 0x7f, 0x89, 0xab, 0xb7, 0x82, 0x09, 0x3d, - 0x9c, 0xbc, 0xb6, 0x83, 0x0d, 0xd4, 0x87, 0x51, 0x9e, 0x4b, 0x50, 0x16, 0xcd, 0x39, 0x52, 0xa3, - 0xf7, 0x44, 0x82, 0x05, 0x4f, 0x20, 0x13, 0x7d, 0xc8, 0x58, 0xcb, 0xe3, 0x4e, 0xbd, 0xcb, 0xe3, - 0x4f, 0x38, 0xc3, 0x85, 0x94, 0x4d, 0x94, 0xc6, 0x4a, 0x59, 0x82, 0x34, 0x58, 0xe5, 0x5f, 0x11, - 0x01, 0x7b, 0x8f, 0x59, 0x23, 0x09, 0x58, 0x87, 0x12, 0xf3, 0xd2, 0x98, 0x71, 0x36, 0x75, 0x5f, - 0x47, 0x6c, 0x47, 0xf6, 0xa0, 0xdc, 0xcf, 0xc7, 0x74, 0x9d, 0xe5, 0xef, 0x63, 0x6f, 0x60, 0xfb, - 0x99, 0x3d, 0xf6, 0x36, 0xc7, 0x2e, 0xf2, 0x9a, 0x02, 0x45, 0x14, 0xe3, 0xa0, 0xfc, 0xb2, 0x00, - 0xb3, 0xb1, 0xd7, 0x8c, 0xd4, 0x37, 0x18, 0xe9, 0x5d, 0xbf, 0xc1, 0xfc, 0x5c, 0x82, 0x45, 0x4f, - 0x3c, 0x48, 0xd4, 0x01, 0xd6, 0x73, 0x3d, 0xc8, 0xf4, 0x3c, 0xe0, 0x0c, 0x67, 0xbf, 0x98, 0xb6, - 0x8b, 0x52, 0xb9, 0x29, 0xa7, 0x21, 0x15, 0x5a, 0xf9, 0x73, 0x11, 0x2a, 0x59, 0x8a, 0x96, 0x7f, - 0x26, 0xc1, 0x52, 0x4f, 0xa0, 0x58, 0x20, 0x8f, 0xa6, 0xb6, 0xb0, 0xff, 0xbf, 0x95, 0x46, 0x13, - 0xa5, 0xb3, 0x12, 0x0f, 0x11, 0x1d, 0x06, 0x47, 0x7b, 0x3f, 0x4b, 0x1e, 0x42, 0x18, 0x30, 0xd3, - 0x59, 0x09, 0xef, 0x4b, 0xa5, 0x63, 0xdf, 0x97, 0x7e, 0x04, 0x27, 0x3c, 0x36, 0xa2, 0xd1, 0x4e, - 0x85, 0x26, 0xd8, 0xf3, 0xc3, 0xdc, 0xd6, 0x24, 0xe6, 0xbb, 0xb0, 0x7a, 0xf4, 0xbe, 0x09, 0x0a, - 0xa8, 0x2a, 0x7f, 0x94, 0x20, 0xe1, 0x7b, 0x23, 0x05, 0xaf, 0x0e, 0xe0, 0xfe, 0x9f, 0x0a, 0x0d, - 0x59, 0x44, 0xb4, 0x18, 0x21, 0xaa, 0x69, 0x2f, 0xde, 0x54, 0x27, 0x5e, 0xbe, 0xa9, 0x4e, 0xbc, - 0x7e, 0x53, 0x9d, 0x78, 0xd2, 0xad, 0x4a, 0x2f, 0xba, 0x55, 0xe9, 0x65, 0xb7, 0x2a, 0xbd, 0xee, - 0x56, 0xa5, 0x7f, 0x77, 0xab, 0xd2, 0xd3, 0xff, 0x54, 0x27, 0xee, 0x9d, 0x19, 0xf4, 0x4b, 0x88, - 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x11, 0xc0, 0x9d, 0x25, 0x28, 0x21, 0x00, 0x00, + // 2231 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x1a, 0x4b, 0x6f, 0x1b, 0xc7, + 0xd9, 0x4b, 0xd2, 0x16, 0xf5, 0xc9, 0xa2, 0xa4, 0xb5, 0x64, 0xd1, 0x8e, 0x42, 0x2a, 0x8b, 0x16, + 0x15, 0x50, 0x9b, 0x8c, 0xe5, 0xc4, 0x31, 0xd2, 0xb4, 0x80, 0xd7, 0x8a, 0x5d, 0xa1, 0x89, 0xa3, + 0x0c, 0x63, 0x27, 0x4e, 0x5f, 0x59, 0x71, 0xc7, 0xd2, 0xd6, 0xe4, 0x2e, 0xbd, 0x33, 0x54, 0x6c, + 0xf4, 0x62, 0x14, 0x7d, 0x5d, 0x0a, 0xa4, 0x68, 0x51, 0xb4, 0xa7, 0x9e, 0x8a, 0xa2, 0x97, 0x5e, + 0xda, 0x7b, 0x0f, 0x41, 0x1b, 0x03, 0xbd, 0x38, 0x68, 0x81, 0x06, 0x3d, 0x10, 0x35, 0xfb, 0x13, + 0x7a, 0xcb, 0xa9, 0x98, 0xc7, 0x3e, 0x66, 0xb9, 0x4b, 0x71, 0xd9, 0x46, 0x48, 0x4e, 0xd2, 0xce, + 0x7c, 0xef, 0xef, 0x9b, 0xef, 0x31, 0x43, 0x38, 0x77, 0xf7, 0x32, 0x69, 0x38, 0x5e, 0xd3, 0xea, + 0x39, 0x4d, 0x1f, 0x13, 0xaf, 0xef, 0xb7, 0x71, 0xf3, 0xe0, 0x82, 0xd5, 0xe9, 0xed, 0x5b, 0x9b, + 0xcd, 0x3d, 0xec, 0x62, 0xdf, 0xa2, 0xd8, 0x6e, 0xf4, 0x7c, 0x8f, 0x7a, 0xfa, 0x9a, 0x80, 0x6e, + 0x58, 0x3d, 0xa7, 0x11, 0x40, 0x37, 0x02, 0xe8, 0xb3, 0xe7, 0xf7, 0x1c, 0xba, 0xdf, 0xdf, 0x6d, + 0xb4, 0xbd, 0x6e, 0x73, 0xcf, 0xdb, 0xf3, 0x9a, 0x1c, 0x69, 0xb7, 0x7f, 0x87, 0x7f, 0xf1, 0x0f, + 0xfe, 0x9f, 0x20, 0x76, 0xd6, 0x88, 0xb1, 0x6e, 0x7b, 0x3e, 0x63, 0x9b, 0x64, 0x78, 0xf6, 0xb9, + 0x08, 0xa6, 0x6b, 0xb5, 0xf7, 0x1d, 0x17, 0xfb, 0x0f, 0x9a, 0xbd, 0xbb, 0x7b, 0xaa, 0xbc, 0x79, + 0xb0, 0x48, 0xb3, 0x8b, 0xa9, 0x95, 0xc6, 0xab, 0x99, 0x85, 0xe5, 0xf7, 0x5d, 0xea, 0x74, 0x47, + 0xd9, 0x5c, 0x3a, 0x0c, 0x81, 0xb4, 0xf7, 0x71, 0xd7, 0x4a, 0xe2, 0x19, 0xbf, 0x2c, 0xc0, 0xe2, + 0x95, 0x4e, 0xc7, 0x6b, 0x5b, 0xd4, 0xf1, 0x5c, 0x84, 0x49, 0xbf, 0x43, 0x75, 0x0f, 0x16, 0x02, + 0x7d, 0xbe, 0x6a, 0xb9, 0x76, 0x07, 0x93, 0xaa, 0xb6, 0x5e, 0xdc, 0x98, 0xdb, 0x3c, 0xd7, 0x18, + 0x67, 0xf4, 0x06, 0x52, 0x90, 0xcc, 0xd5, 0x47, 0x83, 0xfa, 0xb1, 0xe1, 0xa0, 0xbe, 0xa0, 0xae, + 0x13, 0x94, 0xa4, 0xae, 0xef, 0xc2, 0xa2, 0x75, 0x60, 0x39, 0x1d, 0x6b, 0xb7, 0x83, 0x5f, 0x73, + 0x6f, 0x78, 0x36, 0x26, 0xd5, 0xc2, 0xba, 0xb6, 0x31, 0xb7, 0xb9, 0x1e, 0xe7, 0xc8, 0x3c, 0xd3, + 0x38, 0xb8, 0xd0, 0x60, 0x00, 0x2d, 0xdc, 0xc1, 0x6d, 0xea, 0xf9, 0xe6, 0xf2, 0x70, 0x50, 0x5f, + 0xbc, 0x92, 0xc0, 0x46, 0x23, 0xf4, 0xf4, 0x26, 0xcc, 0x92, 0x7d, 0xcb, 0xc7, 0x6c, 0xad, 0x5a, + 0x5c, 0xd7, 0x36, 0xca, 0xe6, 0x92, 0x14, 0x70, 0xb6, 0x15, 0x6c, 0xa0, 0x08, 0xc6, 0xf8, 0xa9, + 0x06, 0x2b, 0x49, 0xd3, 0xbc, 0xea, 0xd9, 0xb8, 0xa3, 0xdf, 0x87, 0x8a, 0x6b, 0x75, 0xb1, 0x1d, + 0xe8, 0xc5, 0xcc, 0xc3, 0x84, 0x7d, 0x69, 0xbc, 0x79, 0x6e, 0x28, 0x38, 0x49, 0xd2, 0xa6, 0x3e, + 0x1c, 0xd4, 0x2b, 0x2a, 0x0c, 0x4a, 0xf0, 0x31, 0x7e, 0x5f, 0x80, 0xd3, 0x5b, 0xbe, 0x73, 0x80, + 0xfd, 0x11, 0xa7, 0xfd, 0x58, 0x83, 0xd5, 0x03, 0xec, 0xda, 0x9e, 0x8f, 0xf0, 0xbd, 0x3e, 0x26, + 0x74, 0xc7, 0xf2, 0xad, 0x2e, 0xa6, 0xd8, 0x0f, 0xc4, 0x3b, 0x1f, 0x13, 0x2f, 0x0c, 0x92, 0x46, + 0xef, 0xee, 0x5e, 0x43, 0x06, 0x49, 0x03, 0x59, 0xef, 0xbe, 0x7c, 0x9f, 0x62, 0x97, 0x38, 0x9e, + 0x6b, 0xd6, 0xa5, 0x75, 0x56, 0x6f, 0xa5, 0x53, 0x45, 0x59, 0xec, 0x98, 0x28, 0x2b, 0x56, 0x9a, + 0xe5, 0xa4, 0x53, 0x2f, 0x8e, 0xb7, 0x53, 0xaa, 0xd1, 0xcd, 0xa7, 0xa5, 0x38, 0xe9, 0x3e, 0x41, + 0xe9, 0x0c, 0x8d, 0x5f, 0x14, 0xa0, 0x22, 0x0c, 0x26, 0xc5, 0x24, 0xfa, 0x26, 0x80, 0xcd, 0x57, + 0x98, 0xad, 0xb9, 0x69, 0x66, 0x4d, 0x5d, 0x12, 0x87, 0xad, 0x70, 0x07, 0xc5, 0xa0, 0x74, 0x02, + 0x8b, 0x42, 0xd9, 0x98, 0x51, 0x0b, 0xd3, 0x18, 0xb5, 0x2a, 0x19, 0x2d, 0xde, 0x4a, 0x90, 0x43, + 0x23, 0x0c, 0xf4, 0xaf, 0x43, 0xd9, 0x97, 0x42, 0x57, 0x8b, 0xfc, 0xfc, 0x9d, 0x9f, 0xec, 0xfc, + 0x49, 0x55, 0xcd, 0x45, 0xc9, 0xac, 0x1c, 0xe8, 0x8e, 0x42, 0x82, 0x86, 0x09, 0xb5, 0xf1, 0xf1, + 0xa8, 0xaf, 0x43, 0xc9, 0x8d, 0x2c, 0x74, 0x52, 0xd2, 0x2a, 0x71, 0xdb, 0xf0, 0x1d, 0xe3, 0x2f, + 0x1a, 0xac, 0x26, 0x88, 0x50, 0xea, 0x3b, 0xbb, 0x7d, 0x8a, 0x0f, 0xc7, 0x66, 0x51, 0x52, 0xb1, + 0x02, 0xf8, 0x5b, 0x56, 0xa7, 0x8f, 0xa5, 0x49, 0x5f, 0xcc, 0x75, 0x8c, 0x14, 0x0a, 0xe6, 0xe7, + 0x24, 0xa3, 0xb5, 0x71, 0x50, 0x28, 0xc1, 0xd7, 0xf8, 0x53, 0x11, 0xc6, 0x22, 0xe8, 0xdf, 0x84, + 0xf2, 0xbd, 0xbe, 0xe5, 0x52, 0x87, 0x3e, 0xa8, 0x9e, 0xe0, 0x42, 0x36, 0x32, 0xfd, 0xae, 0x48, + 0xfd, 0xba, 0xc4, 0x32, 0x97, 0x86, 0x83, 0xfa, 0x7c, 0xf0, 0x25, 0xa4, 0x08, 0x49, 0xea, 0xcf, + 0x40, 0x69, 0xd7, 0xf3, 0xc4, 0xf1, 0x28, 0x9b, 0xf3, 0x2c, 0x25, 0x99, 0x9e, 0xd7, 0x11, 0x60, + 0x7c, 0x4b, 0xaf, 0x41, 0xd1, 0x71, 0x69, 0x75, 0x66, 0x5d, 0xdb, 0x28, 0x9a, 0x27, 0x99, 0x53, + 0xb7, 0x5d, 0x2a, 0x00, 0xd8, 0x86, 0xde, 0x86, 0xb2, 0xe3, 0xd2, 0x56, 0xc7, 0x69, 0xe3, 0x6a, + 0x99, 0x4b, 0xf8, 0x5c, 0x1e, 0x33, 0x6e, 0x4b, 0x5c, 0x21, 0x67, 0xf0, 0x25, 0xe5, 0x0c, 0x08, + 0xeb, 0x5f, 0x80, 0x13, 0x84, 0xfa, 0x8e, 0xbb, 0x57, 0x3d, 0xce, 0xdd, 0xba, 0x30, 0x1c, 0xd4, + 0xe7, 0x5a, 0x7c, 0x45, 0x80, 0xca, 0x6d, 0xdd, 0x83, 0x39, 0xf1, 0x9f, 0x10, 0x68, 0x96, 0x0b, + 0xf4, 0x42, 0x1e, 0x81, 0x5a, 0x11, 0xba, 0x48, 0xf1, 0xb1, 0x05, 0xc1, 0x2b, 0xce, 0xc1, 0xd8, + 0x82, 0x65, 0x15, 0xff, 0x9a, 0xd3, 0xa1, 0xd8, 0xd7, 0xcf, 0x41, 0x99, 0xc8, 0x4a, 0x21, 0x43, + 0x31, 0x3c, 0x14, 0x41, 0x05, 0x41, 0x21, 0x84, 0xf1, 0x1b, 0x0d, 0x4e, 0x27, 0xed, 0x42, 0xa8, + 0xe5, 0xb6, 0x27, 0x89, 0x67, 0x07, 0x20, 0x0c, 0x2b, 0x96, 0x1d, 0xd8, 0x81, 0x7d, 0x7e, 0xaa, + 0x50, 0x8e, 0xd2, 0x51, 0xb8, 0x44, 0x50, 0x8c, 0xb8, 0x71, 0x69, 0x54, 0x4c, 0xe9, 0xa1, 0x35, + 0x28, 0x39, 0x2e, 0x15, 0xf5, 0xba, 0x68, 0x96, 0x99, 0x88, 0xdb, 0x2e, 0x25, 0x88, 0xaf, 0x1a, + 0x2f, 0xc3, 0x4a, 0xa2, 0xc0, 0x88, 0x74, 0x90, 0xd3, 0x4c, 0x0f, 0x47, 0xce, 0x7d, 0xf8, 0x8f, + 0x8e, 0x61, 0xd6, 0x91, 0x36, 0x0b, 0xba, 0x86, 0x9c, 0x81, 0x28, 0x90, 0xa3, 0xe2, 0x1c, 0xac, + 0x10, 0x14, 0x51, 0x36, 0x4c, 0x38, 0x93, 0x19, 0x2f, 0xfa, 0xe7, 0x61, 0x46, 0xc4, 0x86, 0x90, + 0x60, 0xd6, 0x9c, 0x1b, 0x0e, 0xea, 0x33, 0x02, 0x82, 0xa0, 0x60, 0xcf, 0xf8, 0xa1, 0x06, 0x4b, + 0xac, 0x37, 0x08, 0x68, 0x88, 0xe2, 0x7e, 0x2f, 0xa3, 0xb8, 0xe7, 0x72, 0x65, 0xf8, 0xcf, 0x44, + 0x55, 0xfd, 0xc3, 0x82, 0x2a, 0x88, 0xd0, 0xe2, 0x1d, 0x28, 0xb3, 0xf6, 0xd0, 0xb6, 0xa8, 0x25, + 0x45, 0x78, 0x76, 0x5c, 0xce, 0x21, 0x0d, 0x06, 0xcd, 0xda, 0xa3, 0xd7, 0x76, 0xbf, 0x83, 0xdb, + 0xf4, 0x55, 0x4c, 0xad, 0x28, 0x90, 0xa2, 0x35, 0x14, 0x52, 0x65, 0x5e, 0x77, 0x3d, 0x1b, 0xf3, + 0x3a, 0x58, 0x50, 0xbd, 0x7e, 0x43, 0xae, 0xa3, 0x10, 0x22, 0x51, 0x37, 0x8b, 0x13, 0xd5, 0xcd, + 0xfb, 0xb0, 0xe4, 0x26, 0x2d, 0x5c, 0x2d, 0x71, 0x65, 0x9a, 0x87, 0xd8, 0x33, 0x89, 0x66, 0x9e, + 0x91, 0xbc, 0x46, 0x7d, 0x86, 0x46, 0x99, 0x18, 0x7f, 0xd5, 0x60, 0x65, 0xc4, 0xa6, 0xaf, 0x38, + 0x84, 0xea, 0xdf, 0x18, 0xb1, 0x6b, 0x63, 0x32, 0xbb, 0x32, 0x6c, 0x6e, 0xd5, 0xd0, 0x4a, 0xc1, + 0x4a, 0xcc, 0xa6, 0x6f, 0xc0, 0x71, 0x87, 0xe2, 0x6e, 0x90, 0x00, 0x72, 0x68, 0x29, 0x72, 0xdd, + 0xbc, 0xa4, 0x7d, 0x7c, 0x9b, 0x51, 0x41, 0x82, 0x98, 0xf1, 0xc7, 0x02, 0x2c, 0xef, 0x78, 0x76, + 0xab, 0xbd, 0x8f, 0xed, 0x7e, 0xc7, 0x71, 0xf7, 0xae, 0x7a, 0x2e, 0xc5, 0xf7, 0xe9, 0x11, 0x04, + 0xc9, 0x5b, 0x50, 0x22, 0x3d, 0xdc, 0x96, 0xb5, 0xf9, 0xd2, 0x78, 0x7d, 0xd2, 0x64, 0x6c, 0xf5, + 0x70, 0x3b, 0x4a, 0x98, 0xec, 0x0b, 0x71, 0x8a, 0xfa, 0x3b, 0xac, 0x9a, 0x58, 0xb4, 0x4f, 0x78, + 0x30, 0xcd, 0x6d, 0x5e, 0x9e, 0x82, 0x36, 0xc7, 0x37, 0x2b, 0x92, 0xfa, 0x09, 0xf1, 0x8d, 0x24, + 0x5d, 0xe3, 0x43, 0x0d, 0xaa, 0x69, 0x68, 0x47, 0x10, 0x07, 0x6f, 0xaa, 0x71, 0xb0, 0x99, 0x5f, + 0xb7, 0x8c, 0x50, 0x78, 0x2f, 0x43, 0x27, 0x66, 0x58, 0xfd, 0x32, 0x9c, 0x14, 0x59, 0x1a, 0xdb, + 0x2c, 0xb4, 0x64, 0x2e, 0x5f, 0x96, 0x84, 0x4e, 0xb6, 0x62, 0x7b, 0x48, 0x81, 0xd4, 0x5f, 0x84, + 0x4a, 0xcf, 0xa3, 0xd8, 0xa5, 0x8e, 0xd5, 0x09, 0x06, 0x30, 0x96, 0x3a, 0x79, 0xfe, 0xda, 0x51, + 0x76, 0x50, 0x02, 0xd2, 0xf8, 0x95, 0x06, 0x67, 0xb3, 0xbd, 0xa3, 0x7f, 0x17, 0x2a, 0x81, 0xc6, + 0x57, 0x3b, 0x96, 0xd3, 0x0d, 0xea, 0xc2, 0x97, 0x26, 0xeb, 0x66, 0x39, 0x4e, 0x44, 0x5b, 0xba, + 0xfc, 0xb4, 0xd4, 0xa9, 0xa2, 0x80, 0x11, 0x94, 0x60, 0x65, 0xfc, 0xba, 0x00, 0xf3, 0x0a, 0xc8, + 0x11, 0x1c, 0x99, 0xd7, 0x95, 0x23, 0xd3, 0xcc, 0xa3, 0x66, 0xd6, 0x59, 0xb9, 0x9d, 0x38, 0x2b, + 0x17, 0xf2, 0x10, 0x1d, 0x7f, 0x48, 0x86, 0x1a, 0xd4, 0x14, 0xf8, 0xab, 0x9e, 0x4b, 0xfa, 0x5d, + 0x36, 0x31, 0xdd, 0xc1, 0x3e, 0x66, 0xcd, 0xcf, 0x39, 0x28, 0x5b, 0x3d, 0xe7, 0xba, 0xef, 0xf5, + 0x7b, 0xc9, 0xf6, 0xe0, 0xca, 0xce, 0x36, 0x5f, 0x47, 0x21, 0x04, 0x83, 0x0e, 0x24, 0x92, 0x65, + 0x22, 0x36, 0x88, 0xc8, 0x09, 0x25, 0x84, 0x08, 0x1b, 0xab, 0x52, 0x66, 0x63, 0x65, 0x42, 0xb1, + 0xef, 0xd8, 0xb2, 0xe5, 0x7c, 0x56, 0x02, 0x14, 0x6f, 0x6e, 0x6f, 0x7d, 0x3c, 0xa8, 0x3f, 0x93, + 0x75, 0xef, 0x41, 0x1f, 0xf4, 0x30, 0x69, 0xdc, 0xdc, 0xde, 0x42, 0x0c, 0xd9, 0x78, 0x5f, 0x83, + 0x25, 0x45, 0xc9, 0x23, 0x48, 0x01, 0x3b, 0x6a, 0x0a, 0xf8, 0x62, 0x0e, 0x97, 0x65, 0x9c, 0xfd, + 0x9f, 0x15, 0x61, 0x55, 0x81, 0x8b, 0x4d, 0x8b, 0x9f, 0x7c, 0x58, 0xbf, 0x0b, 0xf3, 0xe1, 0xf5, + 0xd1, 0x35, 0xdf, 0xeb, 0xca, 0xf8, 0xfe, 0x4a, 0x0e, 0xbd, 0x62, 0xf3, 0x6e, 0x10, 0x5c, 0x62, + 0xe2, 0xb8, 0x1e, 0x27, 0x8c, 0x54, 0x3e, 0xb9, 0xaf, 0x6e, 0xf4, 0x0e, 0x54, 0x6c, 0x65, 0xe8, + 0xaf, 0x96, 0x26, 0xb9, 0xbf, 0x52, 0x2f, 0x0a, 0xa2, 0x14, 0xa3, 0xae, 0xa3, 0x04, 0x6d, 0xe3, + 0x1f, 0x1a, 0x3c, 0x95, 0xa1, 0xe5, 0x11, 0x44, 0xd9, 0xdb, 0x6a, 0x94, 0x3d, 0x3f, 0x95, 0x37, + 0x32, 0xe2, 0xed, 0xe7, 0x1a, 0xac, 0x1f, 0xe6, 0xbf, 0x9c, 0xc9, 0x61, 0x1d, 0x4a, 0x77, 0x1d, + 0xd7, 0x96, 0xfd, 0x66, 0x78, 0xdc, 0xbf, 0xe6, 0xb8, 0x36, 0xe2, 0x3b, 0x61, 0x42, 0x28, 0x66, + 0xde, 0x3b, 0x3c, 0xd4, 0xe0, 0xe9, 0xb1, 0xd5, 0x61, 0x82, 0x69, 0xed, 0xcb, 0xb0, 0xd0, 0x77, + 0x49, 0xdf, 0xa1, 0x2c, 0x60, 0xe2, 0x05, 0xef, 0xd4, 0x70, 0x50, 0x5f, 0xb8, 0xa9, 0x6e, 0xa1, + 0x24, 0xac, 0xf1, 0xdb, 0x42, 0x22, 0x9f, 0xf0, 0xf2, 0x7b, 0x1d, 0x96, 0x62, 0xe5, 0x87, 0x90, + 0xd8, 0x0d, 0x53, 0xd8, 0xbd, 0xa2, 0x24, 0x00, 0x1a, 0xc5, 0x61, 0x47, 0xad, 0x17, 0x37, 0xf5, + 0xff, 0xf3, 0xa8, 0x29, 0x1b, 0x48, 0xe5, 0xa3, 0xef, 0x40, 0x25, 0xba, 0x48, 0x63, 0x9d, 0xb4, + 0x74, 0xc3, 0x46, 0x70, 0x16, 0xae, 0x28, 0xbb, 0x1f, 0x8f, 0xac, 0xa0, 0x04, 0xbe, 0xf1, 0x9f, + 0x02, 0x9c, 0x4a, 0x29, 0x47, 0x53, 0x5d, 0xc3, 0x7d, 0x0b, 0x20, 0xa2, 0x2e, 0x6d, 0xd2, 0xc8, + 0x77, 0x99, 0x68, 0x56, 0xf8, 0x5c, 0x1d, 0xad, 0xc6, 0x28, 0xea, 0x04, 0xe6, 0x7c, 0x4c, 0xb0, + 0x7f, 0x80, 0xed, 0x6b, 0x9e, 0x2f, 0x2f, 0xdd, 0x5e, 0xca, 0x61, 0xf4, 0x91, 0xd2, 0x69, 0x9e, + 0x92, 0x2a, 0xcd, 0xa1, 0x88, 0x30, 0x8a, 0x73, 0xd1, 0x5b, 0xb0, 0x62, 0xe3, 0xf8, 0xed, 0x25, + 0x4f, 0x2b, 0xd8, 0xe6, 0x15, 0xb1, 0x1c, 0xdd, 0x7b, 0x6e, 0xa5, 0x01, 0xa1, 0x74, 0x5c, 0xe3, + 0xef, 0x1a, 0xac, 0x28, 0x92, 0xbd, 0x81, 0xbb, 0xbd, 0x8e, 0x45, 0x8f, 0x62, 0xac, 0xbc, 0xad, + 0xb4, 0x3f, 0x2f, 0xe4, 0x30, 0x5f, 0x20, 0x64, 0x56, 0x1b, 0x64, 0xfc, 0x4d, 0x83, 0x33, 0xa9, + 0x18, 0x47, 0x90, 0x68, 0xdf, 0x52, 0x13, 0xed, 0xc5, 0x29, 0xf4, 0xca, 0x48, 0xb3, 0x8f, 0xb3, + 0xb4, 0x6a, 0x89, 0x31, 0xe9, 0xb3, 0xd7, 0xaf, 0x1a, 0x1f, 0x14, 0x95, 0xb6, 0x9b, 0x1c, 0x45, + 0x7f, 0xa2, 0x66, 0x94, 0xc2, 0x44, 0x19, 0x65, 0x24, 0xd1, 0x16, 0x73, 0x26, 0x5a, 0x42, 0xa6, + 0x4b, 0xb4, 0xb7, 0x61, 0x5e, 0xad, 0x3e, 0xa5, 0x09, 0xdf, 0xbb, 0x38, 0xe9, 0x96, 0x52, 0x9d, + 0x54, 0x4a, 0xfa, 0x2b, 0xb0, 0x4c, 0xa8, 0xdf, 0x6f, 0xd3, 0xbe, 0x8f, 0xed, 0xd8, 0x83, 0xc5, + 0x71, 0x9e, 0x4f, 0xaa, 0xc3, 0x41, 0x7d, 0xb9, 0x95, 0xb2, 0x8f, 0x52, 0xb1, 0x92, 0x9d, 0x33, + 0x21, 0x9f, 0xe6, 0xce, 0x99, 0x64, 0x75, 0x32, 0xef, 0xab, 0x9d, 0x73, 0xdc, 0x6b, 0x9f, 0x85, + 0xce, 0x79, 0x4c, 0x94, 0x8d, 0xed, 0x9c, 0x69, 0xca, 0xbb, 0x95, 0xa8, 0x6a, 0x87, 0x94, 0xcd, + 0xe4, 0xf3, 0x54, 0xae, 0x87, 0xab, 0x37, 0x61, 0xe6, 0x0e, 0xbf, 0x7e, 0x9f, 0xb0, 0xef, 0x0e, + 0x14, 0x15, 0x77, 0xf6, 0xe6, 0x82, 0x64, 0x35, 0x23, 0xbe, 0x09, 0x0a, 0xa8, 0x25, 0x3b, 0xed, + 0xb8, 0x55, 0x3e, 0xcd, 0x9d, 0x76, 0x5c, 0xce, 0x8c, 0xf8, 0xfc, 0xb3, 0xda, 0x69, 0xa7, 0xfa, + 0xfb, 0xe8, 0x3b, 0x6d, 0x36, 0x79, 0xb1, 0xbf, 0xa4, 0x67, 0xb5, 0x83, 0x09, 0x3d, 0x9c, 0xbc, + 0x6e, 0x04, 0x1b, 0x28, 0x82, 0x31, 0x3e, 0xd0, 0xa0, 0xa2, 0xba, 0x73, 0xaa, 0x46, 0xef, 0xa1, + 0x06, 0xa7, 0x7c, 0x85, 0x4c, 0xfc, 0xfd, 0xf8, 0x42, 0x9e, 0x70, 0x12, 0x97, 0xc7, 0x4f, 0x49, + 0x86, 0xa7, 0x52, 0x36, 0x51, 0x1a, 0x2b, 0xe3, 0x07, 0x1a, 0xa4, 0x01, 0xeb, 0x6e, 0xc6, 0xfb, + 0xc0, 0x66, 0x9e, 0xf7, 0x01, 0x19, 0xe9, 0x93, 0x3c, 0x0e, 0xfc, 0x33, 0x66, 0x51, 0xf1, 0x7b, + 0x89, 0xa9, 0x2c, 0xba, 0x0e, 0x25, 0x7e, 0x2c, 0x12, 0xd1, 0xb0, 0x65, 0x51, 0x0b, 0xf1, 0x1d, + 0xdd, 0x87, 0x4a, 0x54, 0x00, 0xd8, 0x3a, 0x2f, 0x18, 0x87, 0x5e, 0xf9, 0x46, 0xa5, 0x24, 0xf1, + 0xf3, 0x0f, 0xae, 0x5c, 0x4b, 0xa1, 0x88, 0x12, 0x1c, 0x8c, 0x9f, 0x14, 0x60, 0x21, 0xf1, 0x6a, + 0x9d, 0xfa, 0xd6, 0xae, 0x7d, 0xd2, 0x6f, 0xed, 0xdf, 0xd7, 0x60, 0xd9, 0x57, 0x05, 0x89, 0x47, + 0xdc, 0x66, 0xae, 0x87, 0x77, 0x11, 0x72, 0x6b, 0x92, 0xfd, 0x72, 0xda, 0x2e, 0x4a, 0xe5, 0x66, + 0xfc, 0x48, 0x83, 0x54, 0x70, 0xdd, 0xcb, 0x88, 0xba, 0x8b, 0xf9, 0x5e, 0xa5, 0xc4, 0xef, 0x02, + 0x26, 0x09, 0xbb, 0x3f, 0x14, 0xa1, 0x9a, 0xe5, 0x5a, 0xfd, 0x7b, 0x1a, 0xac, 0x08, 0x13, 0x26, + 0x72, 0xd5, 0x74, 0x8e, 0x0a, 0x47, 0x9c, 0x5b, 0x69, 0x34, 0x51, 0x3a, 0x2b, 0x55, 0x88, 0xf8, + 0xbc, 0x3b, 0xdd, 0x2f, 0x33, 0x46, 0x85, 0x50, 0x66, 0xe8, 0x74, 0x56, 0xca, 0x13, 0x5a, 0xe9, + 0xd0, 0x27, 0xb4, 0x6f, 0xc3, 0x8c, 0xcf, 0xa7, 0x50, 0xd6, 0x8c, 0x4d, 0xf0, 0x34, 0x9a, 0xfe, + 0x53, 0x9f, 0xa8, 0x40, 0x8a, 0x6f, 0x82, 0x02, 0xaa, 0xc6, 0xef, 0x34, 0x18, 0x89, 0xf6, 0xa9, + 0xd2, 0x85, 0x05, 0xd0, 0xfb, 0x1f, 0x0d, 0x1a, 0xb2, 0x88, 0x59, 0x31, 0x46, 0xd4, 0x34, 0x1f, + 0x3d, 0xa9, 0x1d, 0x7b, 0xfc, 0xa4, 0x76, 0xec, 0xa3, 0x27, 0xb5, 0x63, 0x0f, 0x87, 0x35, 0xed, + 0xd1, 0xb0, 0xa6, 0x3d, 0x1e, 0xd6, 0xb4, 0x8f, 0x86, 0x35, 0xed, 0x5f, 0xc3, 0x9a, 0xf6, 0xde, + 0xbf, 0x6b, 0xc7, 0xde, 0x5e, 0x1b, 0xf7, 0xa3, 0xc0, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x15, + 0x38, 0x05, 0x05, 0x33, 0x28, 0x00, 0x00, } func (m *AllocationResult) Marshal() (dAtA []byte, err error) { @@ -1263,6 +1551,18 @@ func (m *AllocationResultModel) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.NamedResources != nil { + { + size, err := m.NamedResources.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } return len(dAtA) - i, nil } @@ -1361,6 +1661,350 @@ func (m *DriverRequests) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *NamedResourcesAllocationResult) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NamedResourcesAllocationResult) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NamedResourcesAllocationResult) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *NamedResourcesAttribute) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NamedResourcesAttribute) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NamedResourcesAttribute) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.NamedResourcesAttributeValue.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *NamedResourcesAttributeValue) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NamedResourcesAttributeValue) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NamedResourcesAttributeValue) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.StringSliceValue != nil { + { + size, err := m.StringSliceValue.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x4a + } + if m.IntSliceValue != nil { + { + size, err := m.IntSliceValue.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } + if m.IntValue != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.IntValue)) + i-- + dAtA[i] = 0x38 + } + if m.QuantityValue != nil { + { + size, err := m.QuantityValue.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + if m.StringValue != nil { + i -= len(*m.StringValue) + copy(dAtA[i:], *m.StringValue) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.StringValue))) + i-- + dAtA[i] = 0x2a + } + if m.BoolValue != nil { + i-- + if *m.BoolValue { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } + return len(dAtA) - i, nil +} + +func (m *NamedResourcesFilter) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NamedResourcesFilter) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NamedResourcesFilter) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Selector) + copy(dAtA[i:], m.Selector) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Selector))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *NamedResourcesInstance) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NamedResourcesInstance) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NamedResourcesInstance) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Attributes) > 0 { + for iNdEx := len(m.Attributes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Attributes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *NamedResourcesIntSlice) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NamedResourcesIntSlice) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NamedResourcesIntSlice) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Ints) > 0 { + for iNdEx := len(m.Ints) - 1; iNdEx >= 0; iNdEx-- { + i = encodeVarintGenerated(dAtA, i, uint64(m.Ints[iNdEx])) + i-- + dAtA[i] = 0x8 + } + } + return len(dAtA) - i, nil +} + +func (m *NamedResourcesRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NamedResourcesRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NamedResourcesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Selector) + copy(dAtA[i:], m.Selector) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Selector))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *NamedResourcesResources) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NamedResourcesResources) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NamedResourcesResources) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Instances) > 0 { + for iNdEx := len(m.Instances) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Instances[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *NamedResourcesStringSlice) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NamedResourcesStringSlice) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NamedResourcesStringSlice) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Strings) > 0 { + for iNdEx := len(m.Strings) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Strings[iNdEx]) + copy(dAtA[i:], m.Strings[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Strings[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func (m *NodeResourceModel) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1381,6 +2025,18 @@ func (m *NodeResourceModel) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.NamedResources != nil { + { + size, err := m.NamedResources.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } return len(dAtA) - i, nil } @@ -2570,6 +3226,18 @@ func (m *ResourceFilterModel) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.NamedResources != nil { + { + size, err := m.NamedResources.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } return len(dAtA) - i, nil } @@ -2681,6 +3349,18 @@ func (m *ResourceRequestModel) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.NamedResources != nil { + { + size, err := m.NamedResources.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } return len(dAtA) - i, nil } @@ -2821,6 +3501,10 @@ func (m *AllocationResultModel) Size() (n int) { } var l int _ = l + if m.NamedResources != nil { + l = m.NamedResources.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -2856,12 +3540,154 @@ func (m *DriverRequests) Size() (n int) { return n } +func (m *NamedResourcesAllocationResult) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *NamedResourcesAttribute) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + l = m.NamedResourcesAttributeValue.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *NamedResourcesAttributeValue) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BoolValue != nil { + n += 2 + } + if m.StringValue != nil { + l = len(*m.StringValue) + n += 1 + l + sovGenerated(uint64(l)) + } + if m.QuantityValue != nil { + l = m.QuantityValue.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.IntValue != nil { + n += 1 + sovGenerated(uint64(*m.IntValue)) + } + if m.IntSliceValue != nil { + l = m.IntSliceValue.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.StringSliceValue != nil { + l = m.StringSliceValue.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *NamedResourcesFilter) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Selector) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *NamedResourcesInstance) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Attributes) > 0 { + for _, e := range m.Attributes { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *NamedResourcesIntSlice) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Ints) > 0 { + for _, e := range m.Ints { + n += 1 + sovGenerated(uint64(e)) + } + } + return n +} + +func (m *NamedResourcesRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Selector) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *NamedResourcesResources) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Instances) > 0 { + for _, e := range m.Instances { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *NamedResourcesStringSlice) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Strings) > 0 { + for _, s := range m.Strings { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + func (m *NodeResourceModel) Size() (n int) { if m == nil { return 0 } var l int _ = l + if m.NamedResources != nil { + l = m.NamedResources.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -3286,6 +4112,10 @@ func (m *ResourceFilterModel) Size() (n int) { } var l int _ = l + if m.NamedResources != nil { + l = m.NamedResources.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -3325,6 +4155,10 @@ func (m *ResourceRequestModel) Size() (n int) { } var l int _ = l + if m.NamedResources != nil { + l = m.NamedResources.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -3390,6 +4224,7 @@ func (this *AllocationResultModel) String() string { return "nil" } s := strings.Join([]string{`&AllocationResultModel{`, + `NamedResources:` + strings.Replace(this.NamedResources.String(), "NamedResourcesAllocationResult", "NamedResourcesAllocationResult", 1) + `,`, `}`, }, "") return s @@ -3422,11 +4257,119 @@ func (this *DriverRequests) String() string { }, "") return s } +func (this *NamedResourcesAllocationResult) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NamedResourcesAllocationResult{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `}`, + }, "") + return s +} +func (this *NamedResourcesAttribute) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NamedResourcesAttribute{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `NamedResourcesAttributeValue:` + strings.Replace(strings.Replace(this.NamedResourcesAttributeValue.String(), "NamedResourcesAttributeValue", "NamedResourcesAttributeValue", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *NamedResourcesAttributeValue) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NamedResourcesAttributeValue{`, + `BoolValue:` + valueToStringGenerated(this.BoolValue) + `,`, + `StringValue:` + valueToStringGenerated(this.StringValue) + `,`, + `QuantityValue:` + strings.Replace(fmt.Sprintf("%v", this.QuantityValue), "Quantity", "resource.Quantity", 1) + `,`, + `IntValue:` + valueToStringGenerated(this.IntValue) + `,`, + `IntSliceValue:` + strings.Replace(this.IntSliceValue.String(), "NamedResourcesIntSlice", "NamedResourcesIntSlice", 1) + `,`, + `StringSliceValue:` + strings.Replace(this.StringSliceValue.String(), "NamedResourcesStringSlice", "NamedResourcesStringSlice", 1) + `,`, + `}`, + }, "") + return s +} +func (this *NamedResourcesFilter) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NamedResourcesFilter{`, + `Selector:` + fmt.Sprintf("%v", this.Selector) + `,`, + `}`, + }, "") + return s +} +func (this *NamedResourcesInstance) String() string { + if this == nil { + return "nil" + } + repeatedStringForAttributes := "[]NamedResourcesAttribute{" + for _, f := range this.Attributes { + repeatedStringForAttributes += strings.Replace(strings.Replace(f.String(), "NamedResourcesAttribute", "NamedResourcesAttribute", 1), `&`, ``, 1) + "," + } + repeatedStringForAttributes += "}" + s := strings.Join([]string{`&NamedResourcesInstance{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Attributes:` + repeatedStringForAttributes + `,`, + `}`, + }, "") + return s +} +func (this *NamedResourcesIntSlice) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NamedResourcesIntSlice{`, + `Ints:` + fmt.Sprintf("%v", this.Ints) + `,`, + `}`, + }, "") + return s +} +func (this *NamedResourcesRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NamedResourcesRequest{`, + `Selector:` + fmt.Sprintf("%v", this.Selector) + `,`, + `}`, + }, "") + return s +} +func (this *NamedResourcesResources) String() string { + if this == nil { + return "nil" + } + repeatedStringForInstances := "[]NamedResourcesInstance{" + for _, f := range this.Instances { + repeatedStringForInstances += strings.Replace(strings.Replace(f.String(), "NamedResourcesInstance", "NamedResourcesInstance", 1), `&`, ``, 1) + "," + } + repeatedStringForInstances += "}" + s := strings.Join([]string{`&NamedResourcesResources{`, + `Instances:` + repeatedStringForInstances + `,`, + `}`, + }, "") + return s +} +func (this *NamedResourcesStringSlice) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NamedResourcesStringSlice{`, + `Strings:` + fmt.Sprintf("%v", this.Strings) + `,`, + `}`, + }, "") + return s +} func (this *NodeResourceModel) String() string { if this == nil { return "nil" } s := strings.Join([]string{`&NodeResourceModel{`, + `NamedResources:` + strings.Replace(this.NamedResources.String(), "NamedResourcesResources", "NamedResourcesResources", 1) + `,`, `}`, }, "") return s @@ -3778,6 +4721,7 @@ func (this *ResourceFilterModel) String() string { return "nil" } s := strings.Join([]string{`&ResourceFilterModel{`, + `NamedResources:` + strings.Replace(this.NamedResources.String(), "NamedResourcesFilter", "NamedResourcesFilter", 1) + `,`, `}`, }, "") return s @@ -3810,6 +4754,7 @@ func (this *ResourceRequestModel) String() string { return "nil" } s := strings.Join([]string{`&ResourceRequestModel{`, + `NamedResources:` + strings.Replace(this.NamedResources.String(), "NamedResourcesRequest", "NamedResourcesRequest", 1) + `,`, `}`, }, "") return s @@ -4020,6 +4965,42 @@ func (m *AllocationResultModel) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: AllocationResultModel: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NamedResources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NamedResources == nil { + m.NamedResources = &NamedResourcesAllocationResult{} + } + if err := m.NamedResources.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -4306,6 +5287,1007 @@ func (m *DriverRequests) Unmarshal(dAtA []byte) error { } return nil } +func (m *NamedResourcesAllocationResult) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NamedResourcesAllocationResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NamedResourcesAllocationResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NamedResourcesAttribute) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NamedResourcesAttribute: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NamedResourcesAttribute: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NamedResourcesAttributeValue", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.NamedResourcesAttributeValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NamedResourcesAttributeValue) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NamedResourcesAttributeValue: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NamedResourcesAttributeValue: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BoolValue", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.BoolValue = &b + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StringValue", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.StringValue = &s + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field QuantityValue", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.QuantityValue == nil { + m.QuantityValue = &resource.Quantity{} + } + if err := m.QuantityValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IntValue", wireType) + } + var v int64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IntValue = &v + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IntSliceValue", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.IntSliceValue == nil { + m.IntSliceValue = &NamedResourcesIntSlice{} + } + if err := m.IntSliceValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StringSliceValue", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.StringSliceValue == nil { + m.StringSliceValue = &NamedResourcesStringSlice{} + } + if err := m.StringSliceValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NamedResourcesFilter) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NamedResourcesFilter: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NamedResourcesFilter: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Selector", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Selector = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NamedResourcesInstance) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NamedResourcesInstance: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NamedResourcesInstance: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Attributes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Attributes = append(m.Attributes, NamedResourcesAttribute{}) + if err := m.Attributes[len(m.Attributes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NamedResourcesIntSlice) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NamedResourcesIntSlice: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NamedResourcesIntSlice: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType == 0 { + var v int64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Ints = append(m.Ints, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.Ints) == 0 { + m.Ints = make([]int64, 0, elementCount) + } + for iNdEx < postIndex { + var v int64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Ints = append(m.Ints, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field Ints", wireType) + } + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NamedResourcesRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NamedResourcesRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NamedResourcesRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Selector", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Selector = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NamedResourcesResources) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NamedResourcesResources: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NamedResourcesResources: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Instances", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Instances = append(m.Instances, NamedResourcesInstance{}) + if err := m.Instances[len(m.Instances)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NamedResourcesStringSlice) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NamedResourcesStringSlice: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NamedResourcesStringSlice: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Strings", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Strings = append(m.Strings, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *NodeResourceModel) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -4335,6 +6317,42 @@ func (m *NodeResourceModel) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: NodeResourceModel: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NamedResources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NamedResources == nil { + m.NamedResources = &NamedResourcesResources{} + } + if err := m.NamedResources.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -7733,6 +9751,42 @@ func (m *ResourceFilterModel) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: ResourceFilterModel: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NamedResources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NamedResources == nil { + m.NamedResources = &NamedResourcesFilter{} + } + if err := m.NamedResources.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -8049,6 +10103,42 @@ func (m *ResourceRequestModel) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: ResourceRequestModel: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NamedResources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NamedResources == nil { + m.NamedResources = &NamedResourcesRequest{} + } + if err := m.NamedResources.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/staging/src/k8s.io/api/resource/v1alpha2/generated.proto b/staging/src/k8s.io/api/resource/v1alpha2/generated.proto index 2248d551d9d..e5ddc261137 100644 --- a/staging/src/k8s.io/api/resource/v1alpha2/generated.proto +++ b/staging/src/k8s.io/api/resource/v1alpha2/generated.proto @@ -22,6 +22,7 @@ syntax = "proto2"; package k8s.io.api.resource.v1alpha2; import "k8s.io/api/core/v1/generated.proto"; +import "k8s.io/apimachinery/pkg/api/resource/generated.proto"; import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; import "k8s.io/apimachinery/pkg/runtime/generated.proto"; import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; @@ -65,6 +66,10 @@ message AllocationResult { // AllocationResultModel must have one and only one field set. message AllocationResultModel { + // NamedResources describes the allocation result when using the named resources model. + // + // +optional + optional NamedResourcesAllocationResult namedResources = 1; } // DriverAllocationResult contains vendor parameters and the allocation result for @@ -95,8 +100,117 @@ message DriverRequests { repeated ResourceRequest requests = 3; } +// NamedResourcesAllocationResult is used in AllocationResultModel. +message NamedResourcesAllocationResult { + // Name is the name of the selected resource instance. + optional string name = 1; +} + +// NamedResourcesAttribute is a combination of an attribute name and its value. +message NamedResourcesAttribute { + // Name is unique identifier among all resource instances managed by + // the driver on the node. It must be a DNS subdomain. + optional string name = 1; + + optional NamedResourcesAttributeValue attributeValue = 2; +} + +// NamedResourcesAttributeValue must have one and only one field set. +message NamedResourcesAttributeValue { + // QuantityValue is a quantity. + optional k8s.io.apimachinery.pkg.api.resource.Quantity quantity = 6; + + // BoolValue is a true/false value. + optional bool bool = 2; + + // IntValue is a 64-bit integer. + optional int64 int = 7; + + // IntSliceValue is an array of 64-bit integers. + optional NamedResourcesIntSlice intSlice = 8; + + // StringValue is a string. + optional string string = 5; + + // StringSliceValue is an array of strings. + optional NamedResourcesStringSlice stringSlice = 9; +} + +// NamedResourcesFilter is used in ResourceFilterModel. +message NamedResourcesFilter { + // Selector is a CEL expression which must evaluate to true if a + // resource instance is suitable. The language is as defined in + // https://kubernetes.io/docs/reference/using-api/cel/ + // + // In addition, for each type NamedResourcesin AttributeValue there is a map that + // resolves to the corresponding value of the instance under evaluation. + // For example: + // + // attributes.quantity["a"].isGreaterThan(quantity("0")) && + // attributes.stringslice["b"].isSorted() + optional string selector = 1; +} + +// NamedResourcesInstance represents one individual hardware instance that can be selected based +// on its attributes. +message NamedResourcesInstance { + // Name is unique identifier among all resource instances managed by + // the driver on the node. It must be a DNS subdomain. + optional string name = 1; + + // Attributes defines the attributes of this resource instance. + // The name of each attribute must be unique. + // + // +listType=atomic + // +optional + repeated NamedResourcesAttribute attributes = 2; +} + +// NamedResourcesIntSlice contains a slice of 64-bit integers. +message NamedResourcesIntSlice { + // Ints is the slice of 64-bit integers. + // + // +listType=atomic + repeated int64 ints = 1; +} + +// NamedResourcesRequest is used in ResourceRequestModel. +message NamedResourcesRequest { + // Selector is a CEL expression which must evaluate to true if a + // resource instance is suitable. The language is as defined in + // https://kubernetes.io/docs/reference/using-api/cel/ + // + // In addition, for each type NamedResourcesin AttributeValue there is a map that + // resolves to the corresponding value of the instance under evaluation. + // For example: + // + // attributes.quantity["a"].isGreaterThan(quantity("0")) && + // attributes.stringslice["b"].isSorted() + optional string selector = 1; +} + +// NamedResourcesResources is used in NodeResourceModel. +message NamedResourcesResources { + // The list of all individual resources instances currently available. + // + // +listType=atomic + repeated NamedResourcesInstance instances = 1; +} + +// NamedResourcesStringSlice contains a slice of strings. +message NamedResourcesStringSlice { + // Strings is the slice of strings. + // + // +listType=atomic + repeated string strings = 1; +} + // NodeResourceModel must have one and only one field set. message NodeResourceModel { + // NamedResources describes available resources using the named resources model. + // + // +optional + optional NamedResourcesResources namedResources = 1; } // NodeResourceSlice provides information about available @@ -536,6 +650,10 @@ message ResourceFilter { // ResourceFilterModel must have one and only one field set. message ResourceFilterModel { + // NamedResources describes a resource filter using the named resources model. + // + // +optional + optional NamedResourcesFilter namedResources = 1; } // ResourceHandle holds opaque resource data for processing by a specific kubelet plugin. @@ -577,6 +695,10 @@ message ResourceRequest { // ResourceRequestModel must have one and only one field set. message ResourceRequestModel { + // NamedResources describes a request for resources with the named resources model. + // + // +optional + optional NamedResourcesRequest namedResources = 1; } // StructuredResourceHandle is the in-tree representation of the allocation result. diff --git a/staging/src/k8s.io/api/resource/v1alpha2/namedresources.go b/staging/src/k8s.io/api/resource/v1alpha2/namedresources.go new file mode 100644 index 00000000000..1af5c7d234e --- /dev/null +++ b/staging/src/k8s.io/api/resource/v1alpha2/namedresources.go @@ -0,0 +1,137 @@ +/* +Copyright 2023 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 v1alpha2 + +import ( + "k8s.io/apimachinery/pkg/api/resource" +) + +// NamedResourcesResources is used in NodeResourceModel. +type NamedResourcesResources struct { + // The list of all individual resources instances currently available. + // + // +listType=atomic + Instances []NamedResourcesInstance `json:"instances" protobuf:"bytes,1,name=instances"` +} + +// NamedResourcesInstance represents one individual hardware instance that can be selected based +// on its attributes. +type NamedResourcesInstance struct { + // Name is unique identifier among all resource instances managed by + // the driver on the node. It must be a DNS subdomain. + Name string `json:"name" protobuf:"bytes,1,name=name"` + + // Attributes defines the attributes of this resource instance. + // The name of each attribute must be unique. + // + // +listType=atomic + // +optional + Attributes []NamedResourcesAttribute `json:"attributes,omitempty" protobuf:"bytes,2,opt,name=attributes"` +} + +// NamedResourcesAttribute is a combination of an attribute name and its value. +type NamedResourcesAttribute struct { + // Name is unique identifier among all resource instances managed by + // the driver on the node. It must be a DNS subdomain. + Name string `json:"name" protobuf:"bytes,1,name=name"` + + NamedResourcesAttributeValue `json:",inline" protobuf:"bytes,2,opt,name=attributeValue"` +} + +// The Go field names below have a Value suffix to avoid a conflict between the +// field "String" and the corresponding method. That method is required. +// The Kubernetes API is defined without that suffix to keep it more natural. + +// NamedResourcesAttributeValue must have one and only one field set. +type NamedResourcesAttributeValue struct { + // QuantityValue is a quantity. + QuantityValue *resource.Quantity `json:"quantity,omitempty" protobuf:"bytes,6,opt,name=quantity"` + // BoolValue is a true/false value. + BoolValue *bool `json:"bool,omitempty" protobuf:"bytes,2,opt,name=bool"` + // IntValue is a 64-bit integer. + IntValue *int64 `json:"int,omitempty" protobuf:"varint,7,opt,name=int"` + // IntSliceValue is an array of 64-bit integers. + IntSliceValue *NamedResourcesIntSlice `json:"intSlice,omitempty" protobuf:"varint,8,rep,name=intSlice"` + // StringValue is a string. + StringValue *string `json:"string,omitempty" protobuf:"bytes,5,opt,name=string"` + // StringSliceValue is an array of strings. + StringSliceValue *NamedResourcesStringSlice `json:"stringSlice,omitempty" protobuf:"bytes,9,rep,name=stringSlice"` + // TODO: VersionValue *SemVersion `json:"version,omitempty" protobuf:"bytes,7,opt,name=version"` +} + +// NamedResourcesIntSlice contains a slice of 64-bit integers. +type NamedResourcesIntSlice struct { + // Ints is the slice of 64-bit integers. + // + // +listType=atomic + Ints []int64 `json:"ints" protobuf:"bytes,1,opt,name=ints"` +} + +// NamedResourcesStringSlice contains a slice of strings. +type NamedResourcesStringSlice struct { + // Strings is the slice of strings. + // + // +listType=atomic + Strings []string `json:"strings" protobuf:"bytes,1,opt,name=strings"` +} + +// TODO +// +// A wrapper around https://pkg.go.dev/github.com/blang/semver/v4#Version which +// is encoded as a string. During decoding, it validates that the string +// can be parsed using tolerant parsing (currently trims spaces, removes a "v" prefix, +// adds a 0 patch number to versions with only major and minor components specified, +// and removes leading 0s). +// type NamedResourcesSemVersion struct { +// semver.Version +//} + +// NamedResourcesRequest is used in ResourceRequestModel. +type NamedResourcesRequest struct { + // Selector is a CEL expression which must evaluate to true if a + // resource instance is suitable. The language is as defined in + // https://kubernetes.io/docs/reference/using-api/cel/ + // + // In addition, for each type NamedResourcesin AttributeValue there is a map that + // resolves to the corresponding value of the instance under evaluation. + // For example: + // + // attributes.quantity["a"].isGreaterThan(quantity("0")) && + // attributes.stringslice["b"].isSorted() + Selector string `json:"selector" protobuf:"bytes,1,name=selector"` +} + +// NamedResourcesFilter is used in ResourceFilterModel. +type NamedResourcesFilter struct { + // Selector is a CEL expression which must evaluate to true if a + // resource instance is suitable. The language is as defined in + // https://kubernetes.io/docs/reference/using-api/cel/ + // + // In addition, for each type NamedResourcesin AttributeValue there is a map that + // resolves to the corresponding value of the instance under evaluation. + // For example: + // + // attributes.quantity["a"].isGreaterThan(quantity("0")) && + // attributes.stringslice["b"].isSorted() + Selector string `json:"selector" protobuf:"bytes,1,name=selector"` +} + +// NamedResourcesAllocationResult is used in AllocationResultModel. +type NamedResourcesAllocationResult struct { + // Name is the name of the selected resource instance. + Name string `json:"name" protobuf:"bytes,1,name=name"` +} diff --git a/staging/src/k8s.io/api/resource/v1alpha2/types.go b/staging/src/k8s.io/api/resource/v1alpha2/types.go index 7fcbba38511..01ffb0b4831 100644 --- a/staging/src/k8s.io/api/resource/v1alpha2/types.go +++ b/staging/src/k8s.io/api/resource/v1alpha2/types.go @@ -247,7 +247,10 @@ type DriverAllocationResult struct { // AllocationResultModel must have one and only one field set. type AllocationResultModel struct { - // TODO: implement one structured parameter model + // NamedResources describes the allocation result when using the named resources model. + // + // +optional + NamedResources *NamedResourcesAllocationResult `json:"namedResources,omitempty" protobuf:"bytes,1,opt,name=namedResources"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -549,7 +552,10 @@ type NodeResourceSlice struct { // NodeResourceModel must have one and only one field set. type NodeResourceModel struct { - // TODO: implement one structured parameter model + // NamedResources describes available resources using the named resources model. + // + // +optional + NamedResources *NamedResourcesResources `json:"namedResources,omitempty" protobuf:"bytes,1,opt,name=namedResources"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -629,7 +635,10 @@ type ResourceRequest struct { // ResourceRequestModel must have one and only one field set. type ResourceRequestModel struct { - // TODO: implement one structured parameter model + // NamedResources describes a request for resources with the named resources model. + // + // +optional + NamedResources *NamedResourcesRequest `json:"namedResources,omitempty" protobuf:"bytes,1,opt,name=namedResources"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -688,7 +697,10 @@ type ResourceFilter struct { // ResourceFilterModel must have one and only one field set. type ResourceFilterModel struct { - // TODO: implement one structured parameter model + // NamedResources describes a resource filter using the named resources model. + // + // +optional + NamedResources *NamedResourcesFilter `json:"namedResources,omitempty" protobuf:"bytes,1,opt,name=namedResources"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/staging/src/k8s.io/api/resource/v1alpha2/types_swagger_doc_generated.go b/staging/src/k8s.io/api/resource/v1alpha2/types_swagger_doc_generated.go index e46c6e06ddb..3bfb1ee1541 100644 --- a/staging/src/k8s.io/api/resource/v1alpha2/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/resource/v1alpha2/types_swagger_doc_generated.go @@ -39,7 +39,8 @@ func (AllocationResult) SwaggerDoc() map[string]string { } var map_AllocationResultModel = map[string]string{ - "": "AllocationResultModel must have one and only one field set.", + "": "AllocationResultModel must have one and only one field set.", + "namedResources": "NamedResources describes the allocation result when using the named resources model.", } func (AllocationResultModel) SwaggerDoc() map[string]string { @@ -67,7 +68,8 @@ func (DriverRequests) SwaggerDoc() map[string]string { } var map_NodeResourceModel = map[string]string{ - "": "NodeResourceModel must have one and only one field set.", + "": "NodeResourceModel must have one and only one field set.", + "namedResources": "NamedResources describes available resources using the named resources model.", } func (NodeResourceModel) SwaggerDoc() map[string]string { @@ -331,7 +333,8 @@ func (ResourceFilter) SwaggerDoc() map[string]string { } var map_ResourceFilterModel = map[string]string{ - "": "ResourceFilterModel must have one and only one field set.", + "": "ResourceFilterModel must have one and only one field set.", + "namedResources": "NamedResources describes a resource filter using the named resources model.", } func (ResourceFilterModel) SwaggerDoc() map[string]string { @@ -359,7 +362,8 @@ func (ResourceRequest) SwaggerDoc() map[string]string { } var map_ResourceRequestModel = map[string]string{ - "": "ResourceRequestModel must have one and only one field set.", + "": "ResourceRequestModel must have one and only one field set.", + "namedResources": "NamedResources describes a request for resources with the named resources model.", } func (ResourceRequestModel) SwaggerDoc() map[string]string { diff --git a/staging/src/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go b/staging/src/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go index 76a11096e7a..f5d3a01bb1b 100644 --- a/staging/src/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go @@ -57,6 +57,11 @@ func (in *AllocationResult) DeepCopy() *AllocationResult { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AllocationResultModel) DeepCopyInto(out *AllocationResultModel) { *out = *in + if in.NamedResources != nil { + in, out := &in.NamedResources, &out.NamedResources + *out = new(NamedResourcesAllocationResult) + **out = **in + } return } @@ -74,7 +79,7 @@ func (in *AllocationResultModel) DeepCopy() *AllocationResultModel { func (in *DriverAllocationResult) DeepCopyInto(out *DriverAllocationResult) { *out = *in in.VendorRequestParameters.DeepCopyInto(&out.VendorRequestParameters) - out.AllocationResultModel = in.AllocationResultModel + in.AllocationResultModel.DeepCopyInto(&out.AllocationResultModel) return } @@ -112,9 +117,213 @@ func (in *DriverRequests) DeepCopy() *DriverRequests { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedResourcesAllocationResult) DeepCopyInto(out *NamedResourcesAllocationResult) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedResourcesAllocationResult. +func (in *NamedResourcesAllocationResult) DeepCopy() *NamedResourcesAllocationResult { + if in == nil { + return nil + } + out := new(NamedResourcesAllocationResult) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedResourcesAttribute) DeepCopyInto(out *NamedResourcesAttribute) { + *out = *in + in.NamedResourcesAttributeValue.DeepCopyInto(&out.NamedResourcesAttributeValue) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedResourcesAttribute. +func (in *NamedResourcesAttribute) DeepCopy() *NamedResourcesAttribute { + if in == nil { + return nil + } + out := new(NamedResourcesAttribute) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedResourcesAttributeValue) DeepCopyInto(out *NamedResourcesAttributeValue) { + *out = *in + if in.QuantityValue != nil { + in, out := &in.QuantityValue, &out.QuantityValue + x := (*in).DeepCopy() + *out = &x + } + if in.BoolValue != nil { + in, out := &in.BoolValue, &out.BoolValue + *out = new(bool) + **out = **in + } + if in.IntValue != nil { + in, out := &in.IntValue, &out.IntValue + *out = new(int64) + **out = **in + } + if in.IntSliceValue != nil { + in, out := &in.IntSliceValue, &out.IntSliceValue + *out = new(NamedResourcesIntSlice) + (*in).DeepCopyInto(*out) + } + if in.StringValue != nil { + in, out := &in.StringValue, &out.StringValue + *out = new(string) + **out = **in + } + if in.StringSliceValue != nil { + in, out := &in.StringSliceValue, &out.StringSliceValue + *out = new(NamedResourcesStringSlice) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedResourcesAttributeValue. +func (in *NamedResourcesAttributeValue) DeepCopy() *NamedResourcesAttributeValue { + if in == nil { + return nil + } + out := new(NamedResourcesAttributeValue) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedResourcesFilter) DeepCopyInto(out *NamedResourcesFilter) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedResourcesFilter. +func (in *NamedResourcesFilter) DeepCopy() *NamedResourcesFilter { + if in == nil { + return nil + } + out := new(NamedResourcesFilter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedResourcesInstance) DeepCopyInto(out *NamedResourcesInstance) { + *out = *in + if in.Attributes != nil { + in, out := &in.Attributes, &out.Attributes + *out = make([]NamedResourcesAttribute, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedResourcesInstance. +func (in *NamedResourcesInstance) DeepCopy() *NamedResourcesInstance { + if in == nil { + return nil + } + out := new(NamedResourcesInstance) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedResourcesIntSlice) DeepCopyInto(out *NamedResourcesIntSlice) { + *out = *in + if in.Ints != nil { + in, out := &in.Ints, &out.Ints + *out = make([]int64, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedResourcesIntSlice. +func (in *NamedResourcesIntSlice) DeepCopy() *NamedResourcesIntSlice { + if in == nil { + return nil + } + out := new(NamedResourcesIntSlice) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedResourcesRequest) DeepCopyInto(out *NamedResourcesRequest) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedResourcesRequest. +func (in *NamedResourcesRequest) DeepCopy() *NamedResourcesRequest { + if in == nil { + return nil + } + out := new(NamedResourcesRequest) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedResourcesResources) DeepCopyInto(out *NamedResourcesResources) { + *out = *in + if in.Instances != nil { + in, out := &in.Instances, &out.Instances + *out = make([]NamedResourcesInstance, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedResourcesResources. +func (in *NamedResourcesResources) DeepCopy() *NamedResourcesResources { + if in == nil { + return nil + } + out := new(NamedResourcesResources) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedResourcesStringSlice) DeepCopyInto(out *NamedResourcesStringSlice) { + *out = *in + if in.Strings != nil { + in, out := &in.Strings, &out.Strings + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedResourcesStringSlice. +func (in *NamedResourcesStringSlice) DeepCopy() *NamedResourcesStringSlice { + if in == nil { + return nil + } + out := new(NamedResourcesStringSlice) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NodeResourceModel) DeepCopyInto(out *NodeResourceModel) { *out = *in + if in.NamedResources != nil { + in, out := &in.NamedResources, &out.NamedResources + *out = new(NamedResourcesResources) + (*in).DeepCopyInto(*out) + } return } @@ -133,7 +342,7 @@ func (in *NodeResourceSlice) DeepCopyInto(out *NodeResourceSlice) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.NodeResourceModel = in.NodeResourceModel + in.NodeResourceModel.DeepCopyInto(&out.NodeResourceModel) return } @@ -697,7 +906,9 @@ func (in *ResourceClassParameters) DeepCopyInto(out *ResourceClassParameters) { if in.Filters != nil { in, out := &in.Filters, &out.Filters *out = make([]ResourceFilter, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } return } @@ -772,7 +983,7 @@ func (in *ResourceClassParametersReference) DeepCopy() *ResourceClassParametersR // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ResourceFilter) DeepCopyInto(out *ResourceFilter) { *out = *in - out.ResourceFilterModel = in.ResourceFilterModel + in.ResourceFilterModel.DeepCopyInto(&out.ResourceFilterModel) return } @@ -789,6 +1000,11 @@ func (in *ResourceFilter) DeepCopy() *ResourceFilter { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ResourceFilterModel) DeepCopyInto(out *ResourceFilterModel) { *out = *in + if in.NamedResources != nil { + in, out := &in.NamedResources, &out.NamedResources + *out = new(NamedResourcesFilter) + **out = **in + } return } @@ -827,7 +1043,7 @@ func (in *ResourceHandle) DeepCopy() *ResourceHandle { func (in *ResourceRequest) DeepCopyInto(out *ResourceRequest) { *out = *in in.VendorParameters.DeepCopyInto(&out.VendorParameters) - out.ResourceRequestModel = in.ResourceRequestModel + in.ResourceRequestModel.DeepCopyInto(&out.ResourceRequestModel) return } @@ -844,6 +1060,11 @@ func (in *ResourceRequest) DeepCopy() *ResourceRequest { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ResourceRequestModel) DeepCopyInto(out *ResourceRequestModel) { *out = *in + if in.NamedResources != nil { + in, out := &in.NamedResources, &out.NamedResources + *out = new(NamedResourcesRequest) + **out = **in + } return } diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.json b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.json index 08001a055a1..fbd9cd70f09 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.json +++ b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.json @@ -44,5 +44,31 @@ ] }, "nodeName": "nodeNameValue", - "driverName": "driverNameValue" + "driverName": "driverNameValue", + "namedResources": { + "instances": [ + { + "name": "nameValue", + "attributes": [ + { + "name": "nameValue", + "quantity": "0", + "bool": true, + "int": 7, + "intSlice": { + "ints": [ + 1 + ] + }, + "string": "stringValue", + "stringSlice": { + "strings": [ + "stringsValue" + ] + } + } + ] + } + ] + } } \ No newline at end of file diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.pb b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.pb index bf5c7af2076035ca5ea50f555c72140d70794a34..b1efc51b7e79e20c6da053e22873f060efac0d89 100644 GIT binary patch delta 90 zcmdnb+|Dw=gz@Y~(^f`b4=y(@7cS1c#N5=d#GKMpA#-GomH?v`cX3HkW?nj2)`*#l Z(ZGV;iHU>Ji;s&3B2x^Ol44L|0061>80`Q6 delta 18 ZcmZo?+0Q(|gt2v_X)7ZugA{`j0{}Dl1VsP< diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.yaml b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.yaml index f1765d1e993..a47bdb4a409 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.yaml @@ -33,4 +33,19 @@ metadata: resourceVersion: resourceVersionValue selfLink: selfLinkValue uid: uidValue +namedResources: + instances: + - attributes: + - bool: true + int: 7 + intSlice: + ints: + - 1 + name: nameValue + quantity: "0" + string: stringValue + stringSlice: + strings: + - stringsValue + name: nameValue nodeName: nodeNameValue diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaim.json b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaim.json index 809fd41137e..3b370ead833 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaim.json +++ b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaim.json @@ -92,6 +92,9 @@ "status": { "available": 1 } + }, + "namedResources": { + "name": "nameValue" } } ] diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaim.pb b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaim.pb index 95dfd8203f4b5df10234ce481b3b79fbc94e9043..b6709816fd46d14bce388c8133669e2431fee03d 100644 GIT binary patch delta 102 zcmeyx-p(<>fbrr+!`+M)Q(3t9Q;IUnQj7c&b5p|-b4pW%PBC+RWWp5YOi3(B1gp@x f#59?aIel_BQz>I9h{eat#m&W;2Qy)ECi6r96+|K2 delta 89 zcmZqY_{BcKfbqyi!`+M)9V}e@DMguOsYQN?xv61^Ii;yWdzrbOFkuRFrX-dmf>mf8 YWtz;$oIbgmsgyAT#A0NaT*f>R0B+_Ty8r+H diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaim.yaml b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaim.yaml index 79ad3c0cdd3..41079295502 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaim.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaim.yaml @@ -59,7 +59,9 @@ status: structuredData: nodeName: nodeNameValue results: - - vendorRequestParameters: + - namedResources: + name: nameValue + vendorRequestParameters: apiVersion: example.com/v1 kind: CustomType spec: diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaimParameters.json b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaimParameters.json index fb4495fe606..aa801a2f5d2 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaimParameters.json +++ b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaimParameters.json @@ -73,6 +73,9 @@ "status": { "available": 1 } + }, + "namedResources": { + "selector": "selectorValue" } } ] diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaimParameters.pb b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaimParameters.pb index 96b724d30723453dbcf7a0d7147e3bde0328282d..33f11f498f18839aa542b918254547a7d25a895c 100644 GIT binary patch delta 50 zcmdnMdXRO36;mVYMw?zn#!r(^F;+5Fa!tO=m?|zL$i>gaTb!Dcnp~1!6qcA%nkvPh G!~g)K`44gc delta 33 pcmX@ex`B0q71IZnjW)fEj1MQDVytA!;F^4wF_le-L5e|%0RYNL3Jw4O diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaimParameters.yaml b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaimParameters.yaml index 5baff21f8dc..9af4582f128 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaimParameters.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClaimParameters.yaml @@ -2,7 +2,9 @@ apiVersion: resource.k8s.io/v1alpha2 driverRequests: - driverName: driverNameValue requests: - - vendorParameters: + - namedResources: + selector: selectorValue + vendorParameters: apiVersion: example.com/v1 kind: CustomType spec: diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClassParameters.json b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClassParameters.json index 84177997e24..17dadf3bb94 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClassParameters.json +++ b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClassParameters.json @@ -66,7 +66,10 @@ ], "filters": [ { - "driverName": "driverNameValue" + "driverName": "driverNameValue", + "namedResources": { + "selector": "selectorValue" + } } ] } \ No newline at end of file diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClassParameters.pb b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceClassParameters.pb index e2c1b15ff5d233ec6ebf43662aa33753e33b91ee..b98a880e769e9f96f9e85e73cb5a85f05ccd759a 100644 GIT binary patch delta 54 zcmaFC@{?tP730p0)}lMHbd6D3;Qj z7tlu@l^7mF57QL9y%8`FcmmhUmS0&+WrF)=C2%Cr;T2)AzNp(N8EDkpU$XWq1W$sg*xcAhDsDiK;2ho-F(?<@?)j0_EXz zHZQnVQ#}JZkT=uBBy(Cs`NyZWE7NF|gbuYj5F`V!j7yo7qmji#q54 a*)dGbm1DGWBi%1&3pQiS`{$l-1=bH#7Q`C> diff --git a/staging/src/k8s.io/api/testdata/v1.29.0/resource.k8s.io.v1alpha2.ResourceClass.after_roundtrip.pb b/staging/src/k8s.io/api/testdata/v1.29.0/resource.k8s.io.v1alpha2.ResourceClass.after_roundtrip.pb deleted file mode 100644 index 99f93ce8e173f493d93bd864453fef5ec0515316..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 565 zcma)2OG?8)7)~ExIyG$!E=rbJ2zF7mPzWyTLQs)XqziYG_HP|Coe48dpo$mp7Op*l zHxPOUapBq<)ai_UP+YkC{^$3ILusKyR1+Y1D*DifL)jqwC_BM4xx-D*>Hbd6D3;Qj z7tlu@l^7mF57QL9y%8`FcmmhUmS0&+WrF)=C2%Cr;T2)AzNp(N8EDkpU$XWq1W$sg*xcAhDsDiK;2ho-F(?<@?)j0_EXz zHZQnVQ#}JZkT=uBBy(Cs`NyZWE7NF|gbuYj5F`V!j7yo7qmji#q54 a*)dGbm1DGWBi%1&3pQiS`{$l-1=bH#7Q`C> diff --git a/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go b/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go index d1f8a5b5240..93121ac8443 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go @@ -11948,6 +11948,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: io.k8s.api.resource.v1alpha2.DriverAllocationResult map: fields: + - name: namedResources + type: + namedType: io.k8s.api.resource.v1alpha2.NamedResourcesAllocationResult - name: vendorRequestParameters type: namedType: __untyped_atomic_ @@ -11966,6 +11969,92 @@ var schemaYAML = typed.YAMLObject(`types: - name: vendorParameters type: namedType: __untyped_atomic_ +- name: io.k8s.api.resource.v1alpha2.NamedResourcesAllocationResult + map: + fields: + - name: name + type: + scalar: string + default: "" +- name: io.k8s.api.resource.v1alpha2.NamedResourcesAttribute + map: + fields: + - name: bool + type: + scalar: boolean + - name: int + type: + scalar: numeric + - name: intSlice + type: + namedType: io.k8s.api.resource.v1alpha2.NamedResourcesIntSlice + - name: name + type: + scalar: string + default: "" + - name: quantity + type: + namedType: io.k8s.apimachinery.pkg.api.resource.Quantity + - name: string + type: + scalar: string + - name: stringSlice + type: + namedType: io.k8s.api.resource.v1alpha2.NamedResourcesStringSlice +- name: io.k8s.api.resource.v1alpha2.NamedResourcesFilter + map: + fields: + - name: selector + type: + scalar: string + default: "" +- name: io.k8s.api.resource.v1alpha2.NamedResourcesInstance + map: + fields: + - name: attributes + type: + list: + elementType: + namedType: io.k8s.api.resource.v1alpha2.NamedResourcesAttribute + elementRelationship: atomic + - name: name + type: + scalar: string + default: "" +- name: io.k8s.api.resource.v1alpha2.NamedResourcesIntSlice + map: + fields: + - name: ints + type: + list: + elementType: + scalar: numeric + elementRelationship: atomic +- name: io.k8s.api.resource.v1alpha2.NamedResourcesRequest + map: + fields: + - name: selector + type: + scalar: string + default: "" +- name: io.k8s.api.resource.v1alpha2.NamedResourcesResources + map: + fields: + - name: instances + type: + list: + elementType: + namedType: io.k8s.api.resource.v1alpha2.NamedResourcesInstance + elementRelationship: atomic +- name: io.k8s.api.resource.v1alpha2.NamedResourcesStringSlice + map: + fields: + - name: strings + type: + list: + elementType: + scalar: string + elementRelationship: atomic - name: io.k8s.api.resource.v1alpha2.NodeResourceSlice map: fields: @@ -11983,6 +12072,9 @@ var schemaYAML = typed.YAMLObject(`types: type: namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta default: {} + - name: namedResources + type: + namedType: io.k8s.api.resource.v1alpha2.NamedResourcesResources - name: nodeName type: scalar: string @@ -12259,6 +12351,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: driverName type: scalar: string + - name: namedResources + type: + namedType: io.k8s.api.resource.v1alpha2.NamedResourcesFilter - name: io.k8s.api.resource.v1alpha2.ResourceHandle map: fields: @@ -12274,6 +12369,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: io.k8s.api.resource.v1alpha2.ResourceRequest map: fields: + - name: namedResources + type: + namedType: io.k8s.api.resource.v1alpha2.NamedResourcesRequest - name: vendorParameters type: namedType: __untyped_atomic_ diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/allocationresultmodel.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/allocationresultmodel.go new file mode 100644 index 00000000000..0c8be0e6aa3 --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/allocationresultmodel.go @@ -0,0 +1,39 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// AllocationResultModelApplyConfiguration represents an declarative configuration of the AllocationResultModel type for use +// with apply. +type AllocationResultModelApplyConfiguration struct { + NamedResources *NamedResourcesAllocationResultApplyConfiguration `json:"namedResources,omitempty"` +} + +// AllocationResultModelApplyConfiguration constructs an declarative configuration of the AllocationResultModel type for use with +// apply. +func AllocationResultModel() *AllocationResultModelApplyConfiguration { + return &AllocationResultModelApplyConfiguration{} +} + +// WithNamedResources sets the NamedResources field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the NamedResources field is set to the value of the last call. +func (b *AllocationResultModelApplyConfiguration) WithNamedResources(value *NamedResourcesAllocationResultApplyConfiguration) *AllocationResultModelApplyConfiguration { + b.NamedResources = value + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/driverallocationresult.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/driverallocationresult.go index 3b0403cca51..a1f082fad7b 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/driverallocationresult.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/driverallocationresult.go @@ -19,15 +19,14 @@ limitations under the License. package v1alpha2 import ( - v1alpha2 "k8s.io/api/resource/v1alpha2" runtime "k8s.io/apimachinery/pkg/runtime" ) // DriverAllocationResultApplyConfiguration represents an declarative configuration of the DriverAllocationResult type for use // with apply. type DriverAllocationResultApplyConfiguration struct { - VendorRequestParameters *runtime.RawExtension `json:"vendorRequestParameters,omitempty"` - v1alpha2.AllocationResultModel `json:",inline"` + VendorRequestParameters *runtime.RawExtension `json:"vendorRequestParameters,omitempty"` + AllocationResultModelApplyConfiguration `json:",inline"` } // DriverAllocationResultApplyConfiguration constructs an declarative configuration of the DriverAllocationResult type for use with @@ -43,3 +42,11 @@ func (b *DriverAllocationResultApplyConfiguration) WithVendorRequestParameters(v b.VendorRequestParameters = &value return b } + +// WithNamedResources sets the NamedResources field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the NamedResources field is set to the value of the last call. +func (b *DriverAllocationResultApplyConfiguration) WithNamedResources(value *NamedResourcesAllocationResultApplyConfiguration) *DriverAllocationResultApplyConfiguration { + b.NamedResources = value + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesallocationresult.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesallocationresult.go new file mode 100644 index 00000000000..311edbac800 --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesallocationresult.go @@ -0,0 +1,39 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// NamedResourcesAllocationResultApplyConfiguration represents an declarative configuration of the NamedResourcesAllocationResult type for use +// with apply. +type NamedResourcesAllocationResultApplyConfiguration struct { + Name *string `json:"name,omitempty"` +} + +// NamedResourcesAllocationResultApplyConfiguration constructs an declarative configuration of the NamedResourcesAllocationResult type for use with +// apply. +func NamedResourcesAllocationResult() *NamedResourcesAllocationResultApplyConfiguration { + return &NamedResourcesAllocationResultApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *NamedResourcesAllocationResultApplyConfiguration) WithName(value string) *NamedResourcesAllocationResultApplyConfiguration { + b.Name = &value + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesattribute.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesattribute.go new file mode 100644 index 00000000000..43cd9044b3a --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesattribute.go @@ -0,0 +1,92 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + resource "k8s.io/apimachinery/pkg/api/resource" +) + +// NamedResourcesAttributeApplyConfiguration represents an declarative configuration of the NamedResourcesAttribute type for use +// with apply. +type NamedResourcesAttributeApplyConfiguration struct { + Name *string `json:"name,omitempty"` + NamedResourcesAttributeValueApplyConfiguration `json:",inline"` +} + +// NamedResourcesAttributeApplyConfiguration constructs an declarative configuration of the NamedResourcesAttribute type for use with +// apply. +func NamedResourcesAttribute() *NamedResourcesAttributeApplyConfiguration { + return &NamedResourcesAttributeApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *NamedResourcesAttributeApplyConfiguration) WithName(value string) *NamedResourcesAttributeApplyConfiguration { + b.Name = &value + return b +} + +// WithQuantityValue sets the QuantityValue field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the QuantityValue field is set to the value of the last call. +func (b *NamedResourcesAttributeApplyConfiguration) WithQuantityValue(value resource.Quantity) *NamedResourcesAttributeApplyConfiguration { + b.QuantityValue = &value + return b +} + +// WithBoolValue sets the BoolValue field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the BoolValue field is set to the value of the last call. +func (b *NamedResourcesAttributeApplyConfiguration) WithBoolValue(value bool) *NamedResourcesAttributeApplyConfiguration { + b.BoolValue = &value + return b +} + +// WithIntValue sets the IntValue field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the IntValue field is set to the value of the last call. +func (b *NamedResourcesAttributeApplyConfiguration) WithIntValue(value int64) *NamedResourcesAttributeApplyConfiguration { + b.IntValue = &value + return b +} + +// WithIntSliceValue sets the IntSliceValue field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the IntSliceValue field is set to the value of the last call. +func (b *NamedResourcesAttributeApplyConfiguration) WithIntSliceValue(value *NamedResourcesIntSliceApplyConfiguration) *NamedResourcesAttributeApplyConfiguration { + b.IntSliceValue = value + return b +} + +// WithStringValue sets the StringValue field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the StringValue field is set to the value of the last call. +func (b *NamedResourcesAttributeApplyConfiguration) WithStringValue(value string) *NamedResourcesAttributeApplyConfiguration { + b.StringValue = &value + return b +} + +// WithStringSliceValue sets the StringSliceValue field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the StringSliceValue field is set to the value of the last call. +func (b *NamedResourcesAttributeApplyConfiguration) WithStringSliceValue(value *NamedResourcesStringSliceApplyConfiguration) *NamedResourcesAttributeApplyConfiguration { + b.StringSliceValue = value + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesattributevalue.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesattributevalue.go new file mode 100644 index 00000000000..ad2c7e185c1 --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesattributevalue.go @@ -0,0 +1,88 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + resource "k8s.io/apimachinery/pkg/api/resource" +) + +// NamedResourcesAttributeValueApplyConfiguration represents an declarative configuration of the NamedResourcesAttributeValue type for use +// with apply. +type NamedResourcesAttributeValueApplyConfiguration struct { + QuantityValue *resource.Quantity `json:"quantity,omitempty"` + BoolValue *bool `json:"bool,omitempty"` + IntValue *int64 `json:"int,omitempty"` + IntSliceValue *NamedResourcesIntSliceApplyConfiguration `json:"intSlice,omitempty"` + StringValue *string `json:"string,omitempty"` + StringSliceValue *NamedResourcesStringSliceApplyConfiguration `json:"stringSlice,omitempty"` +} + +// NamedResourcesAttributeValueApplyConfiguration constructs an declarative configuration of the NamedResourcesAttributeValue type for use with +// apply. +func NamedResourcesAttributeValue() *NamedResourcesAttributeValueApplyConfiguration { + return &NamedResourcesAttributeValueApplyConfiguration{} +} + +// WithQuantityValue sets the QuantityValue field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the QuantityValue field is set to the value of the last call. +func (b *NamedResourcesAttributeValueApplyConfiguration) WithQuantityValue(value resource.Quantity) *NamedResourcesAttributeValueApplyConfiguration { + b.QuantityValue = &value + return b +} + +// WithBoolValue sets the BoolValue field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the BoolValue field is set to the value of the last call. +func (b *NamedResourcesAttributeValueApplyConfiguration) WithBoolValue(value bool) *NamedResourcesAttributeValueApplyConfiguration { + b.BoolValue = &value + return b +} + +// WithIntValue sets the IntValue field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the IntValue field is set to the value of the last call. +func (b *NamedResourcesAttributeValueApplyConfiguration) WithIntValue(value int64) *NamedResourcesAttributeValueApplyConfiguration { + b.IntValue = &value + return b +} + +// WithIntSliceValue sets the IntSliceValue field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the IntSliceValue field is set to the value of the last call. +func (b *NamedResourcesAttributeValueApplyConfiguration) WithIntSliceValue(value *NamedResourcesIntSliceApplyConfiguration) *NamedResourcesAttributeValueApplyConfiguration { + b.IntSliceValue = value + return b +} + +// WithStringValue sets the StringValue field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the StringValue field is set to the value of the last call. +func (b *NamedResourcesAttributeValueApplyConfiguration) WithStringValue(value string) *NamedResourcesAttributeValueApplyConfiguration { + b.StringValue = &value + return b +} + +// WithStringSliceValue sets the StringSliceValue field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the StringSliceValue field is set to the value of the last call. +func (b *NamedResourcesAttributeValueApplyConfiguration) WithStringSliceValue(value *NamedResourcesStringSliceApplyConfiguration) *NamedResourcesAttributeValueApplyConfiguration { + b.StringSliceValue = value + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesfilter.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesfilter.go new file mode 100644 index 00000000000..e483d8622fa --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesfilter.go @@ -0,0 +1,39 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// NamedResourcesFilterApplyConfiguration represents an declarative configuration of the NamedResourcesFilter type for use +// with apply. +type NamedResourcesFilterApplyConfiguration struct { + Selector *string `json:"selector,omitempty"` +} + +// NamedResourcesFilterApplyConfiguration constructs an declarative configuration of the NamedResourcesFilter type for use with +// apply. +func NamedResourcesFilter() *NamedResourcesFilterApplyConfiguration { + return &NamedResourcesFilterApplyConfiguration{} +} + +// WithSelector sets the Selector field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Selector field is set to the value of the last call. +func (b *NamedResourcesFilterApplyConfiguration) WithSelector(value string) *NamedResourcesFilterApplyConfiguration { + b.Selector = &value + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesinstance.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesinstance.go new file mode 100644 index 00000000000..4f01372e4c9 --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesinstance.go @@ -0,0 +1,53 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// NamedResourcesInstanceApplyConfiguration represents an declarative configuration of the NamedResourcesInstance type for use +// with apply. +type NamedResourcesInstanceApplyConfiguration struct { + Name *string `json:"name,omitempty"` + Attributes []NamedResourcesAttributeApplyConfiguration `json:"attributes,omitempty"` +} + +// NamedResourcesInstanceApplyConfiguration constructs an declarative configuration of the NamedResourcesInstance type for use with +// apply. +func NamedResourcesInstance() *NamedResourcesInstanceApplyConfiguration { + return &NamedResourcesInstanceApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *NamedResourcesInstanceApplyConfiguration) WithName(value string) *NamedResourcesInstanceApplyConfiguration { + b.Name = &value + return b +} + +// WithAttributes adds the given value to the Attributes field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Attributes field. +func (b *NamedResourcesInstanceApplyConfiguration) WithAttributes(values ...*NamedResourcesAttributeApplyConfiguration) *NamedResourcesInstanceApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithAttributes") + } + b.Attributes = append(b.Attributes, *values[i]) + } + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesintslice.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesintslice.go new file mode 100644 index 00000000000..ea00bffe516 --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesintslice.go @@ -0,0 +1,41 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// NamedResourcesIntSliceApplyConfiguration represents an declarative configuration of the NamedResourcesIntSlice type for use +// with apply. +type NamedResourcesIntSliceApplyConfiguration struct { + Ints []int64 `json:"ints,omitempty"` +} + +// NamedResourcesIntSliceApplyConfiguration constructs an declarative configuration of the NamedResourcesIntSlice type for use with +// apply. +func NamedResourcesIntSlice() *NamedResourcesIntSliceApplyConfiguration { + return &NamedResourcesIntSliceApplyConfiguration{} +} + +// WithInts adds the given value to the Ints field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Ints field. +func (b *NamedResourcesIntSliceApplyConfiguration) WithInts(values ...int64) *NamedResourcesIntSliceApplyConfiguration { + for i := range values { + b.Ints = append(b.Ints, values[i]) + } + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesrequest.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesrequest.go new file mode 100644 index 00000000000..5adfd84ee54 --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesrequest.go @@ -0,0 +1,39 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// NamedResourcesRequestApplyConfiguration represents an declarative configuration of the NamedResourcesRequest type for use +// with apply. +type NamedResourcesRequestApplyConfiguration struct { + Selector *string `json:"selector,omitempty"` +} + +// NamedResourcesRequestApplyConfiguration constructs an declarative configuration of the NamedResourcesRequest type for use with +// apply. +func NamedResourcesRequest() *NamedResourcesRequestApplyConfiguration { + return &NamedResourcesRequestApplyConfiguration{} +} + +// WithSelector sets the Selector field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Selector field is set to the value of the last call. +func (b *NamedResourcesRequestApplyConfiguration) WithSelector(value string) *NamedResourcesRequestApplyConfiguration { + b.Selector = &value + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesresources.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesresources.go new file mode 100644 index 00000000000..f01ff8699aa --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesresources.go @@ -0,0 +1,44 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// NamedResourcesResourcesApplyConfiguration represents an declarative configuration of the NamedResourcesResources type for use +// with apply. +type NamedResourcesResourcesApplyConfiguration struct { + Instances []NamedResourcesInstanceApplyConfiguration `json:"instances,omitempty"` +} + +// NamedResourcesResourcesApplyConfiguration constructs an declarative configuration of the NamedResourcesResources type for use with +// apply. +func NamedResourcesResources() *NamedResourcesResourcesApplyConfiguration { + return &NamedResourcesResourcesApplyConfiguration{} +} + +// WithInstances adds the given value to the Instances field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Instances field. +func (b *NamedResourcesResourcesApplyConfiguration) WithInstances(values ...*NamedResourcesInstanceApplyConfiguration) *NamedResourcesResourcesApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithInstances") + } + b.Instances = append(b.Instances, *values[i]) + } + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesstringslice.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesstringslice.go new file mode 100644 index 00000000000..1e938735469 --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesstringslice.go @@ -0,0 +1,41 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// NamedResourcesStringSliceApplyConfiguration represents an declarative configuration of the NamedResourcesStringSlice type for use +// with apply. +type NamedResourcesStringSliceApplyConfiguration struct { + Strings []string `json:"strings,omitempty"` +} + +// NamedResourcesStringSliceApplyConfiguration constructs an declarative configuration of the NamedResourcesStringSlice type for use with +// apply. +func NamedResourcesStringSlice() *NamedResourcesStringSliceApplyConfiguration { + return &NamedResourcesStringSliceApplyConfiguration{} +} + +// WithStrings adds the given value to the Strings field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Strings field. +func (b *NamedResourcesStringSliceApplyConfiguration) WithStrings(values ...string) *NamedResourcesStringSliceApplyConfiguration { + for i := range values { + b.Strings = append(b.Strings, values[i]) + } + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/noderesourcemodel.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/noderesourcemodel.go new file mode 100644 index 00000000000..20b7ea861da --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/noderesourcemodel.go @@ -0,0 +1,39 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// NodeResourceModelApplyConfiguration represents an declarative configuration of the NodeResourceModel type for use +// with apply. +type NodeResourceModelApplyConfiguration struct { + NamedResources *NamedResourcesResourcesApplyConfiguration `json:"namedResources,omitempty"` +} + +// NodeResourceModelApplyConfiguration constructs an declarative configuration of the NodeResourceModel type for use with +// apply. +func NodeResourceModel() *NodeResourceModelApplyConfiguration { + return &NodeResourceModelApplyConfiguration{} +} + +// WithNamedResources sets the NamedResources field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the NamedResources field is set to the value of the last call. +func (b *NodeResourceModelApplyConfiguration) WithNamedResources(value *NamedResourcesResourcesApplyConfiguration) *NodeResourceModelApplyConfiguration { + b.NamedResources = value + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/noderesourceslice.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/noderesourceslice.go index a20245489a8..b7d7d99182b 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/noderesourceslice.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/noderesourceslice.go @@ -19,7 +19,7 @@ limitations under the License. package v1alpha2 import ( - v1alpha2 "k8s.io/api/resource/v1alpha2" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" managedfields "k8s.io/apimachinery/pkg/util/managedfields" @@ -30,11 +30,11 @@ import ( // NodeResourceSliceApplyConfiguration represents an declarative configuration of the NodeResourceSlice type for use // with apply. type NodeResourceSliceApplyConfiguration struct { - v1.TypeMetaApplyConfiguration `json:",inline"` - *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - NodeName *string `json:"nodeName,omitempty"` - DriverName *string `json:"driverName,omitempty"` - v1alpha2.NodeResourceModel `json:",inline"` + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + NodeName *string `json:"nodeName,omitempty"` + DriverName *string `json:"driverName,omitempty"` + NodeResourceModelApplyConfiguration `json:",inline"` } // NodeResourceSlice constructs an declarative configuration of the NodeResourceSlice type for use with @@ -58,18 +58,18 @@ func NodeResourceSlice(name string) *NodeResourceSliceApplyConfiguration { // Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously // applied if another fieldManager has updated or force applied any of the previously applied fields. // Experimental! -func ExtractNodeResourceSlice(nodeResourceSlice *v1alpha2.NodeResourceSlice, fieldManager string) (*NodeResourceSliceApplyConfiguration, error) { +func ExtractNodeResourceSlice(nodeResourceSlice *resourcev1alpha2.NodeResourceSlice, fieldManager string) (*NodeResourceSliceApplyConfiguration, error) { return extractNodeResourceSlice(nodeResourceSlice, fieldManager, "") } // ExtractNodeResourceSliceStatus is the same as ExtractNodeResourceSlice except // that it extracts the status subresource applied configuration. // Experimental! -func ExtractNodeResourceSliceStatus(nodeResourceSlice *v1alpha2.NodeResourceSlice, fieldManager string) (*NodeResourceSliceApplyConfiguration, error) { +func ExtractNodeResourceSliceStatus(nodeResourceSlice *resourcev1alpha2.NodeResourceSlice, fieldManager string) (*NodeResourceSliceApplyConfiguration, error) { return extractNodeResourceSlice(nodeResourceSlice, fieldManager, "status") } -func extractNodeResourceSlice(nodeResourceSlice *v1alpha2.NodeResourceSlice, fieldManager string, subresource string) (*NodeResourceSliceApplyConfiguration, error) { +func extractNodeResourceSlice(nodeResourceSlice *resourcev1alpha2.NodeResourceSlice, fieldManager string, subresource string) (*NodeResourceSliceApplyConfiguration, error) { b := &NodeResourceSliceApplyConfiguration{} err := managedfields.ExtractInto(nodeResourceSlice, internal.Parser().Type("io.k8s.api.resource.v1alpha2.NodeResourceSlice"), fieldManager, b, subresource) if err != nil { @@ -255,3 +255,11 @@ func (b *NodeResourceSliceApplyConfiguration) WithDriverName(value string) *Node b.DriverName = &value return b } + +// WithNamedResources sets the NamedResources field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the NamedResources field is set to the value of the last call. +func (b *NodeResourceSliceApplyConfiguration) WithNamedResources(value *NamedResourcesResourcesApplyConfiguration) *NodeResourceSliceApplyConfiguration { + b.NamedResources = value + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcefilter.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcefilter.go index 2fd4ef89f16..15371b44a92 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcefilter.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcefilter.go @@ -18,15 +18,11 @@ limitations under the License. package v1alpha2 -import ( - v1alpha2 "k8s.io/api/resource/v1alpha2" -) - // ResourceFilterApplyConfiguration represents an declarative configuration of the ResourceFilter type for use // with apply. type ResourceFilterApplyConfiguration struct { - DriverName *string `json:"driverName,omitempty"` - v1alpha2.ResourceFilterModel `json:",inline"` + DriverName *string `json:"driverName,omitempty"` + ResourceFilterModelApplyConfiguration `json:",inline"` } // ResourceFilterApplyConfiguration constructs an declarative configuration of the ResourceFilter type for use with @@ -42,3 +38,11 @@ func (b *ResourceFilterApplyConfiguration) WithDriverName(value string) *Resourc b.DriverName = &value return b } + +// WithNamedResources sets the NamedResources field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the NamedResources field is set to the value of the last call. +func (b *ResourceFilterApplyConfiguration) WithNamedResources(value *NamedResourcesFilterApplyConfiguration) *ResourceFilterApplyConfiguration { + b.NamedResources = value + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcefiltermodel.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcefiltermodel.go new file mode 100644 index 00000000000..4f8d138f71f --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcefiltermodel.go @@ -0,0 +1,39 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// ResourceFilterModelApplyConfiguration represents an declarative configuration of the ResourceFilterModel type for use +// with apply. +type ResourceFilterModelApplyConfiguration struct { + NamedResources *NamedResourcesFilterApplyConfiguration `json:"namedResources,omitempty"` +} + +// ResourceFilterModelApplyConfiguration constructs an declarative configuration of the ResourceFilterModel type for use with +// apply. +func ResourceFilterModel() *ResourceFilterModelApplyConfiguration { + return &ResourceFilterModelApplyConfiguration{} +} + +// WithNamedResources sets the NamedResources field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the NamedResources field is set to the value of the last call. +func (b *ResourceFilterModelApplyConfiguration) WithNamedResources(value *NamedResourcesFilterApplyConfiguration) *ResourceFilterModelApplyConfiguration { + b.NamedResources = value + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcerequest.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcerequest.go index 971eace5be1..0243d06f894 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcerequest.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcerequest.go @@ -19,15 +19,14 @@ limitations under the License. package v1alpha2 import ( - v1alpha2 "k8s.io/api/resource/v1alpha2" runtime "k8s.io/apimachinery/pkg/runtime" ) // ResourceRequestApplyConfiguration represents an declarative configuration of the ResourceRequest type for use // with apply. type ResourceRequestApplyConfiguration struct { - VendorParameters *runtime.RawExtension `json:"vendorParameters,omitempty"` - v1alpha2.ResourceRequestModel `json:",inline"` + VendorParameters *runtime.RawExtension `json:"vendorParameters,omitempty"` + ResourceRequestModelApplyConfiguration `json:",inline"` } // ResourceRequestApplyConfiguration constructs an declarative configuration of the ResourceRequest type for use with @@ -43,3 +42,11 @@ func (b *ResourceRequestApplyConfiguration) WithVendorParameters(value runtime.R b.VendorParameters = &value return b } + +// WithNamedResources sets the NamedResources field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the NamedResources field is set to the value of the last call. +func (b *ResourceRequestApplyConfiguration) WithNamedResources(value *NamedResourcesRequestApplyConfiguration) *ResourceRequestApplyConfiguration { + b.NamedResources = value + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcerequestmodel.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcerequestmodel.go new file mode 100644 index 00000000000..35bd1d88fea --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcerequestmodel.go @@ -0,0 +1,39 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// ResourceRequestModelApplyConfiguration represents an declarative configuration of the ResourceRequestModel type for use +// with apply. +type ResourceRequestModelApplyConfiguration struct { + NamedResources *NamedResourcesRequestApplyConfiguration `json:"namedResources,omitempty"` +} + +// ResourceRequestModelApplyConfiguration constructs an declarative configuration of the ResourceRequestModel type for use with +// apply. +func ResourceRequestModel() *ResourceRequestModelApplyConfiguration { + return &ResourceRequestModelApplyConfiguration{} +} + +// WithNamedResources sets the NamedResources field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the NamedResources field is set to the value of the last call. +func (b *ResourceRequestModelApplyConfiguration) WithNamedResources(value *NamedResourcesRequestApplyConfiguration) *ResourceRequestModelApplyConfiguration { + b.NamedResources = value + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/utils.go b/staging/src/k8s.io/client-go/applyconfigurations/utils.go index 847c94f8fac..388e372182d 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/utils.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/utils.go @@ -1523,10 +1523,32 @@ func ForKind(kind schema.GroupVersionKind) interface{} { // Group=resource.k8s.io, Version=v1alpha2 case v1alpha2.SchemeGroupVersion.WithKind("AllocationResult"): return &resourcev1alpha2.AllocationResultApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("AllocationResultModel"): + return &resourcev1alpha2.AllocationResultModelApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("DriverAllocationResult"): return &resourcev1alpha2.DriverAllocationResultApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("DriverRequests"): return &resourcev1alpha2.DriverRequestsApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("NamedResourcesAllocationResult"): + return &resourcev1alpha2.NamedResourcesAllocationResultApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("NamedResourcesAttribute"): + return &resourcev1alpha2.NamedResourcesAttributeApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("NamedResourcesAttributeValue"): + return &resourcev1alpha2.NamedResourcesAttributeValueApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("NamedResourcesFilter"): + return &resourcev1alpha2.NamedResourcesFilterApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("NamedResourcesInstance"): + return &resourcev1alpha2.NamedResourcesInstanceApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("NamedResourcesIntSlice"): + return &resourcev1alpha2.NamedResourcesIntSliceApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("NamedResourcesRequest"): + return &resourcev1alpha2.NamedResourcesRequestApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("NamedResourcesResources"): + return &resourcev1alpha2.NamedResourcesResourcesApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("NamedResourcesStringSlice"): + return &resourcev1alpha2.NamedResourcesStringSliceApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("NodeResourceModel"): + return &resourcev1alpha2.NodeResourceModelApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("NodeResourceSlice"): return &resourcev1alpha2.NodeResourceSliceApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("PodSchedulingContext"): @@ -1561,10 +1583,14 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &resourcev1alpha2.ResourceClassParametersReferenceApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("ResourceFilter"): return &resourcev1alpha2.ResourceFilterApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("ResourceFilterModel"): + return &resourcev1alpha2.ResourceFilterModelApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("ResourceHandle"): return &resourcev1alpha2.ResourceHandleApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("ResourceRequest"): return &resourcev1alpha2.ResourceRequestApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("ResourceRequestModel"): + return &resourcev1alpha2.ResourceRequestModelApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("StructuredResourceHandle"): return &resourcev1alpha2.StructuredResourceHandleApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("VendorParameters"): diff --git a/staging/src/k8s.io/dynamic-resource-allocation/go.mod b/staging/src/k8s.io/dynamic-resource-allocation/go.mod index 2ec3e1dd14f..0881b6010d3 100644 --- a/staging/src/k8s.io/dynamic-resource-allocation/go.mod +++ b/staging/src/k8s.io/dynamic-resource-allocation/go.mod @@ -6,11 +6,13 @@ go 1.22.0 require ( github.com/go-logr/logr v1.4.1 + github.com/google/cel-go v0.17.8 github.com/google/go-cmp v0.6.0 github.com/stretchr/testify v1.8.4 google.golang.org/grpc v1.58.3 k8s.io/api v0.0.0 k8s.io/apimachinery v0.0.0 + k8s.io/apiserver v0.0.0 k8s.io/client-go v0.0.0 k8s.io/klog/v2 v2.120.1 k8s.io/kubelet v0.0.0 @@ -18,6 +20,7 @@ require ( ) require ( + github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect @@ -38,13 +41,17 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stoewer/go-strcase v1.2.0 // indirect + golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect golang.org/x/net v0.21.0 // indirect golang.org/x/oauth2 v0.10.0 // indirect + golang.org/x/sync v0.6.0 // indirect golang.org/x/sys v0.17.0 // indirect golang.org/x/term v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 // indirect google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect @@ -64,5 +71,6 @@ replace ( k8s.io/component-base => ../component-base k8s.io/cri-api => ../cri-api k8s.io/dynamic-resource-allocation => ../dynamic-resource-allocation + k8s.io/kms => ../kms k8s.io/kubelet => ../kubelet ) diff --git a/staging/src/k8s.io/dynamic-resource-allocation/go.sum b/staging/src/k8s.io/dynamic-resource-allocation/go.sum index 340be6f1b18..2c0c8948be5 100644 --- a/staging/src/k8s.io/dynamic-resource-allocation/go.sum +++ b/staging/src/k8s.io/dynamic-resource-allocation/go.sum @@ -1,27 +1,37 @@ cloud.google.com/go/compute v1.21.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= -github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= +github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18= +github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 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/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g= github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= @@ -32,6 +42,7 @@ github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEe github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -39,6 +50,8 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/cel-go v0.17.8 h1:j9m730pMZt1Fc4oKhCLUHfjj6527LuhYcYw0Rl8gqto= +github.com/google/cel-go v0.17.8/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -53,8 +66,13 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -89,31 +107,60 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI= +go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U= +go.etcd.io/etcd/client/v2 v2.305.10/go.mod h1:m3CKZi69HzilhVqtPDcjhSGp+kA1OmbNn0qamH80xjA= +go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc= +go.etcd.io/etcd/pkg/v3 v3.5.10/go.mod h1:TKTuCKKcF1zxmfKWDkfz5qqYaE3JncKKZPFf8c1nFUs= +go.etcd.io/etcd/raft/v3 v3.5.10/go.mod h1:odD6kr8XQXTy9oQnyMPBOr0TVe+gT0neQhElQ6jbGRc= +go.etcd.io/etcd/server/v3 v3.5.10/go.mod h1:gBplPHfs6YI0L+RpGkTQO7buDbHv5HJGG/Bst0/zIPo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0/go.mod h1:5z+/ZWJQKXa9YT34fQNx5K8Hd1EoIhvtUygUQPqEOgQ= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0/go.mod h1:SeQhzAEccGVZVEy7aH87Nh0km+utSpo1pTv6eMMop48= +go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0/go.mod h1:0+KuTDyKL4gjKCF75pHOX4wuzYDUZYfAQdSu43o+Z2I= +go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= +go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= +go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= 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/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= +golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= 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/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= @@ -129,7 +176,8 @@ golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQ 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/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 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= @@ -158,7 +206,8 @@ golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNq google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8= -google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= +google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e h1:z3vDksarJxsAKM5dmEGv0GHwE2hKJ096wZra71Vs4sw= +google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= @@ -170,6 +219,9 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= +gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 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= @@ -183,6 +235,7 @@ k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7F k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0/go.mod h1:z7+wmGM2dfIiLRfrC6jb5kV2Mq/sK1ZP303cxzkV5Y4= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= diff --git a/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/compile.go b/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/compile.go new file mode 100644 index 00000000000..8cbc7985559 --- /dev/null +++ b/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/compile.go @@ -0,0 +1,206 @@ +/* +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 cel + +import ( + "context" + "fmt" + "reflect" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/traits" + + resourceapi "k8s.io/api/resource/v1alpha2" + "k8s.io/apimachinery/pkg/util/version" + celconfig "k8s.io/apiserver/pkg/apis/cel" + apiservercel "k8s.io/apiserver/pkg/cel" + "k8s.io/apiserver/pkg/cel/environment" +) + +const ( + attributesVarPrefix = "attributes." +) + +var ( + Compiler = newCompiler() +) + +// CompilationResult represents a compiled expression. +type CompilationResult struct { + Program cel.Program + Error *apiservercel.Error + Expression string + OutputType *cel.Type + Environment *cel.Env +} + +type compiler struct { + envset *environment.EnvSet +} + +func newCompiler() *compiler { + return &compiler{envset: mustBuildEnv()} +} + +// CompileCELExpression returns a compiled CEL expression. It evaluates to bool. +func (c compiler) CompileCELExpression(expression string, envType environment.Type) CompilationResult { + resultError := func(errorString string, errType apiservercel.ErrorType) CompilationResult { + return CompilationResult{ + Error: &apiservercel.Error{ + Type: errType, + Detail: errorString, + }, + Expression: expression, + } + } + + env, err := c.envset.Env(envType) + if err != nil { + return resultError(fmt.Sprintf("unexpected error loading CEL environment: %v", err), apiservercel.ErrorTypeInternal) + } + + ast, issues := env.Compile(expression) + if issues != nil { + return resultError("compilation failed: "+issues.String(), apiservercel.ErrorTypeInvalid) + } + expectedReturnType := cel.BoolType + if ast.OutputType() != expectedReturnType { + return resultError(fmt.Sprintf("must evaluate to %v", expectedReturnType.String()), apiservercel.ErrorTypeInvalid) + } + _, err = cel.AstToCheckedExpr(ast) + if err != nil { + // should be impossible since env.Compile returned no issues + return resultError("unexpected compilation error: "+err.Error(), apiservercel.ErrorTypeInternal) + } + prog, err := env.Program(ast, + cel.InterruptCheckFrequency(celconfig.CheckFrequency), + ) + if err != nil { + return resultError("program instantiation failed: "+err.Error(), apiservercel.ErrorTypeInternal) + } + return CompilationResult{ + Program: prog, + Expression: expression, + OutputType: ast.OutputType(), + Environment: env, + } +} + +var valueTypes = map[string]struct { + celType *cel.Type + // get returns nil if the attribute doesn't have the type, otherwise + // the value of that type. + get func(attr resourceapi.NamedResourcesAttribute) any +}{ + "quantity": {apiservercel.QuantityType, func(attr resourceapi.NamedResourcesAttribute) any { + if attr.QuantityValue == nil { + return nil + } + return apiservercel.Quantity{Quantity: attr.QuantityValue} + }}, + "bool": {cel.BoolType, func(attr resourceapi.NamedResourcesAttribute) any { + if attr.BoolValue == nil { + return nil + } + return *attr.BoolValue + }}, + "int": {cel.IntType, func(attr resourceapi.NamedResourcesAttribute) any { + if attr.IntValue == nil { + return nil + } + return *attr.IntValue + }}, + "intslice": {types.NewListType(cel.IntType), func(attr resourceapi.NamedResourcesAttribute) any { + if attr.IntSliceValue == nil { + return nil + } + return attr.IntSliceValue.Ints + }}, + "string": {cel.StringType, func(attr resourceapi.NamedResourcesAttribute) any { + if attr.StringValue == nil { + return nil + } + return *attr.StringValue + }}, + "stringslice": {types.NewListType(cel.StringType), func(attr resourceapi.NamedResourcesAttribute) any { + if attr.StringSliceValue == nil { + return nil + } + return attr.StringSliceValue.Strings + }}, +} + +var boolType = reflect.TypeOf(true) + +func (c CompilationResult) Evaluate(ctx context.Context, attributes []resourceapi.NamedResourcesAttribute) (bool, error) { + variables := make(map[string]any, len(valueTypes)) + for name, valueType := range valueTypes { + variables[attributesVarPrefix+name] = buildValueMapper(c.Environment.CELTypeAdapter(), attributes, valueType.get) + } + result, _, err := c.Program.ContextEval(ctx, variables) + if err != nil { + return false, err + } + resultAny, err := result.ConvertToNative(boolType) + if err != nil { + return false, fmt.Errorf("CEL result of type %s could not be converted to bool: %w", result.Type().TypeName(), err) + } + resultBool, ok := resultAny.(bool) + if !ok { + return false, fmt.Errorf("CEL native result value should have been a bool, got instead: %T", resultAny) + } + return resultBool, nil +} + +func mustBuildEnv() *environment.EnvSet { + envset := environment.MustBaseEnvSet(environment.DefaultCompatibilityVersion()) + versioned := []environment.VersionedOptions{ + { + IntroducedVersion: version.MajorMinor(1, 30), + EnvOptions: buildVersionedAttributes(), + }, + } + envset, err := envset.Extend(versioned...) + if err != nil { + panic(fmt.Errorf("internal error building CEL environment: %w", err)) + } + return envset +} + +func buildVersionedAttributes() []cel.EnvOption { + options := make([]cel.EnvOption, 0, len(valueTypes)) + for name, valueType := range valueTypes { + options = append(options, cel.Variable(attributesVarPrefix+name, types.NewMapType(cel.StringType, valueType.celType))) + } + return options +} + +func buildValueMapper(adapter types.Adapter, attributes []resourceapi.NamedResourcesAttribute, get func(resourceapi.NamedResourcesAttribute) any) traits.Mapper { + // This implementation constructs a map and then let's cel handle the + // lookup and iteration. This is done for the sake of simplicity. + // Whether it's faster than writing a custom mapper depends on + // real-world attribute sets and CEL expressions and would have to be + // benchmarked. + valueMap := make(map[string]any) + for _, attribute := range attributes { + if value := get(attribute); value != nil { + valueMap[attribute.Name] = value + } + } + return types.NewStringInterfaceMap(adapter, valueMap) +} diff --git a/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/compile_test.go b/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/compile_test.go new file mode 100644 index 00000000000..bea913c81fc --- /dev/null +++ b/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/compile_test.go @@ -0,0 +1,155 @@ +/* +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 cel + +import ( + "strings" + "testing" + + resourceapi "k8s.io/api/resource/v1alpha2" + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apiserver/pkg/cel/environment" + "k8s.io/klog/v2/ktesting" + "k8s.io/utils/ptr" +) + +func TestCompile(t *testing.T) { + for name, scenario := range map[string]struct { + expression string + attributes []resourceapi.NamedResourcesAttribute + expectCompileError string + expectMatchError string + expectMatch bool + }{ + "true": { + expression: "true", + expectMatch: true, + }, + "false": { + expression: "false", + expectMatch: false, + }, + "syntax-error": { + expression: "?!", + expectCompileError: "Syntax error", + }, + "type-error": { + expression: `attributes.quantity["no-such-attr"]`, + expectCompileError: "must evaluate to bool", + }, + "runtime-error": { + expression: `attributes.quantity["no-such-attr"].isGreaterThan(quantity("0"))`, + expectMatchError: "no such key: no-such-attr", + }, + "quantity": { + expression: `attributes.quantity["name"].isGreaterThan(quantity("0"))`, + attributes: []resourceapi.NamedResourcesAttribute{{Name: "name", NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{QuantityValue: ptr.To(resource.MustParse("1"))}}}, + expectMatch: true, + }, + "bool": { + expression: `attributes.bool["name"]`, + attributes: []resourceapi.NamedResourcesAttribute{{Name: "name", NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{BoolValue: ptr.To(true)}}}, + expectMatch: true, + }, + "int": { + expression: `attributes.int["name"] > 0`, + attributes: []resourceapi.NamedResourcesAttribute{{Name: "name", NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{IntValue: ptr.To(int64(1))}}}, + expectMatch: true, + }, + "intslice": { + expression: `attributes.intslice["name"].isSorted() && attributes.intslice["name"].indexOf(3) == 2`, + attributes: []resourceapi.NamedResourcesAttribute{{Name: "name", NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{IntSliceValue: &resourceapi.NamedResourcesIntSlice{Ints: []int64{1, 2, 3}}}}}, + expectMatch: true, + }, + "empty-intslice": { + expression: `size(attributes.intslice["name"]) == 0`, + attributes: []resourceapi.NamedResourcesAttribute{{Name: "name", NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{IntSliceValue: &resourceapi.NamedResourcesIntSlice{}}}}, + expectMatch: true, + }, + "string": { + expression: `attributes.string["name"] == "fish"`, + attributes: []resourceapi.NamedResourcesAttribute{{Name: "name", NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{StringValue: ptr.To("fish")}}}, + expectMatch: true, + }, + "stringslice": { + expression: `attributes.stringslice["name"].isSorted() && attributes.stringslice["name"].indexOf("a") == 0`, + attributes: []resourceapi.NamedResourcesAttribute{{Name: "name", NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{StringSliceValue: &resourceapi.NamedResourcesStringSlice{Strings: []string{"a", "b", "c"}}}}}, + expectMatch: true, + }, + "empty-stringslice": { + expression: `size(attributes.stringslice["name"]) == 0`, + attributes: []resourceapi.NamedResourcesAttribute{{Name: "name", NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{StringSliceValue: &resourceapi.NamedResourcesStringSlice{}}}}, + expectMatch: true, + }, + "all": { + expression: `attributes.quantity["quantity"].isGreaterThan(quantity("0")) && +attributes.bool["bool"] && +attributes.int["int"] > 0 && +attributes.intslice["intslice"].isSorted() && +attributes.string["string"] == "fish" && +attributes.stringslice["stringslice"].isSorted()`, + attributes: []resourceapi.NamedResourcesAttribute{ + {Name: "quantity", NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{QuantityValue: ptr.To(resource.MustParse("1"))}}, + {Name: "bool", NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{BoolValue: ptr.To(true)}}, + {Name: "int", NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{IntValue: ptr.To(int64(1))}}, + {Name: "intslice", NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{IntSliceValue: &resourceapi.NamedResourcesIntSlice{Ints: []int64{1, 2, 3}}}}, + {Name: "string", NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{StringValue: ptr.To("fish")}}, + {Name: "stringslice", NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{StringSliceValue: &resourceapi.NamedResourcesStringSlice{Strings: []string{"a", "b", "c"}}}}, + }, + expectMatch: true, + }, + "many": { + expression: `attributes.bool["a"] && attributes.bool["b"] && attributes.bool["c"]`, + attributes: []resourceapi.NamedResourcesAttribute{ + {Name: "a", NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{BoolValue: ptr.To(true)}}, + {Name: "b", NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{BoolValue: ptr.To(true)}}, + {Name: "c", NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{BoolValue: ptr.To(true)}}, + }, + expectMatch: true, + }, + } { + t.Run(name, func(t *testing.T) { + _, ctx := ktesting.NewTestContext(t) + result := Compiler.CompileCELExpression(scenario.expression, environment.StoredExpressions) + if scenario.expectCompileError != "" && result.Error == nil { + t.Fatalf("expected compile error %q, got none", scenario.expectCompileError) + } + if result.Error != nil { + if scenario.expectCompileError == "" { + t.Fatalf("unexpected compile error: %v", result.Error) + } + if !strings.Contains(result.Error.Error(), scenario.expectCompileError) { + t.Fatalf("expected compile error to contain %q, but got instead: %v", scenario.expectCompileError, result.Error) + } + return + } + match, err := result.Evaluate(ctx, scenario.attributes) + if err != nil { + if scenario.expectMatchError == "" { + t.Fatalf("unexpected evaluation error: %v", err) + } + if !strings.Contains(err.Error(), scenario.expectMatchError) { + t.Fatalf("expected evaluation error to contain %q, but got instead: %v", scenario.expectMatchError, err) + } + return + } + if match != scenario.expectMatch { + t.Fatalf("expected result %v, got %v", scenario.expectMatch, match) + } + }) + } +} diff --git a/test/integration/etcd/data.go b/test/integration/etcd/data.go index f3014e4e57e..fa7a863ed2b 100644 --- a/test/integration/etcd/data.go +++ b/test/integration/etcd/data.go @@ -455,7 +455,7 @@ func GetEtcdStorageDataForNamespace(namespace string) map[schema.GroupVersionRes ExpectedEtcdPath: "/registry/resourceclaimparameters/" + namespace + "/claim1parameters", }, gvr("resource.k8s.io", "v1alpha2", "noderesourceslices"): { - Stub: `{"metadata": {"name": "node1slice"}, "nodeName": "worker1", "driverName": "dra.example.com"}`, // TODO: add one structured parameter model + Stub: `{"metadata": {"name": "node1slice"}, "nodeName": "worker1", "driverName": "dra.example.com", "namedResources": {}}`, ExpectedEtcdPath: "/registry/noderesourceslices/node1slice", }, // -- From 4ed2b3eaeb69aaf1a9e9b194ac3fb0403657bffe Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Tue, 20 Feb 2024 14:05:38 +0100 Subject: [PATCH 07/18] scheduler_perf: test DRA with structured parameters --- .../config/dra/resourceclaimparameters.yaml | 9 +++ .../dra/resourceclaimtemplate-structured.yaml | 11 +++ .../config/dra/resourceclass-structured.yaml | 6 ++ .../config/performance-config.yaml | 72 +++++++++++++++++++ test/integration/scheduler_perf/dra.go | 47 ++++++++++++ 5 files changed, 145 insertions(+) create mode 100644 test/integration/scheduler_perf/config/dra/resourceclaimparameters.yaml create mode 100644 test/integration/scheduler_perf/config/dra/resourceclaimtemplate-structured.yaml create mode 100644 test/integration/scheduler_perf/config/dra/resourceclass-structured.yaml diff --git a/test/integration/scheduler_perf/config/dra/resourceclaimparameters.yaml b/test/integration/scheduler_perf/config/dra/resourceclaimparameters.yaml new file mode 100644 index 00000000000..9f3a84f9a3d --- /dev/null +++ b/test/integration/scheduler_perf/config/dra/resourceclaimparameters.yaml @@ -0,0 +1,9 @@ +apiVersion: resource.k8s.io/v1alpha2 +kind: ResourceClaimParameters +metadata: + name: test-claim-parameters +driverRequests: +- driverName: test-driver.cdi.k8s.io + requests: + - namedResources: + selector: "true" diff --git a/test/integration/scheduler_perf/config/dra/resourceclaimtemplate-structured.yaml b/test/integration/scheduler_perf/config/dra/resourceclaimtemplate-structured.yaml new file mode 100644 index 00000000000..413125058ac --- /dev/null +++ b/test/integration/scheduler_perf/config/dra/resourceclaimtemplate-structured.yaml @@ -0,0 +1,11 @@ +apiVersion: resource.k8s.io/v1alpha2 +kind: ResourceClaimTemplate +metadata: + name: test-claim-template +spec: + spec: + resourceClassName: test-class + parametersRef: + apiGroup: resource.k8s.io + kind: ResourceClaimParameters + name: test-claim-parameters diff --git a/test/integration/scheduler_perf/config/dra/resourceclass-structured.yaml b/test/integration/scheduler_perf/config/dra/resourceclass-structured.yaml new file mode 100644 index 00000000000..ac1bb2e530d --- /dev/null +++ b/test/integration/scheduler_perf/config/dra/resourceclass-structured.yaml @@ -0,0 +1,6 @@ +apiVersion: resource.k8s.io/v1alpha2 +kind: ResourceClass +metadata: + name: test-class +driverName: test-driver.cdi.k8s.io +structuredParameters: true diff --git a/test/integration/scheduler_perf/config/performance-config.yaml b/test/integration/scheduler_perf/config/performance-config.yaml index c3f96fb58d2..48ec4b8487d 100644 --- a/test/integration/scheduler_perf/config/performance-config.yaml +++ b/test/integration/scheduler_perf/config/performance-config.yaml @@ -853,3 +853,75 @@ initPods: 1000 measurePods: 1000 maxClaimsPerNode: 20 + +# SchedulingWithResourceClaimTemplate uses a ResourceClaimTemplate +# and dynamically creates ResourceClaim instances for each pod. +# The driver uses structured parameters. +- name: SchedulingWithResourceClaimTemplateStructured + featureGates: + DynamicResourceAllocation: true + workloadTemplate: + - opcode: createNodes + countParam: $nodesWithoutDRA + - opcode: createNodes + nodeTemplatePath: config/dra/node-with-dra-test-driver.yaml + countParam: $nodesWithDRA + - opcode: createResourceDriver + driverName: test-driver.cdi.k8s.io + nodes: scheduler-perf-dra-* + maxClaimsPerNodeParam: $maxClaimsPerNode + structuredParameters: true + - opcode: createAny + templatePath: config/dra/resourceclass-structured.yaml + - opcode: createAny + templatePath: config/dra/resourceclaimparameters.yaml + namespace: init + - opcode: createAny + templatePath: config/dra/resourceclaimtemplate-structured.yaml + namespace: init + - opcode: createPods + namespace: init + countParam: $initPods + podTemplatePath: config/dra/pod-with-claim-template.yaml + - opcode: createAny + templatePath: config/dra/resourceclaimparameters.yaml + namespace: test + - opcode: createAny + templatePath: config/dra/resourceclaimtemplate-structured.yaml + namespace: test + - opcode: createPods + namespace: test + countParam: $measurePods + podTemplatePath: config/dra/pod-with-claim-template.yaml + collectMetrics: true + workloads: + - name: fast + labels: [integration-test, fast] + params: + # This testcase runs through all code paths without + # taking too long overall. + nodesWithDRA: 1 + nodesWithoutDRA: 1 + initPods: 0 + measurePods: 10 + maxClaimsPerNode: 10 + - name: 2000pods_100nodes + labels: [performance, fast] + params: + # In this testcase, the number of nodes is smaller + # than the limit for the PodScheduling slices. + nodesWithDRA: 100 + nodesWithoutDRA: 0 + initPods: 1000 + measurePods: 1000 + maxClaimsPerNode: 20 + - name: 2000pods_200nodes + params: + # In this testcase, the driver and scheduler must + # truncate the PotentialNodes and UnsuitableNodes + # slices. + nodesWithDRA: 200 + nodesWithoutDRA: 0 + initPods: 1000 + measurePods: 1000 + maxClaimsPerNode: 10 diff --git a/test/integration/scheduler_perf/dra.go b/test/integration/scheduler_perf/dra.go index 3e263ace1f7..977d83119e7 100644 --- a/test/integration/scheduler_perf/dra.go +++ b/test/integration/scheduler_perf/dra.go @@ -126,6 +126,11 @@ type createResourceDriverOp struct { MaxClaimsPerNodeParam string // Nodes matching this glob pattern have resources managed by the driver. Nodes string + // StructuredParameters is true if the controller that is built into the scheduler + // is used and the control-plane controller is not needed. + // Because we don't run the kubelet plugin, NodeResourceSlices must + // get created for all nodes. + StructuredParameters bool } var _ realOp = &createResourceDriverOp{} @@ -188,6 +193,23 @@ func (op *createResourceDriverOp) run(tCtx ktesting.TContext) { } } + if op.StructuredParameters { + for _, nodeName := range resources.Nodes { + slice := nodeResourceSlice(op.DriverName, nodeName, op.MaxClaimsPerNode) + _, err := tCtx.Client().ResourceV1alpha2().NodeResourceSlices().Create(tCtx, slice, metav1.CreateOptions{}) + tCtx.ExpectNoError(err, "create node resource slice") + } + tCtx.CleanupCtx(func(tCtx ktesting.TContext) { + err := tCtx.Client().ResourceV1alpha2().NodeResourceSlices().DeleteCollection(tCtx, + metav1.DeleteOptions{}, + metav1.ListOptions{FieldSelector: "driverName=" + op.DriverName}, + ) + tCtx.ExpectNoError(err, "delete node resource slices") + }) + // No need for the controller. + return + } + controller := draapp.NewController(tCtx.Client(), resources) ctx, cancel := context.WithCancel(tCtx) var wg sync.WaitGroup @@ -205,3 +227,28 @@ func (op *createResourceDriverOp) run(tCtx ktesting.TContext) { tCtx.Logf("stopped resource driver %q", op.DriverName) }) } + +func nodeResourceSlice(driverName, nodeName string, capacity int) *resourcev1alpha2.NodeResourceSlice { + slice := &resourcev1alpha2.NodeResourceSlice{ + ObjectMeta: metav1.ObjectMeta{ + Name: nodeName, + }, + + NodeName: nodeName, + DriverName: driverName, + + NodeResourceModel: resourcev1alpha2.NodeResourceModel{ + NamedResources: &resourcev1alpha2.NamedResourcesResources{}, + }, + } + + for i := 0; i < capacity; i++ { + slice.NodeResourceModel.NamedResources.Instances = append(slice.NodeResourceModel.NamedResources.Instances, + resourcev1alpha2.NamedResourcesInstance{ + Name: fmt.Sprintf("instance-%d", i), + }, + ) + } + + return slice +} From 6f1ddfcd2e36c76b4e28dbb0ea355441cc4caeb2 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Tue, 20 Feb 2024 18:17:51 +0100 Subject: [PATCH 08/18] kubelet: support structured parameters for preparing resources If the resource handle has data from a structured parameter model, then we need to pass that to the DRA driver kubelet plugin. Because Kubernetes uses gogo/protobuf, we cannot use "optional" for that new optional field and have to resort to "repeated" with a single repetition if present. This is a new, backwards-compatible field. That extending the resource.k8s.io changes the checksum of a kubelet checkpoint is unfortunate. Updating the test cases is a stop-gap measure, the actual solution will have to be something else before beta. --- pkg/kubelet/cm/dra/manager.go | 4 + pkg/kubelet/cm/dra/plugin/client.go | 15 +- .../cm/dra/state/state_checkpoint_test.go | 15 +- .../kubelet/pkg/apis/dra/v1alpha2/api.pb.go | 210 +++++++++++++++--- .../kubelet/pkg/apis/dra/v1alpha2/api.proto | 11 + .../kubelet/pkg/apis/dra/v1alpha3/api.pb.go | 150 ++++++++++--- .../kubelet/pkg/apis/dra/v1alpha3/api.proto | 7 + test/e2e/dra/test-driver/app/kubeletplugin.go | 53 ++++- 8 files changed, 381 insertions(+), 84 deletions(-) diff --git a/pkg/kubelet/cm/dra/manager.go b/pkg/kubelet/cm/dra/manager.go index 62a2bd4cd4f..085366ac0af 100644 --- a/pkg/kubelet/cm/dra/manager.go +++ b/pkg/kubelet/cm/dra/manager.go @@ -21,6 +21,7 @@ import ( "fmt" v1 "k8s.io/api/core/v1" + resourceapi "k8s.io/api/resource/v1alpha2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" clientset "k8s.io/client-go/kubernetes" @@ -143,6 +144,9 @@ func (m *ManagerImpl) PrepareResources(pod *v1.Pod) error { Name: resourceClaim.Name, ResourceHandle: resourceHandle.Data, } + if resourceHandle.StructuredData != nil { + claim.StructuredResourceHandle = []*resourceapi.StructuredResourceHandle{resourceHandle.StructuredData} + } batches[pluginName] = append(batches[pluginName], claim) } claimInfos[resourceClaim.UID] = claimInfo diff --git a/pkg/kubelet/cm/dra/plugin/client.go b/pkg/kubelet/cm/dra/plugin/client.go index bbf0b1e9235..e7cb802181b 100644 --- a/pkg/kubelet/cm/dra/plugin/client.go +++ b/pkg/kubelet/cm/dra/plugin/client.go @@ -54,13 +54,14 @@ func (v1alpha2rm v1alpha2NodeResourceManager) Prepare(ctx context.Context, conn } for _, claim := range req.Claims { - res, err := nodeClient.NodePrepareResource(ctx, - &drapbv1alpha2.NodePrepareResourceRequest{ - Namespace: claim.Namespace, - ClaimUid: claim.Uid, - ClaimName: claim.Name, - ResourceHandle: claim.ResourceHandle, - }) + req := &drapbv1alpha2.NodePrepareResourceRequest{ + Namespace: claim.Namespace, + ClaimUid: claim.Uid, + ClaimName: claim.Name, + ResourceHandle: claim.ResourceHandle, + StructuredResourceHandle: claim.StructuredResourceHandle, + } + res, err := nodeClient.NodePrepareResource(ctx, req) result := &drapb.NodePrepareResourceResponse{} if err != nil { result.Error = err.Error() diff --git a/pkg/kubelet/cm/dra/state/state_checkpoint_test.go b/pkg/kubelet/cm/dra/state/state_checkpoint_test.go index 6e2a49ecdb6..a5ff86eed17 100644 --- a/pkg/kubelet/cm/dra/state/state_checkpoint_test.go +++ b/pkg/kubelet/cm/dra/state/state_checkpoint_test.go @@ -37,6 +37,13 @@ func assertStateEqual(t *testing.T, restoredState, expectedState ClaimInfoStateL assert.Equal(t, expectedState, restoredState, "expected ClaimInfoState does not equal to restored one") } +// TODO (https://github.com/kubernetes/kubernetes/issues/123552): reconsider what data gets stored in checkpoints and whether that is really necessary. +// +// As it stands now, a "v1" checkpoint contains data for types like the resourcev1alpha2.ResourceHandle +// which may change over time as new fields get added in a backward-compatible way (not unusual +// for API types). That breaks checksuming with pkg/util/hash because it is based on spew output. +// That output includes those new fields. + func TestCheckpointGetOrCreate(t *testing.T) { testCases := []struct { description string @@ -52,7 +59,7 @@ func TestCheckpointGetOrCreate(t *testing.T) { }, { "Restore checkpoint - single claim", - `{"version":"v1","entries":[{"DriverName":"test-driver.cdi.k8s.io","ClassName":"class-name","ClaimUID":"067798be-454e-4be4-9047-1aa06aea63f7","ClaimName":"example","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"ResourceHandles":[{"driverName":"test-driver.cdi.k8s.io","data":"{\"a\": \"b\"}"}],"CDIDevices":{"test-driver.cdi.k8s.io":["example.com/example=cdi-example"]}}],"checksum":4194867564}`, + `{"version":"v1","entries":[{"DriverName":"test-driver.cdi.k8s.io","ClassName":"class-name","ClaimUID":"067798be-454e-4be4-9047-1aa06aea63f7","ClaimName":"example","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"ResourceHandles":[{"driverName":"test-driver.cdi.k8s.io","data":"{\"a\": \"b\"}"}],"CDIDevices":{"test-driver.cdi.k8s.io":["example.com/example=cdi-example"]}}],"checksum":113577689}`, "", []ClaimInfoState{ { @@ -76,7 +83,7 @@ func TestCheckpointGetOrCreate(t *testing.T) { }, { "Restore checkpoint - single claim - multiple devices", - `{"version":"v1","entries":[{"DriverName":"meta-test-driver.cdi.k8s.io","ClassName":"class-name","ClaimUID":"067798be-454e-4be4-9047-1aa06aea63f7","ClaimName":"example","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"ResourceHandles":[{"driverName":"test-driver-1.cdi.k8s.io","data":"{\"a\": \"b\"}"},{"driverName":"test-driver-2.cdi.k8s.io","data":"{\"c\": \"d\"}"}],"CDIDevices":{"test-driver-1.cdi.k8s.io":["example-1.com/example-1=cdi-example-1"],"test-driver-2.cdi.k8s.io":["example-2.com/example-2=cdi-example-2"]}}],"checksum":360176657}`, + `{"version":"v1","entries":[{"DriverName":"meta-test-driver.cdi.k8s.io","ClassName":"class-name","ClaimUID":"067798be-454e-4be4-9047-1aa06aea63f7","ClaimName":"example","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"ResourceHandles":[{"driverName":"test-driver-1.cdi.k8s.io","data":"{\"a\": \"b\"}"},{"driverName":"test-driver-2.cdi.k8s.io","data":"{\"c\": \"d\"}"}],"CDIDevices":{"test-driver-1.cdi.k8s.io":["example-1.com/example-1=cdi-example-1"],"test-driver-2.cdi.k8s.io":["example-2.com/example-2=cdi-example-2"]}}],"checksum":1466990255}`, "", []ClaimInfoState{ { @@ -105,7 +112,7 @@ func TestCheckpointGetOrCreate(t *testing.T) { }, { "Restore checkpoint - multiple claims", - `{"version":"v1","entries":[{"DriverName":"test-driver.cdi.k8s.io","ClassName":"class-name-1","ClaimUID":"067798be-454e-4be4-9047-1aa06aea63f7","ClaimName":"example-1","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"ResourceHandles":[{"driverName":"test-driver.cdi.k8s.io","data":"{\"a\": \"b\"}"}],"CDIDevices":{"test-driver.cdi.k8s.io":["example.com/example=cdi-example-1"]}},{"DriverName":"test-driver.cdi.k8s.io","ClassName":"class-name-2","ClaimUID":"4cf8db2d-06c0-7d70-1a51-e59b25b2c16c","ClaimName":"example-2","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"ResourceHandles":[{"driverName":"test-driver.cdi.k8s.io","data":"{\"c\": \"d\"}"}],"CDIDevices":{"test-driver.cdi.k8s.io":["example.com/example=cdi-example-2"]}}],"checksum":103176902}`, + `{"version":"v1","entries":[{"DriverName":"test-driver.cdi.k8s.io","ClassName":"class-name-1","ClaimUID":"067798be-454e-4be4-9047-1aa06aea63f7","ClaimName":"example-1","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"ResourceHandles":[{"driverName":"test-driver.cdi.k8s.io","data":"{\"a\": \"b\"}"}],"CDIDevices":{"test-driver.cdi.k8s.io":["example.com/example=cdi-example-1"]}},{"DriverName":"test-driver.cdi.k8s.io","ClassName":"class-name-2","ClaimUID":"4cf8db2d-06c0-7d70-1a51-e59b25b2c16c","ClaimName":"example-2","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"ResourceHandles":[{"driverName":"test-driver.cdi.k8s.io","data":"{\"c\": \"d\"}"}],"CDIDevices":{"test-driver.cdi.k8s.io":["example.com/example=cdi-example-2"]}}],"checksum":471181742}`, "", []ClaimInfoState{ { @@ -218,7 +225,7 @@ func TestCheckpointStateStore(t *testing.T) { }, } - expectedCheckpoint := `{"version":"v1","entries":[{"DriverName":"test-driver.cdi.k8s.io","ClassName":"class-name","ClaimUID":"067798be-454e-4be4-9047-1aa06aea63f7","ClaimName":"example","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"ResourceHandles":[{"driverName":"test-driver.cdi.k8s.io","data":"{\"a\": \"b\"}"}],"CDIDevices":{"test-driver.cdi.k8s.io":["example.com/example=cdi-example"]}}],"checksum":4194867564}` + expectedCheckpoint := `{"version":"v1","entries":[{"DriverName":"test-driver.cdi.k8s.io","ClassName":"class-name","ClaimUID":"067798be-454e-4be4-9047-1aa06aea63f7","ClaimName":"example","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"ResourceHandles":[{"driverName":"test-driver.cdi.k8s.io","data":"{\"a\": \"b\"}"}],"CDIDevices":{"test-driver.cdi.k8s.io":["example.com/example=cdi-example"]}}],"checksum":113577689}` // Should return an error, stateDir cannot be an empty string if _, err := NewCheckpointState("", testingCheckpoint); err == nil { diff --git a/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha2/api.pb.go b/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha2/api.pb.go index 9b0bd9cea83..047515a147d 100644 --- a/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha2/api.pb.go +++ b/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha2/api.pb.go @@ -28,6 +28,7 @@ import ( codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" io "io" + v1alpha2 "k8s.io/api/resource/v1alpha2" math "math" math_bits "math/bits" reflect "reflect" @@ -57,9 +58,15 @@ type NodePrepareResourceRequest struct { ClaimName string `protobuf:"bytes,3,opt,name=claim_name,json=claimName,proto3" json:"claim_name,omitempty"` // Resource handle (AllocationResult.ResourceHandles[*].Data) // This field is REQUIRED. - ResourceHandle string `protobuf:"bytes,4,opt,name=resource_handle,json=resourceHandle,proto3" json:"resource_handle,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_sizecache int32 `json:"-"` + ResourceHandle string `protobuf:"bytes,4,opt,name=resource_handle,json=resourceHandle,proto3" json:"resource_handle,omitempty"` + // Structured parameter resource handle (AllocationResult.ResourceHandles[*].StructuredData). + // This field is OPTIONAL. If present, it needs to be used + // instead of resource_handle. It will only have a single entry. + // + // Using "repeated" instead of "optional" is a workaround for https://github.com/gogo/protobuf/issues/713. + StructuredResourceHandle []*v1alpha2.StructuredResourceHandle `protobuf:"bytes,5,rep,name=structured_resource_handle,json=structuredResourceHandle,proto3" json:"structured_resource_handle,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *NodePrepareResourceRequest) Reset() { *m = NodePrepareResourceRequest{} } @@ -122,6 +129,13 @@ func (m *NodePrepareResourceRequest) GetResourceHandle() string { return "" } +func (m *NodePrepareResourceRequest) GetStructuredResourceHandle() []*v1alpha2.StructuredResourceHandle { + if m != nil { + return m.StructuredResourceHandle + } + return nil +} + type NodePrepareResourceResponse struct { // These are the additional devices that kubelet must // make available via the container runtime. A resource @@ -182,9 +196,13 @@ type NodeUnprepareResourceRequest struct { ClaimName string `protobuf:"bytes,3,opt,name=claim_name,json=claimName,proto3" json:"claim_name,omitempty"` // Resource handle (AllocationResult.ResourceHandles[*].Data) // This field is REQUIRED. - ResourceHandle string `protobuf:"bytes,4,opt,name=resource_handle,json=resourceHandle,proto3" json:"resource_handle,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_sizecache int32 `json:"-"` + ResourceHandle string `protobuf:"bytes,4,opt,name=resource_handle,json=resourceHandle,proto3" json:"resource_handle,omitempty"` + // Structured parameter resource handle (AllocationResult.ResourceHandles[*].StructuredData). + // This field is OPTIONAL. If present, it needs to be used + // instead of resource_handle. It will only have a single entry. + StructuredResourceHandle []*v1alpha2.StructuredResourceHandle `protobuf:"bytes,5,rep,name=structured_resource_handle,json=structuredResourceHandle,proto3" json:"structured_resource_handle,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *NodeUnprepareResourceRequest) Reset() { *m = NodeUnprepareResourceRequest{} } @@ -247,6 +265,13 @@ func (m *NodeUnprepareResourceRequest) GetResourceHandle() string { return "" } +func (m *NodeUnprepareResourceRequest) GetStructuredResourceHandle() []*v1alpha2.StructuredResourceHandle { + if m != nil { + return m.StructuredResourceHandle + } + return nil +} + type NodeUnprepareResourceResponse struct { XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_sizecache int32 `json:"-"` @@ -294,31 +319,34 @@ func init() { func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) } var fileDescriptor_00212fb1f9d3bf1c = []byte{ - // 369 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x52, 0xb1, 0x6e, 0xe2, 0x40, - 0x10, 0x65, 0x0f, 0x74, 0xc2, 0x7b, 0xd2, 0x9d, 0xb4, 0xa7, 0x93, 0x2c, 0x03, 0x06, 0x59, 0xdc, - 0x41, 0x73, 0xb6, 0x8e, 0x6b, 0xae, 0xba, 0x02, 0xa5, 0x48, 0x85, 0x22, 0x4b, 0x34, 0x69, 0xd0, - 0xda, 0x3b, 0x31, 0x1b, 0x6c, 0xef, 0xc6, 0x6b, 0x53, 0xe7, 0x13, 0xf2, 0x07, 0x51, 0xfe, 0x86, - 0x32, 0x25, 0x65, 0x70, 0x7e, 0x24, 0x62, 0x1d, 0x2b, 0x8a, 0x04, 0xa2, 0x4d, 0xb7, 0xf3, 0xe6, - 0xcd, 0xbc, 0x37, 0xb3, 0x83, 0x0d, 0x2a, 0xb9, 0x2b, 0x33, 0x91, 0x0b, 0xd2, 0x5e, 0xff, 0xa1, - 0xb1, 0x5c, 0xd2, 0x89, 0xf5, 0x3b, 0xe2, 0xf9, 0xb2, 0x08, 0xdc, 0x50, 0x24, 0x5e, 0x24, 0x22, - 0xe1, 0x69, 0x42, 0x50, 0x5c, 0xe9, 0x48, 0x07, 0xfa, 0x55, 0x15, 0x3a, 0xf7, 0x08, 0x5b, 0x33, - 0xc1, 0xe0, 0x22, 0x03, 0x49, 0x33, 0xf0, 0x41, 0x89, 0x22, 0x0b, 0xc1, 0x87, 0x9b, 0x02, 0x54, - 0x4e, 0xba, 0xd8, 0x48, 0x69, 0x02, 0x4a, 0xd2, 0x10, 0x4c, 0x34, 0x40, 0x63, 0xc3, 0x7f, 0x03, - 0x48, 0x07, 0x1b, 0x61, 0x4c, 0x79, 0xb2, 0x28, 0x38, 0x33, 0x3f, 0xe9, 0x6c, 0x5b, 0x03, 0x73, - 0xce, 0x48, 0x0f, 0xe3, 0x2a, 0xb9, 0xe7, 0x9b, 0xcd, 0xaa, 0x56, 0x23, 0x33, 0x9a, 0x00, 0x19, - 0xe1, 0x6f, 0xd9, 0xab, 0xd8, 0x62, 0x49, 0x53, 0x16, 0x83, 0xd9, 0xd2, 0x9c, 0xaf, 0x35, 0x7c, - 0xae, 0x51, 0xe7, 0x3f, 0xee, 0x1c, 0x34, 0xa8, 0xa4, 0x48, 0x15, 0x90, 0x3e, 0xfe, 0x12, 0x32, - 0xbe, 0x60, 0xb0, 0xe6, 0x21, 0x28, 0x13, 0x0d, 0x9a, 0x63, 0xc3, 0xc7, 0x21, 0xe3, 0x67, 0x15, - 0xe2, 0x3c, 0x20, 0xdc, 0xdd, 0x37, 0x98, 0xa7, 0xf2, 0xc3, 0xce, 0xd8, 0xc7, 0xbd, 0x23, 0x16, - 0xab, 0x29, 0x27, 0x5b, 0x84, 0x5b, 0x7b, 0x06, 0x61, 0xf8, 0xfb, 0x81, 0x6d, 0x90, 0xa1, 0x5b, - 0x1f, 0x80, 0x7b, 0xfc, 0x37, 0xad, 0x9f, 0x27, 0x58, 0x95, 0x98, 0xd3, 0x20, 0xd7, 0xf8, 0xc7, - 0x41, 0x3f, 0xe4, 0xd7, 0xfb, 0x0e, 0xc7, 0x76, 0x6a, 0x8d, 0x4e, 0xf2, 0x6a, 0xad, 0xe9, 0x74, - 0xb3, 0xb3, 0xd1, 0x76, 0x67, 0x37, 0x6e, 0x4b, 0x1b, 0x6d, 0x4a, 0x1b, 0x3d, 0x96, 0x36, 0x7a, - 0x2a, 0x6d, 0x74, 0xf7, 0x6c, 0x37, 0x2e, 0x87, 0xab, 0x7f, 0xca, 0xe5, 0xc2, 0x5b, 0x15, 0x01, - 0xc4, 0x90, 0x7b, 0x72, 0x15, 0x79, 0x54, 0x72, 0xe5, 0xb1, 0x8c, 0x7a, 0xb5, 0x46, 0xf0, 0x59, - 0x1f, 0xf3, 0xdf, 0x97, 0x00, 0x00, 0x00, 0xff, 0xff, 0x89, 0x2f, 0x77, 0x8e, 0x12, 0x03, 0x00, - 0x00, + // 432 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x53, 0x4d, 0x6f, 0xd3, 0x40, + 0x10, 0xcd, 0x26, 0x05, 0xd5, 0x53, 0x09, 0xa4, 0x45, 0x48, 0x96, 0xdb, 0xba, 0x51, 0x54, 0x68, + 0x0e, 0x60, 0x8b, 0x20, 0x21, 0x4e, 0x1c, 0x2a, 0x0e, 0x9c, 0x2a, 0x64, 0xd4, 0x0b, 0x97, 0x68, + 0xe3, 0x1d, 0x9c, 0x25, 0x89, 0x77, 0xd9, 0x8f, 0x9e, 0xf9, 0x09, 0x5c, 0x10, 0x7f, 0xa9, 0x47, + 0x8e, 0x3d, 0xd2, 0xf0, 0x47, 0x90, 0x77, 0xeb, 0x56, 0x41, 0x89, 0xf2, 0x07, 0x7a, 0xf3, 0xbe, + 0x79, 0x6f, 0x66, 0xf7, 0x8d, 0x1f, 0x44, 0x4c, 0x89, 0x4c, 0x69, 0x69, 0x25, 0xdd, 0xbd, 0x78, + 0xc5, 0xe6, 0x6a, 0xca, 0x46, 0xc9, 0xcb, 0x4a, 0xd8, 0xa9, 0x9b, 0x64, 0xa5, 0x5c, 0xe4, 0x95, + 0xac, 0x64, 0xee, 0x09, 0x13, 0xf7, 0xc5, 0x9f, 0xfc, 0xc1, 0x7f, 0x05, 0x61, 0xf2, 0x62, 0xf6, + 0xd6, 0x64, 0x42, 0xe6, 0x4c, 0x89, 0x5c, 0xa3, 0x91, 0x4e, 0x97, 0x98, 0xb7, 0xcd, 0xf2, 0x0a, + 0x6b, 0xd4, 0xcc, 0x22, 0x0f, 0xec, 0xc1, 0xcf, 0x2e, 0x24, 0x67, 0x92, 0xe3, 0x47, 0x8d, 0x8a, + 0x69, 0x2c, 0x6e, 0x04, 0x05, 0x7e, 0x73, 0x68, 0x2c, 0x3d, 0x80, 0xa8, 0x66, 0x0b, 0x34, 0x8a, + 0x95, 0x18, 0x93, 0x3e, 0x19, 0x46, 0xc5, 0x1d, 0x40, 0xf7, 0x21, 0x2a, 0xe7, 0x4c, 0x2c, 0xc6, + 0x4e, 0xf0, 0xb8, 0xeb, 0xab, 0xbb, 0x1e, 0x38, 0x17, 0x9c, 0x1e, 0x02, 0x84, 0x62, 0xc3, 0x8f, + 0x7b, 0x41, 0xeb, 0x91, 0x33, 0xb6, 0x40, 0x7a, 0x02, 0x8f, 0xdb, 0xdb, 0x8d, 0xa7, 0xac, 0xe6, + 0x73, 0x8c, 0x77, 0x3c, 0xe7, 0x51, 0x0b, 0x7f, 0xf0, 0x28, 0xb5, 0x90, 0x18, 0xab, 0x5d, 0x69, + 0x9d, 0x46, 0x3e, 0xfe, 0x5f, 0xf3, 0xa0, 0xdf, 0x1b, 0xee, 0x8d, 0xde, 0x64, 0xe1, 0xd1, 0x59, + 0xe3, 0x5f, 0x4b, 0xc9, 0xda, 0x47, 0x67, 0x9f, 0x6e, 0xf5, 0xc5, 0x4a, 0xef, 0x22, 0x36, 0x1b, + 0x2a, 0x83, 0x77, 0xb0, 0xbf, 0xd6, 0x16, 0xa3, 0x64, 0x6d, 0x90, 0x1e, 0xc1, 0x5e, 0xc9, 0xc5, + 0x98, 0xe3, 0x85, 0x28, 0xd1, 0xc4, 0xa4, 0xdf, 0x1b, 0x46, 0x05, 0x94, 0x5c, 0xbc, 0x0f, 0xc8, + 0xe0, 0x57, 0x17, 0x0e, 0x9a, 0x06, 0xe7, 0xb5, 0xba, 0x77, 0x76, 0xc5, 0xd9, 0x23, 0x38, 0xdc, + 0x60, 0x4c, 0xf0, 0x76, 0x74, 0x45, 0x60, 0xa7, 0x61, 0x50, 0x0e, 0x4f, 0xd6, 0xec, 0x80, 0x1e, + 0xdf, 0x8d, 0xdf, 0xfc, 0xe7, 0x26, 0xcf, 0xb6, 0xb0, 0xc2, 0xb0, 0x41, 0x87, 0x7e, 0x85, 0xa7, + 0x6b, 0xef, 0x43, 0x9f, 0xaf, 0x76, 0xd8, 0xb4, 0xc9, 0xe4, 0x64, 0x2b, 0xaf, 0x9d, 0x75, 0x7a, + 0x7a, 0x79, 0x9d, 0x92, 0xab, 0xeb, 0xb4, 0xf3, 0x7d, 0x99, 0x92, 0xcb, 0x65, 0x4a, 0x7e, 0x2f, + 0x53, 0xf2, 0x67, 0x99, 0x92, 0x1f, 0x7f, 0xd3, 0xce, 0xe7, 0xe3, 0x9b, 0xe4, 0xce, 0xdc, 0x04, + 0xe7, 0x68, 0x73, 0x35, 0xab, 0x9a, 0x14, 0x9b, 0x9c, 0x6b, 0x76, 0x9b, 0xe0, 0xc9, 0x43, 0x1f, + 0xdc, 0xd7, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x10, 0x72, 0x70, 0xc7, 0x2c, 0x04, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -457,6 +485,20 @@ func (m *NodePrepareResourceRequest) MarshalToSizedBuffer(dAtA []byte) (int, err _ = i var l int _ = l + if len(m.StructuredResourceHandle) > 0 { + for iNdEx := len(m.StructuredResourceHandle) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.StructuredResourceHandle[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintApi(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } if len(m.ResourceHandle) > 0 { i -= len(m.ResourceHandle) copy(dAtA[i:], m.ResourceHandle) @@ -540,6 +582,20 @@ func (m *NodeUnprepareResourceRequest) MarshalToSizedBuffer(dAtA []byte) (int, e _ = i var l int _ = l + if len(m.StructuredResourceHandle) > 0 { + for iNdEx := len(m.StructuredResourceHandle) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.StructuredResourceHandle[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintApi(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } if len(m.ResourceHandle) > 0 { i -= len(m.ResourceHandle) copy(dAtA[i:], m.ResourceHandle) @@ -627,6 +683,12 @@ func (m *NodePrepareResourceRequest) Size() (n int) { if l > 0 { n += 1 + l + sovApi(uint64(l)) } + if len(m.StructuredResourceHandle) > 0 { + for _, e := range m.StructuredResourceHandle { + l = e.Size() + n += 1 + l + sovApi(uint64(l)) + } + } return n } @@ -667,6 +729,12 @@ func (m *NodeUnprepareResourceRequest) Size() (n int) { if l > 0 { n += 1 + l + sovApi(uint64(l)) } + if len(m.StructuredResourceHandle) > 0 { + for _, e := range m.StructuredResourceHandle { + l = e.Size() + n += 1 + l + sovApi(uint64(l)) + } + } return n } @@ -689,11 +757,17 @@ func (this *NodePrepareResourceRequest) String() string { if this == nil { return "nil" } + repeatedStringForStructuredResourceHandle := "[]*StructuredResourceHandle{" + for _, f := range this.StructuredResourceHandle { + repeatedStringForStructuredResourceHandle += strings.Replace(fmt.Sprintf("%v", f), "StructuredResourceHandle", "v1alpha2.StructuredResourceHandle", 1) + "," + } + repeatedStringForStructuredResourceHandle += "}" s := strings.Join([]string{`&NodePrepareResourceRequest{`, `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, `ClaimUid:` + fmt.Sprintf("%v", this.ClaimUid) + `,`, `ClaimName:` + fmt.Sprintf("%v", this.ClaimName) + `,`, `ResourceHandle:` + fmt.Sprintf("%v", this.ResourceHandle) + `,`, + `StructuredResourceHandle:` + repeatedStringForStructuredResourceHandle + `,`, `}`, }, "") return s @@ -712,11 +786,17 @@ func (this *NodeUnprepareResourceRequest) String() string { if this == nil { return "nil" } + repeatedStringForStructuredResourceHandle := "[]*StructuredResourceHandle{" + for _, f := range this.StructuredResourceHandle { + repeatedStringForStructuredResourceHandle += strings.Replace(fmt.Sprintf("%v", f), "StructuredResourceHandle", "v1alpha2.StructuredResourceHandle", 1) + "," + } + repeatedStringForStructuredResourceHandle += "}" s := strings.Join([]string{`&NodeUnprepareResourceRequest{`, `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, `ClaimUid:` + fmt.Sprintf("%v", this.ClaimUid) + `,`, `ClaimName:` + fmt.Sprintf("%v", this.ClaimName) + `,`, `ResourceHandle:` + fmt.Sprintf("%v", this.ResourceHandle) + `,`, + `StructuredResourceHandle:` + repeatedStringForStructuredResourceHandle + `,`, `}`, }, "") return s @@ -895,6 +975,40 @@ func (m *NodePrepareResourceRequest) Unmarshal(dAtA []byte) error { } m.ResourceHandle = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StructuredResourceHandle", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthApi + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthApi + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.StructuredResourceHandle = append(m.StructuredResourceHandle, &v1alpha2.StructuredResourceHandle{}) + if err := m.StructuredResourceHandle[len(m.StructuredResourceHandle)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApi(dAtA[iNdEx:]) @@ -1155,6 +1269,40 @@ func (m *NodeUnprepareResourceRequest) Unmarshal(dAtA []byte) error { } m.ResourceHandle = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StructuredResourceHandle", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthApi + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthApi + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.StructuredResourceHandle = append(m.StructuredResourceHandle, &v1alpha2.StructuredResourceHandle{}) + if err := m.StructuredResourceHandle[len(m.StructuredResourceHandle)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApi(dAtA[iNdEx:]) diff --git a/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha2/api.proto b/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha2/api.proto index a7a2b1db0a7..5a722616822 100644 --- a/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha2/api.proto +++ b/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha2/api.proto @@ -22,6 +22,7 @@ package v1alpha2; option go_package = "k8s.io/kubelet/pkg/apis/dra/v1alpha2"; import "github.com/gogo/protobuf/gogoproto/gogo.proto"; +import "k8s.io/api/resource/v1alpha2/generated.proto"; option (gogoproto.goproto_stringer_all) = false; option (gogoproto.stringer_all) = true; @@ -52,6 +53,12 @@ message NodePrepareResourceRequest { // Resource handle (AllocationResult.ResourceHandles[*].Data) // This field is REQUIRED. string resource_handle = 4; + // Structured parameter resource handle (AllocationResult.ResourceHandles[*].StructuredData). + // This field is OPTIONAL. If present, it needs to be used + // instead of resource_handle. It will only have a single entry. + // + // Using "repeated" instead of "optional" is a workaround for https://github.com/gogo/protobuf/issues/713. + repeated k8s.io.api.resource.v1alpha2.StructuredResourceHandle structured_resource_handle = 5; } message NodePrepareResourceResponse { @@ -74,6 +81,10 @@ message NodeUnprepareResourceRequest { // Resource handle (AllocationResult.ResourceHandles[*].Data) // This field is REQUIRED. string resource_handle = 4; + // Structured parameter resource handle (AllocationResult.ResourceHandles[*].StructuredData). + // This field is OPTIONAL. If present, it needs to be used + // instead of resource_handle. It will only have a single entry. + repeated k8s.io.api.resource.v1alpha2.StructuredResourceHandle structured_resource_handle = 5; } message NodeUnprepareResourceResponse { diff --git a/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha3/api.pb.go b/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha3/api.pb.go index 92233f98ee9..3a9929690b1 100644 --- a/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha3/api.pb.go +++ b/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha3/api.pb.go @@ -29,6 +29,7 @@ import ( codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" io "io" + v1alpha2 "k8s.io/api/resource/v1alpha2" math "math" math_bits "math/bits" reflect "reflect" @@ -353,9 +354,15 @@ type Claim struct { Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` // Resource handle (AllocationResult.ResourceHandles[*].Data) // This field is REQUIRED. - ResourceHandle string `protobuf:"bytes,4,opt,name=resource_handle,json=resourceHandle,proto3" json:"resource_handle,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_sizecache int32 `json:"-"` + ResourceHandle string `protobuf:"bytes,4,opt,name=resource_handle,json=resourceHandle,proto3" json:"resource_handle,omitempty"` + // Structured parameter resource handle (AllocationResult.ResourceHandles[*].StructuredData). + // This field is OPTIONAL. If present, it needs to be used + // instead of resource_handle. It will only have a single entry. + // + // Using "repeated" instead of "optional" is a workaround for https://github.com/gogo/protobuf/issues/713. + StructuredResourceHandle []*v1alpha2.StructuredResourceHandle `protobuf:"bytes,5,rep,name=structured_resource_handle,json=structuredResourceHandle,proto3" json:"structured_resource_handle,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Claim) Reset() { *m = Claim{} } @@ -418,6 +425,13 @@ func (m *Claim) GetResourceHandle() string { return "" } +func (m *Claim) GetStructuredResourceHandle() []*v1alpha2.StructuredResourceHandle { + if m != nil { + return m.StructuredResourceHandle + } + return nil +} + func init() { proto.RegisterType((*NodePrepareResourcesRequest)(nil), "v1alpha3.NodePrepareResourcesRequest") proto.RegisterType((*NodePrepareResourcesResponse)(nil), "v1alpha3.NodePrepareResourcesResponse") @@ -433,39 +447,43 @@ func init() { func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) } var fileDescriptor_00212fb1f9d3bf1c = []byte{ - // 500 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0x4d, 0x6f, 0xd3, 0x40, - 0x10, 0xcd, 0x36, 0x49, 0x45, 0x26, 0x52, 0x8b, 0x56, 0x15, 0xb2, 0x42, 0x31, 0x91, 0x45, 0x49, - 0x2e, 0xd8, 0x22, 0x05, 0xa9, 0x02, 0x71, 0x49, 0x0b, 0x2a, 0x08, 0x21, 0x64, 0x89, 0x0b, 0x97, - 0xb2, 0xb6, 0x07, 0xc7, 0x8a, 0xe3, 0x35, 0xbb, 0x76, 0xa4, 0xde, 0xf8, 0x09, 0xfc, 0xac, 0x1e, - 0x38, 0x20, 0x4e, 0x9c, 0x2a, 0x6a, 0xfe, 0x08, 0xf2, 0xda, 0x4e, 0x3f, 0xe4, 0x34, 0x95, 0x7a, - 0x9b, 0x7d, 0xbb, 0x33, 0x6f, 0xe6, 0xbd, 0xb1, 0xa1, 0xc3, 0xe2, 0xc0, 0x8c, 0x05, 0x4f, 0x38, - 0xbd, 0x33, 0x7f, 0xca, 0xc2, 0x78, 0xc2, 0x76, 0x7b, 0x4f, 0xfc, 0x20, 0x99, 0xa4, 0x8e, 0xe9, - 0xf2, 0x99, 0xe5, 0x73, 0x9f, 0x5b, 0xea, 0x81, 0x93, 0x7e, 0x55, 0x27, 0x75, 0x50, 0x51, 0x91, - 0x68, 0xbc, 0x81, 0xfb, 0x1f, 0xb8, 0x87, 0x1f, 0x05, 0xc6, 0x4c, 0xa0, 0x8d, 0x92, 0xa7, 0xc2, - 0x45, 0x69, 0xe3, 0xb7, 0x14, 0x65, 0x42, 0x07, 0xb0, 0xee, 0x86, 0x2c, 0x98, 0x49, 0x8d, 0xf4, - 0x9b, 0xc3, 0xee, 0x68, 0xd3, 0xac, 0x88, 0xcc, 0xfd, 0x1c, 0xb7, 0xcb, 0x6b, 0xe3, 0x27, 0x81, - 0xed, 0xfa, 0x42, 0x32, 0xe6, 0x91, 0x44, 0xfa, 0xee, 0x4a, 0xa5, 0xd1, 0x79, 0xa5, 0xeb, 0xf2, - 0x0a, 0x1a, 0xf9, 0x3a, 0x4a, 0xc4, 0x71, 0x45, 0xd6, 0xfb, 0x02, 0xdd, 0x0b, 0x30, 0xbd, 0x0b, - 0xcd, 0x29, 0x1e, 0x6b, 0xa4, 0x4f, 0x86, 0x1d, 0x3b, 0x0f, 0xe9, 0x4b, 0x68, 0xcf, 0x59, 0x98, - 0xa2, 0xb6, 0xd6, 0x27, 0xc3, 0xee, 0x68, 0xe7, 0x5a, 0xae, 0x8a, 0xca, 0x2e, 0x72, 0x5e, 0xac, - 0xed, 0x11, 0xc3, 0xab, 0x95, 0x65, 0x31, 0x8c, 0x05, 0x5d, 0xd7, 0x0b, 0x8e, 0x3c, 0x9c, 0x07, - 0x2e, 0x16, 0x13, 0x75, 0xc6, 0x1b, 0xd9, 0xe9, 0x43, 0xd8, 0x3f, 0x78, 0x7b, 0x50, 0xa0, 0x36, - 0xb8, 0x5e, 0x50, 0xc6, 0x74, 0x0b, 0xda, 0x28, 0x04, 0x17, 0xaa, 0xa1, 0x8e, 0x5d, 0x1c, 0x8c, - 0x43, 0x78, 0x90, 0xb3, 0x7c, 0x8a, 0xe2, 0xdb, 0xca, 0xff, 0x9b, 0x80, 0xbe, 0xac, 0x54, 0xd9, - 0xf3, 0xfb, 0x2b, 0xb5, 0x9e, 0x5d, 0x16, 0x65, 0x79, 0x66, 0xad, 0x05, 0xce, 0x2a, 0x0b, 0x5e, - 0x5d, 0xb6, 0x60, 0xb0, 0x82, 0xad, 0xce, 0x84, 0xe7, 0x4b, 0xe4, 0x59, 0x8c, 0xb4, 0x50, 0x95, - 0x5c, 0x54, 0x35, 0x81, 0xb6, 0x6a, 0x8d, 0x6e, 0x43, 0x27, 0x62, 0x33, 0x94, 0x31, 0x73, 0xb1, - 0x7c, 0x72, 0x0e, 0xe4, 0x2d, 0xa7, 0x81, 0x57, 0x1a, 0x92, 0x87, 0x94, 0x42, 0x2b, 0xbf, 0xd6, - 0x9a, 0x0a, 0x52, 0x31, 0x1d, 0xc0, 0xa6, 0x28, 0x69, 0x8f, 0x26, 0x2c, 0xf2, 0x42, 0xd4, 0x5a, - 0xea, 0x7a, 0xa3, 0x82, 0x0f, 0x15, 0x3a, 0x3a, 0x25, 0xd0, 0xca, 0xbb, 0xa5, 0x3e, 0x6c, 0xd5, - 0x2d, 0x34, 0xdd, 0x59, 0xb5, 0xf0, 0xca, 0xf2, 0xde, 0xe3, 0x9b, 0x7d, 0x17, 0x46, 0x83, 0xce, - 0xe0, 0x5e, 0xbd, 0x71, 0x74, 0xb0, 0xda, 0xda, 0x82, 0x6c, 0x78, 0xd3, 0x1d, 0x30, 0x1a, 0xe3, - 0xf1, 0xc9, 0x99, 0x4e, 0xfe, 0x9c, 0xe9, 0x8d, 0xef, 0x99, 0x4e, 0x4e, 0x32, 0x9d, 0xfc, 0xca, - 0x74, 0xf2, 0x37, 0xd3, 0xc9, 0x8f, 0x7f, 0x7a, 0xe3, 0xf3, 0xa3, 0xe9, 0x9e, 0x34, 0x03, 0x6e, - 0x4d, 0x53, 0x07, 0x43, 0x4c, 0xac, 0x78, 0xea, 0x5b, 0x2c, 0x0e, 0xa4, 0xe5, 0x09, 0x66, 0x55, - 0x24, 0xce, 0xba, 0xfa, 0xe9, 0xec, 0xfe, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x42, 0xff, 0x15, 0x6b, - 0xba, 0x04, 0x00, 0x00, + // 562 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0xcd, 0x6e, 0xd3, 0x40, + 0x10, 0xce, 0x36, 0x49, 0x45, 0x26, 0x52, 0x8b, 0x56, 0x15, 0xb2, 0x42, 0x31, 0x91, 0x45, 0x49, + 0x0e, 0x60, 0x0b, 0x07, 0x50, 0x05, 0xe2, 0x92, 0x16, 0x54, 0x10, 0x42, 0xc8, 0x88, 0x0b, 0x97, + 0xb0, 0xb1, 0x07, 0xc7, 0x4a, 0x62, 0x9b, 0x5d, 0x3b, 0x52, 0x6f, 0x3c, 0x02, 0x8f, 0xd5, 0x03, + 0x07, 0xc4, 0x89, 0x53, 0x45, 0xcd, 0x8d, 0xa7, 0x40, 0x5e, 0xdb, 0x69, 0x13, 0x39, 0x4d, 0xa5, + 0xde, 0x66, 0xe7, 0xef, 0x9b, 0xfd, 0xe6, 0x07, 0x1a, 0x2c, 0xf4, 0xf4, 0x90, 0x07, 0x51, 0x40, + 0x6f, 0xcc, 0x1e, 0xb1, 0x49, 0x38, 0x62, 0xbd, 0xd6, 0x43, 0xd7, 0x8b, 0x46, 0xf1, 0x50, 0xb7, + 0x83, 0xa9, 0xe1, 0x06, 0x6e, 0x60, 0x48, 0x87, 0x61, 0xfc, 0x45, 0xbe, 0xe4, 0x43, 0x4a, 0x59, + 0x60, 0xeb, 0xc1, 0x78, 0x5f, 0xe8, 0x5e, 0x60, 0xb0, 0xd0, 0x33, 0x38, 0x8a, 0x20, 0xe6, 0x36, + 0x1a, 0x79, 0x32, 0xd3, 0x70, 0xd1, 0x47, 0xce, 0x22, 0x74, 0x32, 0x6f, 0xed, 0x15, 0xdc, 0x7e, + 0x17, 0x38, 0xf8, 0x9e, 0x63, 0xc8, 0x38, 0x5a, 0xb9, 0xbf, 0xb0, 0xf0, 0x6b, 0x8c, 0x22, 0xa2, + 0x1d, 0xd8, 0xb4, 0x27, 0xcc, 0x9b, 0x0a, 0x85, 0xb4, 0xab, 0xdd, 0xa6, 0xb9, 0xad, 0x17, 0x65, + 0xe9, 0x07, 0xa9, 0xde, 0xca, 0xcd, 0xda, 0x0f, 0x02, 0xbb, 0xe5, 0x89, 0x44, 0x18, 0xf8, 0x02, + 0xe9, 0x9b, 0xa5, 0x4c, 0xe6, 0x79, 0xa6, 0xcb, 0xe2, 0x32, 0x18, 0xf1, 0xd2, 0x8f, 0xf8, 0x71, + 0x01, 0xd6, 0xfa, 0x0c, 0xcd, 0x0b, 0x6a, 0x7a, 0x13, 0xaa, 0x63, 0x3c, 0x56, 0x48, 0x9b, 0x74, + 0x1b, 0x56, 0x2a, 0xd2, 0xe7, 0x50, 0x9f, 0xb1, 0x49, 0x8c, 0xca, 0x46, 0x9b, 0x74, 0x9b, 0xe6, + 0xde, 0xa5, 0x58, 0x05, 0x94, 0x95, 0xc5, 0x3c, 0xdb, 0xd8, 0x27, 0x9a, 0x53, 0x4a, 0xcb, 0xfc, + 0x33, 0x06, 0x34, 0x6d, 0xc7, 0x1b, 0x38, 0x38, 0xf3, 0x6c, 0xcc, 0x7e, 0xd4, 0xe8, 0x6f, 0x25, + 0xa7, 0x77, 0xe1, 0xe0, 0xf0, 0xf5, 0x61, 0xa6, 0xb5, 0xc0, 0x76, 0xbc, 0x5c, 0xa6, 0x3b, 0x50, + 0x47, 0xce, 0x03, 0x2e, 0x0b, 0x6a, 0x58, 0xd9, 0x43, 0x3b, 0x82, 0x3b, 0x29, 0xca, 0x47, 0x3f, + 0xbc, 0x2e, 0xfd, 0xbf, 0x08, 0xa8, 0xab, 0x52, 0xe5, 0x35, 0xbf, 0x5d, 0xca, 0xf5, 0x78, 0x91, + 0x94, 0xd5, 0x91, 0xa5, 0x2d, 0x18, 0xae, 0x6b, 0xc1, 0x8b, 0xc5, 0x16, 0x74, 0xd6, 0xa0, 0x95, + 0x35, 0xe1, 0xc9, 0x0a, 0x7a, 0xe6, 0x5f, 0x9a, 0xb3, 0x4a, 0x2e, 0xb2, 0xfa, 0x8f, 0x40, 0x5d, + 0xd6, 0x46, 0x77, 0xa1, 0xe1, 0xb3, 0x29, 0x8a, 0x90, 0xd9, 0x98, 0xfb, 0x9c, 0x2b, 0xd2, 0x9a, + 0x63, 0xcf, 0xc9, 0x3b, 0x92, 0x8a, 0x94, 0x42, 0x2d, 0x35, 0x2b, 0x55, 0xa9, 0x92, 0x32, 0xed, + 0xc0, 0x76, 0xb1, 0x45, 0x83, 0x11, 0xf3, 0x9d, 0x09, 0x2a, 0x35, 0x69, 0xde, 0x2a, 0xd4, 0x47, + 0x52, 0x4b, 0x23, 0x68, 0x89, 0x88, 0xc7, 0x76, 0x14, 0x73, 0x74, 0x06, 0xcb, 0x31, 0x75, 0xc9, + 0xf9, 0x53, 0x3d, 0x5b, 0x4e, 0x3d, 0xdd, 0xf3, 0xc2, 0xa5, 0x60, 0xc6, 0xd4, 0x3f, 0xcc, 0xe3, + 0xad, 0x85, 0xdc, 0x96, 0x22, 0x56, 0x58, 0xcc, 0x53, 0x02, 0xb5, 0x94, 0x24, 0xea, 0xc2, 0x4e, + 0xd9, 0x1e, 0xd1, 0xbd, 0x75, 0x7b, 0x26, 0x27, 0xad, 0x75, 0xff, 0x6a, 0xeb, 0xa8, 0x55, 0xe8, + 0x14, 0x6e, 0x95, 0xcf, 0x0b, 0xed, 0xac, 0x9f, 0xa8, 0x0c, 0xac, 0x7b, 0xd5, 0xd1, 0xd3, 0x2a, + 0xfd, 0xfe, 0xc9, 0x99, 0x4a, 0x7e, 0x9f, 0xa9, 0x95, 0x6f, 0x89, 0x4a, 0x4e, 0x12, 0x95, 0xfc, + 0x4c, 0x54, 0xf2, 0x27, 0x51, 0xc9, 0xf7, 0xbf, 0x6a, 0xe5, 0xd3, 0xbd, 0xfc, 0xd8, 0x8d, 0xe3, + 0x21, 0x4e, 0x30, 0x32, 0xc2, 0xb1, 0x9b, 0x1e, 0x3e, 0x61, 0x38, 0x9c, 0x15, 0x47, 0xaf, 0x37, + 0xdc, 0x94, 0xb7, 0xae, 0xf7, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x14, 0x30, 0xd4, 0x5f, 0x05, + 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -857,6 +875,20 @@ func (m *Claim) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.StructuredResourceHandle) > 0 { + for iNdEx := len(m.StructuredResourceHandle) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.StructuredResourceHandle[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintApi(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } if len(m.ResourceHandle) > 0 { i -= len(m.ResourceHandle) copy(dAtA[i:], m.ResourceHandle) @@ -1027,6 +1059,12 @@ func (m *Claim) Size() (n int) { if l > 0 { n += 1 + l + sovApi(uint64(l)) } + if len(m.StructuredResourceHandle) > 0 { + for _, e := range m.StructuredResourceHandle { + l = e.Size() + n += 1 + l + sovApi(uint64(l)) + } + } return n } @@ -1131,11 +1169,17 @@ func (this *Claim) String() string { if this == nil { return "nil" } + repeatedStringForStructuredResourceHandle := "[]*StructuredResourceHandle{" + for _, f := range this.StructuredResourceHandle { + repeatedStringForStructuredResourceHandle += strings.Replace(fmt.Sprintf("%v", f), "StructuredResourceHandle", "v1alpha2.StructuredResourceHandle", 1) + "," + } + repeatedStringForStructuredResourceHandle += "}" s := strings.Join([]string{`&Claim{`, `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, `Uid:` + fmt.Sprintf("%v", this.Uid) + `,`, `Name:` + fmt.Sprintf("%v", this.Name) + `,`, `ResourceHandle:` + fmt.Sprintf("%v", this.ResourceHandle) + `,`, + `StructuredResourceHandle:` + repeatedStringForStructuredResourceHandle + `,`, `}`, }, "") return s @@ -2027,6 +2071,40 @@ func (m *Claim) Unmarshal(dAtA []byte) error { } m.ResourceHandle = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StructuredResourceHandle", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthApi + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthApi + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.StructuredResourceHandle = append(m.StructuredResourceHandle, &v1alpha2.StructuredResourceHandle{}) + if err := m.StructuredResourceHandle[len(m.StructuredResourceHandle)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApi(dAtA[iNdEx:]) diff --git a/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha3/api.proto b/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha3/api.proto index c729aaf2714..e3ca0238249 100644 --- a/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha3/api.proto +++ b/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha3/api.proto @@ -22,6 +22,7 @@ package v1alpha3; option go_package = "k8s.io/kubelet/pkg/apis/dra/v1alpha3"; import "github.com/gogo/protobuf/gogoproto/gogo.proto"; +import "k8s.io/api/resource/v1alpha2/generated.proto"; option (gogoproto.goproto_stringer_all) = false; option (gogoproto.stringer_all) = true; @@ -100,4 +101,10 @@ message Claim { // Resource handle (AllocationResult.ResourceHandles[*].Data) // This field is REQUIRED. string resource_handle = 4; + // Structured parameter resource handle (AllocationResult.ResourceHandles[*].StructuredData). + // This field is OPTIONAL. If present, it needs to be used + // instead of resource_handle. It will only have a single entry. + // + // Using "repeated" instead of "optional" is a workaround for https://github.com/gogo/protobuf/issues/713. + repeated k8s.io.api.resource.v1alpha2.StructuredResourceHandle structured_resource_handle = 5; } diff --git a/test/e2e/dra/test-driver/app/kubeletplugin.go b/test/e2e/dra/test-driver/app/kubeletplugin.go index 6d9add80ad7..b51521a63b0 100644 --- a/test/e2e/dra/test-driver/app/kubeletplugin.go +++ b/test/e2e/dra/test-driver/app/kubeletplugin.go @@ -19,6 +19,7 @@ package app import ( "context" "encoding/json" + "errors" "fmt" "os" "path/filepath" @@ -26,6 +27,7 @@ import ( "google.golang.org/grpc" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/dynamic-resource-allocation/kubeletplugin" "k8s.io/klog/v2" drapbv1alpha2 "k8s.io/kubelet/pkg/apis/dra/v1alpha2" @@ -71,6 +73,7 @@ type ClaimID struct { } var _ drapbv1alpha2.NodeServer = &ExamplePlugin{} +var _ drapbv1alpha3.NodeServer = &ExamplePlugin{} // getJSONFilePath returns the absolute path where CDI file is/should be. func (ex *ExamplePlugin) getJSONFilePath(claimUID string) string { @@ -160,8 +163,28 @@ func (ex *ExamplePlugin) NodePrepareResource(ctx context.Context, req *drapbv1al // Determine environment variables. var p parameters - if err := json.Unmarshal([]byte(req.ResourceHandle), &p); err != nil { - return nil, fmt.Errorf("unmarshal resource handle: %w", err) + switch len(req.StructuredResourceHandle) { + case 0: + // Control plane controller did the allocation. + if err := json.Unmarshal([]byte(req.ResourceHandle), &p); err != nil { + return nil, fmt.Errorf("unmarshal resource handle: %w", err) + } + case 1: + // Scheduler did the allocation with structured parameters. + handle := req.StructuredResourceHandle[0] + if handle == nil { + return nil, errors.New("unexpected nil StructuredResourceHandle") + } + p.NodeName = handle.NodeName + if err := extractParameters(handle.VendorClassParameters, &p.EnvVars, "admin"); err != nil { + return nil, err + } + if err := extractParameters(handle.VendorClaimParameters, &p.EnvVars, "user"); err != nil { + return nil, err + } + default: + // Huh? + return nil, fmt.Errorf("invalid length of NodePrepareResourceRequest.StructuredResourceHandle: %d", len(req.StructuredResourceHandle)) } // Sanity check scheduling. @@ -212,16 +235,34 @@ func (ex *ExamplePlugin) NodePrepareResource(ctx context.Context, req *drapbv1al return resp, nil } +func extractParameters(parameters runtime.RawExtension, env *map[string]string, kind string) error { + if len(parameters.Raw) == 0 { + return nil + } + var data map[string]string + if err := json.Unmarshal(parameters.Raw, &data); err != nil { + return fmt.Errorf("decoding %s parameters: %v", kind, err) + } + if len(data) > 0 && *env == nil { + *env = make(map[string]string) + } + for key, value := range data { + (*env)[kind+"_"+key] = value + } + return nil +} + func (ex *ExamplePlugin) NodePrepareResources(ctx context.Context, req *drapbv1alpha3.NodePrepareResourcesRequest) (*drapbv1alpha3.NodePrepareResourcesResponse, error) { resp := &drapbv1alpha3.NodePrepareResourcesResponse{ Claims: make(map[string]*drapbv1alpha3.NodePrepareResourceResponse), } for _, claimReq := range req.Claims { claimResp, err := ex.NodePrepareResource(ctx, &drapbv1alpha2.NodePrepareResourceRequest{ - Namespace: claimReq.Namespace, - ClaimName: claimReq.Name, - ClaimUid: claimReq.Uid, - ResourceHandle: claimReq.ResourceHandle, + Namespace: claimReq.Namespace, + ClaimName: claimReq.Name, + ClaimUid: claimReq.Uid, + ResourceHandle: claimReq.ResourceHandle, + StructuredResourceHandle: claimReq.StructuredResourceHandle, }) if err != nil { resp.Claims[claimReq.Uid] = &drapbv1alpha3.NodePrepareResourceResponse{ From 3de376ecf6955ccd1b2ae31ffb310ae082b11cb1 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Wed, 21 Feb 2024 10:06:54 +0100 Subject: [PATCH 09/18] dra controller: support structured parameters When allocation was done by the scheduler, the controller needs to do the deallocation because there is no control-plane controller which could react to "DeallocationRequested". --- pkg/controller/resourceclaim/controller.go | 56 +++++++++++++++++-- .../rbac/bootstrappolicy/controller_policy.go | 2 +- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/pkg/controller/resourceclaim/controller.go b/pkg/controller/resourceclaim/controller.go index 54f3290cd00..b7da2844b96 100644 --- a/pkg/controller/resourceclaim/controller.go +++ b/pkg/controller/resourceclaim/controller.go @@ -20,6 +20,7 @@ import ( "context" "errors" "fmt" + "slices" "strings" "time" @@ -832,9 +833,11 @@ func (ec *Controller) syncClaim(ctx context.Context, namespace, name string) err return fmt.Errorf("unsupported ReservedFor entry: %v", reservedFor) } - logger.V(5).Info("claim reserved for counts", "currentCount", len(claim.Status.ReservedFor), "claim", klog.KRef(namespace, name), "updatedCount", len(valid)) + builtinControllerFinalizer := slices.Index(claim.Finalizers, resourcev1alpha2.Finalizer) + logger.V(5).Info("claim reserved for counts", "currentCount", len(claim.Status.ReservedFor), "claim", klog.KRef(namespace, name), "updatedCount", len(valid), "builtinController", builtinControllerFinalizer >= 0) if len(valid) < len(claim.Status.ReservedFor) { - // TODO (#113700): patch + // This is not using a patch because we want the update to fail if anything + // changed in the meantime. claim := claim.DeepCopy() claim.Status.ReservedFor = valid @@ -854,12 +857,53 @@ func (ec *Controller) syncClaim(ctx context.Context, namespace, name string) err // those, the resource claim controller will trigger deletion when the // pod is done. However, it doesn't hurt to also trigger deallocation // for such claims and not checking for them keeps this code simpler. - if len(valid) == 0 && - claim.Spec.AllocationMode == resourcev1alpha2.AllocationModeWaitForFirstConsumer { - claim.Status.DeallocationRequested = true + if len(valid) == 0 { + if builtinControllerFinalizer >= 0 { + if claim.Spec.AllocationMode == resourcev1alpha2.AllocationModeWaitForFirstConsumer || + claim.DeletionTimestamp != nil { + // Allocated by scheduler with structured parameters. We can "deallocate" + // by clearing the allocation. + claim.Status.Allocation = nil + } + } else if claim.Spec.AllocationMode == resourcev1alpha2.AllocationModeWaitForFirstConsumer { + // DRA driver controller in the control plane + // needs to do the deallocation. + claim.Status.DeallocationRequested = true + } + // In all other cases, we keep the claim allocated, in particular for immediate allocation + // with a control plane controller. } - _, err := ec.kubeClient.ResourceV1alpha2().ResourceClaims(claim.Namespace).UpdateStatus(ctx, claim, metav1.UpdateOptions{}) + claim, err := ec.kubeClient.ResourceV1alpha2().ResourceClaims(claim.Namespace).UpdateStatus(ctx, claim, metav1.UpdateOptions{}) + if err != nil { + return err + } + + // Now also remove the finalizer if it is not needed anymore. + // Note that the index may have changed as a result of the UpdateStatus call. + builtinControllerFinalizer := slices.Index(claim.Finalizers, resourcev1alpha2.Finalizer) + if builtinControllerFinalizer >= 0 && claim.Status.Allocation == nil { + claim.Finalizers = slices.Delete(claim.Finalizers, builtinControllerFinalizer, builtinControllerFinalizer+1) + if _, err := ec.kubeClient.ResourceV1alpha2().ResourceClaims(claim.Namespace).Update(ctx, claim, metav1.UpdateOptions{}); err != nil { + return err + } + } + } else if builtinControllerFinalizer >= 0 && claim.DeletionTimestamp != nil && len(valid) == 0 { + claim := claim.DeepCopy() + if claim.Status.Allocation != nil { + // This can happen when a claim with immediate allocation + // stopped being used, remained allocated, and then got + // deleted. As above we then need to clear the allocation. + claim.Status.Allocation = nil + var err error + claim, err = ec.kubeClient.ResourceV1alpha2().ResourceClaims(claim.Namespace).UpdateStatus(ctx, claim, metav1.UpdateOptions{}) + if err != nil { + return err + } + } + // Whether it was allocated or not, remove the finalizer to unblock removal. + claim.Finalizers = slices.Delete(claim.Finalizers, builtinControllerFinalizer, builtinControllerFinalizer+1) + _, err := ec.kubeClient.ResourceV1alpha2().ResourceClaims(claim.Namespace).Update(ctx, claim, metav1.UpdateOptions{}) if err != nil { return err } diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go index f6219bf3ad6..a79373af461 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go @@ -214,7 +214,7 @@ func buildControllerRoles() ([]rbacv1.ClusterRole, []rbacv1.ClusterRoleBinding) rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("pods/finalizers").RuleOrDie(), rbacv1helpers.NewRule("get", "list", "watch", "create", "delete").Groups(resourceGroup).Resources("resourceclaims").RuleOrDie(), rbacv1helpers.NewRule("get", "list", "watch", "create", "update", "patch").Groups(resourceGroup).Resources("podschedulingcontexts").RuleOrDie(), - rbacv1helpers.NewRule("update", "patch").Groups(resourceGroup).Resources("resourceclaims/status").RuleOrDie(), + rbacv1helpers.NewRule("update", "patch").Groups(resourceGroup).Resources("resourceclaims", "resourceclaims/status").RuleOrDie(), rbacv1helpers.NewRule("update", "patch").Groups(legacyGroup).Resources("pods/status").RuleOrDie(), eventsRule(), }, From 5e40afca060b9a26c68299494eeea3408806ffe3 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Mon, 11 Dec 2023 20:41:55 +0100 Subject: [PATCH 10/18] dra testing: add tests for structured parameters The test driver now supports a ConfigMap (as before) and the named resources structured parameter model. It doesn't have any instance attributes. --- test/e2e/dra/deploy.go | 55 ++- test/e2e/dra/dra.go | 341 ++++++++++++++++-- test/e2e/dra/test-driver/app/kubeletplugin.go | 5 + 3 files changed, 367 insertions(+), 34 deletions(-) diff --git a/test/e2e/dra/deploy.go b/test/e2e/dra/deploy.go index 71378705ebb..8f5bacb854e 100644 --- a/test/e2e/dra/deploy.go +++ b/test/e2e/dra/deploy.go @@ -24,6 +24,7 @@ import ( "net" "path" "sort" + "strings" "sync" "time" @@ -33,6 +34,7 @@ import ( appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/selection" @@ -125,6 +127,12 @@ type Driver struct { Name string Nodes map[string]*app.ExamplePlugin + parameterMode parameterMode + parameterAPIGroup string + parameterAPIVersion string + claimParameterAPIKind string + classParameterAPIKind string + NodeV1alpha2, NodeV1alpha3 bool mutex sync.Mutex @@ -132,6 +140,14 @@ type Driver struct { callCounts map[MethodInstance]int64 } +type parameterMode string + +const ( + parameterModeConfigMap parameterMode = "configmap" // ConfigMap parameters, control plane controller. + parameterModeStructured parameterMode = "structured" // No ConfigMaps, directly create and reference in-tree parameter objects. + parameterModeTranslated parameterMode = "translated" // Reference ConfigMaps in claim and class, generate in-tree parameter objects. +) + func (d *Driver) SetUp(nodes *Nodes, resources app.Resources) { ginkgo.By(fmt.Sprintf("deploying driver on nodes %v", nodes.NodeNames)) d.Nodes = map[string]*app.ExamplePlugin{} @@ -147,19 +163,40 @@ func (d *Driver) SetUp(nodes *Nodes, resources app.Resources) { d.ctx = ctx d.cleanup = append(d.cleanup, cancel) - // The controller is easy: we simply connect to the API server. - d.Controller = app.NewController(d.f.ClientSet, resources) - d.wg.Add(1) - go func() { - defer d.wg.Done() - d.Controller.Run(d.ctx, 5 /* workers */) - }() + switch d.parameterMode { + case "", parameterModeConfigMap: + // The controller is easy: we simply connect to the API server. + d.Controller = app.NewController(d.f.ClientSet, resources) + d.wg.Add(1) + go func() { + defer d.wg.Done() + d.Controller.Run(d.ctx, 5 /* workers */) + }() + } manifests := []string{ // The code below matches the content of this manifest (ports, // container names, etc.). "test/e2e/testing-manifests/dra/dra-test-driver-proxy.yaml", } + if d.parameterMode == "" { + d.parameterMode = parameterModeConfigMap + } + switch d.parameterMode { + case parameterModeConfigMap, parameterModeTranslated: + d.parameterAPIGroup = "" + d.parameterAPIVersion = "v1" + d.claimParameterAPIKind = "ConfigMap" + d.classParameterAPIKind = "ConfigMap" + case parameterModeStructured: + d.parameterAPIGroup = "resource.k8s.io" + d.parameterAPIVersion = "v1alpha2" + d.claimParameterAPIKind = "ResourceClaimParameters" + d.classParameterAPIKind = "ResourceClassParameters" + default: + framework.Failf("unknown test driver parameter mode: %s", d.parameterMode) + } + instanceKey := "app.kubernetes.io/instance" rsName := "" draAddr := path.Join(framework.TestContext.KubeletRootDir, "plugins", d.Name+".sock") @@ -192,6 +229,10 @@ func (d *Driver) SetUp(nodes *Nodes, resources app.Resources) { item.Spec.Template.Spec.Volumes[2].HostPath.Path = path.Join(framework.TestContext.KubeletRootDir, "plugins_registry") item.Spec.Template.Spec.Containers[0].Args = append(item.Spec.Template.Spec.Containers[0].Args, "--endpoint=/plugins_registry/"+d.Name+"-reg.sock") item.Spec.Template.Spec.Containers[1].Args = append(item.Spec.Template.Spec.Containers[1].Args, "--endpoint=/dra/"+d.Name+".sock") + case *apiextensionsv1.CustomResourceDefinition: + item.Name = strings.ReplaceAll(item.Name, "dra.e2e.example.com", d.parameterAPIGroup) + item.Spec.Group = d.parameterAPIGroup + } return nil }, manifests...) diff --git a/test/e2e/dra/dra.go b/test/e2e/dra/dra.go index d9ce944a5b7..7e71eb90847 100644 --- a/test/e2e/dra/dra.go +++ b/test/e2e/dra/dra.go @@ -18,9 +18,11 @@ package dra import ( "context" + "encoding/json" "errors" "fmt" "strings" + "sync" "time" "github.com/onsi/ginkgo/v2" @@ -32,6 +34,7 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes" "k8s.io/dynamic-resource-allocation/controller" "k8s.io/klog/v2" @@ -42,6 +45,7 @@ import ( e2epod "k8s.io/kubernetes/test/e2e/framework/pod" admissionapi "k8s.io/pod-security-admission/api" utilpointer "k8s.io/utils/pointer" + "k8s.io/utils/ptr" ) const ( @@ -142,8 +146,8 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, pod.Spec.NodeName = nodes.NodeNames[0] b.create(ctx, pod) - gomega.Consistently(func() error { - testPod, err := b.f.ClientSet.CoreV1().Pods(pod.Namespace).Get(context.TODO(), pod.Name, metav1.GetOptions{}) + gomega.Consistently(ctx, func(ctx context.Context) error { + testPod, err := b.f.ClientSet.CoreV1().Pods(pod.Namespace).Get(ctx, pod.Name, metav1.GetOptions{}) if err != nil { return fmt.Errorf("expected the test pod %s to exist: %w", pod.Name, err) } @@ -191,25 +195,188 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) }) - ginkgo.Context("driver", func() { + driverTest := func(parameterMode parameterMode) { nodes := NewNodes(f, 1, 1) - driver := NewDriver(f, nodes, networkResources) // All tests get their own driver instance. + maxAllocations := 1 + numPods := 10 + generateResources := func() app.Resources { + resources := perNode(maxAllocations, nodes)() + resources.Shareable = true + return resources + } + driver := NewDriver(f, nodes, generateResources) // All tests get their own driver instance. + driver.parameterMode = parameterMode b := newBuilder(f, driver) // We need the parameters name *before* creating it. b.parametersCounter = 1 b.classParametersName = b.parametersName() + expectedEnv := []string{"user_a", "b", "user_request_foo", "bar", "admin_x", "y"} + genParameters := func() []klog.KMetadata { + var objects []klog.KMetadata + switch parameterMode { + case parameterModeConfigMap: + objects = append(objects, + b.parameters("x", "y"), + b.parameters("a", "b", "request_foo", "bar"), + ) + case parameterModeTranslated: + objects = append(objects, + b.parameters("x", "y"), + b.classParameters(b.parametersName(), "x", "y"), + b.parameters("a", "b", "request_foo", "bar"), + b.claimParameters(b.parametersName(), []string{"a", "b"}, []string{"request_foo", "bar"}), + ) + // The parameters object is not the last one but the second-last. + b.parametersCounter-- + case parameterModeStructured: + objects = append(objects, + b.classParameters("", "x", "y"), + b.claimParameters("", []string{"a", "b"}, []string{"request_foo", "bar"}), + ) + } + return objects + } + ginkgo.It("supports claim and class parameters", func(ctx context.Context) { - classParameters := b.parameters("x", "y") - claimParameters := b.parameters() + objects := genParameters() + + // TODO: replace with publishing NodeResourceSlice through kubelet + if parameterMode == parameterModeTranslated || parameterMode == parameterModeStructured { + objects = append(objects, b.nodeResourceSlice(nodes.NodeNames[0], maxAllocations)) + } + pod, template := b.podInline(resourcev1alpha2.AllocationModeWaitForFirstConsumer) + objects = append(objects, pod, template) - b.create(ctx, classParameters, claimParameters, pod, template) + b.create(ctx, objects...) - b.testPod(ctx, f.ClientSet, pod, "user_a", "b", "admin_x", "y") + b.testPod(ctx, f.ClientSet, pod, expectedEnv...) }) + + ginkgo.It("supports reusing resources", func(ctx context.Context) { + objects := genParameters() + pods := make([]*v1.Pod, numPods) + for i := 0; i < numPods; i++ { + pod, template := b.podInline(resourcev1alpha2.AllocationModeWaitForFirstConsumer) + pods[i] = pod + objects = append(objects, pod, template) + } + + // TODO: replace with publishing NodeResourceSlice through kubelet + if parameterMode == parameterModeTranslated || parameterMode == parameterModeStructured { + objects = append(objects, b.nodeResourceSlice(nodes.NodeNames[0], maxAllocations)) + } + + b.create(ctx, objects...) + + // We don't know the order. All that matters is that all of them get scheduled eventually. + var wg sync.WaitGroup + wg.Add(numPods) + for i := 0; i < numPods; i++ { + pod := pods[i] + go func() { + defer ginkgo.GinkgoRecover() + defer wg.Done() + b.testPod(ctx, f.ClientSet, pod, expectedEnv...) + err := f.ClientSet.CoreV1().Pods(pod.Namespace).Delete(ctx, pod.Name, metav1.DeleteOptions{}) + framework.ExpectNoError(err, "delete pod") + framework.ExpectNoError(e2epod.WaitForPodNotFoundInNamespace(ctx, f.ClientSet, pod.Name, pod.Namespace, f.Timeouts.PodStartSlow)) + }() + } + wg.Wait() + }) + + ginkgo.It("supports sharing a claim concurrently", func(ctx context.Context) { + objects := genParameters() + objects = append(objects, b.externalClaim(resourcev1alpha2.AllocationModeWaitForFirstConsumer)) + + pods := make([]*v1.Pod, numPods) + for i := 0; i < numPods; i++ { + pod := b.podExternal() + pods[i] = pod + objects = append(objects, pod) + } + + // TODO: replace with publishing NodeResourceSlice through kubelet + if parameterMode == parameterModeTranslated || parameterMode == parameterModeStructured { + objects = append(objects, b.nodeResourceSlice(nodes.NodeNames[0], maxAllocations)) + } + + b.create(ctx, objects...) + + // We don't know the order. All that matters is that all of them get scheduled eventually. + f.Timeouts.PodStartSlow *= time.Duration(numPods) + var wg sync.WaitGroup + wg.Add(numPods) + for i := 0; i < numPods; i++ { + pod := pods[i] + go func() { + defer ginkgo.GinkgoRecover() + defer wg.Done() + b.testPod(ctx, f.ClientSet, pod, expectedEnv...) + }() + } + wg.Wait() + }) + + ginkgo.It("supports sharing a claim sequentially", func(ctx context.Context) { + objects := genParameters() + + // Change from "shareable" to "not shareable", if possible. + switch parameterMode { + case parameterModeConfigMap: + ginkgo.Skip("cannot change the driver's controller behavior on-the-fly") + case parameterModeTranslated, parameterModeStructured: + objects[len(objects)-1].(*resourcev1alpha2.ResourceClaimParameters).Shareable = false + } + + objects = append(objects, b.externalClaim(resourcev1alpha2.AllocationModeWaitForFirstConsumer)) + + pods := make([]*v1.Pod, numPods) + for i := 0; i < numPods; i++ { + pod := b.podExternal() + pods[i] = pod + objects = append(objects, pod) + } + + // TODO: replace with publishing NodeResourceSlice through kubelet + if parameterMode == parameterModeTranslated || parameterMode == parameterModeStructured { + objects = append(objects, b.nodeResourceSlice(nodes.NodeNames[0], maxAllocations)) + } + + b.create(ctx, objects...) + + // We don't know the order. All that matters is that all of them get scheduled eventually. + f.Timeouts.PodStartSlow *= time.Duration(numPods) + var wg sync.WaitGroup + wg.Add(numPods) + for i := 0; i < numPods; i++ { + pod := pods[i] + go func() { + defer ginkgo.GinkgoRecover() + defer wg.Done() + b.testPod(ctx, f.ClientSet, pod, expectedEnv...) + // We need to delete each running pod, otherwise the others cannot use the claim. + err := f.ClientSet.CoreV1().Pods(pod.Namespace).Delete(ctx, pod.Name, metav1.DeleteOptions{}) + framework.ExpectNoError(err, "delete pod") + framework.ExpectNoError(e2epod.WaitForPodNotFoundInNamespace(ctx, f.ClientSet, pod.Name, pod.Namespace, f.Timeouts.PodStartSlow)) + }() + } + wg.Wait() + }) + } + + ginkgo.Context("driver", func() { + ginkgo.Context("with ConfigMap parameters", func() { driverTest(parameterModeConfigMap) }) + ginkgo.Context("with translated parameters", func() { driverTest(parameterModeTranslated) }) + ginkgo.Context("with structured parameters", func() { driverTest(parameterModeStructured) }) }) + // TODO: move most of the test below into `testDriver` so that they get + // executed with different parameters. Not done yet because it'll be easier + // once publishing NodeResourceSlices works. + ginkgo.Context("cluster", func() { nodes := NewNodes(f, 1, 1) driver := NewDriver(f, nodes, networkResources) @@ -942,12 +1109,14 @@ func (b *builder) class() *resourcev1alpha2.ResourceClass { ObjectMeta: metav1.ObjectMeta{ Name: b.className(), }, - DriverName: b.driver.Name, - SuitableNodes: b.nodeSelector(), + DriverName: b.driver.Name, + SuitableNodes: b.nodeSelector(), + StructuredParameters: ptr.To(b.driver.parameterMode != parameterModeConfigMap), } if b.classParametersName != "" { class.ParametersRef = &resourcev1alpha2.ResourceClassParametersReference{ - Kind: "ConfigMap", + APIGroup: b.driver.parameterAPIGroup, + Kind: b.driver.classParameterAPIKind, Name: b.classParametersName, Namespace: b.f.Namespace.Name, } @@ -988,8 +1157,9 @@ func (b *builder) externalClaim(allocationMode resourcev1alpha2.AllocationMode) Spec: resourcev1alpha2.ResourceClaimSpec{ ResourceClassName: b.className(), ParametersRef: &resourcev1alpha2.ResourceClaimParametersReference{ - Kind: "ConfigMap", - Name: b.parametersName(), + APIGroup: b.driver.parameterAPIGroup, + Kind: b.driver.claimParameterAPIKind, + Name: b.parametersName(), }, AllocationMode: allocationMode, }, @@ -1005,20 +1175,15 @@ func (b *builder) parametersName() string { // parametersEnv returns the default env variables. func (b *builder) parametersEnv() map[string]string { return map[string]string{ - "a": "b", + "a": "b", + "request_foo": "bar", } } // parameters returns a config map with the default env variables. func (b *builder) parameters(kv ...string) *v1.ConfigMap { + data := b.parameterData(kv...) b.parametersCounter++ - data := map[string]string{} - for i := 0; i < len(kv); i += 2 { - data[kv[i]] = kv[i+1] - } - if len(data) == 0 { - data = b.parametersEnv() - } return &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Namespace: b.f.Namespace.Name, @@ -1028,6 +1193,116 @@ func (b *builder) parameters(kv ...string) *v1.ConfigMap { } } +func (b *builder) classParameters(generatedFrom string, kv ...string) *resourcev1alpha2.ResourceClassParameters { + raw := b.rawParameterData(kv...) + b.parametersCounter++ + parameters := &resourcev1alpha2.ResourceClassParameters{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: b.f.Namespace.Name, + Name: b.parametersName(), + }, + + VendorParameters: []resourcev1alpha2.VendorParameters{ + {DriverName: b.driver.Name, Parameters: runtime.RawExtension{Raw: raw}}, + }, + } + + if generatedFrom != "" { + parameters.GeneratedFrom = &resourcev1alpha2.ResourceClassParametersReference{ + Kind: "ConfigMap", + Namespace: b.f.Namespace.Name, + Name: generatedFrom, + } + } + + return parameters +} + +func (b *builder) claimParameters(generatedFrom string, claimKV, requestKV []string) *resourcev1alpha2.ResourceClaimParameters { + b.parametersCounter++ + parameters := &resourcev1alpha2.ResourceClaimParameters{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: b.f.Namespace.Name, + Name: b.parametersName(), + }, + + Shareable: true, + + // Without any request, nothing gets allocated and vendor + // parameters are also not passed down because they get + // attached to the allocation result. + // TODO: is that the semantic we want? + DriverRequests: []resourcev1alpha2.DriverRequests{ + { + DriverName: b.driver.Name, + VendorParameters: runtime.RawExtension{Raw: b.rawParameterData(claimKV...)}, + Requests: []resourcev1alpha2.ResourceRequest{ + { + VendorParameters: runtime.RawExtension{Raw: b.rawParameterData(requestKV...)}, + ResourceRequestModel: resourcev1alpha2.ResourceRequestModel{ + NamedResources: &resourcev1alpha2.NamedResourcesRequest{ + Selector: "true", + }, + }, + }, + }, + }, + }, + } + + if generatedFrom != "" { + parameters.GeneratedFrom = &resourcev1alpha2.ResourceClaimParametersReference{ + Kind: "ConfigMap", + Name: generatedFrom, + } + } + + return parameters +} + +func (b *builder) parameterData(kv ...string) map[string]string { + data := map[string]string{} + for i := 0; i < len(kv); i += 2 { + data[kv[i]] = kv[i+1] + } + if len(data) == 0 { + data = b.parametersEnv() + } + return data +} + +func (b *builder) rawParameterData(kv ...string) []byte { + data := b.parameterData(kv...) + raw, err := json.Marshal(data) + framework.ExpectNoError(err, "JSON encoding of parameter data") + return raw +} + +func (b *builder) nodeResourceSlice(nodeName string, capacity int) *resourcev1alpha2.NodeResourceSlice { + slice := &resourcev1alpha2.NodeResourceSlice{ + ObjectMeta: metav1.ObjectMeta{ + Name: b.driver.Name + "-" + nodeName, + }, + + NodeName: nodeName, + DriverName: b.driver.Name, + + NodeResourceModel: resourcev1alpha2.NodeResourceModel{ + NamedResources: &resourcev1alpha2.NamedResourcesResources{}, + }, + } + + for i := 0; i < capacity; i++ { + slice.NodeResourceModel.NamedResources.Instances = append(slice.NodeResourceModel.NamedResources.Instances, + resourcev1alpha2.NamedResourcesInstance{ + Name: fmt.Sprintf("instance-%d", i), + }, + ) + } + + return slice +} + // makePod returns a simple pod with no resource claims. // The pod prints its env and waits. func (b *builder) pod() *v1.Pod { @@ -1078,8 +1353,9 @@ func (b *builder) podInline(allocationMode resourcev1alpha2.AllocationMode) (*v1 Spec: resourcev1alpha2.ResourceClaimSpec{ ResourceClassName: b.className(), ParametersRef: &resourcev1alpha2.ResourceClaimParametersReference{ - Kind: "ConfigMap", - Name: b.parametersName(), + APIGroup: b.driver.parameterAPIGroup, + Kind: b.driver.claimParameterAPIKind, + Name: b.parametersName(), }, AllocationMode: allocationMode, }, @@ -1134,14 +1410,28 @@ func (b *builder) create(ctx context.Context, objs ...klog.KMetadata) []klog.KMe switch obj := obj.(type) { case *resourcev1alpha2.ResourceClass: createdObj, err = b.f.ClientSet.ResourceV1alpha2().ResourceClasses().Create(ctx, obj, metav1.CreateOptions{}) + ginkgo.DeferCleanup(func(ctx context.Context) { + err := b.f.ClientSet.ResourceV1alpha2().ResourceClasses().Delete(ctx, createdObj.GetName(), metav1.DeleteOptions{}) + framework.ExpectNoError(err, "delete resource class") + }) case *v1.Pod: createdObj, err = b.f.ClientSet.CoreV1().Pods(b.f.Namespace.Name).Create(ctx, obj, metav1.CreateOptions{}) case *v1.ConfigMap: - _, err = b.f.ClientSet.CoreV1().ConfigMaps(b.f.Namespace.Name).Create(ctx, obj, metav1.CreateOptions{}) + createdObj, err = b.f.ClientSet.CoreV1().ConfigMaps(b.f.Namespace.Name).Create(ctx, obj, metav1.CreateOptions{}) case *resourcev1alpha2.ResourceClaim: createdObj, err = b.f.ClientSet.ResourceV1alpha2().ResourceClaims(b.f.Namespace.Name).Create(ctx, obj, metav1.CreateOptions{}) case *resourcev1alpha2.ResourceClaimTemplate: createdObj, err = b.f.ClientSet.ResourceV1alpha2().ResourceClaimTemplates(b.f.Namespace.Name).Create(ctx, obj, metav1.CreateOptions{}) + case *resourcev1alpha2.ResourceClassParameters: + createdObj, err = b.f.ClientSet.ResourceV1alpha2().ResourceClassParameters(b.f.Namespace.Name).Create(ctx, obj, metav1.CreateOptions{}) + case *resourcev1alpha2.ResourceClaimParameters: + createdObj, err = b.f.ClientSet.ResourceV1alpha2().ResourceClaimParameters(b.f.Namespace.Name).Create(ctx, obj, metav1.CreateOptions{}) + case *resourcev1alpha2.NodeResourceSlice: + createdObj, err = b.f.ClientSet.ResourceV1alpha2().NodeResourceSlices().Create(ctx, obj, metav1.CreateOptions{}) + ginkgo.DeferCleanup(func(ctx context.Context) { + err := b.f.ClientSet.ResourceV1alpha2().NodeResourceSlices().Delete(ctx, createdObj.GetName(), metav1.DeleteOptions{}) + framework.ExpectNoError(err, "delete node resource slice") + }) default: framework.Fail(fmt.Sprintf("internal error, unsupported type %T", obj), 1) } @@ -1190,9 +1480,6 @@ func (b *builder) setUp() { } func (b *builder) tearDown(ctx context.Context) { - err := b.f.ClientSet.ResourceV1alpha2().ResourceClasses().Delete(ctx, b.className(), metav1.DeleteOptions{}) - framework.ExpectNoError(err, "delete resource class") - // Before we allow the namespace and all objects in it do be deleted by // the framework, we must ensure that test pods and the claims that // they use are deleted. Otherwise the driver might get deleted first, diff --git a/test/e2e/dra/test-driver/app/kubeletplugin.go b/test/e2e/dra/test-driver/app/kubeletplugin.go index b51521a63b0..9a564f10e78 100644 --- a/test/e2e/dra/test-driver/app/kubeletplugin.go +++ b/test/e2e/dra/test-driver/app/kubeletplugin.go @@ -182,6 +182,11 @@ func (ex *ExamplePlugin) NodePrepareResource(ctx context.Context, req *drapbv1al if err := extractParameters(handle.VendorClaimParameters, &p.EnvVars, "user"); err != nil { return nil, err } + for _, result := range handle.Results { + if err := extractParameters(result.VendorRequestParameters, &p.EnvVars, "user"); err != nil { + return nil, err + } + } default: // Huh? return nil, fmt.Errorf("invalid length of NodePrepareResourceRequest.StructuredResourceHandle: %d", len(req.StructuredResourceHandle)) From d59676a54531b6e135c0fbbe6b51c530f1150653 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Mon, 26 Feb 2024 12:53:04 +0100 Subject: [PATCH 11/18] dra kubelet: publish NodeResourceSlices The information is received from the DRA driver plugin through a new gRPC streaming interface. This is backwards compatible with old DRA driver kubelet plugins, their gRPC server will return "not implemented" and that can be handled by kubelet. Therefore no API break is needed. However, DRA drivers need to be updated because the Go API changed. They can return status.New(codes.Unimplemented, "no node resource support").Err() if they don't support the new ListAndWatchResources method and structured parameters. The controller in kubelet then synchronizes this information from the driver with NodeResourceSlice objects, creating, updating and deleting them as needed. --- cmd/kubelet/app/server.go | 1 + pkg/kubelet/cm/container_manager.go | 1 + pkg/kubelet/cm/container_manager_linux.go | 2 +- pkg/kubelet/cm/dra/manager.go | 2 +- pkg/kubelet/cm/dra/manager_test.go | 8 +- pkg/kubelet/cm/dra/plugin/client.go | 17 + pkg/kubelet/cm/dra/plugin/client_test.go | 89 ++++ pkg/kubelet/cm/dra/plugin/noderesources.go | 479 ++++++++++++++++++ pkg/kubelet/cm/dra/plugin/plugin.go | 33 +- pkg/kubelet/cm/dra/plugin/plugin_test.go | 14 +- pkg/kubelet/kubelet.go | 2 +- .../kubeletplugin/draplugin.go | 18 +- .../kubeletplugin/noderegistrar.go | 4 +- .../kubeletplugin/nonblockinggrpcserver.go | 13 +- .../kubelet/pkg/apis/dra/v1alpha3/api.pb.go | 478 +++++++++++++++-- .../kubelet/pkg/apis/dra/v1alpha3/api.proto | 13 + test/e2e/dra/deploy.go | 48 +- test/e2e/dra/dra.go | 289 +++++------ test/e2e/dra/test-driver/app/kubeletplugin.go | 69 ++- test/e2e/dra/test-driver/app/server.go | 2 +- test/e2e_node/dra_test.go | 9 +- 21 files changed, 1368 insertions(+), 223 deletions(-) create mode 100644 pkg/kubelet/cm/dra/plugin/noderesources.go diff --git a/cmd/kubelet/app/server.go b/cmd/kubelet/app/server.go index b8d406a2be3..d8d01b21e02 100644 --- a/cmd/kubelet/app/server.go +++ b/cmd/kubelet/app/server.go @@ -815,6 +815,7 @@ func run(ctx context.Context, s *options.KubeletServer, kubeDeps *kubelet.Depend kubeDeps.Mounter, kubeDeps.CAdvisorInterface, cm.NodeConfig{ + NodeName: nodeName, RuntimeCgroupsName: s.RuntimeCgroups, SystemCgroupsName: s.SystemCgroups, KubeletCgroupsName: s.KubeletCgroups, diff --git a/pkg/kubelet/cm/container_manager.go b/pkg/kubelet/cm/container_manager.go index d5ac7cbb459..dbd35dd71ef 100644 --- a/pkg/kubelet/cm/container_manager.go +++ b/pkg/kubelet/cm/container_manager.go @@ -135,6 +135,7 @@ type ContainerManager interface { } type NodeConfig struct { + NodeName types.NodeName RuntimeCgroupsName string SystemCgroupsName string KubeletCgroupsName string diff --git a/pkg/kubelet/cm/container_manager_linux.go b/pkg/kubelet/cm/container_manager_linux.go index 4b3d9ffe9dc..4ed1aa7b591 100644 --- a/pkg/kubelet/cm/container_manager_linux.go +++ b/pkg/kubelet/cm/container_manager_linux.go @@ -308,7 +308,7 @@ func NewContainerManager(mountUtil mount.Interface, cadvisorInterface cadvisor.I // initialize DRA manager if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.DynamicResourceAllocation) { klog.InfoS("Creating Dynamic Resource Allocation (DRA) manager") - cm.draManager, err = dra.NewManagerImpl(kubeClient, nodeConfig.KubeletRootDir) + cm.draManager, err = dra.NewManagerImpl(kubeClient, nodeConfig.KubeletRootDir, nodeConfig.NodeName) if err != nil { return nil, err } diff --git a/pkg/kubelet/cm/dra/manager.go b/pkg/kubelet/cm/dra/manager.go index 085366ac0af..49cd60cb266 100644 --- a/pkg/kubelet/cm/dra/manager.go +++ b/pkg/kubelet/cm/dra/manager.go @@ -45,7 +45,7 @@ type ManagerImpl struct { } // NewManagerImpl creates a new manager. -func NewManagerImpl(kubeClient clientset.Interface, stateFileDirectory string) (*ManagerImpl, error) { +func NewManagerImpl(kubeClient clientset.Interface, stateFileDirectory string, nodeName types.NodeName) (*ManagerImpl, error) { klog.V(2).InfoS("Creating DRA manager") claimInfoCache, err := newClaimInfoCache(stateFileDirectory, draManagerStateFileName) diff --git a/pkg/kubelet/cm/dra/manager_test.go b/pkg/kubelet/cm/dra/manager_test.go index 9e5e8c4bd67..dc0e697d0dd 100644 --- a/pkg/kubelet/cm/dra/manager_test.go +++ b/pkg/kubelet/cm/dra/manager_test.go @@ -154,7 +154,7 @@ func TestNewManagerImpl(t *testing.T) { }, } { t.Run(test.description, func(t *testing.T) { - manager, err := NewManagerImpl(kubeClient, test.stateFileDirectory) + manager, err := NewManagerImpl(kubeClient, test.stateFileDirectory, "worker") if test.wantErr { assert.Error(t, err) return @@ -287,7 +287,7 @@ func TestGetResources(t *testing.T) { }, } { t.Run(test.description, func(t *testing.T) { - manager, err := NewManagerImpl(kubeClient, t.TempDir()) + manager, err := NewManagerImpl(kubeClient, t.TempDir(), "worker") assert.NoError(t, err) if test.claimInfo != nil { @@ -760,7 +760,7 @@ func TestPrepareResources(t *testing.T) { } defer draServerInfo.teardownFn() - plg := plugin.NewRegistrationHandler() + plg := plugin.NewRegistrationHandler(nil, "worker") if err := plg.RegisterPlugin(test.driverName, draServerInfo.socketName, []string{"1.27"}); err != nil { t.Fatalf("failed to register plugin %s, err: %v", test.driverName, err) } @@ -1060,7 +1060,7 @@ func TestUnprepareResources(t *testing.T) { } defer draServerInfo.teardownFn() - plg := plugin.NewRegistrationHandler() + plg := plugin.NewRegistrationHandler(nil, "worker") if err := plg.RegisterPlugin(test.driverName, draServerInfo.socketName, []string{"1.27"}); err != nil { t.Fatalf("failed to register plugin %s, err: %v", test.driverName, err) } diff --git a/pkg/kubelet/cm/dra/plugin/client.go b/pkg/kubelet/cm/dra/plugin/client.go index e7cb802181b..6002a2a87b3 100644 --- a/pkg/kubelet/cm/dra/plugin/client.go +++ b/pkg/kubelet/cm/dra/plugin/client.go @@ -198,3 +198,20 @@ func (p *plugin) NodeUnprepareResources( logger.V(4).Info(log("done calling NodeUnprepareResources rpc"), "response", response, "err", err) return response, err } + +func (p *plugin) NodeListAndWatchResources( + ctx context.Context, + req *drapb.NodeListAndWatchResourcesRequest, + opts ...grpc.CallOption, +) (drapb.Node_NodeListAndWatchResourcesClient, error) { + logger := klog.FromContext(ctx) + logger.V(4).Info(log("calling NodeListAndWatchResources rpc"), "request", req) + + conn, err := p.getOrCreateGRPCConn() + if err != nil { + return nil, err + } + + nodeClient := drapb.NewNodeClient(conn) + return nodeClient.NodeListAndWatchResources(ctx, req, opts...) +} diff --git a/pkg/kubelet/cm/dra/plugin/client_test.go b/pkg/kubelet/cm/dra/plugin/client_test.go index 3e1889e2c97..4b898b88300 100644 --- a/pkg/kubelet/cm/dra/plugin/client_test.go +++ b/pkg/kubelet/cm/dra/plugin/client_test.go @@ -43,6 +43,16 @@ func (f *fakeV1alpha3GRPCServer) NodeUnprepareResource(ctx context.Context, in * return &drapbv1alpha3.NodeUnprepareResourcesResponse{}, nil } +func (f *fakeV1alpha3GRPCServer) NodeListAndWatchResources(req *drapbv1alpha3.NodeListAndWatchResourcesRequest, srv drapbv1alpha3.Node_NodeListAndWatchResourcesServer) error { + if err := srv.Send(&drapbv1alpha3.NodeListAndWatchResourcesResponse{}); err != nil { + return err + } + if err := srv.Send(&drapbv1alpha3.NodeListAndWatchResourcesResponse{}); err != nil { + return err + } + return nil +} + type fakeV1alpha2GRPCServer struct { drapbv1alpha2.UnimplementedNodeServer } @@ -288,3 +298,82 @@ func TestNodeUnprepareResource(t *testing.T) { }) } } + +func TestListAndWatchResources(t *testing.T) { + for _, test := range []struct { + description string + serverSetup func(string) (string, tearDown, error) + serverVersion string + request *drapbv1alpha3.NodeListAndWatchResourcesRequest + responses []*drapbv1alpha3.NodeListAndWatchResourcesResponse + expectError string + }{ + { + description: "server supports NodeResources API", + serverSetup: setupFakeGRPCServer, + serverVersion: v1alpha3Version, + request: &drapbv1alpha3.NodeListAndWatchResourcesRequest{}, + responses: []*drapbv1alpha3.NodeListAndWatchResourcesResponse{ + {}, + {}, + }, + expectError: "EOF", + }, + { + description: "server doesn't support NodeResources API", + serverSetup: setupFakeGRPCServer, + serverVersion: v1alpha2Version, + request: new(drapbv1alpha3.NodeListAndWatchResourcesRequest), + expectError: "Unimplemented", + }, + } { + t.Run(test.description, func(t *testing.T) { + addr, teardown, err := setupFakeGRPCServer(test.serverVersion) + if err != nil { + t.Fatal(err) + } + defer teardown() + + p := &plugin{ + endpoint: addr, + version: v1alpha3Version, + } + + conn, err := p.getOrCreateGRPCConn() + defer func() { + err := conn.Close() + if err != nil { + t.Error(err) + } + }() + if err != nil { + t.Fatal(err) + } + + draPlugins.add("dummy-plugin", p) + defer draPlugins.delete("dummy-plugin") + + client, err := NewDRAPluginClient("dummy-plugin") + if err != nil { + t.Fatal(err) + } + + stream, err := client.NodeListAndWatchResources(context.Background(), test.request) + if err != nil { + t.Fatal(err) + } + var actualResponses []*drapbv1alpha3.NodeListAndWatchResourcesResponse + var actualErr error + for { + resp, err := stream.Recv() + if err != nil { + actualErr = err + break + } + actualResponses = append(actualResponses, resp) + } + assert.Equal(t, test.responses, actualResponses) + assert.Contains(t, actualErr.Error(), test.expectError) + }) + } +} diff --git a/pkg/kubelet/cm/dra/plugin/noderesources.go b/pkg/kubelet/cm/dra/plugin/noderesources.go new file mode 100644 index 00000000000..79cec7cef84 --- /dev/null +++ b/pkg/kubelet/cm/dra/plugin/noderesources.go @@ -0,0 +1,479 @@ +/* +Copyright 2024 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 plugin + +import ( + "context" + "errors" + "fmt" + "io" + "sync" + "time" + + "github.com/google/go-cmp/cmp" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + resourceapi "k8s.io/api/resource/v1alpha2" + apiequality "k8s.io/apimachinery/pkg/api/equality" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/sets" + resourceinformers "k8s.io/client-go/informers/resource/v1alpha2" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/workqueue" + "k8s.io/klog/v2" + drapb "k8s.io/kubelet/pkg/apis/dra/v1alpha3" +) + +const ( + // resyncPeriod for informer + // TODO (https://github.com/kubernetes/kubernetes/issues/123688): disable? + resyncPeriod = time.Duration(10 * time.Minute) +) + +// nodeResourcesController collects resource information from all registered +// plugins and synchronizes that information with NodeResourceSlice objects. +type nodeResourcesController struct { + ctx context.Context + kubeClient kubernetes.Interface + nodeName string + wg sync.WaitGroup + queue workqueue.RateLimitingInterface + sliceStore cache.Store + + mutex sync.RWMutex + activePlugins map[string]*activePlugin +} + +// activePlugin holds the resource information about one plugin +// and the gRPC stream that is used to retrieve that. The context +// used by that stream can be canceled separately to stop +// the monitoring. +type activePlugin struct { + // cancel is the function which cancels the monitorPlugin goroutine + // for this plugin. + cancel func(reason error) + + // resources is protected by the nodeResourcesController read/write lock. + // When receiving updates from the driver, the entire slice gets replaced, + // so it is okay to not do a deep copy of it. Only retrieving the slice + // must be protected by a read lock. + resources []*resourceapi.NodeResourceModel +} + +// startNodeResourcesController constructs a new controller and starts it. +// +// If a kubeClient is provided, then it synchronizes NodeResourceSlices +// with the resource information provided by plugins. Without it, +// the controller is inactive. This can happen when kubelet is run stand-alone +// without an apiserver. In that case we can't and don't need to publish +// NodeResourceSlices. +func startNodeResourcesController(ctx context.Context, kubeClient kubernetes.Interface, nodeName string) *nodeResourcesController { + if kubeClient == nil { + return nil + } + + logger := klog.FromContext(ctx) + logger = klog.LoggerWithName(logger, "node resources controller") + ctx = klog.NewContext(ctx, logger) + + c := &nodeResourcesController{ + ctx: ctx, + kubeClient: kubeClient, + nodeName: nodeName, + queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "node_resource_slices"), + activePlugins: make(map[string]*activePlugin), + } + + c.wg.Add(1) + go func() { + defer c.wg.Done() + c.run(ctx) + }() + + return c +} + +// waitForStop blocks until all background activity spawned by +// the controller has stopped. The context passed to start must +// be canceled for that to happen. +// +// Not needed at the moment, but if it was, this is what it would +// look like... +// func (c *nodeResourcesController) waitForStop() { +// if c == nil { +// return +// } +// +// c.wg.Wait() +// } + +// addPlugin is called whenever a plugin has been (re-)registered. +func (c *nodeResourcesController) addPlugin(driverName string, pluginInstance *plugin) { + if c == nil { + return + } + + klog.FromContext(c.ctx).V(2).Info("Adding plugin", "driverName", driverName) + c.mutex.Lock() + defer c.mutex.Unlock() + + if active := c.activePlugins[driverName]; active != nil { + active.cancel(errors.New("plugin has re-registered")) + } + active := &activePlugin{} + cancelCtx, cancel := context.WithCancelCause(c.ctx) + active.cancel = cancel + c.activePlugins[driverName] = active + c.queue.Add(driverName) + + c.wg.Add(1) + go func() { + defer c.wg.Done() + c.monitorPlugin(cancelCtx, active, driverName, pluginInstance) + }() +} + +// removePlugin is called whenever a plugin has been unregistered. +func (c *nodeResourcesController) removePlugin(driverName string) { + if c == nil { + return + } + + klog.FromContext(c.ctx).V(2).Info("Removing plugin", "driverName", driverName) + c.mutex.Lock() + defer c.mutex.Unlock() + if active, ok := c.activePlugins[driverName]; ok { + active.cancel(errors.New("plugin has unregistered")) + delete(c.activePlugins, driverName) + c.queue.Add(driverName) + } +} + +// monitorPlugin calls the plugin to retrieve resource information and caches +// all responses that it gets for processing in the sync method. It keeps +// retrying until an error or EOF response indicates that no further data is +// going to be sent, then watch resources of the plugin stops until it +// re-registers. +func (c *nodeResourcesController) monitorPlugin(ctx context.Context, active *activePlugin, driverName string, pluginInstance *plugin) { + logger := klog.FromContext(ctx) + logger = klog.LoggerWithValues(logger, "driverName", driverName) + logger.Info("Starting to monitor node resources of the plugin") + defer func() { + r := recover() + logger.Info("Stopping to monitor node resources of the plugin", "reason", context.Cause(ctx), "err", ctx.Err(), "recover", r) + }() + + // Keep trying until canceled. + for ctx.Err() == nil { + logger.V(5).Info("Calling NodeListAndWatchResources") + stream, err := pluginInstance.NodeListAndWatchResources(ctx, new(drapb.NodeListAndWatchResourcesRequest)) + if err != nil { + switch { + case status.Convert(err).Code() == codes.Unimplemented: + // The plugin simply doesn't provide node resources. + active.cancel(errors.New("plugin does not support node resource reporting")) + default: + // This is a problem, report it and retry. + logger.Error(err, "Creating gRPC stream for node resources failed") + // TODO (https://github.com/kubernetes/kubernetes/issues/123689): expontential backoff? + select { + case <-time.After(5 * time.Second): + case <-ctx.Done(): + } + } + continue + } + for { + response, err := stream.Recv() + if err != nil { + switch { + case errors.Is(err, io.EOF): + // This is okay. Some plugins might never change their + // resources after reporting them once. + active.cancel(errors.New("plugin has closed the stream")) + case status.Convert(err).Code() == codes.Unimplemented: + // The plugin has the method, does not really implement it. + active.cancel(errors.New("plugin does not support node resource reporting")) + case ctx.Err() == nil: + // This is a problem, report it and retry. + logger.Error(err, "Reading node resources from gRPC stream failed") + // TODO (https://github.com/kubernetes/kubernetes/issues/123689): expontential backoff? + select { + case <-time.After(5 * time.Second): + case <-ctx.Done(): + } + } + break + } + + if loggerV := logger.V(6); loggerV.Enabled() { + loggerV.Info("Driver resources updated", "resources", response.Resources) + } else { + logger.V(5).Info("Driver resources updated", "numResources", len(response.Resources)) + } + + c.mutex.Lock() + active.resources = response.Resources + c.mutex.Unlock() + c.queue.Add(driverName) + } + } +} + +// run is running in the background. It handles blocking initialization (like +// syncing the informer) and then syncs the actual with the desired state. +func (c *nodeResourcesController) run(ctx context.Context) { + logger := klog.FromContext(ctx) + + // When kubelet starts, we have two choices: + // - Sync immediately, which in practice will delete all NodeResourceSlices + // because no plugin has registered yet. We could do a DeleteCollection + // to speed this up. + // - Wait a bit, then sync. If all plugins have re-registered in the meantime, + // we might not need to change any NodeResourceSlice. + // + // For now syncing starts immediately, with no DeleteCollection. This + // can be reconsidered later. + + // While kubelet starts up, there are errors: + // E0226 13:41:19.880621 126334 reflector.go:150] k8s.io/client-go@v0.0.0/tools/cache/reflector.go:232: Failed to watch *v1alpha2.NodeResourceSlice: failed to list *v1alpha2.NodeResourceSlice: noderesourceslices.resource.k8s.io is forbidden: User "system:anonymous" cannot list resource "noderesourceslices" in API group "resource.k8s.io" at the cluster scope + // + // The credentials used by kubeClient seem to get swapped out later, + // because eventually these list calls succeed. + // TODO (https://github.com/kubernetes/kubernetes/issues/123691): can we avoid these error log entries? Perhaps wait here? + + // We could use an indexer on driver name, but that seems overkill. + informer := resourceinformers.NewFilteredNodeResourceSliceInformer(c.kubeClient, resyncPeriod, nil, func(options *metav1.ListOptions) { + options.FieldSelector = "nodeName=" + c.nodeName + }) + c.sliceStore = informer.GetStore() + handler, err := informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj any) { + slice, ok := obj.(*resourceapi.NodeResourceSlice) + if !ok { + return + } + logger.V(5).Info("NodeResourceSlice add", "slice", klog.KObj(slice)) + c.queue.Add(slice.DriverName) + }, + UpdateFunc: func(old, new any) { + oldSlice, ok := old.(*resourceapi.NodeResourceSlice) + if !ok { + return + } + newSlice, ok := new.(*resourceapi.NodeResourceSlice) + if !ok { + return + } + if loggerV := logger.V(6); loggerV.Enabled() { + loggerV.Info("NodeResourceSlice update", "slice", klog.KObj(newSlice), "diff", cmp.Diff(oldSlice, newSlice)) + } else { + logger.V(5).Info("NodeResourceSlice update", "slice", klog.KObj(newSlice)) + } + c.queue.Add(newSlice.DriverName) + }, + DeleteFunc: func(obj any) { + if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); ok { + obj = tombstone.Obj + } + slice, ok := obj.(*resourceapi.NodeResourceSlice) + if !ok { + return + } + logger.V(5).Info("NodeResourceSlice delete", "slice", klog.KObj(slice)) + c.queue.Add(slice.DriverName) + }, + }) + if err != nil { + logger.Error(err, "Registering event handler on the NodeResourceSlice informer failed, disabling resource monitoring") + return + } + + // Start informer and wait for our cache to be populated. + c.wg.Add(1) + go func() { + defer c.wg.Done() + informer.Run(ctx.Done()) + }() + for !handler.HasSynced() { + select { + case <-time.After(time.Second): + case <-ctx.Done(): + return + } + } + logger.Info("NodeResourceSlice informer has synced") + + for c.processNextWorkItem(ctx) { + } +} + +func (c *nodeResourcesController) processNextWorkItem(ctx context.Context) bool { + key, shutdown := c.queue.Get() + if shutdown { + return false + } + defer c.queue.Done(key) + + driverName := key.(string) + + // Panics are caught and treated like errors. + var err error + func() { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("internal error: %v", r) + } + }() + err = c.sync(ctx, driverName) + }() + + if err != nil { + // TODO (https://github.com/kubernetes/enhancements/issues/3077): contextual logging in utilruntime + utilruntime.HandleError(fmt.Errorf("processing driver %v: %v", driverName, err)) + c.queue.AddRateLimited(key) + + // Return without removing the work item from the queue. + // It will be retried. + return true + } + + c.queue.Forget(key) + return true +} + +func (c *nodeResourcesController) sync(ctx context.Context, driverName string) error { + logger := klog.FromContext(ctx) + + // Gather information about the actual and desired state. + slices := c.sliceStore.List() + var driverResources []*resourceapi.NodeResourceModel + c.mutex.RLock() + if active, ok := c.activePlugins[driverName]; ok { + // No need for a deep copy, the entire slice gets replaced on writes. + driverResources = active.resources + } + c.mutex.RUnlock() + + // Resources that are not yet stored in any slice need to be published. + // Here we track the indices of any resources that are already stored. + storedResourceIndices := sets.New[int]() + + // Slices that don't match any driver resource can either be updated (if there + // are new driver resources that need to be stored) or they need to be deleted. + obsoleteSlices := make([]*resourceapi.NodeResourceSlice, 0, len(slices)) + + // Match slices with resource information. + for _, obj := range slices { + slice := obj.(*resourceapi.NodeResourceSlice) + if slice.DriverName != driverName { + continue + } + + index := indexOfModel(driverResources, &slice.NodeResourceModel) + if index >= 0 { + storedResourceIndices.Insert(index) + continue + } + + obsoleteSlices = append(obsoleteSlices, slice) + } + + if loggerV := logger.V(6); loggerV.Enabled() { + // Dump entire resource information. + loggerV.Info("Syncing existing driver node resource slices with driver resources", "slices", klog.KObjSlice(slices), "resources", driverResources) + } else { + logger.V(5).Info("Syncing existing driver node resource slices with driver resources", "slices", klog.KObjSlice(slices), "numResources", len(driverResources)) + } + + // Update stale slices before removing what's left. + // + // We don't really know which of these slices might have + // been used for "the" driver resource because they don't + // have a unique ID. In practice, a driver is most likely + // to just give us one NodeResourceModel, in which case + // this isn't a problem at all. If we have more than one, + // then at least conceptually it currently doesn't matter + // where we publish it. + // + // The long-term goal is to move the handling of + // NodeResourceSlice objects into the driver, with kubelet + // just acting as a REST proxy. The advantage of that will + // be that kubelet won't need to support the same + // resource API version as the driver and the control plane. + // With that approach, the driver will be able to match + // up objects more intelligently. + numObsoleteSlices := len(obsoleteSlices) + for index, resource := range driverResources { + if storedResourceIndices.Has(index) { + // No need to do anything, it is already stored exactly + // like this in an existing slice. + continue + } + + if numObsoleteSlices > 0 { + // Update one existing slice. + slice := obsoleteSlices[numObsoleteSlices-1] + numObsoleteSlices-- + slice = slice.DeepCopy() + slice.NodeResourceModel = *resource + logger.V(5).Info("Reusing existing node resource slice", "slice", klog.KObj(slice)) + if _, err := c.kubeClient.ResourceV1alpha2().NodeResourceSlices().Update(ctx, slice, metav1.UpdateOptions{}); err != nil { + return fmt.Errorf("update node resource slice: %w", err) + } + continue + } + + // Create a new slice. + slice := &resourceapi.NodeResourceSlice{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: c.nodeName + "-" + driverName + "-", + // TODO (https://github.com/kubernetes/kubernetes/issues/123692): node object as owner + }, + NodeName: c.nodeName, + DriverName: driverName, + NodeResourceModel: *resource, + } + logger.V(5).Info("Creating new node resource slice", "slice", klog.KObj(slice)) + if _, err := c.kubeClient.ResourceV1alpha2().NodeResourceSlices().Create(ctx, slice, metav1.CreateOptions{}); err != nil { + return fmt.Errorf("create node resource slice: %w", err) + } + } + + // All remaining slices are truly orphaned. + for i := 0; i < numObsoleteSlices; i++ { + slice := obsoleteSlices[i] + logger.V(5).Info("Deleting obsolete node resource slice", "slice", klog.KObj(slice)) + if err := c.kubeClient.ResourceV1alpha2().NodeResourceSlices().Delete(ctx, slice.Name, metav1.DeleteOptions{}); err != nil { + return fmt.Errorf("delete node resource slice: %w", err) + } + } + + return nil +} + +func indexOfModel(models []*resourceapi.NodeResourceModel, model *resourceapi.NodeResourceModel) int { + for index, m := range models { + if apiequality.Semantic.DeepEqual(m, model) { + return index + } + } + return -1 +} diff --git a/pkg/kubelet/cm/dra/plugin/plugin.go b/pkg/kubelet/cm/dra/plugin/plugin.go index 94a9c7354de..7acdec5f530 100644 --- a/pkg/kubelet/cm/dra/plugin/plugin.go +++ b/pkg/kubelet/cm/dra/plugin/plugin.go @@ -29,6 +29,7 @@ import ( "google.golang.org/grpc/connectivity" "google.golang.org/grpc/credentials/insecure" utilversion "k8s.io/apimachinery/pkg/util/version" + "k8s.io/client-go/kubernetes" "k8s.io/klog/v2" ) @@ -94,11 +95,23 @@ func (p *plugin) setVersion(version string) { } // RegistrationHandler is the handler which is fed to the pluginwatcher API. -type RegistrationHandler struct{} +type RegistrationHandler struct { + controller *nodeResourcesController +} // NewPluginHandler returns new registration handler. -func NewRegistrationHandler() *RegistrationHandler { - return &RegistrationHandler{} +// +// Must only be called once per process because it manages global state. +// If a kubeClient is provided, then it synchronizes NodeResourceSlices +// with the resource information provided by plugins. +func NewRegistrationHandler(kubeClient kubernetes.Interface, nodeName string) *RegistrationHandler { + handler := &RegistrationHandler{} + + // If kubelet ever gets an API for stopping registration handlers, then + // that would need to be hooked up with stopping the controller. + handler.controller = startNodeResourcesController(context.TODO(), kubeClient, nodeName) + + return handler } // RegisterPlugin is called when a plugin can be registered. @@ -110,15 +123,18 @@ func (h *RegistrationHandler) RegisterPlugin(pluginName string, endpoint string, return err } - // Storing endpoint of newly registered DRA Plugin into the map, where plugin name will be the key - // all other DRA components will be able to get the actual socket of DRA plugins by its name. - // By default we assume the supported plugin version is v1alpha3 - draPlugins.add(pluginName, &plugin{ + pluginInstance := &plugin{ conn: nil, endpoint: endpoint, version: v1alpha3Version, highestSupportedVersion: highestSupportedVersion, - }) + } + + // Storing endpoint of newly registered DRA Plugin into the map, where plugin name will be the key + // all other DRA components will be able to get the actual socket of DRA plugins by its name. + // By default we assume the supported plugin version is v1alpha3 + draPlugins.add(pluginName, pluginInstance) + h.controller.addPlugin(pluginName, pluginInstance) return nil } @@ -178,6 +194,7 @@ func deregisterPlugin(pluginName string) { func (h *RegistrationHandler) DeRegisterPlugin(pluginName string) { klog.InfoS("DeRegister DRA plugin", "name", pluginName) deregisterPlugin(pluginName) + h.controller.removePlugin(pluginName) } // ValidatePlugin is called by kubelet's plugin watcher upon detection diff --git a/pkg/kubelet/cm/dra/plugin/plugin_test.go b/pkg/kubelet/cm/dra/plugin/plugin_test.go index 70499b260c8..f9d70238f60 100644 --- a/pkg/kubelet/cm/dra/plugin/plugin_test.go +++ b/pkg/kubelet/cm/dra/plugin/plugin_test.go @@ -23,6 +23,10 @@ import ( ) func TestRegistrationHandler_ValidatePlugin(t *testing.T) { + newRegistrationHandler := func() *RegistrationHandler { + return NewRegistrationHandler(nil, "worker") + } + for _, test := range []struct { description string handler func() *RegistrationHandler @@ -33,19 +37,19 @@ func TestRegistrationHandler_ValidatePlugin(t *testing.T) { }{ { description: "no versions provided", - handler: NewRegistrationHandler, + handler: newRegistrationHandler, shouldError: true, }, { description: "unsupported version", - handler: NewRegistrationHandler, + handler: newRegistrationHandler, versions: []string{"v2.0.0"}, shouldError: true, }, { description: "plugin already registered with a higher supported version", handler: func() *RegistrationHandler { - handler := NewRegistrationHandler() + handler := newRegistrationHandler() if err := handler.RegisterPlugin("this-plugin-already-exists-and-has-a-long-name-so-it-doesnt-collide", "", []string{"v1.1.0"}); err != nil { t.Fatal(err) } @@ -57,7 +61,7 @@ func TestRegistrationHandler_ValidatePlugin(t *testing.T) { }, { description: "should validate the plugin", - handler: NewRegistrationHandler, + handler: newRegistrationHandler, pluginName: "this-is-a-dummy-plugin-with-a-long-name-so-it-doesnt-collide", versions: []string{"v1.3.0"}, }, @@ -74,7 +78,7 @@ func TestRegistrationHandler_ValidatePlugin(t *testing.T) { } t.Cleanup(func() { - handler := NewRegistrationHandler() + handler := newRegistrationHandler() handler.DeRegisterPlugin("this-plugin-already-exists-and-has-a-long-name-so-it-doesnt-collide") handler.DeRegisterPlugin("this-is-a-dummy-plugin-with-a-long-name-so-it-doesnt-collide") }) diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index 96900baaf44..b8b109df825 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -1561,7 +1561,7 @@ func (kl *Kubelet) initializeRuntimeDependentModules() { kl.pluginManager.AddHandler(pluginwatcherapi.CSIPlugin, plugincache.PluginHandler(csi.PluginHandler)) // Adding Registration Callback function for DRA Plugin if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) { - kl.pluginManager.AddHandler(pluginwatcherapi.DRAPlugin, plugincache.PluginHandler(draplugin.NewRegistrationHandler())) + kl.pluginManager.AddHandler(pluginwatcherapi.DRAPlugin, plugincache.PluginHandler(draplugin.NewRegistrationHandler(kl.kubeClient, kl.hostname))) } // Adding Registration Callback function for Device Manager kl.pluginManager.AddHandler(pluginwatcherapi.DevicePlugin, kl.containerManager.GetPluginRegistrationHandler()) diff --git a/staging/src/k8s.io/dynamic-resource-allocation/kubeletplugin/draplugin.go b/staging/src/k8s.io/dynamic-resource-allocation/kubeletplugin/draplugin.go index e3a0bafe2b8..282b407bd55 100644 --- a/staging/src/k8s.io/dynamic-resource-allocation/kubeletplugin/draplugin.go +++ b/staging/src/k8s.io/dynamic-resource-allocation/kubeletplugin/draplugin.go @@ -140,7 +140,16 @@ func KubeletPluginSocketPath(path string) Option { // may be used more than once and each interceptor will get called. func GRPCInterceptor(interceptor grpc.UnaryServerInterceptor) Option { return func(o *options) error { - o.interceptors = append(o.interceptors, interceptor) + o.unaryInterceptors = append(o.unaryInterceptors, interceptor) + return nil + } +} + +// GRPCStreamInterceptor is called for each gRPC streaming method call. This option +// may be used more than once and each interceptor will get called. +func GRPCStreamInterceptor(interceptor grpc.StreamServerInterceptor) Option { + return func(o *options) error { + o.streamInterceptors = append(o.streamInterceptors, interceptor) return nil } } @@ -170,7 +179,8 @@ type options struct { draEndpoint endpoint draAddress string pluginRegistrationEndpoint endpoint - interceptors []grpc.UnaryServerInterceptor + unaryInterceptors []grpc.UnaryServerInterceptor + streamInterceptors []grpc.StreamServerInterceptor nodeV1alpha2, nodeV1alpha3 bool } @@ -215,7 +225,7 @@ func Start(nodeServer interface{}, opts ...Option) (result DRAPlugin, finalErr e // Run the node plugin gRPC server first to ensure that it is ready. implemented := false - plugin, err := startGRPCServer(klog.LoggerWithName(o.logger, "dra"), o.grpcVerbosity, o.interceptors, o.draEndpoint, func(grpcServer *grpc.Server) { + plugin, err := startGRPCServer(klog.LoggerWithName(o.logger, "dra"), o.grpcVerbosity, o.unaryInterceptors, o.streamInterceptors, o.draEndpoint, func(grpcServer *grpc.Server) { if nodeServer, ok := nodeServer.(drapbv1alpha3.NodeServer); ok && o.nodeV1alpha3 { o.logger.V(5).Info("registering drapbv1alpha3.NodeServer") drapbv1alpha3.RegisterNodeServer(grpcServer, nodeServer) @@ -246,7 +256,7 @@ func Start(nodeServer interface{}, opts ...Option) (result DRAPlugin, finalErr e } // Now make it available to kubelet. - registrar, err := startRegistrar(klog.LoggerWithName(o.logger, "registrar"), o.grpcVerbosity, o.interceptors, o.driverName, o.draAddress, o.pluginRegistrationEndpoint) + registrar, err := startRegistrar(klog.LoggerWithName(o.logger, "registrar"), o.grpcVerbosity, o.unaryInterceptors, o.streamInterceptors, o.driverName, o.draAddress, o.pluginRegistrationEndpoint) if err != nil { return nil, fmt.Errorf("start registrar: %v", err) } diff --git a/staging/src/k8s.io/dynamic-resource-allocation/kubeletplugin/noderegistrar.go b/staging/src/k8s.io/dynamic-resource-allocation/kubeletplugin/noderegistrar.go index f5148e4c9c1..579f86245a7 100644 --- a/staging/src/k8s.io/dynamic-resource-allocation/kubeletplugin/noderegistrar.go +++ b/staging/src/k8s.io/dynamic-resource-allocation/kubeletplugin/noderegistrar.go @@ -31,7 +31,7 @@ type nodeRegistrar struct { } // startRegistrar returns a running instance. -func startRegistrar(logger klog.Logger, grpcVerbosity int, interceptors []grpc.UnaryServerInterceptor, driverName string, endpoint string, pluginRegistrationEndpoint endpoint) (*nodeRegistrar, error) { +func startRegistrar(logger klog.Logger, grpcVerbosity int, interceptors []grpc.UnaryServerInterceptor, streamInterceptors []grpc.StreamServerInterceptor, driverName string, endpoint string, pluginRegistrationEndpoint endpoint) (*nodeRegistrar, error) { n := &nodeRegistrar{ logger: logger, registrationServer: registrationServer{ @@ -40,7 +40,7 @@ func startRegistrar(logger klog.Logger, grpcVerbosity int, interceptors []grpc.U supportedVersions: []string{"1.0.0"}, // TODO: is this correct? }, } - s, err := startGRPCServer(logger, grpcVerbosity, interceptors, pluginRegistrationEndpoint, func(grpcServer *grpc.Server) { + s, err := startGRPCServer(logger, grpcVerbosity, interceptors, streamInterceptors, pluginRegistrationEndpoint, func(grpcServer *grpc.Server) { registerapi.RegisterRegistrationServer(grpcServer, n) }) if err != nil { diff --git a/staging/src/k8s.io/dynamic-resource-allocation/kubeletplugin/nonblockinggrpcserver.go b/staging/src/k8s.io/dynamic-resource-allocation/kubeletplugin/nonblockinggrpcserver.go index b840c91c7df..c2d6cf18267 100644 --- a/staging/src/k8s.io/dynamic-resource-allocation/kubeletplugin/nonblockinggrpcserver.go +++ b/staging/src/k8s.io/dynamic-resource-allocation/kubeletplugin/nonblockinggrpcserver.go @@ -54,7 +54,7 @@ type endpoint struct { // startGRPCServer sets up the GRPC server on a Unix domain socket and spawns a goroutine // which handles requests for arbitrary services. -func startGRPCServer(logger klog.Logger, grpcVerbosity int, interceptors []grpc.UnaryServerInterceptor, endpoint endpoint, services ...registerService) (*grpcServer, error) { +func startGRPCServer(logger klog.Logger, grpcVerbosity int, unaryInterceptors []grpc.UnaryServerInterceptor, streamInterceptors []grpc.StreamServerInterceptor, endpoint endpoint, services ...registerService) (*grpcServer, error) { s := &grpcServer{ logger: logger, endpoint: endpoint, @@ -79,12 +79,15 @@ func startGRPCServer(logger klog.Logger, grpcVerbosity int, interceptors []grpc. // Run a gRPC server. It will close the listening socket when // shutting down, so we don't need to do that. var opts []grpc.ServerOption - var finalInterceptors []grpc.UnaryServerInterceptor + var finalUnaryInterceptors []grpc.UnaryServerInterceptor + var finalStreamInterceptors []grpc.StreamServerInterceptor if grpcVerbosity >= 0 { - finalInterceptors = append(finalInterceptors, s.interceptor) + finalUnaryInterceptors = append(finalUnaryInterceptors, s.interceptor) } - finalInterceptors = append(finalInterceptors, interceptors...) - opts = append(opts, grpc.ChainUnaryInterceptor(finalInterceptors...)) + finalUnaryInterceptors = append(finalUnaryInterceptors, unaryInterceptors...) + finalStreamInterceptors = append(finalStreamInterceptors, streamInterceptors...) + opts = append(opts, grpc.ChainUnaryInterceptor(finalUnaryInterceptors...)) + opts = append(opts, grpc.ChainStreamInterceptor(finalStreamInterceptors...)) s.server = grpc.NewServer(opts...) for _, service := range services { service(s.server) diff --git a/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha3/api.pb.go b/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha3/api.pb.go index 3a9929690b1..50e6c93fbfe 100644 --- a/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha3/api.pb.go +++ b/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha3/api.pb.go @@ -342,6 +342,88 @@ func (m *NodeUnprepareResourceResponse) GetError() string { return "" } +type NodeListAndWatchResourcesRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *NodeListAndWatchResourcesRequest) Reset() { *m = NodeListAndWatchResourcesRequest{} } +func (*NodeListAndWatchResourcesRequest) ProtoMessage() {} +func (*NodeListAndWatchResourcesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{6} +} +func (m *NodeListAndWatchResourcesRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NodeListAndWatchResourcesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_NodeListAndWatchResourcesRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *NodeListAndWatchResourcesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_NodeListAndWatchResourcesRequest.Merge(m, src) +} +func (m *NodeListAndWatchResourcesRequest) XXX_Size() int { + return m.Size() +} +func (m *NodeListAndWatchResourcesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_NodeListAndWatchResourcesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_NodeListAndWatchResourcesRequest proto.InternalMessageInfo + +type NodeListAndWatchResourcesResponse struct { + Resources []*v1alpha2.NodeResourceModel `protobuf:"bytes,1,rep,name=resources,proto3" json:"resources,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *NodeListAndWatchResourcesResponse) Reset() { *m = NodeListAndWatchResourcesResponse{} } +func (*NodeListAndWatchResourcesResponse) ProtoMessage() {} +func (*NodeListAndWatchResourcesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{7} +} +func (m *NodeListAndWatchResourcesResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NodeListAndWatchResourcesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_NodeListAndWatchResourcesResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *NodeListAndWatchResourcesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_NodeListAndWatchResourcesResponse.Merge(m, src) +} +func (m *NodeListAndWatchResourcesResponse) XXX_Size() int { + return m.Size() +} +func (m *NodeListAndWatchResourcesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_NodeListAndWatchResourcesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_NodeListAndWatchResourcesResponse proto.InternalMessageInfo + +func (m *NodeListAndWatchResourcesResponse) GetResources() []*v1alpha2.NodeResourceModel { + if m != nil { + return m.Resources + } + return nil +} + type Claim struct { // The ResourceClaim namespace (ResourceClaim.meta.Namespace). // This field is REQUIRED. @@ -368,7 +450,7 @@ type Claim struct { func (m *Claim) Reset() { *m = Claim{} } func (*Claim) ProtoMessage() {} func (*Claim) Descriptor() ([]byte, []int) { - return fileDescriptor_00212fb1f9d3bf1c, []int{6} + return fileDescriptor_00212fb1f9d3bf1c, []int{8} } func (m *Claim) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -441,49 +523,55 @@ func init() { proto.RegisterType((*NodeUnprepareResourcesResponse)(nil), "v1alpha3.NodeUnprepareResourcesResponse") proto.RegisterMapType((map[string]*NodeUnprepareResourceResponse)(nil), "v1alpha3.NodeUnprepareResourcesResponse.ClaimsEntry") proto.RegisterType((*NodeUnprepareResourceResponse)(nil), "v1alpha3.NodeUnprepareResourceResponse") + proto.RegisterType((*NodeListAndWatchResourcesRequest)(nil), "v1alpha3.NodeListAndWatchResourcesRequest") + proto.RegisterType((*NodeListAndWatchResourcesResponse)(nil), "v1alpha3.NodeListAndWatchResourcesResponse") proto.RegisterType((*Claim)(nil), "v1alpha3.Claim") } func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) } var fileDescriptor_00212fb1f9d3bf1c = []byte{ - // 562 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0xcd, 0x6e, 0xd3, 0x40, - 0x10, 0xce, 0x36, 0x49, 0x45, 0x26, 0x52, 0x8b, 0x56, 0x15, 0xb2, 0x42, 0x31, 0x91, 0x45, 0x49, - 0x0e, 0x60, 0x0b, 0x07, 0x50, 0x05, 0xe2, 0x92, 0x16, 0x54, 0x10, 0x42, 0xc8, 0x88, 0x0b, 0x97, - 0xb0, 0xb1, 0x07, 0xc7, 0x4a, 0x62, 0x9b, 0x5d, 0x3b, 0x52, 0x6f, 0x3c, 0x02, 0x8f, 0xd5, 0x03, - 0x07, 0xc4, 0x89, 0x53, 0x45, 0xcd, 0x8d, 0xa7, 0x40, 0x5e, 0xdb, 0x69, 0x13, 0x39, 0x4d, 0xa5, - 0xde, 0x66, 0xe7, 0xef, 0x9b, 0xfd, 0xe6, 0x07, 0x1a, 0x2c, 0xf4, 0xf4, 0x90, 0x07, 0x51, 0x40, - 0x6f, 0xcc, 0x1e, 0xb1, 0x49, 0x38, 0x62, 0xbd, 0xd6, 0x43, 0xd7, 0x8b, 0x46, 0xf1, 0x50, 0xb7, - 0x83, 0xa9, 0xe1, 0x06, 0x6e, 0x60, 0x48, 0x87, 0x61, 0xfc, 0x45, 0xbe, 0xe4, 0x43, 0x4a, 0x59, - 0x60, 0xeb, 0xc1, 0x78, 0x5f, 0xe8, 0x5e, 0x60, 0xb0, 0xd0, 0x33, 0x38, 0x8a, 0x20, 0xe6, 0x36, - 0x1a, 0x79, 0x32, 0xd3, 0x70, 0xd1, 0x47, 0xce, 0x22, 0x74, 0x32, 0x6f, 0xed, 0x15, 0xdc, 0x7e, - 0x17, 0x38, 0xf8, 0x9e, 0x63, 0xc8, 0x38, 0x5a, 0xb9, 0xbf, 0xb0, 0xf0, 0x6b, 0x8c, 0x22, 0xa2, - 0x1d, 0xd8, 0xb4, 0x27, 0xcc, 0x9b, 0x0a, 0x85, 0xb4, 0xab, 0xdd, 0xa6, 0xb9, 0xad, 0x17, 0x65, - 0xe9, 0x07, 0xa9, 0xde, 0xca, 0xcd, 0xda, 0x0f, 0x02, 0xbb, 0xe5, 0x89, 0x44, 0x18, 0xf8, 0x02, - 0xe9, 0x9b, 0xa5, 0x4c, 0xe6, 0x79, 0xa6, 0xcb, 0xe2, 0x32, 0x18, 0xf1, 0xd2, 0x8f, 0xf8, 0x71, - 0x01, 0xd6, 0xfa, 0x0c, 0xcd, 0x0b, 0x6a, 0x7a, 0x13, 0xaa, 0x63, 0x3c, 0x56, 0x48, 0x9b, 0x74, - 0x1b, 0x56, 0x2a, 0xd2, 0xe7, 0x50, 0x9f, 0xb1, 0x49, 0x8c, 0xca, 0x46, 0x9b, 0x74, 0x9b, 0xe6, - 0xde, 0xa5, 0x58, 0x05, 0x94, 0x95, 0xc5, 0x3c, 0xdb, 0xd8, 0x27, 0x9a, 0x53, 0x4a, 0xcb, 0xfc, - 0x33, 0x06, 0x34, 0x6d, 0xc7, 0x1b, 0x38, 0x38, 0xf3, 0x6c, 0xcc, 0x7e, 0xd4, 0xe8, 0x6f, 0x25, - 0xa7, 0x77, 0xe1, 0xe0, 0xf0, 0xf5, 0x61, 0xa6, 0xb5, 0xc0, 0x76, 0xbc, 0x5c, 0xa6, 0x3b, 0x50, - 0x47, 0xce, 0x03, 0x2e, 0x0b, 0x6a, 0x58, 0xd9, 0x43, 0x3b, 0x82, 0x3b, 0x29, 0xca, 0x47, 0x3f, - 0xbc, 0x2e, 0xfd, 0xbf, 0x08, 0xa8, 0xab, 0x52, 0xe5, 0x35, 0xbf, 0x5d, 0xca, 0xf5, 0x78, 0x91, - 0x94, 0xd5, 0x91, 0xa5, 0x2d, 0x18, 0xae, 0x6b, 0xc1, 0x8b, 0xc5, 0x16, 0x74, 0xd6, 0xa0, 0x95, - 0x35, 0xe1, 0xc9, 0x0a, 0x7a, 0xe6, 0x5f, 0x9a, 0xb3, 0x4a, 0x2e, 0xb2, 0xfa, 0x8f, 0x40, 0x5d, - 0xd6, 0x46, 0x77, 0xa1, 0xe1, 0xb3, 0x29, 0x8a, 0x90, 0xd9, 0x98, 0xfb, 0x9c, 0x2b, 0xd2, 0x9a, - 0x63, 0xcf, 0xc9, 0x3b, 0x92, 0x8a, 0x94, 0x42, 0x2d, 0x35, 0x2b, 0x55, 0xa9, 0x92, 0x32, 0xed, - 0xc0, 0x76, 0xb1, 0x45, 0x83, 0x11, 0xf3, 0x9d, 0x09, 0x2a, 0x35, 0x69, 0xde, 0x2a, 0xd4, 0x47, - 0x52, 0x4b, 0x23, 0x68, 0x89, 0x88, 0xc7, 0x76, 0x14, 0x73, 0x74, 0x06, 0xcb, 0x31, 0x75, 0xc9, - 0xf9, 0x53, 0x3d, 0x5b, 0x4e, 0x3d, 0xdd, 0xf3, 0xc2, 0xa5, 0x60, 0xc6, 0xd4, 0x3f, 0xcc, 0xe3, - 0xad, 0x85, 0xdc, 0x96, 0x22, 0x56, 0x58, 0xcc, 0x53, 0x02, 0xb5, 0x94, 0x24, 0xea, 0xc2, 0x4e, - 0xd9, 0x1e, 0xd1, 0xbd, 0x75, 0x7b, 0x26, 0x27, 0xad, 0x75, 0xff, 0x6a, 0xeb, 0xa8, 0x55, 0xe8, - 0x14, 0x6e, 0x95, 0xcf, 0x0b, 0xed, 0xac, 0x9f, 0xa8, 0x0c, 0xac, 0x7b, 0xd5, 0xd1, 0xd3, 0x2a, - 0xfd, 0xfe, 0xc9, 0x99, 0x4a, 0x7e, 0x9f, 0xa9, 0x95, 0x6f, 0x89, 0x4a, 0x4e, 0x12, 0x95, 0xfc, - 0x4c, 0x54, 0xf2, 0x27, 0x51, 0xc9, 0xf7, 0xbf, 0x6a, 0xe5, 0xd3, 0xbd, 0xfc, 0xd8, 0x8d, 0xe3, - 0x21, 0x4e, 0x30, 0x32, 0xc2, 0xb1, 0x9b, 0x1e, 0x3e, 0x61, 0x38, 0x9c, 0x15, 0x47, 0xaf, 0x37, - 0xdc, 0x94, 0xb7, 0xae, 0xf7, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x14, 0x30, 0xd4, 0x5f, 0x05, - 0x00, 0x00, + // 631 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0xcd, 0x6e, 0xd3, 0x40, + 0x10, 0xce, 0xb6, 0x4d, 0x45, 0x26, 0x52, 0x8b, 0x56, 0x15, 0x0a, 0xa6, 0x98, 0x60, 0x51, 0x12, + 0xf1, 0x63, 0x83, 0x0b, 0xa8, 0x02, 0x71, 0xa0, 0x2d, 0xa8, 0xa0, 0x16, 0x21, 0x23, 0x84, 0xc4, + 0xa5, 0x6c, 0xbc, 0x8b, 0x63, 0xc5, 0xb1, 0xcd, 0xae, 0x5d, 0xd1, 0x1b, 0x8f, 0xc0, 0x63, 0xf5, + 0xc0, 0x01, 0x71, 0xea, 0x09, 0xd1, 0x70, 0xe3, 0x29, 0x90, 0xd7, 0xde, 0xb4, 0x89, 0x9c, 0xa4, + 0x12, 0xb7, 0xd9, 0xf9, 0xf9, 0x66, 0xe7, 0x9b, 0x99, 0x5d, 0xa8, 0x91, 0xd8, 0x37, 0x63, 0x1e, + 0x25, 0x11, 0xbe, 0x70, 0x70, 0x9f, 0x04, 0x71, 0x97, 0xac, 0x6b, 0x77, 0x3d, 0x3f, 0xe9, 0xa6, + 0x1d, 0xd3, 0x8d, 0xfa, 0x96, 0x17, 0x79, 0x91, 0x25, 0x1d, 0x3a, 0xe9, 0x27, 0x79, 0x92, 0x07, + 0x29, 0xe5, 0x81, 0xda, 0x9d, 0xde, 0x86, 0x30, 0xfd, 0xc8, 0x22, 0xb1, 0x6f, 0x71, 0x26, 0xa2, + 0x94, 0xbb, 0xcc, 0x2a, 0xc0, 0x6c, 0xcb, 0x63, 0x21, 0xe3, 0x24, 0x61, 0x34, 0xf7, 0x36, 0x5e, + 0xc0, 0x95, 0xd7, 0x11, 0x65, 0x6f, 0x38, 0x8b, 0x09, 0x67, 0x4e, 0xe1, 0x2f, 0x1c, 0xf6, 0x39, + 0x65, 0x22, 0xc1, 0x2d, 0x58, 0x74, 0x03, 0xe2, 0xf7, 0x45, 0x03, 0x35, 0xe7, 0xdb, 0x75, 0x7b, + 0xd9, 0x54, 0xd7, 0x32, 0xb7, 0x32, 0xbd, 0x53, 0x98, 0x8d, 0xef, 0x08, 0x56, 0xcb, 0x81, 0x44, + 0x1c, 0x85, 0x82, 0xe1, 0x57, 0x63, 0x48, 0xf6, 0x29, 0xd2, 0xb4, 0xb8, 0x3c, 0x8d, 0x78, 0x1e, + 0x26, 0xfc, 0x50, 0x25, 0xd3, 0x3e, 0x42, 0xfd, 0x8c, 0x1a, 0x5f, 0x84, 0xf9, 0x1e, 0x3b, 0x6c, + 0xa0, 0x26, 0x6a, 0xd7, 0x9c, 0x4c, 0xc4, 0x4f, 0xa0, 0x7a, 0x40, 0x82, 0x94, 0x35, 0xe6, 0x9a, + 0xa8, 0x5d, 0xb7, 0xd7, 0xa6, 0xe6, 0x52, 0xa9, 0x9c, 0x3c, 0xe6, 0xf1, 0xdc, 0x06, 0x32, 0x68, + 0x29, 0x2d, 0xc3, 0x62, 0x2c, 0xa8, 0xbb, 0xd4, 0xdf, 0xa7, 0xec, 0xc0, 0x77, 0x59, 0x5e, 0x51, + 0x6d, 0x73, 0x69, 0xf0, 0xeb, 0x1a, 0x6c, 0x6d, 0xbf, 0xdc, 0xce, 0xb5, 0x0e, 0xb8, 0xd4, 0x2f, + 0x64, 0xbc, 0x02, 0x55, 0xc6, 0x79, 0xc4, 0xe5, 0x85, 0x6a, 0x4e, 0x7e, 0x30, 0x76, 0xe0, 0x6a, + 0x96, 0xe5, 0x5d, 0x18, 0xff, 0x2f, 0xfd, 0x3f, 0x11, 0xe8, 0x93, 0xa0, 0x8a, 0x3b, 0xef, 0x8e, + 0x61, 0x3d, 0x18, 0x25, 0x65, 0x72, 0x64, 0x69, 0x0b, 0x3a, 0xb3, 0x5a, 0xf0, 0x74, 0xb4, 0x05, + 0xad, 0x19, 0xd9, 0xca, 0x9a, 0xf0, 0x70, 0x02, 0x3d, 0xc3, 0x92, 0x86, 0xac, 0xa2, 0xb3, 0xac, + 0x1a, 0xd0, 0xcc, 0xc2, 0x76, 0x7d, 0x91, 0x3c, 0x0b, 0xe9, 0x7b, 0x92, 0xb8, 0xdd, 0x71, 0x62, + 0x0d, 0x0e, 0xd7, 0xa7, 0xf8, 0x14, 0xf0, 0x7b, 0x50, 0x53, 0x0b, 0xa4, 0x48, 0xb3, 0xcc, 0x7c, + 0xbb, 0xcc, 0x6c, 0x51, 0x95, 0x51, 0x95, 0x66, 0xcb, 0xd2, 0x14, 0xce, 0x5e, 0x44, 0x59, 0xe0, + 0x9c, 0x22, 0x18, 0x7f, 0x11, 0x54, 0x25, 0x67, 0x78, 0x15, 0x6a, 0x21, 0xe9, 0x33, 0x11, 0x13, + 0x97, 0x15, 0x77, 0x3f, 0x55, 0x64, 0x5c, 0xa6, 0x3e, 0x2d, 0x26, 0x25, 0x13, 0x31, 0x86, 0x85, + 0xcc, 0xdc, 0x98, 0x97, 0x2a, 0x29, 0xe3, 0x16, 0x2c, 0x2b, 0xe8, 0xfd, 0x2e, 0x09, 0x69, 0xc0, + 0x1a, 0x0b, 0xd2, 0xbc, 0xa4, 0xd4, 0x3b, 0x52, 0x8b, 0x13, 0xd0, 0x44, 0xc2, 0x53, 0x37, 0x49, + 0x39, 0xa3, 0xfb, 0xe3, 0x31, 0x55, 0x59, 0xd6, 0xa3, 0xe9, 0x65, 0xbd, 0x1d, 0xc6, 0x3b, 0x23, + 0xd8, 0x4e, 0x43, 0x4c, 0xb0, 0xd8, 0xc7, 0x73, 0xb0, 0x90, 0xb1, 0x81, 0x3d, 0x58, 0x29, 0xdb, + 0x6f, 0xbc, 0x36, 0x6b, 0xff, 0x65, 0xa3, 0xb4, 0x9b, 0xe7, 0x7b, 0x26, 0x8c, 0x0a, 0xee, 0xc3, + 0xa5, 0xf2, 0x39, 0xc6, 0xad, 0xd9, 0x93, 0x9e, 0x27, 0x6b, 0x9f, 0x77, 0x25, 0x8c, 0x0a, 0xfe, + 0x02, 0x97, 0x27, 0x4e, 0x10, 0xbe, 0x35, 0x0a, 0x34, 0x6d, 0x14, 0xb5, 0xdb, 0xe7, 0xf2, 0x55, + 0x79, 0xef, 0xa1, 0xcd, 0xcd, 0xa3, 0x13, 0x1d, 0x1d, 0x9f, 0xe8, 0x95, 0xaf, 0x03, 0x1d, 0x1d, + 0x0d, 0x74, 0xf4, 0x63, 0xa0, 0xa3, 0xdf, 0x03, 0x1d, 0x7d, 0xfb, 0xa3, 0x57, 0x3e, 0xdc, 0x28, + 0x9e, 0xff, 0x5e, 0xda, 0x61, 0x01, 0x4b, 0xac, 0xb8, 0xe7, 0x65, 0x5f, 0x81, 0xb0, 0x28, 0x27, + 0xea, 0x1b, 0x58, 0xef, 0x2c, 0xca, 0xd7, 0x7f, 0xfd, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x20, + 0x6d, 0x9d, 0x90, 0x71, 0x06, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -506,6 +594,10 @@ type NodeClient interface { // NodeUnprepareResources is the opposite of NodePrepareResources. // The same error handling rules apply, NodeUnprepareResources(ctx context.Context, in *NodeUnprepareResourcesRequest, opts ...grpc.CallOption) (*NodeUnprepareResourcesResponse, error) + // NodeListAndWatchResources returns a stream of NodeResourcesResponse objects. + // At the start and whenever resource availability changes, the + // plugin must send one such object with all information to the Kubelet. + NodeListAndWatchResources(ctx context.Context, in *NodeListAndWatchResourcesRequest, opts ...grpc.CallOption) (Node_NodeListAndWatchResourcesClient, error) } type nodeClient struct { @@ -534,6 +626,38 @@ func (c *nodeClient) NodeUnprepareResources(ctx context.Context, in *NodeUnprepa return out, nil } +func (c *nodeClient) NodeListAndWatchResources(ctx context.Context, in *NodeListAndWatchResourcesRequest, opts ...grpc.CallOption) (Node_NodeListAndWatchResourcesClient, error) { + stream, err := c.cc.NewStream(ctx, &_Node_serviceDesc.Streams[0], "/v1alpha3.Node/NodeListAndWatchResources", opts...) + if err != nil { + return nil, err + } + x := &nodeNodeListAndWatchResourcesClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Node_NodeListAndWatchResourcesClient interface { + Recv() (*NodeListAndWatchResourcesResponse, error) + grpc.ClientStream +} + +type nodeNodeListAndWatchResourcesClient struct { + grpc.ClientStream +} + +func (x *nodeNodeListAndWatchResourcesClient) Recv() (*NodeListAndWatchResourcesResponse, error) { + m := new(NodeListAndWatchResourcesResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + // NodeServer is the server API for Node service. type NodeServer interface { // NodePrepareResources prepares several ResourceClaims @@ -544,6 +668,10 @@ type NodeServer interface { // NodeUnprepareResources is the opposite of NodePrepareResources. // The same error handling rules apply, NodeUnprepareResources(context.Context, *NodeUnprepareResourcesRequest) (*NodeUnprepareResourcesResponse, error) + // NodeListAndWatchResources returns a stream of NodeResourcesResponse objects. + // At the start and whenever resource availability changes, the + // plugin must send one such object with all information to the Kubelet. + NodeListAndWatchResources(*NodeListAndWatchResourcesRequest, Node_NodeListAndWatchResourcesServer) error } // UnimplementedNodeServer can be embedded to have forward compatible implementations. @@ -556,6 +684,9 @@ func (*UnimplementedNodeServer) NodePrepareResources(ctx context.Context, req *N func (*UnimplementedNodeServer) NodeUnprepareResources(ctx context.Context, req *NodeUnprepareResourcesRequest) (*NodeUnprepareResourcesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method NodeUnprepareResources not implemented") } +func (*UnimplementedNodeServer) NodeListAndWatchResources(req *NodeListAndWatchResourcesRequest, srv Node_NodeListAndWatchResourcesServer) error { + return status.Errorf(codes.Unimplemented, "method NodeListAndWatchResources not implemented") +} func RegisterNodeServer(s *grpc.Server, srv NodeServer) { s.RegisterService(&_Node_serviceDesc, srv) @@ -597,6 +728,27 @@ func _Node_NodeUnprepareResources_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } +func _Node_NodeListAndWatchResources_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(NodeListAndWatchResourcesRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(NodeServer).NodeListAndWatchResources(m, &nodeNodeListAndWatchResourcesServer{stream}) +} + +type Node_NodeListAndWatchResourcesServer interface { + Send(*NodeListAndWatchResourcesResponse) error + grpc.ServerStream +} + +type nodeNodeListAndWatchResourcesServer struct { + grpc.ServerStream +} + +func (x *nodeNodeListAndWatchResourcesServer) Send(m *NodeListAndWatchResourcesResponse) error { + return x.ServerStream.SendMsg(m) +} + var _Node_serviceDesc = grpc.ServiceDesc{ ServiceName: "v1alpha3.Node", HandlerType: (*NodeServer)(nil), @@ -610,7 +762,13 @@ var _Node_serviceDesc = grpc.ServiceDesc{ Handler: _Node_NodeUnprepareResources_Handler, }, }, - Streams: []grpc.StreamDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "NodeListAndWatchResources", + Handler: _Node_NodeListAndWatchResources_Handler, + ServerStreams: true, + }, + }, Metadata: "api.proto", } @@ -855,6 +1013,66 @@ func (m *NodeUnprepareResourceResponse) MarshalToSizedBuffer(dAtA []byte) (int, return len(dAtA) - i, nil } +func (m *NodeListAndWatchResourcesRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NodeListAndWatchResourcesRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NodeListAndWatchResourcesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *NodeListAndWatchResourcesResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NodeListAndWatchResourcesResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NodeListAndWatchResourcesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Resources) > 0 { + for iNdEx := len(m.Resources) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Resources[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintApi(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func (m *Claim) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1037,6 +1255,30 @@ func (m *NodeUnprepareResourceResponse) Size() (n int) { return n } +func (m *NodeListAndWatchResourcesRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *NodeListAndWatchResourcesResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Resources) > 0 { + for _, e := range m.Resources { + l = e.Size() + n += 1 + l + sovApi(uint64(l)) + } + } + return n +} + func (m *Claim) Size() (n int) { if m == nil { return 0 @@ -1165,6 +1407,30 @@ func (this *NodeUnprepareResourceResponse) String() string { }, "") return s } +func (this *NodeListAndWatchResourcesRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NodeListAndWatchResourcesRequest{`, + `}`, + }, "") + return s +} +func (this *NodeListAndWatchResourcesResponse) String() string { + if this == nil { + return "nil" + } + repeatedStringForResources := "[]*NodeResourceModel{" + for _, f := range this.Resources { + repeatedStringForResources += strings.Replace(fmt.Sprintf("%v", f), "NodeResourceModel", "v1alpha2.NodeResourceModel", 1) + "," + } + repeatedStringForResources += "}" + s := strings.Join([]string{`&NodeListAndWatchResourcesResponse{`, + `Resources:` + repeatedStringForResources + `,`, + `}`, + }, "") + return s +} func (this *Claim) String() string { if this == nil { return "nil" @@ -1914,6 +2180,140 @@ func (m *NodeUnprepareResourceResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *NodeListAndWatchResourcesRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NodeListAndWatchResourcesRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NodeListAndWatchResourcesRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipApi(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthApi + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NodeListAndWatchResourcesResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NodeListAndWatchResourcesResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NodeListAndWatchResourcesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthApi + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthApi + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Resources = append(m.Resources, &v1alpha2.NodeResourceModel{}) + if err := m.Resources[len(m.Resources)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipApi(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthApi + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Claim) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha3/api.proto b/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha3/api.proto index e3ca0238249..6994aa25184 100644 --- a/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha3/api.proto +++ b/staging/src/k8s.io/kubelet/pkg/apis/dra/v1alpha3/api.proto @@ -44,6 +44,12 @@ service Node { // The same error handling rules apply, rpc NodeUnprepareResources (NodeUnprepareResourcesRequest) returns (NodeUnprepareResourcesResponse) {} + + // NodeListAndWatchResources returns a stream of NodeResourcesResponse objects. + // At the start and whenever resource availability changes, the + // plugin must send one such object with all information to the Kubelet. + rpc NodeListAndWatchResources(NodeListAndWatchResourcesRequest) + returns (stream NodeListAndWatchResourcesResponse) {} } message NodePrepareResourcesRequest { @@ -88,6 +94,13 @@ message NodeUnprepareResourceResponse { string error = 1; } +message NodeListAndWatchResourcesRequest { +} + +message NodeListAndWatchResourcesResponse { + repeated k8s.io.api.resource.v1alpha2.NodeResourceModel resources = 1; +} + message Claim { // The ResourceClaim namespace (ResourceClaim.meta.Namespace). // This field is REQUIRED. diff --git a/test/e2e/dra/deploy.go b/test/e2e/dra/deploy.go index 8f5bacb854e..3864fe0f854 100644 --- a/test/e2e/dra/deploy.go +++ b/test/e2e/dra/deploy.go @@ -34,6 +34,7 @@ import ( appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -50,10 +51,11 @@ import ( ) const ( - NodePrepareResourceMethod = "/v1alpha2.Node/NodePrepareResource" - NodePrepareResourcesMethod = "/v1alpha3.Node/NodePrepareResources" - NodeUnprepareResourceMethod = "/v1alpha2.Node/NodeUnprepareResource" - NodeUnprepareResourcesMethod = "/v1alpha3.Node/NodeUnprepareResources" + NodePrepareResourceMethod = "/v1alpha2.Node/NodePrepareResource" + NodePrepareResourcesMethod = "/v1alpha3.Node/NodePrepareResources" + NodeUnprepareResourceMethod = "/v1alpha2.Node/NodeUnprepareResource" + NodeUnprepareResourcesMethod = "/v1alpha3.Node/NodeUnprepareResources" + NodeListAndWatchResourcesMethod = "/v1alpha3.Node/NodeListAndWatchResources" ) type Nodes struct { @@ -105,6 +107,7 @@ func NewDriver(f *framework.Framework, nodes *Nodes, configureResources func() a // not run on all nodes. resources.Nodes = nodes.NodeNames } + ginkgo.DeferCleanup(d.IsGone) // Register first so it gets called last. d.SetUp(nodes, resources) ginkgo.DeferCleanup(d.TearDown) }) @@ -182,6 +185,10 @@ func (d *Driver) SetUp(nodes *Nodes, resources app.Resources) { if d.parameterMode == "" { d.parameterMode = parameterModeConfigMap } + var numResourceInstances = -1 // disabled + if d.parameterMode != parameterModeConfigMap { + numResourceInstances = resources.MaxAllocations + } switch d.parameterMode { case parameterModeConfigMap, parameterModeTranslated: d.parameterAPIGroup = "" @@ -259,7 +266,8 @@ func (d *Driver) SetUp(nodes *Nodes, resources app.Resources) { pod := pod nodename := pod.Spec.NodeName logger := klog.LoggerWithValues(klog.LoggerWithName(klog.Background(), "kubelet plugin"), "node", pod.Spec.NodeName, "pod", klog.KObj(&pod)) - plugin, err := app.StartPlugin(logger, "/cdi", d.Name, nodename, + loggerCtx := klog.NewContext(ctx, logger) + plugin, err := app.StartPlugin(loggerCtx, "/cdi", d.Name, nodename, app.FileOperations{ Create: func(name string, content []byte) error { klog.Background().Info("creating CDI file", "node", nodename, "filename", name, "content", string(content)) @@ -269,11 +277,15 @@ func (d *Driver) SetUp(nodes *Nodes, resources app.Resources) { klog.Background().Info("deleting CDI file", "node", nodename, "filename", name) return d.removeFile(&pod, name) }, + NumResourceInstances: numResourceInstances, }, kubeletplugin.GRPCVerbosity(0), kubeletplugin.GRPCInterceptor(func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { return d.interceptor(nodename, ctx, req, info, handler) }), + kubeletplugin.GRPCStreamInterceptor(func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) (err error) { + return d.streamInterceptor(nodename, srv, ss, info, handler) + }), kubeletplugin.PluginListener(listen(ctx, d.f, pod.Name, "plugin", 9001)), kubeletplugin.RegistrarListener(listen(ctx, d.f, pod.Name, "registrar", 9000)), kubeletplugin.KubeletPluginSocketPath(draAddr), @@ -349,6 +361,16 @@ func (d *Driver) TearDown() { d.wg.Wait() } +func (d *Driver) IsGone(ctx context.Context) { + gomega.Eventually(ctx, func(ctx context.Context) ([]resourcev1alpha2.NodeResourceSlice, error) { + slices, err := d.f.ClientSet.ResourceV1alpha2().NodeResourceSlices().List(ctx, metav1.ListOptions{FieldSelector: "driverName=" + d.Name}) + if err != nil { + return nil, err + } + return slices.Items, err + }).Should(gomega.BeEmpty()) +} + func (d *Driver) interceptor(nodename string, ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { d.mutex.Lock() defer d.mutex.Unlock() @@ -362,6 +384,22 @@ func (d *Driver) interceptor(nodename string, ctx context.Context, req interface return handler(ctx, req) } +func (d *Driver) streamInterceptor(nodename string, srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + // Stream calls block for a long time. We must not hold the lock while + // they are running. + d.mutex.Lock() + m := MethodInstance{nodename, info.FullMethod} + d.callCounts[m]++ + fail := d.fail[m] + d.mutex.Unlock() + + if fail { + return errors.New("injected error") + } + + return handler(srv, stream) +} + func (d *Driver) Fail(m MethodInstance, injectError bool) { d.mutex.Lock() defer d.mutex.Unlock() diff --git a/test/e2e/dra/dra.go b/test/e2e/dra/dra.go index 7e71eb90847..f97aee67af3 100644 --- a/test/e2e/dra/dra.go +++ b/test/e2e/dra/dra.go @@ -28,6 +28,7 @@ import ( "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" "github.com/onsi/gomega/gcustom" + "github.com/onsi/gomega/gstruct" v1 "k8s.io/api/core/v1" resourcev1alpha2 "k8s.io/api/resource/v1alpha2" @@ -82,116 +83,167 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, ginkgo.Context("kubelet", func() { nodes := NewNodes(f, 1, 1) - driver := NewDriver(f, nodes, networkResources) // All tests get their own driver instance. - b := newBuilder(f, driver) - ginkgo.It("registers plugin", func() { - ginkgo.By("the driver is running") - }) + ginkgo.Context("with ConfigMap parameters", func() { + driver := NewDriver(f, nodes, networkResources) + b := newBuilder(f, driver) - ginkgo.It("must retry NodePrepareResources", func(ctx context.Context) { - // We have exactly one host. - m := MethodInstance{driver.Nodenames()[0], NodePrepareResourcesMethod} - - driver.Fail(m, true) - - ginkgo.By("waiting for container startup to fail") - parameters := b.parameters() - pod, template := b.podInline(resourcev1alpha2.AllocationModeWaitForFirstConsumer) - - b.create(ctx, parameters, pod, template) - - ginkgo.By("wait for NodePrepareResources call") - gomega.Eventually(ctx, func(ctx context.Context) error { - if driver.CallCount(m) == 0 { - return errors.New("NodePrepareResources not called yet") - } - return nil - }).WithTimeout(podStartTimeout).Should(gomega.Succeed()) - - ginkgo.By("allowing container startup to succeed") - callCount := driver.CallCount(m) - driver.Fail(m, false) - err := e2epod.WaitForPodNameRunningInNamespace(ctx, f.ClientSet, pod.Name, pod.Namespace) - framework.ExpectNoError(err, "start pod with inline resource claim") - if driver.CallCount(m) == callCount { - framework.Fail("NodePrepareResources should have been called again") - } - }) - - ginkgo.It("must not run a pod if a claim is not reserved for it", func(ctx context.Context) { - // Pretend that the resource is allocated and reserved for some other entity. - // Until the resourceclaim controller learns to remove reservations for - // arbitrary types we can simply fake somthing here. - claim := b.externalClaim(resourcev1alpha2.AllocationModeWaitForFirstConsumer) - b.create(ctx, claim) - claim, err := f.ClientSet.ResourceV1alpha2().ResourceClaims(f.Namespace.Name).Get(ctx, claim.Name, metav1.GetOptions{}) - framework.ExpectNoError(err, "get claim") - claim.Status.Allocation = &resourcev1alpha2.AllocationResult{} - claim.Status.DriverName = driver.Name - claim.Status.ReservedFor = append(claim.Status.ReservedFor, resourcev1alpha2.ResourceClaimConsumerReference{ - APIGroup: "example.com", - Resource: "some", - Name: "thing", - UID: "12345", + ginkgo.It("registers plugin", func() { + ginkgo.By("the driver is running") }) - _, err = f.ClientSet.ResourceV1alpha2().ResourceClaims(f.Namespace.Name).UpdateStatus(ctx, claim, metav1.UpdateOptions{}) - framework.ExpectNoError(err, "update claim") - pod := b.podExternal() + ginkgo.It("must retry NodePrepareResources", func(ctx context.Context) { + // We have exactly one host. + m := MethodInstance{driver.Nodenames()[0], NodePrepareResourcesMethod} - // This bypasses scheduling and therefore the pod gets - // to run on the node although it never gets added to - // the `ReservedFor` field of the claim. - pod.Spec.NodeName = nodes.NodeNames[0] - b.create(ctx, pod) + driver.Fail(m, true) - gomega.Consistently(ctx, func(ctx context.Context) error { - testPod, err := b.f.ClientSet.CoreV1().Pods(pod.Namespace).Get(ctx, pod.Name, metav1.GetOptions{}) - if err != nil { - return fmt.Errorf("expected the test pod %s to exist: %w", pod.Name, err) + ginkgo.By("waiting for container startup to fail") + parameters := b.parameters() + pod, template := b.podInline(resourcev1alpha2.AllocationModeWaitForFirstConsumer) + + b.create(ctx, parameters, pod, template) + + ginkgo.By("wait for NodePrepareResources call") + gomega.Eventually(ctx, func(ctx context.Context) error { + if driver.CallCount(m) == 0 { + return errors.New("NodePrepareResources not called yet") + } + return nil + }).WithTimeout(podStartTimeout).Should(gomega.Succeed()) + + ginkgo.By("allowing container startup to succeed") + callCount := driver.CallCount(m) + driver.Fail(m, false) + err := e2epod.WaitForPodNameRunningInNamespace(ctx, f.ClientSet, pod.Name, pod.Namespace) + framework.ExpectNoError(err, "start pod with inline resource claim") + if driver.CallCount(m) == callCount { + framework.Fail("NodePrepareResources should have been called again") } - if testPod.Status.Phase != v1.PodPending { - return fmt.Errorf("pod %s: unexpected status %s, expected status: %s", pod.Name, testPod.Status.Phase, v1.PodPending) + }) + + ginkgo.It("must not run a pod if a claim is not reserved for it", func(ctx context.Context) { + // Pretend that the resource is allocated and reserved for some other entity. + // Until the resourceclaim controller learns to remove reservations for + // arbitrary types we can simply fake somthing here. + claim := b.externalClaim(resourcev1alpha2.AllocationModeWaitForFirstConsumer) + b.create(ctx, claim) + claim, err := f.ClientSet.ResourceV1alpha2().ResourceClaims(f.Namespace.Name).Get(ctx, claim.Name, metav1.GetOptions{}) + framework.ExpectNoError(err, "get claim") + claim.Status.Allocation = &resourcev1alpha2.AllocationResult{} + claim.Status.DriverName = driver.Name + claim.Status.ReservedFor = append(claim.Status.ReservedFor, resourcev1alpha2.ResourceClaimConsumerReference{ + APIGroup: "example.com", + Resource: "some", + Name: "thing", + UID: "12345", + }) + _, err = f.ClientSet.ResourceV1alpha2().ResourceClaims(f.Namespace.Name).UpdateStatus(ctx, claim, metav1.UpdateOptions{}) + framework.ExpectNoError(err, "update claim") + + pod := b.podExternal() + + // This bypasses scheduling and therefore the pod gets + // to run on the node although it never gets added to + // the `ReservedFor` field of the claim. + pod.Spec.NodeName = nodes.NodeNames[0] + b.create(ctx, pod) + + gomega.Consistently(ctx, func(ctx context.Context) error { + testPod, err := b.f.ClientSet.CoreV1().Pods(pod.Namespace).Get(ctx, pod.Name, metav1.GetOptions{}) + if err != nil { + return fmt.Errorf("expected the test pod %s to exist: %w", pod.Name, err) + } + if testPod.Status.Phase != v1.PodPending { + return fmt.Errorf("pod %s: unexpected status %s, expected status: %s", pod.Name, testPod.Status.Phase, v1.PodPending) + } + return nil + }, 20*time.Second, 200*time.Millisecond).Should(gomega.BeNil()) + }) + + ginkgo.It("must unprepare resources for force-deleted pod", func(ctx context.Context) { + parameters := b.parameters() + claim := b.externalClaim(resourcev1alpha2.AllocationModeImmediate) + pod := b.podExternal() + zero := int64(0) + pod.Spec.TerminationGracePeriodSeconds = &zero + + b.create(ctx, parameters, claim, pod) + + b.testPod(ctx, f.ClientSet, pod) + + ginkgo.By(fmt.Sprintf("force delete test pod %s", pod.Name)) + err := b.f.ClientSet.CoreV1().Pods(b.f.Namespace.Name).Delete(ctx, pod.Name, metav1.DeleteOptions{GracePeriodSeconds: &zero}) + if !apierrors.IsNotFound(err) { + framework.ExpectNoError(err, "force delete test pod") } - return nil - }, 20*time.Second, 200*time.Millisecond).Should(gomega.BeNil()) + + for host, plugin := range b.driver.Nodes { + ginkgo.By(fmt.Sprintf("waiting for resources on %s to be unprepared", host)) + gomega.Eventually(plugin.GetPreparedResources).WithTimeout(time.Minute).Should(gomega.BeEmpty(), "prepared claims on host %s", host) + } + }) + + ginkgo.It("must skip NodePrepareResource if not used by any container", func(ctx context.Context) { + parameters := b.parameters() + pod, template := b.podInline(resourcev1alpha2.AllocationModeWaitForFirstConsumer) + for i := range pod.Spec.Containers { + pod.Spec.Containers[i].Resources.Claims = nil + } + b.create(ctx, parameters, pod, template) + framework.ExpectNoError(e2epod.WaitForPodRunningInNamespace(ctx, f.ClientSet, pod), "start pod") + for host, plugin := range b.driver.Nodes { + gomega.Expect(plugin.GetPreparedResources()).Should(gomega.BeEmpty(), "not claims should be prepared on host %s while pod is running", host) + } + }) + }) - ginkgo.It("must unprepare resources for force-deleted pod", func(ctx context.Context) { - parameters := b.parameters() - claim := b.externalClaim(resourcev1alpha2.AllocationModeImmediate) - pod := b.podExternal() - zero := int64(0) - pod.Spec.TerminationGracePeriodSeconds = &zero + ginkgo.Context("with structured parameters", func() { + driver := NewDriver(f, nodes, perNode(1, nodes)) + driver.parameterMode = parameterModeStructured - b.create(ctx, parameters, claim, pod) + f.It("must manage NodeResourceSlice", f.WithSlow(), func(ctx context.Context) { + nodeName := nodes.NodeNames[0] + driverName := driver.Name + m := MethodInstance{nodeName, NodeListAndWatchResourcesMethod} + ginkgo.By("wait for NodeListAndWatchResources call") + gomega.Eventually(ctx, func() int64 { + return driver.CallCount(m) + }).WithTimeout(podStartTimeout).Should(gomega.BeNumerically(">", int64(0)), "NodeListAndWatchResources call count") - b.testPod(ctx, f.ClientSet, pod) + ginkgo.By("check if NodeResourceSlice object exists on the API server") + resourceClient := f.ClientSet.ResourceV1alpha2().NodeResourceSlices() + matchSlices := gomega.And( + gomega.HaveLen(1), + gomega.ContainElement(gstruct.MatchAllFields(gstruct.Fields{ + "TypeMeta": gstruct.Ignore(), + "ObjectMeta": gstruct.Ignore(), // TODO: validate ownerref + "NodeName": gomega.Equal(nodes.NodeNames[0]), + "DriverName": gomega.Equal(driver.Name), + "NodeResourceModel": gomega.Equal(resourcev1alpha2.NodeResourceModel{NamedResources: &resourcev1alpha2.NamedResourcesResources{ + Instances: []resourcev1alpha2.NamedResourcesInstance{{Name: "instance-0"}}, + }}), + })), + ) + getSlices := func(ctx context.Context) ([]resourcev1alpha2.NodeResourceSlice, error) { + slices, err := resourceClient.List(ctx, metav1.ListOptions{FieldSelector: fmt.Sprintf("nodeName=%s,driverName=%s", nodeName, driverName)}) + if err != nil { + return nil, err + } + return slices.Items, nil + } + gomega.Eventually(ctx, getSlices).WithTimeout(20 * time.Second).Should(matchSlices) + gomega.Consistently(ctx, getSlices).WithTimeout(20 * time.Second).Should(matchSlices) - ginkgo.By(fmt.Sprintf("force delete test pod %s", pod.Name)) - err := b.f.ClientSet.CoreV1().Pods(b.f.Namespace.Name).Delete(ctx, pod.Name, metav1.DeleteOptions{GracePeriodSeconds: &zero}) - if !apierrors.IsNotFound(err) { - framework.ExpectNoError(err, "force delete test pod") - } + // Removal of node resource slice is tested by the general driver removal code. + }) - for host, plugin := range b.driver.Nodes { - ginkgo.By(fmt.Sprintf("waiting for resources on %s to be unprepared", host)) - gomega.Eventually(plugin.GetPreparedResources).WithTimeout(time.Minute).Should(gomega.BeEmpty(), "prepared claims on host %s", host) - } - }) - - ginkgo.It("must skip NodePrepareResource if not used by any container", func(ctx context.Context) { - parameters := b.parameters() - pod, template := b.podInline(resourcev1alpha2.AllocationModeWaitForFirstConsumer) - for i := range pod.Spec.Containers { - pod.Spec.Containers[i].Resources.Claims = nil - } - b.create(ctx, parameters, pod, template) - framework.ExpectNoError(e2epod.WaitForPodRunningInNamespace(ctx, f.ClientSet, pod), "start pod") - for host, plugin := range b.driver.Nodes { - gomega.Expect(plugin.GetPreparedResources()).Should(gomega.BeEmpty(), "not claims should be prepared on host %s while pod is running", host) - } + // TODO: more test scenarios: + // - driver returns "unimplemented" as method response + // - driver returns "Unimplemented" as part of stream + // - driver returns EOF + // - driver changes resources }) }) @@ -241,11 +293,6 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, ginkgo.It("supports claim and class parameters", func(ctx context.Context) { objects := genParameters() - // TODO: replace with publishing NodeResourceSlice through kubelet - if parameterMode == parameterModeTranslated || parameterMode == parameterModeStructured { - objects = append(objects, b.nodeResourceSlice(nodes.NodeNames[0], maxAllocations)) - } - pod, template := b.podInline(resourcev1alpha2.AllocationModeWaitForFirstConsumer) objects = append(objects, pod, template) @@ -263,11 +310,6 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, objects = append(objects, pod, template) } - // TODO: replace with publishing NodeResourceSlice through kubelet - if parameterMode == parameterModeTranslated || parameterMode == parameterModeStructured { - objects = append(objects, b.nodeResourceSlice(nodes.NodeNames[0], maxAllocations)) - } - b.create(ctx, objects...) // We don't know the order. All that matters is that all of them get scheduled eventually. @@ -298,11 +340,6 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, objects = append(objects, pod) } - // TODO: replace with publishing NodeResourceSlice through kubelet - if parameterMode == parameterModeTranslated || parameterMode == parameterModeStructured { - objects = append(objects, b.nodeResourceSlice(nodes.NodeNames[0], maxAllocations)) - } - b.create(ctx, objects...) // We don't know the order. All that matters is that all of them get scheduled eventually. @@ -340,11 +377,6 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, objects = append(objects, pod) } - // TODO: replace with publishing NodeResourceSlice through kubelet - if parameterMode == parameterModeTranslated || parameterMode == parameterModeStructured { - objects = append(objects, b.nodeResourceSlice(nodes.NodeNames[0], maxAllocations)) - } - b.create(ctx, objects...) // We don't know the order. All that matters is that all of them get scheduled eventually. @@ -1278,31 +1310,6 @@ func (b *builder) rawParameterData(kv ...string) []byte { return raw } -func (b *builder) nodeResourceSlice(nodeName string, capacity int) *resourcev1alpha2.NodeResourceSlice { - slice := &resourcev1alpha2.NodeResourceSlice{ - ObjectMeta: metav1.ObjectMeta{ - Name: b.driver.Name + "-" + nodeName, - }, - - NodeName: nodeName, - DriverName: b.driver.Name, - - NodeResourceModel: resourcev1alpha2.NodeResourceModel{ - NamedResources: &resourcev1alpha2.NamedResourcesResources{}, - }, - } - - for i := 0; i < capacity; i++ { - slice.NodeResourceModel.NamedResources.Instances = append(slice.NodeResourceModel.NamedResources.Instances, - resourcev1alpha2.NamedResourcesInstance{ - Name: fmt.Sprintf("instance-%d", i), - }, - ) - } - - return slice -} - // makePod returns a simple pod with no resource claims. // The pod prints its env and waits. func (b *builder) pod() *v1.Pod { diff --git a/test/e2e/dra/test-driver/app/kubeletplugin.go b/test/e2e/dra/test-driver/app/kubeletplugin.go index 9a564f10e78..8a95669d13e 100644 --- a/test/e2e/dra/test-driver/app/kubeletplugin.go +++ b/test/e2e/dra/test-driver/app/kubeletplugin.go @@ -26,7 +26,10 @@ import ( "sync" "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + resourceapi "k8s.io/api/resource/v1alpha2" "k8s.io/apimachinery/pkg/runtime" "k8s.io/dynamic-resource-allocation/kubeletplugin" "k8s.io/klog/v2" @@ -35,6 +38,7 @@ import ( ) type ExamplePlugin struct { + stopCh <-chan struct{} logger klog.Logger d kubeletplugin.DRAPlugin fileOps FileOperations @@ -80,7 +84,8 @@ func (ex *ExamplePlugin) getJSONFilePath(claimUID string) string { return filepath.Join(ex.cdiDir, fmt.Sprintf("%s-%s.json", ex.driverName, claimUID)) } -// FileOperations defines optional callbacks for handling CDI files. +// FileOperations defines optional callbacks for handling CDI files +// and some other configuration. type FileOperations struct { // Create must overwrite the file. Create func(name string, content []byte) error @@ -88,10 +93,16 @@ type FileOperations struct { // Remove must remove the file. It must not return an error when the // file does not exist. Remove func(name string) error + + // NumResourceInstances determines whether the plugin reports resources + // instances and how many. A negative value causes it to report "not implemented" + // in the NodeListAndWatchResources gRPC call. + NumResourceInstances int } // StartPlugin sets up the servers that are necessary for a DRA kubelet plugin. -func StartPlugin(logger klog.Logger, cdiDir, driverName string, nodeName string, fileOps FileOperations, opts ...kubeletplugin.Option) (*ExamplePlugin, error) { +func StartPlugin(ctx context.Context, cdiDir, driverName string, nodeName string, fileOps FileOperations, opts ...kubeletplugin.Option) (*ExamplePlugin, error) { + logger := klog.FromContext(ctx) if fileOps.Create == nil { fileOps.Create = func(name string, content []byte) error { return os.WriteFile(name, content, os.FileMode(0644)) @@ -106,6 +117,7 @@ func StartPlugin(logger klog.Logger, cdiDir, driverName string, nodeName string, } } ex := &ExamplePlugin{ + stopCh: ctx.Done(), logger: logger, fileOps: fileOps, cdiDir: cdiDir, @@ -118,6 +130,7 @@ func StartPlugin(logger klog.Logger, cdiDir, driverName string, nodeName string, kubeletplugin.Logger(logger), kubeletplugin.DriverName(driverName), kubeletplugin.GRPCInterceptor(ex.recordGRPCCall), + kubeletplugin.GRPCStreamInterceptor(ex.recordGRPCStream), ) d, err := kubeletplugin.Start(ex, opts...) if err != nil { @@ -330,6 +343,39 @@ func (ex *ExamplePlugin) NodeUnprepareResources(ctx context.Context, req *drapbv return resp, nil } +func (ex *ExamplePlugin) NodeListAndWatchResources(req *drapbv1alpha3.NodeListAndWatchResourcesRequest, stream drapbv1alpha3.Node_NodeListAndWatchResourcesServer) error { + if ex.fileOps.NumResourceInstances < 0 { + ex.logger.Info("Sending no NodeResourcesResponse") + return status.New(codes.Unimplemented, "node resource support disabled").Err() + } + + instances := make([]resourceapi.NamedResourcesInstance, ex.fileOps.NumResourceInstances) + for i := 0; i < ex.fileOps.NumResourceInstances; i++ { + instances[i].Name = fmt.Sprintf("instance-%d", i) + } + resp := &drapbv1alpha3.NodeListAndWatchResourcesResponse{ + Resources: []*resourceapi.NodeResourceModel{ + { + NamedResources: &resourceapi.NamedResourcesResources{ + Instances: instances, + }, + }, + }, + } + + ex.logger.Info("Sending NodeListAndWatchResourcesResponse", "response", resp) + if err := stream.Send(resp); err != nil { + return err + } + + // Keep the stream open until the test is done. + // TODO: test sending more updates later + <-ex.stopCh + ex.logger.Info("Done sending NodeListAndWatchResourcesResponse, closing stream") + + return nil +} + func (ex *ExamplePlugin) GetPreparedResources() []ClaimID { ex.mutex.Lock() defer ex.mutex.Unlock() @@ -360,6 +406,25 @@ func (ex *ExamplePlugin) recordGRPCCall(ctx context.Context, req interface{}, in return call.Response, call.Err } +func (ex *ExamplePlugin) recordGRPCStream(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + call := GRPCCall{ + FullMethod: info.FullMethod, + } + ex.mutex.Lock() + ex.gRPCCalls = append(ex.gRPCCalls, call) + index := len(ex.gRPCCalls) - 1 + ex.mutex.Unlock() + + // We don't hold the mutex here to allow concurrent calls. + call.Err = handler(srv, stream) + + ex.mutex.Lock() + ex.gRPCCalls[index] = call + ex.mutex.Unlock() + + return call.Err +} + func (ex *ExamplePlugin) GetGRPCCalls() []GRPCCall { ex.mutex.Lock() defer ex.mutex.Unlock() diff --git a/test/e2e/dra/test-driver/app/server.go b/test/e2e/dra/test-driver/app/server.go index 8bafdb649fc..3f55c541463 100644 --- a/test/e2e/dra/test-driver/app/server.go +++ b/test/e2e/dra/test-driver/app/server.go @@ -287,7 +287,7 @@ func NewCommand() *cobra.Command { return fmt.Errorf("create socket directory: %w", err) } - plugin, err := StartPlugin(logger, *cdiDir, *driverName, "", FileOperations{}, + plugin, err := StartPlugin(cmd.Context(), *cdiDir, *driverName, "", FileOperations{}, kubeletplugin.PluginSocketPath(*endpoint), kubeletplugin.RegistrarSocketPath(path.Join(*pluginRegistrationPath, *driverName+"-reg.sock")), kubeletplugin.KubeletPluginSocketPath(*draAddress), diff --git a/test/e2e_node/dra_test.go b/test/e2e_node/dra_test.go index 5344a05753e..ad2fab45d6d 100644 --- a/test/e2e_node/dra_test.go +++ b/test/e2e_node/dra_test.go @@ -68,7 +68,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, f.Context("Resource Kubelet Plugin", f.WithSerial(), func() { ginkgo.BeforeEach(func(ctx context.Context) { - kubeletPlugin = newKubeletPlugin(getNodeName(ctx, f)) + kubeletPlugin = newKubeletPlugin(ctx, getNodeName(ctx, f)) }) ginkgo.It("must register after Kubelet restart", func(ctx context.Context) { @@ -88,7 +88,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, ginkgo.It("must register after plugin restart", func(ctx context.Context) { ginkgo.By("restart Kubelet Plugin") kubeletPlugin.Stop() - kubeletPlugin = newKubeletPlugin(getNodeName(ctx, f)) + kubeletPlugin = newKubeletPlugin(ctx, getNodeName(ctx, f)) ginkgo.By("wait for Kubelet plugin re-registration") gomega.Eventually(kubeletPlugin.GetGRPCCalls).WithTimeout(pluginRegistrationTimeout).Should(testdriver.BeRegistered) @@ -134,9 +134,10 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) // Run Kubelet plugin and wait until it's registered -func newKubeletPlugin(nodeName string) *testdriver.ExamplePlugin { +func newKubeletPlugin(ctx context.Context, nodeName string) *testdriver.ExamplePlugin { ginkgo.By("start Kubelet plugin") logger := klog.LoggerWithValues(klog.LoggerWithName(klog.Background(), "kubelet plugin"), "node", nodeName) + ctx = klog.NewContext(ctx, logger) // Ensure that directories exist, creating them if necessary. We want // to know early if there is a setup problem that would prevent @@ -147,7 +148,7 @@ func newKubeletPlugin(nodeName string) *testdriver.ExamplePlugin { framework.ExpectNoError(err, "create socket directory") plugin, err := testdriver.StartPlugin( - logger, + ctx, cdiDir, driverName, "", From 234dc1f63d7a6b4aa77f4bf66b4fdff828262349 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Mon, 26 Feb 2024 18:47:33 +0100 Subject: [PATCH 12/18] dra e2e: run more test scenarios with structured parameters --- test/e2e/dra/dra.go | 448 +++++++++++++++++++++++--------------------- 1 file changed, 239 insertions(+), 209 deletions(-) diff --git a/test/e2e/dra/dra.go b/test/e2e/dra/dra.go index f97aee67af3..60bc50857ff 100644 --- a/test/e2e/dra/dra.go +++ b/test/e2e/dra/dra.go @@ -218,7 +218,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, gomega.HaveLen(1), gomega.ContainElement(gstruct.MatchAllFields(gstruct.Fields{ "TypeMeta": gstruct.Ignore(), - "ObjectMeta": gstruct.Ignore(), // TODO: validate ownerref + "ObjectMeta": gstruct.Ignore(), // TODO (https://github.com/kubernetes/kubernetes/issues/123692): validate ownerref "NodeName": gomega.Equal(nodes.NodeNames[0]), "DriverName": gomega.Equal(driver.Name), "NodeResourceModel": gomega.Equal(resourcev1alpha2.NodeResourceModel{NamedResources: &resourcev1alpha2.NamedResourcesResources{ @@ -239,7 +239,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, // Removal of node resource slice is tested by the general driver removal code. }) - // TODO: more test scenarios: + // TODO (https://github.com/kubernetes/kubernetes/issues/123699): more test scenarios: // - driver returns "unimplemented" as method response // - driver returns "Unimplemented" as part of stream // - driver returns EOF @@ -247,7 +247,184 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) }) - driverTest := func(parameterMode parameterMode) { + genConfigMapParameters := func(b *builder) ([]klog.KMetadata, []string) { + return []klog.KMetadata{b.parameters()}, []string{"user_a", "b"} + } + + genFlexibleParameters := func(b *builder) ([]klog.KMetadata, []string) { + var objects []klog.KMetadata + switch b.driver.parameterMode { + case parameterModeConfigMap: + objects = append(objects, + b.parameters("x", "y"), + b.parameters("a", "b", "request_foo", "bar"), + ) + case parameterModeTranslated: + objects = append(objects, + b.parameters("x", "y"), + b.classParameters(b.parametersName(), "x", "y"), + b.parameters("a", "b", "request_foo", "bar"), + b.claimParameters(b.parametersName(), []string{"a", "b"}, []string{"request_foo", "bar"}), + ) + // The parameters object is not the last one but the second-last. + b.parametersCounter-- + case parameterModeStructured: + objects = append(objects, + b.classParameters("", "x", "y"), + b.claimParameters("", []string{"a", "b"}, []string{"request_foo", "bar"}), + ) + } + return objects, []string{"user_a", "b", "user_request_foo", "bar", "admin_x", "y"} + } + + // claimTests tries out several different combinations of pods with + // claims, both inline and external. + claimTests := func(b *builder, driver *Driver, allocationMode resourcev1alpha2.AllocationMode, genParameters func(b *builder) ([]klog.KMetadata, []string)) { + ginkgo.It("supports simple pod referencing inline resource claim", func(ctx context.Context) { + objects, expectedEnv := genParameters(b) + pod, template := b.podInline(allocationMode) + objects = append(objects, pod, template) + b.create(ctx, objects...) + + b.testPod(ctx, f.ClientSet, pod, expectedEnv...) + }) + + ginkgo.It("supports inline claim referenced by multiple containers", func(ctx context.Context) { + objects, expectedEnv := genParameters(b) + pod, template := b.podInlineMultiple(allocationMode) + objects = append(objects, pod, template) + b.create(ctx, objects...) + + b.testPod(ctx, f.ClientSet, pod, expectedEnv...) + }) + + ginkgo.It("supports simple pod referencing external resource claim", func(ctx context.Context) { + objects, expectedEnv := genParameters(b) + pod := b.podExternal() + claim := b.externalClaim(allocationMode) + objects = append(objects, claim, pod) + b.create(ctx, objects...) + + b.testPod(ctx, f.ClientSet, pod, expectedEnv...) + }) + + ginkgo.It("supports external claim referenced by multiple pods", func(ctx context.Context) { + objects, expectedEnv := genParameters(b) + pod1 := b.podExternal() + pod2 := b.podExternal() + pod3 := b.podExternal() + claim := b.externalClaim(allocationMode) + objects = append(objects, claim, pod1, pod2, pod3) + b.create(ctx, objects...) + + for _, pod := range []*v1.Pod{pod1, pod2, pod3} { + b.testPod(ctx, f.ClientSet, pod, expectedEnv...) + } + }) + + ginkgo.It("supports external claim referenced by multiple containers of multiple pods", func(ctx context.Context) { + objects, expectedEnv := genParameters(b) + pod1 := b.podExternalMultiple() + pod2 := b.podExternalMultiple() + pod3 := b.podExternalMultiple() + claim := b.externalClaim(allocationMode) + objects = append(objects, claim, pod1, pod2, pod3) + b.create(ctx, objects...) + + for _, pod := range []*v1.Pod{pod1, pod2, pod3} { + b.testPod(ctx, f.ClientSet, pod, expectedEnv...) + } + }) + + ginkgo.It("supports init containers", func(ctx context.Context) { + objects, expectedEnv := genParameters(b) + pod, template := b.podInline(allocationMode) + pod.Spec.InitContainers = []v1.Container{pod.Spec.Containers[0]} + pod.Spec.InitContainers[0].Name += "-init" + // This must succeed for the pod to start. + pod.Spec.InitContainers[0].Command = []string{"sh", "-c", "env | grep user_a=b"} + objects = append(objects, pod, template) + b.create(ctx, objects...) + + b.testPod(ctx, f.ClientSet, pod, expectedEnv...) + }) + + ginkgo.It("removes reservation from claim when pod is done", func(ctx context.Context) { + objects, _ := genParameters(b) + pod := b.podExternal() + claim := b.externalClaim(allocationMode) + pod.Spec.Containers[0].Command = []string{"true"} + objects = append(objects, claim, pod) + b.create(ctx, objects...) + + ginkgo.By("waiting for pod to finish") + framework.ExpectNoError(e2epod.WaitForPodNoLongerRunningInNamespace(ctx, f.ClientSet, pod.Name, pod.Namespace), "wait for pod to finish") + ginkgo.By("waiting for claim to be unreserved") + gomega.Eventually(ctx, func(ctx context.Context) (*resourcev1alpha2.ResourceClaim, error) { + return f.ClientSet.ResourceV1alpha2().ResourceClaims(pod.Namespace).Get(ctx, claim.Name, metav1.GetOptions{}) + }).WithTimeout(f.Timeouts.PodDelete).Should(gomega.HaveField("Status.ReservedFor", gomega.BeEmpty()), "reservation should have been removed") + }) + + ginkgo.It("deletes generated claims when pod is done", func(ctx context.Context) { + objects, _ := genParameters(b) + pod, template := b.podInline(allocationMode) + pod.Spec.Containers[0].Command = []string{"true"} + objects = append(objects, template, pod) + b.create(ctx, objects...) + + ginkgo.By("waiting for pod to finish") + framework.ExpectNoError(e2epod.WaitForPodNoLongerRunningInNamespace(ctx, f.ClientSet, pod.Name, pod.Namespace), "wait for pod to finish") + ginkgo.By("waiting for claim to be deleted") + gomega.Eventually(ctx, func(ctx context.Context) ([]resourcev1alpha2.ResourceClaim, error) { + claims, err := f.ClientSet.ResourceV1alpha2().ResourceClaims(pod.Namespace).List(ctx, metav1.ListOptions{}) + if err != nil { + return nil, err + } + return claims.Items, nil + }).WithTimeout(f.Timeouts.PodDelete).Should(gomega.BeEmpty(), "claim should have been deleted") + }) + + ginkgo.It("does not delete generated claims when pod is restarting", func(ctx context.Context) { + objects, _ := genParameters(b) + pod, template := b.podInline(allocationMode) + pod.Spec.Containers[0].Command = []string{"sh", "-c", "sleep 1; exit 1"} + pod.Spec.RestartPolicy = v1.RestartPolicyAlways + objects = append(objects, template, pod) + b.create(ctx, objects...) + + ginkgo.By("waiting for pod to restart twice") + gomega.Eventually(ctx, func(ctx context.Context) (*v1.Pod, error) { + return f.ClientSet.CoreV1().Pods(pod.Namespace).Get(ctx, pod.Name, metav1.GetOptions{}) + }).WithTimeout(f.Timeouts.PodStartSlow).Should(gomega.HaveField("Status.ContainerStatuses", gomega.ContainElements(gomega.HaveField("RestartCount", gomega.BeNumerically(">=", 2))))) + if driver.Controller != nil { + gomega.Expect(driver.Controller.GetNumAllocations()).To(gomega.Equal(int64(1)), "number of allocations") + } + }) + + ginkgo.It("must deallocate after use when using delayed allocation", func(ctx context.Context) { + objects, expectedEnv := genParameters(b) + pod := b.podExternal() + claim := b.externalClaim(resourcev1alpha2.AllocationModeWaitForFirstConsumer) + objects = append(objects, claim, pod) + b.create(ctx, objects...) + + gomega.Eventually(ctx, func(ctx context.Context) (*resourcev1alpha2.ResourceClaim, error) { + return b.f.ClientSet.ResourceV1alpha2().ResourceClaims(b.f.Namespace.Name).Get(ctx, claim.Name, metav1.GetOptions{}) + }).WithTimeout(f.Timeouts.PodDelete).ShouldNot(gomega.HaveField("Status.Allocation", (*resourcev1alpha2.AllocationResult)(nil))) + + b.testPod(ctx, f.ClientSet, pod, expectedEnv...) + + ginkgo.By(fmt.Sprintf("deleting pod %s", klog.KObj(pod))) + framework.ExpectNoError(b.f.ClientSet.CoreV1().Pods(b.f.Namespace.Name).Delete(ctx, pod.Name, metav1.DeleteOptions{})) + + ginkgo.By("waiting for claim to get deallocated") + gomega.Eventually(ctx, func(ctx context.Context) (*resourcev1alpha2.ResourceClaim, error) { + return b.f.ClientSet.ResourceV1alpha2().ResourceClaims(b.f.Namespace.Name).Get(ctx, claim.Name, metav1.GetOptions{}) + }).WithTimeout(f.Timeouts.PodDelete).Should(gomega.HaveField("Status.Allocation", (*resourcev1alpha2.AllocationResult)(nil))) + }) + } + + runTests := func(parameterMode parameterMode) { nodes := NewNodes(f, 1, 1) maxAllocations := 1 numPods := 10 @@ -263,35 +440,12 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, b.parametersCounter = 1 b.classParametersName = b.parametersName() - expectedEnv := []string{"user_a", "b", "user_request_foo", "bar", "admin_x", "y"} - genParameters := func() []klog.KMetadata { - var objects []klog.KMetadata - switch parameterMode { - case parameterModeConfigMap: - objects = append(objects, - b.parameters("x", "y"), - b.parameters("a", "b", "request_foo", "bar"), - ) - case parameterModeTranslated: - objects = append(objects, - b.parameters("x", "y"), - b.classParameters(b.parametersName(), "x", "y"), - b.parameters("a", "b", "request_foo", "bar"), - b.claimParameters(b.parametersName(), []string{"a", "b"}, []string{"request_foo", "bar"}), - ) - // The parameters object is not the last one but the second-last. - b.parametersCounter-- - case parameterModeStructured: - objects = append(objects, - b.classParameters("", "x", "y"), - b.claimParameters("", []string{"a", "b"}, []string{"request_foo", "bar"}), - ) - } - return objects + genParameters := func() ([]klog.KMetadata, []string) { + return genFlexibleParameters(b) } ginkgo.It("supports claim and class parameters", func(ctx context.Context) { - objects := genParameters() + objects, expectedEnv := genParameters() pod, template := b.podInline(resourcev1alpha2.AllocationModeWaitForFirstConsumer) objects = append(objects, pod, template) @@ -302,7 +456,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) ginkgo.It("supports reusing resources", func(ctx context.Context) { - objects := genParameters() + objects, expectedEnv := genParameters() pods := make([]*v1.Pod, numPods) for i := 0; i < numPods; i++ { pod, template := b.podInline(resourcev1alpha2.AllocationModeWaitForFirstConsumer) @@ -330,7 +484,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) ginkgo.It("supports sharing a claim concurrently", func(ctx context.Context) { - objects := genParameters() + objects, expectedEnv := genParameters() objects = append(objects, b.externalClaim(resourcev1alpha2.AllocationModeWaitForFirstConsumer)) pods := make([]*v1.Pod, numPods) @@ -358,7 +512,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) ginkgo.It("supports sharing a claim sequentially", func(ctx context.Context) { - objects := genParameters() + objects, expectedEnv := genParameters() // Change from "shareable" to "not shareable", if possible. switch parameterMode { @@ -397,41 +551,15 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, } wg.Wait() }) - } - - ginkgo.Context("driver", func() { - ginkgo.Context("with ConfigMap parameters", func() { driverTest(parameterModeConfigMap) }) - ginkgo.Context("with translated parameters", func() { driverTest(parameterModeTranslated) }) - ginkgo.Context("with structured parameters", func() { driverTest(parameterModeStructured) }) - }) - - // TODO: move most of the test below into `testDriver` so that they get - // executed with different parameters. Not done yet because it'll be easier - // once publishing NodeResourceSlices works. - - ginkgo.Context("cluster", func() { - nodes := NewNodes(f, 1, 1) - driver := NewDriver(f, nodes, networkResources) - b := newBuilder(f, driver) - - ginkgo.It("truncates the name of a generated resource claim", func(ctx context.Context) { - parameters := b.parameters() - pod, template := b.podInline(resourcev1alpha2.AllocationModeWaitForFirstConsumer) - pod.Name = strings.Repeat("p", 63) - pod.Spec.ResourceClaims[0].Name = strings.Repeat("c", 63) - pod.Spec.Containers[0].Resources.Claims[0].Name = pod.Spec.ResourceClaims[0].Name - b.create(ctx, parameters, template, pod) - - b.testPod(ctx, f.ClientSet, pod) - }) ginkgo.It("retries pod scheduling after creating resource class", func(ctx context.Context) { - parameters := b.parameters() + objects, expectedEnv := genParameters() pod, template := b.podInline(resourcev1alpha2.AllocationModeWaitForFirstConsumer) class, err := f.ClientSet.ResourceV1alpha2().ResourceClasses().Get(ctx, template.Spec.Spec.ResourceClassName, metav1.GetOptions{}) framework.ExpectNoError(err) template.Spec.Spec.ResourceClassName += "-b" - b.create(ctx, parameters, template, pod) + objects = append(objects, template, pod) + b.create(ctx, objects...) // There's no way to be sure that the scheduler has checked the pod. // But if we sleep for a short while, it's likely and if there are any @@ -444,11 +572,11 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, class.Name = template.Spec.Spec.ResourceClassName b.create(ctx, class) - b.testPod(ctx, f.ClientSet, pod) + b.testPod(ctx, f.ClientSet, pod, expectedEnv...) }) ginkgo.It("retries pod scheduling after updating resource class", func(ctx context.Context) { - parameters := b.parameters() + objects, expectedEnv := genParameters() pod, template := b.podInline(resourcev1alpha2.AllocationModeWaitForFirstConsumer) // First modify the class so that it matches no nodes. @@ -471,7 +599,8 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, framework.ExpectNoError(err) // Now create the pod. - b.create(ctx, parameters, template, pod) + objects = append(objects, template, pod) + b.create(ctx, objects...) // There's no way to be sure that the scheduler has checked the pod. // But if we sleep for a short while, it's likely and if there are any @@ -484,7 +613,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, _, err = f.ClientSet.ResourceV1alpha2().ResourceClasses().Update(ctx, class, metav1.UpdateOptions{}) framework.ExpectNoError(err) - b.testPod(ctx, f.ClientSet, pod) + b.testPod(ctx, f.ClientSet, pod, expectedEnv...) }) ginkgo.It("runs a pod without a generated resource claim", func(ctx context.Context) { @@ -504,6 +633,38 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, framework.ExpectNoError(err) framework.ExpectNoError(e2epod.WaitForPodRunningInNamespace(ctx, f.ClientSet, pod)) }) + + ginkgo.Context("with delayed allocation", func() { + claimTests(b, driver, resourcev1alpha2.AllocationModeWaitForFirstConsumer, genFlexibleParameters) + }) + + ginkgo.Context("with immediate allocation", func() { + claimTests(b, driver, resourcev1alpha2.AllocationModeImmediate, genFlexibleParameters) + }) + } + + ginkgo.Context("with ConfigMap parameters", func() { runTests(parameterModeConfigMap) }) + ginkgo.Context("with translated parameters", func() { runTests(parameterModeTranslated) }) + ginkgo.Context("with structured parameters", func() { runTests(parameterModeStructured) }) + + // TODO (https://github.com/kubernetes/kubernetes/issues/123699): move most of the test below into `testDriver` so that they get + // executed with different parameters. + + ginkgo.Context("cluster", func() { + nodes := NewNodes(f, 1, 1) + driver := NewDriver(f, nodes, networkResources) + b := newBuilder(f, driver) + + ginkgo.It("truncates the name of a generated resource claim", func(ctx context.Context) { + parameters := b.parameters() + pod, template := b.podInline(resourcev1alpha2.AllocationModeWaitForFirstConsumer) + pod.Name = strings.Repeat("p", 63) + pod.Spec.ResourceClaims[0].Name = strings.Repeat("c", 63) + pod.Spec.Containers[0].Resources.Claims[0].Name = pod.Spec.ResourceClaims[0].Name + b.create(ctx, parameters, template, pod) + + b.testPod(ctx, f.ClientSet, pod) + }) }) ginkgo.Context("cluster", func() { @@ -611,146 +772,13 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) }) - // claimTests tries out several different combinations of pods with - // claims, both inline and external. - claimTests := func(b *builder, driver *Driver, allocationMode resourcev1alpha2.AllocationMode) { - ginkgo.It("supports simple pod referencing inline resource claim", func(ctx context.Context) { - parameters := b.parameters() - pod, template := b.podInline(allocationMode) - b.create(ctx, parameters, pod, template) - - b.testPod(ctx, f.ClientSet, pod) - }) - - ginkgo.It("supports inline claim referenced by multiple containers", func(ctx context.Context) { - parameters := b.parameters() - pod, template := b.podInlineMultiple(allocationMode) - b.create(ctx, parameters, pod, template) - - b.testPod(ctx, f.ClientSet, pod) - }) - - ginkgo.It("supports simple pod referencing external resource claim", func(ctx context.Context) { - parameters := b.parameters() - pod := b.podExternal() - b.create(ctx, parameters, b.externalClaim(allocationMode), pod) - - b.testPod(ctx, f.ClientSet, pod) - }) - - ginkgo.It("supports external claim referenced by multiple pods", func(ctx context.Context) { - parameters := b.parameters() - pod1 := b.podExternal() - pod2 := b.podExternal() - pod3 := b.podExternal() - claim := b.externalClaim(allocationMode) - b.create(ctx, parameters, claim, pod1, pod2, pod3) - - for _, pod := range []*v1.Pod{pod1, pod2, pod3} { - b.testPod(ctx, f.ClientSet, pod) - } - }) - - ginkgo.It("supports external claim referenced by multiple containers of multiple pods", func(ctx context.Context) { - parameters := b.parameters() - pod1 := b.podExternalMultiple() - pod2 := b.podExternalMultiple() - pod3 := b.podExternalMultiple() - claim := b.externalClaim(allocationMode) - b.create(ctx, parameters, claim, pod1, pod2, pod3) - - for _, pod := range []*v1.Pod{pod1, pod2, pod3} { - b.testPod(ctx, f.ClientSet, pod) - } - }) - - ginkgo.It("supports init containers", func(ctx context.Context) { - parameters := b.parameters() - pod, template := b.podInline(allocationMode) - pod.Spec.InitContainers = []v1.Container{pod.Spec.Containers[0]} - pod.Spec.InitContainers[0].Name += "-init" - // This must succeed for the pod to start. - pod.Spec.InitContainers[0].Command = []string{"sh", "-c", "env | grep user_a=b"} - b.create(ctx, parameters, pod, template) - - b.testPod(ctx, f.ClientSet, pod) - }) - - ginkgo.It("removes reservation from claim when pod is done", func(ctx context.Context) { - parameters := b.parameters() - pod := b.podExternal() - claim := b.externalClaim(allocationMode) - pod.Spec.Containers[0].Command = []string{"true"} - b.create(ctx, parameters, claim, pod) - - ginkgo.By("waiting for pod to finish") - framework.ExpectNoError(e2epod.WaitForPodNoLongerRunningInNamespace(ctx, f.ClientSet, pod.Name, pod.Namespace), "wait for pod to finish") - ginkgo.By("waiting for claim to be unreserved") - gomega.Eventually(ctx, func(ctx context.Context) (*resourcev1alpha2.ResourceClaim, error) { - return f.ClientSet.ResourceV1alpha2().ResourceClaims(pod.Namespace).Get(ctx, claim.Name, metav1.GetOptions{}) - }).WithTimeout(f.Timeouts.PodDelete).Should(gomega.HaveField("Status.ReservedFor", gomega.BeEmpty()), "reservation should have been removed") - }) - - ginkgo.It("deletes generated claims when pod is done", func(ctx context.Context) { - parameters := b.parameters() - pod, template := b.podInline(allocationMode) - pod.Spec.Containers[0].Command = []string{"true"} - b.create(ctx, parameters, template, pod) - - ginkgo.By("waiting for pod to finish") - framework.ExpectNoError(e2epod.WaitForPodNoLongerRunningInNamespace(ctx, f.ClientSet, pod.Name, pod.Namespace), "wait for pod to finish") - ginkgo.By("waiting for claim to be deleted") - gomega.Eventually(ctx, func(ctx context.Context) ([]resourcev1alpha2.ResourceClaim, error) { - claims, err := f.ClientSet.ResourceV1alpha2().ResourceClaims(pod.Namespace).List(ctx, metav1.ListOptions{}) - if err != nil { - return nil, err - } - return claims.Items, nil - }).WithTimeout(f.Timeouts.PodDelete).Should(gomega.BeEmpty(), "claim should have been deleted") - }) - - ginkgo.It("does not delete generated claims when pod is restarting", func(ctx context.Context) { - parameters := b.parameters() - pod, template := b.podInline(allocationMode) - pod.Spec.Containers[0].Command = []string{"sh", "-c", "sleep 1; exit 1"} - pod.Spec.RestartPolicy = v1.RestartPolicyAlways - b.create(ctx, parameters, template, pod) - - ginkgo.By("waiting for pod to restart twice") - gomega.Eventually(ctx, func(ctx context.Context) (*v1.Pod, error) { - return f.ClientSet.CoreV1().Pods(pod.Namespace).Get(ctx, pod.Name, metav1.GetOptions{}) - }).WithTimeout(f.Timeouts.PodStartSlow).Should(gomega.HaveField("Status.ContainerStatuses", gomega.ContainElements(gomega.HaveField("RestartCount", gomega.BeNumerically(">=", 2))))) - gomega.Expect(driver.Controller.GetNumAllocations()).To(gomega.Equal(int64(1)), "number of allocations") - }) - - ginkgo.It("must deallocate after use when using delayed allocation", func(ctx context.Context) { - parameters := b.parameters() - pod := b.podExternal() - claim := b.externalClaim(resourcev1alpha2.AllocationModeWaitForFirstConsumer) - b.create(ctx, parameters, claim, pod) - - gomega.Eventually(ctx, func(ctx context.Context) (*resourcev1alpha2.ResourceClaim, error) { - return b.f.ClientSet.ResourceV1alpha2().ResourceClaims(b.f.Namespace.Name).Get(ctx, claim.Name, metav1.GetOptions{}) - }).WithTimeout(f.Timeouts.PodDelete).ShouldNot(gomega.HaveField("Status.Allocation", (*resourcev1alpha2.AllocationResult)(nil))) - - b.testPod(ctx, f.ClientSet, pod) - - ginkgo.By(fmt.Sprintf("deleting pod %s", klog.KObj(pod))) - framework.ExpectNoError(b.f.ClientSet.CoreV1().Pods(b.f.Namespace.Name).Delete(ctx, pod.Name, metav1.DeleteOptions{})) - - ginkgo.By("waiting for claim to get deallocated") - gomega.Eventually(ctx, func(ctx context.Context) (*resourcev1alpha2.ResourceClaim, error) { - return b.f.ClientSet.ResourceV1alpha2().ResourceClaims(b.f.Namespace.Name).Get(ctx, claim.Name, metav1.GetOptions{}) - }).WithTimeout(f.Timeouts.PodDelete).Should(gomega.HaveField("Status.Allocation", (*resourcev1alpha2.AllocationResult)(nil))) - }) - - // kube-controller-manager can trigger delayed allocation for pods where the - // node name was already selected when creating the pod. For immediate - // allocation, the creator has to ensure that the node matches the claims. - // This does not work for resource claim templates and only isn't - // a problem here because the resource is network-attached and available - // on all nodes. - + // kube-controller-manager can trigger delayed allocation for pods where the + // node name was already selected when creating the pod. For immediate + // allocation, the creator has to ensure that the node matches the claims. + // This does not work for resource claim templates and only isn't + // a problem here because the resource is network-attached and available + // on all nodes. + preScheduledTests := func(b *builder, driver *Driver, allocationMode resourcev1alpha2.AllocationMode) { ginkgo.It("supports scheduled pod referencing inline resource claim", func(ctx context.Context) { parameters := b.parameters() pod, template := b.podInline(allocationMode) @@ -774,7 +802,8 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, ginkgo.Context("with delayed allocation and setting ReservedFor", func() { driver := NewDriver(f, nodes, networkResources) b := newBuilder(f, driver) - claimTests(b, driver, resourcev1alpha2.AllocationModeWaitForFirstConsumer) + preScheduledTests(b, driver, resourcev1alpha2.AllocationModeWaitForFirstConsumer) + claimTests(b, driver, resourcev1alpha2.AllocationModeWaitForFirstConsumer, genConfigMapParameters) }) ginkgo.Context("with delayed allocation and not setting ReservedFor", func() { @@ -784,13 +813,15 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, return resources }) b := newBuilder(f, driver) - claimTests(b, driver, resourcev1alpha2.AllocationModeWaitForFirstConsumer) + preScheduledTests(b, driver, resourcev1alpha2.AllocationModeWaitForFirstConsumer) + claimTests(b, driver, resourcev1alpha2.AllocationModeWaitForFirstConsumer, genConfigMapParameters) }) ginkgo.Context("with immediate allocation", func() { driver := NewDriver(f, nodes, networkResources) b := newBuilder(f, driver) - claimTests(b, driver, resourcev1alpha2.AllocationModeImmediate) + preScheduledTests(b, driver, resourcev1alpha2.AllocationModeImmediate) + claimTests(b, driver, resourcev1alpha2.AllocationModeImmediate, genConfigMapParameters) }) }) @@ -1263,7 +1294,6 @@ func (b *builder) claimParameters(generatedFrom string, claimKV, requestKV []str // Without any request, nothing gets allocated and vendor // parameters are also not passed down because they get // attached to the allocation result. - // TODO: is that the semantic we want? DriverRequests: []resourcev1alpha2.DriverRequests{ { DriverName: b.driver.Name, From 42ee56f093133402ed860d4c5f54b049041386c9 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Mon, 4 Mar 2024 09:13:19 +0100 Subject: [PATCH 13/18] dra api: implement semver attribute value type This adds support for semantic version comparison to the CEL support in the "named resources" structured parameter model. For example, it can be used to check that an instance supports a certain API level. To minimize the risk, the new "semver" type is only defined in the CEL environment for DRA expressions, not in the base library. See https://github.com/kubernetes/kubernetes/pull/123664 for a PR which adds it to the base library. Validation of semver strings is done with the regular expression from semver.org. The actual evaluation at runtime then uses semver/v4. --- api/api-rules/violation_exceptions.list | 1 + api/openapi-spec/swagger.json | 4 + ...is__resource.k8s.io__v1alpha2_openapi.json | 4 + pkg/apis/resource/namedresources.go | 14 +- .../namedresources/validation/validation.go | 29 +- .../validation/validation_test.go | 43 ++- .../v1alpha2/zz_generated.conversion.go | 2 + pkg/apis/resource/zz_generated.deepcopy.go | 5 + pkg/generated/openapi/zz_generated.openapi.go | 14 + .../api/resource/v1alpha2/generated.pb.go | 329 ++++++++++-------- .../api/resource/v1alpha2/generated.proto | 3 + .../api/resource/v1alpha2/namedresources.go | 14 +- .../v1alpha2/zz_generated.deepcopy.go | 5 + ...rce.k8s.io.v1alpha2.NodeResourceSlice.json | 3 +- ...ource.k8s.io.v1alpha2.NodeResourceSlice.pb | Bin 519 -> 533 bytes ...rce.k8s.io.v1alpha2.NodeResourceSlice.yaml | 1 + .../applyconfigurations/internal/internal.go | 3 + .../v1alpha2/namedresourcesattribute.go | 8 + .../v1alpha2/namedresourcesattributevalue.go | 9 + .../k8s.io/dynamic-resource-allocation/go.mod | 1 + .../k8s.io/dynamic-resource-allocation/go.sum | 1 + .../structured/namedresources/cel/compile.go | 72 ++-- .../structured/namedresources/cel/semver.go | 73 ++++ .../namedresources/cel/semver_test.go | 209 +++++++++++ .../namedresources/cel/semverlib.go | 238 +++++++++++++ 25 files changed, 891 insertions(+), 194 deletions(-) create mode 100644 staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/semver.go create mode 100644 staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/semver_test.go create mode 100644 staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/semverlib.go diff --git a/api/api-rules/violation_exceptions.list b/api/api-rules/violation_exceptions.list index ad6ea5d5ff7..9658074af87 100644 --- a/api/api-rules/violation_exceptions.list +++ b/api/api-rules/violation_exceptions.list @@ -57,6 +57,7 @@ API rule violation: names_match,k8s.io/api/resource/v1alpha2,NamedResourcesAttri API rule violation: names_match,k8s.io/api/resource/v1alpha2,NamedResourcesAttributeValue,QuantityValue API rule violation: names_match,k8s.io/api/resource/v1alpha2,NamedResourcesAttributeValue,StringSliceValue API rule violation: names_match,k8s.io/api/resource/v1alpha2,NamedResourcesAttributeValue,StringValue +API rule violation: names_match,k8s.io/api/resource/v1alpha2,NamedResourcesAttributeValue,VersionValue API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,Ref API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,Schema API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,XEmbeddedResource diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 98b12379620..28208b252ee 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -14900,6 +14900,10 @@ "stringSlice": { "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NamedResourcesStringSlice", "description": "StringSliceValue is an array of strings." + }, + "version": { + "description": "VersionValue is a semantic version according to semver.org spec 2.0.0.", + "type": "string" } }, "required": [ diff --git a/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha2_openapi.json b/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha2_openapi.json index eb9fed5e5d1..0d9a3b97082 100644 --- a/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha2_openapi.json +++ b/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha2_openapi.json @@ -228,6 +228,10 @@ } ], "description": "StringSliceValue is an array of strings." + }, + "version": { + "description": "VersionValue is a semantic version according to semver.org spec 2.0.0.", + "type": "string" } }, "required": [ diff --git a/pkg/apis/resource/namedresources.go b/pkg/apis/resource/namedresources.go index e64d2796a0e..cee94e34a84 100644 --- a/pkg/apis/resource/namedresources.go +++ b/pkg/apis/resource/namedresources.go @@ -59,7 +59,8 @@ type NamedResourcesAttributeValue struct { StringValue *string // StringSliceValue is an array of strings. StringSliceValue *NamedResourcesStringSlice - // TODO: VersionValue *SemVersion + // VersionValue is a semantic version according to semver.org spec 2.0.0. + VersionValue *string } // NamedResourcesIntSlice contains a slice of 64-bit integers. @@ -74,17 +75,6 @@ type NamedResourcesStringSlice struct { Strings []string } -// TODO -// -// A wrapper around https://pkg.go.dev/github.com/blang/semver/v4#Version which -// is encoded as a string. During decoding, it validates that the string -// can be parsed using tolerant parsing (currently trims spaces, removes a "v" prefix, -// adds a 0 patch number to versions with only major and minor components specified, -// and removes leading 0s). -// type SemVersion struct { -// semver.Version -//} - // NamedResourcesRequest is used in ResourceRequestModel. type NamedResourcesRequest struct { // Selector is a CEL expression which must evaluate to true if a diff --git a/pkg/apis/resource/structured/namedresources/validation/validation.go b/pkg/apis/resource/structured/namedresources/validation/validation.go index a9f703753e8..92748c4edc8 100644 --- a/pkg/apis/resource/structured/namedresources/validation/validation.go +++ b/pkg/apis/resource/structured/namedresources/validation/validation.go @@ -18,6 +18,7 @@ package validation import ( "fmt" + "regexp" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation/field" @@ -63,6 +64,27 @@ func validateInstances(instances []resource.NamedResourcesInstance, fldPath *fie return allErrs } +var ( + numericIdentifier = `(0|[1-9]\d*)` + + preReleaseIdentifier = `(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)` + + buildIdentifier = `[0-9a-zA-Z-]+` + + semverRe = regexp.MustCompile(`^` + + + // dot-separated version segments (e.g. 1.2.3) + numericIdentifier + `\.` + numericIdentifier + `\.` + numericIdentifier + + + // optional dot-separated prerelease segments (e.g. -alpha.PRERELEASE.1) + `(-` + preReleaseIdentifier + `(\.` + preReleaseIdentifier + `)*)?` + + + // optional dot-separated build identifier segments (e.g. +build.id.20240305) + `(\+` + buildIdentifier + `(\.` + buildIdentifier + `)*)?` + + + `$`) +) + func validateAttributes(attributes []resource.NamedResourcesAttribute, fldPath *field.Path) field.ErrorList { var allErrs field.ErrorList attributeNames := sets.New[string]() @@ -95,7 +117,12 @@ func validateAttributes(attributes []resource.NamedResourcesAttribute, fldPath * if attribute.StringSliceValue != nil { entries.Insert("stringSlice") } - // TODO: VersionValue + if attribute.VersionValue != nil { + entries.Insert("version") + if !semverRe.MatchString(*attribute.VersionValue) { + allErrs = append(allErrs, field.Invalid(idxPath.Child("version"), *attribute.VersionValue, "must be a string compatible with semver.org spec 2.0.0")) + } + } switch len(entries) { case 0: diff --git a/pkg/apis/resource/structured/namedresources/validation/validation_test.go b/pkg/apis/resource/structured/namedresources/validation/validation_test.go index 22f8f57196e..7fedfcae556 100644 --- a/pkg/apis/resource/structured/namedresources/validation/validation_test.go +++ b/pkg/apis/resource/structured/namedresources/validation/validation_test.go @@ -75,7 +75,44 @@ func TestValidateResources(t *testing.T) { "string-slice": { resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{StringSliceValue: &resourceapi.NamedResourcesStringSlice{Strings: []string{"hello"}}}}}}}), }, - // TODO: semver + "version-okay": { + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To("1.0.0")}}}}}), + }, + "version-beta": { + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To("1.0.0-beta")}}}}}), + }, + "version-beta-1": { + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To("1.0.0-beta.1")}}}}}), + }, + "version-build": { + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To("1.0.0+build")}}}}}), + }, + "version-build-1": { + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To("1.0.0+build.1")}}}}}), + }, + "version-beta-1-build-1": { + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To("1.0.0-beta.1+build.1")}}}}}), + }, + "version-bad": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("instances").Index(0).Child("attributes").Index(0).Child("version"), "1.0", "must be a string compatible with semver.org spec 2.0.0")}, + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To("1.0")}}}}}), + }, + "version-bad-leading-zeros": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("instances").Index(0).Child("attributes").Index(0).Child("version"), "01.0.0", "must be a string compatible with semver.org spec 2.0.0")}, + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To("01.0.0")}}}}}), + }, + "version-bad-leading-zeros-middle": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("instances").Index(0).Child("attributes").Index(0).Child("version"), "1.00.0", "must be a string compatible with semver.org spec 2.0.0")}, + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To("1.00.0")}}}}}), + }, + "version-bad-leading-zeros-end": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("instances").Index(0).Child("attributes").Index(0).Child("version"), "1.0.00", "must be a string compatible with semver.org spec 2.0.0")}, + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To("1.0.00")}}}}}), + }, + "version-bad-spaces": { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("instances").Index(0).Child("attributes").Index(0).Child("version"), " 1.0.0 ", "must be a string compatible with semver.org spec 2.0.0")}, + resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To(" 1.0.0 ")}}}}}), + }, "empty-attribute": { wantFailures: field.ErrorList{field.Required(field.NewPath("instances").Index(0).Child("attributes").Index(0), "exactly one value must be set")}, resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName}}}}), @@ -132,7 +169,9 @@ func TestValidateSelector(t *testing.T) { "stringslice": { selector: `attributes.stringslice["name"].isSorted()`, }, - // TODO: semver + "version": { + selector: `attributes.version["name"].isGreaterThan(semver("1.0.0"))`, + }, } for name, scenario := range scenarios { diff --git a/pkg/apis/resource/v1alpha2/zz_generated.conversion.go b/pkg/apis/resource/v1alpha2/zz_generated.conversion.go index 0562983865a..e99c229accb 100644 --- a/pkg/apis/resource/v1alpha2/zz_generated.conversion.go +++ b/pkg/apis/resource/v1alpha2/zz_generated.conversion.go @@ -679,6 +679,7 @@ func autoConvert_v1alpha2_NamedResourcesAttributeValue_To_resource_NamedResource out.IntSliceValue = (*resource.NamedResourcesIntSlice)(unsafe.Pointer(in.IntSliceValue)) out.StringValue = (*string)(unsafe.Pointer(in.StringValue)) out.StringSliceValue = (*resource.NamedResourcesStringSlice)(unsafe.Pointer(in.StringSliceValue)) + out.VersionValue = (*string)(unsafe.Pointer(in.VersionValue)) return nil } @@ -694,6 +695,7 @@ func autoConvert_resource_NamedResourcesAttributeValue_To_v1alpha2_NamedResource out.IntSliceValue = (*v1alpha2.NamedResourcesIntSlice)(unsafe.Pointer(in.IntSliceValue)) out.StringValue = (*string)(unsafe.Pointer(in.StringValue)) out.StringSliceValue = (*v1alpha2.NamedResourcesStringSlice)(unsafe.Pointer(in.StringSliceValue)) + out.VersionValue = (*string)(unsafe.Pointer(in.VersionValue)) return nil } diff --git a/pkg/apis/resource/zz_generated.deepcopy.go b/pkg/apis/resource/zz_generated.deepcopy.go index 44d2aa3bc94..df0fd44e2d2 100644 --- a/pkg/apis/resource/zz_generated.deepcopy.go +++ b/pkg/apis/resource/zz_generated.deepcopy.go @@ -187,6 +187,11 @@ func (in *NamedResourcesAttributeValue) DeepCopyInto(out *NamedResourcesAttribut *out = new(NamedResourcesStringSlice) (*in).DeepCopyInto(*out) } + if in.VersionValue != nil { + in, out := &in.VersionValue, &out.VersionValue + *out = new(string) + **out = **in + } return } diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index eccec33d32f..32ac61db12d 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -44907,6 +44907,13 @@ func schema_k8sio_api_resource_v1alpha2_NamedResourcesAttribute(ref common.Refer Ref: ref("k8s.io/api/resource/v1alpha2.NamedResourcesStringSlice"), }, }, + "version": { + SchemaProps: spec.SchemaProps{ + Description: "VersionValue is a semantic version according to semver.org spec 2.0.0.", + Type: []string{"string"}, + Format: "", + }, + }, }, Required: []string{"name"}, }, @@ -44962,6 +44969,13 @@ func schema_k8sio_api_resource_v1alpha2_NamedResourcesAttributeValue(ref common. Ref: ref("k8s.io/api/resource/v1alpha2.NamedResourcesStringSlice"), }, }, + "version": { + SchemaProps: spec.SchemaProps{ + Description: "VersionValue is a semantic version according to semver.org spec 2.0.0.", + Type: []string{"string"}, + Format: "", + }, + }, }, }, }, diff --git a/staging/src/k8s.io/api/resource/v1alpha2/generated.pb.go b/staging/src/k8s.io/api/resource/v1alpha2/generated.pb.go index 82fb3c0f1c6..0144435a342 100644 --- a/staging/src/k8s.io/api/resource/v1alpha2/generated.pb.go +++ b/staging/src/k8s.io/api/resource/v1alpha2/generated.pb.go @@ -1331,147 +1331,149 @@ func init() { } var fileDescriptor_4312f5b44a31ec02 = []byte{ - // 2231 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x1a, 0x4b, 0x6f, 0x1b, 0xc7, - 0xd9, 0x4b, 0xd2, 0x16, 0xf5, 0xc9, 0xa2, 0xa4, 0xb5, 0x64, 0xd1, 0x8e, 0x42, 0x2a, 0x8b, 0x16, - 0x15, 0x50, 0x9b, 0x8c, 0xe5, 0xc4, 0x31, 0xd2, 0xb4, 0x80, 0xd7, 0x8a, 0x5d, 0xa1, 0x89, 0xa3, - 0x0c, 0x63, 0x27, 0x4e, 0x5f, 0x59, 0x71, 0xc7, 0xd2, 0xd6, 0xe4, 0x2e, 0xbd, 0x33, 0x54, 0x6c, - 0xf4, 0x62, 0x14, 0x7d, 0x5d, 0x0a, 0xa4, 0x68, 0x51, 0xb4, 0xa7, 0x9e, 0x8a, 0xa2, 0x97, 0x5e, - 0xda, 0x7b, 0x0f, 0x41, 0x1b, 0x03, 0xbd, 0x38, 0x68, 0x81, 0x06, 0x3d, 0x10, 0x35, 0xfb, 0x13, - 0x7a, 0xcb, 0xa9, 0x98, 0xc7, 0x3e, 0x66, 0xb9, 0x4b, 0x71, 0xd9, 0x46, 0x48, 0x4e, 0xd2, 0xce, - 0x7c, 0xef, 0xef, 0x9b, 0xef, 0x31, 0x43, 0x38, 0x77, 0xf7, 0x32, 0x69, 0x38, 0x5e, 0xd3, 0xea, - 0x39, 0x4d, 0x1f, 0x13, 0xaf, 0xef, 0xb7, 0x71, 0xf3, 0xe0, 0x82, 0xd5, 0xe9, 0xed, 0x5b, 0x9b, - 0xcd, 0x3d, 0xec, 0x62, 0xdf, 0xa2, 0xd8, 0x6e, 0xf4, 0x7c, 0x8f, 0x7a, 0xfa, 0x9a, 0x80, 0x6e, - 0x58, 0x3d, 0xa7, 0x11, 0x40, 0x37, 0x02, 0xe8, 0xb3, 0xe7, 0xf7, 0x1c, 0xba, 0xdf, 0xdf, 0x6d, - 0xb4, 0xbd, 0x6e, 0x73, 0xcf, 0xdb, 0xf3, 0x9a, 0x1c, 0x69, 0xb7, 0x7f, 0x87, 0x7f, 0xf1, 0x0f, - 0xfe, 0x9f, 0x20, 0x76, 0xd6, 0x88, 0xb1, 0x6e, 0x7b, 0x3e, 0x63, 0x9b, 0x64, 0x78, 0xf6, 0xb9, - 0x08, 0xa6, 0x6b, 0xb5, 0xf7, 0x1d, 0x17, 0xfb, 0x0f, 0x9a, 0xbd, 0xbb, 0x7b, 0xaa, 0xbc, 0x79, - 0xb0, 0x48, 0xb3, 0x8b, 0xa9, 0x95, 0xc6, 0xab, 0x99, 0x85, 0xe5, 0xf7, 0x5d, 0xea, 0x74, 0x47, - 0xd9, 0x5c, 0x3a, 0x0c, 0x81, 0xb4, 0xf7, 0x71, 0xd7, 0x4a, 0xe2, 0x19, 0xbf, 0x2c, 0xc0, 0xe2, - 0x95, 0x4e, 0xc7, 0x6b, 0x5b, 0xd4, 0xf1, 0x5c, 0x84, 0x49, 0xbf, 0x43, 0x75, 0x0f, 0x16, 0x02, - 0x7d, 0xbe, 0x6a, 0xb9, 0x76, 0x07, 0x93, 0xaa, 0xb6, 0x5e, 0xdc, 0x98, 0xdb, 0x3c, 0xd7, 0x18, - 0x67, 0xf4, 0x06, 0x52, 0x90, 0xcc, 0xd5, 0x47, 0x83, 0xfa, 0xb1, 0xe1, 0xa0, 0xbe, 0xa0, 0xae, - 0x13, 0x94, 0xa4, 0xae, 0xef, 0xc2, 0xa2, 0x75, 0x60, 0x39, 0x1d, 0x6b, 0xb7, 0x83, 0x5f, 0x73, - 0x6f, 0x78, 0x36, 0x26, 0xd5, 0xc2, 0xba, 0xb6, 0x31, 0xb7, 0xb9, 0x1e, 0xe7, 0xc8, 0x3c, 0xd3, - 0x38, 0xb8, 0xd0, 0x60, 0x00, 0x2d, 0xdc, 0xc1, 0x6d, 0xea, 0xf9, 0xe6, 0xf2, 0x70, 0x50, 0x5f, - 0xbc, 0x92, 0xc0, 0x46, 0x23, 0xf4, 0xf4, 0x26, 0xcc, 0x92, 0x7d, 0xcb, 0xc7, 0x6c, 0xad, 0x5a, - 0x5c, 0xd7, 0x36, 0xca, 0xe6, 0x92, 0x14, 0x70, 0xb6, 0x15, 0x6c, 0xa0, 0x08, 0xc6, 0xf8, 0xa9, - 0x06, 0x2b, 0x49, 0xd3, 0xbc, 0xea, 0xd9, 0xb8, 0xa3, 0xdf, 0x87, 0x8a, 0x6b, 0x75, 0xb1, 0x1d, - 0xe8, 0xc5, 0xcc, 0xc3, 0x84, 0x7d, 0x69, 0xbc, 0x79, 0x6e, 0x28, 0x38, 0x49, 0xd2, 0xa6, 0x3e, - 0x1c, 0xd4, 0x2b, 0x2a, 0x0c, 0x4a, 0xf0, 0x31, 0x7e, 0x5f, 0x80, 0xd3, 0x5b, 0xbe, 0x73, 0x80, - 0xfd, 0x11, 0xa7, 0xfd, 0x58, 0x83, 0xd5, 0x03, 0xec, 0xda, 0x9e, 0x8f, 0xf0, 0xbd, 0x3e, 0x26, - 0x74, 0xc7, 0xf2, 0xad, 0x2e, 0xa6, 0xd8, 0x0f, 0xc4, 0x3b, 0x1f, 0x13, 0x2f, 0x0c, 0x92, 0x46, - 0xef, 0xee, 0x5e, 0x43, 0x06, 0x49, 0x03, 0x59, 0xef, 0xbe, 0x7c, 0x9f, 0x62, 0x97, 0x38, 0x9e, - 0x6b, 0xd6, 0xa5, 0x75, 0x56, 0x6f, 0xa5, 0x53, 0x45, 0x59, 0xec, 0x98, 0x28, 0x2b, 0x56, 0x9a, - 0xe5, 0xa4, 0x53, 0x2f, 0x8e, 0xb7, 0x53, 0xaa, 0xd1, 0xcd, 0xa7, 0xa5, 0x38, 0xe9, 0x3e, 0x41, - 0xe9, 0x0c, 0x8d, 0x5f, 0x14, 0xa0, 0x22, 0x0c, 0x26, 0xc5, 0x24, 0xfa, 0x26, 0x80, 0xcd, 0x57, - 0x98, 0xad, 0xb9, 0x69, 0x66, 0x4d, 0x5d, 0x12, 0x87, 0xad, 0x70, 0x07, 0xc5, 0xa0, 0x74, 0x02, - 0x8b, 0x42, 0xd9, 0x98, 0x51, 0x0b, 0xd3, 0x18, 0xb5, 0x2a, 0x19, 0x2d, 0xde, 0x4a, 0x90, 0x43, - 0x23, 0x0c, 0xf4, 0xaf, 0x43, 0xd9, 0x97, 0x42, 0x57, 0x8b, 0xfc, 0xfc, 0x9d, 0x9f, 0xec, 0xfc, - 0x49, 0x55, 0xcd, 0x45, 0xc9, 0xac, 0x1c, 0xe8, 0x8e, 0x42, 0x82, 0x86, 0x09, 0xb5, 0xf1, 0xf1, - 0xa8, 0xaf, 0x43, 0xc9, 0x8d, 0x2c, 0x74, 0x52, 0xd2, 0x2a, 0x71, 0xdb, 0xf0, 0x1d, 0xe3, 0x2f, - 0x1a, 0xac, 0x26, 0x88, 0x50, 0xea, 0x3b, 0xbb, 0x7d, 0x8a, 0x0f, 0xc7, 0x66, 0x51, 0x52, 0xb1, - 0x02, 0xf8, 0x5b, 0x56, 0xa7, 0x8f, 0xa5, 0x49, 0x5f, 0xcc, 0x75, 0x8c, 0x14, 0x0a, 0xe6, 0xe7, - 0x24, 0xa3, 0xb5, 0x71, 0x50, 0x28, 0xc1, 0xd7, 0xf8, 0x53, 0x11, 0xc6, 0x22, 0xe8, 0xdf, 0x84, - 0xf2, 0xbd, 0xbe, 0xe5, 0x52, 0x87, 0x3e, 0xa8, 0x9e, 0xe0, 0x42, 0x36, 0x32, 0xfd, 0xae, 0x48, - 0xfd, 0xba, 0xc4, 0x32, 0x97, 0x86, 0x83, 0xfa, 0x7c, 0xf0, 0x25, 0xa4, 0x08, 0x49, 0xea, 0xcf, - 0x40, 0x69, 0xd7, 0xf3, 0xc4, 0xf1, 0x28, 0x9b, 0xf3, 0x2c, 0x25, 0x99, 0x9e, 0xd7, 0x11, 0x60, - 0x7c, 0x4b, 0xaf, 0x41, 0xd1, 0x71, 0x69, 0x75, 0x66, 0x5d, 0xdb, 0x28, 0x9a, 0x27, 0x99, 0x53, - 0xb7, 0x5d, 0x2a, 0x00, 0xd8, 0x86, 0xde, 0x86, 0xb2, 0xe3, 0xd2, 0x56, 0xc7, 0x69, 0xe3, 0x6a, - 0x99, 0x4b, 0xf8, 0x5c, 0x1e, 0x33, 0x6e, 0x4b, 0x5c, 0x21, 0x67, 0xf0, 0x25, 0xe5, 0x0c, 0x08, - 0xeb, 0x5f, 0x80, 0x13, 0x84, 0xfa, 0x8e, 0xbb, 0x57, 0x3d, 0xce, 0xdd, 0xba, 0x30, 0x1c, 0xd4, - 0xe7, 0x5a, 0x7c, 0x45, 0x80, 0xca, 0x6d, 0xdd, 0x83, 0x39, 0xf1, 0x9f, 0x10, 0x68, 0x96, 0x0b, - 0xf4, 0x42, 0x1e, 0x81, 0x5a, 0x11, 0xba, 0x48, 0xf1, 0xb1, 0x05, 0xc1, 0x2b, 0xce, 0xc1, 0xd8, - 0x82, 0x65, 0x15, 0xff, 0x9a, 0xd3, 0xa1, 0xd8, 0xd7, 0xcf, 0x41, 0x99, 0xc8, 0x4a, 0x21, 0x43, - 0x31, 0x3c, 0x14, 0x41, 0x05, 0x41, 0x21, 0x84, 0xf1, 0x1b, 0x0d, 0x4e, 0x27, 0xed, 0x42, 0xa8, - 0xe5, 0xb6, 0x27, 0x89, 0x67, 0x07, 0x20, 0x0c, 0x2b, 0x96, 0x1d, 0xd8, 0x81, 0x7d, 0x7e, 0xaa, - 0x50, 0x8e, 0xd2, 0x51, 0xb8, 0x44, 0x50, 0x8c, 0xb8, 0x71, 0x69, 0x54, 0x4c, 0xe9, 0xa1, 0x35, - 0x28, 0x39, 0x2e, 0x15, 0xf5, 0xba, 0x68, 0x96, 0x99, 0x88, 0xdb, 0x2e, 0x25, 0x88, 0xaf, 0x1a, - 0x2f, 0xc3, 0x4a, 0xa2, 0xc0, 0x88, 0x74, 0x90, 0xd3, 0x4c, 0x0f, 0x47, 0xce, 0x7d, 0xf8, 0x8f, - 0x8e, 0x61, 0xd6, 0x91, 0x36, 0x0b, 0xba, 0x86, 0x9c, 0x81, 0x28, 0x90, 0xa3, 0xe2, 0x1c, 0xac, - 0x10, 0x14, 0x51, 0x36, 0x4c, 0x38, 0x93, 0x19, 0x2f, 0xfa, 0xe7, 0x61, 0x46, 0xc4, 0x86, 0x90, - 0x60, 0xd6, 0x9c, 0x1b, 0x0e, 0xea, 0x33, 0x02, 0x82, 0xa0, 0x60, 0xcf, 0xf8, 0xa1, 0x06, 0x4b, - 0xac, 0x37, 0x08, 0x68, 0x88, 0xe2, 0x7e, 0x2f, 0xa3, 0xb8, 0xe7, 0x72, 0x65, 0xf8, 0xcf, 0x44, - 0x55, 0xfd, 0xc3, 0x82, 0x2a, 0x88, 0xd0, 0xe2, 0x1d, 0x28, 0xb3, 0xf6, 0xd0, 0xb6, 0xa8, 0x25, - 0x45, 0x78, 0x76, 0x5c, 0xce, 0x21, 0x0d, 0x06, 0xcd, 0xda, 0xa3, 0xd7, 0x76, 0xbf, 0x83, 0xdb, - 0xf4, 0x55, 0x4c, 0xad, 0x28, 0x90, 0xa2, 0x35, 0x14, 0x52, 0x65, 0x5e, 0x77, 0x3d, 0x1b, 0xf3, - 0x3a, 0x58, 0x50, 0xbd, 0x7e, 0x43, 0xae, 0xa3, 0x10, 0x22, 0x51, 0x37, 0x8b, 0x13, 0xd5, 0xcd, - 0xfb, 0xb0, 0xe4, 0x26, 0x2d, 0x5c, 0x2d, 0x71, 0x65, 0x9a, 0x87, 0xd8, 0x33, 0x89, 0x66, 0x9e, - 0x91, 0xbc, 0x46, 0x7d, 0x86, 0x46, 0x99, 0x18, 0x7f, 0xd5, 0x60, 0x65, 0xc4, 0xa6, 0xaf, 0x38, - 0x84, 0xea, 0xdf, 0x18, 0xb1, 0x6b, 0x63, 0x32, 0xbb, 0x32, 0x6c, 0x6e, 0xd5, 0xd0, 0x4a, 0xc1, - 0x4a, 0xcc, 0xa6, 0x6f, 0xc0, 0x71, 0x87, 0xe2, 0x6e, 0x90, 0x00, 0x72, 0x68, 0x29, 0x72, 0xdd, - 0xbc, 0xa4, 0x7d, 0x7c, 0x9b, 0x51, 0x41, 0x82, 0x98, 0xf1, 0xc7, 0x02, 0x2c, 0xef, 0x78, 0x76, - 0xab, 0xbd, 0x8f, 0xed, 0x7e, 0xc7, 0x71, 0xf7, 0xae, 0x7a, 0x2e, 0xc5, 0xf7, 0xe9, 0x11, 0x04, - 0xc9, 0x5b, 0x50, 0x22, 0x3d, 0xdc, 0x96, 0xb5, 0xf9, 0xd2, 0x78, 0x7d, 0xd2, 0x64, 0x6c, 0xf5, - 0x70, 0x3b, 0x4a, 0x98, 0xec, 0x0b, 0x71, 0x8a, 0xfa, 0x3b, 0xac, 0x9a, 0x58, 0xb4, 0x4f, 0x78, - 0x30, 0xcd, 0x6d, 0x5e, 0x9e, 0x82, 0x36, 0xc7, 0x37, 0x2b, 0x92, 0xfa, 0x09, 0xf1, 0x8d, 0x24, - 0x5d, 0xe3, 0x43, 0x0d, 0xaa, 0x69, 0x68, 0x47, 0x10, 0x07, 0x6f, 0xaa, 0x71, 0xb0, 0x99, 0x5f, - 0xb7, 0x8c, 0x50, 0x78, 0x2f, 0x43, 0x27, 0x66, 0x58, 0xfd, 0x32, 0x9c, 0x14, 0x59, 0x1a, 0xdb, - 0x2c, 0xb4, 0x64, 0x2e, 0x5f, 0x96, 0x84, 0x4e, 0xb6, 0x62, 0x7b, 0x48, 0x81, 0xd4, 0x5f, 0x84, - 0x4a, 0xcf, 0xa3, 0xd8, 0xa5, 0x8e, 0xd5, 0x09, 0x06, 0x30, 0x96, 0x3a, 0x79, 0xfe, 0xda, 0x51, - 0x76, 0x50, 0x02, 0xd2, 0xf8, 0x95, 0x06, 0x67, 0xb3, 0xbd, 0xa3, 0x7f, 0x17, 0x2a, 0x81, 0xc6, - 0x57, 0x3b, 0x96, 0xd3, 0x0d, 0xea, 0xc2, 0x97, 0x26, 0xeb, 0x66, 0x39, 0x4e, 0x44, 0x5b, 0xba, - 0xfc, 0xb4, 0xd4, 0xa9, 0xa2, 0x80, 0x11, 0x94, 0x60, 0x65, 0xfc, 0xba, 0x00, 0xf3, 0x0a, 0xc8, - 0x11, 0x1c, 0x99, 0xd7, 0x95, 0x23, 0xd3, 0xcc, 0xa3, 0x66, 0xd6, 0x59, 0xb9, 0x9d, 0x38, 0x2b, - 0x17, 0xf2, 0x10, 0x1d, 0x7f, 0x48, 0x86, 0x1a, 0xd4, 0x14, 0xf8, 0xab, 0x9e, 0x4b, 0xfa, 0x5d, - 0x36, 0x31, 0xdd, 0xc1, 0x3e, 0x66, 0xcd, 0xcf, 0x39, 0x28, 0x5b, 0x3d, 0xe7, 0xba, 0xef, 0xf5, - 0x7b, 0xc9, 0xf6, 0xe0, 0xca, 0xce, 0x36, 0x5f, 0x47, 0x21, 0x04, 0x83, 0x0e, 0x24, 0x92, 0x65, - 0x22, 0x36, 0x88, 0xc8, 0x09, 0x25, 0x84, 0x08, 0x1b, 0xab, 0x52, 0x66, 0x63, 0x65, 0x42, 0xb1, - 0xef, 0xd8, 0xb2, 0xe5, 0x7c, 0x56, 0x02, 0x14, 0x6f, 0x6e, 0x6f, 0x7d, 0x3c, 0xa8, 0x3f, 0x93, - 0x75, 0xef, 0x41, 0x1f, 0xf4, 0x30, 0x69, 0xdc, 0xdc, 0xde, 0x42, 0x0c, 0xd9, 0x78, 0x5f, 0x83, - 0x25, 0x45, 0xc9, 0x23, 0x48, 0x01, 0x3b, 0x6a, 0x0a, 0xf8, 0x62, 0x0e, 0x97, 0x65, 0x9c, 0xfd, - 0x9f, 0x15, 0x61, 0x55, 0x81, 0x8b, 0x4d, 0x8b, 0x9f, 0x7c, 0x58, 0xbf, 0x0b, 0xf3, 0xe1, 0xf5, - 0xd1, 0x35, 0xdf, 0xeb, 0xca, 0xf8, 0xfe, 0x4a, 0x0e, 0xbd, 0x62, 0xf3, 0x6e, 0x10, 0x5c, 0x62, - 0xe2, 0xb8, 0x1e, 0x27, 0x8c, 0x54, 0x3e, 0xb9, 0xaf, 0x6e, 0xf4, 0x0e, 0x54, 0x6c, 0x65, 0xe8, - 0xaf, 0x96, 0x26, 0xb9, 0xbf, 0x52, 0x2f, 0x0a, 0xa2, 0x14, 0xa3, 0xae, 0xa3, 0x04, 0x6d, 0xe3, - 0x1f, 0x1a, 0x3c, 0x95, 0xa1, 0xe5, 0x11, 0x44, 0xd9, 0xdb, 0x6a, 0x94, 0x3d, 0x3f, 0x95, 0x37, - 0x32, 0xe2, 0xed, 0xe7, 0x1a, 0xac, 0x1f, 0xe6, 0xbf, 0x9c, 0xc9, 0x61, 0x1d, 0x4a, 0x77, 0x1d, - 0xd7, 0x96, 0xfd, 0x66, 0x78, 0xdc, 0xbf, 0xe6, 0xb8, 0x36, 0xe2, 0x3b, 0x61, 0x42, 0x28, 0x66, - 0xde, 0x3b, 0x3c, 0xd4, 0xe0, 0xe9, 0xb1, 0xd5, 0x61, 0x82, 0x69, 0xed, 0xcb, 0xb0, 0xd0, 0x77, - 0x49, 0xdf, 0xa1, 0x2c, 0x60, 0xe2, 0x05, 0xef, 0xd4, 0x70, 0x50, 0x5f, 0xb8, 0xa9, 0x6e, 0xa1, - 0x24, 0xac, 0xf1, 0xdb, 0x42, 0x22, 0x9f, 0xf0, 0xf2, 0x7b, 0x1d, 0x96, 0x62, 0xe5, 0x87, 0x90, - 0xd8, 0x0d, 0x53, 0xd8, 0xbd, 0xa2, 0x24, 0x00, 0x1a, 0xc5, 0x61, 0x47, 0xad, 0x17, 0x37, 0xf5, - 0xff, 0xf3, 0xa8, 0x29, 0x1b, 0x48, 0xe5, 0xa3, 0xef, 0x40, 0x25, 0xba, 0x48, 0x63, 0x9d, 0xb4, - 0x74, 0xc3, 0x46, 0x70, 0x16, 0xae, 0x28, 0xbb, 0x1f, 0x8f, 0xac, 0xa0, 0x04, 0xbe, 0xf1, 0x9f, - 0x02, 0x9c, 0x4a, 0x29, 0x47, 0x53, 0x5d, 0xc3, 0x7d, 0x0b, 0x20, 0xa2, 0x2e, 0x6d, 0xd2, 0xc8, - 0x77, 0x99, 0x68, 0x56, 0xf8, 0x5c, 0x1d, 0xad, 0xc6, 0x28, 0xea, 0x04, 0xe6, 0x7c, 0x4c, 0xb0, - 0x7f, 0x80, 0xed, 0x6b, 0x9e, 0x2f, 0x2f, 0xdd, 0x5e, 0xca, 0x61, 0xf4, 0x91, 0xd2, 0x69, 0x9e, - 0x92, 0x2a, 0xcd, 0xa1, 0x88, 0x30, 0x8a, 0x73, 0xd1, 0x5b, 0xb0, 0x62, 0xe3, 0xf8, 0xed, 0x25, - 0x4f, 0x2b, 0xd8, 0xe6, 0x15, 0xb1, 0x1c, 0xdd, 0x7b, 0x6e, 0xa5, 0x01, 0xa1, 0x74, 0x5c, 0xe3, - 0xef, 0x1a, 0xac, 0x28, 0x92, 0xbd, 0x81, 0xbb, 0xbd, 0x8e, 0x45, 0x8f, 0x62, 0xac, 0xbc, 0xad, - 0xb4, 0x3f, 0x2f, 0xe4, 0x30, 0x5f, 0x20, 0x64, 0x56, 0x1b, 0x64, 0xfc, 0x4d, 0x83, 0x33, 0xa9, - 0x18, 0x47, 0x90, 0x68, 0xdf, 0x52, 0x13, 0xed, 0xc5, 0x29, 0xf4, 0xca, 0x48, 0xb3, 0x8f, 0xb3, - 0xb4, 0x6a, 0x89, 0x31, 0xe9, 0xb3, 0xd7, 0xaf, 0x1a, 0x1f, 0x14, 0x95, 0xb6, 0x9b, 0x1c, 0x45, - 0x7f, 0xa2, 0x66, 0x94, 0xc2, 0x44, 0x19, 0x65, 0x24, 0xd1, 0x16, 0x73, 0x26, 0x5a, 0x42, 0xa6, - 0x4b, 0xb4, 0xb7, 0x61, 0x5e, 0xad, 0x3e, 0xa5, 0x09, 0xdf, 0xbb, 0x38, 0xe9, 0x96, 0x52, 0x9d, - 0x54, 0x4a, 0xfa, 0x2b, 0xb0, 0x4c, 0xa8, 0xdf, 0x6f, 0xd3, 0xbe, 0x8f, 0xed, 0xd8, 0x83, 0xc5, - 0x71, 0x9e, 0x4f, 0xaa, 0xc3, 0x41, 0x7d, 0xb9, 0x95, 0xb2, 0x8f, 0x52, 0xb1, 0x92, 0x9d, 0x33, - 0x21, 0x9f, 0xe6, 0xce, 0x99, 0x64, 0x75, 0x32, 0xef, 0xab, 0x9d, 0x73, 0xdc, 0x6b, 0x9f, 0x85, - 0xce, 0x79, 0x4c, 0x94, 0x8d, 0xed, 0x9c, 0x69, 0xca, 0xbb, 0x95, 0xa8, 0x6a, 0x87, 0x94, 0xcd, - 0xe4, 0xf3, 0x54, 0xae, 0x87, 0xab, 0x37, 0x61, 0xe6, 0x0e, 0xbf, 0x7e, 0x9f, 0xb0, 0xef, 0x0e, - 0x14, 0x15, 0x77, 0xf6, 0xe6, 0x82, 0x64, 0x35, 0x23, 0xbe, 0x09, 0x0a, 0xa8, 0x25, 0x3b, 0xed, - 0xb8, 0x55, 0x3e, 0xcd, 0x9d, 0x76, 0x5c, 0xce, 0x8c, 0xf8, 0xfc, 0xb3, 0xda, 0x69, 0xa7, 0xfa, - 0xfb, 0xe8, 0x3b, 0x6d, 0x36, 0x79, 0xb1, 0xbf, 0xa4, 0x67, 0xb5, 0x83, 0x09, 0x3d, 0x9c, 0xbc, - 0x6e, 0x04, 0x1b, 0x28, 0x82, 0x31, 0x3e, 0xd0, 0xa0, 0xa2, 0xba, 0x73, 0xaa, 0x46, 0xef, 0xa1, - 0x06, 0xa7, 0x7c, 0x85, 0x4c, 0xfc, 0xfd, 0xf8, 0x42, 0x9e, 0x70, 0x12, 0x97, 0xc7, 0x4f, 0x49, - 0x86, 0xa7, 0x52, 0x36, 0x51, 0x1a, 0x2b, 0xe3, 0x07, 0x1a, 0xa4, 0x01, 0xeb, 0x6e, 0xc6, 0xfb, - 0xc0, 0x66, 0x9e, 0xf7, 0x01, 0x19, 0xe9, 0x93, 0x3c, 0x0e, 0xfc, 0x33, 0x66, 0x51, 0xf1, 0x7b, - 0x89, 0xa9, 0x2c, 0xba, 0x0e, 0x25, 0x7e, 0x2c, 0x12, 0xd1, 0xb0, 0x65, 0x51, 0x0b, 0xf1, 0x1d, - 0xdd, 0x87, 0x4a, 0x54, 0x00, 0xd8, 0x3a, 0x2f, 0x18, 0x87, 0x5e, 0xf9, 0x46, 0xa5, 0x24, 0xf1, - 0xf3, 0x0f, 0xae, 0x5c, 0x4b, 0xa1, 0x88, 0x12, 0x1c, 0x8c, 0x9f, 0x14, 0x60, 0x21, 0xf1, 0x6a, - 0x9d, 0xfa, 0xd6, 0xae, 0x7d, 0xd2, 0x6f, 0xed, 0xdf, 0xd7, 0x60, 0xd9, 0x57, 0x05, 0x89, 0x47, - 0xdc, 0x66, 0xae, 0x87, 0x77, 0x11, 0x72, 0x6b, 0x92, 0xfd, 0x72, 0xda, 0x2e, 0x4a, 0xe5, 0x66, - 0xfc, 0x48, 0x83, 0x54, 0x70, 0xdd, 0xcb, 0x88, 0xba, 0x8b, 0xf9, 0x5e, 0xa5, 0xc4, 0xef, 0x02, - 0x26, 0x09, 0xbb, 0x3f, 0x14, 0xa1, 0x9a, 0xe5, 0x5a, 0xfd, 0x7b, 0x1a, 0xac, 0x08, 0x13, 0x26, - 0x72, 0xd5, 0x74, 0x8e, 0x0a, 0x47, 0x9c, 0x5b, 0x69, 0x34, 0x51, 0x3a, 0x2b, 0x55, 0x88, 0xf8, - 0xbc, 0x3b, 0xdd, 0x2f, 0x33, 0x46, 0x85, 0x50, 0x66, 0xe8, 0x74, 0x56, 0xca, 0x13, 0x5a, 0xe9, - 0xd0, 0x27, 0xb4, 0x6f, 0xc3, 0x8c, 0xcf, 0xa7, 0x50, 0xd6, 0x8c, 0x4d, 0xf0, 0x34, 0x9a, 0xfe, - 0x53, 0x9f, 0xa8, 0x40, 0x8a, 0x6f, 0x82, 0x02, 0xaa, 0xc6, 0xef, 0x34, 0x18, 0x89, 0xf6, 0xa9, - 0xd2, 0x85, 0x05, 0xd0, 0xfb, 0x1f, 0x0d, 0x1a, 0xb2, 0x88, 0x59, 0x31, 0x46, 0xd4, 0x34, 0x1f, - 0x3d, 0xa9, 0x1d, 0x7b, 0xfc, 0xa4, 0x76, 0xec, 0xa3, 0x27, 0xb5, 0x63, 0x0f, 0x87, 0x35, 0xed, - 0xd1, 0xb0, 0xa6, 0x3d, 0x1e, 0xd6, 0xb4, 0x8f, 0x86, 0x35, 0xed, 0x5f, 0xc3, 0x9a, 0xf6, 0xde, - 0xbf, 0x6b, 0xc7, 0xde, 0x5e, 0x1b, 0xf7, 0xa3, 0xc0, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x15, - 0x38, 0x05, 0x05, 0x33, 0x28, 0x00, 0x00, + // 2257 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x3a, 0xcd, 0x6f, 0x1b, 0xc7, + 0xf5, 0x5e, 0x92, 0xb6, 0xa8, 0x27, 0x8b, 0x92, 0xd6, 0x92, 0x4d, 0x3b, 0x0a, 0xa9, 0x2c, 0x7e, + 0x3f, 0x54, 0x68, 0x6d, 0x32, 0x96, 0x13, 0xc7, 0x48, 0xd3, 0x02, 0x5e, 0x2b, 0x76, 0x85, 0x26, + 0x8e, 0x32, 0x8c, 0x95, 0x38, 0xfd, 0xca, 0x8a, 0x3b, 0x96, 0xb6, 0x26, 0x77, 0xe9, 0x9d, 0xa1, + 0x62, 0xa3, 0x17, 0xa3, 0xe8, 0xd7, 0xa5, 0x40, 0x8a, 0x16, 0x45, 0x7b, 0xea, 0xa9, 0x28, 0x7a, + 0xe9, 0xa5, 0xfd, 0x0f, 0x82, 0x36, 0x06, 0x7a, 0x71, 0xd0, 0x02, 0x0d, 0x7a, 0x20, 0x6a, 0xf6, + 0xd8, 0x63, 0x6f, 0x39, 0x15, 0xf3, 0xb1, 0x1f, 0xb3, 0xdc, 0xa5, 0xb8, 0x6c, 0x23, 0x24, 0x27, + 0x72, 0x66, 0xde, 0xf7, 0x7b, 0xf3, 0xde, 0x9b, 0x99, 0x85, 0xf3, 0x77, 0xaf, 0x90, 0x86, 0xe3, + 0x35, 0xad, 0x9e, 0xd3, 0xf4, 0x31, 0xf1, 0xfa, 0x7e, 0x1b, 0x37, 0x0f, 0x2e, 0x5a, 0x9d, 0xde, + 0xbe, 0xb5, 0xd1, 0xdc, 0xc3, 0x2e, 0xf6, 0x2d, 0x8a, 0xed, 0x46, 0xcf, 0xf7, 0xa8, 0xa7, 0xaf, + 0x0a, 0xe8, 0x86, 0xd5, 0x73, 0x1a, 0x01, 0x74, 0x23, 0x80, 0x3e, 0x77, 0x61, 0xcf, 0xa1, 0xfb, + 0xfd, 0xdd, 0x46, 0xdb, 0xeb, 0x36, 0xf7, 0xbc, 0x3d, 0xaf, 0xc9, 0x91, 0x76, 0xfb, 0x77, 0xf8, + 0x88, 0x0f, 0xf8, 0x3f, 0x41, 0xec, 0x9c, 0x11, 0x63, 0xdd, 0xf6, 0x7c, 0xc6, 0x36, 0xc9, 0xf0, + 0xdc, 0x73, 0x11, 0x4c, 0xd7, 0x6a, 0xef, 0x3b, 0x2e, 0xf6, 0x1f, 0x34, 0x7b, 0x77, 0xf7, 0x54, + 0x79, 0xf3, 0x60, 0x91, 0x66, 0x17, 0x53, 0x2b, 0x8d, 0x57, 0x33, 0x0b, 0xcb, 0xef, 0xbb, 0xd4, + 0xe9, 0x8e, 0xb2, 0xb9, 0x7c, 0x18, 0x02, 0x69, 0xef, 0xe3, 0xae, 0x95, 0xc4, 0x33, 0x7e, 0x51, + 0x80, 0xc5, 0xab, 0x9d, 0x8e, 0xd7, 0xb6, 0xa8, 0xe3, 0xb9, 0x08, 0x93, 0x7e, 0x87, 0xea, 0x1e, + 0x2c, 0x04, 0xfa, 0x7c, 0xc5, 0x72, 0xed, 0x0e, 0x26, 0x55, 0x6d, 0xad, 0xb8, 0x3e, 0xb7, 0x71, + 0xbe, 0x31, 0xce, 0xe8, 0x0d, 0xa4, 0x20, 0x99, 0x67, 0x1e, 0x0d, 0xea, 0xc7, 0x86, 0x83, 0xfa, + 0x82, 0x3a, 0x4f, 0x50, 0x92, 0xba, 0xbe, 0x0b, 0x8b, 0xd6, 0x81, 0xe5, 0x74, 0xac, 0xdd, 0x0e, + 0x7e, 0xcd, 0xbd, 0xe9, 0xd9, 0x98, 0x54, 0x0b, 0x6b, 0xda, 0xfa, 0xdc, 0xc6, 0x5a, 0x9c, 0x23, + 0xf3, 0x4c, 0xe3, 0xe0, 0x62, 0x83, 0x01, 0xb4, 0x70, 0x07, 0xb7, 0xa9, 0xe7, 0x9b, 0xcb, 0xc3, + 0x41, 0x7d, 0xf1, 0x6a, 0x02, 0x1b, 0x8d, 0xd0, 0xd3, 0x9b, 0x30, 0x4b, 0xf6, 0x2d, 0x1f, 0xb3, + 0xb9, 0x6a, 0x71, 0x4d, 0x5b, 0x2f, 0x9b, 0x4b, 0x52, 0xc0, 0xd9, 0x56, 0xb0, 0x80, 0x22, 0x18, + 0xe3, 0x27, 0x1a, 0xac, 0x24, 0x4d, 0xf3, 0xaa, 0x67, 0xe3, 0x8e, 0x7e, 0x1f, 0x2a, 0xae, 0xd5, + 0xc5, 0x76, 0xa0, 0x17, 0x33, 0x0f, 0x13, 0xf6, 0xa5, 0xf1, 0xe6, 0xb9, 0xa9, 0xe0, 0x24, 0x49, + 0x9b, 0xfa, 0x70, 0x50, 0xaf, 0xa8, 0x30, 0x28, 0xc1, 0xc7, 0xf8, 0x5d, 0x01, 0x4e, 0x6f, 0xfa, + 0xce, 0x01, 0xf6, 0x47, 0x9c, 0xf6, 0x23, 0x0d, 0xce, 0x1c, 0x60, 0xd7, 0xf6, 0x7c, 0x84, 0xef, + 0xf5, 0x31, 0xa1, 0xdb, 0x96, 0x6f, 0x75, 0x31, 0xc5, 0x7e, 0x20, 0xde, 0x85, 0x98, 0x78, 0x61, + 0x90, 0x34, 0x7a, 0x77, 0xf7, 0x1a, 0x32, 0x48, 0x1a, 0xc8, 0x7a, 0xf7, 0xe5, 0xfb, 0x14, 0xbb, + 0xc4, 0xf1, 0x5c, 0xb3, 0x2e, 0xad, 0x73, 0x66, 0x27, 0x9d, 0x2a, 0xca, 0x62, 0xc7, 0x44, 0x59, + 0xb1, 0xd2, 0x2c, 0x27, 0x9d, 0x7a, 0x69, 0xbc, 0x9d, 0x52, 0x8d, 0x6e, 0x3e, 0x2d, 0xc5, 0x49, + 0xf7, 0x09, 0x4a, 0x67, 0x68, 0xfc, 0xbc, 0x00, 0x15, 0x61, 0x30, 0x29, 0x26, 0xd1, 0x37, 0x00, + 0x6c, 0x3e, 0xc3, 0x6c, 0xcd, 0x4d, 0x33, 0x6b, 0xea, 0x92, 0x38, 0x6c, 0x86, 0x2b, 0x28, 0x06, + 0xa5, 0x13, 0x58, 0x14, 0xca, 0xc6, 0x8c, 0x5a, 0x98, 0xc6, 0xa8, 0x55, 0xc9, 0x68, 0x71, 0x27, + 0x41, 0x0e, 0x8d, 0x30, 0xd0, 0xbf, 0x06, 0x65, 0x5f, 0x0a, 0x5d, 0x2d, 0xf2, 0xfd, 0x77, 0x61, + 0xb2, 0xfd, 0x27, 0x55, 0x35, 0x17, 0x25, 0xb3, 0x72, 0xa0, 0x3b, 0x0a, 0x09, 0x1a, 0x26, 0xd4, + 0xc6, 0xc7, 0xa3, 0xbe, 0x06, 0x25, 0x37, 0xb2, 0xd0, 0x49, 0x49, 0xab, 0xc4, 0x6d, 0xc3, 0x57, + 0x8c, 0x3f, 0x69, 0x70, 0x26, 0x41, 0x84, 0x52, 0xdf, 0xd9, 0xed, 0x53, 0x7c, 0x38, 0x36, 0x8b, + 0x92, 0x8a, 0x15, 0xc0, 0xef, 0x58, 0x9d, 0x3e, 0x96, 0x26, 0x7d, 0x31, 0xd7, 0x36, 0x52, 0x28, + 0x98, 0xff, 0x27, 0x19, 0xad, 0x8e, 0x83, 0x42, 0x09, 0xbe, 0xc6, 0xbf, 0x8a, 0x30, 0x16, 0x41, + 0xff, 0x06, 0x94, 0xef, 0xf5, 0x2d, 0x97, 0x3a, 0xf4, 0x41, 0xf5, 0x04, 0x17, 0xb2, 0x91, 0xe9, + 0x77, 0x45, 0xea, 0xd7, 0x25, 0x96, 0xb9, 0x34, 0x1c, 0xd4, 0xe7, 0x83, 0x91, 0x90, 0x22, 0x24, + 0xa9, 0x3f, 0x03, 0xa5, 0x5d, 0xcf, 0x13, 0xdb, 0xa3, 0x6c, 0xce, 0xb3, 0x94, 0x64, 0x7a, 0x5e, + 0x47, 0x80, 0xf1, 0x25, 0xbd, 0x06, 0x45, 0xc7, 0xa5, 0xd5, 0x99, 0x35, 0x6d, 0xbd, 0x68, 0x9e, + 0x64, 0x4e, 0xdd, 0x72, 0xa9, 0x00, 0x60, 0x0b, 0x7a, 0x1b, 0xca, 0x8e, 0x4b, 0x5b, 0x1d, 0xa7, + 0x8d, 0xab, 0x65, 0x2e, 0xe1, 0x73, 0x79, 0xcc, 0xb8, 0x25, 0x71, 0x85, 0x9c, 0xc1, 0x48, 0xca, + 0x19, 0x10, 0xd6, 0x3f, 0x07, 0x27, 0x08, 0xf5, 0x1d, 0x77, 0xaf, 0x7a, 0x9c, 0xbb, 0x75, 0x61, + 0x38, 0xa8, 0xcf, 0xb5, 0xf8, 0x8c, 0x00, 0x95, 0xcb, 0xba, 0x07, 0x73, 0xe2, 0x9f, 0x10, 0x68, + 0x96, 0x0b, 0xf4, 0x42, 0x1e, 0x81, 0x5a, 0x11, 0xba, 0x48, 0xf1, 0xb1, 0x09, 0xc1, 0x2b, 0xce, + 0x41, 0xff, 0x3c, 0xcc, 0x1c, 0x60, 0x9f, 0x6d, 0xb1, 0x2a, 0x70, 0xd1, 0x16, 0x87, 0x83, 0xfa, + 0xc9, 0x1d, 0x31, 0x25, 0xe0, 0x03, 0x00, 0x63, 0x13, 0x96, 0x55, 0x5e, 0xd7, 0x9d, 0x0e, 0xc5, + 0xbe, 0x7e, 0x1e, 0xca, 0x44, 0x56, 0x15, 0x19, 0xb6, 0xe1, 0x06, 0x0a, 0xaa, 0x0d, 0x0a, 0x21, + 0x8c, 0x5f, 0x6b, 0x70, 0x3a, 0x69, 0x43, 0x42, 0x2d, 0xb7, 0x3d, 0x49, 0xec, 0x3b, 0x00, 0x61, + 0x08, 0xb2, 0x4c, 0xc2, 0x36, 0xf7, 0xf3, 0x53, 0x85, 0x7d, 0x94, 0xba, 0xc2, 0x29, 0x82, 0x62, + 0xc4, 0x8d, 0xcb, 0xa3, 0x62, 0x4a, 0x6f, 0xae, 0x42, 0xc9, 0x71, 0xa9, 0xa8, 0xed, 0x45, 0xb3, + 0xcc, 0x44, 0xdc, 0x72, 0x29, 0x41, 0x7c, 0xd6, 0x78, 0x19, 0x56, 0x12, 0xc5, 0x48, 0xa4, 0x8e, + 0x9c, 0x66, 0x7a, 0x38, 0x92, 0x23, 0xc2, 0x3f, 0x3a, 0x86, 0x59, 0x47, 0xda, 0x2c, 0xe8, 0x30, + 0x72, 0x06, 0xad, 0x40, 0x8e, 0x0a, 0x79, 0x30, 0x43, 0x50, 0x44, 0xd9, 0x30, 0xe1, 0x6c, 0x66, + 0x6c, 0xe9, 0xff, 0x0f, 0x33, 0x22, 0x8e, 0x84, 0x04, 0xb3, 0xe6, 0xdc, 0x70, 0x50, 0x9f, 0x11, + 0x10, 0x04, 0x05, 0x6b, 0xc6, 0x0f, 0x34, 0x58, 0x62, 0x7d, 0x44, 0x40, 0x43, 0x34, 0x02, 0xf7, + 0x32, 0x1a, 0x81, 0x5c, 0xae, 0x0c, 0xff, 0x4c, 0xd4, 0x01, 0x7c, 0x58, 0x50, 0x05, 0x11, 0x5a, + 0xbc, 0x03, 0x65, 0xd6, 0x4a, 0xda, 0x16, 0xb5, 0xa4, 0x08, 0xcf, 0x8e, 0xcb, 0x4f, 0xa4, 0xc1, + 0xa0, 0x59, 0x2b, 0xf5, 0xda, 0xee, 0xb7, 0x71, 0x9b, 0xbe, 0x8a, 0xa9, 0x15, 0x05, 0x52, 0x34, + 0x87, 0x42, 0xaa, 0xcc, 0xeb, 0xae, 0x67, 0x63, 0x5e, 0x33, 0x0b, 0xaa, 0xd7, 0x6f, 0xca, 0x79, + 0x14, 0x42, 0x24, 0x6a, 0x6c, 0x71, 0xa2, 0x1a, 0x7b, 0x1f, 0x96, 0xdc, 0xa4, 0x85, 0xab, 0x25, + 0xae, 0x4c, 0xf3, 0x10, 0x7b, 0x26, 0xd1, 0xcc, 0xb3, 0x92, 0xd7, 0xa8, 0xcf, 0xd0, 0x28, 0x13, + 0xe3, 0xcf, 0x1a, 0xac, 0x8c, 0xd8, 0xf4, 0x15, 0x87, 0x50, 0xfd, 0xeb, 0x23, 0x76, 0x6d, 0x4c, + 0x66, 0x57, 0x86, 0xcd, 0xad, 0x1a, 0x5a, 0x29, 0x98, 0x89, 0xd9, 0xf4, 0x0d, 0x38, 0xee, 0x50, + 0xdc, 0x0d, 0x12, 0x40, 0x0e, 0x2d, 0x45, 0x5e, 0x9c, 0x97, 0xb4, 0x8f, 0x6f, 0x31, 0x2a, 0x48, + 0x10, 0x33, 0xfe, 0x50, 0x80, 0xe5, 0x6d, 0xcf, 0x6e, 0xb5, 0xf7, 0xb1, 0xdd, 0xef, 0x38, 0xee, + 0xde, 0x35, 0xcf, 0xa5, 0xf8, 0x3e, 0x3d, 0x82, 0x20, 0x79, 0x0b, 0x4a, 0xa4, 0x87, 0xdb, 0xb2, + 0x8e, 0x5f, 0x1e, 0xaf, 0x4f, 0x9a, 0x8c, 0xad, 0x1e, 0x6e, 0x47, 0x09, 0x93, 0x8d, 0x10, 0xa7, + 0xa8, 0xbf, 0xc3, 0x2a, 0x8f, 0x45, 0xfb, 0x84, 0x07, 0xd3, 0xdc, 0xc6, 0x95, 0x29, 0x68, 0x73, + 0x7c, 0xb3, 0x22, 0xa9, 0x9f, 0x10, 0x63, 0x24, 0xe9, 0x1a, 0x1f, 0x6a, 0x50, 0x4d, 0x43, 0x3b, + 0x82, 0x38, 0x78, 0x53, 0x8d, 0x83, 0x8d, 0xfc, 0xba, 0x65, 0x84, 0xc2, 0x7b, 0x19, 0x3a, 0x31, + 0xc3, 0xea, 0x57, 0xe0, 0xa4, 0xc8, 0xd2, 0xd8, 0x66, 0xa1, 0x25, 0x73, 0xf9, 0xb2, 0x24, 0x74, + 0xb2, 0x15, 0x5b, 0x43, 0x0a, 0xa4, 0xfe, 0x22, 0x54, 0x7a, 0x1e, 0xc5, 0x2e, 0x75, 0xac, 0x4e, + 0x70, 0x58, 0x63, 0xa9, 0x93, 0xe7, 0xaf, 0x6d, 0x65, 0x05, 0x25, 0x20, 0x8d, 0x5f, 0x6a, 0x70, + 0x2e, 0xdb, 0x3b, 0xfa, 0x77, 0xa0, 0x12, 0x68, 0x7c, 0xad, 0x63, 0x39, 0xdd, 0xa0, 0x2e, 0x7c, + 0x71, 0xb2, 0xce, 0x97, 0xe3, 0x44, 0xb4, 0xa5, 0xcb, 0x4f, 0x4b, 0x9d, 0x2a, 0x0a, 0x18, 0x41, + 0x09, 0x56, 0xc6, 0xaf, 0x0a, 0x30, 0xaf, 0x80, 0x1c, 0xc1, 0x96, 0x79, 0x5d, 0xd9, 0x32, 0xcd, + 0x3c, 0x6a, 0x66, 0xed, 0x95, 0xdb, 0x89, 0xbd, 0x72, 0x31, 0x0f, 0xd1, 0xf1, 0x9b, 0x64, 0xa8, + 0x41, 0x4d, 0x81, 0xbf, 0xe6, 0xb9, 0xa4, 0xdf, 0x65, 0xa7, 0xab, 0x3b, 0xd8, 0xc7, 0xac, 0xf9, + 0x39, 0x0f, 0x65, 0xab, 0xe7, 0xdc, 0xf0, 0xbd, 0x7e, 0x2f, 0xd9, 0x1e, 0x5c, 0xdd, 0xde, 0xe2, + 0xf3, 0x28, 0x84, 0x60, 0xd0, 0x81, 0x44, 0xb2, 0x4c, 0xc4, 0x0e, 0x2d, 0xf2, 0x34, 0x13, 0x42, + 0x84, 0x8d, 0x55, 0x29, 0xb3, 0xb1, 0x32, 0xa1, 0xd8, 0x77, 0x6c, 0xd9, 0x9e, 0x3e, 0x2b, 0x01, + 0x8a, 0xb7, 0xb6, 0x36, 0x3f, 0x1e, 0xd4, 0x9f, 0xc9, 0xba, 0x23, 0xa1, 0x0f, 0x7a, 0x98, 0x34, + 0x6e, 0x6d, 0x6d, 0x22, 0x86, 0x6c, 0xbc, 0xaf, 0xc1, 0x92, 0xa2, 0xe4, 0x11, 0xa4, 0x80, 0x6d, + 0x35, 0x05, 0x7c, 0x21, 0x87, 0xcb, 0x32, 0xf6, 0xfe, 0x4f, 0x8b, 0x70, 0x46, 0x81, 0x8b, 0x9d, + 0x2c, 0x3f, 0xf9, 0xb0, 0x7e, 0x17, 0xe6, 0xc3, 0xab, 0xa6, 0xeb, 0xbe, 0xd7, 0x95, 0xf1, 0xfd, + 0xe5, 0x1c, 0x7a, 0xc5, 0xce, 0xc6, 0x41, 0x70, 0x89, 0xd3, 0xc9, 0x8d, 0x38, 0x61, 0xa4, 0xf2, + 0xc9, 0x7d, 0xcd, 0xa3, 0x77, 0xa0, 0x62, 0x2b, 0x17, 0x04, 0xd5, 0xd2, 0x24, 0x77, 0x5d, 0xea, + 0xa5, 0x42, 0x94, 0x62, 0xd4, 0x79, 0x94, 0xa0, 0x6d, 0xfc, 0x4d, 0x83, 0xa7, 0x32, 0xb4, 0x3c, + 0x82, 0x28, 0x7b, 0x5b, 0x8d, 0xb2, 0xe7, 0xa7, 0xf2, 0x46, 0x46, 0xbc, 0xfd, 0x4c, 0x83, 0xb5, + 0xc3, 0xfc, 0x97, 0x33, 0x39, 0xac, 0x41, 0xe9, 0xae, 0xe3, 0xda, 0xb2, 0xdf, 0x0c, 0xb7, 0xfb, + 0x57, 0x1d, 0xd7, 0x46, 0x7c, 0x25, 0x4c, 0x08, 0xc5, 0xcc, 0x3b, 0x8a, 0x87, 0x1a, 0x3c, 0x3d, + 0xb6, 0x3a, 0x4c, 0x70, 0x5a, 0xfb, 0x12, 0x2c, 0xf4, 0x5d, 0xd2, 0x77, 0x28, 0x0b, 0x98, 0x78, + 0xc1, 0x3b, 0x35, 0x1c, 0xd4, 0x17, 0x6e, 0xa9, 0x4b, 0x28, 0x09, 0x6b, 0xfc, 0xa6, 0x90, 0xc8, + 0x27, 0xbc, 0xfc, 0xde, 0x80, 0xa5, 0x58, 0xf9, 0x21, 0x24, 0x76, 0x1b, 0x15, 0x76, 0xaf, 0x28, + 0x09, 0x80, 0x46, 0x71, 0xd8, 0x56, 0xeb, 0xc5, 0x4d, 0xfd, 0xbf, 0xdc, 0x6a, 0xca, 0x02, 0x52, + 0xf9, 0xe8, 0xdb, 0x50, 0x89, 0x2e, 0xdd, 0x58, 0x27, 0x2d, 0xdd, 0xb0, 0x1e, 0xec, 0x85, 0xab, + 0xca, 0xea, 0xc7, 0x23, 0x33, 0x28, 0x81, 0x6f, 0xfc, 0xbb, 0x00, 0xa7, 0x52, 0xca, 0xd1, 0x54, + 0x57, 0x76, 0xdf, 0x04, 0x88, 0xa8, 0x4b, 0x9b, 0x34, 0xf2, 0x5d, 0x3c, 0x9a, 0x15, 0x7e, 0xae, + 0x8e, 0x66, 0x63, 0x14, 0x75, 0x02, 0x73, 0x3e, 0x26, 0xd8, 0x3f, 0xc0, 0xf6, 0x75, 0xcf, 0x97, + 0x17, 0x74, 0x2f, 0xe5, 0x30, 0xfa, 0x48, 0xe9, 0x34, 0x4f, 0x49, 0x95, 0xe6, 0x50, 0x44, 0x18, + 0xc5, 0xb9, 0xe8, 0x2d, 0x58, 0xb1, 0x71, 0xfc, 0xa6, 0x93, 0xa7, 0x15, 0x6c, 0xf3, 0x8a, 0x58, + 0x8e, 0xee, 0x48, 0x37, 0xd3, 0x80, 0x50, 0x3a, 0xae, 0xf1, 0x57, 0x0d, 0x56, 0x14, 0xc9, 0xde, + 0xc0, 0xdd, 0x5e, 0xc7, 0xa2, 0x47, 0x71, 0xac, 0xbc, 0xad, 0xb4, 0x3f, 0x2f, 0xe4, 0x30, 0x5f, + 0x20, 0x64, 0x56, 0x1b, 0x64, 0xfc, 0x45, 0x83, 0xb3, 0xa9, 0x18, 0x47, 0x90, 0x68, 0xdf, 0x52, + 0x13, 0xed, 0xa5, 0x29, 0xf4, 0xca, 0x48, 0xb3, 0x8f, 0xb3, 0xb4, 0x6a, 0x89, 0x63, 0xd2, 0x67, + 0xaf, 0x5f, 0x35, 0x3e, 0x28, 0x2a, 0x6d, 0x37, 0x39, 0x8a, 0xfe, 0x44, 0xcd, 0x28, 0x85, 0x89, + 0x32, 0xca, 0x48, 0xa2, 0x2d, 0xe6, 0x4c, 0xb4, 0x84, 0x4c, 0x97, 0x68, 0x6f, 0xc3, 0xbc, 0x5a, + 0x7d, 0x4a, 0x13, 0xbe, 0x8d, 0x71, 0xd2, 0x2d, 0xa5, 0x3a, 0xa9, 0x94, 0xf4, 0x57, 0x60, 0x99, + 0x50, 0xbf, 0xdf, 0xa6, 0x7d, 0x1f, 0xdb, 0xb1, 0xc7, 0x8d, 0xe3, 0x3c, 0x9f, 0x54, 0x87, 0x83, + 0xfa, 0x72, 0x2b, 0x65, 0x1d, 0xa5, 0x62, 0x25, 0x3b, 0x67, 0x42, 0x3e, 0xcd, 0x9d, 0x33, 0xc9, + 0xea, 0x64, 0xde, 0x57, 0x3b, 0xe7, 0xb8, 0xd7, 0x3e, 0x0b, 0x9d, 0xf3, 0x98, 0x28, 0x1b, 0xdb, + 0x39, 0xd3, 0x94, 0x37, 0x2e, 0x51, 0xd5, 0x0e, 0x29, 0x9b, 0xc9, 0xa7, 0xac, 0x5c, 0x8f, 0x5c, + 0x6f, 0xc2, 0xcc, 0x1d, 0x7e, 0xfd, 0x3e, 0x61, 0xdf, 0x1d, 0x28, 0x2a, 0xee, 0xec, 0xcd, 0x05, + 0xc9, 0x6a, 0x46, 0x8c, 0x09, 0x0a, 0xa8, 0x25, 0x3b, 0xed, 0xb8, 0x55, 0x3e, 0xcd, 0x9d, 0x76, + 0x5c, 0xce, 0x8c, 0xf8, 0xfc, 0xa3, 0xda, 0x69, 0xa7, 0xfa, 0xfb, 0xe8, 0x3b, 0x6d, 0x76, 0xf2, + 0x62, 0xbf, 0xa4, 0x67, 0xb5, 0x83, 0x13, 0x7a, 0x78, 0xf2, 0xba, 0x19, 0x2c, 0xa0, 0x08, 0xc6, + 0xf8, 0x40, 0x83, 0x8a, 0xea, 0xce, 0xa9, 0x1a, 0xbd, 0x87, 0x1a, 0x9c, 0xf2, 0x15, 0x32, 0xf1, + 0xb7, 0xe6, 0x8b, 0x79, 0xc2, 0x49, 0x5c, 0x1e, 0x3f, 0x25, 0x19, 0x9e, 0x4a, 0x59, 0x44, 0x69, + 0xac, 0x8c, 0xef, 0x6b, 0x90, 0x06, 0xac, 0xbb, 0x19, 0xef, 0x03, 0x1b, 0x79, 0xde, 0x07, 0x64, + 0xa4, 0x4f, 0xf2, 0x38, 0xf0, 0xf7, 0x98, 0x45, 0xc5, 0xb7, 0x15, 0x53, 0x59, 0x74, 0x0d, 0x4a, + 0x7c, 0x5b, 0x24, 0xa2, 0x61, 0xd3, 0xa2, 0x16, 0xe2, 0x2b, 0xba, 0x0f, 0x95, 0xa8, 0x00, 0xb0, + 0x79, 0x5e, 0x30, 0x0e, 0xbd, 0xf2, 0x8d, 0x4a, 0x49, 0xe2, 0x53, 0x11, 0xae, 0x5c, 0x4b, 0xa1, + 0x88, 0x12, 0x1c, 0x8c, 0x1f, 0x17, 0x60, 0x21, 0xf1, 0xc2, 0x9d, 0xfa, 0x2e, 0xaf, 0x7d, 0xd2, + 0xef, 0xf2, 0xdf, 0xd3, 0x60, 0xd9, 0x57, 0x05, 0x89, 0x47, 0xdc, 0x46, 0xae, 0x47, 0x7a, 0x11, + 0x72, 0xab, 0x92, 0xfd, 0x72, 0xda, 0x2a, 0x4a, 0xe5, 0x66, 0xfc, 0x50, 0x83, 0x54, 0x70, 0xdd, + 0xcb, 0x88, 0xba, 0x4b, 0xf9, 0x5e, 0xa5, 0xc4, 0x37, 0x04, 0x93, 0x84, 0xdd, 0xef, 0x8b, 0x50, + 0xcd, 0x72, 0xad, 0xfe, 0x5d, 0x0d, 0x56, 0x84, 0x09, 0x13, 0xb9, 0x6a, 0x3a, 0x47, 0x85, 0x47, + 0x9c, 0x9d, 0x34, 0x9a, 0x28, 0x9d, 0x95, 0x2a, 0x44, 0xfc, 0xbc, 0x3b, 0xdd, 0x57, 0x1c, 0xa3, + 0x42, 0x28, 0x67, 0xe8, 0x74, 0x56, 0xca, 0x13, 0x5a, 0xe9, 0xd0, 0x27, 0xb4, 0x6f, 0xc1, 0x8c, + 0xcf, 0x4f, 0xa1, 0xac, 0x19, 0x9b, 0xe0, 0x69, 0x34, 0xfd, 0xb3, 0xa0, 0xa8, 0x40, 0x8a, 0x31, + 0x41, 0x01, 0x55, 0xe3, 0xb7, 0x1a, 0x8c, 0x44, 0xfb, 0x54, 0xe9, 0xc2, 0x02, 0xe8, 0xfd, 0x97, + 0x06, 0x0d, 0x59, 0xc4, 0xac, 0x18, 0x23, 0x6a, 0x9a, 0x8f, 0x9e, 0xd4, 0x8e, 0x3d, 0x7e, 0x52, + 0x3b, 0xf6, 0xd1, 0x93, 0xda, 0xb1, 0x87, 0xc3, 0x9a, 0xf6, 0x68, 0x58, 0xd3, 0x1e, 0x0f, 0x6b, + 0xda, 0x47, 0xc3, 0x9a, 0xf6, 0x8f, 0x61, 0x4d, 0x7b, 0xef, 0x9f, 0xb5, 0x63, 0x6f, 0xaf, 0x8e, + 0xfb, 0x80, 0xf0, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x03, 0x20, 0x09, 0x51, 0x5f, 0x28, 0x00, + 0x00, } func (m *AllocationResult) Marshal() (dAtA []byte, err error) { @@ -1747,6 +1749,13 @@ func (m *NamedResourcesAttributeValue) MarshalToSizedBuffer(dAtA []byte) (int, e _ = i var l int _ = l + if m.VersionValue != nil { + i -= len(*m.VersionValue) + copy(dAtA[i:], *m.VersionValue) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.VersionValue))) + i-- + dAtA[i] = 0x52 + } if m.StringSliceValue != nil { { size, err := m.StringSliceValue.MarshalToSizedBuffer(dAtA[:i]) @@ -3592,6 +3601,10 @@ func (m *NamedResourcesAttributeValue) Size() (n int) { l = m.StringSliceValue.Size() n += 1 + l + sovGenerated(uint64(l)) } + if m.VersionValue != nil { + l = len(*m.VersionValue) + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -4289,6 +4302,7 @@ func (this *NamedResourcesAttributeValue) String() string { `IntValue:` + valueToStringGenerated(this.IntValue) + `,`, `IntSliceValue:` + strings.Replace(this.IntSliceValue.String(), "NamedResourcesIntSlice", "NamedResourcesIntSlice", 1) + `,`, `StringSliceValue:` + strings.Replace(this.StringSliceValue.String(), "NamedResourcesStringSlice", "NamedResourcesStringSlice", 1) + `,`, + `VersionValue:` + valueToStringGenerated(this.VersionValue) + `,`, `}`, }, "") return s @@ -5695,6 +5709,39 @@ func (m *NamedResourcesAttributeValue) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VersionValue", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.VersionValue = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/staging/src/k8s.io/api/resource/v1alpha2/generated.proto b/staging/src/k8s.io/api/resource/v1alpha2/generated.proto index e5ddc261137..210bce01bc0 100644 --- a/staging/src/k8s.io/api/resource/v1alpha2/generated.proto +++ b/staging/src/k8s.io/api/resource/v1alpha2/generated.proto @@ -134,6 +134,9 @@ message NamedResourcesAttributeValue { // StringSliceValue is an array of strings. optional NamedResourcesStringSlice stringSlice = 9; + + // VersionValue is a semantic version according to semver.org spec 2.0.0. + optional string version = 10; } // NamedResourcesFilter is used in ResourceFilterModel. diff --git a/staging/src/k8s.io/api/resource/v1alpha2/namedresources.go b/staging/src/k8s.io/api/resource/v1alpha2/namedresources.go index 1af5c7d234e..e28f6cc4331 100644 --- a/staging/src/k8s.io/api/resource/v1alpha2/namedresources.go +++ b/staging/src/k8s.io/api/resource/v1alpha2/namedresources.go @@ -70,7 +70,8 @@ type NamedResourcesAttributeValue struct { StringValue *string `json:"string,omitempty" protobuf:"bytes,5,opt,name=string"` // StringSliceValue is an array of strings. StringSliceValue *NamedResourcesStringSlice `json:"stringSlice,omitempty" protobuf:"bytes,9,rep,name=stringSlice"` - // TODO: VersionValue *SemVersion `json:"version,omitempty" protobuf:"bytes,7,opt,name=version"` + // VersionValue is a semantic version according to semver.org spec 2.0.0. + VersionValue *string `json:"version,omitempty" protobuf:"bytes,10,opt,name=version"` } // NamedResourcesIntSlice contains a slice of 64-bit integers. @@ -89,17 +90,6 @@ type NamedResourcesStringSlice struct { Strings []string `json:"strings" protobuf:"bytes,1,opt,name=strings"` } -// TODO -// -// A wrapper around https://pkg.go.dev/github.com/blang/semver/v4#Version which -// is encoded as a string. During decoding, it validates that the string -// can be parsed using tolerant parsing (currently trims spaces, removes a "v" prefix, -// adds a 0 patch number to versions with only major and minor components specified, -// and removes leading 0s). -// type NamedResourcesSemVersion struct { -// semver.Version -//} - // NamedResourcesRequest is used in ResourceRequestModel. type NamedResourcesRequest struct { // Selector is a CEL expression which must evaluate to true if a diff --git a/staging/src/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go b/staging/src/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go index f5d3a01bb1b..89539070a2b 100644 --- a/staging/src/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go @@ -183,6 +183,11 @@ func (in *NamedResourcesAttributeValue) DeepCopyInto(out *NamedResourcesAttribut *out = new(NamedResourcesStringSlice) (*in).DeepCopyInto(*out) } + if in.VersionValue != nil { + in, out := &in.VersionValue, &out.VersionValue + *out = new(string) + **out = **in + } return } diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.json b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.json index fbd9cd70f09..218ee89bc47 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.json +++ b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.json @@ -65,7 +65,8 @@ "strings": [ "stringsValue" ] - } + }, + "version": "versionValue" } ] } diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.pb b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.pb index b1efc51b7e79e20c6da053e22873f060efac0d89..ba0323b80fa7b3426f3676f1054aeb4cc7d06e46 100644 GIT binary patch delta 67 zcmZo?naVQ3gz@%9(^f|LFs=};ATG|l#N5=d#GKMpAy;IM#pIieT0%iQWvNBQnfZBO J6;cdJ3;@Dw6sZ6J delta 53 ycmbQr(#|r$gz@Y~(^f`#4=y(@7cS1c#N5=d#GKMpA#-Go*5sRvS}alwN(=z0SPtd@ diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.yaml b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.yaml index a47bdb4a409..a1c13f739c8 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.yaml @@ -47,5 +47,6 @@ namedResources: stringSlice: strings: - stringsValue + version: versionValue name: nameValue nodeName: nodeNameValue diff --git a/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go b/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go index 93121ac8443..396ecf04a0c 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go @@ -12001,6 +12001,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: stringSlice type: namedType: io.k8s.api.resource.v1alpha2.NamedResourcesStringSlice + - name: version + type: + scalar: string - name: io.k8s.api.resource.v1alpha2.NamedResourcesFilter map: fields: diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesattribute.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesattribute.go index 43cd9044b3a..d9545d054f3 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesattribute.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesattribute.go @@ -90,3 +90,11 @@ func (b *NamedResourcesAttributeApplyConfiguration) WithStringSliceValue(value * b.StringSliceValue = value return b } + +// WithVersionValue sets the VersionValue field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the VersionValue field is set to the value of the last call. +func (b *NamedResourcesAttributeApplyConfiguration) WithVersionValue(value string) *NamedResourcesAttributeApplyConfiguration { + b.VersionValue = &value + return b +} diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesattributevalue.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesattributevalue.go index ad2c7e185c1..e0b19650a92 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesattributevalue.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/namedresourcesattributevalue.go @@ -31,6 +31,7 @@ type NamedResourcesAttributeValueApplyConfiguration struct { IntSliceValue *NamedResourcesIntSliceApplyConfiguration `json:"intSlice,omitempty"` StringValue *string `json:"string,omitempty"` StringSliceValue *NamedResourcesStringSliceApplyConfiguration `json:"stringSlice,omitempty"` + VersionValue *string `json:"version,omitempty"` } // NamedResourcesAttributeValueApplyConfiguration constructs an declarative configuration of the NamedResourcesAttributeValue type for use with @@ -86,3 +87,11 @@ func (b *NamedResourcesAttributeValueApplyConfiguration) WithStringSliceValue(va b.StringSliceValue = value return b } + +// WithVersionValue sets the VersionValue field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the VersionValue field is set to the value of the last call. +func (b *NamedResourcesAttributeValueApplyConfiguration) WithVersionValue(value string) *NamedResourcesAttributeValueApplyConfiguration { + b.VersionValue = &value + return b +} diff --git a/staging/src/k8s.io/dynamic-resource-allocation/go.mod b/staging/src/k8s.io/dynamic-resource-allocation/go.mod index 0881b6010d3..d800a1a80f3 100644 --- a/staging/src/k8s.io/dynamic-resource-allocation/go.mod +++ b/staging/src/k8s.io/dynamic-resource-allocation/go.mod @@ -5,6 +5,7 @@ module k8s.io/dynamic-resource-allocation go 1.22.0 require ( + github.com/blang/semver/v4 v4.0.0 github.com/go-logr/logr v1.4.1 github.com/google/cel-go v0.17.8 github.com/google/go-cmp v0.6.0 diff --git a/staging/src/k8s.io/dynamic-resource-allocation/go.sum b/staging/src/k8s.io/dynamic-resource-allocation/go.sum index 2c0c8948be5..e846de407b6 100644 --- a/staging/src/k8s.io/dynamic-resource-allocation/go.sum +++ b/staging/src/k8s.io/dynamic-resource-allocation/go.sum @@ -6,6 +6,7 @@ github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/g github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= diff --git a/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/compile.go b/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/compile.go index 8cbc7985559..b61f1eacd4c 100644 --- a/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/compile.go +++ b/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/compile.go @@ -21,6 +21,7 @@ import ( "fmt" "reflect" + "github.com/blang/semver/v4" "github.com/google/cel-go/cel" "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/traits" @@ -105,43 +106,54 @@ var valueTypes = map[string]struct { celType *cel.Type // get returns nil if the attribute doesn't have the type, otherwise // the value of that type. - get func(attr resourceapi.NamedResourcesAttribute) any + get func(attr resourceapi.NamedResourcesAttribute) (any, error) }{ - "quantity": {apiservercel.QuantityType, func(attr resourceapi.NamedResourcesAttribute) any { + "quantity": {apiservercel.QuantityType, func(attr resourceapi.NamedResourcesAttribute) (any, error) { if attr.QuantityValue == nil { - return nil + return nil, nil } - return apiservercel.Quantity{Quantity: attr.QuantityValue} + return apiservercel.Quantity{Quantity: attr.QuantityValue}, nil }}, - "bool": {cel.BoolType, func(attr resourceapi.NamedResourcesAttribute) any { + "bool": {cel.BoolType, func(attr resourceapi.NamedResourcesAttribute) (any, error) { if attr.BoolValue == nil { - return nil + return nil, nil } - return *attr.BoolValue + return *attr.BoolValue, nil }}, - "int": {cel.IntType, func(attr resourceapi.NamedResourcesAttribute) any { + "int": {cel.IntType, func(attr resourceapi.NamedResourcesAttribute) (any, error) { if attr.IntValue == nil { - return nil + return nil, nil } - return *attr.IntValue + return *attr.IntValue, nil }}, - "intslice": {types.NewListType(cel.IntType), func(attr resourceapi.NamedResourcesAttribute) any { + "intslice": {types.NewListType(cel.IntType), func(attr resourceapi.NamedResourcesAttribute) (any, error) { if attr.IntSliceValue == nil { - return nil + return nil, nil } - return attr.IntSliceValue.Ints + return attr.IntSliceValue.Ints, nil }}, - "string": {cel.StringType, func(attr resourceapi.NamedResourcesAttribute) any { + "string": {cel.StringType, func(attr resourceapi.NamedResourcesAttribute) (any, error) { if attr.StringValue == nil { - return nil + return nil, nil } - return *attr.StringValue + return *attr.StringValue, nil }}, - "stringslice": {types.NewListType(cel.StringType), func(attr resourceapi.NamedResourcesAttribute) any { + "stringslice": {types.NewListType(cel.StringType), func(attr resourceapi.NamedResourcesAttribute) (any, error) { if attr.StringSliceValue == nil { - return nil + return nil, nil } - return attr.StringSliceValue.Strings + return attr.StringSliceValue.Strings, nil + }}, + "version": {SemverType, func(attr resourceapi.NamedResourcesAttribute) (any, error) { + if attr.VersionValue == nil { + return nil, nil + } + v, err := semver.Parse(*attr.VersionValue) + if err != nil { + return nil, fmt.Errorf("parse semantic version: %v", err) + } + + return Semver{Version: v}, nil }}, } @@ -150,7 +162,11 @@ var boolType = reflect.TypeOf(true) func (c CompilationResult) Evaluate(ctx context.Context, attributes []resourceapi.NamedResourcesAttribute) (bool, error) { variables := make(map[string]any, len(valueTypes)) for name, valueType := range valueTypes { - variables[attributesVarPrefix+name] = buildValueMapper(c.Environment.CELTypeAdapter(), attributes, valueType.get) + m, err := buildValueMapper(c.Environment.CELTypeAdapter(), attributes, valueType.get) + if err != nil { + return false, fmt.Errorf("extract attributes with type %s: %v", name, err) + } + variables[attributesVarPrefix+name] = m } result, _, err := c.Program.ContextEval(ctx, variables) if err != nil { @@ -172,7 +188,9 @@ func mustBuildEnv() *environment.EnvSet { versioned := []environment.VersionedOptions{ { IntroducedVersion: version.MajorMinor(1, 30), - EnvOptions: buildVersionedAttributes(), + EnvOptions: append(buildVersionedAttributes(), + SemverLib(), + ), }, } envset, err := envset.Extend(versioned...) @@ -190,17 +208,21 @@ func buildVersionedAttributes() []cel.EnvOption { return options } -func buildValueMapper(adapter types.Adapter, attributes []resourceapi.NamedResourcesAttribute, get func(resourceapi.NamedResourcesAttribute) any) traits.Mapper { +func buildValueMapper(adapter types.Adapter, attributes []resourceapi.NamedResourcesAttribute, get func(resourceapi.NamedResourcesAttribute) (any, error)) (traits.Mapper, error) { // This implementation constructs a map and then let's cel handle the // lookup and iteration. This is done for the sake of simplicity. // Whether it's faster than writing a custom mapper depends on // real-world attribute sets and CEL expressions and would have to be // benchmarked. valueMap := make(map[string]any) - for _, attribute := range attributes { - if value := get(attribute); value != nil { + for name, attribute := range attributes { + value, err := get(attribute) + if err != nil { + return nil, fmt.Errorf("attribute %q: %v", name, err) + } + if value != nil { valueMap[attribute.Name] = value } } - return types.NewStringInterfaceMap(adapter, valueMap) + return types.NewStringInterfaceMap(adapter, valueMap), nil } diff --git a/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/semver.go b/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/semver.go new file mode 100644 index 00000000000..c53b9c306a0 --- /dev/null +++ b/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/semver.go @@ -0,0 +1,73 @@ +/* +Copyright 2024 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 cel + +import ( + "fmt" + "reflect" + + "github.com/blang/semver/v4" + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" +) + +var ( + SemverType = cel.ObjectType("kubernetes.Semver") +) + +// Semver provdes a CEL representation of a [semver.Version]. +type Semver struct { + semver.Version +} + +func (v Semver) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + if reflect.TypeOf(v.Version).AssignableTo(typeDesc) { + return v.Version, nil + } + if reflect.TypeOf("").AssignableTo(typeDesc) { + return v.Version.String(), nil + } + return nil, fmt.Errorf("type conversion error from 'Semver' to '%v'", typeDesc) +} + +func (v Semver) ConvertToType(typeVal ref.Type) ref.Val { + switch typeVal { + case SemverType: + return v + case types.TypeType: + return SemverType + default: + return types.NewErr("type conversion error from '%s' to '%s'", SemverType, typeVal) + } +} + +func (v Semver) Equal(other ref.Val) ref.Val { + otherDur, ok := other.(Semver) + if !ok { + return types.MaybeNoSuchOverloadErr(other) + } + return types.Bool(v.Version.EQ(otherDur.Version)) +} + +func (v Semver) Type() ref.Type { + return SemverType +} + +func (v Semver) Value() interface{} { + return v.Version +} diff --git a/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/semver_test.go b/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/semver_test.go new file mode 100644 index 00000000000..38f43d15fb1 --- /dev/null +++ b/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/semver_test.go @@ -0,0 +1,209 @@ +/* +Copyright 2023 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 cel_test + +import ( + "regexp" + "testing" + + "github.com/blang/semver/v4" + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + "github.com/stretchr/testify/require" + + "k8s.io/apimachinery/pkg/util/sets" + library "k8s.io/dynamic-resource-allocation/structured/namedresources/cel" +) + +func testSemver(t *testing.T, expr string, expectResult ref.Val, expectRuntimeErrPattern string, expectCompileErrs []string) { + env, err := cel.NewEnv( + library.SemverLib(), + ) + if err != nil { + t.Fatalf("%v", err) + } + compiled, issues := env.Compile(expr) + + if len(expectCompileErrs) > 0 { + missingCompileErrs := []string{} + matchedCompileErrs := sets.New[int]() + for _, expectedCompileErr := range expectCompileErrs { + compiledPattern, err := regexp.Compile(expectedCompileErr) + if err != nil { + t.Fatalf("failed to compile expected err regex: %v", err) + } + + didMatch := false + + for i, compileError := range issues.Errors() { + if compiledPattern.Match([]byte(compileError.Message)) { + didMatch = true + matchedCompileErrs.Insert(i) + } + } + + if !didMatch { + missingCompileErrs = append(missingCompileErrs, expectedCompileErr) + } else if len(matchedCompileErrs) != len(issues.Errors()) { + unmatchedErrs := []cel.Error{} + for i, issue := range issues.Errors() { + if !matchedCompileErrs.Has(i) { + unmatchedErrs = append(unmatchedErrs, *issue) + } + } + require.Empty(t, unmatchedErrs, "unexpected compilation errors") + } + } + + require.Empty(t, missingCompileErrs, "expected compilation errors") + return + } else if len(issues.Errors()) > 0 { + for _, err := range issues.Errors() { + t.Errorf("unexpected compile error: %v", err) + } + t.FailNow() + } + + prog, err := env.Program(compiled) + if err != nil { + t.Fatalf("%v", err) + } + res, _, err := prog.Eval(map[string]interface{}{}) + if len(expectRuntimeErrPattern) > 0 { + if err == nil { + t.Fatalf("no runtime error thrown. Expected: %v", expectRuntimeErrPattern) + } else if matched, regexErr := regexp.MatchString(expectRuntimeErrPattern, err.Error()); regexErr != nil { + t.Fatalf("failed to compile expected err regex: %v", regexErr) + } else if !matched { + t.Fatalf("unexpected err: %v", err) + } + } else if err != nil { + t.Fatalf("%v", err) + } else if expectResult != nil { + converted := res.Equal(expectResult).Value().(bool) + require.True(t, converted, "expectation not equal to output") + } else { + t.Fatal("expected result must not be nil") + } + +} + +func TestSemver(t *testing.T) { + trueVal := types.Bool(true) + falseVal := types.Bool(false) + + cases := []struct { + name string + expr string + expectValue ref.Val + expectedCompileErr []string + expectedRuntimeErr string + }{ + { + name: "parse", + expr: `semver("1.2.3")`, + expectValue: library.Semver{Version: semver.MustParse("1.2.3")}, + }, + { + name: "parseInvalidVersion", + expr: `semver("v1.0")`, + expectedRuntimeErr: "No Major.Minor.Patch elements found", + }, + { + name: "isSemver", + expr: `isSemver("1.2.3-beta.1+build.1")`, + expectValue: trueVal, + }, + { + name: "isSemver_false", + expr: `isSemver("v1.0")`, + expectValue: falseVal, + }, + { + name: "isSemver_noOverload", + expr: `isSemver([1, 2, 3])`, + expectedCompileErr: []string{"found no matching overload for 'isSemver' applied to.*"}, + }, + { + name: "equality_reflexivity", + expr: `semver("1.2.3") == semver("1.2.3")`, + expectValue: trueVal, + }, + { + name: "inequality", + expr: `semver("1.2.3") == semver("1.0.0")`, + expectValue: falseVal, + }, + { + name: "semver_less", + expr: `semver("1.0.0").isLessThan(semver("1.2.3"))`, + expectValue: trueVal, + }, + { + name: "semver_less_false", + expr: `semver("1.0.0").isLessThan(semver("1.0.0"))`, + expectValue: falseVal, + }, + { + name: "semver_greater", + expr: `semver("1.2.3").isGreaterThan(semver("1.0.0"))`, + expectValue: trueVal, + }, + { + name: "semver_greater_false", + expr: `semver("1.0.0").isGreaterThan(semver("1.0.0"))`, + expectValue: falseVal, + }, + { + name: "compare_equal", + expr: `semver("1.2.3").compareTo(semver("1.2.3"))`, + expectValue: types.Int(0), + }, + { + name: "compare_less", + expr: `semver("1.0.0").compareTo(semver("1.2.3"))`, + expectValue: types.Int(-1), + }, + { + name: "compare_greater", + expr: `semver("1.2.3").compareTo(semver("1.0.0"))`, + expectValue: types.Int(1), + }, + { + name: "major", + expr: `semver("1.2.3").major()`, + expectValue: types.Int(1), + }, + { + name: "minor", + expr: `semver("1.2.3").minor()`, + expectValue: types.Int(2), + }, + { + name: "patch", + expr: `semver("1.2.3").patch()`, + expectValue: types.Int(3), + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + testSemver(t, c.expr, c.expectValue, c.expectedRuntimeErr, c.expectedCompileErr) + }) + } +} diff --git a/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/semverlib.go b/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/semverlib.go new file mode 100644 index 00000000000..c9470761e73 --- /dev/null +++ b/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/semverlib.go @@ -0,0 +1,238 @@ +/* +Copyright 2024 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 cel + +import ( + "github.com/blang/semver/v4" + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" +) + +// Semver provides a CEL function library extension for [semver.Version]. +// +// semver +// +// Converts a string to a semantic version or results in an error if the string is not a valid semantic version. Refer +// to semver.org documentation for information on accepted patterns. +// +// semver() +// +// Examples: +// +// semver('1.0.0') // returns a Semver +// semver('0.1.0-alpha.1') // returns a Semver +// semver('200K') // error +// semver('Three') // error +// semver('Mi') // error +// +// isSemver +// +// Returns true if a string is a valid Semver. isSemver returns true if and +// only if semver does not result in error. +// +// isSemver( ) +// +// Examples: +// +// isSemver('1.0.0') // returns true +// isSemver('v1.0') // returns true (tolerant parsing) +// isSemver('hello') // returns false +// +// Conversion to Scalars: +// +// - major/minor/patch: return the major version number as int64. +// +// .major() +// +// Examples: +// +// semver("1.2.3").major() // returns 1 +// +// Comparisons +// +// - isGreaterThan: Returns true if and only if the receiver is greater than the operand +// +// - isLessThan: Returns true if and only if the receiver is less than the operand +// +// - compareTo: Compares receiver to operand and returns 0 if they are equal, 1 if the receiver is greater, or -1 if the receiver is less than the operand +// +// +// .isLessThan() +// .isGreaterThan() +// .compareTo() +// +// Examples: +// +// semver("1.2.3").compareTo(semver("1.2.3")) // returns 0 +// semver("1.2.3").compareTo(semver("2.0.0")) // returns -1 +// semver("1.2.3").compareTo(semver("0.1.2")) // returns 1 + +func SemverLib() cel.EnvOption { + return cel.Lib(semverLib) +} + +var semverLib = &semverLibType{} + +type semverLibType struct{} + +func (*semverLibType) LibraryName() string { + return "k8s.semver" +} + +func (*semverLibType) CompileOptions() []cel.EnvOption { + // Defined in this function to avoid an initialization order problem. + semverLibraryDecls := map[string][]cel.FunctionOpt{ + "semver": { + cel.Overload("string_to_semver", []*cel.Type{cel.StringType}, SemverType, cel.UnaryBinding((stringToSemver))), + }, + "isSemver": { + cel.Overload("is_semver_string", []*cel.Type{cel.StringType}, cel.BoolType, cel.UnaryBinding(isSemver)), + }, + "isGreaterThan": { + cel.MemberOverload("semver_is_greater_than", []*cel.Type{SemverType, SemverType}, cel.BoolType, cel.BinaryBinding(semverIsGreaterThan)), + }, + "isLessThan": { + cel.MemberOverload("semver_is_less_than", []*cel.Type{SemverType, SemverType}, cel.BoolType, cel.BinaryBinding(semverIsLessThan)), + }, + "compareTo": { + cel.MemberOverload("semver_compare_to", []*cel.Type{SemverType, SemverType}, cel.IntType, cel.BinaryBinding(semverCompareTo)), + }, + "major": { + cel.MemberOverload("semver_major", []*cel.Type{SemverType}, cel.IntType, cel.UnaryBinding(semverMajor)), + }, + "minor": { + cel.MemberOverload("semver_minor", []*cel.Type{SemverType}, cel.IntType, cel.UnaryBinding(semverMinor)), + }, + "patch": { + cel.MemberOverload("semver_patch", []*cel.Type{SemverType}, cel.IntType, cel.UnaryBinding(semverPatch)), + }, + } + + options := make([]cel.EnvOption, 0, len(semverLibraryDecls)) + for name, overloads := range semverLibraryDecls { + options = append(options, cel.Function(name, overloads...)) + } + return options +} + +func (*semverLibType) ProgramOptions() []cel.ProgramOption { + return []cel.ProgramOption{} +} + +func isSemver(arg ref.Val) ref.Val { + str, ok := arg.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + + // Using semver/v4 here is okay because this function isn't + // used to validate the Kubernetes API. In the CEL base library + // we would have to use the regular expression from + // pkg/apis/resource/structured/namedresources/validation/validation.go. + _, err := semver.Parse(str) + if err != nil { + return types.Bool(false) + } + + return types.Bool(true) +} + +func stringToSemver(arg ref.Val) ref.Val { + str, ok := arg.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + + // Using semver/v4 here is okay because this function isn't + // used to validate the Kubernetes API. In the CEL base library + // we would have to use the regular expression from + // pkg/apis/resource/structured/namedresources/validation/validation.go + // first before parsing. + v, err := semver.Parse(str) + if err != nil { + return types.WrapErr(err) + } + + return Semver{Version: v} +} + +func semverMajor(arg ref.Val) ref.Val { + v, ok := arg.Value().(semver.Version) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + return types.Int(v.Major) +} + +func semverMinor(arg ref.Val) ref.Val { + v, ok := arg.Value().(semver.Version) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + return types.Int(v.Minor) +} + +func semverPatch(arg ref.Val) ref.Val { + v, ok := arg.Value().(semver.Version) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + return types.Int(v.Patch) +} + +func semverIsGreaterThan(arg ref.Val, other ref.Val) ref.Val { + v, ok := arg.Value().(semver.Version) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + + v2, ok := other.Value().(semver.Version) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + + return types.Bool(v.Compare(v2) == 1) +} + +func semverIsLessThan(arg ref.Val, other ref.Val) ref.Val { + v, ok := arg.Value().(semver.Version) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + + v2, ok := other.Value().(semver.Version) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + + return types.Bool(v.Compare(v2) == -1) +} + +func semverCompareTo(arg ref.Val, other ref.Val) ref.Val { + v, ok := arg.Value().(semver.Version) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + + v2, ok := other.Value().(semver.Version) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + + return types.Int(v.Compare(v2)) +} From 0b6a0d686a060b5d5ff92cea931aacd4eba85adb Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Thu, 7 Mar 2024 10:14:11 +0100 Subject: [PATCH 14/18] dra api: rename NodeResourceSlice -> ResourceSlice While currently those objects only get published by the kubelet for node-local resources, this could change once we also support network-attached resources. Dropping the "Node" prefix enables such a future extension. The NodeName in ResourceSlice and StructuredResourceHandle then becomes optional. The kubelet still needs to provide one and it must match its own node name, otherwise it doesn't have permission to access ResourceSlice objects. --- api/discovery/aggregated_v2beta1.json | 40 +- .../apis__resource.k8s.io__v1alpha2.json | 34 +- api/openapi-spec/swagger.json | 1424 +++++----- ...is__resource.k8s.io__v1alpha2_openapi.json | 2442 ++++++++--------- pkg/apis/resource/register.go | 4 +- pkg/apis/resource/types.go | 21 +- pkg/apis/resource/v1alpha2/conversion.go | 4 +- .../v1alpha2/zz_generated.conversion.go | 144 +- pkg/apis/resource/validation/validation.go | 30 +- .../validation_resourceclaim_test.go | 71 +- ...st.go => validation_resourceslice_test.go} | 110 +- pkg/apis/resource/zz_generated.deepcopy.go | 120 +- pkg/generated/openapi/zz_generated.openapi.go | 228 +- pkg/kubeapiserver/authorizer/config.go | 4 +- pkg/kubelet/cm/dra/plugin/noderesources.go | 48 +- pkg/kubelet/cm/dra/plugin/plugin.go | 2 +- pkg/printers/internalversion/printers.go | 14 +- .../storage/storage.go | 28 +- .../storage/storage_test.go | 24 +- .../strategy.go | 48 +- .../strategy_test.go | 8 +- .../resource/rest/storage_resource.go | 8 +- .../dynamicresources/dynamicresources.go | 8 +- .../dynamicresources/structuredparameters.go | 4 +- .../admission/noderestriction/admission.go | 24 +- .../noderestriction/admission_test.go | 10 +- plugin/pkg/auth/authorizer/node/graph.go | 12 +- .../auth/authorizer/node/graph_populator.go | 18 +- .../auth/authorizer/node/node_authorizer.go | 18 +- .../authorizer/node/node_authorizer_test.go | 60 +- .../authorizer/rbac/bootstrappolicy/policy.go | 2 +- .../api/resource/v1alpha2/generated.pb.go | 1373 +++++---- .../api/resource/v1alpha2/generated.proto | 69 +- .../k8s.io/api/resource/v1alpha2/register.go | 4 +- .../src/k8s.io/api/resource/v1alpha2/types.go | 29 +- .../v1alpha2/types_swagger_doc_generated.go | 44 +- .../v1alpha2/zz_generated.deepcopy.go | 120 +- ...source.k8s.io.v1alpha2.ResourceSlice.json} | 2 +- ...resource.k8s.io.v1alpha2.ResourceSlice.pb} | Bin 533 -> 529 bytes ...source.k8s.io.v1alpha2.ResourceSlice.yaml} | 2 +- .../applyconfigurations/internal/internal.go | 48 +- ...{noderesourceslice.go => resourceslice.go} | 80 +- .../client-go/applyconfigurations/utils.go | 4 +- .../src/k8s.io/client-go/informers/generic.go | 4 +- .../informers/resource/v1alpha2/interface.go | 14 +- ...{noderesourceslice.go => resourceslice.go} | 38 +- .../v1alpha2/fake/fake_noderesourceslice.go | 145 - .../v1alpha2/fake/fake_resource_client.go | 8 +- .../v1alpha2/fake/fake_resourceslice.go | 145 + .../resource/v1alpha2/generated_expansion.go | 4 +- .../resource/v1alpha2/noderesourceslice.go | 197 -- .../resource/v1alpha2/resource_client.go | 10 +- .../typed/resource/v1alpha2/resourceslice.go | 197 ++ .../resource/v1alpha2/expansion_generated.go | 8 +- .../resource/v1alpha2/noderesourceslice.go | 68 - .../resource/v1alpha2/resourceslice.go | 68 + test/e2e/dra/deploy.go | 4 +- test/e2e/dra/dra.go | 14 +- test/integration/etcd/data.go | 4 +- test/integration/scheduler_perf/dra.go | 12 +- 60 files changed, 3868 insertions(+), 3859 deletions(-) rename pkg/apis/resource/validation/{validation_noderesourceslice_test.go => validation_resourceslice_test.go} (62%) rename pkg/registry/resource/{noderesourceslice => resourceslice}/storage/storage.go (67%) rename pkg/registry/resource/{noderesourceslice => resourceslice}/storage/storage_test.go (86%) rename pkg/registry/resource/{noderesourceslice => resourceslice}/strategy.go (62%) rename pkg/registry/resource/{noderesourceslice => resourceslice}/strategy_test.go (91%) rename staging/src/k8s.io/api/testdata/HEAD/{resource.k8s.io.v1alpha2.NodeResourceSlice.json => resource.k8s.io.v1alpha2.ResourceSlice.json} (98%) rename staging/src/k8s.io/api/testdata/HEAD/{resource.k8s.io.v1alpha2.NodeResourceSlice.pb => resource.k8s.io.v1alpha2.ResourceSlice.pb} (90%) rename staging/src/k8s.io/api/testdata/HEAD/{resource.k8s.io.v1alpha2.NodeResourceSlice.yaml => resource.k8s.io.v1alpha2.ResourceSlice.yaml} (98%) rename staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/{noderesourceslice.go => resourceslice.go} (68%) rename staging/src/k8s.io/client-go/informers/resource/v1alpha2/{noderesourceslice.go => resourceslice.go} (54%) delete mode 100644 staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_noderesourceslice.go create mode 100644 staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resourceslice.go delete mode 100644 staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/noderesourceslice.go create mode 100644 staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceslice.go delete mode 100644 staging/src/k8s.io/client-go/listers/resource/v1alpha2/noderesourceslice.go create mode 100644 staging/src/k8s.io/client-go/listers/resource/v1alpha2/resourceslice.go diff --git a/api/discovery/aggregated_v2beta1.json b/api/discovery/aggregated_v2beta1.json index dcada7821e6..a0cafb515e7 100644 --- a/api/discovery/aggregated_v2beta1.json +++ b/api/discovery/aggregated_v2beta1.json @@ -1891,26 +1891,6 @@ { "freshness": "Current", "resources": [ - { - "resource": "noderesourceslices", - "responseKind": { - "group": "", - "kind": "NodeResourceSlice", - "version": "" - }, - "scope": "Cluster", - "singularResource": "noderesourceslice", - "verbs": [ - "create", - "delete", - "deletecollection", - "get", - "list", - "patch", - "update", - "watch" - ] - }, { "resource": "podschedulingcontexts", "responseKind": { @@ -2060,6 +2040,26 @@ "update", "watch" ] + }, + { + "resource": "resourceslices", + "responseKind": { + "group": "", + "kind": "ResourceSlice", + "version": "" + }, + "scope": "Cluster", + "singularResource": "resourceslice", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] } ], "version": "v1alpha2" diff --git a/api/discovery/apis__resource.k8s.io__v1alpha2.json b/api/discovery/apis__resource.k8s.io__v1alpha2.json index 4538e4d685a..5c564395271 100644 --- a/api/discovery/apis__resource.k8s.io__v1alpha2.json +++ b/api/discovery/apis__resource.k8s.io__v1alpha2.json @@ -3,23 +3,6 @@ "groupVersion": "resource.k8s.io/v1alpha2", "kind": "APIResourceList", "resources": [ - { - "kind": "NodeResourceSlice", - "name": "noderesourceslices", - "namespaced": false, - "singularName": "noderesourceslice", - "storageVersionHash": "KmjmPdo2jrQ=", - "verbs": [ - "create", - "delete", - "deletecollection", - "get", - "list", - "patch", - "update", - "watch" - ] - }, { "kind": "PodSchedulingContext", "name": "podschedulingcontexts", @@ -143,6 +126,23 @@ "update", "watch" ] + }, + { + "kind": "ResourceSlice", + "name": "resourceslices", + "namespaced": false, + "singularName": "resourceslice", + "storageVersionHash": "IECvOcO76kw=", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] } ] } diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 28208b252ee..5a3f6e9ac32 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -15010,82 +15010,6 @@ ], "type": "object" }, - "io.k8s.api.resource.v1alpha2.NodeResourceSlice": { - "description": "NodeResourceSlice provides information about available resources on individual nodes.", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "driverName": { - "description": "DriverName identifies the DRA driver providing the capacity information. A field selector can be used to list only NodeResourceSlice objects with a certain driver name.", - "type": "string" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta", - "description": "Standard object metadata" - }, - "namedResources": { - "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NamedResourcesResources", - "description": "NamedResources describes available resources using the named resources model." - }, - "nodeName": { - "description": "NodeName identifies the node where the capacity is available. A field selector can be used to list only NodeResourceSlice objects with a certain node name.", - "type": "string" - } - }, - "required": [ - "nodeName", - "driverName" - ], - "type": "object", - "x-kubernetes-group-version-kind": [ - { - "group": "resource.k8s.io", - "kind": "NodeResourceSlice", - "version": "v1alpha2" - } - ] - }, - "io.k8s.api.resource.v1alpha2.NodeResourceSliceList": { - "description": "NodeResourceSliceList is a collection of NodeResourceSlices.", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "items": { - "description": "Items is the list of node resource capacity objects.", - "items": { - "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - }, - "type": "array" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta", - "description": "Standard list metadata" - } - }, - "required": [ - "items" - ], - "type": "object", - "x-kubernetes-group-version-kind": [ - { - "group": "resource.k8s.io", - "kind": "NodeResourceSliceList", - "version": "v1alpha2" - } - ] - }, "io.k8s.api.resource.v1alpha2.PodSchedulingContext": { "description": "PodSchedulingContext objects hold information that is needed to schedule a Pod with ResourceClaims that use \"WaitForFirstConsumer\" allocation mode.\n\nThis is an alpha type and requires enabling the DynamicResourceAllocation feature gate.", "properties": { @@ -15773,11 +15697,86 @@ }, "type": "object" }, + "io.k8s.api.resource.v1alpha2.ResourceSlice": { + "description": "ResourceSlice provides information about available resources on individual nodes.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "driverName": { + "description": "DriverName identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta", + "description": "Standard object metadata" + }, + "namedResources": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NamedResourcesResources", + "description": "NamedResources describes available resources using the named resources model." + }, + "nodeName": { + "description": "NodeName identifies the node which provides the resources if they are local to a node.\n\nA field selector can be used to list only ResourceSlice objects with a certain node name.", + "type": "string" + } + }, + "required": [ + "driverName" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "resource.k8s.io", + "kind": "ResourceSlice", + "version": "v1alpha2" + } + ] + }, + "io.k8s.api.resource.v1alpha2.ResourceSliceList": { + "description": "ResourceSliceList is a collection of ResourceSlices.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "Items is the list of node resource capacity objects.", + "items": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceSlice" + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta", + "description": "Standard list metadata" + } + }, + "required": [ + "items" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "resource.k8s.io", + "kind": "ResourceSliceList", + "version": "v1alpha2" + } + ] + }, "io.k8s.api.resource.v1alpha2.StructuredResourceHandle": { "description": "StructuredResourceHandle is the in-tree representation of the allocation result.", "properties": { "nodeName": { - "description": "NodeName is the name of the node providing the necessary resources.", + "description": "NodeName is the name of the node providing the necessary resources if the resources are local to a node.", "type": "string" }, "results": { @@ -15798,7 +15797,6 @@ } }, "required": [ - "nodeName", "results" ], "type": "object" @@ -72938,485 +72936,6 @@ } } }, - "/apis/resource.k8s.io/v1alpha2/noderesourceslices": { - "delete": { - "consumes": [ - "*/*" - ], - "description": "delete collection of NodeResourceSlice", - "operationId": "deleteResourceV1alpha2CollectionNodeResourceSlice", - "parameters": [ - { - "$ref": "#/parameters/body-2Y1dVQaQ" - }, - { - "$ref": "#/parameters/continue-QfD61s0i" - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "$ref": "#/parameters/fieldSelector-xIcQKXFG" - }, - { - "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" - }, - { - "$ref": "#/parameters/labelSelector-5Zw57w4C" - }, - { - "$ref": "#/parameters/limit-1NfNmdNH" - }, - { - "$ref": "#/parameters/orphanDependents-uRB25kX5" - }, - { - "$ref": "#/parameters/propagationPolicy-6jk3prlO" - }, - { - "$ref": "#/parameters/resourceVersion-5WAnf1kx" - }, - { - "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" - }, - { - "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" - }, - { - "$ref": "#/parameters/timeoutSeconds-yvYezaOC" - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "resource_v1alpha2" - ], - "x-kubernetes-action": "deletecollection", - "x-kubernetes-group-version-kind": { - "group": "resource.k8s.io", - "kind": "NodeResourceSlice", - "version": "v1alpha2" - } - }, - "get": { - "consumes": [ - "*/*" - ], - "description": "list or watch objects of kind NodeResourceSlice", - "operationId": "listResourceV1alpha2NodeResourceSlice", - "parameters": [ - { - "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" - }, - { - "$ref": "#/parameters/continue-QfD61s0i" - }, - { - "$ref": "#/parameters/fieldSelector-xIcQKXFG" - }, - { - "$ref": "#/parameters/labelSelector-5Zw57w4C" - }, - { - "$ref": "#/parameters/limit-1NfNmdNH" - }, - { - "$ref": "#/parameters/resourceVersion-5WAnf1kx" - }, - { - "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" - }, - { - "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" - }, - { - "$ref": "#/parameters/timeoutSeconds-yvYezaOC" - }, - { - "$ref": "#/parameters/watch-XNNPZGbK" - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSliceList" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "resource_v1alpha2" - ], - "x-kubernetes-action": "list", - "x-kubernetes-group-version-kind": { - "group": "resource.k8s.io", - "kind": "NodeResourceSlice", - "version": "v1alpha2" - } - }, - "parameters": [ - { - "$ref": "#/parameters/pretty-tJGM1-ng" - } - ], - "post": { - "consumes": [ - "*/*" - ], - "description": "create a NodeResourceSlice", - "operationId": "createResourceV1alpha2NodeResourceSlice", - "parameters": [ - { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "$ref": "#/parameters/fieldManager-Qy4HdaTW" - }, - { - "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", - "in": "query", - "name": "fieldValidation", - "type": "string", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "202": { - "description": "Accepted", - "schema": { - "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "resource_v1alpha2" - ], - "x-kubernetes-action": "post", - "x-kubernetes-group-version-kind": { - "group": "resource.k8s.io", - "kind": "NodeResourceSlice", - "version": "v1alpha2" - } - } - }, - "/apis/resource.k8s.io/v1alpha2/noderesourceslices/{name}": { - "delete": { - "consumes": [ - "*/*" - ], - "description": "delete a NodeResourceSlice", - "operationId": "deleteResourceV1alpha2NodeResourceSlice", - "parameters": [ - { - "$ref": "#/parameters/body-2Y1dVQaQ" - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" - }, - { - "$ref": "#/parameters/orphanDependents-uRB25kX5" - }, - { - "$ref": "#/parameters/propagationPolicy-6jk3prlO" - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "202": { - "description": "Accepted", - "schema": { - "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "resource_v1alpha2" - ], - "x-kubernetes-action": "delete", - "x-kubernetes-group-version-kind": { - "group": "resource.k8s.io", - "kind": "NodeResourceSlice", - "version": "v1alpha2" - } - }, - "get": { - "consumes": [ - "*/*" - ], - "description": "read the specified NodeResourceSlice", - "operationId": "readResourceV1alpha2NodeResourceSlice", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "resource_v1alpha2" - ], - "x-kubernetes-action": "get", - "x-kubernetes-group-version-kind": { - "group": "resource.k8s.io", - "kind": "NodeResourceSlice", - "version": "v1alpha2" - } - }, - "parameters": [ - { - "description": "name of the NodeResourceSlice", - "in": "path", - "name": "name", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "$ref": "#/parameters/pretty-tJGM1-ng" - } - ], - "patch": { - "consumes": [ - "application/json-patch+json", - "application/merge-patch+json", - "application/strategic-merge-patch+json", - "application/apply-patch+yaml" - ], - "description": "partially update the specified NodeResourceSlice", - "operationId": "patchResourceV1alpha2NodeResourceSlice", - "parameters": [ - { - "$ref": "#/parameters/body-78PwaGsr" - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "$ref": "#/parameters/fieldManager-7c6nTn1T" - }, - { - "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", - "in": "query", - "name": "fieldValidation", - "type": "string", - "uniqueItems": true - }, - { - "$ref": "#/parameters/force-tOGGb0Yi" - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "resource_v1alpha2" - ], - "x-kubernetes-action": "patch", - "x-kubernetes-group-version-kind": { - "group": "resource.k8s.io", - "kind": "NodeResourceSlice", - "version": "v1alpha2" - } - }, - "put": { - "consumes": [ - "*/*" - ], - "description": "replace the specified NodeResourceSlice", - "operationId": "replaceResourceV1alpha2NodeResourceSlice", - "parameters": [ - { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "$ref": "#/parameters/fieldManager-Qy4HdaTW" - }, - { - "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", - "in": "query", - "name": "fieldValidation", - "type": "string", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "resource_v1alpha2" - ], - "x-kubernetes-action": "put", - "x-kubernetes-group-version-kind": { - "group": "resource.k8s.io", - "kind": "NodeResourceSlice", - "version": "v1alpha2" - } - } - }, "/apis/resource.k8s.io/v1alpha2/podschedulingcontexts": { "get": { "consumes": [ @@ -74266,6 +73785,485 @@ } ] }, + "/apis/resource.k8s.io/v1alpha2/resourceslices": { + "delete": { + "consumes": [ + "*/*" + ], + "description": "delete collection of ResourceSlice", + "operationId": "deleteResourceV1alpha2CollectionResourceSlice", + "parameters": [ + { + "$ref": "#/parameters/body-2Y1dVQaQ" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "$ref": "#/parameters/orphanDependents-uRB25kX5" + }, + { + "$ref": "#/parameters/propagationPolicy-6jk3prlO" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "deletecollection", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceSlice", + "version": "v1alpha2" + } + }, + "get": { + "consumes": [ + "*/*" + ], + "description": "list or watch objects of kind ResourceSlice", + "operationId": "listResourceV1alpha2ResourceSlice", + "parameters": [ + { + "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + }, + { + "$ref": "#/parameters/watch-XNNPZGbK" + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf", + "application/json;stream=watch", + "application/vnd.kubernetes.protobuf;stream=watch" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceSliceList" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "list", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceSlice", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "$ref": "#/parameters/pretty-tJGM1-ng" + } + ], + "post": { + "consumes": [ + "*/*" + ], + "description": "create a ResourceSlice", + "operationId": "createResourceV1alpha2ResourceSlice", + "parameters": [ + { + "in": "body", + "name": "body", + "required": true, + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/fieldManager-Qy4HdaTW" + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "type": "string", + "uniqueItems": true + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "202": { + "description": "Accepted", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "post", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceSlice", + "version": "v1alpha2" + } + } + }, + "/apis/resource.k8s.io/v1alpha2/resourceslices/{name}": { + "delete": { + "consumes": [ + "*/*" + ], + "description": "delete a ResourceSlice", + "operationId": "deleteResourceV1alpha2ResourceSlice", + "parameters": [ + { + "$ref": "#/parameters/body-2Y1dVQaQ" + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" + }, + { + "$ref": "#/parameters/orphanDependents-uRB25kX5" + }, + { + "$ref": "#/parameters/propagationPolicy-6jk3prlO" + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "202": { + "description": "Accepted", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "delete", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceSlice", + "version": "v1alpha2" + } + }, + "get": { + "consumes": [ + "*/*" + ], + "description": "read the specified ResourceSlice", + "operationId": "readResourceV1alpha2ResourceSlice", + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "get", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceSlice", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "name of the ResourceSlice", + "in": "path", + "name": "name", + "required": true, + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/pretty-tJGM1-ng" + } + ], + "patch": { + "consumes": [ + "application/json-patch+json", + "application/merge-patch+json", + "application/strategic-merge-patch+json", + "application/apply-patch+yaml" + ], + "description": "partially update the specified ResourceSlice", + "operationId": "patchResourceV1alpha2ResourceSlice", + "parameters": [ + { + "$ref": "#/parameters/body-78PwaGsr" + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/fieldManager-7c6nTn1T" + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/force-tOGGb0Yi" + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "patch", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceSlice", + "version": "v1alpha2" + } + }, + "put": { + "consumes": [ + "*/*" + ], + "description": "replace the specified ResourceSlice", + "operationId": "replaceResourceV1alpha2ResourceSlice", + "parameters": [ + { + "in": "body", + "name": "body", + "required": true, + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/fieldManager-Qy4HdaTW" + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "type": "string", + "uniqueItems": true + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "put", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceSlice", + "version": "v1alpha2" + } + } + }, "/apis/resource.k8s.io/v1alpha2/watch/namespaces/{namespace}/podschedulingcontexts": { "get": { "consumes": [ @@ -75076,162 +75074,6 @@ } ] }, - "/apis/resource.k8s.io/v1alpha2/watch/noderesourceslices": { - "get": { - "consumes": [ - "*/*" - ], - "description": "watch individual changes to a list of NodeResourceSlice. deprecated: use the 'watch' parameter with a list operation instead.", - "operationId": "watchResourceV1alpha2NodeResourceSliceList", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "resource_v1alpha2" - ], - "x-kubernetes-action": "watchlist", - "x-kubernetes-group-version-kind": { - "group": "resource.k8s.io", - "kind": "NodeResourceSlice", - "version": "v1alpha2" - } - }, - "parameters": [ - { - "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" - }, - { - "$ref": "#/parameters/continue-QfD61s0i" - }, - { - "$ref": "#/parameters/fieldSelector-xIcQKXFG" - }, - { - "$ref": "#/parameters/labelSelector-5Zw57w4C" - }, - { - "$ref": "#/parameters/limit-1NfNmdNH" - }, - { - "$ref": "#/parameters/pretty-tJGM1-ng" - }, - { - "$ref": "#/parameters/resourceVersion-5WAnf1kx" - }, - { - "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" - }, - { - "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" - }, - { - "$ref": "#/parameters/timeoutSeconds-yvYezaOC" - }, - { - "$ref": "#/parameters/watch-XNNPZGbK" - } - ] - }, - "/apis/resource.k8s.io/v1alpha2/watch/noderesourceslices/{name}": { - "get": { - "consumes": [ - "*/*" - ], - "description": "watch changes to an object of kind NodeResourceSlice. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", - "operationId": "watchResourceV1alpha2NodeResourceSlice", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "resource_v1alpha2" - ], - "x-kubernetes-action": "watch", - "x-kubernetes-group-version-kind": { - "group": "resource.k8s.io", - "kind": "NodeResourceSlice", - "version": "v1alpha2" - } - }, - "parameters": [ - { - "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" - }, - { - "$ref": "#/parameters/continue-QfD61s0i" - }, - { - "$ref": "#/parameters/fieldSelector-xIcQKXFG" - }, - { - "$ref": "#/parameters/labelSelector-5Zw57w4C" - }, - { - "$ref": "#/parameters/limit-1NfNmdNH" - }, - { - "description": "name of the NodeResourceSlice", - "in": "path", - "name": "name", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "$ref": "#/parameters/pretty-tJGM1-ng" - }, - { - "$ref": "#/parameters/resourceVersion-5WAnf1kx" - }, - { - "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" - }, - { - "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" - }, - { - "$ref": "#/parameters/timeoutSeconds-yvYezaOC" - }, - { - "$ref": "#/parameters/watch-XNNPZGbK" - } - ] - }, "/apis/resource.k8s.io/v1alpha2/watch/podschedulingcontexts": { "get": { "consumes": [ @@ -75758,6 +75600,162 @@ } ] }, + "/apis/resource.k8s.io/v1alpha2/watch/resourceslices": { + "get": { + "consumes": [ + "*/*" + ], + "description": "watch individual changes to a list of ResourceSlice. deprecated: use the 'watch' parameter with a list operation instead.", + "operationId": "watchResourceV1alpha2ResourceSliceList", + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf", + "application/json;stream=watch", + "application/vnd.kubernetes.protobuf;stream=watch" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "watchlist", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceSlice", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "$ref": "#/parameters/pretty-tJGM1-ng" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + }, + { + "$ref": "#/parameters/watch-XNNPZGbK" + } + ] + }, + "/apis/resource.k8s.io/v1alpha2/watch/resourceslices/{name}": { + "get": { + "consumes": [ + "*/*" + ], + "description": "watch changes to an object of kind ResourceSlice. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", + "operationId": "watchResourceV1alpha2ResourceSlice", + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf", + "application/json;stream=watch", + "application/vnd.kubernetes.protobuf;stream=watch" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "watch", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceSlice", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "description": "name of the ResourceSlice", + "in": "path", + "name": "name", + "required": true, + "type": "string", + "uniqueItems": true + }, + { + "$ref": "#/parameters/pretty-tJGM1-ng" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + }, + { + "$ref": "#/parameters/watch-XNNPZGbK" + } + ] + }, "/apis/scheduling.k8s.io/": { "get": { "consumes": [ diff --git a/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha2_openapi.json b/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha2_openapi.json index 0d9a3b97082..43e1256496b 100644 --- a/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha2_openapi.json +++ b/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha2_openapi.json @@ -353,103 +353,6 @@ ], "type": "object" }, - "io.k8s.api.resource.v1alpha2.NodeResourceSlice": { - "description": "NodeResourceSlice provides information about available resources on individual nodes.", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "driverName": { - "default": "", - "description": "DriverName identifies the DRA driver providing the capacity information. A field selector can be used to list only NodeResourceSlice objects with a certain driver name.", - "type": "string" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "allOf": [ - { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta" - } - ], - "default": {}, - "description": "Standard object metadata" - }, - "namedResources": { - "allOf": [ - { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NamedResourcesResources" - } - ], - "description": "NamedResources describes available resources using the named resources model." - }, - "nodeName": { - "default": "", - "description": "NodeName identifies the node where the capacity is available. A field selector can be used to list only NodeResourceSlice objects with a certain node name.", - "type": "string" - } - }, - "required": [ - "nodeName", - "driverName" - ], - "type": "object", - "x-kubernetes-group-version-kind": [ - { - "group": "resource.k8s.io", - "kind": "NodeResourceSlice", - "version": "v1alpha2" - } - ] - }, - "io.k8s.api.resource.v1alpha2.NodeResourceSliceList": { - "description": "NodeResourceSliceList is a collection of NodeResourceSlices.", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "items": { - "description": "Items is the list of node resource capacity objects.", - "items": { - "allOf": [ - { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - ], - "default": {} - }, - "type": "array" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "allOf": [ - { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" - } - ], - "default": {}, - "description": "Standard list metadata" - } - }, - "required": [ - "items" - ], - "type": "object", - "x-kubernetes-group-version-kind": [ - { - "group": "resource.k8s.io", - "kind": "NodeResourceSliceList", - "version": "v1alpha2" - } - ] - }, "io.k8s.api.resource.v1alpha2.PodSchedulingContext": { "description": "PodSchedulingContext objects hold information that is needed to schedule a Pod with ResourceClaims that use \"WaitForFirstConsumer\" allocation mode.\n\nThis is an alpha type and requires enabling the DynamicResourceAllocation feature gate.", "properties": { @@ -1338,12 +1241,106 @@ }, "type": "object" }, + "io.k8s.api.resource.v1alpha2.ResourceSlice": { + "description": "ResourceSlice provides information about available resources on individual nodes.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "driverName": { + "default": "", + "description": "DriverName identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta" + } + ], + "default": {}, + "description": "Standard object metadata" + }, + "namedResources": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NamedResourcesResources" + } + ], + "description": "NamedResources describes available resources using the named resources model." + }, + "nodeName": { + "description": "NodeName identifies the node which provides the resources if they are local to a node.\n\nA field selector can be used to list only ResourceSlice objects with a certain node name.", + "type": "string" + } + }, + "required": [ + "driverName" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "resource.k8s.io", + "kind": "ResourceSlice", + "version": "v1alpha2" + } + ] + }, + "io.k8s.api.resource.v1alpha2.ResourceSliceList": { + "description": "ResourceSliceList is a collection of ResourceSlices.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "Items is the list of node resource capacity objects.", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + ], + "default": {} + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + ], + "default": {}, + "description": "Standard list metadata" + } + }, + "required": [ + "items" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "resource.k8s.io", + "kind": "ResourceSliceList", + "version": "v1alpha2" + } + ] + }, "io.k8s.api.resource.v1alpha2.StructuredResourceHandle": { "description": "StructuredResourceHandle is the in-tree representation of the allocation result.", "properties": { "nodeName": { - "default": "", - "description": "NodeName is the name of the node providing the necessary resources.", + "description": "NodeName is the name of the node providing the necessary resources if the resources are local to a node.", "type": "string" }, "results": { @@ -1377,7 +1374,6 @@ } }, "required": [ - "nodeName", "results" ], "type": "object" @@ -7327,817 +7323,6 @@ } } }, - "/apis/resource.k8s.io/v1alpha2/noderesourceslices": { - "delete": { - "description": "delete collection of NodeResourceSlice", - "operationId": "deleteResourceV1alpha2CollectionNodeResourceSlice", - "parameters": [ - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", - "in": "query", - "name": "gracePeriodSeconds", - "schema": { - "type": "integer", - "uniqueItems": true - } - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "schema": { - "type": "integer", - "uniqueItems": true - } - }, - { - "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", - "in": "query", - "name": "orphanDependents", - "schema": { - "type": "boolean", - "uniqueItems": true - } - }, - { - "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", - "in": "query", - "name": "propagationPolicy", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", - "in": "query", - "name": "sendInitialEvents", - "schema": { - "type": "boolean", - "uniqueItems": true - } - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "schema": { - "type": "integer", - "uniqueItems": true - } - } - ], - "requestBody": { - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" - } - } - } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" - } - }, - "application/vnd.kubernetes.protobuf": { - "schema": { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" - } - }, - "application/yaml": { - "schema": { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" - } - } - }, - "description": "OK" - }, - "401": { - "description": "Unauthorized" - } - }, - "tags": [ - "resource_v1alpha2" - ], - "x-kubernetes-action": "deletecollection", - "x-kubernetes-group-version-kind": { - "group": "resource.k8s.io", - "kind": "NodeResourceSlice", - "version": "v1alpha2" - } - }, - "get": { - "description": "list or watch objects of kind NodeResourceSlice", - "operationId": "listResourceV1alpha2NodeResourceSlice", - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "schema": { - "type": "boolean", - "uniqueItems": true - } - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "schema": { - "type": "integer", - "uniqueItems": true - } - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", - "in": "query", - "name": "sendInitialEvents", - "schema": { - "type": "boolean", - "uniqueItems": true - } - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "schema": { - "type": "integer", - "uniqueItems": true - } - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "schema": { - "type": "boolean", - "uniqueItems": true - } - } - ], - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSliceList" - } - }, - "application/json;stream=watch": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSliceList" - } - }, - "application/vnd.kubernetes.protobuf": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSliceList" - } - }, - "application/vnd.kubernetes.protobuf;stream=watch": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSliceList" - } - }, - "application/yaml": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSliceList" - } - } - }, - "description": "OK" - }, - "401": { - "description": "Unauthorized" - } - }, - "tags": [ - "resource_v1alpha2" - ], - "x-kubernetes-action": "list", - "x-kubernetes-group-version-kind": { - "group": "resource.k8s.io", - "kind": "NodeResourceSlice", - "version": "v1alpha2" - } - }, - "parameters": [ - { - "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", - "in": "query", - "name": "pretty", - "schema": { - "type": "string", - "uniqueItems": true - } - } - ], - "post": { - "description": "create a NodeResourceSlice", - "operationId": "createResourceV1alpha2NodeResourceSlice", - "parameters": [ - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", - "in": "query", - "name": "fieldManager", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", - "in": "query", - "name": "fieldValidation", - "schema": { - "type": "string", - "uniqueItems": true - } - } - ], - "requestBody": { - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - } - }, - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "application/vnd.kubernetes.protobuf": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "application/yaml": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - } - }, - "description": "OK" - }, - "201": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "application/vnd.kubernetes.protobuf": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "application/yaml": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - } - }, - "description": "Created" - }, - "202": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "application/vnd.kubernetes.protobuf": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "application/yaml": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - } - }, - "description": "Accepted" - }, - "401": { - "description": "Unauthorized" - } - }, - "tags": [ - "resource_v1alpha2" - ], - "x-kubernetes-action": "post", - "x-kubernetes-group-version-kind": { - "group": "resource.k8s.io", - "kind": "NodeResourceSlice", - "version": "v1alpha2" - } - } - }, - "/apis/resource.k8s.io/v1alpha2/noderesourceslices/{name}": { - "delete": { - "description": "delete a NodeResourceSlice", - "operationId": "deleteResourceV1alpha2NodeResourceSlice", - "parameters": [ - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", - "in": "query", - "name": "gracePeriodSeconds", - "schema": { - "type": "integer", - "uniqueItems": true - } - }, - { - "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", - "in": "query", - "name": "orphanDependents", - "schema": { - "type": "boolean", - "uniqueItems": true - } - }, - { - "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", - "in": "query", - "name": "propagationPolicy", - "schema": { - "type": "string", - "uniqueItems": true - } - } - ], - "requestBody": { - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" - } - } - } - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "application/vnd.kubernetes.protobuf": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "application/yaml": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - } - }, - "description": "OK" - }, - "202": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "application/vnd.kubernetes.protobuf": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "application/yaml": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - } - }, - "description": "Accepted" - }, - "401": { - "description": "Unauthorized" - } - }, - "tags": [ - "resource_v1alpha2" - ], - "x-kubernetes-action": "delete", - "x-kubernetes-group-version-kind": { - "group": "resource.k8s.io", - "kind": "NodeResourceSlice", - "version": "v1alpha2" - } - }, - "get": { - "description": "read the specified NodeResourceSlice", - "operationId": "readResourceV1alpha2NodeResourceSlice", - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "application/vnd.kubernetes.protobuf": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "application/yaml": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - } - }, - "description": "OK" - }, - "401": { - "description": "Unauthorized" - } - }, - "tags": [ - "resource_v1alpha2" - ], - "x-kubernetes-action": "get", - "x-kubernetes-group-version-kind": { - "group": "resource.k8s.io", - "kind": "NodeResourceSlice", - "version": "v1alpha2" - } - }, - "parameters": [ - { - "description": "name of the NodeResourceSlice", - "in": "path", - "name": "name", - "required": true, - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", - "in": "query", - "name": "pretty", - "schema": { - "type": "string", - "uniqueItems": true - } - } - ], - "patch": { - "description": "partially update the specified NodeResourceSlice", - "operationId": "patchResourceV1alpha2NodeResourceSlice", - "parameters": [ - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch).", - "in": "query", - "name": "fieldManager", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", - "in": "query", - "name": "fieldValidation", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "Force is going to \"force\" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests.", - "in": "query", - "name": "force", - "schema": { - "type": "boolean", - "uniqueItems": true - } - } - ], - "requestBody": { - "content": { - "application/apply-patch+yaml": { - "schema": { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" - } - }, - "application/json-patch+json": { - "schema": { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" - } - }, - "application/merge-patch+json": { - "schema": { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" - } - }, - "application/strategic-merge-patch+json": { - "schema": { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" - } - } - }, - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "application/vnd.kubernetes.protobuf": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "application/yaml": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - } - }, - "description": "OK" - }, - "201": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "application/vnd.kubernetes.protobuf": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "application/yaml": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - } - }, - "description": "Created" - }, - "401": { - "description": "Unauthorized" - } - }, - "tags": [ - "resource_v1alpha2" - ], - "x-kubernetes-action": "patch", - "x-kubernetes-group-version-kind": { - "group": "resource.k8s.io", - "kind": "NodeResourceSlice", - "version": "v1alpha2" - } - }, - "put": { - "description": "replace the specified NodeResourceSlice", - "operationId": "replaceResourceV1alpha2NodeResourceSlice", - "parameters": [ - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", - "in": "query", - "name": "fieldManager", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", - "in": "query", - "name": "fieldValidation", - "schema": { - "type": "string", - "uniqueItems": true - } - } - ], - "requestBody": { - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - } - }, - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "application/vnd.kubernetes.protobuf": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "application/yaml": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - } - }, - "description": "OK" - }, - "201": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "application/vnd.kubernetes.protobuf": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - }, - "application/yaml": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.NodeResourceSlice" - } - } - }, - "description": "Created" - }, - "401": { - "description": "Unauthorized" - } - }, - "tags": [ - "resource_v1alpha2" - ], - "x-kubernetes-action": "put", - "x-kubernetes-group-version-kind": { - "group": "resource.k8s.io", - "kind": "NodeResourceSlice", - "version": "v1alpha2" - } - } - }, "/apis/resource.k8s.io/v1alpha2/podschedulingcontexts": { "get": { "description": "list or watch objects of kind PodSchedulingContext", @@ -9704,6 +8889,817 @@ } ] }, + "/apis/resource.k8s.io/v1alpha2/resourceslices": { + "delete": { + "description": "delete collection of ResourceSlice", + "operationId": "deleteResourceV1alpha2CollectionResourceSlice", + "parameters": [ + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "in": "query", + "name": "gracePeriodSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "in": "query", + "name": "orphanDependents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "in": "query", + "name": "propagationPolicy", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "in": "query", + "name": "sendInitialEvents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "deletecollection", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceSlice", + "version": "v1alpha2" + } + }, + "get": { + "description": "list or watch objects of kind ResourceSlice", + "operationId": "listResourceV1alpha2ResourceSlice", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "in": "query", + "name": "sendInitialEvents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSliceList" + } + }, + "application/json;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSliceList" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSliceList" + } + }, + "application/vnd.kubernetes.protobuf;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSliceList" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSliceList" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "list", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceSlice", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "post": { + "description": "create a ResourceSlice", + "operationId": "createResourceV1alpha2ResourceSlice", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + } + }, + "description": "Created" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "post", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceSlice", + "version": "v1alpha2" + } + } + }, + "/apis/resource.k8s.io/v1alpha2/resourceslices/{name}": { + "delete": { + "description": "delete a ResourceSlice", + "operationId": "deleteResourceV1alpha2ResourceSlice", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "in": "query", + "name": "gracePeriodSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "in": "query", + "name": "orphanDependents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "in": "query", + "name": "propagationPolicy", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + } + }, + "description": "OK" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "delete", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceSlice", + "version": "v1alpha2" + } + }, + "get": { + "description": "read the specified ResourceSlice", + "operationId": "readResourceV1alpha2ResourceSlice", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "get", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceSlice", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "name of the ResourceSlice", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "patch": { + "description": "partially update the specified ResourceSlice", + "operationId": "patchResourceV1alpha2ResourceSlice", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch).", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Force is going to \"force\" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests.", + "in": "query", + "name": "force", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/apply-patch+yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/json-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/merge-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/strategic-merge-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + } + }, + "description": "Created" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "patch", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceSlice", + "version": "v1alpha2" + } + }, + "put": { + "description": "replace the specified ResourceSlice", + "operationId": "replaceResourceV1alpha2ResourceSlice", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.resource.v1alpha2.ResourceSlice" + } + } + }, + "description": "Created" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "put", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceSlice", + "version": "v1alpha2" + } + } + }, "/apis/resource.k8s.io/v1alpha2/watch/namespaces/{namespace}/podschedulingcontexts": { "get": { "description": "watch individual changes to a list of PodSchedulingContext. deprecated: use the 'watch' parameter with a list operation instead.", @@ -11364,318 +11360,6 @@ } ] }, - "/apis/resource.k8s.io/v1alpha2/watch/noderesourceslices": { - "get": { - "description": "watch individual changes to a list of NodeResourceSlice. deprecated: use the 'watch' parameter with a list operation instead.", - "operationId": "watchResourceV1alpha2NodeResourceSliceList", - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "application/json;stream=watch": { - "schema": { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "application/vnd.kubernetes.protobuf": { - "schema": { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "application/vnd.kubernetes.protobuf;stream=watch": { - "schema": { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "application/yaml": { - "schema": { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - } - }, - "description": "OK" - }, - "401": { - "description": "Unauthorized" - } - }, - "tags": [ - "resource_v1alpha2" - ], - "x-kubernetes-action": "watchlist", - "x-kubernetes-group-version-kind": { - "group": "resource.k8s.io", - "kind": "NodeResourceSlice", - "version": "v1alpha2" - } - }, - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "schema": { - "type": "boolean", - "uniqueItems": true - } - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "schema": { - "type": "integer", - "uniqueItems": true - } - }, - { - "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", - "in": "query", - "name": "pretty", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", - "in": "query", - "name": "sendInitialEvents", - "schema": { - "type": "boolean", - "uniqueItems": true - } - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "schema": { - "type": "integer", - "uniqueItems": true - } - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "schema": { - "type": "boolean", - "uniqueItems": true - } - } - ] - }, - "/apis/resource.k8s.io/v1alpha2/watch/noderesourceslices/{name}": { - "get": { - "description": "watch changes to an object of kind NodeResourceSlice. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", - "operationId": "watchResourceV1alpha2NodeResourceSlice", - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "application/json;stream=watch": { - "schema": { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "application/vnd.kubernetes.protobuf": { - "schema": { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "application/vnd.kubernetes.protobuf;stream=watch": { - "schema": { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "application/yaml": { - "schema": { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - } - }, - "description": "OK" - }, - "401": { - "description": "Unauthorized" - } - }, - "tags": [ - "resource_v1alpha2" - ], - "x-kubernetes-action": "watch", - "x-kubernetes-group-version-kind": { - "group": "resource.k8s.io", - "kind": "NodeResourceSlice", - "version": "v1alpha2" - } - }, - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "schema": { - "type": "boolean", - "uniqueItems": true - } - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "schema": { - "type": "integer", - "uniqueItems": true - } - }, - { - "description": "name of the NodeResourceSlice", - "in": "path", - "name": "name", - "required": true, - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", - "in": "query", - "name": "pretty", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", - "in": "query", - "name": "sendInitialEvents", - "schema": { - "type": "boolean", - "uniqueItems": true - } - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "schema": { - "type": "integer", - "uniqueItems": true - } - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "schema": { - "type": "boolean", - "uniqueItems": true - } - } - ] - }, "/apis/resource.k8s.io/v1alpha2/watch/podschedulingcontexts": { "get": { "description": "watch individual changes to a list of PodSchedulingContext. deprecated: use the 'watch' parameter with a list operation instead.", @@ -12742,6 +12426,318 @@ } } ] + }, + "/apis/resource.k8s.io/v1alpha2/watch/resourceslices": { + "get": { + "description": "watch individual changes to a list of ResourceSlice. deprecated: use the 'watch' parameter with a list operation instead.", + "operationId": "watchResourceV1alpha2ResourceSliceList", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/json;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/vnd.kubernetes.protobuf;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "watchlist", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceSlice", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "in": "query", + "name": "sendInitialEvents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ] + }, + "/apis/resource.k8s.io/v1alpha2/watch/resourceslices/{name}": { + "get": { + "description": "watch changes to an object of kind ResourceSlice. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", + "operationId": "watchResourceV1alpha2ResourceSlice", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/json;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/vnd.kubernetes.protobuf;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [ + "resource_v1alpha2" + ], + "x-kubernetes-action": "watch", + "x-kubernetes-group-version-kind": { + "group": "resource.k8s.io", + "kind": "ResourceSlice", + "version": "v1alpha2" + } + }, + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "name of the ResourceSlice", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "in": "query", + "name": "sendInitialEvents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ] } } } diff --git a/pkg/apis/resource/register.go b/pkg/apis/resource/register.go index 0f1a5b17029..1d7b718abef 100644 --- a/pkg/apis/resource/register.go +++ b/pkg/apis/resource/register.go @@ -60,8 +60,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { &ResourceClaimTemplateList{}, &PodSchedulingContext{}, &PodSchedulingContextList{}, - &NodeResourceSlice{}, - &NodeResourceSliceList{}, + &ResourceSlice{}, + &ResourceSliceList{}, &ResourceClaimParameters{}, &ResourceClaimParametersList{}, &ResourceClassParameters{}, diff --git a/pkg/apis/resource/types.go b/pkg/apis/resource/types.go index a667b0ab71e..a5ece05d20a 100644 --- a/pkg/apis/resource/types.go +++ b/pkg/apis/resource/types.go @@ -205,7 +205,8 @@ type StructuredResourceHandle struct { // allocated. VendorClaimParameters runtime.Object - // NodeName is the name of the node providing the necessary resources. + // NodeName is the name of the node providing the necessary resources + // if the resources are local to a node. NodeName string // Results lists all allocated driver resources. @@ -479,20 +480,22 @@ type ResourceClaimTemplateList struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// NodeResourceSlice provides information about available +// ResourceSlice provides information about available // resources on individual nodes. -type NodeResourceSlice struct { +type ResourceSlice struct { metav1.TypeMeta // Standard object metadata metav1.ObjectMeta - // NodeName identifies the node where the capacity is available. - // A field selector can be used to list only NodeResourceSlice + // NodeName identifies the node which provides the resources + // if they are local to a node. + // + // A field selector can be used to list only ResourceSlice // objects with a certain node name. NodeName string // DriverName identifies the DRA driver providing the capacity information. - // A field selector can be used to list only NodeResourceSlice + // A field selector can be used to list only ResourceSlice // objects with a certain driver name. DriverName string @@ -507,14 +510,14 @@ type NodeResourceModel struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// NodeResourceSliceList is a collection of NodeResourceSlices. -type NodeResourceSliceList struct { +// ResourceSliceList is a collection of ResourceSlices. +type ResourceSliceList struct { metav1.TypeMeta // Standard list metadata metav1.ListMeta // Items is the list of node resource capacity objects. - Items []NodeResourceSlice + Items []ResourceSlice } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/apis/resource/v1alpha2/conversion.go b/pkg/apis/resource/v1alpha2/conversion.go index 5e35ad6dee0..456a8b243e1 100644 --- a/pkg/apis/resource/v1alpha2/conversion.go +++ b/pkg/apis/resource/v1alpha2/conversion.go @@ -23,13 +23,13 @@ import ( ) func addConversionFuncs(scheme *runtime.Scheme) error { - if err := scheme.AddFieldLabelConversionFunc(SchemeGroupVersion.WithKind("NodeResourceSlice"), + if err := scheme.AddFieldLabelConversionFunc(SchemeGroupVersion.WithKind("ResourceSlice"), func(label, value string) (string, string, error) { switch label { case "metadata.name", "nodeName", "driverName": return label, value, nil default: - return "", "", fmt.Errorf("field label not supported for %s: %s", SchemeGroupVersion.WithKind("NodeResourceSlice"), label) + return "", "", fmt.Errorf("field label not supported for %s: %s", SchemeGroupVersion.WithKind("ResourceSlice"), label) } }); err != nil { return err diff --git a/pkg/apis/resource/v1alpha2/zz_generated.conversion.go b/pkg/apis/resource/v1alpha2/zz_generated.conversion.go index e99c229accb..a9dba818c48 100644 --- a/pkg/apis/resource/v1alpha2/zz_generated.conversion.go +++ b/pkg/apis/resource/v1alpha2/zz_generated.conversion.go @@ -181,26 +181,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1alpha2.NodeResourceSlice)(nil), (*resource.NodeResourceSlice)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1alpha2_NodeResourceSlice_To_resource_NodeResourceSlice(a.(*v1alpha2.NodeResourceSlice), b.(*resource.NodeResourceSlice), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*resource.NodeResourceSlice)(nil), (*v1alpha2.NodeResourceSlice)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_resource_NodeResourceSlice_To_v1alpha2_NodeResourceSlice(a.(*resource.NodeResourceSlice), b.(*v1alpha2.NodeResourceSlice), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*v1alpha2.NodeResourceSliceList)(nil), (*resource.NodeResourceSliceList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1alpha2_NodeResourceSliceList_To_resource_NodeResourceSliceList(a.(*v1alpha2.NodeResourceSliceList), b.(*resource.NodeResourceSliceList), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*resource.NodeResourceSliceList)(nil), (*v1alpha2.NodeResourceSliceList)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_resource_NodeResourceSliceList_To_v1alpha2_NodeResourceSliceList(a.(*resource.NodeResourceSliceList), b.(*v1alpha2.NodeResourceSliceList), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*v1alpha2.PodSchedulingContext)(nil), (*resource.PodSchedulingContext)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha2_PodSchedulingContext_To_resource_PodSchedulingContext(a.(*v1alpha2.PodSchedulingContext), b.(*resource.PodSchedulingContext), scope) }); err != nil { @@ -461,6 +441,26 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*v1alpha2.ResourceSlice)(nil), (*resource.ResourceSlice)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_ResourceSlice_To_resource_ResourceSlice(a.(*v1alpha2.ResourceSlice), b.(*resource.ResourceSlice), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.ResourceSlice)(nil), (*v1alpha2.ResourceSlice)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_ResourceSlice_To_v1alpha2_ResourceSlice(a.(*resource.ResourceSlice), b.(*v1alpha2.ResourceSlice), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.ResourceSliceList)(nil), (*resource.ResourceSliceList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_ResourceSliceList_To_resource_ResourceSliceList(a.(*v1alpha2.ResourceSliceList), b.(*resource.ResourceSliceList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*resource.ResourceSliceList)(nil), (*v1alpha2.ResourceSliceList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_resource_ResourceSliceList_To_v1alpha2_ResourceSliceList(a.(*resource.ResourceSliceList), b.(*v1alpha2.ResourceSliceList), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*v1alpha2.StructuredResourceHandle)(nil), (*resource.StructuredResourceHandle)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha2_StructuredResourceHandle_To_resource_StructuredResourceHandle(a.(*v1alpha2.StructuredResourceHandle), b.(*resource.StructuredResourceHandle), scope) }); err != nil { @@ -846,58 +846,6 @@ func Convert_resource_NodeResourceModel_To_v1alpha2_NodeResourceModel(in *resour return autoConvert_resource_NodeResourceModel_To_v1alpha2_NodeResourceModel(in, out, s) } -func autoConvert_v1alpha2_NodeResourceSlice_To_resource_NodeResourceSlice(in *v1alpha2.NodeResourceSlice, out *resource.NodeResourceSlice, s conversion.Scope) error { - out.ObjectMeta = in.ObjectMeta - out.NodeName = in.NodeName - out.DriverName = in.DriverName - if err := Convert_v1alpha2_NodeResourceModel_To_resource_NodeResourceModel(&in.NodeResourceModel, &out.NodeResourceModel, s); err != nil { - return err - } - return nil -} - -// Convert_v1alpha2_NodeResourceSlice_To_resource_NodeResourceSlice is an autogenerated conversion function. -func Convert_v1alpha2_NodeResourceSlice_To_resource_NodeResourceSlice(in *v1alpha2.NodeResourceSlice, out *resource.NodeResourceSlice, s conversion.Scope) error { - return autoConvert_v1alpha2_NodeResourceSlice_To_resource_NodeResourceSlice(in, out, s) -} - -func autoConvert_resource_NodeResourceSlice_To_v1alpha2_NodeResourceSlice(in *resource.NodeResourceSlice, out *v1alpha2.NodeResourceSlice, s conversion.Scope) error { - out.ObjectMeta = in.ObjectMeta - out.NodeName = in.NodeName - out.DriverName = in.DriverName - if err := Convert_resource_NodeResourceModel_To_v1alpha2_NodeResourceModel(&in.NodeResourceModel, &out.NodeResourceModel, s); err != nil { - return err - } - return nil -} - -// Convert_resource_NodeResourceSlice_To_v1alpha2_NodeResourceSlice is an autogenerated conversion function. -func Convert_resource_NodeResourceSlice_To_v1alpha2_NodeResourceSlice(in *resource.NodeResourceSlice, out *v1alpha2.NodeResourceSlice, s conversion.Scope) error { - return autoConvert_resource_NodeResourceSlice_To_v1alpha2_NodeResourceSlice(in, out, s) -} - -func autoConvert_v1alpha2_NodeResourceSliceList_To_resource_NodeResourceSliceList(in *v1alpha2.NodeResourceSliceList, out *resource.NodeResourceSliceList, s conversion.Scope) error { - out.ListMeta = in.ListMeta - out.Items = *(*[]resource.NodeResourceSlice)(unsafe.Pointer(&in.Items)) - return nil -} - -// Convert_v1alpha2_NodeResourceSliceList_To_resource_NodeResourceSliceList is an autogenerated conversion function. -func Convert_v1alpha2_NodeResourceSliceList_To_resource_NodeResourceSliceList(in *v1alpha2.NodeResourceSliceList, out *resource.NodeResourceSliceList, s conversion.Scope) error { - return autoConvert_v1alpha2_NodeResourceSliceList_To_resource_NodeResourceSliceList(in, out, s) -} - -func autoConvert_resource_NodeResourceSliceList_To_v1alpha2_NodeResourceSliceList(in *resource.NodeResourceSliceList, out *v1alpha2.NodeResourceSliceList, s conversion.Scope) error { - out.ListMeta = in.ListMeta - out.Items = *(*[]v1alpha2.NodeResourceSlice)(unsafe.Pointer(&in.Items)) - return nil -} - -// Convert_resource_NodeResourceSliceList_To_v1alpha2_NodeResourceSliceList is an autogenerated conversion function. -func Convert_resource_NodeResourceSliceList_To_v1alpha2_NodeResourceSliceList(in *resource.NodeResourceSliceList, out *v1alpha2.NodeResourceSliceList, s conversion.Scope) error { - return autoConvert_resource_NodeResourceSliceList_To_v1alpha2_NodeResourceSliceList(in, out, s) -} - func autoConvert_v1alpha2_PodSchedulingContext_To_resource_PodSchedulingContext(in *v1alpha2.PodSchedulingContext, out *resource.PodSchedulingContext, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta if err := Convert_v1alpha2_PodSchedulingContextSpec_To_resource_PodSchedulingContextSpec(&in.Spec, &out.Spec, s); err != nil { @@ -1668,6 +1616,58 @@ func Convert_resource_ResourceRequestModel_To_v1alpha2_ResourceRequestModel(in * return autoConvert_resource_ResourceRequestModel_To_v1alpha2_ResourceRequestModel(in, out, s) } +func autoConvert_v1alpha2_ResourceSlice_To_resource_ResourceSlice(in *v1alpha2.ResourceSlice, out *resource.ResourceSlice, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + out.NodeName = in.NodeName + out.DriverName = in.DriverName + if err := Convert_v1alpha2_NodeResourceModel_To_resource_NodeResourceModel(&in.NodeResourceModel, &out.NodeResourceModel, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha2_ResourceSlice_To_resource_ResourceSlice is an autogenerated conversion function. +func Convert_v1alpha2_ResourceSlice_To_resource_ResourceSlice(in *v1alpha2.ResourceSlice, out *resource.ResourceSlice, s conversion.Scope) error { + return autoConvert_v1alpha2_ResourceSlice_To_resource_ResourceSlice(in, out, s) +} + +func autoConvert_resource_ResourceSlice_To_v1alpha2_ResourceSlice(in *resource.ResourceSlice, out *v1alpha2.ResourceSlice, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + out.NodeName = in.NodeName + out.DriverName = in.DriverName + if err := Convert_resource_NodeResourceModel_To_v1alpha2_NodeResourceModel(&in.NodeResourceModel, &out.NodeResourceModel, s); err != nil { + return err + } + return nil +} + +// Convert_resource_ResourceSlice_To_v1alpha2_ResourceSlice is an autogenerated conversion function. +func Convert_resource_ResourceSlice_To_v1alpha2_ResourceSlice(in *resource.ResourceSlice, out *v1alpha2.ResourceSlice, s conversion.Scope) error { + return autoConvert_resource_ResourceSlice_To_v1alpha2_ResourceSlice(in, out, s) +} + +func autoConvert_v1alpha2_ResourceSliceList_To_resource_ResourceSliceList(in *v1alpha2.ResourceSliceList, out *resource.ResourceSliceList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]resource.ResourceSlice)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_v1alpha2_ResourceSliceList_To_resource_ResourceSliceList is an autogenerated conversion function. +func Convert_v1alpha2_ResourceSliceList_To_resource_ResourceSliceList(in *v1alpha2.ResourceSliceList, out *resource.ResourceSliceList, s conversion.Scope) error { + return autoConvert_v1alpha2_ResourceSliceList_To_resource_ResourceSliceList(in, out, s) +} + +func autoConvert_resource_ResourceSliceList_To_v1alpha2_ResourceSliceList(in *resource.ResourceSliceList, out *v1alpha2.ResourceSliceList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]v1alpha2.ResourceSlice)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_resource_ResourceSliceList_To_v1alpha2_ResourceSliceList is an autogenerated conversion function. +func Convert_resource_ResourceSliceList_To_v1alpha2_ResourceSliceList(in *resource.ResourceSliceList, out *v1alpha2.ResourceSliceList, s conversion.Scope) error { + return autoConvert_resource_ResourceSliceList_To_v1alpha2_ResourceSliceList(in, out, s) +} + func autoConvert_v1alpha2_StructuredResourceHandle_To_resource_StructuredResourceHandle(in *v1alpha2.StructuredResourceHandle, out *resource.StructuredResourceHandle, s conversion.Scope) error { if err := runtime.Convert_runtime_RawExtension_To_runtime_Object(&in.VendorClassParameters, &out.VendorClassParameters, s); err != nil { return err diff --git a/pkg/apis/resource/validation/validation.go b/pkg/apis/resource/validation/validation.go index 713501de9c1..12afb50327d 100644 --- a/pkg/apis/resource/validation/validation.go +++ b/pkg/apis/resource/validation/validation.go @@ -220,7 +220,9 @@ func validateResourceHandles(resourceHandles []resource.ResourceHandle, maxSize func validateStructuredResourceHandle(handle *resource.StructuredResourceHandle, fldPath *field.Path) field.ErrorList { var allErrs field.ErrorList - allErrs = append(allErrs, validateNodeName(handle.NodeName, fldPath.Child("nodeName"))...) + if handle.NodeName != "" { + allErrs = append(allErrs, validateNodeName(handle.NodeName, fldPath.Child("nodeName"))...) + } allErrs = append(allErrs, validateDriverAllocationResults(handle.Results, fldPath.Child("results"))...) return allErrs } @@ -388,12 +390,14 @@ func validateNodeName(name string, fldPath *field.Path) field.ErrorList { return allErrs } -// ValidateNodeResourceSlice tests if a NodeResourceSlice object is valid. -func ValidateNodeResourceSlice(nodeResourceSlice *resource.NodeResourceSlice) field.ErrorList { - allErrs := corevalidation.ValidateObjectMeta(&nodeResourceSlice.ObjectMeta, false, apimachineryvalidation.NameIsDNSSubdomain, field.NewPath("metadata")) - allErrs = append(allErrs, validateNodeName(nodeResourceSlice.NodeName, field.NewPath("nodeName"))...) - allErrs = append(allErrs, validateResourceDriverName(nodeResourceSlice.DriverName, field.NewPath("driverName"))...) - allErrs = append(allErrs, validateNodeResourceModel(&nodeResourceSlice.NodeResourceModel, nil)...) +// ValidateResourceSlice tests if a ResourceSlice object is valid. +func ValidateResourceSlice(resourceSlice *resource.ResourceSlice) field.ErrorList { + allErrs := corevalidation.ValidateObjectMeta(&resourceSlice.ObjectMeta, false, apimachineryvalidation.NameIsDNSSubdomain, field.NewPath("metadata")) + if resourceSlice.NodeName != "" { + allErrs = append(allErrs, validateNodeName(resourceSlice.NodeName, field.NewPath("nodeName"))...) + } + allErrs = append(allErrs, validateResourceDriverName(resourceSlice.DriverName, field.NewPath("driverName"))...) + allErrs = append(allErrs, validateNodeResourceModel(&resourceSlice.NodeResourceModel, nil)...) return allErrs } @@ -415,12 +419,12 @@ func validateNodeResourceModel(model *resource.NodeResourceModel, fldPath *field return allErrs } -// ValidateNodeResourceSlice tests if a NodeResourceSlice update is valid. -func ValidateNodeResourceSliceUpdate(nodeResourceSlice, oldNodeResourceSlice *resource.NodeResourceSlice) field.ErrorList { - allErrs := corevalidation.ValidateObjectMetaUpdate(&nodeResourceSlice.ObjectMeta, &oldNodeResourceSlice.ObjectMeta, field.NewPath("metadata")) - allErrs = append(allErrs, ValidateNodeResourceSlice(nodeResourceSlice)...) - allErrs = append(allErrs, apimachineryvalidation.ValidateImmutableField(nodeResourceSlice.NodeName, oldNodeResourceSlice.NodeName, field.NewPath("nodeName"))...) - allErrs = append(allErrs, apimachineryvalidation.ValidateImmutableField(nodeResourceSlice.DriverName, oldNodeResourceSlice.DriverName, field.NewPath("driverName"))...) +// ValidateResourceSlice tests if a ResourceSlice update is valid. +func ValidateResourceSliceUpdate(resourceSlice, oldResourceSlice *resource.ResourceSlice) field.ErrorList { + allErrs := corevalidation.ValidateObjectMetaUpdate(&resourceSlice.ObjectMeta, &oldResourceSlice.ObjectMeta, field.NewPath("metadata")) + allErrs = append(allErrs, ValidateResourceSlice(resourceSlice)...) + allErrs = append(allErrs, apimachineryvalidation.ValidateImmutableField(resourceSlice.NodeName, oldResourceSlice.NodeName, field.NewPath("nodeName"))...) + allErrs = append(allErrs, apimachineryvalidation.ValidateImmutableField(resourceSlice.DriverName, oldResourceSlice.DriverName, field.NewPath("driverName"))...) return allErrs } diff --git a/pkg/apis/resource/validation/validation_resourceclaim_test.go b/pkg/apis/resource/validation/validation_resourceclaim_test.go index d4582e479da..e5b59dba9f8 100644 --- a/pkg/apis/resource/validation/validation_resourceclaim_test.go +++ b/pkg/apis/resource/validation/validation_resourceclaim_test.go @@ -387,42 +387,8 @@ func TestValidateClaimStatusUpdate(t *testing.T) { claim.Status.Allocation = &resource.AllocationResult{ ResourceHandles: []resource.ResourceHandle{ { - DriverName: "valid", - StructuredData: &resource.StructuredResourceHandle{ - NodeName: "worker", - }, - }, - }, - } - return claim - }, - }, - "invalid-add-allocation-structured": { - wantFailures: field.ErrorList{ - field.Invalid(field.NewPath("status", "allocation", "resourceHandles").Index(0).Child("structuredData", "nodeName"), "", "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')"), - field.Required(field.NewPath("status", "allocation", "resourceHandles").Index(0).Child("structuredData", "results").Index(1), "exactly one structured model field must be set"), - }, - oldClaim: validClaim, - update: func(claim *resource.ResourceClaim) *resource.ResourceClaim { - claim.Status.DriverName = "valid" - claim.Status.Allocation = &resource.AllocationResult{ - ResourceHandles: []resource.ResourceHandle{ - { - DriverName: "valid", - StructuredData: &resource.StructuredResourceHandle{ - Results: []resource.DriverAllocationResult{ - { - AllocationResultModel: resource.AllocationResultModel{ - NamedResources: &resource.NamedResourcesAllocationResult{ - Name: "some-resource-instance", - }, - }, - }, - { - AllocationResultModel: resource.AllocationResultModel{}, // invalid - }, - }, - }, + DriverName: "valid", + StructuredData: &resource.StructuredResourceHandle{}, }, }, } @@ -446,6 +412,39 @@ func TestValidateClaimStatusUpdate(t *testing.T) { return claim }, }, + "invalid-add-allocation-structured": { + wantFailures: field.ErrorList{ + field.Invalid(field.NewPath("status", "allocation", "resourceHandles").Index(0).Child("structuredData", "nodeName"), "&^!", "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')"), + field.Required(field.NewPath("status", "allocation", "resourceHandles").Index(0).Child("structuredData", "results").Index(1), "exactly one structured model field must be set"), + }, + oldClaim: validClaim, + update: func(claim *resource.ResourceClaim) *resource.ResourceClaim { + claim.Status.DriverName = "valid" + claim.Status.Allocation = &resource.AllocationResult{ + ResourceHandles: []resource.ResourceHandle{ + { + DriverName: "valid", + StructuredData: &resource.StructuredResourceHandle{ + NodeName: "&^!", + Results: []resource.DriverAllocationResult{ + { + AllocationResultModel: resource.AllocationResultModel{ + NamedResources: &resource.NamedResourcesAllocationResult{ + Name: "some-resource-instance", + }, + }, + }, + { + AllocationResultModel: resource.AllocationResultModel{}, // invalid + }, + }, + }, + }, + }, + } + return claim + }, + }, "invalid-duplicated-data": { wantFailures: field.ErrorList{field.Invalid(field.NewPath("status", "allocation", "resourceHandles").Index(0), nil, "data and structuredData are mutually exclusive")}, oldClaim: validClaim, diff --git a/pkg/apis/resource/validation/validation_noderesourceslice_test.go b/pkg/apis/resource/validation/validation_resourceslice_test.go similarity index 62% rename from pkg/apis/resource/validation/validation_noderesourceslice_test.go rename to pkg/apis/resource/validation/validation_resourceslice_test.go index e0ada2e7ec3..97681c6758f 100644 --- a/pkg/apis/resource/validation/validation_noderesourceslice_test.go +++ b/pkg/apis/resource/validation/validation_resourceslice_test.go @@ -27,8 +27,8 @@ import ( "k8s.io/utils/ptr" ) -func testNodeResourceSlice(name, nodeName, driverName string) *resource.NodeResourceSlice { - return &resource.NodeResourceSlice{ +func testResourceSlice(name, nodeName, driverName string) *resource.ResourceSlice { + return &resource.ResourceSlice{ ObjectMeta: metav1.ObjectMeta{ Name: name, }, @@ -40,7 +40,7 @@ func testNodeResourceSlice(name, nodeName, driverName string) *resource.NodeReso } } -func TestValidateNodeResourceSlice(t *testing.T) { +func TestValidateResourceSlice(t *testing.T) { goodName := "foo" badName := "!@#$%^" driverName := "test.example.com" @@ -48,65 +48,65 @@ func TestValidateNodeResourceSlice(t *testing.T) { badValue := "spaces not allowed" scenarios := map[string]struct { - slice *resource.NodeResourceSlice + slice *resource.ResourceSlice wantFailures field.ErrorList }{ "good": { - slice: testNodeResourceSlice(goodName, goodName, driverName), + slice: testResourceSlice(goodName, goodName, driverName), }, "missing-name": { wantFailures: field.ErrorList{field.Required(field.NewPath("metadata", "name"), "name or generateName is required")}, - slice: testNodeResourceSlice("", goodName, driverName), + slice: testResourceSlice("", goodName, driverName), }, "bad-name": { wantFailures: field.ErrorList{field.Invalid(field.NewPath("metadata", "name"), badName, "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')")}, - slice: testNodeResourceSlice(badName, goodName, driverName), + slice: testResourceSlice(badName, goodName, driverName), }, "generate-name": { - slice: func() *resource.NodeResourceSlice { - slice := testNodeResourceSlice(goodName, goodName, driverName) + slice: func() *resource.ResourceSlice { + slice := testResourceSlice(goodName, goodName, driverName) slice.GenerateName = "prefix-" return slice }(), }, "uid": { - slice: func() *resource.NodeResourceSlice { - slice := testNodeResourceSlice(goodName, goodName, driverName) + slice: func() *resource.ResourceSlice { + slice := testResourceSlice(goodName, goodName, driverName) slice.UID = "ac051fac-2ead-46d9-b8b4-4e0fbeb7455d" return slice }(), }, "resource-version": { - slice: func() *resource.NodeResourceSlice { - slice := testNodeResourceSlice(goodName, goodName, driverName) + slice: func() *resource.ResourceSlice { + slice := testResourceSlice(goodName, goodName, driverName) slice.ResourceVersion = "1" return slice }(), }, "generation": { - slice: func() *resource.NodeResourceSlice { - slice := testNodeResourceSlice(goodName, goodName, driverName) + slice: func() *resource.ResourceSlice { + slice := testResourceSlice(goodName, goodName, driverName) slice.Generation = 100 return slice }(), }, "creation-timestamp": { - slice: func() *resource.NodeResourceSlice { - slice := testNodeResourceSlice(goodName, goodName, driverName) + slice: func() *resource.ResourceSlice { + slice := testResourceSlice(goodName, goodName, driverName) slice.CreationTimestamp = now return slice }(), }, "deletion-grace-period-seconds": { - slice: func() *resource.NodeResourceSlice { - slice := testNodeResourceSlice(goodName, goodName, driverName) + slice: func() *resource.ResourceSlice { + slice := testResourceSlice(goodName, goodName, driverName) slice.DeletionGracePeriodSeconds = ptr.To[int64](10) return slice }(), }, "owner-references": { - slice: func() *resource.NodeResourceSlice { - slice := testNodeResourceSlice(goodName, goodName, driverName) + slice: func() *resource.ResourceSlice { + slice := testResourceSlice(goodName, goodName, driverName) slice.OwnerReferences = []metav1.OwnerReference{ { APIVersion: "v1", @@ -119,8 +119,8 @@ func TestValidateNodeResourceSlice(t *testing.T) { }(), }, "finalizers": { - slice: func() *resource.NodeResourceSlice { - slice := testNodeResourceSlice(goodName, goodName, driverName) + slice: func() *resource.ResourceSlice { + slice := testResourceSlice(goodName, goodName, driverName) slice.Finalizers = []string{ "example.com/foo", } @@ -128,8 +128,8 @@ func TestValidateNodeResourceSlice(t *testing.T) { }(), }, "managed-fields": { - slice: func() *resource.NodeResourceSlice { - slice := testNodeResourceSlice(goodName, goodName, driverName) + slice: func() *resource.ResourceSlice { + slice := testResourceSlice(goodName, goodName, driverName) slice.ManagedFields = []metav1.ManagedFieldsEntry{ { FieldsType: "FieldsV1", @@ -142,8 +142,8 @@ func TestValidateNodeResourceSlice(t *testing.T) { }(), }, "good-labels": { - slice: func() *resource.NodeResourceSlice { - slice := testNodeResourceSlice(goodName, goodName, driverName) + slice: func() *resource.ResourceSlice { + slice := testResourceSlice(goodName, goodName, driverName) slice.Labels = map[string]string{ "apps.kubernetes.io/name": "test", } @@ -152,8 +152,8 @@ func TestValidateNodeResourceSlice(t *testing.T) { }, "bad-labels": { wantFailures: field.ErrorList{field.Invalid(field.NewPath("metadata", "labels"), badValue, "a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyValue', or 'my_value', or '12345', regex used for validation is '(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?')")}, - slice: func() *resource.NodeResourceSlice { - slice := testNodeResourceSlice(goodName, goodName, driverName) + slice: func() *resource.ResourceSlice { + slice := testResourceSlice(goodName, goodName, driverName) slice.Labels = map[string]string{ "hello-world": badValue, } @@ -161,8 +161,8 @@ func TestValidateNodeResourceSlice(t *testing.T) { }(), }, "good-annotations": { - slice: func() *resource.NodeResourceSlice { - slice := testNodeResourceSlice(goodName, goodName, driverName) + slice: func() *resource.ResourceSlice { + slice := testResourceSlice(goodName, goodName, driverName) slice.Annotations = map[string]string{ "foo": "bar", } @@ -171,8 +171,8 @@ func TestValidateNodeResourceSlice(t *testing.T) { }, "bad-annotations": { wantFailures: field.ErrorList{field.Invalid(field.NewPath("metadata", "annotations"), badName, "name part must consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')")}, - slice: func() *resource.NodeResourceSlice { - slice := testNodeResourceSlice(goodName, goodName, driverName) + slice: func() *resource.ResourceSlice { + slice := testResourceSlice(goodName, goodName, driverName) slice.Annotations = map[string]string{ badName: "hello world", } @@ -181,17 +181,17 @@ func TestValidateNodeResourceSlice(t *testing.T) { }, "bad-nodename": { wantFailures: field.ErrorList{field.Invalid(field.NewPath("nodeName"), badName, "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')")}, - slice: testNodeResourceSlice(goodName, badName, driverName), + slice: testResourceSlice(goodName, badName, driverName), }, "bad-drivername": { wantFailures: field.ErrorList{field.Invalid(field.NewPath("driverName"), badName, "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')")}, - slice: testNodeResourceSlice(goodName, goodName, badName), + slice: testResourceSlice(goodName, goodName, badName), }, "empty-model": { wantFailures: field.ErrorList{field.Required(nil, "exactly one structured model field must be set")}, - slice: func() *resource.NodeResourceSlice { - slice := testNodeResourceSlice(goodName, goodName, driverName) + slice: func() *resource.ResourceSlice { + slice := testResourceSlice(goodName, goodName, driverName) slice.NodeResourceModel = resource.NodeResourceModel{} return slice }(), @@ -200,45 +200,45 @@ func TestValidateNodeResourceSlice(t *testing.T) { for name, scenario := range scenarios { t.Run(name, func(t *testing.T) { - errs := ValidateNodeResourceSlice(scenario.slice) + errs := ValidateResourceSlice(scenario.slice) assert.Equal(t, scenario.wantFailures, errs) }) } } -func TestValidateNodeResourceSliceUpdate(t *testing.T) { +func TestValidateResourceSliceUpdate(t *testing.T) { name := "valid" - validNodeResourceSlice := testNodeResourceSlice(name, name, name) + validResourceSlice := testResourceSlice(name, name, name) scenarios := map[string]struct { - oldNodeResourceSlice *resource.NodeResourceSlice - update func(slice *resource.NodeResourceSlice) *resource.NodeResourceSlice - wantFailures field.ErrorList + oldResourceSlice *resource.ResourceSlice + update func(slice *resource.ResourceSlice) *resource.ResourceSlice + wantFailures field.ErrorList }{ "valid-no-op-update": { - oldNodeResourceSlice: validNodeResourceSlice, - update: func(slice *resource.NodeResourceSlice) *resource.NodeResourceSlice { return slice }, + oldResourceSlice: validResourceSlice, + update: func(slice *resource.ResourceSlice) *resource.ResourceSlice { return slice }, }, "invalid-name-update": { - oldNodeResourceSlice: validNodeResourceSlice, - update: func(slice *resource.NodeResourceSlice) *resource.NodeResourceSlice { + oldResourceSlice: validResourceSlice, + update: func(slice *resource.ResourceSlice) *resource.ResourceSlice { slice.Name += "-update" return slice }, wantFailures: field.ErrorList{field.Invalid(field.NewPath("metadata", "name"), name+"-update", "field is immutable")}, }, "invalid-update-nodename": { - wantFailures: field.ErrorList{field.Invalid(field.NewPath("nodeName"), name+"-updated", "field is immutable")}, - oldNodeResourceSlice: validNodeResourceSlice, - update: func(slice *resource.NodeResourceSlice) *resource.NodeResourceSlice { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("nodeName"), name+"-updated", "field is immutable")}, + oldResourceSlice: validResourceSlice, + update: func(slice *resource.ResourceSlice) *resource.ResourceSlice { slice.NodeName += "-updated" return slice }, }, "invalid-update-drivername": { - wantFailures: field.ErrorList{field.Invalid(field.NewPath("driverName"), name+"-updated", "field is immutable")}, - oldNodeResourceSlice: validNodeResourceSlice, - update: func(slice *resource.NodeResourceSlice) *resource.NodeResourceSlice { + wantFailures: field.ErrorList{field.Invalid(field.NewPath("driverName"), name+"-updated", "field is immutable")}, + oldResourceSlice: validResourceSlice, + update: func(slice *resource.ResourceSlice) *resource.ResourceSlice { slice.DriverName += "-updated" return slice }, @@ -247,8 +247,8 @@ func TestValidateNodeResourceSliceUpdate(t *testing.T) { for name, scenario := range scenarios { t.Run(name, func(t *testing.T) { - scenario.oldNodeResourceSlice.ResourceVersion = "1" - errs := ValidateNodeResourceSliceUpdate(scenario.update(scenario.oldNodeResourceSlice.DeepCopy()), scenario.oldNodeResourceSlice) + scenario.oldResourceSlice.ResourceVersion = "1" + errs := ValidateResourceSliceUpdate(scenario.update(scenario.oldResourceSlice.DeepCopy()), scenario.oldResourceSlice) assert.Equal(t, scenario.wantFailures, errs) }) } diff --git a/pkg/apis/resource/zz_generated.deepcopy.go b/pkg/apis/resource/zz_generated.deepcopy.go index df0fd44e2d2..98077f25a2c 100644 --- a/pkg/apis/resource/zz_generated.deepcopy.go +++ b/pkg/apis/resource/zz_generated.deepcopy.go @@ -346,66 +346,6 @@ func (in *NodeResourceModel) DeepCopy() *NodeResourceModel { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NodeResourceSlice) DeepCopyInto(out *NodeResourceSlice) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.NodeResourceModel.DeepCopyInto(&out.NodeResourceModel) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeResourceSlice. -func (in *NodeResourceSlice) DeepCopy() *NodeResourceSlice { - if in == nil { - return nil - } - out := new(NodeResourceSlice) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *NodeResourceSlice) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NodeResourceSliceList) DeepCopyInto(out *NodeResourceSliceList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]NodeResourceSlice, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeResourceSliceList. -func (in *NodeResourceSliceList) DeepCopy() *NodeResourceSliceList { - if in == nil { - return nil - } - out := new(NodeResourceSliceList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *NodeResourceSliceList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PodSchedulingContext) DeepCopyInto(out *PodSchedulingContext) { *out = *in @@ -1089,6 +1029,66 @@ func (in *ResourceRequestModel) DeepCopy() *ResourceRequestModel { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceSlice) DeepCopyInto(out *ResourceSlice) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.NodeResourceModel.DeepCopyInto(&out.NodeResourceModel) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceSlice. +func (in *ResourceSlice) DeepCopy() *ResourceSlice { + if in == nil { + return nil + } + out := new(ResourceSlice) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ResourceSlice) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceSliceList) DeepCopyInto(out *ResourceSliceList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ResourceSlice, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceSliceList. +func (in *ResourceSliceList) DeepCopy() *ResourceSliceList { + if in == nil { + return nil + } + out := new(ResourceSliceList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ResourceSliceList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *StructuredResourceHandle) DeepCopyInto(out *StructuredResourceHandle) { *out = *in diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index 32ac61db12d..06f001bca99 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -881,8 +881,6 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "k8s.io/api/resource/v1alpha2.NamedResourcesResources": schema_k8sio_api_resource_v1alpha2_NamedResourcesResources(ref), "k8s.io/api/resource/v1alpha2.NamedResourcesStringSlice": schema_k8sio_api_resource_v1alpha2_NamedResourcesStringSlice(ref), "k8s.io/api/resource/v1alpha2.NodeResourceModel": schema_k8sio_api_resource_v1alpha2_NodeResourceModel(ref), - "k8s.io/api/resource/v1alpha2.NodeResourceSlice": schema_k8sio_api_resource_v1alpha2_NodeResourceSlice(ref), - "k8s.io/api/resource/v1alpha2.NodeResourceSliceList": schema_k8sio_api_resource_v1alpha2_NodeResourceSliceList(ref), "k8s.io/api/resource/v1alpha2.PodSchedulingContext": schema_k8sio_api_resource_v1alpha2_PodSchedulingContext(ref), "k8s.io/api/resource/v1alpha2.PodSchedulingContextList": schema_k8sio_api_resource_v1alpha2_PodSchedulingContextList(ref), "k8s.io/api/resource/v1alpha2.PodSchedulingContextSpec": schema_k8sio_api_resource_v1alpha2_PodSchedulingContextSpec(ref), @@ -909,6 +907,8 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "k8s.io/api/resource/v1alpha2.ResourceHandle": schema_k8sio_api_resource_v1alpha2_ResourceHandle(ref), "k8s.io/api/resource/v1alpha2.ResourceRequest": schema_k8sio_api_resource_v1alpha2_ResourceRequest(ref), "k8s.io/api/resource/v1alpha2.ResourceRequestModel": schema_k8sio_api_resource_v1alpha2_ResourceRequestModel(ref), + "k8s.io/api/resource/v1alpha2.ResourceSlice": schema_k8sio_api_resource_v1alpha2_ResourceSlice(ref), + "k8s.io/api/resource/v1alpha2.ResourceSliceList": schema_k8sio_api_resource_v1alpha2_ResourceSliceList(ref), "k8s.io/api/resource/v1alpha2.StructuredResourceHandle": schema_k8sio_api_resource_v1alpha2_StructuredResourceHandle(ref), "k8s.io/api/resource/v1alpha2.VendorParameters": schema_k8sio_api_resource_v1alpha2_VendorParameters(ref), "k8s.io/api/scheduling/v1.PriorityClass": schema_k8sio_api_scheduling_v1_PriorityClass(ref), @@ -45195,116 +45195,6 @@ func schema_k8sio_api_resource_v1alpha2_NodeResourceModel(ref common.ReferenceCa } } -func schema_k8sio_api_resource_v1alpha2_NodeResourceSlice(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "NodeResourceSlice provides information about available resources on individual nodes.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Description: "Standard object metadata", - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), - }, - }, - "nodeName": { - SchemaProps: spec.SchemaProps{ - Description: "NodeName identifies the node where the capacity is available. A field selector can be used to list only NodeResourceSlice objects with a certain node name.", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "driverName": { - SchemaProps: spec.SchemaProps{ - Description: "DriverName identifies the DRA driver providing the capacity information. A field selector can be used to list only NodeResourceSlice objects with a certain driver name.", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "namedResources": { - SchemaProps: spec.SchemaProps{ - Description: "NamedResources describes available resources using the named resources model.", - Ref: ref("k8s.io/api/resource/v1alpha2.NamedResourcesResources"), - }, - }, - }, - Required: []string{"nodeName", "driverName"}, - }, - }, - Dependencies: []string{ - "k8s.io/api/resource/v1alpha2.NamedResourcesResources", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, - } -} - -func schema_k8sio_api_resource_v1alpha2_NodeResourceSliceList(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "NodeResourceSliceList is a collection of NodeResourceSlices.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Description: "Standard list metadata", - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), - }, - }, - "items": { - SchemaProps: spec.SchemaProps{ - Description: "Items is the list of node resource capacity objects.", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/resource/v1alpha2.NodeResourceSlice"), - }, - }, - }, - }, - }, - }, - Required: []string{"items"}, - }, - }, - Dependencies: []string{ - "k8s.io/api/resource/v1alpha2.NodeResourceSlice", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, - } -} - func schema_k8sio_api_resource_v1alpha2_PodSchedulingContext(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -46470,6 +46360,115 @@ func schema_k8sio_api_resource_v1alpha2_ResourceRequestModel(ref common.Referenc } } +func schema_k8sio_api_resource_v1alpha2_ResourceSlice(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ResourceSlice provides information about available resources on individual nodes.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Description: "Standard object metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "nodeName": { + SchemaProps: spec.SchemaProps{ + Description: "NodeName identifies the node which provides the resources if they are local to a node.\n\nA field selector can be used to list only ResourceSlice objects with a certain node name.", + Type: []string{"string"}, + Format: "", + }, + }, + "driverName": { + SchemaProps: spec.SchemaProps{ + Description: "DriverName identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "namedResources": { + SchemaProps: spec.SchemaProps{ + Description: "NamedResources describes available resources using the named resources model.", + Ref: ref("k8s.io/api/resource/v1alpha2.NamedResourcesResources"), + }, + }, + }, + Required: []string{"driverName"}, + }, + }, + Dependencies: []string{ + "k8s.io/api/resource/v1alpha2.NamedResourcesResources", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_k8sio_api_resource_v1alpha2_ResourceSliceList(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ResourceSliceList is a collection of ResourceSlices.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Description: "Standard list metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), + }, + }, + "items": { + SchemaProps: spec.SchemaProps{ + Description: "Items is the list of node resource capacity objects.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/resource/v1alpha2.ResourceSlice"), + }, + }, + }, + }, + }, + }, + Required: []string{"items"}, + }, + }, + Dependencies: []string{ + "k8s.io/api/resource/v1alpha2.ResourceSlice", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + func schema_k8sio_api_resource_v1alpha2_StructuredResourceHandle(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -46491,8 +46490,7 @@ func schema_k8sio_api_resource_v1alpha2_StructuredResourceHandle(ref common.Refe }, "nodeName": { SchemaProps: spec.SchemaProps{ - Description: "NodeName is the name of the node providing the necessary resources.", - Default: "", + Description: "NodeName is the name of the node providing the necessary resources if the resources are local to a node.", Type: []string{"string"}, Format: "", }, @@ -46517,7 +46515,7 @@ func schema_k8sio_api_resource_v1alpha2_StructuredResourceHandle(ref common.Refe }, }, }, - Required: []string{"nodeName", "results"}, + Required: []string{"results"}, }, }, Dependencies: []string{ diff --git a/pkg/kubeapiserver/authorizer/config.go b/pkg/kubeapiserver/authorizer/config.go index 3a0e101c54c..5a74fa7c748 100644 --- a/pkg/kubeapiserver/authorizer/config.go +++ b/pkg/kubeapiserver/authorizer/config.go @@ -93,9 +93,9 @@ func (config Config) New(ctx context.Context, serverID string) (authorizer.Autho // Keep cases in sync with constant list in k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes/modes.go. switch configuredAuthorizer.Type { case authzconfig.AuthorizerType(modes.ModeNode): - var slices resourcev1alpha2informers.NodeResourceSliceInformer + var slices resourcev1alpha2informers.ResourceSliceInformer if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) { - slices = config.VersionedInformerFactory.Resource().V1alpha2().NodeResourceSlices() + slices = config.VersionedInformerFactory.Resource().V1alpha2().ResourceSlices() } node.RegisterMetrics() graph := node.NewGraph() diff --git a/pkg/kubelet/cm/dra/plugin/noderesources.go b/pkg/kubelet/cm/dra/plugin/noderesources.go index 79cec7cef84..88ed9600872 100644 --- a/pkg/kubelet/cm/dra/plugin/noderesources.go +++ b/pkg/kubelet/cm/dra/plugin/noderesources.go @@ -48,7 +48,7 @@ const ( ) // nodeResourcesController collects resource information from all registered -// plugins and synchronizes that information with NodeResourceSlice objects. +// plugins and synchronizes that information with ResourceSlice objects. type nodeResourcesController struct { ctx context.Context kubeClient kubernetes.Interface @@ -79,11 +79,11 @@ type activePlugin struct { // startNodeResourcesController constructs a new controller and starts it. // -// If a kubeClient is provided, then it synchronizes NodeResourceSlices +// If a kubeClient is provided, then it synchronizes ResourceSlices // with the resource information provided by plugins. Without it, // the controller is inactive. This can happen when kubelet is run stand-alone // without an apiserver. In that case we can't and don't need to publish -// NodeResourceSlices. +// ResourceSlices. func startNodeResourcesController(ctx context.Context, kubeClient kubernetes.Interface, nodeName string) *nodeResourcesController { if kubeClient == nil { return nil @@ -243,49 +243,49 @@ func (c *nodeResourcesController) run(ctx context.Context) { logger := klog.FromContext(ctx) // When kubelet starts, we have two choices: - // - Sync immediately, which in practice will delete all NodeResourceSlices + // - Sync immediately, which in practice will delete all ResourceSlices // because no plugin has registered yet. We could do a DeleteCollection // to speed this up. // - Wait a bit, then sync. If all plugins have re-registered in the meantime, - // we might not need to change any NodeResourceSlice. + // we might not need to change any ResourceSlice. // // For now syncing starts immediately, with no DeleteCollection. This // can be reconsidered later. // While kubelet starts up, there are errors: - // E0226 13:41:19.880621 126334 reflector.go:150] k8s.io/client-go@v0.0.0/tools/cache/reflector.go:232: Failed to watch *v1alpha2.NodeResourceSlice: failed to list *v1alpha2.NodeResourceSlice: noderesourceslices.resource.k8s.io is forbidden: User "system:anonymous" cannot list resource "noderesourceslices" in API group "resource.k8s.io" at the cluster scope + // E0226 13:41:19.880621 126334 reflector.go:150] k8s.io/client-go@v0.0.0/tools/cache/reflector.go:232: Failed to watch *v1alpha2.ResourceSlice: failed to list *v1alpha2.ResourceSlice: resourceslices.resource.k8s.io is forbidden: User "system:anonymous" cannot list resource "resourceslices" in API group "resource.k8s.io" at the cluster scope // // The credentials used by kubeClient seem to get swapped out later, // because eventually these list calls succeed. // TODO (https://github.com/kubernetes/kubernetes/issues/123691): can we avoid these error log entries? Perhaps wait here? // We could use an indexer on driver name, but that seems overkill. - informer := resourceinformers.NewFilteredNodeResourceSliceInformer(c.kubeClient, resyncPeriod, nil, func(options *metav1.ListOptions) { + informer := resourceinformers.NewFilteredResourceSliceInformer(c.kubeClient, resyncPeriod, nil, func(options *metav1.ListOptions) { options.FieldSelector = "nodeName=" + c.nodeName }) c.sliceStore = informer.GetStore() handler, err := informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: func(obj any) { - slice, ok := obj.(*resourceapi.NodeResourceSlice) + slice, ok := obj.(*resourceapi.ResourceSlice) if !ok { return } - logger.V(5).Info("NodeResourceSlice add", "slice", klog.KObj(slice)) + logger.V(5).Info("ResourceSlice add", "slice", klog.KObj(slice)) c.queue.Add(slice.DriverName) }, UpdateFunc: func(old, new any) { - oldSlice, ok := old.(*resourceapi.NodeResourceSlice) + oldSlice, ok := old.(*resourceapi.ResourceSlice) if !ok { return } - newSlice, ok := new.(*resourceapi.NodeResourceSlice) + newSlice, ok := new.(*resourceapi.ResourceSlice) if !ok { return } if loggerV := logger.V(6); loggerV.Enabled() { - loggerV.Info("NodeResourceSlice update", "slice", klog.KObj(newSlice), "diff", cmp.Diff(oldSlice, newSlice)) + loggerV.Info("ResourceSlice update", "slice", klog.KObj(newSlice), "diff", cmp.Diff(oldSlice, newSlice)) } else { - logger.V(5).Info("NodeResourceSlice update", "slice", klog.KObj(newSlice)) + logger.V(5).Info("ResourceSlice update", "slice", klog.KObj(newSlice)) } c.queue.Add(newSlice.DriverName) }, @@ -293,16 +293,16 @@ func (c *nodeResourcesController) run(ctx context.Context) { if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); ok { obj = tombstone.Obj } - slice, ok := obj.(*resourceapi.NodeResourceSlice) + slice, ok := obj.(*resourceapi.ResourceSlice) if !ok { return } - logger.V(5).Info("NodeResourceSlice delete", "slice", klog.KObj(slice)) + logger.V(5).Info("ResourceSlice delete", "slice", klog.KObj(slice)) c.queue.Add(slice.DriverName) }, }) if err != nil { - logger.Error(err, "Registering event handler on the NodeResourceSlice informer failed, disabling resource monitoring") + logger.Error(err, "Registering event handler on the ResourceSlice informer failed, disabling resource monitoring") return } @@ -319,7 +319,7 @@ func (c *nodeResourcesController) run(ctx context.Context) { return } } - logger.Info("NodeResourceSlice informer has synced") + logger.Info("ResourceSlice informer has synced") for c.processNextWorkItem(ctx) { } @@ -378,11 +378,11 @@ func (c *nodeResourcesController) sync(ctx context.Context, driverName string) e // Slices that don't match any driver resource can either be updated (if there // are new driver resources that need to be stored) or they need to be deleted. - obsoleteSlices := make([]*resourceapi.NodeResourceSlice, 0, len(slices)) + obsoleteSlices := make([]*resourceapi.ResourceSlice, 0, len(slices)) // Match slices with resource information. for _, obj := range slices { - slice := obj.(*resourceapi.NodeResourceSlice) + slice := obj.(*resourceapi.ResourceSlice) if slice.DriverName != driverName { continue } @@ -414,7 +414,7 @@ func (c *nodeResourcesController) sync(ctx context.Context, driverName string) e // where we publish it. // // The long-term goal is to move the handling of - // NodeResourceSlice objects into the driver, with kubelet + // ResourceSlice objects into the driver, with kubelet // just acting as a REST proxy. The advantage of that will // be that kubelet won't need to support the same // resource API version as the driver and the control plane. @@ -435,14 +435,14 @@ func (c *nodeResourcesController) sync(ctx context.Context, driverName string) e slice = slice.DeepCopy() slice.NodeResourceModel = *resource logger.V(5).Info("Reusing existing node resource slice", "slice", klog.KObj(slice)) - if _, err := c.kubeClient.ResourceV1alpha2().NodeResourceSlices().Update(ctx, slice, metav1.UpdateOptions{}); err != nil { + if _, err := c.kubeClient.ResourceV1alpha2().ResourceSlices().Update(ctx, slice, metav1.UpdateOptions{}); err != nil { return fmt.Errorf("update node resource slice: %w", err) } continue } // Create a new slice. - slice := &resourceapi.NodeResourceSlice{ + slice := &resourceapi.ResourceSlice{ ObjectMeta: metav1.ObjectMeta{ GenerateName: c.nodeName + "-" + driverName + "-", // TODO (https://github.com/kubernetes/kubernetes/issues/123692): node object as owner @@ -452,7 +452,7 @@ func (c *nodeResourcesController) sync(ctx context.Context, driverName string) e NodeResourceModel: *resource, } logger.V(5).Info("Creating new node resource slice", "slice", klog.KObj(slice)) - if _, err := c.kubeClient.ResourceV1alpha2().NodeResourceSlices().Create(ctx, slice, metav1.CreateOptions{}); err != nil { + if _, err := c.kubeClient.ResourceV1alpha2().ResourceSlices().Create(ctx, slice, metav1.CreateOptions{}); err != nil { return fmt.Errorf("create node resource slice: %w", err) } } @@ -461,7 +461,7 @@ func (c *nodeResourcesController) sync(ctx context.Context, driverName string) e for i := 0; i < numObsoleteSlices; i++ { slice := obsoleteSlices[i] logger.V(5).Info("Deleting obsolete node resource slice", "slice", klog.KObj(slice)) - if err := c.kubeClient.ResourceV1alpha2().NodeResourceSlices().Delete(ctx, slice.Name, metav1.DeleteOptions{}); err != nil { + if err := c.kubeClient.ResourceV1alpha2().ResourceSlices().Delete(ctx, slice.Name, metav1.DeleteOptions{}); err != nil { return fmt.Errorf("delete node resource slice: %w", err) } } diff --git a/pkg/kubelet/cm/dra/plugin/plugin.go b/pkg/kubelet/cm/dra/plugin/plugin.go index 7acdec5f530..f85a14b8369 100644 --- a/pkg/kubelet/cm/dra/plugin/plugin.go +++ b/pkg/kubelet/cm/dra/plugin/plugin.go @@ -102,7 +102,7 @@ type RegistrationHandler struct { // NewPluginHandler returns new registration handler. // // Must only be called once per process because it manages global state. -// If a kubeClient is provided, then it synchronizes NodeResourceSlices +// If a kubeClient is provided, then it synchronizes ResourceSlices // with the resource information provided by plugins. func NewRegistrationHandler(kubeClient kubernetes.Interface, nodeName string) *RegistrationHandler { handler := &RegistrationHandler{} diff --git a/pkg/printers/internalversion/printers.go b/pkg/printers/internalversion/printers.go index 6dbc72061d7..ca404cc77ac 100644 --- a/pkg/printers/internalversion/printers.go +++ b/pkg/printers/internalversion/printers.go @@ -674,12 +674,12 @@ func AddHandlers(h printers.PrintHandler) { nodeResourceCapacityColumnDefinitions := []metav1.TableColumnDefinition{ {Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]}, - {Name: "Node", Type: "string", Description: resourcev1alpha2.NodeResourceSlice{}.SwaggerDoc()["nodeName"]}, - {Name: "Driver", Type: "string", Description: resourcev1alpha2.NodeResourceSlice{}.SwaggerDoc()["driverName"]}, + {Name: "Node", Type: "string", Description: resourcev1alpha2.ResourceSlice{}.SwaggerDoc()["nodeName"]}, + {Name: "Driver", Type: "string", Description: resourcev1alpha2.ResourceSlice{}.SwaggerDoc()["driverName"]}, {Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]}, } - _ = h.TableHandler(nodeResourceCapacityColumnDefinitions, printNodeResourceSlice) - _ = h.TableHandler(nodeResourceCapacityColumnDefinitions, printNodeResourceSliceList) + _ = h.TableHandler(nodeResourceCapacityColumnDefinitions, printResourceSlice) + _ = h.TableHandler(nodeResourceCapacityColumnDefinitions, printResourceSliceList) serviceCIDRColumnDefinitions := []metav1.TableColumnDefinition{ {Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]}, @@ -3121,7 +3121,7 @@ func printResourceClassParametersList(list *resource.ResourceClassParametersList return rows, nil } -func printNodeResourceSlice(obj *resource.NodeResourceSlice, options printers.GenerateOptions) ([]metav1.TableRow, error) { +func printResourceSlice(obj *resource.ResourceSlice, options printers.GenerateOptions) ([]metav1.TableRow, error) { row := metav1.TableRow{ Object: runtime.RawExtension{Object: obj}, } @@ -3130,10 +3130,10 @@ func printNodeResourceSlice(obj *resource.NodeResourceSlice, options printers.Ge return []metav1.TableRow{row}, nil } -func printNodeResourceSliceList(list *resource.NodeResourceSliceList, options printers.GenerateOptions) ([]metav1.TableRow, error) { +func printResourceSliceList(list *resource.ResourceSliceList, options printers.GenerateOptions) ([]metav1.TableRow, error) { rows := make([]metav1.TableRow, 0, len(list.Items)) for i := range list.Items { - r, err := printNodeResourceSlice(&list.Items[i], options) + r, err := printResourceSlice(&list.Items[i], options) if err != nil { return nil, err } diff --git a/pkg/registry/resource/noderesourceslice/storage/storage.go b/pkg/registry/resource/resourceslice/storage/storage.go similarity index 67% rename from pkg/registry/resource/noderesourceslice/storage/storage.go rename to pkg/registry/resource/resourceslice/storage/storage.go index b6f16d97a60..c723c101c50 100644 --- a/pkg/registry/resource/noderesourceslice/storage/storage.go +++ b/pkg/registry/resource/resourceslice/storage/storage.go @@ -24,35 +24,35 @@ import ( "k8s.io/kubernetes/pkg/printers" printersinternal "k8s.io/kubernetes/pkg/printers/internalversion" printerstorage "k8s.io/kubernetes/pkg/printers/storage" - "k8s.io/kubernetes/pkg/registry/resource/noderesourceslice" + "k8s.io/kubernetes/pkg/registry/resource/resourceslice" ) -// REST implements a RESTStorage for NodeResourceSlice. +// REST implements a RESTStorage for ResourceSlice. type REST struct { *genericregistry.Store } -// NewREST returns a RESTStorage object that will work against NodeResourceSlice. +// NewREST returns a RESTStorage object that will work against ResourceSlice. func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { store := &genericregistry.Store{ - NewFunc: func() runtime.Object { return &resource.NodeResourceSlice{} }, - NewListFunc: func() runtime.Object { return &resource.NodeResourceSliceList{} }, - PredicateFunc: noderesourceslice.Match, - DefaultQualifiedResource: resource.Resource("noderesourceslices"), - SingularQualifiedResource: resource.Resource("noderesourceslice"), + NewFunc: func() runtime.Object { return &resource.ResourceSlice{} }, + NewListFunc: func() runtime.Object { return &resource.ResourceSliceList{} }, + PredicateFunc: resourceslice.Match, + DefaultQualifiedResource: resource.Resource("resourceslices"), + SingularQualifiedResource: resource.Resource("resourceslice"), - CreateStrategy: noderesourceslice.Strategy, - UpdateStrategy: noderesourceslice.Strategy, - DeleteStrategy: noderesourceslice.Strategy, + CreateStrategy: resourceslice.Strategy, + UpdateStrategy: resourceslice.Strategy, + DeleteStrategy: resourceslice.Strategy, ReturnDeletedObject: true, TableConvertor: printerstorage.TableConvertor{TableGenerator: printers.NewTableGenerator().With(printersinternal.AddHandlers)}, } options := &generic.StoreOptions{ RESTOptions: optsGetter, - AttrFunc: noderesourceslice.GetAttrs, - TriggerFunc: noderesourceslice.TriggerFunc, - Indexers: noderesourceslice.Indexers(), + AttrFunc: resourceslice.GetAttrs, + TriggerFunc: resourceslice.TriggerFunc, + Indexers: resourceslice.Indexers(), } if err := store.CompleteWithOptions(options); err != nil { return nil, err diff --git a/pkg/registry/resource/noderesourceslice/storage/storage_test.go b/pkg/registry/resource/resourceslice/storage/storage_test.go similarity index 86% rename from pkg/registry/resource/noderesourceslice/storage/storage_test.go rename to pkg/registry/resource/resourceslice/storage/storage_test.go index db88974bf0d..7e53995c738 100644 --- a/pkg/registry/resource/noderesourceslice/storage/storage_test.go +++ b/pkg/registry/resource/resourceslice/storage/storage_test.go @@ -37,7 +37,7 @@ func newStorage(t *testing.T) (*REST, *etcd3testing.EtcdTestServer) { StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1, - ResourcePrefix: "noderesourceslices", + ResourcePrefix: "resourceslices", } resourceClassStorage, err := NewREST(restOptions) if err != nil { @@ -46,8 +46,8 @@ func newStorage(t *testing.T) (*REST, *etcd3testing.EtcdTestServer) { return resourceClassStorage, server } -func validNewNodeResourceSlice(name string) *resource.NodeResourceSlice { - return &resource.NodeResourceSlice{ +func validNewResourceSlice(name string) *resource.ResourceSlice { + return &resource.ResourceSlice{ ObjectMeta: metav1.ObjectMeta{ Name: name, }, @@ -64,13 +64,13 @@ func TestCreate(t *testing.T) { defer server.Terminate(t) defer storage.Store.DestroyFunc() test := genericregistrytest.New(t, storage.Store).ClusterScope() - resourceClass := validNewNodeResourceSlice("foo") + resourceClass := validNewResourceSlice("foo") resourceClass.ObjectMeta = metav1.ObjectMeta{GenerateName: "foo"} test.TestCreate( // valid resourceClass, // invalid - &resource.NodeResourceSlice{ + &resource.ResourceSlice{ ObjectMeta: metav1.ObjectMeta{Name: "*BadName!"}, }, ) @@ -83,16 +83,16 @@ func TestUpdate(t *testing.T) { test := genericregistrytest.New(t, storage.Store).ClusterScope() test.TestUpdate( // valid - validNewNodeResourceSlice("foo"), + validNewResourceSlice("foo"), // updateFunc func(obj runtime.Object) runtime.Object { - object := obj.(*resource.NodeResourceSlice) + object := obj.(*resource.ResourceSlice) object.Labels = map[string]string{"foo": "bar"} return object }, // invalid update func(obj runtime.Object) runtime.Object { - object := obj.(*resource.NodeResourceSlice) + object := obj.(*resource.ResourceSlice) object.DriverName = "" return object }, @@ -105,7 +105,7 @@ func TestDelete(t *testing.T) { defer server.Terminate(t) defer storage.Store.DestroyFunc() test := genericregistrytest.New(t, storage.Store).ClusterScope().ReturnDeletedObject() - test.TestDelete(validNewNodeResourceSlice("foo")) + test.TestDelete(validNewResourceSlice("foo")) } func TestGet(t *testing.T) { @@ -113,7 +113,7 @@ func TestGet(t *testing.T) { defer server.Terminate(t) defer storage.Store.DestroyFunc() test := genericregistrytest.New(t, storage.Store).ClusterScope() - test.TestGet(validNewNodeResourceSlice("foo")) + test.TestGet(validNewResourceSlice("foo")) } func TestList(t *testing.T) { @@ -121,7 +121,7 @@ func TestList(t *testing.T) { defer server.Terminate(t) defer storage.Store.DestroyFunc() test := genericregistrytest.New(t, storage.Store).ClusterScope() - test.TestList(validNewNodeResourceSlice("foo")) + test.TestList(validNewResourceSlice("foo")) } func TestWatch(t *testing.T) { @@ -130,7 +130,7 @@ func TestWatch(t *testing.T) { defer storage.Store.DestroyFunc() test := genericregistrytest.New(t, storage.Store).ClusterScope() test.TestWatch( - validNewNodeResourceSlice("foo"), + validNewResourceSlice("foo"), // matching labels []labels.Set{}, // not matching labels diff --git a/pkg/registry/resource/noderesourceslice/strategy.go b/pkg/registry/resource/resourceslice/strategy.go similarity index 62% rename from pkg/registry/resource/noderesourceslice/strategy.go rename to pkg/registry/resource/resourceslice/strategy.go index 3f6ec715669..e23b7d7ba36 100644 --- a/pkg/registry/resource/noderesourceslice/strategy.go +++ b/pkg/registry/resource/resourceslice/strategy.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package noderesourceslice +package resourceslice import ( "context" @@ -33,49 +33,49 @@ import ( "k8s.io/kubernetes/pkg/apis/resource/validation" ) -// nodeResourceSliceStrategy implements behavior for NodeResourceSlice objects -type nodeResourceSliceStrategy struct { +// resourceSliceStrategy implements behavior for ResourceSlice objects +type resourceSliceStrategy struct { runtime.ObjectTyper names.NameGenerator } -var Strategy = nodeResourceSliceStrategy{legacyscheme.Scheme, names.SimpleNameGenerator} +var Strategy = resourceSliceStrategy{legacyscheme.Scheme, names.SimpleNameGenerator} -func (nodeResourceSliceStrategy) NamespaceScoped() bool { +func (resourceSliceStrategy) NamespaceScoped() bool { return false } -func (nodeResourceSliceStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { +func (resourceSliceStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { } -func (nodeResourceSliceStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { - slice := obj.(*resource.NodeResourceSlice) - return validation.ValidateNodeResourceSlice(slice) +func (resourceSliceStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { + slice := obj.(*resource.ResourceSlice) + return validation.ValidateResourceSlice(slice) } -func (nodeResourceSliceStrategy) WarningsOnCreate(ctx context.Context, obj runtime.Object) []string { +func (resourceSliceStrategy) WarningsOnCreate(ctx context.Context, obj runtime.Object) []string { return nil } -func (nodeResourceSliceStrategy) Canonicalize(obj runtime.Object) { +func (resourceSliceStrategy) Canonicalize(obj runtime.Object) { } -func (nodeResourceSliceStrategy) AllowCreateOnUpdate() bool { +func (resourceSliceStrategy) AllowCreateOnUpdate() bool { return false } -func (nodeResourceSliceStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { +func (resourceSliceStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { } -func (nodeResourceSliceStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { - return validation.ValidateNodeResourceSliceUpdate(obj.(*resource.NodeResourceSlice), old.(*resource.NodeResourceSlice)) +func (resourceSliceStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { + return validation.ValidateResourceSliceUpdate(obj.(*resource.ResourceSlice), old.(*resource.ResourceSlice)) } -func (nodeResourceSliceStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.Object) []string { +func (resourceSliceStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.Object) []string { return nil } -func (nodeResourceSliceStrategy) AllowUnconditionalUpdate() bool { +func (resourceSliceStrategy) AllowUnconditionalUpdate() bool { return true } @@ -86,10 +86,10 @@ var TriggerFunc = map[string]storage.IndexerFunc{ } func nodeNameTriggerFunc(obj runtime.Object) string { - return obj.(*resource.NodeResourceSlice).NodeName + return obj.(*resource.ResourceSlice).NodeName } -// Indexers returns the indexers for NodeResourceSlice. +// Indexers returns the indexers for ResourceSlice. func Indexers() *cache.Indexers { return &cache.Indexers{ storage.FieldIndex("nodeName"): nodeNameIndexFunc, @@ -97,18 +97,18 @@ func Indexers() *cache.Indexers { } func nodeNameIndexFunc(obj interface{}) ([]string, error) { - slice, ok := obj.(*resource.NodeResourceSlice) + slice, ok := obj.(*resource.ResourceSlice) if !ok { - return nil, fmt.Errorf("not a NodeResourceSlice") + return nil, fmt.Errorf("not a ResourceSlice") } return []string{slice.NodeName}, nil } // GetAttrs returns labels and fields of a given object for filtering purposes. func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) { - slice, ok := obj.(*resource.NodeResourceSlice) + slice, ok := obj.(*resource.ResourceSlice) if !ok { - return nil, nil, fmt.Errorf("not a NodeResourceSlice") + return nil, nil, fmt.Errorf("not a ResourceSlice") } return labels.Set(slice.ObjectMeta.Labels), toSelectableFields(slice), nil } @@ -125,7 +125,7 @@ func Match(label labels.Selector, field fields.Selector) storage.SelectionPredic // toSelectableFields returns a field set that represents the object // TODO: fields are not labels, and the validation rules for them do not apply. -func toSelectableFields(slice *resource.NodeResourceSlice) fields.Set { +func toSelectableFields(slice *resource.ResourceSlice) fields.Set { // The purpose of allocation with a given number of elements is to reduce // amount of allocations needed to create the fields.Set. If you add any // field here or the number of object-meta related fields changes, this should diff --git a/pkg/registry/resource/noderesourceslice/strategy_test.go b/pkg/registry/resource/resourceslice/strategy_test.go similarity index 91% rename from pkg/registry/resource/noderesourceslice/strategy_test.go rename to pkg/registry/resource/resourceslice/strategy_test.go index 1e84c1905bb..31ccf8f45f9 100644 --- a/pkg/registry/resource/noderesourceslice/strategy_test.go +++ b/pkg/registry/resource/resourceslice/strategy_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package noderesourceslice +package resourceslice import ( "testing" @@ -24,7 +24,7 @@ import ( "k8s.io/kubernetes/pkg/apis/resource" ) -var slice = &resource.NodeResourceSlice{ +var slice = &resource.ResourceSlice{ ObjectMeta: metav1.ObjectMeta{ Name: "valid-class", }, @@ -37,10 +37,10 @@ var slice = &resource.NodeResourceSlice{ func TestClassStrategy(t *testing.T) { if Strategy.NamespaceScoped() { - t.Errorf("NodeResourceSlice must not be namespace scoped") + t.Errorf("ResourceSlice must not be namespace scoped") } if Strategy.AllowCreateOnUpdate() { - t.Errorf("NodeResourceSlice should not allow create on update") + t.Errorf("ResourceSlice should not allow create on update") } } diff --git a/pkg/registry/resource/rest/storage_resource.go b/pkg/registry/resource/rest/storage_resource.go index 28a2eaaecc5..b13e7f0227b 100644 --- a/pkg/registry/resource/rest/storage_resource.go +++ b/pkg/registry/resource/rest/storage_resource.go @@ -24,13 +24,13 @@ import ( serverstorage "k8s.io/apiserver/pkg/server/storage" "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/apis/resource" - noderesourceslicestore "k8s.io/kubernetes/pkg/registry/resource/noderesourceslice/storage" podschedulingcontextsstore "k8s.io/kubernetes/pkg/registry/resource/podschedulingcontext/storage" resourceclaimstore "k8s.io/kubernetes/pkg/registry/resource/resourceclaim/storage" resourceclaimparametersstore "k8s.io/kubernetes/pkg/registry/resource/resourceclaimparameters/storage" resourceclaimtemplatestore "k8s.io/kubernetes/pkg/registry/resource/resourceclaimtemplate/storage" resourceclassstore "k8s.io/kubernetes/pkg/registry/resource/resourceclass/storage" resourceclassparametersstore "k8s.io/kubernetes/pkg/registry/resource/resourceclassparameters/storage" + resourceslicestore "k8s.io/kubernetes/pkg/registry/resource/resourceslice/storage" ) type RESTStorageProvider struct{} @@ -102,12 +102,12 @@ func (p RESTStorageProvider) v1alpha2Storage(apiResourceConfigSource serverstora storage[resource] = resourceClassParametersStorage } - if resource := "noderesourceslices"; apiResourceConfigSource.ResourceEnabled(resourcev1alpha2.SchemeGroupVersion.WithResource(resource)) { - nodeResourceSliceStorage, err := noderesourceslicestore.NewREST(restOptionsGetter) + if resource := "resourceslices"; apiResourceConfigSource.ResourceEnabled(resourcev1alpha2.SchemeGroupVersion.WithResource(resource)) { + resourceSliceStorage, err := resourceslicestore.NewREST(restOptionsGetter) if err != nil { return nil, err } - storage[resource] = nodeResourceSliceStorage + storage[resource] = resourceSliceStorage } return storage, nil diff --git a/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go b/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go index 9cfa96e88fe..fdd0e5533a5 100644 --- a/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go +++ b/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go @@ -277,7 +277,7 @@ type dynamicResources struct { podSchedulingContextLister resourcev1alpha2listers.PodSchedulingContextLister claimParametersLister resourcev1alpha2listers.ResourceClaimParametersLister classParametersLister resourcev1alpha2listers.ResourceClassParametersLister - nodeResourceSliceLister resourcev1alpha2listers.NodeResourceSliceLister + resourceSliceLister resourcev1alpha2listers.ResourceSliceLister claimNameLookup *resourceclaim.Lookup // claimAssumeCache enables temporarily storing a newer claim object @@ -295,7 +295,7 @@ type dynamicResources struct { // assigned to such a claim. Alternatively, claim allocation state // could also get tracked across pod scheduling cycles, but that // - adds complexity (need to carefully sync state with informer events - // for claims and NodeResourceSlices) + // for claims and ResourceSlices) // - would make integration with cluster autoscaler harder because it would need // to trigger informer callbacks. // @@ -353,7 +353,7 @@ func New(ctx context.Context, plArgs runtime.Object, fh framework.Handle, fts fe podSchedulingContextLister: fh.SharedInformerFactory().Resource().V1alpha2().PodSchedulingContexts().Lister(), claimParametersLister: fh.SharedInformerFactory().Resource().V1alpha2().ResourceClaimParameters().Lister(), classParametersLister: fh.SharedInformerFactory().Resource().V1alpha2().ResourceClassParameters().Lister(), - nodeResourceSliceLister: fh.SharedInformerFactory().Resource().V1alpha2().NodeResourceSlices().Lister(), + resourceSliceLister: fh.SharedInformerFactory().Resource().V1alpha2().ResourceSlices().Lister(), claimNameLookup: resourceclaim.NewNameLookup(fh.ClientSet()), claimAssumeCache: volumebinding.NewAssumeCache(logger, fh.SharedInformerFactory().Resource().V1alpha2().ResourceClaims().Informer(), "claim", "", nil), } @@ -943,7 +943,7 @@ func (pl *dynamicResources) PreFilter(ctx context.Context, state *framework.Cycl // problems for using the plugin in the Cluster Autoscaler. If // this step here turns out to be expensive, we may have to // maintain and update state more persistently. - resources, err := newResourceModel(logger, pl.nodeResourceSliceLister, pl.claimAssumeCache) + resources, err := newResourceModel(logger, pl.resourceSliceLister, pl.claimAssumeCache) if err != nil { return nil, statusError(logger, err) } diff --git a/pkg/scheduler/framework/plugins/dynamicresources/structuredparameters.go b/pkg/scheduler/framework/plugins/dynamicresources/structuredparameters.go index 72ae918b669..6ac1d263f16 100644 --- a/pkg/scheduler/framework/plugins/dynamicresources/structuredparameters.go +++ b/pkg/scheduler/framework/plugins/dynamicresources/structuredparameters.go @@ -44,10 +44,10 @@ type resourceModels struct { // with an unknown structured parameter model silently ignored. An error gets // logged later when parameters required for a pod depend on such an unknown // model. -func newResourceModel(logger klog.Logger, nodeResourceSliceLister resourcev1alpha2listers.NodeResourceSliceLister, claimAssumeCache volumebinding.AssumeCache) (resources, error) { +func newResourceModel(logger klog.Logger, resourceSliceLister resourcev1alpha2listers.ResourceSliceLister, claimAssumeCache volumebinding.AssumeCache) (resources, error) { model := make(resources) - slices, err := nodeResourceSliceLister.List(labels.Everything()) + slices, err := resourceSliceLister.List(labels.Everything()) if err != nil { return nil, fmt.Errorf("list node resource slices: %w", err) } diff --git a/plugin/pkg/admission/noderestriction/admission.go b/plugin/pkg/admission/noderestriction/admission.go index e00bb6141ed..9388ac52252 100644 --- a/plugin/pkg/admission/noderestriction/admission.go +++ b/plugin/pkg/admission/noderestriction/admission.go @@ -110,13 +110,13 @@ func (p *Plugin) ValidateInitialization() error { } var ( - podResource = api.Resource("pods") - nodeResource = api.Resource("nodes") - pvcResource = api.Resource("persistentvolumeclaims") - svcacctResource = api.Resource("serviceaccounts") - leaseResource = coordapi.Resource("leases") - csiNodeResource = storage.Resource("csinodes") - nodeResourceSliceResource = resource.Resource("noderesourceslices") + podResource = api.Resource("pods") + nodeResource = api.Resource("nodes") + pvcResource = api.Resource("persistentvolumeclaims") + svcacctResource = api.Resource("serviceaccounts") + leaseResource = coordapi.Resource("leases") + csiNodeResource = storage.Resource("csinodes") + resourceSliceResource = resource.Resource("resourceslices") ) // Admit checks the admission policy and triggers corresponding actions @@ -168,8 +168,8 @@ func (p *Plugin) Admit(ctx context.Context, a admission.Attributes, o admission. case csiNodeResource: return p.admitCSINode(nodeName, a) - case nodeResourceSliceResource: - return p.admitNodeResourceSlice(nodeName, a) + case resourceSliceResource: + return p.admitResourceSlice(nodeName, a) default: return nil @@ -639,17 +639,17 @@ func (p *Plugin) admitCSINode(nodeName string, a admission.Attributes) error { return nil } -func (p *Plugin) admitNodeResourceSlice(nodeName string, a admission.Attributes) error { +func (p *Plugin) admitResourceSlice(nodeName string, a admission.Attributes) error { // The create request must come from a node with the same name as the NodeName field. // Other requests gets checked by the node authorizer. if a.GetOperation() == admission.Create { - slice, ok := a.GetObject().(*resource.NodeResourceSlice) + slice, ok := a.GetObject().(*resource.ResourceSlice) if !ok { return admission.NewForbidden(a, fmt.Errorf("unexpected type %T", a.GetObject())) } if slice.NodeName != nodeName { - return admission.NewForbidden(a, errors.New("can only create NodeResourceSlice with the same NodeName as the requesting node")) + return admission.NewForbidden(a, errors.New("can only create ResourceSlice with the same NodeName as the requesting node")) } } diff --git a/plugin/pkg/admission/noderestriction/admission_test.go b/plugin/pkg/admission/noderestriction/admission_test.go index dd8b4ee04ac..17bb2f50b2b 100644 --- a/plugin/pkg/admission/noderestriction/admission_test.go +++ b/plugin/pkg/admission/noderestriction/admission_test.go @@ -1603,19 +1603,19 @@ func createPodAttributes(pod *api.Pod, user user.Info) admission.Attributes { return admission.NewAttributesRecord(pod, nil, podKind, pod.Namespace, pod.Name, podResource, "", admission.Create, &metav1.CreateOptions{}, false, user) } -func TestAdmitNodeResourceSlice(t *testing.T) { - apiResource := resourceapi.SchemeGroupVersion.WithResource("noderesourceslices") +func TestAdmitResourceSlice(t *testing.T) { + apiResource := resourceapi.SchemeGroupVersion.WithResource("resourceslices") nodename := "mynode" mynode := &user.DefaultInfo{Name: "system:node:" + nodename, Groups: []string{"system:nodes"}} - err := "can only create NodeResourceSlice with the same NodeName as the requesting node" + err := "can only create ResourceSlice with the same NodeName as the requesting node" - sliceNode := &resourceapi.NodeResourceSlice{ + sliceNode := &resourceapi.ResourceSlice{ ObjectMeta: metav1.ObjectMeta{ Name: "something", }, NodeName: nodename, } - sliceOtherNode := &resourceapi.NodeResourceSlice{ + sliceOtherNode := &resourceapi.ResourceSlice{ ObjectMeta: metav1.ObjectMeta{ Name: "something", }, diff --git a/plugin/pkg/auth/authorizer/node/graph.go b/plugin/pkg/auth/authorizer/node/graph.go index 64596fb9714..a9d17219a55 100644 --- a/plugin/pkg/auth/authorizer/node/graph.go +++ b/plugin/pkg/auth/authorizer/node/graph.go @@ -127,7 +127,7 @@ const ( var vertexTypes = map[vertexType]string{ configMapVertexType: "configmap", - sliceVertexType: "noderesourceslice", + sliceVertexType: "resourceslice", nodeVertexType: "node", podVertexType: "pod", pvcVertexType: "pvc", @@ -495,13 +495,13 @@ func (g *Graph) DeleteVolumeAttachment(name string) { g.deleteVertex_locked(vaVertexType, "", name) } -// AddNodeResourceSlice sets up edges for the following relationships: +// AddResourceSlice sets up edges for the following relationships: // // node resource slice -> node -func (g *Graph) AddNodeResourceSlice(sliceName, nodeName string) { +func (g *Graph) AddResourceSlice(sliceName, nodeName string) { start := time.Now() defer func() { - graphActionsDuration.WithLabelValues("AddNodeResourceSlice").Observe(time.Since(start).Seconds()) + graphActionsDuration.WithLabelValues("AddResourceSlice").Observe(time.Since(start).Seconds()) }() g.lock.Lock() defer g.lock.Unlock() @@ -516,10 +516,10 @@ func (g *Graph) AddNodeResourceSlice(sliceName, nodeName string) { g.graph.SetEdge(newDestinationEdge(sliceVertex, nodeVertex, nodeVertex)) } } -func (g *Graph) DeleteNodeResourceSlice(sliceName string) { +func (g *Graph) DeleteResourceSlice(sliceName string) { start := time.Now() defer func() { - graphActionsDuration.WithLabelValues("DeleteNodeResourceSlice").Observe(time.Since(start).Seconds()) + graphActionsDuration.WithLabelValues("DeleteResourceSlice").Observe(time.Since(start).Seconds()) }() g.lock.Lock() defer g.lock.Unlock() diff --git a/plugin/pkg/auth/authorizer/node/graph_populator.go b/plugin/pkg/auth/authorizer/node/graph_populator.go index 96ff92c77e3..0e4fb0764b0 100644 --- a/plugin/pkg/auth/authorizer/node/graph_populator.go +++ b/plugin/pkg/auth/authorizer/node/graph_populator.go @@ -41,7 +41,7 @@ func AddGraphEventHandlers( pods corev1informers.PodInformer, pvs corev1informers.PersistentVolumeInformer, attachments storageinformers.VolumeAttachmentInformer, - slices resourcev1alpha2informers.NodeResourceSliceInformer, + slices resourcev1alpha2informers.ResourceSliceInformer, ) { g := &graphPopulator{ graph: graph, @@ -71,9 +71,9 @@ func AddGraphEventHandlers( if slices != nil { sliceHandler, _ := slices.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ - AddFunc: g.addNodeResourceSlice, + AddFunc: g.addResourceSlice, UpdateFunc: nil, // Not needed, NodeName is immutable. - DeleteFunc: g.deleteNodeResourceSlice, + DeleteFunc: g.deleteResourceSlice, }) synced = append(synced, sliceHandler.HasSynced) } @@ -200,23 +200,23 @@ func (g *graphPopulator) deleteVolumeAttachment(obj interface{}) { g.graph.DeleteVolumeAttachment(attachment.Name) } -func (g *graphPopulator) addNodeResourceSlice(obj interface{}) { - slice, ok := obj.(*resourcev1alpha2.NodeResourceSlice) +func (g *graphPopulator) addResourceSlice(obj interface{}) { + slice, ok := obj.(*resourcev1alpha2.ResourceSlice) if !ok { klog.Infof("unexpected type %T", obj) return } - g.graph.AddNodeResourceSlice(slice.Name, slice.NodeName) + g.graph.AddResourceSlice(slice.Name, slice.NodeName) } -func (g *graphPopulator) deleteNodeResourceSlice(obj interface{}) { +func (g *graphPopulator) deleteResourceSlice(obj interface{}) { if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); ok { obj = tombstone.Obj } - slice, ok := obj.(*resourcev1alpha2.NodeResourceSlice) + slice, ok := obj.(*resourcev1alpha2.ResourceSlice) if !ok { klog.Infof("unexpected type %T", obj) return } - g.graph.DeleteNodeResourceSlice(slice.Name) + g.graph.DeleteResourceSlice(slice.Name) } diff --git a/plugin/pkg/auth/authorizer/node/node_authorizer.go b/plugin/pkg/auth/authorizer/node/node_authorizer.go index d983ed8c3cf..d6b5c8d3037 100644 --- a/plugin/pkg/auth/authorizer/node/node_authorizer.go +++ b/plugin/pkg/auth/authorizer/node/node_authorizer.go @@ -50,7 +50,7 @@ import ( // node <- pod <- pvc <- pv // node <- pod <- pvc <- pv <- secret // node <- pod <- ResourceClaim -// 4. If a request is for a noderesourceslice, then authorize access if there is an +// 4. If a request is for a resourceslice, then authorize access if there is an // edge from the existing slice object to the node, which is the case if the // existing object has the node in its NodeName field. For create, the access gets // granted because the noderestriction admission plugin checks that the NodeName @@ -81,7 +81,7 @@ func NewAuthorizer(graph *Graph, identifier nodeidentifier.NodeIdentifier, rules var ( configMapResource = api.Resource("configmaps") secretResource = api.Resource("secrets") - nodeResourceSlice = resourceapi.Resource("noderesourceslices") + resourceSlice = resourceapi.Resource("resourceslices") pvcResource = api.Resource("persistentvolumeclaims") pvResource = api.Resource("persistentvolumes") resourceClaimResource = resourceapi.Resource("resourceclaims") @@ -136,8 +136,8 @@ func (r *NodeAuthorizer) Authorize(ctx context.Context, attrs authorizer.Attribu return r.authorizeLease(nodeName, attrs) case csiNodeResource: return r.authorizeCSINode(nodeName, attrs) - case nodeResourceSlice: - return r.authorizeNodeResourceSlice(nodeName, attrs) + case resourceSlice: + return r.authorizeResourceSlice(nodeName, attrs) } } @@ -302,11 +302,11 @@ func (r *NodeAuthorizer) authorizeCSINode(nodeName string, attrs authorizer.Attr return authorizer.DecisionAllow, "", nil } -// authorizeNodeResourceSlice authorizes node requests to NodeResourceSlice resource.k8s.io/noderesourceslices -func (r *NodeAuthorizer) authorizeNodeResourceSlice(nodeName string, attrs authorizer.Attributes) (authorizer.Decision, string, error) { +// authorizeResourceSlice authorizes node requests to ResourceSlice resource.k8s.io/resourceslices +func (r *NodeAuthorizer) authorizeResourceSlice(nodeName string, attrs authorizer.Attributes) (authorizer.Decision, string, error) { if len(attrs.GetSubresource()) > 0 { klog.V(2).Infof("NODE DENY: '%s' %#v", nodeName, attrs) - return authorizer.DecisionNoOpinion, "cannot authorize NodeResourceSlice subresources", nil + return authorizer.DecisionNoOpinion, "cannot authorize ResourceSlice subresources", nil } // allowed verbs: get, create, update, patch, delete @@ -319,10 +319,10 @@ func (r *NodeAuthorizer) authorizeNodeResourceSlice(nodeName string, attrs autho return authorizer.DecisionAllow, "", nil default: klog.V(2).Infof("NODE DENY: '%s' %#v", nodeName, attrs) - return authorizer.DecisionNoOpinion, "can only get, create, update, patch, or delete a NodeResourceSlice", nil + return authorizer.DecisionNoOpinion, "can only get, create, update, patch, or delete a ResourceSlice", nil } - // The request must come from a node with the same name as the NodeResourceSlice.NodeName field. + // The request must come from a node with the same name as the ResourceSlice.NodeName field. // // For create, the noderestriction admission plugin is performing this check. // Here we don't have access to the content of the new object. diff --git a/plugin/pkg/auth/authorizer/node/node_authorizer_test.go b/plugin/pkg/auth/authorizer/node/node_authorizer_test.go index a427b16967c..776d52c73bc 100644 --- a/plugin/pkg/auth/authorizer/node/node_authorizer_test.go +++ b/plugin/pkg/auth/authorizer/node/node_authorizer_test.go @@ -338,65 +338,65 @@ func TestAuthorizer(t *testing.T) { attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "csinodes", APIGroup: "storage.k8s.io", Name: "node0"}, expect: authorizer.DecisionAllow, }, - // NodeResourceSlice + // ResourceSlice { - name: "disallowed NodeResourceSlice with subresource", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "noderesourceslices", Subresource: "status", APIGroup: "resource.k8s.io", Name: "slice0-node0"}, + name: "disallowed ResourceSlice with subresource", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "resourceslices", Subresource: "status", APIGroup: "resource.k8s.io", Name: "slice0-node0"}, expect: authorizer.DecisionNoOpinion, }, { - name: "disallowed get another node's NodeResourceSlice", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "noderesourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node1"}, + name: "disallowed get another node's ResourceSlice", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "resourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node1"}, expect: authorizer.DecisionNoOpinion, }, { - name: "disallowed update another node's NodeResourceSlice", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "update", Resource: "noderesourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node1"}, + name: "disallowed update another node's ResourceSlice", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "update", Resource: "resourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node1"}, expect: authorizer.DecisionNoOpinion, }, { - name: "disallowed patch another node's NodeResourceSlice", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "patch", Resource: "noderesourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node1"}, + name: "disallowed patch another node's ResourceSlice", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "patch", Resource: "resourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node1"}, expect: authorizer.DecisionNoOpinion, }, { - name: "disallowed delete another node's NodeResourceSlice", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "noderesourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node1"}, + name: "disallowed delete another node's ResourceSlice", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "resourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node1"}, expect: authorizer.DecisionNoOpinion, }, { - name: "allowed list NodeResourceSlices", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "list", Resource: "noderesourceslices", APIGroup: "resource.k8s.io"}, + name: "allowed list ResourceSlices", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "list", Resource: "resourceslices", APIGroup: "resource.k8s.io"}, expect: authorizer.DecisionAllow, }, { - name: "allowed watch NodeResourceSlices", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "watch", Resource: "noderesourceslices", APIGroup: "resource.k8s.io"}, + name: "allowed watch ResourceSlices", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "watch", Resource: "resourceslices", APIGroup: "resource.k8s.io"}, expect: authorizer.DecisionAllow, }, { - name: "allowed get NodeResourceSlice", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "noderesourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node0"}, + name: "allowed get ResourceSlice", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "resourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node0"}, expect: authorizer.DecisionAllow, }, { - name: "allowed create NodeResourceSlice", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "create", Resource: "noderesourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node0"}, + name: "allowed create ResourceSlice", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "create", Resource: "resourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node0"}, expect: authorizer.DecisionAllow, }, { - name: "allowed update NodeResourceSlice", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "update", Resource: "noderesourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node0"}, + name: "allowed update ResourceSlice", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "update", Resource: "resourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node0"}, expect: authorizer.DecisionAllow, }, { - name: "allowed patch NodeResourceSlice", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "patch", Resource: "noderesourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node0"}, + name: "allowed patch ResourceSlice", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "patch", Resource: "resourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node0"}, expect: authorizer.DecisionAllow, }, { - name: "allowed delete NodeResourceSlice", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "noderesourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node0"}, + name: "allowed delete ResourceSlice", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "resourceslices", APIGroup: "resource.k8s.io", Name: "slice0-node0"}, expect: authorizer.DecisionAllow, }, } @@ -831,7 +831,7 @@ func BenchmarkAuthorization(b *testing.B) { } } -func populate(graph *Graph, nodes []*corev1.Node, pods []*corev1.Pod, pvs []*corev1.PersistentVolume, attachments []*storagev1.VolumeAttachment, slices []*resourcev1alpha2.NodeResourceSlice) { +func populate(graph *Graph, nodes []*corev1.Node, pods []*corev1.Pod, pvs []*corev1.PersistentVolume, attachments []*storagev1.VolumeAttachment, slices []*resourcev1alpha2.ResourceSlice) { p := &graphPopulator{} p.graph = graph for _, pod := range pods { @@ -844,7 +844,7 @@ func populate(graph *Graph, nodes []*corev1.Node, pods []*corev1.Pod, pvs []*cor p.addVolumeAttachment(attachment) } for _, slice := range slices { - p.addNodeResourceSlice(slice) + p.addResourceSlice(slice) } } @@ -859,12 +859,12 @@ func randomSubset(a, b int) []int { // the secret/configmap/pvc/node references in the pod and pv objects are named to indicate the connections between the objects. // for example, secret0-pod0-node0 is a secret referenced by pod0 which is bound to node0. // when populated into the graph, the node authorizer should allow node0 to access that secret, but not node1. -func generate(opts *sampleDataOpts) ([]*corev1.Node, []*corev1.Pod, []*corev1.PersistentVolume, []*storagev1.VolumeAttachment, []*resourcev1alpha2.NodeResourceSlice) { +func generate(opts *sampleDataOpts) ([]*corev1.Node, []*corev1.Pod, []*corev1.PersistentVolume, []*storagev1.VolumeAttachment, []*resourcev1alpha2.ResourceSlice) { nodes := make([]*corev1.Node, 0, opts.nodes) pods := make([]*corev1.Pod, 0, opts.nodes*opts.podsPerNode) pvs := make([]*corev1.PersistentVolume, 0, (opts.nodes*opts.podsPerNode*opts.uniquePVCsPerPod)+(opts.sharedPVCsPerPod*opts.namespaces)) attachments := make([]*storagev1.VolumeAttachment, 0, opts.nodes*opts.attachmentsPerNode) - slices := make([]*resourcev1alpha2.NodeResourceSlice, 0, opts.nodes*opts.nodeResourceCapacitiesPerNode) + slices := make([]*resourcev1alpha2.ResourceSlice, 0, opts.nodes*opts.nodeResourceCapacitiesPerNode) rand.Seed(12345) @@ -893,7 +893,7 @@ func generate(opts *sampleDataOpts) ([]*corev1.Node, []*corev1.Pod, []*corev1.Pe for p := 0; p <= opts.nodeResourceCapacitiesPerNode; p++ { name := fmt.Sprintf("slice%d-%s", p, nodeName) - slice := &resourcev1alpha2.NodeResourceSlice{ + slice := &resourcev1alpha2.ResourceSlice{ ObjectMeta: metav1.ObjectMeta{Name: name}, NodeName: nodeName, } diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go index 58ac1a15712..b8056c4e6d0 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go @@ -582,7 +582,7 @@ func ClusterRoles() []rbacv1.ClusterRole { rbacv1helpers.NewRule(ReadWrite...).Groups(resourceGroup).Resources("podschedulingcontexts").RuleOrDie(), rbacv1helpers.NewRule(Read...).Groups(resourceGroup).Resources("podschedulingcontexts/status").RuleOrDie(), rbacv1helpers.NewRule(ReadUpdate...).Groups(legacyGroup).Resources("pods/finalizers").RuleOrDie(), - rbacv1helpers.NewRule(Read...).Groups(resourceGroup).Resources("noderesourceslices", "resourceclassparameters", "resourceclaimparameters").RuleOrDie(), + rbacv1helpers.NewRule(Read...).Groups(resourceGroup).Resources("resourceslices", "resourceclassparameters", "resourceclaimparameters").RuleOrDie(), ) } roles = append(roles, rbacv1.ClusterRole{ diff --git a/staging/src/k8s.io/api/resource/v1alpha2/generated.pb.go b/staging/src/k8s.io/api/resource/v1alpha2/generated.pb.go index 0144435a342..8924f7d8e9d 100644 --- a/staging/src/k8s.io/api/resource/v1alpha2/generated.pb.go +++ b/staging/src/k8s.io/api/resource/v1alpha2/generated.pb.go @@ -439,66 +439,10 @@ func (m *NodeResourceModel) XXX_DiscardUnknown() { var xxx_messageInfo_NodeResourceModel proto.InternalMessageInfo -func (m *NodeResourceSlice) Reset() { *m = NodeResourceSlice{} } -func (*NodeResourceSlice) ProtoMessage() {} -func (*NodeResourceSlice) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{14} -} -func (m *NodeResourceSlice) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *NodeResourceSlice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *NodeResourceSlice) XXX_Merge(src proto.Message) { - xxx_messageInfo_NodeResourceSlice.Merge(m, src) -} -func (m *NodeResourceSlice) XXX_Size() int { - return m.Size() -} -func (m *NodeResourceSlice) XXX_DiscardUnknown() { - xxx_messageInfo_NodeResourceSlice.DiscardUnknown(m) -} - -var xxx_messageInfo_NodeResourceSlice proto.InternalMessageInfo - -func (m *NodeResourceSliceList) Reset() { *m = NodeResourceSliceList{} } -func (*NodeResourceSliceList) ProtoMessage() {} -func (*NodeResourceSliceList) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{15} -} -func (m *NodeResourceSliceList) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *NodeResourceSliceList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *NodeResourceSliceList) XXX_Merge(src proto.Message) { - xxx_messageInfo_NodeResourceSliceList.Merge(m, src) -} -func (m *NodeResourceSliceList) XXX_Size() int { - return m.Size() -} -func (m *NodeResourceSliceList) XXX_DiscardUnknown() { - xxx_messageInfo_NodeResourceSliceList.DiscardUnknown(m) -} - -var xxx_messageInfo_NodeResourceSliceList proto.InternalMessageInfo - func (m *PodSchedulingContext) Reset() { *m = PodSchedulingContext{} } func (*PodSchedulingContext) ProtoMessage() {} func (*PodSchedulingContext) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{16} + return fileDescriptor_4312f5b44a31ec02, []int{14} } func (m *PodSchedulingContext) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -526,7 +470,7 @@ var xxx_messageInfo_PodSchedulingContext proto.InternalMessageInfo func (m *PodSchedulingContextList) Reset() { *m = PodSchedulingContextList{} } func (*PodSchedulingContextList) ProtoMessage() {} func (*PodSchedulingContextList) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{17} + return fileDescriptor_4312f5b44a31ec02, []int{15} } func (m *PodSchedulingContextList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -554,7 +498,7 @@ var xxx_messageInfo_PodSchedulingContextList proto.InternalMessageInfo func (m *PodSchedulingContextSpec) Reset() { *m = PodSchedulingContextSpec{} } func (*PodSchedulingContextSpec) ProtoMessage() {} func (*PodSchedulingContextSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{18} + return fileDescriptor_4312f5b44a31ec02, []int{16} } func (m *PodSchedulingContextSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -582,7 +526,7 @@ var xxx_messageInfo_PodSchedulingContextSpec proto.InternalMessageInfo func (m *PodSchedulingContextStatus) Reset() { *m = PodSchedulingContextStatus{} } func (*PodSchedulingContextStatus) ProtoMessage() {} func (*PodSchedulingContextStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{19} + return fileDescriptor_4312f5b44a31ec02, []int{17} } func (m *PodSchedulingContextStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -610,7 +554,7 @@ var xxx_messageInfo_PodSchedulingContextStatus proto.InternalMessageInfo func (m *ResourceClaim) Reset() { *m = ResourceClaim{} } func (*ResourceClaim) ProtoMessage() {} func (*ResourceClaim) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{20} + return fileDescriptor_4312f5b44a31ec02, []int{18} } func (m *ResourceClaim) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -638,7 +582,7 @@ var xxx_messageInfo_ResourceClaim proto.InternalMessageInfo func (m *ResourceClaimConsumerReference) Reset() { *m = ResourceClaimConsumerReference{} } func (*ResourceClaimConsumerReference) ProtoMessage() {} func (*ResourceClaimConsumerReference) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{21} + return fileDescriptor_4312f5b44a31ec02, []int{19} } func (m *ResourceClaimConsumerReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -666,7 +610,7 @@ var xxx_messageInfo_ResourceClaimConsumerReference proto.InternalMessageInfo func (m *ResourceClaimList) Reset() { *m = ResourceClaimList{} } func (*ResourceClaimList) ProtoMessage() {} func (*ResourceClaimList) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{22} + return fileDescriptor_4312f5b44a31ec02, []int{20} } func (m *ResourceClaimList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -694,7 +638,7 @@ var xxx_messageInfo_ResourceClaimList proto.InternalMessageInfo func (m *ResourceClaimParameters) Reset() { *m = ResourceClaimParameters{} } func (*ResourceClaimParameters) ProtoMessage() {} func (*ResourceClaimParameters) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{23} + return fileDescriptor_4312f5b44a31ec02, []int{21} } func (m *ResourceClaimParameters) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -722,7 +666,7 @@ var xxx_messageInfo_ResourceClaimParameters proto.InternalMessageInfo func (m *ResourceClaimParametersList) Reset() { *m = ResourceClaimParametersList{} } func (*ResourceClaimParametersList) ProtoMessage() {} func (*ResourceClaimParametersList) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{24} + return fileDescriptor_4312f5b44a31ec02, []int{22} } func (m *ResourceClaimParametersList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -750,7 +694,7 @@ var xxx_messageInfo_ResourceClaimParametersList proto.InternalMessageInfo func (m *ResourceClaimParametersReference) Reset() { *m = ResourceClaimParametersReference{} } func (*ResourceClaimParametersReference) ProtoMessage() {} func (*ResourceClaimParametersReference) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{25} + return fileDescriptor_4312f5b44a31ec02, []int{23} } func (m *ResourceClaimParametersReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -778,7 +722,7 @@ var xxx_messageInfo_ResourceClaimParametersReference proto.InternalMessageInfo func (m *ResourceClaimSchedulingStatus) Reset() { *m = ResourceClaimSchedulingStatus{} } func (*ResourceClaimSchedulingStatus) ProtoMessage() {} func (*ResourceClaimSchedulingStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{26} + return fileDescriptor_4312f5b44a31ec02, []int{24} } func (m *ResourceClaimSchedulingStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -806,7 +750,7 @@ var xxx_messageInfo_ResourceClaimSchedulingStatus proto.InternalMessageInfo func (m *ResourceClaimSpec) Reset() { *m = ResourceClaimSpec{} } func (*ResourceClaimSpec) ProtoMessage() {} func (*ResourceClaimSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{27} + return fileDescriptor_4312f5b44a31ec02, []int{25} } func (m *ResourceClaimSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -834,7 +778,7 @@ var xxx_messageInfo_ResourceClaimSpec proto.InternalMessageInfo func (m *ResourceClaimStatus) Reset() { *m = ResourceClaimStatus{} } func (*ResourceClaimStatus) ProtoMessage() {} func (*ResourceClaimStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{28} + return fileDescriptor_4312f5b44a31ec02, []int{26} } func (m *ResourceClaimStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -862,7 +806,7 @@ var xxx_messageInfo_ResourceClaimStatus proto.InternalMessageInfo func (m *ResourceClaimTemplate) Reset() { *m = ResourceClaimTemplate{} } func (*ResourceClaimTemplate) ProtoMessage() {} func (*ResourceClaimTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{29} + return fileDescriptor_4312f5b44a31ec02, []int{27} } func (m *ResourceClaimTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -890,7 +834,7 @@ var xxx_messageInfo_ResourceClaimTemplate proto.InternalMessageInfo func (m *ResourceClaimTemplateList) Reset() { *m = ResourceClaimTemplateList{} } func (*ResourceClaimTemplateList) ProtoMessage() {} func (*ResourceClaimTemplateList) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{30} + return fileDescriptor_4312f5b44a31ec02, []int{28} } func (m *ResourceClaimTemplateList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -918,7 +862,7 @@ var xxx_messageInfo_ResourceClaimTemplateList proto.InternalMessageInfo func (m *ResourceClaimTemplateSpec) Reset() { *m = ResourceClaimTemplateSpec{} } func (*ResourceClaimTemplateSpec) ProtoMessage() {} func (*ResourceClaimTemplateSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{31} + return fileDescriptor_4312f5b44a31ec02, []int{29} } func (m *ResourceClaimTemplateSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -946,7 +890,7 @@ var xxx_messageInfo_ResourceClaimTemplateSpec proto.InternalMessageInfo func (m *ResourceClass) Reset() { *m = ResourceClass{} } func (*ResourceClass) ProtoMessage() {} func (*ResourceClass) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{32} + return fileDescriptor_4312f5b44a31ec02, []int{30} } func (m *ResourceClass) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -974,7 +918,7 @@ var xxx_messageInfo_ResourceClass proto.InternalMessageInfo func (m *ResourceClassList) Reset() { *m = ResourceClassList{} } func (*ResourceClassList) ProtoMessage() {} func (*ResourceClassList) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{33} + return fileDescriptor_4312f5b44a31ec02, []int{31} } func (m *ResourceClassList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1002,7 +946,7 @@ var xxx_messageInfo_ResourceClassList proto.InternalMessageInfo func (m *ResourceClassParameters) Reset() { *m = ResourceClassParameters{} } func (*ResourceClassParameters) ProtoMessage() {} func (*ResourceClassParameters) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{34} + return fileDescriptor_4312f5b44a31ec02, []int{32} } func (m *ResourceClassParameters) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1030,7 +974,7 @@ var xxx_messageInfo_ResourceClassParameters proto.InternalMessageInfo func (m *ResourceClassParametersList) Reset() { *m = ResourceClassParametersList{} } func (*ResourceClassParametersList) ProtoMessage() {} func (*ResourceClassParametersList) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{35} + return fileDescriptor_4312f5b44a31ec02, []int{33} } func (m *ResourceClassParametersList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1058,7 +1002,7 @@ var xxx_messageInfo_ResourceClassParametersList proto.InternalMessageInfo func (m *ResourceClassParametersReference) Reset() { *m = ResourceClassParametersReference{} } func (*ResourceClassParametersReference) ProtoMessage() {} func (*ResourceClassParametersReference) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{36} + return fileDescriptor_4312f5b44a31ec02, []int{34} } func (m *ResourceClassParametersReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1086,7 +1030,7 @@ var xxx_messageInfo_ResourceClassParametersReference proto.InternalMessageInfo func (m *ResourceFilter) Reset() { *m = ResourceFilter{} } func (*ResourceFilter) ProtoMessage() {} func (*ResourceFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{37} + return fileDescriptor_4312f5b44a31ec02, []int{35} } func (m *ResourceFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1114,7 +1058,7 @@ var xxx_messageInfo_ResourceFilter proto.InternalMessageInfo func (m *ResourceFilterModel) Reset() { *m = ResourceFilterModel{} } func (*ResourceFilterModel) ProtoMessage() {} func (*ResourceFilterModel) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{38} + return fileDescriptor_4312f5b44a31ec02, []int{36} } func (m *ResourceFilterModel) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1142,7 +1086,7 @@ var xxx_messageInfo_ResourceFilterModel proto.InternalMessageInfo func (m *ResourceHandle) Reset() { *m = ResourceHandle{} } func (*ResourceHandle) ProtoMessage() {} func (*ResourceHandle) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{39} + return fileDescriptor_4312f5b44a31ec02, []int{37} } func (m *ResourceHandle) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1170,7 +1114,7 @@ var xxx_messageInfo_ResourceHandle proto.InternalMessageInfo func (m *ResourceRequest) Reset() { *m = ResourceRequest{} } func (*ResourceRequest) ProtoMessage() {} func (*ResourceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{40} + return fileDescriptor_4312f5b44a31ec02, []int{38} } func (m *ResourceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1198,7 +1142,7 @@ var xxx_messageInfo_ResourceRequest proto.InternalMessageInfo func (m *ResourceRequestModel) Reset() { *m = ResourceRequestModel{} } func (*ResourceRequestModel) ProtoMessage() {} func (*ResourceRequestModel) Descriptor() ([]byte, []int) { - return fileDescriptor_4312f5b44a31ec02, []int{41} + return fileDescriptor_4312f5b44a31ec02, []int{39} } func (m *ResourceRequestModel) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1223,6 +1167,62 @@ func (m *ResourceRequestModel) XXX_DiscardUnknown() { var xxx_messageInfo_ResourceRequestModel proto.InternalMessageInfo +func (m *ResourceSlice) Reset() { *m = ResourceSlice{} } +func (*ResourceSlice) ProtoMessage() {} +func (*ResourceSlice) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{40} +} +func (m *ResourceSlice) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceSlice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceSlice) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceSlice.Merge(m, src) +} +func (m *ResourceSlice) XXX_Size() int { + return m.Size() +} +func (m *ResourceSlice) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceSlice.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceSlice proto.InternalMessageInfo + +func (m *ResourceSliceList) Reset() { *m = ResourceSliceList{} } +func (*ResourceSliceList) ProtoMessage() {} +func (*ResourceSliceList) Descriptor() ([]byte, []int) { + return fileDescriptor_4312f5b44a31ec02, []int{41} +} +func (m *ResourceSliceList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceSliceList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceSliceList) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceSliceList.Merge(m, src) +} +func (m *ResourceSliceList) XXX_Size() int { + return m.Size() +} +func (m *ResourceSliceList) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceSliceList.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceSliceList proto.InternalMessageInfo + func (m *StructuredResourceHandle) Reset() { *m = StructuredResourceHandle{} } func (*StructuredResourceHandle) ProtoMessage() {} func (*StructuredResourceHandle) Descriptor() ([]byte, []int) { @@ -1294,8 +1294,6 @@ func init() { proto.RegisterType((*NamedResourcesResources)(nil), "k8s.io.api.resource.v1alpha2.NamedResourcesResources") proto.RegisterType((*NamedResourcesStringSlice)(nil), "k8s.io.api.resource.v1alpha2.NamedResourcesStringSlice") proto.RegisterType((*NodeResourceModel)(nil), "k8s.io.api.resource.v1alpha2.NodeResourceModel") - proto.RegisterType((*NodeResourceSlice)(nil), "k8s.io.api.resource.v1alpha2.NodeResourceSlice") - proto.RegisterType((*NodeResourceSliceList)(nil), "k8s.io.api.resource.v1alpha2.NodeResourceSliceList") proto.RegisterType((*PodSchedulingContext)(nil), "k8s.io.api.resource.v1alpha2.PodSchedulingContext") proto.RegisterType((*PodSchedulingContextList)(nil), "k8s.io.api.resource.v1alpha2.PodSchedulingContextList") proto.RegisterType((*PodSchedulingContextSpec)(nil), "k8s.io.api.resource.v1alpha2.PodSchedulingContextSpec") @@ -1322,6 +1320,8 @@ func init() { proto.RegisterType((*ResourceHandle)(nil), "k8s.io.api.resource.v1alpha2.ResourceHandle") proto.RegisterType((*ResourceRequest)(nil), "k8s.io.api.resource.v1alpha2.ResourceRequest") proto.RegisterType((*ResourceRequestModel)(nil), "k8s.io.api.resource.v1alpha2.ResourceRequestModel") + proto.RegisterType((*ResourceSlice)(nil), "k8s.io.api.resource.v1alpha2.ResourceSlice") + proto.RegisterType((*ResourceSliceList)(nil), "k8s.io.api.resource.v1alpha2.ResourceSliceList") proto.RegisterType((*StructuredResourceHandle)(nil), "k8s.io.api.resource.v1alpha2.StructuredResourceHandle") proto.RegisterType((*VendorParameters)(nil), "k8s.io.api.resource.v1alpha2.VendorParameters") } @@ -1331,149 +1331,148 @@ func init() { } var fileDescriptor_4312f5b44a31ec02 = []byte{ - // 2257 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x3a, 0xcd, 0x6f, 0x1b, 0xc7, - 0xf5, 0x5e, 0x92, 0xb6, 0xa8, 0x27, 0x8b, 0x92, 0xd6, 0x92, 0x4d, 0x3b, 0x0a, 0xa9, 0x2c, 0x7e, - 0x3f, 0x54, 0x68, 0x6d, 0x32, 0x96, 0x13, 0xc7, 0x48, 0xd3, 0x02, 0x5e, 0x2b, 0x76, 0x85, 0x26, - 0x8e, 0x32, 0x8c, 0x95, 0x38, 0xfd, 0xca, 0x8a, 0x3b, 0x96, 0xb6, 0x26, 0x77, 0xe9, 0x9d, 0xa1, - 0x62, 0xa3, 0x17, 0xa3, 0xe8, 0xd7, 0xa5, 0x40, 0x8a, 0x16, 0x45, 0x7b, 0xea, 0xa9, 0x28, 0x7a, - 0xe9, 0xa5, 0xfd, 0x0f, 0x82, 0x36, 0x06, 0x7a, 0x71, 0xd0, 0x02, 0x0d, 0x7a, 0x20, 0x6a, 0xf6, - 0xd8, 0x63, 0x6f, 0x39, 0x15, 0xf3, 0xb1, 0x1f, 0xb3, 0xdc, 0xa5, 0xb8, 0x6c, 0x23, 0x24, 0x27, - 0x72, 0x66, 0xde, 0xf7, 0x7b, 0xf3, 0xde, 0x9b, 0x99, 0x85, 0xf3, 0x77, 0xaf, 0x90, 0x86, 0xe3, - 0x35, 0xad, 0x9e, 0xd3, 0xf4, 0x31, 0xf1, 0xfa, 0x7e, 0x1b, 0x37, 0x0f, 0x2e, 0x5a, 0x9d, 0xde, - 0xbe, 0xb5, 0xd1, 0xdc, 0xc3, 0x2e, 0xf6, 0x2d, 0x8a, 0xed, 0x46, 0xcf, 0xf7, 0xa8, 0xa7, 0xaf, - 0x0a, 0xe8, 0x86, 0xd5, 0x73, 0x1a, 0x01, 0x74, 0x23, 0x80, 0x3e, 0x77, 0x61, 0xcf, 0xa1, 0xfb, - 0xfd, 0xdd, 0x46, 0xdb, 0xeb, 0x36, 0xf7, 0xbc, 0x3d, 0xaf, 0xc9, 0x91, 0x76, 0xfb, 0x77, 0xf8, - 0x88, 0x0f, 0xf8, 0x3f, 0x41, 0xec, 0x9c, 0x11, 0x63, 0xdd, 0xf6, 0x7c, 0xc6, 0x36, 0xc9, 0xf0, - 0xdc, 0x73, 0x11, 0x4c, 0xd7, 0x6a, 0xef, 0x3b, 0x2e, 0xf6, 0x1f, 0x34, 0x7b, 0x77, 0xf7, 0x54, - 0x79, 0xf3, 0x60, 0x91, 0x66, 0x17, 0x53, 0x2b, 0x8d, 0x57, 0x33, 0x0b, 0xcb, 0xef, 0xbb, 0xd4, - 0xe9, 0x8e, 0xb2, 0xb9, 0x7c, 0x18, 0x02, 0x69, 0xef, 0xe3, 0xae, 0x95, 0xc4, 0x33, 0x7e, 0x51, - 0x80, 0xc5, 0xab, 0x9d, 0x8e, 0xd7, 0xb6, 0xa8, 0xe3, 0xb9, 0x08, 0x93, 0x7e, 0x87, 0xea, 0x1e, - 0x2c, 0x04, 0xfa, 0x7c, 0xc5, 0x72, 0xed, 0x0e, 0x26, 0x55, 0x6d, 0xad, 0xb8, 0x3e, 0xb7, 0x71, - 0xbe, 0x31, 0xce, 0xe8, 0x0d, 0xa4, 0x20, 0x99, 0x67, 0x1e, 0x0d, 0xea, 0xc7, 0x86, 0x83, 0xfa, - 0x82, 0x3a, 0x4f, 0x50, 0x92, 0xba, 0xbe, 0x0b, 0x8b, 0xd6, 0x81, 0xe5, 0x74, 0xac, 0xdd, 0x0e, - 0x7e, 0xcd, 0xbd, 0xe9, 0xd9, 0x98, 0x54, 0x0b, 0x6b, 0xda, 0xfa, 0xdc, 0xc6, 0x5a, 0x9c, 0x23, - 0xf3, 0x4c, 0xe3, 0xe0, 0x62, 0x83, 0x01, 0xb4, 0x70, 0x07, 0xb7, 0xa9, 0xe7, 0x9b, 0xcb, 0xc3, - 0x41, 0x7d, 0xf1, 0x6a, 0x02, 0x1b, 0x8d, 0xd0, 0xd3, 0x9b, 0x30, 0x4b, 0xf6, 0x2d, 0x1f, 0xb3, - 0xb9, 0x6a, 0x71, 0x4d, 0x5b, 0x2f, 0x9b, 0x4b, 0x52, 0xc0, 0xd9, 0x56, 0xb0, 0x80, 0x22, 0x18, - 0xe3, 0x27, 0x1a, 0xac, 0x24, 0x4d, 0xf3, 0xaa, 0x67, 0xe3, 0x8e, 0x7e, 0x1f, 0x2a, 0xae, 0xd5, - 0xc5, 0x76, 0xa0, 0x17, 0x33, 0x0f, 0x13, 0xf6, 0xa5, 0xf1, 0xe6, 0xb9, 0xa9, 0xe0, 0x24, 0x49, - 0x9b, 0xfa, 0x70, 0x50, 0xaf, 0xa8, 0x30, 0x28, 0xc1, 0xc7, 0xf8, 0x5d, 0x01, 0x4e, 0x6f, 0xfa, - 0xce, 0x01, 0xf6, 0x47, 0x9c, 0xf6, 0x23, 0x0d, 0xce, 0x1c, 0x60, 0xd7, 0xf6, 0x7c, 0x84, 0xef, - 0xf5, 0x31, 0xa1, 0xdb, 0x96, 0x6f, 0x75, 0x31, 0xc5, 0x7e, 0x20, 0xde, 0x85, 0x98, 0x78, 0x61, - 0x90, 0x34, 0x7a, 0x77, 0xf7, 0x1a, 0x32, 0x48, 0x1a, 0xc8, 0x7a, 0xf7, 0xe5, 0xfb, 0x14, 0xbb, - 0xc4, 0xf1, 0x5c, 0xb3, 0x2e, 0xad, 0x73, 0x66, 0x27, 0x9d, 0x2a, 0xca, 0x62, 0xc7, 0x44, 0x59, - 0xb1, 0xd2, 0x2c, 0x27, 0x9d, 0x7a, 0x69, 0xbc, 0x9d, 0x52, 0x8d, 0x6e, 0x3e, 0x2d, 0xc5, 0x49, - 0xf7, 0x09, 0x4a, 0x67, 0x68, 0xfc, 0xbc, 0x00, 0x15, 0x61, 0x30, 0x29, 0x26, 0xd1, 0x37, 0x00, - 0x6c, 0x3e, 0xc3, 0x6c, 0xcd, 0x4d, 0x33, 0x6b, 0xea, 0x92, 0x38, 0x6c, 0x86, 0x2b, 0x28, 0x06, - 0xa5, 0x13, 0x58, 0x14, 0xca, 0xc6, 0x8c, 0x5a, 0x98, 0xc6, 0xa8, 0x55, 0xc9, 0x68, 0x71, 0x27, - 0x41, 0x0e, 0x8d, 0x30, 0xd0, 0xbf, 0x06, 0x65, 0x5f, 0x0a, 0x5d, 0x2d, 0xf2, 0xfd, 0x77, 0x61, - 0xb2, 0xfd, 0x27, 0x55, 0x35, 0x17, 0x25, 0xb3, 0x72, 0xa0, 0x3b, 0x0a, 0x09, 0x1a, 0x26, 0xd4, - 0xc6, 0xc7, 0xa3, 0xbe, 0x06, 0x25, 0x37, 0xb2, 0xd0, 0x49, 0x49, 0xab, 0xc4, 0x6d, 0xc3, 0x57, - 0x8c, 0x3f, 0x69, 0x70, 0x26, 0x41, 0x84, 0x52, 0xdf, 0xd9, 0xed, 0x53, 0x7c, 0x38, 0x36, 0x8b, - 0x92, 0x8a, 0x15, 0xc0, 0xef, 0x58, 0x9d, 0x3e, 0x96, 0x26, 0x7d, 0x31, 0xd7, 0x36, 0x52, 0x28, - 0x98, 0xff, 0x27, 0x19, 0xad, 0x8e, 0x83, 0x42, 0x09, 0xbe, 0xc6, 0xbf, 0x8a, 0x30, 0x16, 0x41, - 0xff, 0x06, 0x94, 0xef, 0xf5, 0x2d, 0x97, 0x3a, 0xf4, 0x41, 0xf5, 0x04, 0x17, 0xb2, 0x91, 0xe9, - 0x77, 0x45, 0xea, 0xd7, 0x25, 0x96, 0xb9, 0x34, 0x1c, 0xd4, 0xe7, 0x83, 0x91, 0x90, 0x22, 0x24, - 0xa9, 0x3f, 0x03, 0xa5, 0x5d, 0xcf, 0x13, 0xdb, 0xa3, 0x6c, 0xce, 0xb3, 0x94, 0x64, 0x7a, 0x5e, - 0x47, 0x80, 0xf1, 0x25, 0xbd, 0x06, 0x45, 0xc7, 0xa5, 0xd5, 0x99, 0x35, 0x6d, 0xbd, 0x68, 0x9e, - 0x64, 0x4e, 0xdd, 0x72, 0xa9, 0x00, 0x60, 0x0b, 0x7a, 0x1b, 0xca, 0x8e, 0x4b, 0x5b, 0x1d, 0xa7, - 0x8d, 0xab, 0x65, 0x2e, 0xe1, 0x73, 0x79, 0xcc, 0xb8, 0x25, 0x71, 0x85, 0x9c, 0xc1, 0x48, 0xca, - 0x19, 0x10, 0xd6, 0x3f, 0x07, 0x27, 0x08, 0xf5, 0x1d, 0x77, 0xaf, 0x7a, 0x9c, 0xbb, 0x75, 0x61, - 0x38, 0xa8, 0xcf, 0xb5, 0xf8, 0x8c, 0x00, 0x95, 0xcb, 0xba, 0x07, 0x73, 0xe2, 0x9f, 0x10, 0x68, - 0x96, 0x0b, 0xf4, 0x42, 0x1e, 0x81, 0x5a, 0x11, 0xba, 0x48, 0xf1, 0xb1, 0x09, 0xc1, 0x2b, 0xce, - 0x41, 0xff, 0x3c, 0xcc, 0x1c, 0x60, 0x9f, 0x6d, 0xb1, 0x2a, 0x70, 0xd1, 0x16, 0x87, 0x83, 0xfa, - 0xc9, 0x1d, 0x31, 0x25, 0xe0, 0x03, 0x00, 0x63, 0x13, 0x96, 0x55, 0x5e, 0xd7, 0x9d, 0x0e, 0xc5, - 0xbe, 0x7e, 0x1e, 0xca, 0x44, 0x56, 0x15, 0x19, 0xb6, 0xe1, 0x06, 0x0a, 0xaa, 0x0d, 0x0a, 0x21, - 0x8c, 0x5f, 0x6b, 0x70, 0x3a, 0x69, 0x43, 0x42, 0x2d, 0xb7, 0x3d, 0x49, 0xec, 0x3b, 0x00, 0x61, - 0x08, 0xb2, 0x4c, 0xc2, 0x36, 0xf7, 0xf3, 0x53, 0x85, 0x7d, 0x94, 0xba, 0xc2, 0x29, 0x82, 0x62, - 0xc4, 0x8d, 0xcb, 0xa3, 0x62, 0x4a, 0x6f, 0xae, 0x42, 0xc9, 0x71, 0xa9, 0xa8, 0xed, 0x45, 0xb3, - 0xcc, 0x44, 0xdc, 0x72, 0x29, 0x41, 0x7c, 0xd6, 0x78, 0x19, 0x56, 0x12, 0xc5, 0x48, 0xa4, 0x8e, - 0x9c, 0x66, 0x7a, 0x38, 0x92, 0x23, 0xc2, 0x3f, 0x3a, 0x86, 0x59, 0x47, 0xda, 0x2c, 0xe8, 0x30, - 0x72, 0x06, 0xad, 0x40, 0x8e, 0x0a, 0x79, 0x30, 0x43, 0x50, 0x44, 0xd9, 0x30, 0xe1, 0x6c, 0x66, - 0x6c, 0xe9, 0xff, 0x0f, 0x33, 0x22, 0x8e, 0x84, 0x04, 0xb3, 0xe6, 0xdc, 0x70, 0x50, 0x9f, 0x11, - 0x10, 0x04, 0x05, 0x6b, 0xc6, 0x0f, 0x34, 0x58, 0x62, 0x7d, 0x44, 0x40, 0x43, 0x34, 0x02, 0xf7, - 0x32, 0x1a, 0x81, 0x5c, 0xae, 0x0c, 0xff, 0x4c, 0xd4, 0x01, 0x7c, 0x58, 0x50, 0x05, 0x11, 0x5a, - 0xbc, 0x03, 0x65, 0xd6, 0x4a, 0xda, 0x16, 0xb5, 0xa4, 0x08, 0xcf, 0x8e, 0xcb, 0x4f, 0xa4, 0xc1, - 0xa0, 0x59, 0x2b, 0xf5, 0xda, 0xee, 0xb7, 0x71, 0x9b, 0xbe, 0x8a, 0xa9, 0x15, 0x05, 0x52, 0x34, - 0x87, 0x42, 0xaa, 0xcc, 0xeb, 0xae, 0x67, 0x63, 0x5e, 0x33, 0x0b, 0xaa, 0xd7, 0x6f, 0xca, 0x79, - 0x14, 0x42, 0x24, 0x6a, 0x6c, 0x71, 0xa2, 0x1a, 0x7b, 0x1f, 0x96, 0xdc, 0xa4, 0x85, 0xab, 0x25, - 0xae, 0x4c, 0xf3, 0x10, 0x7b, 0x26, 0xd1, 0xcc, 0xb3, 0x92, 0xd7, 0xa8, 0xcf, 0xd0, 0x28, 0x13, - 0xe3, 0xcf, 0x1a, 0xac, 0x8c, 0xd8, 0xf4, 0x15, 0x87, 0x50, 0xfd, 0xeb, 0x23, 0x76, 0x6d, 0x4c, - 0x66, 0x57, 0x86, 0xcd, 0xad, 0x1a, 0x5a, 0x29, 0x98, 0x89, 0xd9, 0xf4, 0x0d, 0x38, 0xee, 0x50, - 0xdc, 0x0d, 0x12, 0x40, 0x0e, 0x2d, 0x45, 0x5e, 0x9c, 0x97, 0xb4, 0x8f, 0x6f, 0x31, 0x2a, 0x48, - 0x10, 0x33, 0xfe, 0x50, 0x80, 0xe5, 0x6d, 0xcf, 0x6e, 0xb5, 0xf7, 0xb1, 0xdd, 0xef, 0x38, 0xee, - 0xde, 0x35, 0xcf, 0xa5, 0xf8, 0x3e, 0x3d, 0x82, 0x20, 0x79, 0x0b, 0x4a, 0xa4, 0x87, 0xdb, 0xb2, - 0x8e, 0x5f, 0x1e, 0xaf, 0x4f, 0x9a, 0x8c, 0xad, 0x1e, 0x6e, 0x47, 0x09, 0x93, 0x8d, 0x10, 0xa7, - 0xa8, 0xbf, 0xc3, 0x2a, 0x8f, 0x45, 0xfb, 0x84, 0x07, 0xd3, 0xdc, 0xc6, 0x95, 0x29, 0x68, 0x73, - 0x7c, 0xb3, 0x22, 0xa9, 0x9f, 0x10, 0x63, 0x24, 0xe9, 0x1a, 0x1f, 0x6a, 0x50, 0x4d, 0x43, 0x3b, - 0x82, 0x38, 0x78, 0x53, 0x8d, 0x83, 0x8d, 0xfc, 0xba, 0x65, 0x84, 0xc2, 0x7b, 0x19, 0x3a, 0x31, - 0xc3, 0xea, 0x57, 0xe0, 0xa4, 0xc8, 0xd2, 0xd8, 0x66, 0xa1, 0x25, 0x73, 0xf9, 0xb2, 0x24, 0x74, - 0xb2, 0x15, 0x5b, 0x43, 0x0a, 0xa4, 0xfe, 0x22, 0x54, 0x7a, 0x1e, 0xc5, 0x2e, 0x75, 0xac, 0x4e, - 0x70, 0x58, 0x63, 0xa9, 0x93, 0xe7, 0xaf, 0x6d, 0x65, 0x05, 0x25, 0x20, 0x8d, 0x5f, 0x6a, 0x70, - 0x2e, 0xdb, 0x3b, 0xfa, 0x77, 0xa0, 0x12, 0x68, 0x7c, 0xad, 0x63, 0x39, 0xdd, 0xa0, 0x2e, 0x7c, - 0x71, 0xb2, 0xce, 0x97, 0xe3, 0x44, 0xb4, 0xa5, 0xcb, 0x4f, 0x4b, 0x9d, 0x2a, 0x0a, 0x18, 0x41, - 0x09, 0x56, 0xc6, 0xaf, 0x0a, 0x30, 0xaf, 0x80, 0x1c, 0xc1, 0x96, 0x79, 0x5d, 0xd9, 0x32, 0xcd, - 0x3c, 0x6a, 0x66, 0xed, 0x95, 0xdb, 0x89, 0xbd, 0x72, 0x31, 0x0f, 0xd1, 0xf1, 0x9b, 0x64, 0xa8, - 0x41, 0x4d, 0x81, 0xbf, 0xe6, 0xb9, 0xa4, 0xdf, 0x65, 0xa7, 0xab, 0x3b, 0xd8, 0xc7, 0xac, 0xf9, - 0x39, 0x0f, 0x65, 0xab, 0xe7, 0xdc, 0xf0, 0xbd, 0x7e, 0x2f, 0xd9, 0x1e, 0x5c, 0xdd, 0xde, 0xe2, - 0xf3, 0x28, 0x84, 0x60, 0xd0, 0x81, 0x44, 0xb2, 0x4c, 0xc4, 0x0e, 0x2d, 0xf2, 0x34, 0x13, 0x42, - 0x84, 0x8d, 0x55, 0x29, 0xb3, 0xb1, 0x32, 0xa1, 0xd8, 0x77, 0x6c, 0xd9, 0x9e, 0x3e, 0x2b, 0x01, - 0x8a, 0xb7, 0xb6, 0x36, 0x3f, 0x1e, 0xd4, 0x9f, 0xc9, 0xba, 0x23, 0xa1, 0x0f, 0x7a, 0x98, 0x34, - 0x6e, 0x6d, 0x6d, 0x22, 0x86, 0x6c, 0xbc, 0xaf, 0xc1, 0x92, 0xa2, 0xe4, 0x11, 0xa4, 0x80, 0x6d, - 0x35, 0x05, 0x7c, 0x21, 0x87, 0xcb, 0x32, 0xf6, 0xfe, 0x4f, 0x8b, 0x70, 0x46, 0x81, 0x8b, 0x9d, - 0x2c, 0x3f, 0xf9, 0xb0, 0x7e, 0x17, 0xe6, 0xc3, 0xab, 0xa6, 0xeb, 0xbe, 0xd7, 0x95, 0xf1, 0xfd, - 0xe5, 0x1c, 0x7a, 0xc5, 0xce, 0xc6, 0x41, 0x70, 0x89, 0xd3, 0xc9, 0x8d, 0x38, 0x61, 0xa4, 0xf2, - 0xc9, 0x7d, 0xcd, 0xa3, 0x77, 0xa0, 0x62, 0x2b, 0x17, 0x04, 0xd5, 0xd2, 0x24, 0x77, 0x5d, 0xea, - 0xa5, 0x42, 0x94, 0x62, 0xd4, 0x79, 0x94, 0xa0, 0x6d, 0xfc, 0x4d, 0x83, 0xa7, 0x32, 0xb4, 0x3c, - 0x82, 0x28, 0x7b, 0x5b, 0x8d, 0xb2, 0xe7, 0xa7, 0xf2, 0x46, 0x46, 0xbc, 0xfd, 0x4c, 0x83, 0xb5, - 0xc3, 0xfc, 0x97, 0x33, 0x39, 0xac, 0x41, 0xe9, 0xae, 0xe3, 0xda, 0xb2, 0xdf, 0x0c, 0xb7, 0xfb, - 0x57, 0x1d, 0xd7, 0x46, 0x7c, 0x25, 0x4c, 0x08, 0xc5, 0xcc, 0x3b, 0x8a, 0x87, 0x1a, 0x3c, 0x3d, - 0xb6, 0x3a, 0x4c, 0x70, 0x5a, 0xfb, 0x12, 0x2c, 0xf4, 0x5d, 0xd2, 0x77, 0x28, 0x0b, 0x98, 0x78, - 0xc1, 0x3b, 0x35, 0x1c, 0xd4, 0x17, 0x6e, 0xa9, 0x4b, 0x28, 0x09, 0x6b, 0xfc, 0xa6, 0x90, 0xc8, - 0x27, 0xbc, 0xfc, 0xde, 0x80, 0xa5, 0x58, 0xf9, 0x21, 0x24, 0x76, 0x1b, 0x15, 0x76, 0xaf, 0x28, - 0x09, 0x80, 0x46, 0x71, 0xd8, 0x56, 0xeb, 0xc5, 0x4d, 0xfd, 0xbf, 0xdc, 0x6a, 0xca, 0x02, 0x52, - 0xf9, 0xe8, 0xdb, 0x50, 0x89, 0x2e, 0xdd, 0x58, 0x27, 0x2d, 0xdd, 0xb0, 0x1e, 0xec, 0x85, 0xab, - 0xca, 0xea, 0xc7, 0x23, 0x33, 0x28, 0x81, 0x6f, 0xfc, 0xbb, 0x00, 0xa7, 0x52, 0xca, 0xd1, 0x54, - 0x57, 0x76, 0xdf, 0x04, 0x88, 0xa8, 0x4b, 0x9b, 0x34, 0xf2, 0x5d, 0x3c, 0x9a, 0x15, 0x7e, 0xae, - 0x8e, 0x66, 0x63, 0x14, 0x75, 0x02, 0x73, 0x3e, 0x26, 0xd8, 0x3f, 0xc0, 0xf6, 0x75, 0xcf, 0x97, - 0x17, 0x74, 0x2f, 0xe5, 0x30, 0xfa, 0x48, 0xe9, 0x34, 0x4f, 0x49, 0x95, 0xe6, 0x50, 0x44, 0x18, - 0xc5, 0xb9, 0xe8, 0x2d, 0x58, 0xb1, 0x71, 0xfc, 0xa6, 0x93, 0xa7, 0x15, 0x6c, 0xf3, 0x8a, 0x58, - 0x8e, 0xee, 0x48, 0x37, 0xd3, 0x80, 0x50, 0x3a, 0xae, 0xf1, 0x57, 0x0d, 0x56, 0x14, 0xc9, 0xde, - 0xc0, 0xdd, 0x5e, 0xc7, 0xa2, 0x47, 0x71, 0xac, 0xbc, 0xad, 0xb4, 0x3f, 0x2f, 0xe4, 0x30, 0x5f, - 0x20, 0x64, 0x56, 0x1b, 0x64, 0xfc, 0x45, 0x83, 0xb3, 0xa9, 0x18, 0x47, 0x90, 0x68, 0xdf, 0x52, - 0x13, 0xed, 0xa5, 0x29, 0xf4, 0xca, 0x48, 0xb3, 0x8f, 0xb3, 0xb4, 0x6a, 0x89, 0x63, 0xd2, 0x67, - 0xaf, 0x5f, 0x35, 0x3e, 0x28, 0x2a, 0x6d, 0x37, 0x39, 0x8a, 0xfe, 0x44, 0xcd, 0x28, 0x85, 0x89, - 0x32, 0xca, 0x48, 0xa2, 0x2d, 0xe6, 0x4c, 0xb4, 0x84, 0x4c, 0x97, 0x68, 0x6f, 0xc3, 0xbc, 0x5a, - 0x7d, 0x4a, 0x13, 0xbe, 0x8d, 0x71, 0xd2, 0x2d, 0xa5, 0x3a, 0xa9, 0x94, 0xf4, 0x57, 0x60, 0x99, - 0x50, 0xbf, 0xdf, 0xa6, 0x7d, 0x1f, 0xdb, 0xb1, 0xc7, 0x8d, 0xe3, 0x3c, 0x9f, 0x54, 0x87, 0x83, - 0xfa, 0x72, 0x2b, 0x65, 0x1d, 0xa5, 0x62, 0x25, 0x3b, 0x67, 0x42, 0x3e, 0xcd, 0x9d, 0x33, 0xc9, - 0xea, 0x64, 0xde, 0x57, 0x3b, 0xe7, 0xb8, 0xd7, 0x3e, 0x0b, 0x9d, 0xf3, 0x98, 0x28, 0x1b, 0xdb, - 0x39, 0xd3, 0x94, 0x37, 0x2e, 0x51, 0xd5, 0x0e, 0x29, 0x9b, 0xc9, 0xa7, 0xac, 0x5c, 0x8f, 0x5c, - 0x6f, 0xc2, 0xcc, 0x1d, 0x7e, 0xfd, 0x3e, 0x61, 0xdf, 0x1d, 0x28, 0x2a, 0xee, 0xec, 0xcd, 0x05, - 0xc9, 0x6a, 0x46, 0x8c, 0x09, 0x0a, 0xa8, 0x25, 0x3b, 0xed, 0xb8, 0x55, 0x3e, 0xcd, 0x9d, 0x76, - 0x5c, 0xce, 0x8c, 0xf8, 0xfc, 0xa3, 0xda, 0x69, 0xa7, 0xfa, 0xfb, 0xe8, 0x3b, 0x6d, 0x76, 0xf2, - 0x62, 0xbf, 0xa4, 0x67, 0xb5, 0x83, 0x13, 0x7a, 0x78, 0xf2, 0xba, 0x19, 0x2c, 0xa0, 0x08, 0xc6, - 0xf8, 0x40, 0x83, 0x8a, 0xea, 0xce, 0xa9, 0x1a, 0xbd, 0x87, 0x1a, 0x9c, 0xf2, 0x15, 0x32, 0xf1, - 0xb7, 0xe6, 0x8b, 0x79, 0xc2, 0x49, 0x5c, 0x1e, 0x3f, 0x25, 0x19, 0x9e, 0x4a, 0x59, 0x44, 0x69, - 0xac, 0x8c, 0xef, 0x6b, 0x90, 0x06, 0xac, 0xbb, 0x19, 0xef, 0x03, 0x1b, 0x79, 0xde, 0x07, 0x64, - 0xa4, 0x4f, 0xf2, 0x38, 0xf0, 0xf7, 0x98, 0x45, 0xc5, 0xb7, 0x15, 0x53, 0x59, 0x74, 0x0d, 0x4a, - 0x7c, 0x5b, 0x24, 0xa2, 0x61, 0xd3, 0xa2, 0x16, 0xe2, 0x2b, 0xba, 0x0f, 0x95, 0xa8, 0x00, 0xb0, - 0x79, 0x5e, 0x30, 0x0e, 0xbd, 0xf2, 0x8d, 0x4a, 0x49, 0xe2, 0x53, 0x11, 0xae, 0x5c, 0x4b, 0xa1, - 0x88, 0x12, 0x1c, 0x8c, 0x1f, 0x17, 0x60, 0x21, 0xf1, 0xc2, 0x9d, 0xfa, 0x2e, 0xaf, 0x7d, 0xd2, - 0xef, 0xf2, 0xdf, 0xd3, 0x60, 0xd9, 0x57, 0x05, 0x89, 0x47, 0xdc, 0x46, 0xae, 0x47, 0x7a, 0x11, - 0x72, 0xab, 0x92, 0xfd, 0x72, 0xda, 0x2a, 0x4a, 0xe5, 0x66, 0xfc, 0x50, 0x83, 0x54, 0x70, 0xdd, - 0xcb, 0x88, 0xba, 0x4b, 0xf9, 0x5e, 0xa5, 0xc4, 0x37, 0x04, 0x93, 0x84, 0xdd, 0xef, 0x8b, 0x50, - 0xcd, 0x72, 0xad, 0xfe, 0x5d, 0x0d, 0x56, 0x84, 0x09, 0x13, 0xb9, 0x6a, 0x3a, 0x47, 0x85, 0x47, - 0x9c, 0x9d, 0x34, 0x9a, 0x28, 0x9d, 0x95, 0x2a, 0x44, 0xfc, 0xbc, 0x3b, 0xdd, 0x57, 0x1c, 0xa3, - 0x42, 0x28, 0x67, 0xe8, 0x74, 0x56, 0xca, 0x13, 0x5a, 0xe9, 0xd0, 0x27, 0xb4, 0x6f, 0xc1, 0x8c, - 0xcf, 0x4f, 0xa1, 0xac, 0x19, 0x9b, 0xe0, 0x69, 0x34, 0xfd, 0xb3, 0xa0, 0xa8, 0x40, 0x8a, 0x31, - 0x41, 0x01, 0x55, 0xe3, 0xb7, 0x1a, 0x8c, 0x44, 0xfb, 0x54, 0xe9, 0xc2, 0x02, 0xe8, 0xfd, 0x97, - 0x06, 0x0d, 0x59, 0xc4, 0xac, 0x18, 0x23, 0x6a, 0x9a, 0x8f, 0x9e, 0xd4, 0x8e, 0x3d, 0x7e, 0x52, - 0x3b, 0xf6, 0xd1, 0x93, 0xda, 0xb1, 0x87, 0xc3, 0x9a, 0xf6, 0x68, 0x58, 0xd3, 0x1e, 0x0f, 0x6b, - 0xda, 0x47, 0xc3, 0x9a, 0xf6, 0x8f, 0x61, 0x4d, 0x7b, 0xef, 0x9f, 0xb5, 0x63, 0x6f, 0xaf, 0x8e, - 0xfb, 0x80, 0xf0, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x03, 0x20, 0x09, 0x51, 0x5f, 0x28, 0x00, - 0x00, + // 2251 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5a, 0xcb, 0x6f, 0x1b, 0xc7, + 0x19, 0xd7, 0x92, 0xb4, 0x45, 0x7d, 0x92, 0x28, 0x69, 0x25, 0x59, 0xb4, 0xa3, 0x90, 0xcc, 0xa2, + 0x45, 0x85, 0x56, 0x26, 0x63, 0x39, 0x71, 0x8c, 0x34, 0x2d, 0xe0, 0xb5, 0x62, 0x57, 0x68, 0xe2, + 0x28, 0xc3, 0x5a, 0x89, 0xd3, 0x57, 0x56, 0xdc, 0xb1, 0xb4, 0x35, 0xb9, 0x4b, 0xef, 0x0c, 0x15, + 0x1b, 0xbd, 0x18, 0x45, 0x5f, 0x97, 0x02, 0x29, 0x5a, 0x14, 0xed, 0xa9, 0xa7, 0xa2, 0xe8, 0xa5, + 0x97, 0xf6, 0x3f, 0x08, 0xda, 0xf8, 0x52, 0xc0, 0x45, 0x0b, 0x34, 0xe8, 0x81, 0xa8, 0xd9, 0x63, + 0x8f, 0xbd, 0xe5, 0x54, 0xec, 0xcc, 0xec, 0x63, 0x96, 0xbb, 0x14, 0x97, 0x8d, 0x05, 0xe7, 0x24, + 0xed, 0xcc, 0xf7, 0x9a, 0x6f, 0xbe, 0xc7, 0x6f, 0x66, 0x08, 0x9b, 0x77, 0x2e, 0x93, 0xba, 0xe5, + 0x34, 0x8c, 0xae, 0xd5, 0x70, 0x31, 0x71, 0x7a, 0x6e, 0x0b, 0x37, 0x8e, 0x2e, 0x18, 0xed, 0xee, + 0xa1, 0xb1, 0xd5, 0x38, 0xc0, 0x36, 0x76, 0x0d, 0x8a, 0xcd, 0x7a, 0xd7, 0x75, 0xa8, 0xa3, 0xae, + 0x73, 0xea, 0xba, 0xd1, 0xb5, 0xea, 0x3e, 0x75, 0xdd, 0xa7, 0x3e, 0x77, 0xfe, 0xc0, 0xa2, 0x87, + 0xbd, 0xfd, 0x7a, 0xcb, 0xe9, 0x34, 0x0e, 0x9c, 0x03, 0xa7, 0xc1, 0x98, 0xf6, 0x7b, 0xb7, 0xd9, + 0x17, 0xfb, 0x60, 0xff, 0x71, 0x61, 0xe7, 0xb4, 0x88, 0xea, 0x96, 0xe3, 0x7a, 0x6a, 0xe3, 0x0a, + 0xcf, 0xbd, 0x10, 0xd2, 0x74, 0x8c, 0xd6, 0xa1, 0x65, 0x63, 0xf7, 0x7e, 0xa3, 0x7b, 0xe7, 0x40, + 0xb6, 0x37, 0x0b, 0x17, 0x69, 0x74, 0x30, 0x35, 0x92, 0x74, 0x35, 0xd2, 0xb8, 0xdc, 0x9e, 0x4d, + 0xad, 0xce, 0xb0, 0x9a, 0x4b, 0xc7, 0x31, 0x90, 0xd6, 0x21, 0xee, 0x18, 0x71, 0x3e, 0xed, 0x97, + 0x39, 0x58, 0xbc, 0xd2, 0x6e, 0x3b, 0x2d, 0x83, 0x5a, 0x8e, 0x8d, 0x30, 0xe9, 0xb5, 0xa9, 0xea, + 0xc0, 0x82, 0xbf, 0x9e, 0xaf, 0x18, 0xb6, 0xd9, 0xc6, 0xa4, 0xac, 0xd4, 0xf2, 0x1b, 0xb3, 0x5b, + 0x9b, 0xf5, 0x51, 0x4e, 0xaf, 0x23, 0x89, 0x49, 0x5f, 0x7b, 0xd8, 0xaf, 0x4e, 0x0d, 0xfa, 0xd5, + 0x05, 0x79, 0x9c, 0xa0, 0xb8, 0x74, 0x75, 0x1f, 0x16, 0x8d, 0x23, 0xc3, 0x6a, 0x1b, 0xfb, 0x6d, + 0xfc, 0x86, 0x7d, 0xc3, 0x31, 0x31, 0x29, 0xe7, 0x6a, 0xca, 0xc6, 0xec, 0x56, 0x2d, 0xaa, 0xd1, + 0xdb, 0x99, 0xfa, 0xd1, 0x85, 0xba, 0x47, 0xd0, 0xc4, 0x6d, 0xdc, 0xa2, 0x8e, 0xab, 0xaf, 0x0c, + 0xfa, 0xd5, 0xc5, 0x2b, 0x31, 0x6e, 0x34, 0x24, 0x4f, 0x6d, 0xc0, 0x0c, 0x39, 0x34, 0x5c, 0xec, + 0x8d, 0x95, 0xf3, 0x35, 0x65, 0xa3, 0xa8, 0x2f, 0x09, 0x03, 0x67, 0x9a, 0xfe, 0x04, 0x0a, 0x69, + 0xb4, 0x9f, 0x2a, 0xb0, 0x1a, 0x77, 0xcd, 0xeb, 0x8e, 0x89, 0xdb, 0xea, 0x3d, 0x28, 0xd9, 0x46, + 0x07, 0x9b, 0xfe, 0xba, 0x3c, 0xf7, 0x78, 0xc6, 0xbe, 0x32, 0xda, 0x3d, 0x37, 0x24, 0x9e, 0xb8, + 0x68, 0x5d, 0x1d, 0xf4, 0xab, 0x25, 0x99, 0x06, 0xc5, 0xf4, 0x68, 0xbf, 0xcf, 0xc1, 0x99, 0x6d, + 0xd7, 0x3a, 0xc2, 0xee, 0xd0, 0xa6, 0xfd, 0x58, 0x81, 0xb5, 0x23, 0x6c, 0x9b, 0x8e, 0x8b, 0xf0, + 0xdd, 0x1e, 0x26, 0x74, 0xd7, 0x70, 0x8d, 0x0e, 0xa6, 0xd8, 0xf5, 0xcd, 0x3b, 0x1f, 0x31, 0x2f, + 0x08, 0x92, 0x7a, 0xf7, 0xce, 0x41, 0x5d, 0x04, 0x49, 0x1d, 0x19, 0xef, 0xbd, 0x7a, 0x8f, 0x62, + 0x9b, 0x58, 0x8e, 0xad, 0x57, 0x85, 0x77, 0xd6, 0xf6, 0x92, 0xa5, 0xa2, 0x34, 0x75, 0x9e, 0x29, + 0xab, 0x46, 0x92, 0xe7, 0xc4, 0xa6, 0x5e, 0x1c, 0xed, 0xa7, 0x44, 0xa7, 0xeb, 0xcf, 0x0a, 0x73, + 0x92, 0xf7, 0x04, 0x25, 0x2b, 0xd4, 0x7e, 0x91, 0x83, 0x12, 0x77, 0x98, 0x30, 0x93, 0xa8, 0x5b, + 0x00, 0x26, 0x1b, 0xf1, 0x7c, 0xcd, 0x5c, 0x33, 0xa3, 0xab, 0x42, 0x38, 0x6c, 0x07, 0x33, 0x28, + 0x42, 0xa5, 0x12, 0x58, 0xe4, 0x8b, 0x8d, 0x38, 0x35, 0x37, 0x89, 0x53, 0xcb, 0x42, 0xd1, 0xe2, + 0x5e, 0x4c, 0x1c, 0x1a, 0x52, 0xa0, 0x7e, 0x1d, 0x8a, 0xae, 0x30, 0xba, 0x9c, 0x67, 0xf9, 0x77, + 0x7e, 0xbc, 0xfc, 0x13, 0x4b, 0xd5, 0x17, 0x85, 0xb2, 0xa2, 0xbf, 0x76, 0x14, 0x08, 0xd4, 0x74, + 0xa8, 0x8c, 0x8e, 0x47, 0xb5, 0x06, 0x05, 0x3b, 0xf4, 0xd0, 0x9c, 0x90, 0x55, 0x60, 0xbe, 0x61, + 0x33, 0xda, 0x9f, 0x15, 0x58, 0x8b, 0x09, 0xa1, 0xd4, 0xb5, 0xf6, 0x7b, 0x14, 0x1f, 0xcf, 0xed, + 0x45, 0x49, 0xc9, 0xf0, 0xe9, 0xf7, 0x8c, 0x76, 0x0f, 0x0b, 0x97, 0xbe, 0x9c, 0x29, 0x8d, 0x24, + 0x09, 0xfa, 0x67, 0x84, 0xa2, 0xf5, 0x51, 0x54, 0x28, 0xa6, 0x57, 0xfb, 0x4f, 0x1e, 0x46, 0x32, + 0xa8, 0xdf, 0x84, 0xe2, 0xdd, 0x9e, 0x61, 0x53, 0x8b, 0xde, 0x2f, 0x9f, 0x66, 0x46, 0xd6, 0x53, + 0xf7, 0x5d, 0xb2, 0xfa, 0x4d, 0xc1, 0xa5, 0x2f, 0x0d, 0xfa, 0xd5, 0x79, 0xff, 0x8b, 0x5b, 0x11, + 0x88, 0x54, 0x9f, 0x83, 0xc2, 0xbe, 0xe3, 0xf0, 0xf4, 0x28, 0xea, 0xf3, 0x5e, 0x49, 0xd2, 0x1d, + 0xa7, 0xcd, 0xc9, 0xd8, 0x94, 0x5a, 0x81, 0xbc, 0x65, 0xd3, 0xf2, 0x74, 0x4d, 0xd9, 0xc8, 0xeb, + 0x73, 0xde, 0xa6, 0xee, 0xd8, 0x94, 0x13, 0x78, 0x13, 0x6a, 0x0b, 0x8a, 0x96, 0x4d, 0x9b, 0x6d, + 0xab, 0x85, 0xcb, 0x45, 0x66, 0xe1, 0x0b, 0x59, 0xdc, 0xb8, 0x23, 0x78, 0xb9, 0x9d, 0xfe, 0x97, + 0xb0, 0xd3, 0x17, 0xac, 0x7e, 0x0e, 0x4e, 0x13, 0xea, 0x5a, 0xf6, 0x41, 0xf9, 0x14, 0xdb, 0xd6, + 0x85, 0x41, 0xbf, 0x3a, 0xdb, 0x64, 0x23, 0x9c, 0x54, 0x4c, 0xab, 0x0e, 0xcc, 0xf2, 0xff, 0xb8, + 0x41, 0x33, 0xcc, 0xa0, 0x97, 0xb2, 0x18, 0xd4, 0x0c, 0xd9, 0x79, 0x89, 0x8f, 0x0c, 0x70, 0x5d, + 0x51, 0x0d, 0xea, 0xe7, 0x61, 0xfa, 0x08, 0xbb, 0x5e, 0x8a, 0x95, 0x81, 0x99, 0xb6, 0x38, 0xe8, + 0x57, 0xe7, 0xf6, 0xf8, 0x10, 0xa7, 0xf7, 0x09, 0xb4, 0x6d, 0x58, 0x91, 0x75, 0x5d, 0xb3, 0xda, + 0x14, 0xbb, 0xea, 0x26, 0x14, 0x89, 0xe8, 0x2a, 0x22, 0x6c, 0x83, 0x04, 0xf2, 0xbb, 0x0d, 0x0a, + 0x28, 0xb4, 0xdf, 0x28, 0x70, 0x26, 0xee, 0x43, 0x42, 0x0d, 0xbb, 0x35, 0x4e, 0xec, 0x5b, 0x00, + 0x41, 0x08, 0x7a, 0x95, 0xc4, 0x4b, 0xee, 0x17, 0x27, 0x0a, 0xfb, 0xb0, 0x74, 0x05, 0x43, 0x04, + 0x45, 0x84, 0x6b, 0x97, 0x86, 0xcd, 0x14, 0xbb, 0xb9, 0x0e, 0x05, 0xcb, 0xa6, 0xbc, 0xb7, 0xe7, + 0xf5, 0xa2, 0x67, 0xe2, 0x8e, 0x4d, 0x09, 0x62, 0xa3, 0xda, 0xab, 0xb0, 0x1a, 0x6b, 0x46, 0xbc, + 0x74, 0x64, 0x74, 0xd3, 0x83, 0xa1, 0x1a, 0x11, 0xfc, 0xa3, 0x62, 0x98, 0xb1, 0x84, 0xcf, 0x7c, + 0x84, 0x91, 0x31, 0x68, 0x39, 0x73, 0xd8, 0xc8, 0xfd, 0x11, 0x82, 0x42, 0xc9, 0x9a, 0x0e, 0x67, + 0x53, 0x63, 0x4b, 0xfd, 0x2c, 0x4c, 0xf3, 0x38, 0xe2, 0x16, 0xcc, 0xe8, 0xb3, 0x83, 0x7e, 0x75, + 0x9a, 0x53, 0x10, 0xe4, 0xcf, 0x69, 0x3f, 0x54, 0x60, 0xc9, 0xc3, 0x11, 0xbe, 0x0c, 0x0e, 0x04, + 0xee, 0xa6, 0x00, 0x81, 0x4c, 0x5b, 0x19, 0xfc, 0x33, 0x16, 0x02, 0xf8, 0x63, 0x0e, 0x56, 0x76, + 0x1d, 0xb3, 0xd9, 0x3a, 0xc4, 0x66, 0xaf, 0x6d, 0xd9, 0x07, 0x57, 0x1d, 0x9b, 0xe2, 0x7b, 0x54, + 0x7d, 0x17, 0x8a, 0x1e, 0x9a, 0x34, 0x0d, 0x6a, 0x08, 0x2b, 0x9e, 0x1f, 0x55, 0xa2, 0x48, 0xdd, + 0xa3, 0xf6, 0xd0, 0xd4, 0x1b, 0xfb, 0xdf, 0xc1, 0x2d, 0xfa, 0x3a, 0xa6, 0x46, 0x18, 0x4b, 0xe1, + 0x18, 0x0a, 0xa4, 0xaa, 0x6f, 0x43, 0x81, 0x74, 0x71, 0x4b, 0x54, 0xe9, 0x4b, 0xa3, 0xd7, 0x98, + 0x64, 0x63, 0xb3, 0x8b, 0x5b, 0x61, 0x3a, 0x78, 0x5f, 0x88, 0x49, 0x54, 0xdf, 0xf5, 0xea, 0x8a, + 0x41, 0x7b, 0x84, 0x01, 0xb3, 0xd9, 0xad, 0xcb, 0x13, 0xc8, 0x66, 0xfc, 0x7a, 0x49, 0x48, 0x3f, + 0xcd, 0xbf, 0x91, 0x90, 0xab, 0xfd, 0x55, 0x81, 0x72, 0x12, 0xdb, 0x6b, 0x16, 0xa1, 0xea, 0x37, + 0x86, 0x5c, 0x57, 0x1f, 0xcf, 0x75, 0x1e, 0x37, 0x73, 0x5c, 0x90, 0x01, 0xfe, 0x48, 0xc4, 0x6d, + 0x6f, 0xc1, 0x29, 0x8b, 0xe2, 0x8e, 0x9f, 0xe6, 0x5b, 0xd9, 0xd7, 0xa6, 0xcf, 0x0b, 0xf1, 0xa7, + 0x76, 0x3c, 0x41, 0x88, 0xcb, 0xd3, 0xde, 0x4f, 0x59, 0x93, 0xe7, 0x58, 0xf5, 0x32, 0xcc, 0xf1, + 0x1c, 0xc4, 0xa6, 0x17, 0xb7, 0x22, 0x53, 0x57, 0x84, 0xa0, 0xb9, 0x66, 0x64, 0x0e, 0x49, 0x94, + 0xea, 0xcb, 0x50, 0xea, 0x3a, 0x14, 0xdb, 0xd4, 0x32, 0xda, 0x3e, 0x14, 0xf7, 0x12, 0x83, 0x45, + 0xe7, 0xae, 0x34, 0x83, 0x62, 0x94, 0xda, 0xaf, 0x14, 0x38, 0x97, 0xbe, 0x3b, 0xea, 0x77, 0xa1, + 0xe4, 0xaf, 0xf8, 0x6a, 0xdb, 0xb0, 0x3a, 0x7e, 0xd6, 0x7f, 0x71, 0x3c, 0x5c, 0xc3, 0x78, 0x42, + 0xd9, 0x62, 0xcb, 0xcf, 0x88, 0x35, 0x95, 0x24, 0x32, 0x82, 0x62, 0xaa, 0xb4, 0x5f, 0xe7, 0x60, + 0x5e, 0x22, 0x39, 0x81, 0x94, 0x79, 0x53, 0x4a, 0x99, 0x46, 0x96, 0x65, 0xa6, 0xe5, 0xca, 0xad, + 0x58, 0xae, 0x5c, 0xc8, 0x22, 0x74, 0x74, 0x92, 0x0c, 0x14, 0xa8, 0x48, 0xf4, 0x57, 0x1d, 0x9b, + 0xf4, 0x3a, 0x1e, 0x76, 0xbe, 0x8d, 0x5d, 0xec, 0xb5, 0xb6, 0x4d, 0x28, 0x1a, 0x5d, 0xeb, 0xba, + 0xeb, 0xf4, 0xba, 0xf1, 0xe2, 0x7f, 0x65, 0x77, 0x87, 0x8d, 0xa3, 0x80, 0xc2, 0xa3, 0xf6, 0x2d, + 0x62, 0xd6, 0xce, 0x44, 0x21, 0xa9, 0xc0, 0xaa, 0x01, 0x45, 0xd0, 0x36, 0x0b, 0xa9, 0x6d, 0x53, + 0x87, 0x7c, 0xcf, 0x32, 0x05, 0xf8, 0x78, 0x5e, 0x10, 0xe4, 0x6f, 0xee, 0x6c, 0x7f, 0xdc, 0xaf, + 0x3e, 0x97, 0x76, 0x02, 0xa6, 0xf7, 0xbb, 0x98, 0xd4, 0x6f, 0xee, 0x6c, 0x23, 0x8f, 0x59, 0xfb, + 0x40, 0x81, 0x25, 0x69, 0x91, 0x27, 0x50, 0x02, 0x76, 0xe5, 0x12, 0xf0, 0x85, 0x0c, 0x5b, 0x96, + 0x92, 0xfb, 0x3f, 0xcb, 0xc3, 0x9a, 0x44, 0x17, 0x39, 0x37, 0x3c, 0xf9, 0xb0, 0x7e, 0x0f, 0xe6, + 0x83, 0x8b, 0x84, 0x6b, 0xae, 0xd3, 0x11, 0xf1, 0xfd, 0xe5, 0x0c, 0xeb, 0x8a, 0x9c, 0x7c, 0xfc, + 0xe0, 0xe2, 0xd8, 0xf3, 0x7a, 0x54, 0x30, 0x92, 0xf5, 0x64, 0x3e, 0xc4, 0xab, 0x6d, 0x28, 0x99, + 0xd2, 0xf1, 0xaf, 0x5c, 0x18, 0xe7, 0x26, 0x43, 0x3e, 0x32, 0x86, 0x25, 0x46, 0x1e, 0x47, 0x31, + 0xd9, 0xda, 0x3f, 0x14, 0x78, 0x26, 0x65, 0x95, 0x27, 0x10, 0x65, 0xef, 0xc8, 0x51, 0xf6, 0xe2, + 0x44, 0xbb, 0x91, 0x12, 0x6f, 0x3f, 0x57, 0xa0, 0x76, 0xdc, 0xfe, 0x65, 0x2c, 0x0e, 0x35, 0x28, + 0xdc, 0xb1, 0x6c, 0x93, 0xc5, 0x4e, 0x24, 0xdd, 0xbf, 0x6a, 0xd9, 0x26, 0x62, 0x33, 0x41, 0x41, + 0xc8, 0xa7, 0x9e, 0x40, 0x1f, 0x28, 0xf0, 0xec, 0xc8, 0xee, 0x30, 0x06, 0x16, 0xff, 0x12, 0x2c, + 0xf4, 0x6c, 0xd2, 0xb3, 0xa8, 0x17, 0x30, 0xd1, 0x86, 0xb7, 0x3c, 0xe8, 0x57, 0x17, 0x6e, 0xca, + 0x53, 0x28, 0x4e, 0xab, 0xfd, 0x36, 0x17, 0xab, 0x27, 0xac, 0xfd, 0x5e, 0x87, 0xa5, 0x48, 0xfb, + 0x21, 0x24, 0x72, 0xd7, 0x70, 0x56, 0xd8, 0x10, 0xe5, 0xe2, 0x04, 0x68, 0x98, 0xc7, 0x4b, 0xb5, + 0x6e, 0xd4, 0xd5, 0x9f, 0x64, 0xaa, 0x49, 0x13, 0x48, 0xd6, 0xa3, 0xee, 0x42, 0x29, 0xbc, 0x52, + 0xf1, 0xe0, 0xae, 0xd8, 0x86, 0x0d, 0x3f, 0x17, 0xae, 0x48, 0xb3, 0x1f, 0x0f, 0x8d, 0xa0, 0x18, + 0xbf, 0xf6, 0xdf, 0x1c, 0x2c, 0x27, 0xb4, 0xa3, 0x89, 0x2e, 0x64, 0xbe, 0x05, 0x10, 0x4a, 0x17, + 0x3e, 0xa9, 0x67, 0xbb, 0x56, 0xd2, 0x4b, 0xec, 0xd4, 0x14, 0x8e, 0x46, 0x24, 0xaa, 0x04, 0x66, + 0x5d, 0x4c, 0xb0, 0x7b, 0x84, 0xcd, 0x6b, 0x8e, 0x2b, 0xae, 0x5f, 0x5e, 0xc9, 0xe0, 0xf4, 0xa1, + 0xd6, 0xa9, 0x2f, 0x8b, 0x25, 0xcd, 0xa2, 0x50, 0x30, 0x8a, 0x6a, 0x51, 0x9b, 0xb0, 0x6a, 0xe2, + 0xe8, 0x3d, 0x16, 0x2b, 0x2b, 0xd8, 0x64, 0x1d, 0xb1, 0x18, 0xde, 0x80, 0x6d, 0x27, 0x11, 0xa1, + 0x64, 0x5e, 0xed, 0xef, 0x0a, 0xac, 0x4a, 0x96, 0x7d, 0x0d, 0x77, 0xba, 0x6d, 0x83, 0xe2, 0x13, + 0xe8, 0x13, 0xb7, 0x24, 0xf8, 0xf3, 0x52, 0x06, 0xf7, 0xf9, 0x46, 0xa6, 0xc1, 0x20, 0xed, 0x6f, + 0x0a, 0x9c, 0x4d, 0xe4, 0x38, 0x81, 0x42, 0xfb, 0xb6, 0x5c, 0x68, 0x2f, 0x4e, 0xb0, 0xae, 0x94, + 0x32, 0xfb, 0x28, 0x6d, 0x55, 0x4d, 0x7e, 0x4c, 0xfa, 0xf4, 0xe1, 0x55, 0xed, 0xc3, 0xbc, 0x04, + 0xbb, 0xc9, 0x49, 0xe0, 0x13, 0xb9, 0xa2, 0xe4, 0xc6, 0xaa, 0x28, 0x43, 0x85, 0x36, 0x9f, 0xb1, + 0xd0, 0x12, 0x32, 0x59, 0xa1, 0xbd, 0x05, 0xf3, 0x72, 0xf7, 0x29, 0x8c, 0xf9, 0xf2, 0xc1, 0x44, + 0x37, 0xa5, 0xee, 0x24, 0x4b, 0x52, 0x5f, 0x83, 0x15, 0x42, 0xdd, 0x5e, 0x8b, 0xf6, 0x5c, 0x6c, + 0x46, 0xae, 0xae, 0x4f, 0xb1, 0x7a, 0x52, 0x1e, 0xf4, 0xab, 0x2b, 0xcd, 0x84, 0x79, 0x94, 0xc8, + 0x15, 0x47, 0xce, 0x84, 0x3c, 0xcd, 0xc8, 0x99, 0xa4, 0x21, 0x99, 0x0f, 0x64, 0xe4, 0x1c, 0xdd, + 0xb5, 0x4f, 0x03, 0x72, 0x1e, 0x11, 0x65, 0x23, 0x91, 0x33, 0x4d, 0x78, 0xc1, 0xe0, 0x5d, 0xed, + 0x98, 0xb6, 0x19, 0x7f, 0xa8, 0xc8, 0xf4, 0x84, 0xf1, 0x16, 0x4c, 0xdf, 0x66, 0x97, 0xab, 0x63, + 0xe2, 0x6e, 0x7f, 0xa1, 0xfc, 0x46, 0x56, 0x5f, 0x10, 0xaa, 0xa6, 0xf9, 0x37, 0x41, 0xbe, 0xb4, + 0x38, 0xd2, 0x8e, 0x7a, 0xe5, 0x69, 0x46, 0xda, 0x51, 0x3b, 0x53, 0xe2, 0xf3, 0x4f, 0x32, 0xd2, + 0x4e, 0xdc, 0xef, 0x93, 0x47, 0xda, 0xde, 0xc9, 0xcb, 0xfb, 0x4b, 0xba, 0x46, 0xcb, 0x3f, 0xa1, + 0x07, 0x27, 0xaf, 0x1b, 0xfe, 0x04, 0x0a, 0x69, 0xb4, 0x0f, 0x15, 0x28, 0xc9, 0xdb, 0x39, 0x11, + 0xd0, 0x7b, 0xa0, 0xc0, 0xb2, 0x2b, 0x89, 0x89, 0xbe, 0x24, 0x5e, 0xc8, 0x12, 0x4e, 0xfc, 0x1d, + 0xf1, 0x19, 0xa1, 0x70, 0x39, 0x61, 0x12, 0x25, 0xa9, 0xd2, 0x7e, 0xa0, 0x40, 0x12, 0xb1, 0x6a, + 0xa7, 0xdc, 0xfe, 0x6e, 0x65, 0xb9, 0xfd, 0x15, 0x91, 0x3e, 0xce, 0xd5, 0xef, 0x3f, 0x23, 0x1e, + 0xe5, 0x2f, 0xe7, 0x13, 0x79, 0xb4, 0x06, 0x05, 0x96, 0x16, 0xb1, 0x68, 0xd8, 0x36, 0xa8, 0x81, + 0xd8, 0x8c, 0xea, 0x42, 0x29, 0x6c, 0x00, 0xde, 0x38, 0x6b, 0x18, 0xc7, 0x5e, 0xf9, 0x86, 0xad, + 0x24, 0xf6, 0x43, 0x00, 0xb6, 0xb8, 0xa6, 0x24, 0x11, 0xc5, 0x34, 0x68, 0x3f, 0xc9, 0xc1, 0x42, + 0xec, 0xfd, 0x32, 0xf1, 0xd5, 0x55, 0x79, 0xd2, 0xaf, 0xae, 0xdf, 0x57, 0x60, 0xc5, 0x95, 0x0d, + 0x89, 0x46, 0xdc, 0x56, 0xa6, 0x27, 0x58, 0x1e, 0x72, 0xeb, 0x42, 0xfd, 0x4a, 0xd2, 0x2c, 0x4a, + 0xd4, 0xa6, 0xfd, 0x48, 0x81, 0x44, 0x72, 0xd5, 0x49, 0x89, 0xba, 0x8b, 0xd9, 0xde, 0x1c, 0xf8, + 0x0b, 0xf1, 0x38, 0x61, 0xf7, 0x97, 0xc8, 0xbd, 0x29, 0x7f, 0x33, 0x79, 0xf2, 0x6d, 0x72, 0x13, + 0x8a, 0xb6, 0x63, 0xe2, 0x08, 0x7c, 0x0b, 0xea, 0xdb, 0x0d, 0x31, 0x8e, 0x02, 0x8a, 0x58, 0x16, + 0xe4, 0xc7, 0xca, 0x82, 0x7b, 0xb0, 0x64, 0xc7, 0xdf, 0x73, 0x04, 0xf2, 0x3a, 0x06, 0xf6, 0x0e, + 0x3d, 0x03, 0x85, 0x27, 0xfa, 0xa1, 0x29, 0x34, 0xac, 0x44, 0x82, 0x51, 0xcc, 0x9f, 0x4f, 0x2d, + 0x8c, 0xe2, 0xaf, 0xaf, 0xc9, 0x6d, 0xea, 0x0f, 0x79, 0x28, 0xa7, 0x25, 0xbc, 0xfa, 0x3d, 0x05, + 0x56, 0x79, 0x62, 0xc5, 0x3a, 0xd8, 0x64, 0xe9, 0x1b, 0x1c, 0x7c, 0xf7, 0x92, 0x64, 0xa2, 0x64, + 0x55, 0xb2, 0x11, 0xd1, 0x5b, 0x90, 0xc9, 0x7e, 0xb9, 0x31, 0x6c, 0x84, 0x74, 0xb3, 0x92, 0xac, + 0x4a, 0x0a, 0xe4, 0xc2, 0xb1, 0x81, 0xfc, 0x6d, 0x98, 0x76, 0xd9, 0xdd, 0x84, 0x07, 0xd1, 0xc7, + 0x78, 0x0e, 0x4d, 0xfe, 0x29, 0x50, 0x08, 0x9b, 0xf8, 0x37, 0x41, 0xbe, 0x54, 0xed, 0x77, 0x0a, + 0x0c, 0xd5, 0xc0, 0x89, 0x9a, 0x88, 0x01, 0xd0, 0xfd, 0x3f, 0x1d, 0x1a, 0xa8, 0x88, 0x78, 0x31, + 0x22, 0x54, 0xd7, 0x1f, 0x3e, 0xae, 0x4c, 0x3d, 0x7a, 0x5c, 0x99, 0xfa, 0xe8, 0x71, 0x65, 0xea, + 0xc1, 0xa0, 0xa2, 0x3c, 0x1c, 0x54, 0x94, 0x47, 0x83, 0x8a, 0xf2, 0xd1, 0xa0, 0xa2, 0xfc, 0x6b, + 0x50, 0x51, 0xde, 0xff, 0x77, 0x65, 0xea, 0x9d, 0xf5, 0x51, 0x3f, 0x1a, 0xfc, 0x5f, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x2a, 0x22, 0x93, 0x1b, 0x53, 0x28, 0x00, 0x00, } func (m *AllocationResult) Marshal() (dAtA []byte, err error) { @@ -2049,106 +2048,6 @@ func (m *NodeResourceModel) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *NodeResourceSlice) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *NodeResourceSlice) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *NodeResourceSlice) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.NodeResourceModel.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - i -= len(m.DriverName) - copy(dAtA[i:], m.DriverName) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.DriverName))) - i-- - dAtA[i] = 0x1a - i -= len(m.NodeName) - copy(dAtA[i:], m.NodeName) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.NodeName))) - i-- - dAtA[i] = 0x12 - { - size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *NodeResourceSliceList) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *NodeResourceSliceList) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *NodeResourceSliceList) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Items) > 0 { - for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - { - size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - func (m *PodSchedulingContext) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -3373,6 +3272,106 @@ func (m *ResourceRequestModel) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ResourceSlice) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceSlice) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceSlice) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.NodeResourceModel.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + i -= len(m.DriverName) + copy(dAtA[i:], m.DriverName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.DriverName))) + i-- + dAtA[i] = 0x1a + i -= len(m.NodeName) + copy(dAtA[i:], m.NodeName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.NodeName))) + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourceSliceList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceSliceList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceSliceList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *StructuredResourceHandle) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -3704,40 +3703,6 @@ func (m *NodeResourceModel) Size() (n int) { return n } -func (m *NodeResourceSlice) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.ObjectMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.NodeName) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.DriverName) - n += 1 + l + sovGenerated(uint64(l)) - l = m.NodeResourceModel.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *NodeResourceSliceList) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.ListMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Items) > 0 { - for _, e := range m.Items { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - func (m *PodSchedulingContext) Size() (n int) { if m == nil { return 0 @@ -4175,6 +4140,40 @@ func (m *ResourceRequestModel) Size() (n int) { return n } +func (m *ResourceSlice) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.NodeName) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.DriverName) + n += 1 + l + sovGenerated(uint64(l)) + l = m.NodeResourceModel.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ResourceSliceList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + func (m *StructuredResourceHandle) Size() (n int) { if m == nil { return 0 @@ -4388,35 +4387,6 @@ func (this *NodeResourceModel) String() string { }, "") return s } -func (this *NodeResourceSlice) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&NodeResourceSlice{`, - `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v11.ObjectMeta", 1), `&`, ``, 1) + `,`, - `NodeName:` + fmt.Sprintf("%v", this.NodeName) + `,`, - `DriverName:` + fmt.Sprintf("%v", this.DriverName) + `,`, - `NodeResourceModel:` + strings.Replace(strings.Replace(this.NodeResourceModel.String(), "NodeResourceModel", "NodeResourceModel", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *NodeResourceSliceList) String() string { - if this == nil { - return "nil" - } - repeatedStringForItems := "[]NodeResourceSlice{" - for _, f := range this.Items { - repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "NodeResourceSlice", "NodeResourceSlice", 1), `&`, ``, 1) + "," - } - repeatedStringForItems += "}" - s := strings.Join([]string{`&NodeResourceSliceList{`, - `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v11.ListMeta", 1), `&`, ``, 1) + `,`, - `Items:` + repeatedStringForItems + `,`, - `}`, - }, "") - return s -} func (this *PodSchedulingContext) String() string { if this == nil { return "nil" @@ -4773,6 +4743,35 @@ func (this *ResourceRequestModel) String() string { }, "") return s } +func (this *ResourceSlice) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ResourceSlice{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v11.ObjectMeta", 1), `&`, ``, 1) + `,`, + `NodeName:` + fmt.Sprintf("%v", this.NodeName) + `,`, + `DriverName:` + fmt.Sprintf("%v", this.DriverName) + `,`, + `NodeResourceModel:` + strings.Replace(strings.Replace(this.NodeResourceModel.String(), "NodeResourceModel", "NodeResourceModel", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *ResourceSliceList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]ResourceSlice{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ResourceSlice", "ResourceSlice", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&ResourceSliceList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v11.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} func (this *StructuredResourceHandle) String() string { if this == nil { return "nil" @@ -6421,303 +6420,6 @@ func (m *NodeResourceModel) Unmarshal(dAtA []byte) error { } return nil } -func (m *NodeResourceSlice) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: NodeResourceSlice: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: NodeResourceSlice: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NodeName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.NodeName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DriverName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.DriverName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NodeResourceModel", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.NodeResourceModel.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *NodeResourceSliceList) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: NodeResourceSliceList: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: NodeResourceSliceList: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Items = append(m.Items, NodeResourceSlice{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *PodSchedulingContext) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -10207,6 +9909,303 @@ func (m *ResourceRequestModel) Unmarshal(dAtA []byte) error { } return nil } +func (m *ResourceSlice) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceSlice: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceSlice: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NodeName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DriverName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DriverName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeResourceModel", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.NodeResourceModel.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceSliceList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceSliceList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceSliceList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, ResourceSlice{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *StructuredResourceHandle) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/staging/src/k8s.io/api/resource/v1alpha2/generated.proto b/staging/src/k8s.io/api/resource/v1alpha2/generated.proto index 210bce01bc0..690181bdf26 100644 --- a/staging/src/k8s.io/api/resource/v1alpha2/generated.proto +++ b/staging/src/k8s.io/api/resource/v1alpha2/generated.proto @@ -216,36 +216,6 @@ message NodeResourceModel { optional NamedResourcesResources namedResources = 1; } -// NodeResourceSlice provides information about available -// resources on individual nodes. -message NodeResourceSlice { - // Standard object metadata - // +optional - optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - - // NodeName identifies the node where the capacity is available. - // A field selector can be used to list only NodeResourceSlice - // objects with a certain node name. - optional string nodeName = 2; - - // DriverName identifies the DRA driver providing the capacity information. - // A field selector can be used to list only NodeResourceSlice - // objects with a certain driver name. - optional string driverName = 3; - - optional NodeResourceModel nodeResourceModel = 4; -} - -// NodeResourceSliceList is a collection of NodeResourceSlices. -message NodeResourceSliceList { - // Standard list metadata - // +optional - optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - - // Items is the list of node resource capacity objects. - repeated NodeResourceSlice items = 2; -} - // PodSchedulingContext objects hold information that is needed to schedule // a Pod with ResourceClaims that use "WaitForFirstConsumer" allocation // mode. @@ -704,6 +674,40 @@ message ResourceRequestModel { optional NamedResourcesRequest namedResources = 1; } +// ResourceSlice provides information about available +// resources on individual nodes. +message ResourceSlice { + // Standard object metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // NodeName identifies the node which provides the resources + // if they are local to a node. + // + // A field selector can be used to list only ResourceSlice + // objects with a certain node name. + // + // +optional + optional string nodeName = 2; + + // DriverName identifies the DRA driver providing the capacity information. + // A field selector can be used to list only ResourceSlice + // objects with a certain driver name. + optional string driverName = 3; + + optional NodeResourceModel nodeResourceModel = 4; +} + +// ResourceSliceList is a collection of ResourceSlices. +message ResourceSliceList { + // Standard list metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // Items is the list of node resource capacity objects. + repeated ResourceSlice items = 2; +} + // StructuredResourceHandle is the in-tree representation of the allocation result. message StructuredResourceHandle { // VendorClassParameters are the per-claim configuration parameters @@ -719,7 +723,10 @@ message StructuredResourceHandle { // +optional optional k8s.io.apimachinery.pkg.runtime.RawExtension vendorClaimParameters = 2; - // NodeName is the name of the node providing the necessary resources. + // NodeName is the name of the node providing the necessary resources + // if the resources are local to a node. + // + // +optional optional string nodeName = 4; // Results lists all allocated driver resources. diff --git a/staging/src/k8s.io/api/resource/v1alpha2/register.go b/staging/src/k8s.io/api/resource/v1alpha2/register.go index 0d948096bc5..893fb4c1e52 100644 --- a/staging/src/k8s.io/api/resource/v1alpha2/register.go +++ b/staging/src/k8s.io/api/resource/v1alpha2/register.go @@ -52,8 +52,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { &ResourceClaimTemplateList{}, &PodSchedulingContext{}, &PodSchedulingContextList{}, - &NodeResourceSlice{}, - &NodeResourceSliceList{}, + &ResourceSlice{}, + &ResourceSliceList{}, &ResourceClaimParameters{}, &ResourceClaimParametersList{}, &ResourceClassParameters{}, diff --git a/staging/src/k8s.io/api/resource/v1alpha2/types.go b/staging/src/k8s.io/api/resource/v1alpha2/types.go index 01ffb0b4831..dc2639f0925 100644 --- a/staging/src/k8s.io/api/resource/v1alpha2/types.go +++ b/staging/src/k8s.io/api/resource/v1alpha2/types.go @@ -224,8 +224,11 @@ type StructuredResourceHandle struct { // +optional VendorClaimParameters runtime.RawExtension `json:"vendorClaimParameters,omitempty" protobuf:"bytes,2,opt,name=vendorClaimParameters"` - // NodeName is the name of the node providing the necessary resources. - NodeName string `json:"nodeName" protobuf:"bytes,4,name=nodeName"` + // NodeName is the name of the node providing the necessary resources + // if the resources are local to a node. + // + // +optional + NodeName string `json:"nodeName,omitempty" protobuf:"bytes,4,name=nodeName"` // Results lists all allocated driver resources. // @@ -529,21 +532,25 @@ type ResourceClaimTemplateList struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.30 -// NodeResourceSlice provides information about available +// ResourceSlice provides information about available // resources on individual nodes. -type NodeResourceSlice struct { +type ResourceSlice struct { metav1.TypeMeta `json:",inline"` // Standard object metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // NodeName identifies the node where the capacity is available. - // A field selector can be used to list only NodeResourceSlice + // NodeName identifies the node which provides the resources + // if they are local to a node. + // + // A field selector can be used to list only ResourceSlice // objects with a certain node name. - NodeName string `json:"nodeName" protobuf:"bytes,2,name=nodeName"` + // + // +optional + NodeName string `json:"nodeName,omitempty" protobuf:"bytes,2,opt,name=nodeName"` // DriverName identifies the DRA driver providing the capacity information. - // A field selector can be used to list only NodeResourceSlice + // A field selector can be used to list only ResourceSlice // objects with a certain driver name. DriverName string `json:"driverName" protobuf:"bytes,3,name=driverName"` @@ -561,15 +568,15 @@ type NodeResourceModel struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.30 -// NodeResourceSliceList is a collection of NodeResourceSlices. -type NodeResourceSliceList struct { +// ResourceSliceList is a collection of ResourceSlices. +type ResourceSliceList struct { metav1.TypeMeta `json:",inline"` // Standard list metadata // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` // Items is the list of node resource capacity objects. - Items []NodeResourceSlice `json:"items" protobuf:"bytes,2,rep,name=items"` + Items []ResourceSlice `json:"items" protobuf:"bytes,2,rep,name=items"` } // +genclient diff --git a/staging/src/k8s.io/api/resource/v1alpha2/types_swagger_doc_generated.go b/staging/src/k8s.io/api/resource/v1alpha2/types_swagger_doc_generated.go index 3bfb1ee1541..99f4e3bd03c 100644 --- a/staging/src/k8s.io/api/resource/v1alpha2/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/resource/v1alpha2/types_swagger_doc_generated.go @@ -76,27 +76,6 @@ func (NodeResourceModel) SwaggerDoc() map[string]string { return map_NodeResourceModel } -var map_NodeResourceSlice = map[string]string{ - "": "NodeResourceSlice provides information about available resources on individual nodes.", - "metadata": "Standard object metadata", - "nodeName": "NodeName identifies the node where the capacity is available. A field selector can be used to list only NodeResourceSlice objects with a certain node name.", - "driverName": "DriverName identifies the DRA driver providing the capacity information. A field selector can be used to list only NodeResourceSlice objects with a certain driver name.", -} - -func (NodeResourceSlice) SwaggerDoc() map[string]string { - return map_NodeResourceSlice -} - -var map_NodeResourceSliceList = map[string]string{ - "": "NodeResourceSliceList is a collection of NodeResourceSlices.", - "metadata": "Standard list metadata", - "items": "Items is the list of node resource capacity objects.", -} - -func (NodeResourceSliceList) SwaggerDoc() map[string]string { - return map_NodeResourceSliceList -} - var map_PodSchedulingContext = map[string]string{ "": "PodSchedulingContext objects hold information that is needed to schedule a Pod with ResourceClaims that use \"WaitForFirstConsumer\" allocation mode.\n\nThis is an alpha type and requires enabling the DynamicResourceAllocation feature gate.", "metadata": "Standard object metadata", @@ -370,11 +349,32 @@ func (ResourceRequestModel) SwaggerDoc() map[string]string { return map_ResourceRequestModel } +var map_ResourceSlice = map[string]string{ + "": "ResourceSlice provides information about available resources on individual nodes.", + "metadata": "Standard object metadata", + "nodeName": "NodeName identifies the node which provides the resources if they are local to a node.\n\nA field selector can be used to list only ResourceSlice objects with a certain node name.", + "driverName": "DriverName identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.", +} + +func (ResourceSlice) SwaggerDoc() map[string]string { + return map_ResourceSlice +} + +var map_ResourceSliceList = map[string]string{ + "": "ResourceSliceList is a collection of ResourceSlices.", + "metadata": "Standard list metadata", + "items": "Items is the list of node resource capacity objects.", +} + +func (ResourceSliceList) SwaggerDoc() map[string]string { + return map_ResourceSliceList +} + var map_StructuredResourceHandle = map[string]string{ "": "StructuredResourceHandle is the in-tree representation of the allocation result.", "vendorClassParameters": "VendorClassParameters are the per-claim configuration parameters from the resource class at the time that the claim was allocated.", "vendorClaimParameters": "VendorClaimParameters are the per-claim configuration parameters from the resource claim parameters at the time that the claim was allocated.", - "nodeName": "NodeName is the name of the node providing the necessary resources.", + "nodeName": "NodeName is the name of the node providing the necessary resources if the resources are local to a node.", "results": "Results lists all allocated driver resources.", } diff --git a/staging/src/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go b/staging/src/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go index 89539070a2b..848acbbc44b 100644 --- a/staging/src/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go @@ -342,66 +342,6 @@ func (in *NodeResourceModel) DeepCopy() *NodeResourceModel { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NodeResourceSlice) DeepCopyInto(out *NodeResourceSlice) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.NodeResourceModel.DeepCopyInto(&out.NodeResourceModel) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeResourceSlice. -func (in *NodeResourceSlice) DeepCopy() *NodeResourceSlice { - if in == nil { - return nil - } - out := new(NodeResourceSlice) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *NodeResourceSlice) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NodeResourceSliceList) DeepCopyInto(out *NodeResourceSliceList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]NodeResourceSlice, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeResourceSliceList. -func (in *NodeResourceSliceList) DeepCopy() *NodeResourceSliceList { - if in == nil { - return nil - } - out := new(NodeResourceSliceList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *NodeResourceSliceList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PodSchedulingContext) DeepCopyInto(out *PodSchedulingContext) { *out = *in @@ -1083,6 +1023,66 @@ func (in *ResourceRequestModel) DeepCopy() *ResourceRequestModel { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceSlice) DeepCopyInto(out *ResourceSlice) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.NodeResourceModel.DeepCopyInto(&out.NodeResourceModel) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceSlice. +func (in *ResourceSlice) DeepCopy() *ResourceSlice { + if in == nil { + return nil + } + out := new(ResourceSlice) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ResourceSlice) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceSliceList) DeepCopyInto(out *ResourceSliceList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ResourceSlice, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceSliceList. +func (in *ResourceSliceList) DeepCopy() *ResourceSliceList { + if in == nil { + return nil + } + out := new(ResourceSliceList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ResourceSliceList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *StructuredResourceHandle) DeepCopyInto(out *StructuredResourceHandle) { *out = *in diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.json b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceSlice.json similarity index 98% rename from staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.json rename to staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceSlice.json index 218ee89bc47..032eff1cf1e 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.json +++ b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceSlice.json @@ -1,5 +1,5 @@ { - "kind": "NodeResourceSlice", + "kind": "ResourceSlice", "apiVersion": "resource.k8s.io/v1alpha2", "metadata": { "name": "nameValue", diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.pb b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceSlice.pb similarity index 90% rename from staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.pb rename to staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceSlice.pb index ba0323b80fa7b3426f3676f1054aeb4cc7d06e46..1d09471bd3b9b116ac6c7825acff2de343a08eba 100644 GIT binary patch delta 43 xcmbQrGLc0o+oG6(OOs2YD784hv?w`M4=A9QnXg}Fn3z+Lk!U2uyHV{uBLEgF4PpQQ delta 47 zcmbQpGL=Ow+oG6(OP5QcD784hv?w`M4=A9QnXg}Fn3z+Lk!U0&=$D_8x>4ypBLGja B4)6c~ diff --git a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.yaml b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceSlice.yaml similarity index 98% rename from staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.yaml rename to staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceSlice.yaml index a1c13f739c8..5869fbbca22 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.NodeResourceSlice.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/resource.k8s.io.v1alpha2.ResourceSlice.yaml @@ -1,6 +1,6 @@ apiVersion: resource.k8s.io/v1alpha2 driverName: driverNameValue -kind: NodeResourceSlice +kind: ResourceSlice metadata: annotations: annotationsKey: annotationsValue diff --git a/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go b/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go index 396ecf04a0c..825e2a96590 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go @@ -12058,30 +12058,6 @@ var schemaYAML = typed.YAMLObject(`types: elementType: scalar: string elementRelationship: atomic -- name: io.k8s.api.resource.v1alpha2.NodeResourceSlice - map: - fields: - - name: apiVersion - type: - scalar: string - - name: driverName - type: - scalar: string - default: "" - - name: kind - type: - scalar: string - - name: metadata - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta - default: {} - - name: namedResources - type: - namedType: io.k8s.api.resource.v1alpha2.NamedResourcesResources - - name: nodeName - type: - scalar: string - default: "" - name: io.k8s.api.resource.v1alpha2.PodSchedulingContext map: fields: @@ -12378,13 +12354,35 @@ var schemaYAML = typed.YAMLObject(`types: - name: vendorParameters type: namedType: __untyped_atomic_ +- name: io.k8s.api.resource.v1alpha2.ResourceSlice + map: + fields: + - name: apiVersion + type: + scalar: string + - name: driverName + type: + scalar: string + default: "" + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: namedResources + type: + namedType: io.k8s.api.resource.v1alpha2.NamedResourcesResources + - name: nodeName + type: + scalar: string - name: io.k8s.api.resource.v1alpha2.StructuredResourceHandle map: fields: - name: nodeName type: scalar: string - default: "" - name: results type: list: diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/noderesourceslice.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceslice.go similarity index 68% rename from staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/noderesourceslice.go rename to staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceslice.go index b7d7d99182b..91ff2a3e5e9 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/noderesourceslice.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceslice.go @@ -27,9 +27,9 @@ import ( v1 "k8s.io/client-go/applyconfigurations/meta/v1" ) -// NodeResourceSliceApplyConfiguration represents an declarative configuration of the NodeResourceSlice type for use +// ResourceSliceApplyConfiguration represents an declarative configuration of the ResourceSlice type for use // with apply. -type NodeResourceSliceApplyConfiguration struct { +type ResourceSliceApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` NodeName *string `json:"nodeName,omitempty"` @@ -37,47 +37,47 @@ type NodeResourceSliceApplyConfiguration struct { NodeResourceModelApplyConfiguration `json:",inline"` } -// NodeResourceSlice constructs an declarative configuration of the NodeResourceSlice type for use with +// ResourceSlice constructs an declarative configuration of the ResourceSlice type for use with // apply. -func NodeResourceSlice(name string) *NodeResourceSliceApplyConfiguration { - b := &NodeResourceSliceApplyConfiguration{} +func ResourceSlice(name string) *ResourceSliceApplyConfiguration { + b := &ResourceSliceApplyConfiguration{} b.WithName(name) - b.WithKind("NodeResourceSlice") + b.WithKind("ResourceSlice") b.WithAPIVersion("resource.k8s.io/v1alpha2") return b } -// ExtractNodeResourceSlice extracts the applied configuration owned by fieldManager from -// nodeResourceSlice. If no managedFields are found in nodeResourceSlice for fieldManager, a -// NodeResourceSliceApplyConfiguration is returned with only the Name, Namespace (if applicable), +// ExtractResourceSlice extracts the applied configuration owned by fieldManager from +// resourceSlice. If no managedFields are found in resourceSlice for fieldManager, a +// ResourceSliceApplyConfiguration is returned with only the Name, Namespace (if applicable), // APIVersion and Kind populated. It is possible that no managed fields were found for because other // field managers have taken ownership of all the fields previously owned by fieldManager, or because // the fieldManager never owned fields any fields. -// nodeResourceSlice must be a unmodified NodeResourceSlice API object that was retrieved from the Kubernetes API. -// ExtractNodeResourceSlice provides a way to perform a extract/modify-in-place/apply workflow. +// resourceSlice must be a unmodified ResourceSlice API object that was retrieved from the Kubernetes API. +// ExtractResourceSlice provides a way to perform a extract/modify-in-place/apply workflow. // Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously // applied if another fieldManager has updated or force applied any of the previously applied fields. // Experimental! -func ExtractNodeResourceSlice(nodeResourceSlice *resourcev1alpha2.NodeResourceSlice, fieldManager string) (*NodeResourceSliceApplyConfiguration, error) { - return extractNodeResourceSlice(nodeResourceSlice, fieldManager, "") +func ExtractResourceSlice(resourceSlice *resourcev1alpha2.ResourceSlice, fieldManager string) (*ResourceSliceApplyConfiguration, error) { + return extractResourceSlice(resourceSlice, fieldManager, "") } -// ExtractNodeResourceSliceStatus is the same as ExtractNodeResourceSlice except +// ExtractResourceSliceStatus is the same as ExtractResourceSlice except // that it extracts the status subresource applied configuration. // Experimental! -func ExtractNodeResourceSliceStatus(nodeResourceSlice *resourcev1alpha2.NodeResourceSlice, fieldManager string) (*NodeResourceSliceApplyConfiguration, error) { - return extractNodeResourceSlice(nodeResourceSlice, fieldManager, "status") +func ExtractResourceSliceStatus(resourceSlice *resourcev1alpha2.ResourceSlice, fieldManager string) (*ResourceSliceApplyConfiguration, error) { + return extractResourceSlice(resourceSlice, fieldManager, "status") } -func extractNodeResourceSlice(nodeResourceSlice *resourcev1alpha2.NodeResourceSlice, fieldManager string, subresource string) (*NodeResourceSliceApplyConfiguration, error) { - b := &NodeResourceSliceApplyConfiguration{} - err := managedfields.ExtractInto(nodeResourceSlice, internal.Parser().Type("io.k8s.api.resource.v1alpha2.NodeResourceSlice"), fieldManager, b, subresource) +func extractResourceSlice(resourceSlice *resourcev1alpha2.ResourceSlice, fieldManager string, subresource string) (*ResourceSliceApplyConfiguration, error) { + b := &ResourceSliceApplyConfiguration{} + err := managedfields.ExtractInto(resourceSlice, internal.Parser().Type("io.k8s.api.resource.v1alpha2.ResourceSlice"), fieldManager, b, subresource) if err != nil { return nil, err } - b.WithName(nodeResourceSlice.Name) + b.WithName(resourceSlice.Name) - b.WithKind("NodeResourceSlice") + b.WithKind("ResourceSlice") b.WithAPIVersion("resource.k8s.io/v1alpha2") return b, nil } @@ -85,7 +85,7 @@ func extractNodeResourceSlice(nodeResourceSlice *resourcev1alpha2.NodeResourceSl // WithKind sets the Kind field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Kind field is set to the value of the last call. -func (b *NodeResourceSliceApplyConfiguration) WithKind(value string) *NodeResourceSliceApplyConfiguration { +func (b *ResourceSliceApplyConfiguration) WithKind(value string) *ResourceSliceApplyConfiguration { b.Kind = &value return b } @@ -93,7 +93,7 @@ func (b *NodeResourceSliceApplyConfiguration) WithKind(value string) *NodeResour // WithAPIVersion sets the APIVersion field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the APIVersion field is set to the value of the last call. -func (b *NodeResourceSliceApplyConfiguration) WithAPIVersion(value string) *NodeResourceSliceApplyConfiguration { +func (b *ResourceSliceApplyConfiguration) WithAPIVersion(value string) *ResourceSliceApplyConfiguration { b.APIVersion = &value return b } @@ -101,7 +101,7 @@ func (b *NodeResourceSliceApplyConfiguration) WithAPIVersion(value string) *Node // WithName sets the Name field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Name field is set to the value of the last call. -func (b *NodeResourceSliceApplyConfiguration) WithName(value string) *NodeResourceSliceApplyConfiguration { +func (b *ResourceSliceApplyConfiguration) WithName(value string) *ResourceSliceApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.Name = &value return b @@ -110,7 +110,7 @@ func (b *NodeResourceSliceApplyConfiguration) WithName(value string) *NodeResour // WithGenerateName sets the GenerateName field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the GenerateName field is set to the value of the last call. -func (b *NodeResourceSliceApplyConfiguration) WithGenerateName(value string) *NodeResourceSliceApplyConfiguration { +func (b *ResourceSliceApplyConfiguration) WithGenerateName(value string) *ResourceSliceApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.GenerateName = &value return b @@ -119,7 +119,7 @@ func (b *NodeResourceSliceApplyConfiguration) WithGenerateName(value string) *No // WithNamespace sets the Namespace field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Namespace field is set to the value of the last call. -func (b *NodeResourceSliceApplyConfiguration) WithNamespace(value string) *NodeResourceSliceApplyConfiguration { +func (b *ResourceSliceApplyConfiguration) WithNamespace(value string) *ResourceSliceApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.Namespace = &value return b @@ -128,7 +128,7 @@ func (b *NodeResourceSliceApplyConfiguration) WithNamespace(value string) *NodeR // WithUID sets the UID field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the UID field is set to the value of the last call. -func (b *NodeResourceSliceApplyConfiguration) WithUID(value types.UID) *NodeResourceSliceApplyConfiguration { +func (b *ResourceSliceApplyConfiguration) WithUID(value types.UID) *ResourceSliceApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.UID = &value return b @@ -137,7 +137,7 @@ func (b *NodeResourceSliceApplyConfiguration) WithUID(value types.UID) *NodeReso // WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the ResourceVersion field is set to the value of the last call. -func (b *NodeResourceSliceApplyConfiguration) WithResourceVersion(value string) *NodeResourceSliceApplyConfiguration { +func (b *ResourceSliceApplyConfiguration) WithResourceVersion(value string) *ResourceSliceApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ResourceVersion = &value return b @@ -146,7 +146,7 @@ func (b *NodeResourceSliceApplyConfiguration) WithResourceVersion(value string) // WithGeneration sets the Generation field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Generation field is set to the value of the last call. -func (b *NodeResourceSliceApplyConfiguration) WithGeneration(value int64) *NodeResourceSliceApplyConfiguration { +func (b *ResourceSliceApplyConfiguration) WithGeneration(value int64) *ResourceSliceApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.Generation = &value return b @@ -155,7 +155,7 @@ func (b *NodeResourceSliceApplyConfiguration) WithGeneration(value int64) *NodeR // WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the CreationTimestamp field is set to the value of the last call. -func (b *NodeResourceSliceApplyConfiguration) WithCreationTimestamp(value metav1.Time) *NodeResourceSliceApplyConfiguration { +func (b *ResourceSliceApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ResourceSliceApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.CreationTimestamp = &value return b @@ -164,7 +164,7 @@ func (b *NodeResourceSliceApplyConfiguration) WithCreationTimestamp(value metav1 // WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the DeletionTimestamp field is set to the value of the last call. -func (b *NodeResourceSliceApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *NodeResourceSliceApplyConfiguration { +func (b *ResourceSliceApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ResourceSliceApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.DeletionTimestamp = &value return b @@ -173,7 +173,7 @@ func (b *NodeResourceSliceApplyConfiguration) WithDeletionTimestamp(value metav1 // WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. -func (b *NodeResourceSliceApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *NodeResourceSliceApplyConfiguration { +func (b *ResourceSliceApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ResourceSliceApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.DeletionGracePeriodSeconds = &value return b @@ -183,7 +183,7 @@ func (b *NodeResourceSliceApplyConfiguration) WithDeletionGracePeriodSeconds(val // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, the entries provided by each call will be put on the Labels field, // overwriting an existing map entries in Labels field with the same key. -func (b *NodeResourceSliceApplyConfiguration) WithLabels(entries map[string]string) *NodeResourceSliceApplyConfiguration { +func (b *ResourceSliceApplyConfiguration) WithLabels(entries map[string]string) *ResourceSliceApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() if b.Labels == nil && len(entries) > 0 { b.Labels = make(map[string]string, len(entries)) @@ -198,7 +198,7 @@ func (b *NodeResourceSliceApplyConfiguration) WithLabels(entries map[string]stri // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, the entries provided by each call will be put on the Annotations field, // overwriting an existing map entries in Annotations field with the same key. -func (b *NodeResourceSliceApplyConfiguration) WithAnnotations(entries map[string]string) *NodeResourceSliceApplyConfiguration { +func (b *ResourceSliceApplyConfiguration) WithAnnotations(entries map[string]string) *ResourceSliceApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() if b.Annotations == nil && len(entries) > 0 { b.Annotations = make(map[string]string, len(entries)) @@ -212,7 +212,7 @@ func (b *NodeResourceSliceApplyConfiguration) WithAnnotations(entries map[string // WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the OwnerReferences field. -func (b *NodeResourceSliceApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *NodeResourceSliceApplyConfiguration { +func (b *ResourceSliceApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *ResourceSliceApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() for i := range values { if values[i] == nil { @@ -226,7 +226,7 @@ func (b *NodeResourceSliceApplyConfiguration) WithOwnerReferences(values ...*v1. // WithFinalizers adds the given value to the Finalizers field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the Finalizers field. -func (b *NodeResourceSliceApplyConfiguration) WithFinalizers(values ...string) *NodeResourceSliceApplyConfiguration { +func (b *ResourceSliceApplyConfiguration) WithFinalizers(values ...string) *ResourceSliceApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() for i := range values { b.Finalizers = append(b.Finalizers, values[i]) @@ -234,7 +234,7 @@ func (b *NodeResourceSliceApplyConfiguration) WithFinalizers(values ...string) * return b } -func (b *NodeResourceSliceApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { +func (b *ResourceSliceApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { if b.ObjectMetaApplyConfiguration == nil { b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} } @@ -243,7 +243,7 @@ func (b *NodeResourceSliceApplyConfiguration) ensureObjectMetaApplyConfiguration // WithNodeName sets the NodeName field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the NodeName field is set to the value of the last call. -func (b *NodeResourceSliceApplyConfiguration) WithNodeName(value string) *NodeResourceSliceApplyConfiguration { +func (b *ResourceSliceApplyConfiguration) WithNodeName(value string) *ResourceSliceApplyConfiguration { b.NodeName = &value return b } @@ -251,7 +251,7 @@ func (b *NodeResourceSliceApplyConfiguration) WithNodeName(value string) *NodeRe // WithDriverName sets the DriverName field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the DriverName field is set to the value of the last call. -func (b *NodeResourceSliceApplyConfiguration) WithDriverName(value string) *NodeResourceSliceApplyConfiguration { +func (b *ResourceSliceApplyConfiguration) WithDriverName(value string) *ResourceSliceApplyConfiguration { b.DriverName = &value return b } @@ -259,7 +259,7 @@ func (b *NodeResourceSliceApplyConfiguration) WithDriverName(value string) *Node // WithNamedResources sets the NamedResources field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the NamedResources field is set to the value of the last call. -func (b *NodeResourceSliceApplyConfiguration) WithNamedResources(value *NamedResourcesResourcesApplyConfiguration) *NodeResourceSliceApplyConfiguration { +func (b *ResourceSliceApplyConfiguration) WithNamedResources(value *NamedResourcesResourcesApplyConfiguration) *ResourceSliceApplyConfiguration { b.NamedResources = value return b } diff --git a/staging/src/k8s.io/client-go/applyconfigurations/utils.go b/staging/src/k8s.io/client-go/applyconfigurations/utils.go index 388e372182d..516096eda58 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/utils.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/utils.go @@ -1549,8 +1549,6 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &resourcev1alpha2.NamedResourcesStringSliceApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("NodeResourceModel"): return &resourcev1alpha2.NodeResourceModelApplyConfiguration{} - case v1alpha2.SchemeGroupVersion.WithKind("NodeResourceSlice"): - return &resourcev1alpha2.NodeResourceSliceApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("PodSchedulingContext"): return &resourcev1alpha2.PodSchedulingContextApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("PodSchedulingContextSpec"): @@ -1591,6 +1589,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &resourcev1alpha2.ResourceRequestApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("ResourceRequestModel"): return &resourcev1alpha2.ResourceRequestModelApplyConfiguration{} + case v1alpha2.SchemeGroupVersion.WithKind("ResourceSlice"): + return &resourcev1alpha2.ResourceSliceApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("StructuredResourceHandle"): return &resourcev1alpha2.StructuredResourceHandleApplyConfiguration{} case v1alpha2.SchemeGroupVersion.WithKind("VendorParameters"): diff --git a/staging/src/k8s.io/client-go/informers/generic.go b/staging/src/k8s.io/client-go/informers/generic.go index 37e928e8dd3..297633c2340 100644 --- a/staging/src/k8s.io/client-go/informers/generic.go +++ b/staging/src/k8s.io/client-go/informers/generic.go @@ -362,8 +362,6 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource return &genericInformer{resource: resource.GroupResource(), informer: f.Rbac().V1beta1().RoleBindings().Informer()}, nil // Group=resource.k8s.io, Version=v1alpha2 - case v1alpha2.SchemeGroupVersion.WithResource("noderesourceslices"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().NodeResourceSlices().Informer()}, nil case v1alpha2.SchemeGroupVersion.WithResource("podschedulingcontexts"): return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().PodSchedulingContexts().Informer()}, nil case v1alpha2.SchemeGroupVersion.WithResource("resourceclaims"): @@ -376,6 +374,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().ResourceClasses().Informer()}, nil case v1alpha2.SchemeGroupVersion.WithResource("resourceclassparameters"): return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().ResourceClassParameters().Informer()}, nil + case v1alpha2.SchemeGroupVersion.WithResource("resourceslices"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().ResourceSlices().Informer()}, nil // Group=scheduling.k8s.io, Version=v1 case schedulingv1.SchemeGroupVersion.WithResource("priorityclasses"): diff --git a/staging/src/k8s.io/client-go/informers/resource/v1alpha2/interface.go b/staging/src/k8s.io/client-go/informers/resource/v1alpha2/interface.go index 29d4a7c6630..aa4a5ae7dca 100644 --- a/staging/src/k8s.io/client-go/informers/resource/v1alpha2/interface.go +++ b/staging/src/k8s.io/client-go/informers/resource/v1alpha2/interface.go @@ -24,8 +24,6 @@ import ( // Interface provides access to all the informers in this group version. type Interface interface { - // NodeResourceSlices returns a NodeResourceSliceInformer. - NodeResourceSlices() NodeResourceSliceInformer // PodSchedulingContexts returns a PodSchedulingContextInformer. PodSchedulingContexts() PodSchedulingContextInformer // ResourceClaims returns a ResourceClaimInformer. @@ -38,6 +36,8 @@ type Interface interface { ResourceClasses() ResourceClassInformer // ResourceClassParameters returns a ResourceClassParametersInformer. ResourceClassParameters() ResourceClassParametersInformer + // ResourceSlices returns a ResourceSliceInformer. + ResourceSlices() ResourceSliceInformer } type version struct { @@ -51,11 +51,6 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} } -// NodeResourceSlices returns a NodeResourceSliceInformer. -func (v *version) NodeResourceSlices() NodeResourceSliceInformer { - return &nodeResourceSliceInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} -} - // PodSchedulingContexts returns a PodSchedulingContextInformer. func (v *version) PodSchedulingContexts() PodSchedulingContextInformer { return &podSchedulingContextInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} @@ -85,3 +80,8 @@ func (v *version) ResourceClasses() ResourceClassInformer { func (v *version) ResourceClassParameters() ResourceClassParametersInformer { return &resourceClassParametersInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} } + +// ResourceSlices returns a ResourceSliceInformer. +func (v *version) ResourceSlices() ResourceSliceInformer { + return &resourceSliceInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/staging/src/k8s.io/client-go/informers/resource/v1alpha2/noderesourceslice.go b/staging/src/k8s.io/client-go/informers/resource/v1alpha2/resourceslice.go similarity index 54% rename from staging/src/k8s.io/client-go/informers/resource/v1alpha2/noderesourceslice.go rename to staging/src/k8s.io/client-go/informers/resource/v1alpha2/resourceslice.go index e4e6197d182..da9d2a0243c 100644 --- a/staging/src/k8s.io/client-go/informers/resource/v1alpha2/noderesourceslice.go +++ b/staging/src/k8s.io/client-go/informers/resource/v1alpha2/resourceslice.go @@ -32,58 +32,58 @@ import ( cache "k8s.io/client-go/tools/cache" ) -// NodeResourceSliceInformer provides access to a shared informer and lister for -// NodeResourceSlices. -type NodeResourceSliceInformer interface { +// ResourceSliceInformer provides access to a shared informer and lister for +// ResourceSlices. +type ResourceSliceInformer interface { Informer() cache.SharedIndexInformer - Lister() v1alpha2.NodeResourceSliceLister + Lister() v1alpha2.ResourceSliceLister } -type nodeResourceSliceInformer struct { +type resourceSliceInformer struct { factory internalinterfaces.SharedInformerFactory tweakListOptions internalinterfaces.TweakListOptionsFunc } -// NewNodeResourceSliceInformer constructs a new informer for NodeResourceSlice type. +// NewResourceSliceInformer constructs a new informer for ResourceSlice type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. -func NewNodeResourceSliceInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredNodeResourceSliceInformer(client, resyncPeriod, indexers, nil) +func NewResourceSliceInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredResourceSliceInformer(client, resyncPeriod, indexers, nil) } -// NewFilteredNodeResourceSliceInformer constructs a new informer for NodeResourceSlice type. +// NewFilteredResourceSliceInformer constructs a new informer for ResourceSlice type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. -func NewFilteredNodeResourceSliceInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { +func NewFilteredResourceSliceInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { return cache.NewSharedIndexInformer( &cache.ListWatch{ ListFunc: func(options v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.ResourceV1alpha2().NodeResourceSlices().List(context.TODO(), options) + return client.ResourceV1alpha2().ResourceSlices().List(context.TODO(), options) }, WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.ResourceV1alpha2().NodeResourceSlices().Watch(context.TODO(), options) + return client.ResourceV1alpha2().ResourceSlices().Watch(context.TODO(), options) }, }, - &resourcev1alpha2.NodeResourceSlice{}, + &resourcev1alpha2.ResourceSlice{}, resyncPeriod, indexers, ) } -func (f *nodeResourceSliceInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredNodeResourceSliceInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +func (f *resourceSliceInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredResourceSliceInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) } -func (f *nodeResourceSliceInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&resourcev1alpha2.NodeResourceSlice{}, f.defaultInformer) +func (f *resourceSliceInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&resourcev1alpha2.ResourceSlice{}, f.defaultInformer) } -func (f *nodeResourceSliceInformer) Lister() v1alpha2.NodeResourceSliceLister { - return v1alpha2.NewNodeResourceSliceLister(f.Informer().GetIndexer()) +func (f *resourceSliceInformer) Lister() v1alpha2.ResourceSliceLister { + return v1alpha2.NewResourceSliceLister(f.Informer().GetIndexer()) } diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_noderesourceslice.go b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_noderesourceslice.go deleted file mode 100644 index 13ec45b6f4b..00000000000 --- a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_noderesourceslice.go +++ /dev/null @@ -1,145 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package fake - -import ( - "context" - json "encoding/json" - "fmt" - - v1alpha2 "k8s.io/api/resource/v1alpha2" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - labels "k8s.io/apimachinery/pkg/labels" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" - testing "k8s.io/client-go/testing" -) - -// FakeNodeResourceSlices implements NodeResourceSliceInterface -type FakeNodeResourceSlices struct { - Fake *FakeResourceV1alpha2 -} - -var noderesourceslicesResource = v1alpha2.SchemeGroupVersion.WithResource("noderesourceslices") - -var noderesourceslicesKind = v1alpha2.SchemeGroupVersion.WithKind("NodeResourceSlice") - -// Get takes name of the nodeResourceSlice, and returns the corresponding nodeResourceSlice object, and an error if there is any. -func (c *FakeNodeResourceSlices) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.NodeResourceSlice, err error) { - obj, err := c.Fake. - Invokes(testing.NewRootGetAction(noderesourceslicesResource, name), &v1alpha2.NodeResourceSlice{}) - if obj == nil { - return nil, err - } - return obj.(*v1alpha2.NodeResourceSlice), err -} - -// List takes label and field selectors, and returns the list of NodeResourceSlices that match those selectors. -func (c *FakeNodeResourceSlices) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.NodeResourceSliceList, err error) { - obj, err := c.Fake. - Invokes(testing.NewRootListAction(noderesourceslicesResource, noderesourceslicesKind, opts), &v1alpha2.NodeResourceSliceList{}) - if obj == nil { - return nil, err - } - - label, _, _ := testing.ExtractFromListOptions(opts) - if label == nil { - label = labels.Everything() - } - list := &v1alpha2.NodeResourceSliceList{ListMeta: obj.(*v1alpha2.NodeResourceSliceList).ListMeta} - for _, item := range obj.(*v1alpha2.NodeResourceSliceList).Items { - if label.Matches(labels.Set(item.Labels)) { - list.Items = append(list.Items, item) - } - } - return list, err -} - -// Watch returns a watch.Interface that watches the requested nodeResourceSlices. -func (c *FakeNodeResourceSlices) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { - return c.Fake. - InvokesWatch(testing.NewRootWatchAction(noderesourceslicesResource, opts)) -} - -// Create takes the representation of a nodeResourceSlice and creates it. Returns the server's representation of the nodeResourceSlice, and an error, if there is any. -func (c *FakeNodeResourceSlices) Create(ctx context.Context, nodeResourceSlice *v1alpha2.NodeResourceSlice, opts v1.CreateOptions) (result *v1alpha2.NodeResourceSlice, err error) { - obj, err := c.Fake. - Invokes(testing.NewRootCreateAction(noderesourceslicesResource, nodeResourceSlice), &v1alpha2.NodeResourceSlice{}) - if obj == nil { - return nil, err - } - return obj.(*v1alpha2.NodeResourceSlice), err -} - -// Update takes the representation of a nodeResourceSlice and updates it. Returns the server's representation of the nodeResourceSlice, and an error, if there is any. -func (c *FakeNodeResourceSlices) Update(ctx context.Context, nodeResourceSlice *v1alpha2.NodeResourceSlice, opts v1.UpdateOptions) (result *v1alpha2.NodeResourceSlice, err error) { - obj, err := c.Fake. - Invokes(testing.NewRootUpdateAction(noderesourceslicesResource, nodeResourceSlice), &v1alpha2.NodeResourceSlice{}) - if obj == nil { - return nil, err - } - return obj.(*v1alpha2.NodeResourceSlice), err -} - -// Delete takes name of the nodeResourceSlice and deletes it. Returns an error if one occurs. -func (c *FakeNodeResourceSlices) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - _, err := c.Fake. - Invokes(testing.NewRootDeleteActionWithOptions(noderesourceslicesResource, name, opts), &v1alpha2.NodeResourceSlice{}) - return err -} - -// DeleteCollection deletes a collection of objects. -func (c *FakeNodeResourceSlices) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - action := testing.NewRootDeleteCollectionAction(noderesourceslicesResource, listOpts) - - _, err := c.Fake.Invokes(action, &v1alpha2.NodeResourceSliceList{}) - return err -} - -// Patch applies the patch and returns the patched nodeResourceSlice. -func (c *FakeNodeResourceSlices) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.NodeResourceSlice, err error) { - obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(noderesourceslicesResource, name, pt, data, subresources...), &v1alpha2.NodeResourceSlice{}) - if obj == nil { - return nil, err - } - return obj.(*v1alpha2.NodeResourceSlice), err -} - -// Apply takes the given apply declarative configuration, applies it and returns the applied nodeResourceSlice. -func (c *FakeNodeResourceSlices) Apply(ctx context.Context, nodeResourceSlice *resourcev1alpha2.NodeResourceSliceApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.NodeResourceSlice, err error) { - if nodeResourceSlice == nil { - return nil, fmt.Errorf("nodeResourceSlice provided to Apply must not be nil") - } - data, err := json.Marshal(nodeResourceSlice) - if err != nil { - return nil, err - } - name := nodeResourceSlice.Name - if name == nil { - return nil, fmt.Errorf("nodeResourceSlice.Name must be provided to Apply") - } - obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(noderesourceslicesResource, *name, types.ApplyPatchType, data), &v1alpha2.NodeResourceSlice{}) - if obj == nil { - return nil, err - } - return obj.(*v1alpha2.NodeResourceSlice), err -} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resource_client.go b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resource_client.go index c26af9ecd14..6f69d0fa795 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resource_client.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resource_client.go @@ -28,10 +28,6 @@ type FakeResourceV1alpha2 struct { *testing.Fake } -func (c *FakeResourceV1alpha2) NodeResourceSlices() v1alpha2.NodeResourceSliceInterface { - return &FakeNodeResourceSlices{c} -} - func (c *FakeResourceV1alpha2) PodSchedulingContexts(namespace string) v1alpha2.PodSchedulingContextInterface { return &FakePodSchedulingContexts{c, namespace} } @@ -56,6 +52,10 @@ func (c *FakeResourceV1alpha2) ResourceClassParameters(namespace string) v1alpha return &FakeResourceClassParameters{c, namespace} } +func (c *FakeResourceV1alpha2) ResourceSlices() v1alpha2.ResourceSliceInterface { + return &FakeResourceSlices{c} +} + // RESTClient returns a RESTClient that is used to communicate // with API server by this client implementation. func (c *FakeResourceV1alpha2) RESTClient() rest.Interface { diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resourceslice.go b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resourceslice.go new file mode 100644 index 00000000000..325e729e92f --- /dev/null +++ b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resourceslice.go @@ -0,0 +1,145 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + json "encoding/json" + "fmt" + + v1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" + testing "k8s.io/client-go/testing" +) + +// FakeResourceSlices implements ResourceSliceInterface +type FakeResourceSlices struct { + Fake *FakeResourceV1alpha2 +} + +var resourceslicesResource = v1alpha2.SchemeGroupVersion.WithResource("resourceslices") + +var resourceslicesKind = v1alpha2.SchemeGroupVersion.WithKind("ResourceSlice") + +// Get takes name of the resourceSlice, and returns the corresponding resourceSlice object, and an error if there is any. +func (c *FakeResourceSlices) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ResourceSlice, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootGetAction(resourceslicesResource, name), &v1alpha2.ResourceSlice{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ResourceSlice), err +} + +// List takes label and field selectors, and returns the list of ResourceSlices that match those selectors. +func (c *FakeResourceSlices) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ResourceSliceList, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootListAction(resourceslicesResource, resourceslicesKind, opts), &v1alpha2.ResourceSliceList{}) + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha2.ResourceSliceList{ListMeta: obj.(*v1alpha2.ResourceSliceList).ListMeta} + for _, item := range obj.(*v1alpha2.ResourceSliceList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested resourceSlices. +func (c *FakeResourceSlices) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewRootWatchAction(resourceslicesResource, opts)) +} + +// Create takes the representation of a resourceSlice and creates it. Returns the server's representation of the resourceSlice, and an error, if there is any. +func (c *FakeResourceSlices) Create(ctx context.Context, resourceSlice *v1alpha2.ResourceSlice, opts v1.CreateOptions) (result *v1alpha2.ResourceSlice, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootCreateAction(resourceslicesResource, resourceSlice), &v1alpha2.ResourceSlice{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ResourceSlice), err +} + +// Update takes the representation of a resourceSlice and updates it. Returns the server's representation of the resourceSlice, and an error, if there is any. +func (c *FakeResourceSlices) Update(ctx context.Context, resourceSlice *v1alpha2.ResourceSlice, opts v1.UpdateOptions) (result *v1alpha2.ResourceSlice, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateAction(resourceslicesResource, resourceSlice), &v1alpha2.ResourceSlice{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ResourceSlice), err +} + +// Delete takes name of the resourceSlice and deletes it. Returns an error if one occurs. +func (c *FakeResourceSlices) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewRootDeleteActionWithOptions(resourceslicesResource, name, opts), &v1alpha2.ResourceSlice{}) + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeResourceSlices) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewRootDeleteCollectionAction(resourceslicesResource, listOpts) + + _, err := c.Fake.Invokes(action, &v1alpha2.ResourceSliceList{}) + return err +} + +// Patch applies the patch and returns the patched resourceSlice. +func (c *FakeResourceSlices) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceSlice, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(resourceslicesResource, name, pt, data, subresources...), &v1alpha2.ResourceSlice{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ResourceSlice), err +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied resourceSlice. +func (c *FakeResourceSlices) Apply(ctx context.Context, resourceSlice *resourcev1alpha2.ResourceSliceApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceSlice, err error) { + if resourceSlice == nil { + return nil, fmt.Errorf("resourceSlice provided to Apply must not be nil") + } + data, err := json.Marshal(resourceSlice) + if err != nil { + return nil, err + } + name := resourceSlice.Name + if name == nil { + return nil, fmt.Errorf("resourceSlice.Name must be provided to Apply") + } + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(resourceslicesResource, *name, types.ApplyPatchType, data), &v1alpha2.ResourceSlice{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.ResourceSlice), err +} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/generated_expansion.go b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/generated_expansion.go index abb4d70045c..d11410bb9b9 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/generated_expansion.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/generated_expansion.go @@ -18,8 +18,6 @@ limitations under the License. package v1alpha2 -type NodeResourceSliceExpansion interface{} - type PodSchedulingContextExpansion interface{} type ResourceClaimExpansion interface{} @@ -31,3 +29,5 @@ type ResourceClaimTemplateExpansion interface{} type ResourceClassExpansion interface{} type ResourceClassParametersExpansion interface{} + +type ResourceSliceExpansion interface{} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/noderesourceslice.go b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/noderesourceslice.go deleted file mode 100644 index 491f63e7c48..00000000000 --- a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/noderesourceslice.go +++ /dev/null @@ -1,197 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package v1alpha2 - -import ( - "context" - json "encoding/json" - "fmt" - "time" - - v1alpha2 "k8s.io/api/resource/v1alpha2" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" - scheme "k8s.io/client-go/kubernetes/scheme" - rest "k8s.io/client-go/rest" -) - -// NodeResourceSlicesGetter has a method to return a NodeResourceSliceInterface. -// A group's client should implement this interface. -type NodeResourceSlicesGetter interface { - NodeResourceSlices() NodeResourceSliceInterface -} - -// NodeResourceSliceInterface has methods to work with NodeResourceSlice resources. -type NodeResourceSliceInterface interface { - Create(ctx context.Context, nodeResourceSlice *v1alpha2.NodeResourceSlice, opts v1.CreateOptions) (*v1alpha2.NodeResourceSlice, error) - Update(ctx context.Context, nodeResourceSlice *v1alpha2.NodeResourceSlice, opts v1.UpdateOptions) (*v1alpha2.NodeResourceSlice, error) - Delete(ctx context.Context, name string, opts v1.DeleteOptions) error - DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha2.NodeResourceSlice, error) - List(ctx context.Context, opts v1.ListOptions) (*v1alpha2.NodeResourceSliceList, error) - Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.NodeResourceSlice, err error) - Apply(ctx context.Context, nodeResourceSlice *resourcev1alpha2.NodeResourceSliceApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.NodeResourceSlice, err error) - NodeResourceSliceExpansion -} - -// nodeResourceSlices implements NodeResourceSliceInterface -type nodeResourceSlices struct { - client rest.Interface -} - -// newNodeResourceSlices returns a NodeResourceSlices -func newNodeResourceSlices(c *ResourceV1alpha2Client) *nodeResourceSlices { - return &nodeResourceSlices{ - client: c.RESTClient(), - } -} - -// Get takes name of the nodeResourceSlice, and returns the corresponding nodeResourceSlice object, and an error if there is any. -func (c *nodeResourceSlices) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.NodeResourceSlice, err error) { - result = &v1alpha2.NodeResourceSlice{} - err = c.client.Get(). - Resource("noderesourceslices"). - Name(name). - VersionedParams(&options, scheme.ParameterCodec). - Do(ctx). - Into(result) - return -} - -// List takes label and field selectors, and returns the list of NodeResourceSlices that match those selectors. -func (c *nodeResourceSlices) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.NodeResourceSliceList, err error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - result = &v1alpha2.NodeResourceSliceList{} - err = c.client.Get(). - Resource("noderesourceslices"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Do(ctx). - Into(result) - return -} - -// Watch returns a watch.Interface that watches the requested nodeResourceSlices. -func (c *nodeResourceSlices) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - opts.Watch = true - return c.client.Get(). - Resource("noderesourceslices"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Watch(ctx) -} - -// Create takes the representation of a nodeResourceSlice and creates it. Returns the server's representation of the nodeResourceSlice, and an error, if there is any. -func (c *nodeResourceSlices) Create(ctx context.Context, nodeResourceSlice *v1alpha2.NodeResourceSlice, opts v1.CreateOptions) (result *v1alpha2.NodeResourceSlice, err error) { - result = &v1alpha2.NodeResourceSlice{} - err = c.client.Post(). - Resource("noderesourceslices"). - VersionedParams(&opts, scheme.ParameterCodec). - Body(nodeResourceSlice). - Do(ctx). - Into(result) - return -} - -// Update takes the representation of a nodeResourceSlice and updates it. Returns the server's representation of the nodeResourceSlice, and an error, if there is any. -func (c *nodeResourceSlices) Update(ctx context.Context, nodeResourceSlice *v1alpha2.NodeResourceSlice, opts v1.UpdateOptions) (result *v1alpha2.NodeResourceSlice, err error) { - result = &v1alpha2.NodeResourceSlice{} - err = c.client.Put(). - Resource("noderesourceslices"). - Name(nodeResourceSlice.Name). - VersionedParams(&opts, scheme.ParameterCodec). - Body(nodeResourceSlice). - Do(ctx). - Into(result) - return -} - -// Delete takes name of the nodeResourceSlice and deletes it. Returns an error if one occurs. -func (c *nodeResourceSlices) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - return c.client.Delete(). - Resource("noderesourceslices"). - Name(name). - Body(&opts). - Do(ctx). - Error() -} - -// DeleteCollection deletes a collection of objects. -func (c *nodeResourceSlices) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - var timeout time.Duration - if listOpts.TimeoutSeconds != nil { - timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second - } - return c.client.Delete(). - Resource("noderesourceslices"). - VersionedParams(&listOpts, scheme.ParameterCodec). - Timeout(timeout). - Body(&opts). - Do(ctx). - Error() -} - -// Patch applies the patch and returns the patched nodeResourceSlice. -func (c *nodeResourceSlices) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.NodeResourceSlice, err error) { - result = &v1alpha2.NodeResourceSlice{} - err = c.client.Patch(pt). - Resource("noderesourceslices"). - Name(name). - SubResource(subresources...). - VersionedParams(&opts, scheme.ParameterCodec). - Body(data). - Do(ctx). - Into(result) - return -} - -// Apply takes the given apply declarative configuration, applies it and returns the applied nodeResourceSlice. -func (c *nodeResourceSlices) Apply(ctx context.Context, nodeResourceSlice *resourcev1alpha2.NodeResourceSliceApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.NodeResourceSlice, err error) { - if nodeResourceSlice == nil { - return nil, fmt.Errorf("nodeResourceSlice provided to Apply must not be nil") - } - patchOpts := opts.ToPatchOptions() - data, err := json.Marshal(nodeResourceSlice) - if err != nil { - return nil, err - } - name := nodeResourceSlice.Name - if name == nil { - return nil, fmt.Errorf("nodeResourceSlice.Name must be provided to Apply") - } - result = &v1alpha2.NodeResourceSlice{} - err = c.client.Patch(types.ApplyPatchType). - Resource("noderesourceslices"). - Name(*name). - VersionedParams(&patchOpts, scheme.ParameterCodec). - Body(data). - Do(ctx). - Into(result) - return -} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resource_client.go b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resource_client.go index 2a5c3585554..8e258b3e1ca 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resource_client.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resource_client.go @@ -28,13 +28,13 @@ import ( type ResourceV1alpha2Interface interface { RESTClient() rest.Interface - NodeResourceSlicesGetter PodSchedulingContextsGetter ResourceClaimsGetter ResourceClaimParametersGetter ResourceClaimTemplatesGetter ResourceClassesGetter ResourceClassParametersGetter + ResourceSlicesGetter } // ResourceV1alpha2Client is used to interact with features provided by the resource.k8s.io group. @@ -42,10 +42,6 @@ type ResourceV1alpha2Client struct { restClient rest.Interface } -func (c *ResourceV1alpha2Client) NodeResourceSlices() NodeResourceSliceInterface { - return newNodeResourceSlices(c) -} - func (c *ResourceV1alpha2Client) PodSchedulingContexts(namespace string) PodSchedulingContextInterface { return newPodSchedulingContexts(c, namespace) } @@ -70,6 +66,10 @@ func (c *ResourceV1alpha2Client) ResourceClassParameters(namespace string) Resou return newResourceClassParameters(c, namespace) } +func (c *ResourceV1alpha2Client) ResourceSlices() ResourceSliceInterface { + return newResourceSlices(c) +} + // NewForConfig creates a new ResourceV1alpha2Client for the given config. // NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), // where httpClient was generated with rest.HTTPClientFor(c). diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceslice.go b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceslice.go new file mode 100644 index 00000000000..302f370d525 --- /dev/null +++ b/staging/src/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceslice.go @@ -0,0 +1,197 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// ResourceSlicesGetter has a method to return a ResourceSliceInterface. +// A group's client should implement this interface. +type ResourceSlicesGetter interface { + ResourceSlices() ResourceSliceInterface +} + +// ResourceSliceInterface has methods to work with ResourceSlice resources. +type ResourceSliceInterface interface { + Create(ctx context.Context, resourceSlice *v1alpha2.ResourceSlice, opts v1.CreateOptions) (*v1alpha2.ResourceSlice, error) + Update(ctx context.Context, resourceSlice *v1alpha2.ResourceSlice, opts v1.UpdateOptions) (*v1alpha2.ResourceSlice, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha2.ResourceSlice, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha2.ResourceSliceList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceSlice, err error) + Apply(ctx context.Context, resourceSlice *resourcev1alpha2.ResourceSliceApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceSlice, err error) + ResourceSliceExpansion +} + +// resourceSlices implements ResourceSliceInterface +type resourceSlices struct { + client rest.Interface +} + +// newResourceSlices returns a ResourceSlices +func newResourceSlices(c *ResourceV1alpha2Client) *resourceSlices { + return &resourceSlices{ + client: c.RESTClient(), + } +} + +// Get takes name of the resourceSlice, and returns the corresponding resourceSlice object, and an error if there is any. +func (c *resourceSlices) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ResourceSlice, err error) { + result = &v1alpha2.ResourceSlice{} + err = c.client.Get(). + Resource("resourceslices"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ResourceSlices that match those selectors. +func (c *resourceSlices) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ResourceSliceList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha2.ResourceSliceList{} + err = c.client.Get(). + Resource("resourceslices"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested resourceSlices. +func (c *resourceSlices) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("resourceslices"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a resourceSlice and creates it. Returns the server's representation of the resourceSlice, and an error, if there is any. +func (c *resourceSlices) Create(ctx context.Context, resourceSlice *v1alpha2.ResourceSlice, opts v1.CreateOptions) (result *v1alpha2.ResourceSlice, err error) { + result = &v1alpha2.ResourceSlice{} + err = c.client.Post(). + Resource("resourceslices"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(resourceSlice). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a resourceSlice and updates it. Returns the server's representation of the resourceSlice, and an error, if there is any. +func (c *resourceSlices) Update(ctx context.Context, resourceSlice *v1alpha2.ResourceSlice, opts v1.UpdateOptions) (result *v1alpha2.ResourceSlice, err error) { + result = &v1alpha2.ResourceSlice{} + err = c.client.Put(). + Resource("resourceslices"). + Name(resourceSlice.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(resourceSlice). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the resourceSlice and deletes it. Returns an error if one occurs. +func (c *resourceSlices) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Resource("resourceslices"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *resourceSlices) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("resourceslices"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched resourceSlice. +func (c *resourceSlices) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceSlice, err error) { + result = &v1alpha2.ResourceSlice{} + err = c.client.Patch(pt). + Resource("resourceslices"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied resourceSlice. +func (c *resourceSlices) Apply(ctx context.Context, resourceSlice *resourcev1alpha2.ResourceSliceApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceSlice, err error) { + if resourceSlice == nil { + return nil, fmt.Errorf("resourceSlice provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(resourceSlice) + if err != nil { + return nil, err + } + name := resourceSlice.Name + if name == nil { + return nil, fmt.Errorf("resourceSlice.Name must be provided to Apply") + } + result = &v1alpha2.ResourceSlice{} + err = c.client.Patch(types.ApplyPatchType). + Resource("resourceslices"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/staging/src/k8s.io/client-go/listers/resource/v1alpha2/expansion_generated.go b/staging/src/k8s.io/client-go/listers/resource/v1alpha2/expansion_generated.go index dd8a21755ff..68861832d9c 100644 --- a/staging/src/k8s.io/client-go/listers/resource/v1alpha2/expansion_generated.go +++ b/staging/src/k8s.io/client-go/listers/resource/v1alpha2/expansion_generated.go @@ -18,10 +18,6 @@ limitations under the License. package v1alpha2 -// NodeResourceSliceListerExpansion allows custom methods to be added to -// NodeResourceSliceLister. -type NodeResourceSliceListerExpansion interface{} - // PodSchedulingContextListerExpansion allows custom methods to be added to // PodSchedulingContextLister. type PodSchedulingContextListerExpansion interface{} @@ -65,3 +61,7 @@ type ResourceClassParametersListerExpansion interface{} // ResourceClassParametersNamespaceListerExpansion allows custom methods to be added to // ResourceClassParametersNamespaceLister. type ResourceClassParametersNamespaceListerExpansion interface{} + +// ResourceSliceListerExpansion allows custom methods to be added to +// ResourceSliceLister. +type ResourceSliceListerExpansion interface{} diff --git a/staging/src/k8s.io/client-go/listers/resource/v1alpha2/noderesourceslice.go b/staging/src/k8s.io/client-go/listers/resource/v1alpha2/noderesourceslice.go deleted file mode 100644 index f5853499a02..00000000000 --- a/staging/src/k8s.io/client-go/listers/resource/v1alpha2/noderesourceslice.go +++ /dev/null @@ -1,68 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package v1alpha2 - -import ( - v1alpha2 "k8s.io/api/resource/v1alpha2" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" -) - -// NodeResourceSliceLister helps list NodeResourceSlices. -// All objects returned here must be treated as read-only. -type NodeResourceSliceLister interface { - // List lists all NodeResourceSlices in the indexer. - // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1alpha2.NodeResourceSlice, err error) - // Get retrieves the NodeResourceSlice from the index for a given name. - // Objects returned here must be treated as read-only. - Get(name string) (*v1alpha2.NodeResourceSlice, error) - NodeResourceSliceListerExpansion -} - -// nodeResourceSliceLister implements the NodeResourceSliceLister interface. -type nodeResourceSliceLister struct { - indexer cache.Indexer -} - -// NewNodeResourceSliceLister returns a new NodeResourceSliceLister. -func NewNodeResourceSliceLister(indexer cache.Indexer) NodeResourceSliceLister { - return &nodeResourceSliceLister{indexer: indexer} -} - -// List lists all NodeResourceSlices in the indexer. -func (s *nodeResourceSliceLister) List(selector labels.Selector) (ret []*v1alpha2.NodeResourceSlice, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha2.NodeResourceSlice)) - }) - return ret, err -} - -// Get retrieves the NodeResourceSlice from the index for a given name. -func (s *nodeResourceSliceLister) Get(name string) (*v1alpha2.NodeResourceSlice, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(v1alpha2.Resource("noderesourceslice"), name) - } - return obj.(*v1alpha2.NodeResourceSlice), nil -} diff --git a/staging/src/k8s.io/client-go/listers/resource/v1alpha2/resourceslice.go b/staging/src/k8s.io/client-go/listers/resource/v1alpha2/resourceslice.go new file mode 100644 index 00000000000..4301cea2e36 --- /dev/null +++ b/staging/src/k8s.io/client-go/listers/resource/v1alpha2/resourceslice.go @@ -0,0 +1,68 @@ +/* +Copyright 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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + v1alpha2 "k8s.io/api/resource/v1alpha2" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ResourceSliceLister helps list ResourceSlices. +// All objects returned here must be treated as read-only. +type ResourceSliceLister interface { + // List lists all ResourceSlices in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha2.ResourceSlice, err error) + // Get retrieves the ResourceSlice from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha2.ResourceSlice, error) + ResourceSliceListerExpansion +} + +// resourceSliceLister implements the ResourceSliceLister interface. +type resourceSliceLister struct { + indexer cache.Indexer +} + +// NewResourceSliceLister returns a new ResourceSliceLister. +func NewResourceSliceLister(indexer cache.Indexer) ResourceSliceLister { + return &resourceSliceLister{indexer: indexer} +} + +// List lists all ResourceSlices in the indexer. +func (s *resourceSliceLister) List(selector labels.Selector) (ret []*v1alpha2.ResourceSlice, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.ResourceSlice)) + }) + return ret, err +} + +// Get retrieves the ResourceSlice from the index for a given name. +func (s *resourceSliceLister) Get(name string) (*v1alpha2.ResourceSlice, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha2.Resource("resourceslice"), name) + } + return obj.(*v1alpha2.ResourceSlice), nil +} diff --git a/test/e2e/dra/deploy.go b/test/e2e/dra/deploy.go index 3864fe0f854..8ad46d83932 100644 --- a/test/e2e/dra/deploy.go +++ b/test/e2e/dra/deploy.go @@ -362,8 +362,8 @@ func (d *Driver) TearDown() { } func (d *Driver) IsGone(ctx context.Context) { - gomega.Eventually(ctx, func(ctx context.Context) ([]resourcev1alpha2.NodeResourceSlice, error) { - slices, err := d.f.ClientSet.ResourceV1alpha2().NodeResourceSlices().List(ctx, metav1.ListOptions{FieldSelector: "driverName=" + d.Name}) + gomega.Eventually(ctx, func(ctx context.Context) ([]resourcev1alpha2.ResourceSlice, error) { + slices, err := d.f.ClientSet.ResourceV1alpha2().ResourceSlices().List(ctx, metav1.ListOptions{FieldSelector: "driverName=" + d.Name}) if err != nil { return nil, err } diff --git a/test/e2e/dra/dra.go b/test/e2e/dra/dra.go index 60bc50857ff..65ed92b221c 100644 --- a/test/e2e/dra/dra.go +++ b/test/e2e/dra/dra.go @@ -203,7 +203,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, driver := NewDriver(f, nodes, perNode(1, nodes)) driver.parameterMode = parameterModeStructured - f.It("must manage NodeResourceSlice", f.WithSlow(), func(ctx context.Context) { + f.It("must manage ResourceSlice", f.WithSlow(), func(ctx context.Context) { nodeName := nodes.NodeNames[0] driverName := driver.Name m := MethodInstance{nodeName, NodeListAndWatchResourcesMethod} @@ -212,8 +212,8 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, return driver.CallCount(m) }).WithTimeout(podStartTimeout).Should(gomega.BeNumerically(">", int64(0)), "NodeListAndWatchResources call count") - ginkgo.By("check if NodeResourceSlice object exists on the API server") - resourceClient := f.ClientSet.ResourceV1alpha2().NodeResourceSlices() + ginkgo.By("check if ResourceSlice object exists on the API server") + resourceClient := f.ClientSet.ResourceV1alpha2().ResourceSlices() matchSlices := gomega.And( gomega.HaveLen(1), gomega.ContainElement(gstruct.MatchAllFields(gstruct.Fields{ @@ -226,7 +226,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }}), })), ) - getSlices := func(ctx context.Context) ([]resourcev1alpha2.NodeResourceSlice, error) { + getSlices := func(ctx context.Context) ([]resourcev1alpha2.ResourceSlice, error) { slices, err := resourceClient.List(ctx, metav1.ListOptions{FieldSelector: fmt.Sprintf("nodeName=%s,driverName=%s", nodeName, driverName)}) if err != nil { return nil, err @@ -1463,10 +1463,10 @@ func (b *builder) create(ctx context.Context, objs ...klog.KMetadata) []klog.KMe createdObj, err = b.f.ClientSet.ResourceV1alpha2().ResourceClassParameters(b.f.Namespace.Name).Create(ctx, obj, metav1.CreateOptions{}) case *resourcev1alpha2.ResourceClaimParameters: createdObj, err = b.f.ClientSet.ResourceV1alpha2().ResourceClaimParameters(b.f.Namespace.Name).Create(ctx, obj, metav1.CreateOptions{}) - case *resourcev1alpha2.NodeResourceSlice: - createdObj, err = b.f.ClientSet.ResourceV1alpha2().NodeResourceSlices().Create(ctx, obj, metav1.CreateOptions{}) + case *resourcev1alpha2.ResourceSlice: + createdObj, err = b.f.ClientSet.ResourceV1alpha2().ResourceSlices().Create(ctx, obj, metav1.CreateOptions{}) ginkgo.DeferCleanup(func(ctx context.Context) { - err := b.f.ClientSet.ResourceV1alpha2().NodeResourceSlices().Delete(ctx, createdObj.GetName(), metav1.DeleteOptions{}) + err := b.f.ClientSet.ResourceV1alpha2().ResourceSlices().Delete(ctx, createdObj.GetName(), metav1.DeleteOptions{}) framework.ExpectNoError(err, "delete node resource slice") }) default: diff --git a/test/integration/etcd/data.go b/test/integration/etcd/data.go index fa7a863ed2b..4bf2b88e1db 100644 --- a/test/integration/etcd/data.go +++ b/test/integration/etcd/data.go @@ -454,9 +454,9 @@ func GetEtcdStorageDataForNamespace(namespace string) map[schema.GroupVersionRes Stub: `{"metadata": {"name": "claim1parameters"}}`, ExpectedEtcdPath: "/registry/resourceclaimparameters/" + namespace + "/claim1parameters", }, - gvr("resource.k8s.io", "v1alpha2", "noderesourceslices"): { + gvr("resource.k8s.io", "v1alpha2", "resourceslices"): { Stub: `{"metadata": {"name": "node1slice"}, "nodeName": "worker1", "driverName": "dra.example.com", "namedResources": {}}`, - ExpectedEtcdPath: "/registry/noderesourceslices/node1slice", + ExpectedEtcdPath: "/registry/resourceslices/node1slice", }, // -- diff --git a/test/integration/scheduler_perf/dra.go b/test/integration/scheduler_perf/dra.go index 977d83119e7..103c35ae333 100644 --- a/test/integration/scheduler_perf/dra.go +++ b/test/integration/scheduler_perf/dra.go @@ -128,7 +128,7 @@ type createResourceDriverOp struct { Nodes string // StructuredParameters is true if the controller that is built into the scheduler // is used and the control-plane controller is not needed. - // Because we don't run the kubelet plugin, NodeResourceSlices must + // Because we don't run the kubelet plugin, ResourceSlices must // get created for all nodes. StructuredParameters bool } @@ -195,12 +195,12 @@ func (op *createResourceDriverOp) run(tCtx ktesting.TContext) { if op.StructuredParameters { for _, nodeName := range resources.Nodes { - slice := nodeResourceSlice(op.DriverName, nodeName, op.MaxClaimsPerNode) - _, err := tCtx.Client().ResourceV1alpha2().NodeResourceSlices().Create(tCtx, slice, metav1.CreateOptions{}) + slice := resourceSlice(op.DriverName, nodeName, op.MaxClaimsPerNode) + _, err := tCtx.Client().ResourceV1alpha2().ResourceSlices().Create(tCtx, slice, metav1.CreateOptions{}) tCtx.ExpectNoError(err, "create node resource slice") } tCtx.CleanupCtx(func(tCtx ktesting.TContext) { - err := tCtx.Client().ResourceV1alpha2().NodeResourceSlices().DeleteCollection(tCtx, + err := tCtx.Client().ResourceV1alpha2().ResourceSlices().DeleteCollection(tCtx, metav1.DeleteOptions{}, metav1.ListOptions{FieldSelector: "driverName=" + op.DriverName}, ) @@ -228,8 +228,8 @@ func (op *createResourceDriverOp) run(tCtx ktesting.TContext) { }) } -func nodeResourceSlice(driverName, nodeName string, capacity int) *resourcev1alpha2.NodeResourceSlice { - slice := &resourcev1alpha2.NodeResourceSlice{ +func resourceSlice(driverName, nodeName string, capacity int) *resourcev1alpha2.ResourceSlice { + slice := &resourcev1alpha2.ResourceSlice{ ObjectMeta: metav1.ObjectMeta{ Name: nodeName, }, From 2c6246c906694641c0cb6d6b32ab7f28f19a1858 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Thu, 7 Mar 2024 10:53:35 +0100 Subject: [PATCH 15/18] dra e2e: move ResourceSlice test This should better run with multiple nodes, it's more realistic that way. --- test/e2e/dra/dra.go | 98 ++++++++++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 41 deletions(-) diff --git a/test/e2e/dra/dra.go b/test/e2e/dra/dra.go index 65ed92b221c..d75454db1fe 100644 --- a/test/e2e/dra/dra.go +++ b/test/e2e/dra/dra.go @@ -203,47 +203,6 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, driver := NewDriver(f, nodes, perNode(1, nodes)) driver.parameterMode = parameterModeStructured - f.It("must manage ResourceSlice", f.WithSlow(), func(ctx context.Context) { - nodeName := nodes.NodeNames[0] - driverName := driver.Name - m := MethodInstance{nodeName, NodeListAndWatchResourcesMethod} - ginkgo.By("wait for NodeListAndWatchResources call") - gomega.Eventually(ctx, func() int64 { - return driver.CallCount(m) - }).WithTimeout(podStartTimeout).Should(gomega.BeNumerically(">", int64(0)), "NodeListAndWatchResources call count") - - ginkgo.By("check if ResourceSlice object exists on the API server") - resourceClient := f.ClientSet.ResourceV1alpha2().ResourceSlices() - matchSlices := gomega.And( - gomega.HaveLen(1), - gomega.ContainElement(gstruct.MatchAllFields(gstruct.Fields{ - "TypeMeta": gstruct.Ignore(), - "ObjectMeta": gstruct.Ignore(), // TODO (https://github.com/kubernetes/kubernetes/issues/123692): validate ownerref - "NodeName": gomega.Equal(nodes.NodeNames[0]), - "DriverName": gomega.Equal(driver.Name), - "NodeResourceModel": gomega.Equal(resourcev1alpha2.NodeResourceModel{NamedResources: &resourcev1alpha2.NamedResourcesResources{ - Instances: []resourcev1alpha2.NamedResourcesInstance{{Name: "instance-0"}}, - }}), - })), - ) - getSlices := func(ctx context.Context) ([]resourcev1alpha2.ResourceSlice, error) { - slices, err := resourceClient.List(ctx, metav1.ListOptions{FieldSelector: fmt.Sprintf("nodeName=%s,driverName=%s", nodeName, driverName)}) - if err != nil { - return nil, err - } - return slices.Items, nil - } - gomega.Eventually(ctx, getSlices).WithTimeout(20 * time.Second).Should(matchSlices) - gomega.Consistently(ctx, getSlices).WithTimeout(20 * time.Second).Should(matchSlices) - - // Removal of node resource slice is tested by the general driver removal code. - }) - - // TODO (https://github.com/kubernetes/kubernetes/issues/123699): more test scenarios: - // - driver returns "unimplemented" as method response - // - driver returns "Unimplemented" as part of stream - // - driver returns EOF - // - driver changes resources }) }) @@ -670,6 +629,63 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, ginkgo.Context("cluster", func() { nodes := NewNodes(f, 1, 4) + ginkgo.Context("with structured parameters", func() { + driver := NewDriver(f, nodes, perNode(1, nodes)) + driver.parameterMode = parameterModeStructured + + f.It("must manage ResourceSlices", f.WithSlow(), func(ctx context.Context) { + nodeName := nodes.NodeNames[0] + driverName := driver.Name + + // Check for gRPC call on one node. If that already fails, then + // we have a fundamental problem. + m := MethodInstance{nodeName, NodeListAndWatchResourcesMethod} + ginkgo.By("wait for NodeListAndWatchResources call") + gomega.Eventually(ctx, func() int64 { + return driver.CallCount(m) + }).WithTimeout(podStartTimeout).Should(gomega.BeNumerically(">", int64(0)), "NodeListAndWatchResources call count") + + // Now check for exactly the right set of objects for all nodes. + ginkgo.By("check if ResourceSlice object(s) exist on the API server") + resourceClient := f.ClientSet.ResourceV1alpha2().ResourceSlices() + var expectedObjects []any + for _, nodeName := range nodes.NodeNames { + expectedObjects = append(expectedObjects, + gstruct.MatchAllFields(gstruct.Fields{ + "TypeMeta": gstruct.Ignore(), + "ObjectMeta": gstruct.Ignore(), // TODO (https://github.com/kubernetes/kubernetes/issues/123692): validate ownerref + "NodeName": gomega.Equal(nodeName), + "DriverName": gomega.Equal(driver.Name), + "NodeResourceModel": gomega.Equal(resourcev1alpha2.NodeResourceModel{NamedResources: &resourcev1alpha2.NamedResourcesResources{ + Instances: []resourcev1alpha2.NamedResourcesInstance{{Name: "instance-0"}}, + }}), + }), + ) + } + matchSlices := gomega.ContainElements(expectedObjects...) + getSlices := func(ctx context.Context) ([]resourcev1alpha2.ResourceSlice, error) { + slices, err := resourceClient.List(ctx, metav1.ListOptions{FieldSelector: fmt.Sprintf("driverName=%s", driverName)}) + if err != nil { + return nil, err + } + return slices.Items, nil + } + gomega.Eventually(ctx, getSlices).WithTimeout(20 * time.Second).Should(matchSlices) + gomega.Consistently(ctx, getSlices).WithTimeout(20 * time.Second).Should(matchSlices) + + // Removal of node resource slice is tested by the general driver removal code. + }) + + // TODO (https://github.com/kubernetes/kubernetes/issues/123699): more test scenarios: + // - driver returns "unimplemented" as method response + // - driver returns "Unimplemented" as part of stream + // - driver returns EOF + // - driver changes resources + // + // None of those matter if the publishing gets moved into the driver itself, + // which is the goal for 1.31 to support version skew for kubelet. + }) + ginkgo.Context("with local unshared resources", func() { driver := NewDriver(f, nodes, func() app.Resources { return app.Resources{ From 251b3859b0b71d9a42881dc1d0c974e0d30e3f0e Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Thu, 7 Mar 2024 16:02:01 +0100 Subject: [PATCH 16/18] dra scheduler: consider in-flight allocation for resource calculation Storing a modified claim with allocation and the original resource version in the assume cache was not reliable: if an update was received, it replaced the modified claim and the resource that was reserved for the claim might have been used for some other claim. To fix this, the in-flight claims are now stored in the map instead of just a boolean and the status stored there overrides whatever is in the assume cache. Logging got extended to diagnose this problem better. It started to occur in E2E tests after splitting the claim update so that first the finalizer is set and then the status, because setting the finalizer triggered an update. --- .../dynamicresources/dynamicresources.go | 29 ++++++++++------- .../namedresources/namedresourcesmodel.go | 31 ++++++++++--------- .../dynamicresources/structuredparameters.go | 28 ++++++++++------- 3 files changed, 51 insertions(+), 37 deletions(-) diff --git a/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go b/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go index fdd0e5533a5..9fce37fdabe 100644 --- a/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go +++ b/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go @@ -283,9 +283,9 @@ type dynamicResources struct { // claimAssumeCache enables temporarily storing a newer claim object // while the scheduler has allocated it and the corresponding object // update from the apiserver has not been processed by the claim - // informer callbacks. Claims get added here in Reserve and removed by + // informer callbacks. Claims get added here in PreBind and removed by // the informer callback (based on the "newer than" comparison in the - // assume cache) or when the API call in PreBind fails. + // assume cache). // // It uses cache.MetaNamespaceKeyFunc to generate object names, which // therefore are "/". @@ -304,7 +304,7 @@ type dynamicResources struct { // might have to be managed by the cluster autoscaler. claimAssumeCache volumebinding.AssumeCache - // inFlightAllocations is map from claim UUIDs to true for those claims + // inFlightAllocations is map from claim UUIDs to claim objects for those claims // for which allocation was triggered during a scheduling cycle and the // corresponding claim status update call in PreBind has not been done // yet. If another pod needs the claim, the pod is treated as "not @@ -943,7 +943,11 @@ func (pl *dynamicResources) PreFilter(ctx context.Context, state *framework.Cycl // problems for using the plugin in the Cluster Autoscaler. If // this step here turns out to be expensive, we may have to // maintain and update state more persistently. - resources, err := newResourceModel(logger, pl.resourceSliceLister, pl.claimAssumeCache) + // + // Claims are treated as "allocated" if they are in the assume cache + // or currently their allocation is in-flight. + resources, err := newResourceModel(logger, pl.resourceSliceLister, pl.claimAssumeCache, &pl.inFlightAllocations) + logger.V(5).Info("Resource usage", "resources", klog.Format(resources)) if err != nil { return nil, statusError(logger, err) } @@ -1382,14 +1386,11 @@ func (pl *dynamicResources) Reserve(ctx context.Context, cs *framework.CycleStat } state.informationsForClaim[index].allocation = allocation state.informationsForClaim[index].allocationDriverName = driverName - pl.inFlightAllocations.Store(claim.UID, true) claim = claim.DeepCopy() claim.Status.DriverName = driverName claim.Status.Allocation = allocation - if err := pl.claimAssumeCache.Assume(claim); err != nil { - return statusError(logger, fmt.Errorf("update claim assume cache: %v", err)) - } - logger.V(5).Info("Reserved resource in allocation result", "claim", klog.KObj(claim), "driver", driverName, "allocation", allocation) + pl.inFlightAllocations.Store(claim.UID, claim) + logger.V(5).Info("Reserved resource in allocation result", "claim", klog.KObj(claim), "driver", driverName, "allocation", klog.Format(allocation)) } // When there is only one pending resource, we can go ahead with @@ -1557,7 +1558,7 @@ func (pl *dynamicResources) bindClaim(ctx context.Context, state *stateData, ind allocationPatch := "" allocation := state.informationsForClaim[index].allocation - logger.V(5).Info("preparing claim status patch", "claim", klog.KObj(state.claims[index]), "allocation", allocation) + logger.V(5).Info("preparing claim status patch", "claim", klog.KObj(state.claims[index]), "allocation", klog.Format(allocation)) // Do we need to store an allocation result from Reserve? if allocation != nil { @@ -1609,8 +1610,12 @@ func (pl *dynamicResources) bindClaim(ctx context.Context, state *stateData, ind if allocationPatch != "" { // The scheduler was handling allocation. Now that has // completed, either successfully or with a failure. - if err != nil { - pl.claimAssumeCache.Restore(claim.Namespace + "/" + claim.Name) + if err == nil { + // This can fail, but only for reasons that are okay (concurrent delete or update). + // Shouldn't happen in this case. + if err := pl.claimAssumeCache.Assume(claim); err != nil { + logger.V(5).Info("Claim not stored in assume cache", "err", err) + } } pl.inFlightAllocations.Delete(claim.UID) } diff --git a/pkg/scheduler/framework/plugins/dynamicresources/structured/namedresources/namedresourcesmodel.go b/pkg/scheduler/framework/plugins/dynamicresources/structured/namedresources/namedresourcesmodel.go index 08ba8a32dd6..c65265c8380 100644 --- a/pkg/scheduler/framework/plugins/dynamicresources/structured/namedresources/namedresourcesmodel.go +++ b/pkg/scheduler/framework/plugins/dynamicresources/structured/namedresources/namedresourcesmodel.go @@ -27,13 +27,16 @@ import ( "k8s.io/dynamic-resource-allocation/structured/namedresources/cel" ) +// These types and fields are all exported to allow logging them with +// pretty-printed JSON. + type Model struct { - instances []instanceAllocation + Instances []InstanceAllocation } -type instanceAllocation struct { - allocated bool - instance *resourceapi.NamedResourcesInstance +type InstanceAllocation struct { + Allocated bool + Instance *resourceapi.NamedResourcesInstance } // AddResources must be called first to create entries for all existing @@ -44,7 +47,7 @@ func AddResources(m *Model, resources *resourceapi.NamedResourcesResources) { } for i := range resources.Instances { - m.instances = append(m.instances, instanceAllocation{instance: &resources.Instances[i]}) + m.Instances = append(m.Instances, InstanceAllocation{Instance: &resources.Instances[i]}) } } @@ -54,9 +57,9 @@ func AddAllocation(m *Model, result *resourceapi.NamedResourcesAllocationResult) if result == nil { return } - for i := range m.instances { - if m.instances[i].instance.Name == result.Name { - m.instances[i].allocated = true + for i := range m.Instances { + if m.Instances[i].Instance.Name == result.Name { + m.Instances[i].Allocated = true break } } @@ -103,23 +106,23 @@ func (c *Controller) Allocate(ctx context.Context, model Model) ([]*resourceapi. } results := make([]*resourceapi.NamedResourcesAllocationResult, len(c.requests)) for i := range c.requests { - results[i] = &resourceapi.NamedResourcesAllocationResult{Name: model.instances[indices[i]].instance.Name} + results[i] = &resourceapi.NamedResourcesAllocationResult{Name: model.Instances[indices[i]].Instance.Name} } return results, nil } func (c *Controller) allocate(ctx context.Context, model Model) ([]int, error) { // Shallow copy, we need to modify the allocated boolean. - instances := slices.Clone(model.instances) + instances := slices.Clone(model.Instances) indices := make([]int, 0, len(c.requests)) for _, request := range c.requests { for i, instance := range instances { - if instance.allocated { + if instance.Allocated { continue } if c.filter != nil { - okay, err := c.filter.Evaluate(ctx, instance.instance.Attributes) + okay, err := c.filter.Evaluate(ctx, instance.Instance.Attributes) if err != nil { return nil, fmt.Errorf("evaluate filter CEL expression: %w", err) } @@ -127,7 +130,7 @@ func (c *Controller) allocate(ctx context.Context, model Model) ([]int, error) { continue } } - okay, err := request.Evaluate(ctx, instance.instance.Attributes) + okay, err := request.Evaluate(ctx, instance.Instance.Attributes) if err != nil { return nil, fmt.Errorf("evaluate request CEL expression: %w", err) } @@ -140,7 +143,7 @@ func (c *Controller) allocate(ctx context.Context, model Model) ([]int, error) { // allocating one "large" instances for a "small" request may // make a following "large" request impossible to satisfy when // only "small" instances are left. - instances[i].allocated = true + instances[i].Allocated = true indices = append(indices, i) break } diff --git a/pkg/scheduler/framework/plugins/dynamicresources/structuredparameters.go b/pkg/scheduler/framework/plugins/dynamicresources/structuredparameters.go index 6ac1d263f16..44b9aee85b9 100644 --- a/pkg/scheduler/framework/plugins/dynamicresources/structuredparameters.go +++ b/pkg/scheduler/framework/plugins/dynamicresources/structuredparameters.go @@ -19,6 +19,7 @@ package dynamicresources import ( "context" "fmt" + "sync" v1 "k8s.io/api/core/v1" resourcev1alpha2 "k8s.io/api/resource/v1alpha2" @@ -32,19 +33,19 @@ import ( // resources is a map "node name" -> "driver name" -> available and // allocated resources per structured parameter model. -type resources map[string]map[string]resourceModels +type resources map[string]map[string]ResourceModels -// resourceModels may have more than one entry because it is valid for a driver to +// ResourceModels may have more than one entry because it is valid for a driver to // use more than one structured parameter model. -type resourceModels struct { - namedresources namedresourcesmodel.Model +type ResourceModels struct { + NamedResources namedresourcesmodel.Model } // newResourceModel parses the available information about resources. Objects // with an unknown structured parameter model silently ignored. An error gets // logged later when parameters required for a pod depend on such an unknown // model. -func newResourceModel(logger klog.Logger, resourceSliceLister resourcev1alpha2listers.ResourceSliceLister, claimAssumeCache volumebinding.AssumeCache) (resources, error) { +func newResourceModel(logger klog.Logger, resourceSliceLister resourcev1alpha2listers.ResourceSliceLister, claimAssumeCache volumebinding.AssumeCache, inFlightAllocations *sync.Map) (resources, error) { model := make(resources) slices, err := resourceSliceLister.List(labels.Everything()) @@ -53,10 +54,10 @@ func newResourceModel(logger klog.Logger, resourceSliceLister resourcev1alpha2li } for _, slice := range slices { if model[slice.NodeName] == nil { - model[slice.NodeName] = make(map[string]resourceModels) + model[slice.NodeName] = make(map[string]ResourceModels) } resource := model[slice.NodeName][slice.DriverName] - namedresourcesmodel.AddResources(&resource.namedresources, slice.NamedResources) + namedresourcesmodel.AddResources(&resource.NamedResources, slice.NamedResources) model[slice.NodeName][slice.DriverName] = resource } @@ -66,6 +67,11 @@ func newResourceModel(logger klog.Logger, resourceSliceLister resourcev1alpha2li if !ok { return nil, fmt.Errorf("got unexpected object of type %T from claim assume cache", obj) } + if obj, ok := inFlightAllocations.Load(claim.UID); ok { + // If the allocation is in-flight, then we have to use the allocation + // from that claim. + claim = obj.(*resourcev1alpha2.ResourceClaim) + } if claim.Status.Allocation == nil { continue } @@ -75,12 +81,12 @@ func newResourceModel(logger klog.Logger, resourceSliceLister resourcev1alpha2li continue } if model[structured.NodeName] == nil { - model[structured.NodeName] = make(map[string]resourceModels) + model[structured.NodeName] = make(map[string]ResourceModels) } resource := model[structured.NodeName][handle.DriverName] for _, result := range structured.Results { // Call AddAllocation for each known model. Each call itself needs to check for nil. - namedresourcesmodel.AddAllocation(&resource.namedresources, result.NamedResources) + namedresourcesmodel.AddAllocation(&resource.NamedResources, result.NamedResources) } } } @@ -159,7 +165,7 @@ type perDriverController struct { func (c claimController) nodeIsSuitable(ctx context.Context, nodeName string, resources resources) (bool, error) { nodeResources := resources[nodeName] for driverName, perDriver := range c.namedresources { - okay, err := perDriver.controller.NodeIsSuitable(ctx, nodeResources[driverName].namedresources) + okay, err := perDriver.controller.NodeIsSuitable(ctx, nodeResources[driverName].NamedResources) if err != nil { // This is an error in the CEL expression which needs // to be fixed. Better fail very visibly instead of @@ -191,7 +197,7 @@ func (c claimController) allocate(ctx context.Context, nodeName string, resource for driverName, perDriver := range c.namedresources { // Must return one entry for each request. The entry may be nil. This way, // the result can be correlated with the per-request parameters. - results, err := perDriver.controller.Allocate(ctx, nodeResources[driverName].namedresources) + results, err := perDriver.controller.Allocate(ctx, nodeResources[driverName].NamedResources) if err != nil { return "", nil, fmt.Errorf("allocating via named resources structured model: %w", err) } From 7f5566ac6f6abd5827da120bd57187e390339daf Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Thu, 7 Mar 2024 18:30:52 +0100 Subject: [PATCH 17/18] dra e2e: enable more tests for usage with structured parameters This finishes the shuffling around of test scenarios so that all of them which make sense with structured parameters are also executed with those. --- test/e2e/dra/dra.go | 700 ++++++++++++++++++++++---------------------- 1 file changed, 358 insertions(+), 342 deletions(-) diff --git a/test/e2e/dra/dra.go b/test/e2e/dra/dra.go index d75454db1fe..74c05663596 100644 --- a/test/e2e/dra/dra.go +++ b/test/e2e/dra/dra.go @@ -198,49 +198,13 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) }) - - ginkgo.Context("with structured parameters", func() { - driver := NewDriver(f, nodes, perNode(1, nodes)) - driver.parameterMode = parameterModeStructured - - }) }) - genConfigMapParameters := func(b *builder) ([]klog.KMetadata, []string) { - return []klog.KMetadata{b.parameters()}, []string{"user_a", "b"} - } - - genFlexibleParameters := func(b *builder) ([]klog.KMetadata, []string) { - var objects []klog.KMetadata - switch b.driver.parameterMode { - case parameterModeConfigMap: - objects = append(objects, - b.parameters("x", "y"), - b.parameters("a", "b", "request_foo", "bar"), - ) - case parameterModeTranslated: - objects = append(objects, - b.parameters("x", "y"), - b.classParameters(b.parametersName(), "x", "y"), - b.parameters("a", "b", "request_foo", "bar"), - b.claimParameters(b.parametersName(), []string{"a", "b"}, []string{"request_foo", "bar"}), - ) - // The parameters object is not the last one but the second-last. - b.parametersCounter-- - case parameterModeStructured: - objects = append(objects, - b.classParameters("", "x", "y"), - b.claimParameters("", []string{"a", "b"}, []string{"request_foo", "bar"}), - ) - } - return objects, []string{"user_a", "b", "user_request_foo", "bar", "admin_x", "y"} - } - // claimTests tries out several different combinations of pods with // claims, both inline and external. - claimTests := func(b *builder, driver *Driver, allocationMode resourcev1alpha2.AllocationMode, genParameters func(b *builder) ([]klog.KMetadata, []string)) { + claimTests := func(b *builder, driver *Driver, allocationMode resourcev1alpha2.AllocationMode) { ginkgo.It("supports simple pod referencing inline resource claim", func(ctx context.Context) { - objects, expectedEnv := genParameters(b) + objects, expectedEnv := b.flexibleParameters() pod, template := b.podInline(allocationMode) objects = append(objects, pod, template) b.create(ctx, objects...) @@ -249,7 +213,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) ginkgo.It("supports inline claim referenced by multiple containers", func(ctx context.Context) { - objects, expectedEnv := genParameters(b) + objects, expectedEnv := b.flexibleParameters() pod, template := b.podInlineMultiple(allocationMode) objects = append(objects, pod, template) b.create(ctx, objects...) @@ -258,7 +222,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) ginkgo.It("supports simple pod referencing external resource claim", func(ctx context.Context) { - objects, expectedEnv := genParameters(b) + objects, expectedEnv := b.flexibleParameters() pod := b.podExternal() claim := b.externalClaim(allocationMode) objects = append(objects, claim, pod) @@ -268,7 +232,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) ginkgo.It("supports external claim referenced by multiple pods", func(ctx context.Context) { - objects, expectedEnv := genParameters(b) + objects, expectedEnv := b.flexibleParameters() pod1 := b.podExternal() pod2 := b.podExternal() pod3 := b.podExternal() @@ -282,7 +246,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) ginkgo.It("supports external claim referenced by multiple containers of multiple pods", func(ctx context.Context) { - objects, expectedEnv := genParameters(b) + objects, expectedEnv := b.flexibleParameters() pod1 := b.podExternalMultiple() pod2 := b.podExternalMultiple() pod3 := b.podExternalMultiple() @@ -296,7 +260,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) ginkgo.It("supports init containers", func(ctx context.Context) { - objects, expectedEnv := genParameters(b) + objects, expectedEnv := b.flexibleParameters() pod, template := b.podInline(allocationMode) pod.Spec.InitContainers = []v1.Container{pod.Spec.Containers[0]} pod.Spec.InitContainers[0].Name += "-init" @@ -309,7 +273,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) ginkgo.It("removes reservation from claim when pod is done", func(ctx context.Context) { - objects, _ := genParameters(b) + objects, _ := b.flexibleParameters() pod := b.podExternal() claim := b.externalClaim(allocationMode) pod.Spec.Containers[0].Command = []string{"true"} @@ -325,7 +289,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) ginkgo.It("deletes generated claims when pod is done", func(ctx context.Context) { - objects, _ := genParameters(b) + objects, _ := b.flexibleParameters() pod, template := b.podInline(allocationMode) pod.Spec.Containers[0].Command = []string{"true"} objects = append(objects, template, pod) @@ -344,7 +308,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) ginkgo.It("does not delete generated claims when pod is restarting", func(ctx context.Context) { - objects, _ := genParameters(b) + objects, _ := b.flexibleParameters() pod, template := b.podInline(allocationMode) pod.Spec.Containers[0].Command = []string{"sh", "-c", "sleep 1; exit 1"} pod.Spec.RestartPolicy = v1.RestartPolicyAlways @@ -361,7 +325,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) ginkgo.It("must deallocate after use when using delayed allocation", func(ctx context.Context) { - objects, expectedEnv := genParameters(b) + objects, expectedEnv := b.flexibleParameters() pod := b.podExternal() claim := b.externalClaim(resourcev1alpha2.AllocationModeWaitForFirstConsumer) objects = append(objects, claim, pod) @@ -383,7 +347,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) } - runTests := func(parameterMode parameterMode) { + singleNodeTests := func(parameterMode parameterMode) { nodes := NewNodes(f, 1, 1) maxAllocations := 1 numPods := 10 @@ -399,12 +363,8 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, b.parametersCounter = 1 b.classParametersName = b.parametersName() - genParameters := func() ([]klog.KMetadata, []string) { - return genFlexibleParameters(b) - } - ginkgo.It("supports claim and class parameters", func(ctx context.Context) { - objects, expectedEnv := genParameters() + objects, expectedEnv := b.flexibleParameters() pod, template := b.podInline(resourcev1alpha2.AllocationModeWaitForFirstConsumer) objects = append(objects, pod, template) @@ -415,7 +375,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) ginkgo.It("supports reusing resources", func(ctx context.Context) { - objects, expectedEnv := genParameters() + objects, expectedEnv := b.flexibleParameters() pods := make([]*v1.Pod, numPods) for i := 0; i < numPods; i++ { pod, template := b.podInline(resourcev1alpha2.AllocationModeWaitForFirstConsumer) @@ -443,7 +403,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) ginkgo.It("supports sharing a claim concurrently", func(ctx context.Context) { - objects, expectedEnv := genParameters() + objects, expectedEnv := b.flexibleParameters() objects = append(objects, b.externalClaim(resourcev1alpha2.AllocationModeWaitForFirstConsumer)) pods := make([]*v1.Pod, numPods) @@ -470,8 +430,9 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, wg.Wait() }) - ginkgo.It("supports sharing a claim sequentially", func(ctx context.Context) { - objects, expectedEnv := genParameters() + f.It("supports sharing a claim sequentially", f.WithSlow(), func(ctx context.Context) { + objects, expectedEnv := b.flexibleParameters() + numPods := numPods / 2 // Change from "shareable" to "not shareable", if possible. switch parameterMode { @@ -512,7 +473,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) ginkgo.It("retries pod scheduling after creating resource class", func(ctx context.Context) { - objects, expectedEnv := genParameters() + objects, expectedEnv := b.flexibleParameters() pod, template := b.podInline(resourcev1alpha2.AllocationModeWaitForFirstConsumer) class, err := f.ClientSet.ResourceV1alpha2().ResourceClasses().Get(ctx, template.Spec.Spec.ResourceClassName, metav1.GetOptions{}) framework.ExpectNoError(err) @@ -524,6 +485,9 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, // But if we sleep for a short while, it's likely and if there are any // bugs that prevent the scheduler from handling creation of the class, // those bugs should show up as test flakes. + // + // TODO (https://github.com/kubernetes/kubernetes/issues/123805): check the Schedulable condition instead of + // sleeping. time.Sleep(time.Second) class.UID = "" @@ -535,7 +499,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) ginkgo.It("retries pod scheduling after updating resource class", func(ctx context.Context) { - objects, expectedEnv := genParameters() + objects, expectedEnv := b.flexibleParameters() pod, template := b.podInline(resourcev1alpha2.AllocationModeWaitForFirstConsumer) // First modify the class so that it matches no nodes. @@ -594,17 +558,306 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) ginkgo.Context("with delayed allocation", func() { - claimTests(b, driver, resourcev1alpha2.AllocationModeWaitForFirstConsumer, genFlexibleParameters) + claimTests(b, driver, resourcev1alpha2.AllocationModeWaitForFirstConsumer) }) ginkgo.Context("with immediate allocation", func() { - claimTests(b, driver, resourcev1alpha2.AllocationModeImmediate, genFlexibleParameters) + claimTests(b, driver, resourcev1alpha2.AllocationModeImmediate) }) } - ginkgo.Context("with ConfigMap parameters", func() { runTests(parameterModeConfigMap) }) - ginkgo.Context("with translated parameters", func() { runTests(parameterModeTranslated) }) - ginkgo.Context("with structured parameters", func() { runTests(parameterModeStructured) }) + // These tests depend on having more than one node and a DRA driver controller. + multiNodeDRAControllerTests := func(nodes *Nodes) { + driver := NewDriver(f, nodes, networkResources) + b := newBuilder(f, driver) + + ginkgo.It("schedules onto different nodes", func(ctx context.Context) { + parameters := b.parameters() + label := "app.kubernetes.io/instance" + instance := f.UniqueName + "-test-app" + antiAffinity := &v1.Affinity{ + PodAntiAffinity: &v1.PodAntiAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []v1.PodAffinityTerm{ + { + TopologyKey: "kubernetes.io/hostname", + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + label: instance, + }, + }, + }, + }, + }, + } + createPod := func() *v1.Pod { + pod := b.podExternal() + pod.Labels[label] = instance + pod.Spec.Affinity = antiAffinity + return pod + } + pod1 := createPod() + pod2 := createPod() + claim := b.externalClaim(resourcev1alpha2.AllocationModeWaitForFirstConsumer) + b.create(ctx, parameters, claim, pod1, pod2) + + for _, pod := range []*v1.Pod{pod1, pod2} { + err := e2epod.WaitForPodRunningInNamespace(ctx, f.ClientSet, pod) + framework.ExpectNoError(err, "start pod") + } + }) + + // This test covers aspects of non graceful node shutdown by DRA controller + // More details about this can be found in the KEP: + // https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/2268-non-graceful-shutdown + // NOTE: this test depends on kind. It will only work with kind cluster as it shuts down one of the + // nodes by running `docker stop `, which is very kind-specific. + f.It(f.WithSerial(), f.WithDisruptive(), f.WithSlow(), "must deallocate on non graceful node shutdown", func(ctx context.Context) { + ginkgo.By("create test pod") + parameters := b.parameters() + label := "app.kubernetes.io/instance" + instance := f.UniqueName + "-test-app" + pod := b.podExternal() + pod.Labels[label] = instance + claim := b.externalClaim(resourcev1alpha2.AllocationModeWaitForFirstConsumer) + b.create(ctx, parameters, claim, pod) + + ginkgo.By("wait for test pod " + pod.Name + " to run") + labelSelector := labels.SelectorFromSet(labels.Set(pod.Labels)) + pods, err := e2epod.WaitForPodsWithLabelRunningReady(ctx, f.ClientSet, pod.Namespace, labelSelector, 1, framework.PodStartTimeout) + framework.ExpectNoError(err, "start pod") + runningPod := &pods.Items[0] + + nodeName := runningPod.Spec.NodeName + // Prevent builder tearDown to fail waiting for unprepared resources + delete(b.driver.Nodes, nodeName) + ginkgo.By("stop node " + nodeName + " non gracefully") + _, stderr, err := framework.RunCmd("docker", "stop", nodeName) + gomega.Expect(stderr).To(gomega.BeEmpty()) + framework.ExpectNoError(err) + ginkgo.DeferCleanup(framework.RunCmd, "docker", "start", nodeName) + if ok := e2enode.WaitForNodeToBeNotReady(ctx, f.ClientSet, nodeName, f.Timeouts.NodeNotReady); !ok { + framework.Failf("Node %s failed to enter NotReady state", nodeName) + } + + ginkgo.By("apply out-of-service taint on node " + nodeName) + taint := v1.Taint{ + Key: v1.TaintNodeOutOfService, + Effect: v1.TaintEffectNoExecute, + } + e2enode.AddOrUpdateTaintOnNode(ctx, f.ClientSet, nodeName, taint) + e2enode.ExpectNodeHasTaint(ctx, f.ClientSet, nodeName, &taint) + ginkgo.DeferCleanup(e2enode.RemoveTaintOffNode, f.ClientSet, nodeName, taint) + + ginkgo.By("waiting for claim to get deallocated") + gomega.Eventually(ctx, framework.GetObject(b.f.ClientSet.ResourceV1alpha2().ResourceClaims(b.f.Namespace.Name).Get, claim.Name, metav1.GetOptions{})).WithTimeout(f.Timeouts.PodDelete).Should(gomega.HaveField("Status.Allocation", gomega.BeNil())) + }) + } + + // The following tests only make sense when there is more than one node. + // They get skipped when there's only one node. + multiNodeTests := func(parameterMode parameterMode) { + nodes := NewNodes(f, 2, 8) + + if parameterMode == parameterModeConfigMap { + ginkgo.Context("with network-attached resources", func() { + multiNodeDRAControllerTests(nodes) + }) + + ginkgo.Context("reallocation", func() { + var allocateWrapper2 app.AllocateWrapperType + driver := NewDriver(f, nodes, perNode(1, nodes)) + driver2 := NewDriver(f, nodes, func() app.Resources { + return app.Resources{ + NodeLocal: true, + MaxAllocations: 1, + Nodes: nodes.NodeNames, + + AllocateWrapper: func( + ctx context.Context, + claimAllocations []*controller.ClaimAllocation, + selectedNode string, + handler func( + ctx context.Context, + claimAllocations []*controller.ClaimAllocation, + selectedNode string), + ) { + allocateWrapper2(ctx, claimAllocations, selectedNode, handler) + }, + } + }) + driver2.NameSuffix = "-other" + + b := newBuilder(f, driver) + b2 := newBuilder(f, driver2) + + ginkgo.It("works", func(ctx context.Context) { + // A pod with multiple claims can run on a node, but + // only if allocation of all succeeds. This + // test simulates the scenario where one claim + // gets allocated from one driver, but the claims + // from second driver fail allocation because of a + // race with some other pod. + // + // To ensure the right timing, allocation of the + // claims from second driver are delayed while + // creating another pod that gets the remaining + // resource on the node from second driver. + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + parameters1 := b.parameters() + parameters2 := b2.parameters() + // Order is relevant here: each pod must be matched with its own claim. + pod1claim1 := b.externalClaim(resourcev1alpha2.AllocationModeWaitForFirstConsumer) + pod1 := b.podExternal() + pod2claim1 := b2.externalClaim(resourcev1alpha2.AllocationModeWaitForFirstConsumer) + pod2 := b2.podExternal() + + // Add another claim to pod1. + pod1claim2 := b2.externalClaim(resourcev1alpha2.AllocationModeWaitForFirstConsumer) + pod1.Spec.ResourceClaims = append(pod1.Spec.ResourceClaims, + v1.PodResourceClaim{ + Name: "claim-other", + Source: v1.ClaimSource{ + ResourceClaimName: &pod1claim2.Name, + }, + }, + ) + + // Allocating the second claim in pod1 has to wait until pod2 has + // consumed the available resources on the node. + blockClaim, cancelBlockClaim := context.WithCancel(ctx) + defer cancelBlockClaim() + allocateWrapper2 = func(ctx context.Context, + claimAllocations []*controller.ClaimAllocation, + selectedNode string, + handler func(ctx context.Context, + claimAllocations []*controller.ClaimAllocation, + selectedNode string), + ) { + if claimAllocations[0].Claim.Name == pod1claim2.Name { + <-blockClaim.Done() + } + handler(ctx, claimAllocations, selectedNode) + } + + b.create(ctx, parameters1, parameters2, pod1claim1, pod1claim2, pod1) + + ginkgo.By("waiting for one claim from driver1 to be allocated") + var nodeSelector *v1.NodeSelector + gomega.Eventually(ctx, func(ctx context.Context) (int, error) { + claims, err := f.ClientSet.ResourceV1alpha2().ResourceClaims(f.Namespace.Name).List(ctx, metav1.ListOptions{}) + if err != nil { + return 0, err + } + allocated := 0 + for _, claim := range claims.Items { + if claim.Status.Allocation != nil { + allocated++ + nodeSelector = claim.Status.Allocation.AvailableOnNodes + } + } + return allocated, nil + }).WithTimeout(time.Minute).Should(gomega.Equal(1), "one claim allocated") + + // Now create a second pod which we force to + // run on the same node that is currently being + // considered for the first one. We know what + // the node selector looks like and can + // directly access the key and value from it. + ginkgo.By(fmt.Sprintf("create second pod on the same node %s", nodeSelector)) + + req := nodeSelector.NodeSelectorTerms[0].MatchExpressions[0] + node := req.Values[0] + pod2.Spec.NodeSelector = map[string]string{req.Key: node} + + b2.create(ctx, pod2claim1, pod2) + framework.ExpectNoError(e2epod.WaitForPodRunningInNamespace(ctx, f.ClientSet, pod2), "start pod 2") + + // Allow allocation of second claim in pod1 to proceed. It should fail now + // and the other node must be used instead, after deallocating + // the first claim. + ginkgo.By("move first pod to other node") + cancelBlockClaim() + + framework.ExpectNoError(e2epod.WaitForPodRunningInNamespace(ctx, f.ClientSet, pod1), "start pod 1") + pod1, err := f.ClientSet.CoreV1().Pods(pod1.Namespace).Get(ctx, pod1.Name, metav1.GetOptions{}) + framework.ExpectNoError(err, "get first pod") + if pod1.Spec.NodeName == "" { + framework.Fail("first pod should be running on node, was not scheduled") + } + gomega.Expect(pod1.Spec.NodeName).ToNot(gomega.Equal(node), "first pod should run on different node than second one") + gomega.Expect(driver.Controller.GetNumDeallocations()).To(gomega.Equal(int64(1)), "number of deallocations") + }) + }) + } + + ginkgo.Context("with node-local resources", func() { + driver := NewDriver(f, nodes, perNode(1, nodes)) + driver.parameterMode = parameterMode + b := newBuilder(f, driver) + + tests := func(allocationMode resourcev1alpha2.AllocationMode) { + ginkgo.It("uses all resources", func(ctx context.Context) { + objs, _ := b.flexibleParameters() + var pods []*v1.Pod + for i := 0; i < len(nodes.NodeNames); i++ { + pod, template := b.podInline(allocationMode) + pods = append(pods, pod) + objs = append(objs, pod, template) + } + b.create(ctx, objs...) + + for _, pod := range pods { + err := e2epod.WaitForPodRunningInNamespace(ctx, f.ClientSet, pod) + framework.ExpectNoError(err, "start pod") + } + + // The pods all should run on different + // nodes because the maximum number of + // claims per node was limited to 1 for + // this test. + // + // We cannot know for sure why the pods + // ran on two different nodes (could + // also be a coincidence) but if they + // don't cover all nodes, then we have + // a problem. + used := make(map[string]*v1.Pod) + for _, pod := range pods { + pod, err := f.ClientSet.CoreV1().Pods(pod.Namespace).Get(ctx, pod.Name, metav1.GetOptions{}) + framework.ExpectNoError(err, "get pod") + nodeName := pod.Spec.NodeName + if other, ok := used[nodeName]; ok { + framework.Failf("Pod %s got started on the same node %s as pod %s although claim allocation should have been limited to one claim per node.", pod.Name, nodeName, other.Name) + } + used[nodeName] = pod + } + }) + } + + ginkgo.Context("with delayed allocation", func() { + tests(resourcev1alpha2.AllocationModeWaitForFirstConsumer) + }) + + ginkgo.Context("with immediate allocation", func() { + tests(resourcev1alpha2.AllocationModeImmediate) + }) + }) + } + + tests := func(parameterMode parameterMode) { + ginkgo.Context("on single node", func() { + singleNodeTests(parameterMode) + }) + ginkgo.Context("on multiple nodes", func() { + multiNodeTests(parameterMode) + }) + } + + ginkgo.Context("with ConfigMap parameters", func() { tests(parameterModeConfigMap) }) + ginkgo.Context("with translated parameters", func() { tests(parameterModeTranslated) }) + ginkgo.Context("with structured parameters", func() { tests(parameterModeStructured) }) // TODO (https://github.com/kubernetes/kubernetes/issues/123699): move most of the test below into `testDriver` so that they get // executed with different parameters. @@ -626,7 +879,9 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) }) - ginkgo.Context("cluster", func() { + // The following tests are all about behavior in combination with a + // control-plane DRA driver controller. + ginkgo.Context("cluster with DRA driver controller", func() { nodes := NewNodes(f, 1, 4) ginkgo.Context("with structured parameters", func() { @@ -784,7 +1039,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, b.create(ctx, objects...) ginkgo.By("waiting all pods to start") - framework.ExpectNoError(e2epod.WaitForPodsRunning(ctx, b.f.ClientSet, f.Namespace.Name, numPods+1 /* driver */, f.Timeouts.PodStartSlow)) + framework.ExpectNoError(e2epod.WaitForPodsRunning(ctx, b.f.ClientSet, f.Namespace.Name, numPods+len(nodes.NodeNames) /* driver(s) */, f.Timeouts.PodStartSlow)) }) }) @@ -819,7 +1074,7 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, driver := NewDriver(f, nodes, networkResources) b := newBuilder(f, driver) preScheduledTests(b, driver, resourcev1alpha2.AllocationModeWaitForFirstConsumer) - claimTests(b, driver, resourcev1alpha2.AllocationModeWaitForFirstConsumer, genConfigMapParameters) + claimTests(b, driver, resourcev1alpha2.AllocationModeWaitForFirstConsumer) }) ginkgo.Context("with delayed allocation and not setting ReservedFor", func() { @@ -830,287 +1085,14 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation, }) b := newBuilder(f, driver) preScheduledTests(b, driver, resourcev1alpha2.AllocationModeWaitForFirstConsumer) - claimTests(b, driver, resourcev1alpha2.AllocationModeWaitForFirstConsumer, genConfigMapParameters) + claimTests(b, driver, resourcev1alpha2.AllocationModeWaitForFirstConsumer) }) ginkgo.Context("with immediate allocation", func() { driver := NewDriver(f, nodes, networkResources) b := newBuilder(f, driver) preScheduledTests(b, driver, resourcev1alpha2.AllocationModeImmediate) - claimTests(b, driver, resourcev1alpha2.AllocationModeImmediate, genConfigMapParameters) - }) - }) - - ginkgo.Context("multiple nodes", func() { - nodes := NewNodes(f, 2, 8) - ginkgo.Context("with network-attached resources", func() { - driver := NewDriver(f, nodes, networkResources) - b := newBuilder(f, driver) - - ginkgo.It("schedules onto different nodes", func(ctx context.Context) { - parameters := b.parameters() - label := "app.kubernetes.io/instance" - instance := f.UniqueName + "-test-app" - antiAffinity := &v1.Affinity{ - PodAntiAffinity: &v1.PodAntiAffinity{ - RequiredDuringSchedulingIgnoredDuringExecution: []v1.PodAffinityTerm{ - { - TopologyKey: "kubernetes.io/hostname", - LabelSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - label: instance, - }, - }, - }, - }, - }, - } - createPod := func() *v1.Pod { - pod := b.podExternal() - pod.Labels[label] = instance - pod.Spec.Affinity = antiAffinity - return pod - } - pod1 := createPod() - pod2 := createPod() - claim := b.externalClaim(resourcev1alpha2.AllocationModeWaitForFirstConsumer) - b.create(ctx, parameters, claim, pod1, pod2) - - for _, pod := range []*v1.Pod{pod1, pod2} { - err := e2epod.WaitForPodRunningInNamespace(ctx, f.ClientSet, pod) - framework.ExpectNoError(err, "start pod") - } - }) - - // This test covers aspects of non graceful node shutdown by DRA controller - // More details about this can be found in the KEP: - // https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/2268-non-graceful-shutdown - // NOTE: this test depends on kind. It will only work with kind cluster as it shuts down one of the - // nodes by running `docker stop `, which is very kind-specific. - f.It(f.WithSerial(), f.WithDisruptive(), f.WithSlow(), "must deallocate on non graceful node shutdown", func(ctx context.Context) { - ginkgo.By("create test pod") - parameters := b.parameters() - label := "app.kubernetes.io/instance" - instance := f.UniqueName + "-test-app" - pod := b.podExternal() - pod.Labels[label] = instance - claim := b.externalClaim(resourcev1alpha2.AllocationModeWaitForFirstConsumer) - b.create(ctx, parameters, claim, pod) - - ginkgo.By("wait for test pod " + pod.Name + " to run") - labelSelector := labels.SelectorFromSet(labels.Set(pod.Labels)) - pods, err := e2epod.WaitForPodsWithLabelRunningReady(ctx, f.ClientSet, pod.Namespace, labelSelector, 1, framework.PodStartTimeout) - framework.ExpectNoError(err, "start pod") - runningPod := &pods.Items[0] - - nodeName := runningPod.Spec.NodeName - // Prevent builder tearDown to fail waiting for unprepared resources - delete(b.driver.Nodes, nodeName) - ginkgo.By("stop node " + nodeName + " non gracefully") - _, stderr, err := framework.RunCmd("docker", "stop", nodeName) - gomega.Expect(stderr).To(gomega.BeEmpty()) - framework.ExpectNoError(err) - ginkgo.DeferCleanup(framework.RunCmd, "docker", "start", nodeName) - if ok := e2enode.WaitForNodeToBeNotReady(ctx, f.ClientSet, nodeName, f.Timeouts.NodeNotReady); !ok { - framework.Failf("Node %s failed to enter NotReady state", nodeName) - } - - ginkgo.By("apply out-of-service taint on node " + nodeName) - taint := v1.Taint{ - Key: v1.TaintNodeOutOfService, - Effect: v1.TaintEffectNoExecute, - } - e2enode.AddOrUpdateTaintOnNode(ctx, f.ClientSet, nodeName, taint) - e2enode.ExpectNodeHasTaint(ctx, f.ClientSet, nodeName, &taint) - ginkgo.DeferCleanup(e2enode.RemoveTaintOffNode, f.ClientSet, nodeName, taint) - - ginkgo.By("waiting for claim to get deallocated") - gomega.Eventually(ctx, framework.GetObject(b.f.ClientSet.ResourceV1alpha2().ResourceClaims(b.f.Namespace.Name).Get, claim.Name, metav1.GetOptions{})).WithTimeout(f.Timeouts.PodDelete).Should(gomega.HaveField("Status.Allocation", gomega.BeNil())) - }) - }) - - ginkgo.Context("with node-local resources", func() { - driver := NewDriver(f, nodes, perNode(1, nodes)) - b := newBuilder(f, driver) - - tests := func(allocationMode resourcev1alpha2.AllocationMode) { - ginkgo.It("uses all resources", func(ctx context.Context) { - var objs = []klog.KMetadata{ - b.parameters(), - } - var pods []*v1.Pod - for i := 0; i < len(nodes.NodeNames); i++ { - pod, template := b.podInline(allocationMode) - pods = append(pods, pod) - objs = append(objs, pod, template) - } - b.create(ctx, objs...) - - for _, pod := range pods { - err := e2epod.WaitForPodRunningInNamespace(ctx, f.ClientSet, pod) - framework.ExpectNoError(err, "start pod") - } - - // The pods all should run on different - // nodes because the maximum number of - // claims per node was limited to 1 for - // this test. - // - // We cannot know for sure why the pods - // ran on two different nodes (could - // also be a coincidence) but if they - // don't cover all nodes, then we have - // a problem. - used := make(map[string]*v1.Pod) - for _, pod := range pods { - pod, err := f.ClientSet.CoreV1().Pods(pod.Namespace).Get(ctx, pod.Name, metav1.GetOptions{}) - framework.ExpectNoError(err, "get pod") - nodeName := pod.Spec.NodeName - if other, ok := used[nodeName]; ok { - framework.Failf("Pod %s got started on the same node %s as pod %s although claim allocation should have been limited to one claim per node.", pod.Name, nodeName, other.Name) - } - used[nodeName] = pod - } - }) - } - - ginkgo.Context("with delayed allocation", func() { - tests(resourcev1alpha2.AllocationModeWaitForFirstConsumer) - }) - - ginkgo.Context("with immediate allocation", func() { - tests(resourcev1alpha2.AllocationModeImmediate) - }) - }) - - ginkgo.Context("reallocation", func() { - var allocateWrapper2 app.AllocateWrapperType - driver := NewDriver(f, nodes, perNode(1, nodes)) - driver2 := NewDriver(f, nodes, func() app.Resources { - return app.Resources{ - NodeLocal: true, - MaxAllocations: 1, - Nodes: nodes.NodeNames, - - AllocateWrapper: func( - ctx context.Context, - claimAllocations []*controller.ClaimAllocation, - selectedNode string, - handler func( - ctx context.Context, - claimAllocations []*controller.ClaimAllocation, - selectedNode string), - ) { - allocateWrapper2(ctx, claimAllocations, selectedNode, handler) - return - }, - } - }) - driver2.NameSuffix = "-other" - - b := newBuilder(f, driver) - b2 := newBuilder(f, driver2) - - ginkgo.It("works", func(ctx context.Context) { - // A pod with multiple claims can run on a node, but - // only if allocation of all succeeds. This - // test simulates the scenario where one claim - // gets allocated from one driver, but the claims - // from second driver fail allocation because of a - // race with some other pod. - // - // To ensure the right timing, allocation of the - // claims from second driver are delayed while - // creating another pod that gets the remaining - // resource on the node from second driver. - ctx, cancel := context.WithCancel(ctx) - defer cancel() - - parameters1 := b.parameters() - parameters2 := b2.parameters() - // Order is relevant here: each pod must be matched with its own claim. - pod1claim1 := b.externalClaim(resourcev1alpha2.AllocationModeWaitForFirstConsumer) - pod1 := b.podExternal() - pod2claim1 := b2.externalClaim(resourcev1alpha2.AllocationModeWaitForFirstConsumer) - pod2 := b2.podExternal() - - // Add another claim to pod1. - pod1claim2 := b2.externalClaim(resourcev1alpha2.AllocationModeWaitForFirstConsumer) - pod1.Spec.ResourceClaims = append(pod1.Spec.ResourceClaims, - v1.PodResourceClaim{ - Name: "claim-other", - Source: v1.ClaimSource{ - ResourceClaimName: &pod1claim2.Name, - }, - }, - ) - - // Allocating the second claim in pod1 has to wait until pod2 has - // consumed the available resources on the node. - blockClaim, cancelBlockClaim := context.WithCancel(ctx) - defer cancelBlockClaim() - allocateWrapper2 = func(ctx context.Context, - claimAllocations []*controller.ClaimAllocation, - selectedNode string, - handler func(ctx context.Context, - claimAllocations []*controller.ClaimAllocation, - selectedNode string), - ) { - if claimAllocations[0].Claim.Name == pod1claim2.Name { - <-blockClaim.Done() - } - handler(ctx, claimAllocations, selectedNode) - return - } - - b.create(ctx, parameters1, parameters2, pod1claim1, pod1claim2, pod1) - - ginkgo.By("waiting for one claim from driver1 to be allocated") - var nodeSelector *v1.NodeSelector - gomega.Eventually(ctx, func(ctx context.Context) (int, error) { - claims, err := f.ClientSet.ResourceV1alpha2().ResourceClaims(f.Namespace.Name).List(ctx, metav1.ListOptions{}) - if err != nil { - return 0, err - } - allocated := 0 - for _, claim := range claims.Items { - if claim.Status.Allocation != nil { - allocated++ - nodeSelector = claim.Status.Allocation.AvailableOnNodes - } - } - return allocated, nil - }).WithTimeout(time.Minute).Should(gomega.Equal(1), "one claim allocated") - - // Now create a second pod which we force to - // run on the same node that is currently being - // considered for the first one. We know what - // the node selector looks like and can - // directly access the key and value from it. - ginkgo.By(fmt.Sprintf("create second pod on the same node %s", nodeSelector)) - - req := nodeSelector.NodeSelectorTerms[0].MatchExpressions[0] - node := req.Values[0] - pod2.Spec.NodeSelector = map[string]string{req.Key: node} - - b2.create(ctx, pod2claim1, pod2) - framework.ExpectNoError(e2epod.WaitForPodRunningInNamespace(ctx, f.ClientSet, pod2), "start pod 2") - - // Allow allocation of second claim in pod1 to proceed. It should fail now - // and the other node must be used instead, after deallocating - // the first claim. - ginkgo.By("move first pod to other node") - cancelBlockClaim() - - framework.ExpectNoError(e2epod.WaitForPodRunningInNamespace(ctx, f.ClientSet, pod1), "start pod 1") - pod1, err := f.ClientSet.CoreV1().Pods(pod1.Namespace).Get(ctx, pod1.Name, metav1.GetOptions{}) - framework.ExpectNoError(err, "get first pod") - if pod1.Spec.NodeName == "" { - framework.Fail("first pod should be running on node, was not scheduled") - } - gomega.Expect(pod1.Spec.NodeName).ToNot(gomega.Equal(node), "first pod should run on different node than second one") - gomega.Expect(driver.Controller.GetNumDeallocations()).To(gomega.Equal(int64(1)), "number of deallocations") - }) + claimTests(b, driver, resourcev1alpha2.AllocationModeImmediate) }) }) @@ -1245,6 +1227,40 @@ func (b *builder) externalClaim(allocationMode resourcev1alpha2.AllocationMode) } } +// flexibleParameters returns parameter objects for claims and +// class with their type depending on the current parameter mode. +// It also returns the expected environment in a pod using +// the corresponding resource. +func (b *builder) flexibleParameters() ([]klog.KMetadata, []string) { + var objects []klog.KMetadata + switch b.driver.parameterMode { + case parameterModeConfigMap: + objects = append(objects, + b.parameters("x", "y"), + b.parameters("a", "b", "request_foo", "bar"), + ) + case parameterModeTranslated: + objects = append(objects, + b.parameters("x", "y"), + b.classParameters(b.parametersName(), "x", "y"), + b.parameters("a", "b", "request_foo", "bar"), + b.claimParameters(b.parametersName(), []string{"a", "b"}, []string{"request_foo", "bar"}), + ) + // The parameters object is not the last one but the second-last. + b.parametersCounter-- + case parameterModeStructured: + objects = append(objects, + b.classParameters("", "x", "y"), + b.claimParameters("", []string{"a", "b"}, []string{"request_foo", "bar"}), + ) + } + env := []string{"user_a", "b", "user_request_foo", "bar"} + if b.classParametersName != "" { + env = append(env, "admin_x", "y") + } + return objects, env +} + // parametersName returns the current ConfigMap name for resource // claim or class parameters. func (b *builder) parametersName() string { From 6a361e1f36404e053eadc09e2e23c3ac3e62c8fa Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Thu, 7 Mar 2024 18:44:17 +0100 Subject: [PATCH 18/18] dra api: enable new CEL features by faking their version There are two approaches for making new versioned CEL features available in the release where they get introduced: - Always use the environment for "StoredExpressions". - Use an older version (typically 1.0) and only bump it up later. The second approach was used before, so this is now also done here. --- .../namedresources/validation/validation.go | 14 ++++---------- .../structured/namedresources/cel/compile.go | 7 ++++++- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/pkg/apis/resource/structured/namedresources/validation/validation.go b/pkg/apis/resource/structured/namedresources/validation/validation.go index 92748c4edc8..755507c8e86 100644 --- a/pkg/apis/resource/structured/namedresources/validation/validation.go +++ b/pkg/apis/resource/structured/namedresources/validation/validation.go @@ -149,16 +149,10 @@ func validateSelector(opts Options, selector string, fldPath *field.Path) field. if selector == "" { allErrs = append(allErrs, field.Required(fldPath, "")) } else { - // TODO (https://github.com/kubernetes/kubernetes/issues/123687): - // when this API gets promoted to beta, we have to - // validate new and stored expressions differently. - // While it is alpha, new expressions are allowed to - // use everything that is currently available. - // envType := environment.NewExpressions - // if opts.StoredExpressions { - // envType = environment.StoredExpressions - // } - envType := environment.StoredExpressions + envType := environment.NewExpressions + if opts.StoredExpressions { + envType = environment.StoredExpressions + } result := namedresourcescel.Compiler.CompileCELExpression(selector, envType) if result.Error != nil { allErrs = append(allErrs, convertCELErrorToValidationError(fldPath, selector, result.Error)) diff --git a/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/compile.go b/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/compile.go index b61f1eacd4c..755dcbff10b 100644 --- a/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/compile.go +++ b/staging/src/k8s.io/dynamic-resource-allocation/structured/namedresources/cel/compile.go @@ -187,7 +187,12 @@ func mustBuildEnv() *environment.EnvSet { envset := environment.MustBaseEnvSet(environment.DefaultCompatibilityVersion()) versioned := []environment.VersionedOptions{ { - IntroducedVersion: version.MajorMinor(1, 30), + // Feature epoch was actually 1.30, but we artificially set it to 1.0 because these + // options should always be present. + // + // TODO (https://github.com/kubernetes/kubernetes/issues/123687): set this + // version properly before going to beta. + IntroducedVersion: version.MajorMinor(1, 0), EnvOptions: append(buildVersionedAttributes(), SemverLib(), ),