diff --git a/api/api-rules/violation_exceptions.list b/api/api-rules/violation_exceptions.list index bbb45f218ab4..e1a3ce9833a7 100644 --- a/api/api-rules/violation_exceptions.list +++ b/api/api-rules/violation_exceptions.list @@ -253,6 +253,7 @@ API rule violation: list_type_missing,k8s.io/api/rbac/v1beta1,Role,Rules API rule violation: list_type_missing,k8s.io/api/rbac/v1beta1,RoleBinding,Subjects API rule violation: list_type_missing,k8s.io/api/storage/v1,CSINodeDriver,TopologyKeys API rule violation: list_type_missing,k8s.io/api/storage/v1,CSINodeSpec,Drivers +API rule violation: list_type_missing,k8s.io/api/storage/v1,CSIStorageCapacityList,Items API rule violation: list_type_missing,k8s.io/api/storage/v1,StorageClass,MountOptions API rule violation: list_type_missing,k8s.io/api/storage/v1alpha1,CSIStorageCapacityList,Items API rule violation: list_type_missing,k8s.io/api/storage/v1beta1,CSIDriverSpec,VolumeLifecycleModes diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 337ff9b09d9c..5bd6b97677f5 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -14653,7 +14653,7 @@ "type": "boolean" }, "storageCapacity": { - "description": "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis field was immutable in Kubernetes <= 1.22 and now is mutable.\n\nThis is a beta field and only available when the CSIStorageCapacity feature is enabled. The default is false.", + "description": "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis field was immutable in Kubernetes <= 1.22 and now is mutable.", "type": "boolean" }, "tokenRequests": { @@ -14789,6 +14789,89 @@ ], "type": "object" }, + "io.k8s.api.storage.v1.CSIStorageCapacity": { + "description": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler when a CSI driver opts into capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler compares the MaximumVolumeSize against the requested size of pending volumes to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back to a comparison against the less precise Capacity. If that is also unset, the scheduler assumes that capacity is insufficient and tries some other node.", + "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" + }, + "capacity": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.api.resource.Quantity", + "description": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable." + }, + "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" + }, + "maximumVolumeSize": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.api.resource.Quantity", + "description": "MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThis is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim." + }, + "metadata": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta", + "description": "Standard object's metadata. The name has no particular meaning. It must be be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name.\n\nObjects are namespaced.\n\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" + }, + "nodeTopology": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector", + "description": "NodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable." + }, + "storageClassName": { + "description": "The name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.", + "type": "string" + } + }, + "required": [ + "storageClassName" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "storage.k8s.io", + "kind": "CSIStorageCapacity", + "version": "v1" + } + ] + }, + "io.k8s.api.storage.v1.CSIStorageCapacityList": { + "description": "CSIStorageCapacityList is a collection of CSIStorageCapacity objects.", + "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 CSIStorageCapacity objects.", + "items": { + "$ref": "#/definitions/io.k8s.api.storage.v1.CSIStorageCapacity" + }, + "type": "array", + "x-kubernetes-list-map-keys": [ + "name" + ], + "x-kubernetes-list-type": "map" + }, + "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 More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" + } + }, + "required": [ + "items" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "storage.k8s.io", + "kind": "CSIStorageCapacityList", + "version": "v1" + } + ] + }, "io.k8s.api.storage.v1.StorageClass": { "description": "StorageClass describes the parameters for a class of storage for which PersistentVolumes can be dynamically provisioned.\n\nStorageClasses are non-namespaced; the name of the storage class according to etcd is in ObjectMeta.Name.", "properties": { @@ -15070,7 +15153,7 @@ "type": "object" }, "io.k8s.api.storage.v1alpha1.CSIStorageCapacity": { - "description": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler if the CSIStorageCapacity beta feature gate is enabled there and a CSI driver opts into capacity-aware scheduling with CSIDriver.StorageCapacity.", + "description": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler when a CSI driver opts into capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler compares the MaximumVolumeSize against the requested size of pending volumes to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back to a comparison against the less precise Capacity. If that is also unset, the scheduler assumes that capacity is insufficient and tries some other node.", "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", @@ -15078,7 +15161,7 @@ }, "capacity": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.api.resource.Quantity", - "description": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable and treated like zero capacity." + "description": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable." }, "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", @@ -15153,7 +15236,7 @@ ] }, "io.k8s.api.storage.v1beta1.CSIStorageCapacity": { - "description": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler if the CSIStorageCapacity beta feature gate is enabled there and a CSI driver opts into capacity-aware scheduling with CSIDriver.StorageCapacity.", + "description": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler when a CSI driver opts into capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler compares the MaximumVolumeSize against the requested size of pending volumes to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back to a comparison against the less precise Capacity. If that is also unset, the scheduler assumes that capacity is insufficient and tries some other node.", "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", @@ -15161,7 +15244,7 @@ }, "capacity": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.api.resource.Quantity", - "description": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable and treated like zero capacity." + "description": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable." }, "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", @@ -85430,13 +85513,124 @@ } } }, - "/apis/storage.k8s.io/v1/storageclasses": { + "/apis/storage.k8s.io/v1/csistoragecapacities": { + "get": { + "consumes": [ + "*/*" + ], + "description": "list or watch objects of kind CSIStorageCapacity", + "operationId": "listStorageV1CSIStorageCapacityForAllNamespaces", + "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.storage.v1.CSIStorageCapacityList" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "storage_v1" + ], + "x-kubernetes-action": "list", + "x-kubernetes-group-version-kind": { + "group": "storage.k8s.io", + "kind": "CSIStorageCapacity", + "version": "v1" + } + }, + "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", + "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", + "type": "string", + "uniqueItems": true + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "type": "string", + "uniqueItems": true + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "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", + "type": "integer", + "uniqueItems": true + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "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", + "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", + "type": "string", + "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", + "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", + "type": "boolean", + "uniqueItems": true + } + ] + }, + "/apis/storage.k8s.io/v1/namespaces/{namespace}/csistoragecapacities": { "delete": { "consumes": [ "*/*" ], - "description": "delete collection of StorageClass", - "operationId": "deleteStorageV1CollectionStorageClass", + "description": "delete collection of CSIStorageCapacity", + "operationId": "deleteStorageV1CollectionNamespacedCSIStorageCapacity", "parameters": [ { "in": "body", @@ -85548,7 +85742,7 @@ "x-kubernetes-action": "deletecollection", "x-kubernetes-group-version-kind": { "group": "storage.k8s.io", - "kind": "StorageClass", + "kind": "CSIStorageCapacity", "version": "v1" } }, @@ -85556,8 +85750,8 @@ "consumes": [ "*/*" ], - "description": "list or watch objects of kind StorageClass", - "operationId": "listStorageV1StorageClass", + "description": "list or watch objects of kind CSIStorageCapacity", + "operationId": "listStorageV1NamespacedCSIStorageCapacity", "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.", @@ -85634,7 +85828,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClassList" + "$ref": "#/definitions/io.k8s.api.storage.v1.CSIStorageCapacityList" } }, "401": { @@ -85650,11 +85844,19 @@ "x-kubernetes-action": "list", "x-kubernetes-group-version-kind": { "group": "storage.k8s.io", - "kind": "StorageClass", + "kind": "CSIStorageCapacity", "version": "v1" } }, "parameters": [ + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "type": "string", + "uniqueItems": true + }, { "description": "If 'true', then the output is pretty printed.", "in": "query", @@ -85667,15 +85869,15 @@ "consumes": [ "*/*" ], - "description": "create a StorageClass", - "operationId": "createStorageV1StorageClass", + "description": "create a CSIStorageCapacity", + "operationId": "createStorageV1NamespacedCSIStorageCapacity", "parameters": [ { "in": "body", "name": "body", "required": true, "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/definitions/io.k8s.api.storage.v1.CSIStorageCapacity" } }, { @@ -85709,19 +85911,19 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/definitions/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "201": { "description": "Created", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/definitions/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "202": { "description": "Accepted", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/definitions/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "401": { @@ -85737,18 +85939,18 @@ "x-kubernetes-action": "post", "x-kubernetes-group-version-kind": { "group": "storage.k8s.io", - "kind": "StorageClass", + "kind": "CSIStorageCapacity", "version": "v1" } } }, - "/apis/storage.k8s.io/v1/storageclasses/{name}": { + "/apis/storage.k8s.io/v1/namespaces/{namespace}/csistoragecapacities/{name}": { "delete": { "consumes": [ "*/*" ], - "description": "delete a StorageClass", - "operationId": "deleteStorageV1StorageClass", + "description": "delete a CSIStorageCapacity", + "operationId": "deleteStorageV1NamespacedCSIStorageCapacity", "parameters": [ { "in": "body", @@ -85795,13 +85997,13 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" } }, "202": { "description": "Accepted", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" } }, "401": { @@ -85817,7 +86019,7 @@ "x-kubernetes-action": "delete", "x-kubernetes-group-version-kind": { "group": "storage.k8s.io", - "kind": "StorageClass", + "kind": "CSIStorageCapacity", "version": "v1" } }, @@ -85825,8 +86027,8 @@ "consumes": [ "*/*" ], - "description": "read the specified StorageClass", - "operationId": "readStorageV1StorageClass", + "description": "read the specified CSIStorageCapacity", + "operationId": "readStorageV1NamespacedCSIStorageCapacity", "produces": [ "application/json", "application/yaml", @@ -85836,7 +86038,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/definitions/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "401": { @@ -85852,19 +86054,27 @@ "x-kubernetes-action": "get", "x-kubernetes-group-version-kind": { "group": "storage.k8s.io", - "kind": "StorageClass", + "kind": "CSIStorageCapacity", "version": "v1" } }, "parameters": [ { - "description": "name of the StorageClass", + "description": "name of the CSIStorageCapacity", "in": "path", "name": "name", "required": true, "type": "string", "uniqueItems": true }, + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "type": "string", + "uniqueItems": true + }, { "description": "If 'true', then the output is pretty printed.", "in": "query", @@ -85880,8 +86090,8 @@ "application/strategic-merge-patch+json", "application/apply-patch+yaml" ], - "description": "partially update the specified StorageClass", - "operationId": "patchStorageV1StorageClass", + "description": "partially update the specified CSIStorageCapacity", + "operationId": "patchStorageV1NamespacedCSIStorageCapacity", "parameters": [ { "in": "body", @@ -85929,13 +86139,13 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/definitions/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "201": { "description": "Created", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/definitions/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "401": { @@ -85951,7 +86161,7 @@ "x-kubernetes-action": "patch", "x-kubernetes-group-version-kind": { "group": "storage.k8s.io", - "kind": "StorageClass", + "kind": "CSIStorageCapacity", "version": "v1" } }, @@ -85959,15 +86169,15 @@ "consumes": [ "*/*" ], - "description": "replace the specified StorageClass", - "operationId": "replaceStorageV1StorageClass", + "description": "replace the specified CSIStorageCapacity", + "operationId": "replaceStorageV1NamespacedCSIStorageCapacity", "parameters": [ { "in": "body", "name": "body", "required": true, "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/definitions/io.k8s.api.storage.v1.CSIStorageCapacity" } }, { @@ -86001,13 +86211,13 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/definitions/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "201": { "description": "Created", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/definitions/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "401": { @@ -86023,18 +86233,18 @@ "x-kubernetes-action": "put", "x-kubernetes-group-version-kind": { "group": "storage.k8s.io", - "kind": "StorageClass", + "kind": "CSIStorageCapacity", "version": "v1" } } }, - "/apis/storage.k8s.io/v1/volumeattachments": { + "/apis/storage.k8s.io/v1/storageclasses": { "delete": { "consumes": [ "*/*" ], - "description": "delete collection of VolumeAttachment", - "operationId": "deleteStorageV1CollectionVolumeAttachment", + "description": "delete collection of StorageClass", + "operationId": "deleteStorageV1CollectionStorageClass", "parameters": [ { "in": "body", @@ -86146,7 +86356,7 @@ "x-kubernetes-action": "deletecollection", "x-kubernetes-group-version-kind": { "group": "storage.k8s.io", - "kind": "VolumeAttachment", + "kind": "StorageClass", "version": "v1" } }, @@ -86154,8 +86364,8 @@ "consumes": [ "*/*" ], - "description": "list or watch objects of kind VolumeAttachment", - "operationId": "listStorageV1VolumeAttachment", + "description": "list or watch objects of kind StorageClass", + "operationId": "listStorageV1StorageClass", "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.", @@ -86232,7 +86442,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachmentList" + "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClassList" } }, "401": { @@ -86248,7 +86458,7 @@ "x-kubernetes-action": "list", "x-kubernetes-group-version-kind": { "group": "storage.k8s.io", - "kind": "VolumeAttachment", + "kind": "StorageClass", "version": "v1" } }, @@ -86265,15 +86475,15 @@ "consumes": [ "*/*" ], - "description": "create a VolumeAttachment", - "operationId": "createStorageV1VolumeAttachment", + "description": "create a StorageClass", + "operationId": "createStorageV1StorageClass", "parameters": [ { "in": "body", "name": "body", "required": true, "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" } }, { @@ -86307,19 +86517,19 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" } }, "201": { "description": "Created", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" } }, "202": { "description": "Accepted", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" } }, "401": { @@ -86335,18 +86545,18 @@ "x-kubernetes-action": "post", "x-kubernetes-group-version-kind": { "group": "storage.k8s.io", - "kind": "VolumeAttachment", + "kind": "StorageClass", "version": "v1" } } }, - "/apis/storage.k8s.io/v1/volumeattachments/{name}": { + "/apis/storage.k8s.io/v1/storageclasses/{name}": { "delete": { "consumes": [ "*/*" ], - "description": "delete a VolumeAttachment", - "operationId": "deleteStorageV1VolumeAttachment", + "description": "delete a StorageClass", + "operationId": "deleteStorageV1StorageClass", "parameters": [ { "in": "body", @@ -86393,13 +86603,13 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" } }, "202": { "description": "Accepted", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" } }, "401": { @@ -86415,7 +86625,7 @@ "x-kubernetes-action": "delete", "x-kubernetes-group-version-kind": { "group": "storage.k8s.io", - "kind": "VolumeAttachment", + "kind": "StorageClass", "version": "v1" } }, @@ -86423,8 +86633,8 @@ "consumes": [ "*/*" ], - "description": "read the specified VolumeAttachment", - "operationId": "readStorageV1VolumeAttachment", + "description": "read the specified StorageClass", + "operationId": "readStorageV1StorageClass", "produces": [ "application/json", "application/yaml", @@ -86434,7 +86644,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" } }, "401": { @@ -86450,13 +86660,13 @@ "x-kubernetes-action": "get", "x-kubernetes-group-version-kind": { "group": "storage.k8s.io", - "kind": "VolumeAttachment", + "kind": "StorageClass", "version": "v1" } }, "parameters": [ { - "description": "name of the VolumeAttachment", + "description": "name of the StorageClass", "in": "path", "name": "name", "required": true, @@ -86478,8 +86688,8 @@ "application/strategic-merge-patch+json", "application/apply-patch+yaml" ], - "description": "partially update the specified VolumeAttachment", - "operationId": "patchStorageV1VolumeAttachment", + "description": "partially update the specified StorageClass", + "operationId": "patchStorageV1StorageClass", "parameters": [ { "in": "body", @@ -86527,13 +86737,13 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" } }, "201": { "description": "Created", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" } }, "401": { @@ -86549,7 +86759,7 @@ "x-kubernetes-action": "patch", "x-kubernetes-group-version-kind": { "group": "storage.k8s.io", - "kind": "VolumeAttachment", + "kind": "StorageClass", "version": "v1" } }, @@ -86557,15 +86767,15 @@ "consumes": [ "*/*" ], - "description": "replace the specified VolumeAttachment", - "operationId": "replaceStorageV1VolumeAttachment", + "description": "replace the specified StorageClass", + "operationId": "replaceStorageV1StorageClass", "parameters": [ { "in": "body", "name": "body", "required": true, "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" } }, { @@ -86599,13 +86809,13 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" } }, "201": { "description": "Created", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/definitions/io.k8s.api.storage.v1.StorageClass" } }, "401": { @@ -86621,18 +86831,104 @@ "x-kubernetes-action": "put", "x-kubernetes-group-version-kind": { "group": "storage.k8s.io", - "kind": "VolumeAttachment", + "kind": "StorageClass", "version": "v1" } } }, - "/apis/storage.k8s.io/v1/volumeattachments/{name}/status": { - "get": { + "/apis/storage.k8s.io/v1/volumeattachments": { + "delete": { "consumes": [ "*/*" ], - "description": "read status of the specified VolumeAttachment", - "operationId": "readStorageV1VolumeAttachmentStatus", + "description": "delete collection of VolumeAttachment", + "operationId": "deleteStorageV1CollectionVolumeAttachment", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + }, + { + "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", + "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", + "type": "string", + "uniqueItems": true + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "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", + "type": "integer", + "uniqueItems": true + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "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", + "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", + "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", + "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", + "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", + "type": "string", + "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", + "type": "integer", + "uniqueItems": true + } + ], "produces": [ "application/json", "application/yaml", @@ -86642,7 +86938,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" } }, "401": { @@ -86655,73 +86951,80 @@ "tags": [ "storage_v1" ], - "x-kubernetes-action": "get", + "x-kubernetes-action": "deletecollection", "x-kubernetes-group-version-kind": { "group": "storage.k8s.io", "kind": "VolumeAttachment", "version": "v1" } }, - "parameters": [ - { - "description": "name of the VolumeAttachment", - "in": "path", - "name": "name", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - } - ], - "patch": { + "get": { "consumes": [ - "application/json-patch+json", - "application/merge-patch+json", - "application/strategic-merge-patch+json", - "application/apply-patch+yaml" + "*/*" ], - "description": "partially update status of the specified VolumeAttachment", - "operationId": "patchStorageV1VolumeAttachmentStatus", + "description": "list or watch objects of kind VolumeAttachment", + "operationId": "listStorageV1VolumeAttachment", "parameters": [ { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" - } + "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", + "type": "boolean", + "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", + "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": "dryRun", + "name": "continue", "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).", + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", "in": "query", - "name": "fieldManager", + "name": "fieldSelector", "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, provided that the `ServerSideFieldValidation` feature gate is also enabled. 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 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - 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 when the `ServerSideFieldValidation` feature gate is enabled. - 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.", + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", - "name": "fieldValidation", + "name": "labelSelector", "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.", + "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": "force", + "name": "limit", + "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", + "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", + "type": "string", + "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", + "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", "type": "boolean", "uniqueItems": true } @@ -86729,19 +87032,15 @@ "produces": [ "application/json", "application/yaml", - "application/vnd.kubernetes.protobuf" + "application/vnd.kubernetes.protobuf", + "application/json;stream=watch", + "application/vnd.kubernetes.protobuf;stream=watch" ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachmentList" } }, "401": { @@ -86754,19 +87053,528 @@ "tags": [ "storage_v1" ], - "x-kubernetes-action": "patch", + "x-kubernetes-action": "list", "x-kubernetes-group-version-kind": { "group": "storage.k8s.io", "kind": "VolumeAttachment", "version": "v1" } }, - "put": { + "parameters": [ + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "type": "string", + "uniqueItems": true + } + ], + "post": { "consumes": [ "*/*" ], - "description": "replace status of the specified VolumeAttachment", - "operationId": "replaceStorageV1VolumeAttachmentStatus", + "description": "create a VolumeAttachment", + "operationId": "createStorageV1VolumeAttachment", + "parameters": [ + { + "in": "body", + "name": "body", + "required": true, + "schema": { + "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + { + "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 + }, + { + "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", + "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, provided that the `ServerSideFieldValidation` feature gate is also enabled. 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 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - 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 when the `ServerSideFieldValidation` feature gate is enabled. - 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.storage.v1.VolumeAttachment" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "202": { + "description": "Accepted", + "schema": { + "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "storage_v1" + ], + "x-kubernetes-action": "post", + "x-kubernetes-group-version-kind": { + "group": "storage.k8s.io", + "kind": "VolumeAttachment", + "version": "v1" + } + } + }, + "/apis/storage.k8s.io/v1/volumeattachments/{name}": { + "delete": { + "consumes": [ + "*/*" + ], + "description": "delete a VolumeAttachment", + "operationId": "deleteStorageV1VolumeAttachment", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + }, + { + "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 + }, + { + "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", + "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", + "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", + "type": "string", + "uniqueItems": true + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "202": { + "description": "Accepted", + "schema": { + "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "storage_v1" + ], + "x-kubernetes-action": "delete", + "x-kubernetes-group-version-kind": { + "group": "storage.k8s.io", + "kind": "VolumeAttachment", + "version": "v1" + } + }, + "get": { + "consumes": [ + "*/*" + ], + "description": "read the specified VolumeAttachment", + "operationId": "readStorageV1VolumeAttachment", + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "storage_v1" + ], + "x-kubernetes-action": "get", + "x-kubernetes-group-version-kind": { + "group": "storage.k8s.io", + "kind": "VolumeAttachment", + "version": "v1" + } + }, + "parameters": [ + { + "description": "name of the VolumeAttachment", + "in": "path", + "name": "name", + "required": true, + "type": "string", + "uniqueItems": true + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "type": "string", + "uniqueItems": true + } + ], + "patch": { + "consumes": [ + "application/json-patch+json", + "application/merge-patch+json", + "application/strategic-merge-patch+json", + "application/apply-patch+yaml" + ], + "description": "partially update the specified VolumeAttachment", + "operationId": "patchStorageV1VolumeAttachment", + "parameters": [ + { + "in": "body", + "name": "body", + "required": true, + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + { + "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 + }, + { + "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", + "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, provided that the `ServerSideFieldValidation` feature gate is also enabled. 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 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - 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 when the `ServerSideFieldValidation` feature gate is enabled. - 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 + }, + { + "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", + "type": "boolean", + "uniqueItems": true + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "storage_v1" + ], + "x-kubernetes-action": "patch", + "x-kubernetes-group-version-kind": { + "group": "storage.k8s.io", + "kind": "VolumeAttachment", + "version": "v1" + } + }, + "put": { + "consumes": [ + "*/*" + ], + "description": "replace the specified VolumeAttachment", + "operationId": "replaceStorageV1VolumeAttachment", + "parameters": [ + { + "in": "body", + "name": "body", + "required": true, + "schema": { + "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + { + "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 + }, + { + "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", + "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, provided that the `ServerSideFieldValidation` feature gate is also enabled. 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 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - 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 when the `ServerSideFieldValidation` feature gate is enabled. - 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.storage.v1.VolumeAttachment" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "storage_v1" + ], + "x-kubernetes-action": "put", + "x-kubernetes-group-version-kind": { + "group": "storage.k8s.io", + "kind": "VolumeAttachment", + "version": "v1" + } + } + }, + "/apis/storage.k8s.io/v1/volumeattachments/{name}/status": { + "get": { + "consumes": [ + "*/*" + ], + "description": "read status of the specified VolumeAttachment", + "operationId": "readStorageV1VolumeAttachmentStatus", + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "storage_v1" + ], + "x-kubernetes-action": "get", + "x-kubernetes-group-version-kind": { + "group": "storage.k8s.io", + "kind": "VolumeAttachment", + "version": "v1" + } + }, + "parameters": [ + { + "description": "name of the VolumeAttachment", + "in": "path", + "name": "name", + "required": true, + "type": "string", + "uniqueItems": true + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "type": "string", + "uniqueItems": true + } + ], + "patch": { + "consumes": [ + "application/json-patch+json", + "application/merge-patch+json", + "application/strategic-merge-patch+json", + "application/apply-patch+yaml" + ], + "description": "partially update status of the specified VolumeAttachment", + "operationId": "patchStorageV1VolumeAttachmentStatus", + "parameters": [ + { + "in": "body", + "name": "body", + "required": true, + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + { + "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 + }, + { + "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", + "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, provided that the `ServerSideFieldValidation` feature gate is also enabled. 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 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - 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 when the `ServerSideFieldValidation` feature gate is enabled. - 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 + }, + { + "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", + "type": "boolean", + "uniqueItems": true + } + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "401": { + "description": "Unauthorized" + } + }, + "schemes": [ + "https" + ], + "tags": [ + "storage_v1" + ], + "x-kubernetes-action": "patch", + "x-kubernetes-group-version-kind": { + "group": "storage.k8s.io", + "kind": "VolumeAttachment", + "version": "v1" + } + }, + "put": { + "consumes": [ + "*/*" + ], + "description": "replace status of the specified VolumeAttachment", + "operationId": "replaceStorageV1VolumeAttachmentStatus", "parameters": [ { "in": "body", @@ -87294,6 +88102,363 @@ } ] }, + "/apis/storage.k8s.io/v1/watch/csistoragecapacities": { + "get": { + "consumes": [ + "*/*" + ], + "description": "watch individual changes to a list of CSIStorageCapacity. deprecated: use the 'watch' parameter with a list operation instead.", + "operationId": "watchStorageV1CSIStorageCapacityListForAllNamespaces", + "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": [ + "storage_v1" + ], + "x-kubernetes-action": "watchlist", + "x-kubernetes-group-version-kind": { + "group": "storage.k8s.io", + "kind": "CSIStorageCapacity", + "version": "v1" + } + }, + "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", + "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", + "type": "string", + "uniqueItems": true + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "type": "string", + "uniqueItems": true + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "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", + "type": "integer", + "uniqueItems": true + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "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", + "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", + "type": "string", + "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", + "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", + "type": "boolean", + "uniqueItems": true + } + ] + }, + "/apis/storage.k8s.io/v1/watch/namespaces/{namespace}/csistoragecapacities": { + "get": { + "consumes": [ + "*/*" + ], + "description": "watch individual changes to a list of CSIStorageCapacity. deprecated: use the 'watch' parameter with a list operation instead.", + "operationId": "watchStorageV1NamespacedCSIStorageCapacityList", + "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": [ + "storage_v1" + ], + "x-kubernetes-action": "watchlist", + "x-kubernetes-group-version-kind": { + "group": "storage.k8s.io", + "kind": "CSIStorageCapacity", + "version": "v1" + } + }, + "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", + "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", + "type": "string", + "uniqueItems": true + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "type": "string", + "uniqueItems": true + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "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", + "type": "integer", + "uniqueItems": true + }, + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "type": "string", + "uniqueItems": true + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "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", + "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", + "type": "string", + "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", + "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", + "type": "boolean", + "uniqueItems": true + } + ] + }, + "/apis/storage.k8s.io/v1/watch/namespaces/{namespace}/csistoragecapacities/{name}": { + "get": { + "consumes": [ + "*/*" + ], + "description": "watch changes to an object of kind CSIStorageCapacity. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", + "operationId": "watchStorageV1NamespacedCSIStorageCapacity", + "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": [ + "storage_v1" + ], + "x-kubernetes-action": "watch", + "x-kubernetes-group-version-kind": { + "group": "storage.k8s.io", + "kind": "CSIStorageCapacity", + "version": "v1" + } + }, + "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", + "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", + "type": "string", + "uniqueItems": true + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "type": "string", + "uniqueItems": true + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "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", + "type": "integer", + "uniqueItems": true + }, + { + "description": "name of the CSIStorageCapacity", + "in": "path", + "name": "name", + "required": true, + "type": "string", + "uniqueItems": true + }, + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "type": "string", + "uniqueItems": true + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "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", + "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", + "type": "string", + "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", + "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", + "type": "boolean", + "uniqueItems": true + } + ] + }, "/apis/storage.k8s.io/v1/watch/storageclasses": { "get": { "consumes": [ diff --git a/api/openapi-spec/v3/apis__storage.k8s.io__v1_openapi.json b/api/openapi-spec/v3/apis__storage.k8s.io__v1_openapi.json index c4826883a639..cc079f870749 100644 --- a/api/openapi-spec/v3/apis__storage.k8s.io__v1_openapi.json +++ b/api/openapi-spec/v3/apis__storage.k8s.io__v1_openapi.json @@ -1105,7 +1105,7 @@ "type": "boolean" }, "storageCapacity": { - "description": "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis field was immutable in Kubernetes <= 1.22 and now is mutable.\n\nThis is a beta field and only available when the CSIStorageCapacity feature is enabled. The default is false.", + "description": "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis field was immutable in Kubernetes <= 1.22 and now is mutable.", "type": "boolean" }, "tokenRequests": { @@ -1251,6 +1251,93 @@ ], "type": "object" }, + "io.k8s.api.storage.v1.CSIStorageCapacity": { + "description": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler when a CSI driver opts into capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler compares the MaximumVolumeSize against the requested size of pending volumes to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back to a comparison against the less precise Capacity. If that is also unset, the scheduler assumes that capacity is insufficient and tries some other node.", + "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" + }, + "capacity": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.api.resource.Quantity", + "description": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable." + }, + "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" + }, + "maximumVolumeSize": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.api.resource.Quantity", + "description": "MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThis is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim." + }, + "metadata": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta", + "default": {}, + "description": "Standard object's metadata. The name has no particular meaning. It must be be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name.\n\nObjects are namespaced.\n\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" + }, + "nodeTopology": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector", + "description": "NodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable." + }, + "storageClassName": { + "default": "", + "description": "The name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.", + "type": "string" + } + }, + "required": [ + "storageClassName" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "storage.k8s.io", + "kind": "CSIStorageCapacity", + "version": "v1" + } + ] + }, + "io.k8s.api.storage.v1.CSIStorageCapacityList": { + "description": "CSIStorageCapacityList is a collection of CSIStorageCapacity objects.", + "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 CSIStorageCapacity objects.", + "items": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity", + "default": {} + }, + "type": "array", + "x-kubernetes-list-map-keys": [ + "name" + ], + "x-kubernetes-list-type": "map" + }, + "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": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta", + "default": {}, + "description": "Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" + } + }, + "required": [ + "items" + ], + "type": "object", + "x-kubernetes-group-version-kind": [ + { + "group": "storage.k8s.io", + "kind": "CSIStorageCapacityList", + "version": "v1" + } + ] + }, "io.k8s.api.storage.v1.StorageClass": { "description": "StorageClass describes the parameters for a class of storage for which PersistentVolumes can be dynamically provisioned.\n\nStorageClasses are non-namespaced; the name of the storage class according to etcd is in ObjectMeta.Name.", "properties": { @@ -1966,6 +2053,59 @@ "description": "FieldsV1 stores a set of fields in a data structure like a Trie, in JSON format.\n\nEach key is either a '.' representing the field itself, and will always map to an empty set, or a string representing a sub-field or item. The string will follow one of these four formats: 'f:', where is the name of a field in a struct, or key in a map 'v:', where is the exact json formatted value of a list item 'i:', where is position of a item in a list 'k:', where is a map of a list item's key fields to their unique values If a key maps to an empty Fields value, the field that key represents is part of the set.\n\nThe exact format is defined in sigs.k8s.io/structured-merge-diff", "type": "object" }, + "io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector": { + "description": "A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. An empty label selector matches all objects. A null label selector matches no objects.", + "properties": { + "matchExpressions": { + "description": "matchExpressions is a list of label selector requirements. The requirements are ANDed.", + "items": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelectorRequirement", + "default": {} + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "default": "", + "type": "string" + }, + "description": "matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is \"key\", the operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.", + "type": "object" + } + }, + "type": "object", + "x-kubernetes-map-type": "atomic" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelectorRequirement": { + "description": "A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.", + "properties": { + "key": { + "default": "", + "description": "key is the label key that the selector applies to.", + "type": "string", + "x-kubernetes-patch-merge-key": "key", + "x-kubernetes-patch-strategy": "merge" + }, + "operator": { + "default": "", + "description": "operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.", + "type": "string" + }, + "values": { + "description": "values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.", + "items": { + "default": "", + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "key", + "operator" + ], + "type": "object" + }, "io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta": { "description": "ListMeta describes metadata that synthetic resources must have, including lists and various status objects. A resource may have only one of {ObjectMeta, ListMeta}.", "properties": { @@ -4031,10 +4171,143 @@ ] } }, - "/apis/storage.k8s.io/v1/storageclasses": { + "/apis/storage.k8s.io/v1/csistoragecapacities": { + "get": { + "description": "list or watch objects of kind CSIStorageCapacity", + "operationId": "listStorageV1CSIStorageCapacityForAllNamespaces", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacityList" + } + }, + "application/json;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacityList" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacityList" + } + }, + "application/vnd.kubernetes.protobuf;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacityList" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacityList" + } + } + }, + "description": "OK" + } + }, + "tags": [ + "storage_v1" + ] + }, + "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.", + "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": "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/storage.k8s.io/v1/namespaces/{namespace}/csistoragecapacities": { "delete": { - "description": "delete collection of StorageClass", - "operationId": "deleteStorageV1CollectionStorageClass", + "description": "delete collection of CSIStorageCapacity", + "operationId": "deleteStorageV1CollectionNamespacedCSIStorageCapacity", "parameters": [ { "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.", @@ -4172,8 +4445,8 @@ ] }, "get": { - "description": "list or watch objects of kind StorageClass", - "operationId": "listStorageV1StorageClass", + "description": "list or watch objects of kind CSIStorageCapacity", + "operationId": "listStorageV1NamespacedCSIStorageCapacity", "parameters": [ { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", @@ -4262,27 +4535,27 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClassList" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacityList" } }, "application/json;stream=watch": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClassList" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacityList" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClassList" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacityList" } }, "application/vnd.kubernetes.protobuf;stream=watch": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClassList" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacityList" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClassList" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacityList" } } }, @@ -4294,6 +4567,16 @@ ] }, "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.", "in": "query", @@ -4305,8 +4588,8 @@ } ], "post": { - "description": "create a StorageClass", - "operationId": "createStorageV1StorageClass", + "description": "create a CSIStorageCapacity", + "operationId": "createStorageV1NamespacedCSIStorageCapacity", "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", @@ -4340,7 +4623,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } } } @@ -4350,17 +4633,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } } }, @@ -4370,17 +4653,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } } }, @@ -4390,17 +4673,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } } }, @@ -4412,10 +4695,10 @@ ] } }, - "/apis/storage.k8s.io/v1/storageclasses/{name}": { + "/apis/storage.k8s.io/v1/namespaces/{namespace}/csistoragecapacities/{name}": { "delete": { - "description": "delete a StorageClass", - "operationId": "deleteStorageV1StorageClass", + "description": "delete a CSIStorageCapacity", + "operationId": "deleteStorageV1NamespacedCSIStorageCapacity", "parameters": [ { "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.", @@ -4468,17 +4751,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" } } }, @@ -4488,17 +4771,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" } } }, @@ -4510,24 +4793,24 @@ ] }, "get": { - "description": "read the specified StorageClass", - "operationId": "readStorageV1StorageClass", + "description": "read the specified CSIStorageCapacity", + "operationId": "readStorageV1NamespacedCSIStorageCapacity", "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } } }, @@ -4540,7 +4823,7 @@ }, "parameters": [ { - "description": "name of the StorageClass", + "description": "name of the CSIStorageCapacity", "in": "path", "name": "name", "required": true, @@ -4549,6 +4832,16 @@ "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.", "in": "query", @@ -4560,8 +4853,8 @@ } ], "patch": { - "description": "partially update the specified StorageClass", - "operationId": "patchStorageV1StorageClass", + "description": "partially update the specified CSIStorageCapacity", + "operationId": "patchStorageV1NamespacedCSIStorageCapacity", "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", @@ -4614,17 +4907,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } } }, @@ -4634,17 +4927,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } } }, @@ -4656,8 +4949,8 @@ ] }, "put": { - "description": "replace the specified StorageClass", - "operationId": "replaceStorageV1StorageClass", + "description": "replace the specified CSIStorageCapacity", + "operationId": "replaceStorageV1NamespacedCSIStorageCapacity", "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", @@ -4691,7 +4984,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } } } @@ -4701,17 +4994,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } } }, @@ -4721,17 +5014,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.CSIStorageCapacity" } } }, @@ -4743,10 +5036,10 @@ ] } }, - "/apis/storage.k8s.io/v1/volumeattachments": { + "/apis/storage.k8s.io/v1/storageclasses": { "delete": { - "description": "delete collection of VolumeAttachment", - "operationId": "deleteStorageV1CollectionVolumeAttachment", + "description": "delete collection of StorageClass", + "operationId": "deleteStorageV1CollectionStorageClass", "parameters": [ { "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.", @@ -4884,8 +5177,8 @@ ] }, "get": { - "description": "list or watch objects of kind VolumeAttachment", - "operationId": "listStorageV1VolumeAttachment", + "description": "list or watch objects of kind StorageClass", + "operationId": "listStorageV1StorageClass", "parameters": [ { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", @@ -4974,27 +5267,27 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachmentList" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClassList" } }, "application/json;stream=watch": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachmentList" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClassList" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachmentList" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClassList" } }, "application/vnd.kubernetes.protobuf;stream=watch": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachmentList" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClassList" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachmentList" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClassList" } } }, @@ -5017,8 +5310,8 @@ } ], "post": { - "description": "create a VolumeAttachment", - "operationId": "createStorageV1VolumeAttachment", + "description": "create a StorageClass", + "operationId": "createStorageV1StorageClass", "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", @@ -5052,7 +5345,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } } } @@ -5062,17 +5355,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } } }, @@ -5082,17 +5375,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } } }, @@ -5102,17 +5395,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } } }, @@ -5124,10 +5417,10 @@ ] } }, - "/apis/storage.k8s.io/v1/volumeattachments/{name}": { + "/apis/storage.k8s.io/v1/storageclasses/{name}": { "delete": { - "description": "delete a VolumeAttachment", - "operationId": "deleteStorageV1VolumeAttachment", + "description": "delete a StorageClass", + "operationId": "deleteStorageV1StorageClass", "parameters": [ { "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.", @@ -5180,17 +5473,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } } }, @@ -5200,17 +5493,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } } }, @@ -5222,24 +5515,24 @@ ] }, "get": { - "description": "read the specified VolumeAttachment", - "operationId": "readStorageV1VolumeAttachment", + "description": "read the specified StorageClass", + "operationId": "readStorageV1StorageClass", "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } } }, @@ -5252,7 +5545,7 @@ }, "parameters": [ { - "description": "name of the VolumeAttachment", + "description": "name of the StorageClass", "in": "path", "name": "name", "required": true, @@ -5272,8 +5565,8 @@ } ], "patch": { - "description": "partially update the specified VolumeAttachment", - "operationId": "patchStorageV1VolumeAttachment", + "description": "partially update the specified StorageClass", + "operationId": "patchStorageV1StorageClass", "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", @@ -5326,17 +5619,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } } }, @@ -5346,17 +5639,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } } }, @@ -5368,8 +5661,8 @@ ] }, "put": { - "description": "replace the specified VolumeAttachment", - "operationId": "replaceStorageV1VolumeAttachment", + "description": "replace the specified StorageClass", + "operationId": "replaceStorageV1StorageClass", "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", @@ -5403,7 +5696,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } } } @@ -5413,17 +5706,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } } }, @@ -5433,17 +5726,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } }, "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.api.storage.v1.StorageClass" } } }, @@ -5455,110 +5748,909 @@ ] } }, - "/apis/storage.k8s.io/v1/volumeattachments/{name}/status": { - "get": { - "description": "read status of the specified VolumeAttachment", - "operationId": "readStorageV1VolumeAttachmentStatus", - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" - } - }, - "application/vnd.kubernetes.protobuf": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" - } - }, - "application/yaml": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" - } - } - }, - "description": "OK" - } - }, - "tags": [ - "storage_v1" - ] - }, - "parameters": [ - { - "description": "name of the VolumeAttachment", - "in": "path", - "name": "name", - "required": true, - "schema": { - "type": "string", - "uniqueItems": true - } - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "schema": { - "type": "string", - "uniqueItems": true - } - } - ], - "patch": { - "description": "partially update status of the specified VolumeAttachment", - "operationId": "patchStorageV1VolumeAttachmentStatus", + "/apis/storage.k8s.io/v1/volumeattachments": { + "delete": { + "description": "delete collection of VolumeAttachment", + "operationId": "deleteStorageV1CollectionVolumeAttachment", "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", + "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": "dryRun", + "name": "gracePeriodSeconds", "schema": { - "type": "string", + "type": "integer", "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.", + "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": "force", + "name": "orphanDependents", "schema": { "type": "boolean", "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).", + "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": "fieldManager", + "name": "propagationPolicy", "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, provided that the `ServerSideFieldValidation` feature gate is also enabled. 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 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - 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 when the `ServerSideFieldValidation` feature gate is enabled. - 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.", + "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": "fieldValidation", + "name": "dryRun", "schema": { "type": "string", "uniqueItems": true } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" - } + }, + { + "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 } - } - }, - "responses": { - "200": { - "content": { + }, + { + "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": "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": "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": "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": "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 + } + } + ], + "requestBody": { + "content": { + "application/json": { + "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" + } + }, + "tags": [ + "storage_v1" + ] + }, + "get": { + "description": "list or watch objects of kind VolumeAttachment", + "operationId": "listStorageV1VolumeAttachment", + "parameters": [ + { + "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": "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": "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 + } + }, + { + "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": "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": "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": "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": "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 + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachmentList" + } + }, + "application/json;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachmentList" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachmentList" + } + }, + "application/vnd.kubernetes.protobuf;stream=watch": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachmentList" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachmentList" + } + } + }, + "description": "OK" + } + }, + "tags": [ + "storage_v1" + ] + }, + "parameters": [ + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "post": { + "description": "create a VolumeAttachment", + "operationId": "createStorageV1VolumeAttachment", + "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, provided that the `ServerSideFieldValidation` feature gate is also enabled. 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 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - 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 when the `ServerSideFieldValidation` feature gate is enabled. - 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": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + } + }, + "description": "Created" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + } + }, + "description": "Accepted" + } + }, + "tags": [ + "storage_v1" + ] + } + }, + "/apis/storage.k8s.io/v1/volumeattachments/{name}": { + "delete": { + "description": "delete a VolumeAttachment", + "operationId": "deleteStorageV1VolumeAttachment", + "parameters": [ + { + "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 + } + }, + { + "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 + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + } + }, + "description": "OK" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + } + }, + "description": "Accepted" + } + }, + "tags": [ + "storage_v1" + ] + }, + "get": { + "description": "read the specified VolumeAttachment", + "operationId": "readStorageV1VolumeAttachment", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + } + }, + "description": "OK" + } + }, + "tags": [ + "storage_v1" + ] + }, + "parameters": [ + { + "description": "name of the VolumeAttachment", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "patch": { + "description": "partially update the specified VolumeAttachment", + "operationId": "patchStorageV1VolumeAttachment", + "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": "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 + } + }, + { + "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, provided that the `ServerSideFieldValidation` feature gate is also enabled. 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 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - 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 when the `ServerSideFieldValidation` feature gate is enabled. - 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": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + } + }, + "description": "Created" + } + }, + "tags": [ + "storage_v1" + ] + }, + "put": { + "description": "replace the specified VolumeAttachment", + "operationId": "replaceStorageV1VolumeAttachment", + "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, provided that the `ServerSideFieldValidation` feature gate is also enabled. 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 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - 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 when the `ServerSideFieldValidation` feature gate is enabled. - 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": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + } + }, + "description": "Created" + } + }, + "tags": [ + "storage_v1" + ] + } + }, + "/apis/storage.k8s.io/v1/volumeattachments/{name}/status": { + "get": { + "description": "read status of the specified VolumeAttachment", + "operationId": "readStorageV1VolumeAttachmentStatus", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + } + }, + "description": "OK" + } + }, + "tags": [ + "storage_v1" + ] + }, + "parameters": [ + { + "description": "name of the VolumeAttachment", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "patch": { + "description": "partially update status of the specified VolumeAttachment", + "operationId": "patchStorageV1VolumeAttachmentStatus", + "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": "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 + } + }, + { + "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, provided that the `ServerSideFieldValidation` feature gate is also enabled. 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 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - 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 when the `ServerSideFieldValidation` feature gate is enabled. - 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": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + } + }, + "description": "Created" + } + }, + "tags": [ + "storage_v1" + ] + }, + "put": { + "description": "replace status of the specified VolumeAttachment", + "operationId": "replaceStorageV1VolumeAttachmentStatus", + "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, provided that the `ServerSideFieldValidation` feature gate is also enabled. 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 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - 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 when the `ServerSideFieldValidation` feature gate is enabled. - 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": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + } + } + } + }, + "responses": { + "200": { + "content": { "application/json": { "schema": { "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" @@ -5598,102 +6690,424 @@ "description": "Created" } }, - "tags": [ - "storage_v1" - ] - }, - "put": { - "description": "replace status of the specified VolumeAttachment", - "operationId": "replaceStorageV1VolumeAttachmentStatus", - "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, provided that the `ServerSideFieldValidation` feature gate is also enabled. 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 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - 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 when the `ServerSideFieldValidation` feature gate is enabled. - 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 - } + "tags": [ + "storage_v1" + ] + } + }, + "/apis/storage.k8s.io/v1/watch/csidrivers": { + "get": { + "description": "watch individual changes to a list of CSIDriver. deprecated: use the 'watch' parameter with a list operation instead.", + "operationId": "watchStorageV1CSIDriverList", + "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" + } + }, + "tags": [ + "storage_v1" + ] + }, + "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.", + "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": "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/storage.k8s.io/v1/watch/csidrivers/{name}": { + "get": { + "description": "watch changes to an object of kind CSIDriver. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", + "operationId": "watchStorageV1CSIDriver", + "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" + } + }, + "tags": [ + "storage_v1" + ] + }, + "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 CSIDriver", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "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 } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" - } - } + }, + { + "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": "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/storage.k8s.io/v1/watch/csinodes": { + "get": { + "description": "watch individual changes to a list of CSINode. deprecated: use the 'watch' parameter with a list operation instead.", + "operationId": "watchStorageV1CSINodeList", "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" } }, - "application/vnd.kubernetes.protobuf": { + "application/json;stream=watch": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" } }, - "application/yaml": { - "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" - } - } - }, - "description": "OK" - }, - "201": { - "content": { - "application/json": { + "application/vnd.kubernetes.protobuf": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" } }, - "application/vnd.kubernetes.protobuf": { + "application/vnd.kubernetes.protobuf;stream=watch": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" } }, "application/yaml": { "schema": { - "$ref": "#/components/schemas/io.k8s.api.storage.v1.VolumeAttachment" + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" } } }, - "description": "Created" + "description": "OK" } }, "tags": [ "storage_v1" ] - } + }, + "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.", + "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": "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/storage.k8s.io/v1/watch/csidrivers": { + "/apis/storage.k8s.io/v1/watch/csinodes/{name}": { "get": { - "description": "watch individual changes to a list of CSIDriver. deprecated: use the 'watch' parameter with a list operation instead.", - "operationId": "watchStorageV1CSIDriverList", + "description": "watch changes to an object of kind CSINode. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", + "operationId": "watchStorageV1CSINode", "responses": { "200": { "content": { @@ -5776,6 +7190,16 @@ "uniqueItems": true } }, + { + "description": "name of the CSINode", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, { "description": "If 'true', then the output is pretty printed.", "in": "query", @@ -5823,10 +7247,10 @@ } ] }, - "/apis/storage.k8s.io/v1/watch/csidrivers/{name}": { + "/apis/storage.k8s.io/v1/watch/csistoragecapacities": { "get": { - "description": "watch changes to an object of kind CSIDriver. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", - "operationId": "watchStorageV1CSIDriver", + "description": "watch individual changes to a list of CSIStorageCapacity. deprecated: use the 'watch' parameter with a list operation instead.", + "operationId": "watchStorageV1CSIStorageCapacityListForAllNamespaces", "responses": { "200": { "content": { @@ -5909,16 +7333,6 @@ "uniqueItems": true } }, - { - "description": "name of the CSIDriver", - "in": "path", - "name": "name", - "required": true, - "schema": { - "type": "string", - "uniqueItems": true - } - }, { "description": "If 'true', then the output is pretty printed.", "in": "query", @@ -5966,10 +7380,10 @@ } ] }, - "/apis/storage.k8s.io/v1/watch/csinodes": { + "/apis/storage.k8s.io/v1/watch/namespaces/{namespace}/csistoragecapacities": { "get": { - "description": "watch individual changes to a list of CSINode. deprecated: use the 'watch' parameter with a list operation instead.", - "operationId": "watchStorageV1CSINodeList", + "description": "watch individual changes to a list of CSIStorageCapacity. deprecated: use the 'watch' parameter with a list operation instead.", + "operationId": "watchStorageV1NamespacedCSIStorageCapacityList", "responses": { "200": { "content": { @@ -6052,6 +7466,16 @@ "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.", "in": "query", @@ -6099,10 +7523,10 @@ } ] }, - "/apis/storage.k8s.io/v1/watch/csinodes/{name}": { + "/apis/storage.k8s.io/v1/watch/namespaces/{namespace}/csistoragecapacities/{name}": { "get": { - "description": "watch changes to an object of kind CSINode. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", - "operationId": "watchStorageV1CSINode", + "description": "watch changes to an object of kind CSIStorageCapacity. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", + "operationId": "watchStorageV1NamespacedCSIStorageCapacity", "responses": { "200": { "content": { @@ -6186,7 +7610,7 @@ } }, { - "description": "name of the CSINode", + "description": "name of the CSIStorageCapacity", "in": "path", "name": "name", "required": true, @@ -6195,6 +7619,16 @@ "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.", "in": "query", diff --git a/api/openapi-spec/v3/apis__storage.k8s.io__v1alpha1_openapi.json b/api/openapi-spec/v3/apis__storage.k8s.io__v1alpha1_openapi.json index ef3321168b2b..ffb05e896c36 100644 --- a/api/openapi-spec/v3/apis__storage.k8s.io__v1alpha1_openapi.json +++ b/api/openapi-spec/v3/apis__storage.k8s.io__v1alpha1_openapi.json @@ -2,7 +2,7 @@ "components": { "schemas": { "io.k8s.api.storage.v1alpha1.CSIStorageCapacity": { - "description": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler if the CSIStorageCapacity beta feature gate is enabled there and a CSI driver opts into capacity-aware scheduling with CSIDriver.StorageCapacity.", + "description": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler when a CSI driver opts into capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler compares the MaximumVolumeSize against the requested size of pending volumes to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back to a comparison against the less precise Capacity. If that is also unset, the scheduler assumes that capacity is insufficient and tries some other node.", "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", @@ -10,7 +10,7 @@ }, "capacity": { "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.api.resource.Quantity", - "description": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable and treated like zero capacity." + "description": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable." }, "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", diff --git a/api/openapi-spec/v3/apis__storage.k8s.io__v1beta1_openapi.json b/api/openapi-spec/v3/apis__storage.k8s.io__v1beta1_openapi.json index b80a678ebd7b..cad8293e5144 100644 --- a/api/openapi-spec/v3/apis__storage.k8s.io__v1beta1_openapi.json +++ b/api/openapi-spec/v3/apis__storage.k8s.io__v1beta1_openapi.json @@ -2,7 +2,7 @@ "components": { "schemas": { "io.k8s.api.storage.v1beta1.CSIStorageCapacity": { - "description": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler if the CSIStorageCapacity beta feature gate is enabled there and a CSI driver opts into capacity-aware scheduling with CSIDriver.StorageCapacity.", + "description": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler when a CSI driver opts into capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler compares the MaximumVolumeSize against the requested size of pending volumes to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back to a comparison against the less precise Capacity. If that is also unset, the scheduler assumes that capacity is insufficient and tries some other node.", "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", @@ -10,7 +10,7 @@ }, "capacity": { "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.api.resource.Quantity", - "description": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable and treated like zero capacity." + "description": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable." }, "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", diff --git a/pkg/apis/storage/types.go b/pkg/apis/storage/types.go index 71416b26d23a..6c6fd11d804c 100644 --- a/pkg/apis/storage/types.go +++ b/pkg/apis/storage/types.go @@ -357,9 +357,6 @@ type CSIDriverSpec struct { // // This field was immutable in Kubernetes <= 1.22 and now is mutable. // - // This is a beta field and only available when the CSIStorageCapacity - // feature is enabled. The default is false. - // // +optional StorageCapacity *bool @@ -575,9 +572,13 @@ type CSINodeList struct { // // The producer of these objects can decide which approach is more suitable. // -// They are consumed by the kube-scheduler if the CSIStorageCapacity beta feature gate -// is enabled there and a CSI driver opts into capacity-aware scheduling with -// CSIDriver.StorageCapacity. +// They are consumed by the kube-scheduler when a CSI driver opts into +// capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler +// compares the MaximumVolumeSize against the requested size of pending volumes +// to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back +// to a comparison against the less precise Capacity. If that is also unset, +// the scheduler assumes that capacity is insufficient and tries some other +// node. type CSIStorageCapacity struct { metav1.TypeMeta // Standard object's metadata. The name has no particular meaning. It must be @@ -595,7 +596,7 @@ type CSIStorageCapacity struct { // NodeTopology defines which nodes have access to the storage // for which capacity was reported. If not set, the storage is // not accessible from any node in the cluster. If empty, the - // storage is accessible from all nodes. This field is + // storage is accessible from all nodes. This field is // immutable. // // +optional @@ -616,7 +617,7 @@ type CSIStorageCapacity struct { // The semantic is currently (CSI spec 1.2) defined as: // The available capacity, in bytes, of the storage that can be used // to provision volumes. If not set, that information is currently - // unavailable and treated like zero capacity. + // unavailable. // // +optional Capacity *resource.Quantity diff --git a/pkg/apis/storage/v1/defaults.go b/pkg/apis/storage/v1/defaults.go index 85d786f76500..d2c4218655bb 100644 --- a/pkg/apis/storage/v1/defaults.go +++ b/pkg/apis/storage/v1/defaults.go @@ -49,7 +49,7 @@ func SetDefaults_CSIDriver(obj *storagev1.CSIDriver) { obj.Spec.PodInfoOnMount = new(bool) *(obj.Spec.PodInfoOnMount) = false } - if obj.Spec.StorageCapacity == nil && utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) { + if obj.Spec.StorageCapacity == nil { obj.Spec.StorageCapacity = new(bool) *(obj.Spec.StorageCapacity) = false } diff --git a/pkg/apis/storage/v1/defaults_test.go b/pkg/apis/storage/v1/defaults_test.go index 89174b1bcae5..3c482e086b72 100644 --- a/pkg/apis/storage/v1/defaults_test.go +++ b/pkg/apis/storage/v1/defaults_test.go @@ -52,7 +52,6 @@ func roundTrip(t *testing.T, obj runtime.Object) runtime.Object { } func TestSetDefaultStorageCapacityEnabled(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, true)() driver := &storagev1.CSIDriver{} // field should be defaulted @@ -66,18 +65,6 @@ func TestSetDefaultStorageCapacityEnabled(t *testing.T) { } } -func TestSetDefaultStorageCapacityDisabled(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, false)() - driver := &storagev1.CSIDriver{} - - // field should not be defaulted - output := roundTrip(t, runtime.Object(driver)).(*storagev1.CSIDriver) - outStorageCapacity := output.Spec.StorageCapacity - if outStorageCapacity != nil { - t.Errorf("Expected StorageCapacity to remain nil, got: %+v", outStorageCapacity) - } -} - func TestSetDefaultVolumeBindingMode(t *testing.T) { class := &storagev1.StorageClass{} diff --git a/pkg/apis/storage/v1/zz_generated.conversion.go b/pkg/apis/storage/v1/zz_generated.conversion.go index 3342a2cc5461..3c7e174d1d97 100644 --- a/pkg/apis/storage/v1/zz_generated.conversion.go +++ b/pkg/apis/storage/v1/zz_generated.conversion.go @@ -26,6 +26,8 @@ import ( corev1 "k8s.io/api/core/v1" v1 "k8s.io/api/storage/v1" + resource "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" conversion "k8s.io/apimachinery/pkg/conversion" runtime "k8s.io/apimachinery/pkg/runtime" core "k8s.io/kubernetes/pkg/apis/core" @@ -110,6 +112,26 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*v1.CSIStorageCapacity)(nil), (*storage.CSIStorageCapacity)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_CSIStorageCapacity_To_storage_CSIStorageCapacity(a.(*v1.CSIStorageCapacity), b.(*storage.CSIStorageCapacity), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*storage.CSIStorageCapacity)(nil), (*v1.CSIStorageCapacity)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_storage_CSIStorageCapacity_To_v1_CSIStorageCapacity(a.(*storage.CSIStorageCapacity), b.(*v1.CSIStorageCapacity), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1.CSIStorageCapacityList)(nil), (*storage.CSIStorageCapacityList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_CSIStorageCapacityList_To_storage_CSIStorageCapacityList(a.(*v1.CSIStorageCapacityList), b.(*storage.CSIStorageCapacityList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*storage.CSIStorageCapacityList)(nil), (*v1.CSIStorageCapacityList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_storage_CSIStorageCapacityList_To_v1_CSIStorageCapacityList(a.(*storage.CSIStorageCapacityList), b.(*v1.CSIStorageCapacityList), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*v1.StorageClass)(nil), (*storage.StorageClass)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1_StorageClass_To_storage_StorageClass(a.(*v1.StorageClass), b.(*storage.StorageClass), scope) }); err != nil { @@ -407,6 +429,56 @@ func Convert_storage_CSINodeSpec_To_v1_CSINodeSpec(in *storage.CSINodeSpec, out return autoConvert_storage_CSINodeSpec_To_v1_CSINodeSpec(in, out, s) } +func autoConvert_v1_CSIStorageCapacity_To_storage_CSIStorageCapacity(in *v1.CSIStorageCapacity, out *storage.CSIStorageCapacity, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + out.NodeTopology = (*metav1.LabelSelector)(unsafe.Pointer(in.NodeTopology)) + out.StorageClassName = in.StorageClassName + out.Capacity = (*resource.Quantity)(unsafe.Pointer(in.Capacity)) + out.MaximumVolumeSize = (*resource.Quantity)(unsafe.Pointer(in.MaximumVolumeSize)) + return nil +} + +// Convert_v1_CSIStorageCapacity_To_storage_CSIStorageCapacity is an autogenerated conversion function. +func Convert_v1_CSIStorageCapacity_To_storage_CSIStorageCapacity(in *v1.CSIStorageCapacity, out *storage.CSIStorageCapacity, s conversion.Scope) error { + return autoConvert_v1_CSIStorageCapacity_To_storage_CSIStorageCapacity(in, out, s) +} + +func autoConvert_storage_CSIStorageCapacity_To_v1_CSIStorageCapacity(in *storage.CSIStorageCapacity, out *v1.CSIStorageCapacity, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + out.NodeTopology = (*metav1.LabelSelector)(unsafe.Pointer(in.NodeTopology)) + out.StorageClassName = in.StorageClassName + out.Capacity = (*resource.Quantity)(unsafe.Pointer(in.Capacity)) + out.MaximumVolumeSize = (*resource.Quantity)(unsafe.Pointer(in.MaximumVolumeSize)) + return nil +} + +// Convert_storage_CSIStorageCapacity_To_v1_CSIStorageCapacity is an autogenerated conversion function. +func Convert_storage_CSIStorageCapacity_To_v1_CSIStorageCapacity(in *storage.CSIStorageCapacity, out *v1.CSIStorageCapacity, s conversion.Scope) error { + return autoConvert_storage_CSIStorageCapacity_To_v1_CSIStorageCapacity(in, out, s) +} + +func autoConvert_v1_CSIStorageCapacityList_To_storage_CSIStorageCapacityList(in *v1.CSIStorageCapacityList, out *storage.CSIStorageCapacityList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]storage.CSIStorageCapacity)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_v1_CSIStorageCapacityList_To_storage_CSIStorageCapacityList is an autogenerated conversion function. +func Convert_v1_CSIStorageCapacityList_To_storage_CSIStorageCapacityList(in *v1.CSIStorageCapacityList, out *storage.CSIStorageCapacityList, s conversion.Scope) error { + return autoConvert_v1_CSIStorageCapacityList_To_storage_CSIStorageCapacityList(in, out, s) +} + +func autoConvert_storage_CSIStorageCapacityList_To_v1_CSIStorageCapacityList(in *storage.CSIStorageCapacityList, out *v1.CSIStorageCapacityList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]v1.CSIStorageCapacity)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_storage_CSIStorageCapacityList_To_v1_CSIStorageCapacityList is an autogenerated conversion function. +func Convert_storage_CSIStorageCapacityList_To_v1_CSIStorageCapacityList(in *storage.CSIStorageCapacityList, out *v1.CSIStorageCapacityList, s conversion.Scope) error { + return autoConvert_storage_CSIStorageCapacityList_To_v1_CSIStorageCapacityList(in, out, s) +} + func autoConvert_v1_StorageClass_To_storage_StorageClass(in *v1.StorageClass, out *storage.StorageClass, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta out.Provisioner = in.Provisioner diff --git a/pkg/apis/storage/v1beta1/defaults.go b/pkg/apis/storage/v1beta1/defaults.go index f7dda9691dc4..657da472ee58 100644 --- a/pkg/apis/storage/v1beta1/defaults.go +++ b/pkg/apis/storage/v1beta1/defaults.go @@ -49,7 +49,7 @@ func SetDefaults_CSIDriver(obj *storagev1beta1.CSIDriver) { obj.Spec.PodInfoOnMount = new(bool) *(obj.Spec.PodInfoOnMount) = false } - if obj.Spec.StorageCapacity == nil && utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) { + if obj.Spec.StorageCapacity == nil { obj.Spec.StorageCapacity = new(bool) *(obj.Spec.StorageCapacity) = false } diff --git a/pkg/apis/storage/v1beta1/defaults_test.go b/pkg/apis/storage/v1beta1/defaults_test.go index 572d5dd1dae5..317c8a78a96c 100644 --- a/pkg/apis/storage/v1beta1/defaults_test.go +++ b/pkg/apis/storage/v1beta1/defaults_test.go @@ -87,7 +87,6 @@ func TestSetDefaultAttachRequired(t *testing.T) { } func TestSetDefaultStorageCapacityEnabled(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, true)() driver := &storagev1beta1.CSIDriver{} // field should be defaulted @@ -101,18 +100,6 @@ func TestSetDefaultStorageCapacityEnabled(t *testing.T) { } } -func TestSetDefaultStorageCapacityDisabled(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, false)() - driver := &storagev1beta1.CSIDriver{} - - // field should not be defaulted - output := roundTrip(t, runtime.Object(driver)).(*storagev1beta1.CSIDriver) - outStorageCapacity := output.Spec.StorageCapacity - if outStorageCapacity != nil { - t.Errorf("Expected StorageCapacity to remain nil, got: %+v", outStorageCapacity) - } -} - func TestSetDefaultVolumeLifecycleModesEnabled(t *testing.T) { defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)() driver := &storagev1beta1.CSIDriver{} diff --git a/pkg/apis/storage/validation/validation.go b/pkg/apis/storage/validation/validation.go index 9cd48cd71764..8bb8aa2f0ec3 100644 --- a/pkg/apis/storage/validation/validation.go +++ b/pkg/apis/storage/validation/validation.go @@ -469,7 +469,7 @@ func validatePodInfoOnMount(podInfoOnMount *bool, fldPath *field.Path) field.Err // validateStorageCapacity tests if storageCapacity is set for CSIDriver. func validateStorageCapacity(storageCapacity *bool, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} - if storageCapacity == nil && utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) { + if storageCapacity == nil { allErrs = append(allErrs, field.Required(fldPath, "")) } diff --git a/pkg/apis/storage/validation/validation_test.go b/pkg/apis/storage/validation/validation_test.go index 7b483d48cae1..2374f5004971 100644 --- a/pkg/apis/storage/validation/validation_test.go +++ b/pkg/apis/storage/validation/validation_test.go @@ -2093,9 +2093,7 @@ func TestCSIDriverValidationUpdate(t *testing.T) { } func TestCSIDriverStorageCapacityEnablement(t *testing.T) { - run := func(t *testing.T, enabled, withField bool) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, enabled)() - + run := func(t *testing.T, withField bool) { driverName := "test-driver" attachRequired := true podInfoOnMount := true @@ -2113,7 +2111,7 @@ func TestCSIDriverStorageCapacityEnablement(t *testing.T) { csiDriver.Spec.StorageCapacity = &storageCapacity } errs := ValidateCSIDriver(&csiDriver) - success := !enabled || withField + success := withField if success && len(errs) != 0 { t.Errorf("expected success, got: %v", errs) } @@ -2123,13 +2121,9 @@ func TestCSIDriverStorageCapacityEnablement(t *testing.T) { } yesNo := []bool{true, false} - for _, enabled := range yesNo { - t.Run(fmt.Sprintf("CSIStorageCapacity=%v", enabled), func(t *testing.T) { - for _, withField := range yesNo { - t.Run(fmt.Sprintf("with-field=%v", withField), func(t *testing.T) { - run(t, enabled, withField) - }) - } + for _, withField := range yesNo { + t.Run(fmt.Sprintf("with-field=%v", withField), func(t *testing.T) { + run(t, withField) }) } } diff --git a/pkg/controlplane/storageversionhashdata/data.go b/pkg/controlplane/storageversionhashdata/data.go index 3b02e2878ecd..d5b4e7616ffd 100644 --- a/pkg/controlplane/storageversionhashdata/data.go +++ b/pkg/controlplane/storageversionhashdata/data.go @@ -78,6 +78,7 @@ var GVRToStorageVersionHash = map[string]string{ "storage.k8s.io/v1/csidrivers": "hL6j/rwBV5w=", "storage.k8s.io/v1/csinodes": "Pe62DkZtjuo=", "storage.k8s.io/v1/storageclasses": "K+m6uJwbjGY=", + "storage.k8s.io/v1/csistoragecapacities": "xeVl+2Ly1kE=", "storage.k8s.io/v1/volumeattachments": "vQAqD28V4AY=", "storage.k8s.io/v1beta1/csistoragecapacities": "xeVl+2Ly1kE=", "apps/v1/controllerrevisions": "85nkx63pcBU=", diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index 9d87a9e1cdbb..4ebce0499d09 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -157,6 +157,7 @@ const ( // owner: @pohly // alpha: v1.19 // beta: v1.21 + // GA: v1.24 // // Enables tracking of available storage capacity that CSI drivers provide. CSIStorageCapacity featuregate.Feature = "CSIStorageCapacity" @@ -879,7 +880,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS CSIMigrationPortworx: {Default: false, PreRelease: featuregate.Alpha}, // Off by default (requires Portworx CSI driver) InTreePluginPortworxUnregister: {Default: false, PreRelease: featuregate.Alpha}, CSIInlineVolume: {Default: true, PreRelease: featuregate.Beta}, - CSIStorageCapacity: {Default: true, PreRelease: featuregate.Beta}, + CSIStorageCapacity: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.26 CSIServiceAccountToken: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.23 GenericEphemeralVolume: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25 CSIVolumeFSGroupPolicy: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25 diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index a45aca1f7539..09ac4fc689f1 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -781,6 +781,8 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "k8s.io/api/storage/v1.CSINodeDriver": schema_k8sio_api_storage_v1_CSINodeDriver(ref), "k8s.io/api/storage/v1.CSINodeList": schema_k8sio_api_storage_v1_CSINodeList(ref), "k8s.io/api/storage/v1.CSINodeSpec": schema_k8sio_api_storage_v1_CSINodeSpec(ref), + "k8s.io/api/storage/v1.CSIStorageCapacity": schema_k8sio_api_storage_v1_CSIStorageCapacity(ref), + "k8s.io/api/storage/v1.CSIStorageCapacityList": schema_k8sio_api_storage_v1_CSIStorageCapacityList(ref), "k8s.io/api/storage/v1.StorageClass": schema_k8sio_api_storage_v1_StorageClass(ref), "k8s.io/api/storage/v1.StorageClassList": schema_k8sio_api_storage_v1_StorageClassList(ref), "k8s.io/api/storage/v1.TokenRequest": schema_k8sio_api_storage_v1_TokenRequest(ref), @@ -38726,7 +38728,7 @@ func schema_k8sio_api_storage_v1_CSIDriverSpec(ref common.ReferenceCallback) com }, "storageCapacity": { SchemaProps: spec.SchemaProps{ - Description: "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis field was immutable in Kubernetes <= 1.22 and now is mutable.\n\nThis is a beta field and only available when the CSIStorageCapacity feature is enabled. The default is false.", + Description: "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis field was immutable in Kubernetes <= 1.22 and now is mutable.", Type: []string{"boolean"}, Format: "", }, @@ -38956,6 +38958,128 @@ func schema_k8sio_api_storage_v1_CSINodeSpec(ref common.ReferenceCallback) commo } } +func schema_k8sio_api_storage_v1_CSIStorageCapacity(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler when a CSI driver opts into capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler compares the MaximumVolumeSize against the requested size of pending volumes to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back to a comparison against the less precise Capacity. If that is also unset, the scheduler assumes that capacity is insufficient and tries some other node.", + 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's metadata. The name has no particular meaning. It must be be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name.\n\nObjects are namespaced.\n\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "nodeTopology": { + SchemaProps: spec.SchemaProps{ + Description: "NodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.", + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"), + }, + }, + "storageClassName": { + SchemaProps: spec.SchemaProps{ + Description: "The name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "capacity": { + SchemaProps: spec.SchemaProps{ + Description: "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable.", + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + }, + }, + "maximumVolumeSize": { + SchemaProps: spec.SchemaProps{ + Description: "MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThis is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.", + Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), + }, + }, + }, + Required: []string{"storageClassName"}, + }, + }, + Dependencies: []string{ + "k8s.io/apimachinery/pkg/api/resource.Quantity", "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_k8sio_api_storage_v1_CSIStorageCapacityList(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "CSIStorageCapacityList is a collection of CSIStorageCapacity objects.", + 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 More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), + }, + }, + "items": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-map-keys": []interface{}{ + "name", + }, + "x-kubernetes-list-type": "map", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Items is the list of CSIStorageCapacity objects.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/storage/v1.CSIStorageCapacity"), + }, + }, + }, + }, + }, + }, + Required: []string{"items"}, + }, + }, + Dependencies: []string{ + "k8s.io/api/storage/v1.CSIStorageCapacity", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + func schema_k8sio_api_storage_v1_StorageClass(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -39426,7 +39550,7 @@ func schema_k8sio_api_storage_v1alpha1_CSIStorageCapacity(ref common.ReferenceCa return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler if the CSIStorageCapacity beta feature gate is enabled there and a CSI driver opts into capacity-aware scheduling with CSIDriver.StorageCapacity.", + Description: "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler when a CSI driver opts into capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler compares the MaximumVolumeSize against the requested size of pending volumes to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back to a comparison against the less precise Capacity. If that is also unset, the scheduler assumes that capacity is insufficient and tries some other node.", Type: []string{"object"}, Properties: map[string]spec.Schema{ "kind": { @@ -39466,7 +39590,7 @@ func schema_k8sio_api_storage_v1alpha1_CSIStorageCapacity(ref common.ReferenceCa }, "capacity": { SchemaProps: spec.SchemaProps{ - Description: "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable and treated like zero capacity.", + Description: "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable.", Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), }, }, @@ -39927,7 +40051,7 @@ func schema_k8sio_api_storage_v1beta1_CSIDriverSpec(ref common.ReferenceCallback }, "storageCapacity": { SchemaProps: spec.SchemaProps{ - Description: "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis field was immutable in Kubernetes <= 1.22 and now is mutable.\n\nThis is a beta field and only available when the CSIStorageCapacity feature is enabled. The default is false.", + Description: "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis field was immutable in Kubernetes <= 1.22 and now is mutable.", Type: []string{"boolean"}, Format: "", }, @@ -40161,7 +40285,7 @@ func schema_k8sio_api_storage_v1beta1_CSIStorageCapacity(ref common.ReferenceCal return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler if the CSIStorageCapacity beta feature gate is enabled there and a CSI driver opts into capacity-aware scheduling with CSIDriver.StorageCapacity.", + Description: "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler when a CSI driver opts into capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler compares the MaximumVolumeSize against the requested size of pending volumes to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back to a comparison against the less precise Capacity. If that is also unset, the scheduler assumes that capacity is insufficient and tries some other node.", Type: []string{"object"}, Properties: map[string]spec.Schema{ "kind": { @@ -40201,7 +40325,7 @@ func schema_k8sio_api_storage_v1beta1_CSIStorageCapacity(ref common.ReferenceCal }, "capacity": { SchemaProps: spec.SchemaProps{ - Description: "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable and treated like zero capacity.", + Description: "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable.", Ref: ref("k8s.io/apimachinery/pkg/api/resource.Quantity"), }, }, diff --git a/pkg/kubeapiserver/default_storage_factory_builder.go b/pkg/kubeapiserver/default_storage_factory_builder.go index 31479d776461..a398d3164119 100644 --- a/pkg/kubeapiserver/default_storage_factory_builder.go +++ b/pkg/kubeapiserver/default_storage_factory_builder.go @@ -61,6 +61,8 @@ func DefaultWatchCacheSizes() map[schema.GroupResource]int { func NewStorageFactoryConfig() *StorageFactoryConfig { resources := []schema.GroupVersionResource{ + // TODO (https://github.com/kubernetes/kubernetes/issues/108451): remove the override in + // 1.25. apisstorage.Resource("csistoragecapacities").WithVersion("v1beta1"), } diff --git a/pkg/printers/internalversion/printers.go b/pkg/printers/internalversion/printers.go index 1e557d2ee6de..35c5433ddf76 100644 --- a/pkg/printers/internalversion/printers.go +++ b/pkg/printers/internalversion/printers.go @@ -40,14 +40,12 @@ import ( rbacv1beta1 "k8s.io/api/rbac/v1beta1" schedulingv1 "k8s.io/api/scheduling/v1" storagev1 "k8s.io/api/storage/v1" - storagev1alpha1 "k8s.io/api/storage/v1alpha1" 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/util/duration" "k8s.io/apimachinery/pkg/util/sets" - utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/util/certificate/csr" "k8s.io/kubernetes/pkg/apis/admissionregistration" "k8s.io/kubernetes/pkg/apis/apiserverinternal" @@ -68,7 +66,6 @@ import ( "k8s.io/kubernetes/pkg/apis/scheduling" "k8s.io/kubernetes/pkg/apis/storage" storageutil "k8s.io/kubernetes/pkg/apis/storage/util" - "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/printers" "k8s.io/kubernetes/pkg/util/node" ) @@ -516,11 +513,7 @@ func AddHandlers(h printers.PrintHandler) { {Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]}, {Name: "AttachRequired", Type: "boolean", Description: storagev1.CSIDriverSpec{}.SwaggerDoc()["attachRequired"]}, {Name: "PodInfoOnMount", Type: "boolean", Description: storagev1.CSIDriverSpec{}.SwaggerDoc()["podInfoOnMount"]}, - } - if utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) { - csiDriverColumnDefinitions = append(csiDriverColumnDefinitions, metav1.TableColumnDefinition{ - Name: "StorageCapacity", Type: "boolean", Description: storagev1.CSIDriverSpec{}.SwaggerDoc()["storageCapacity"], - }) + {Name: "StorageCapacity", Type: "boolean", Description: storagev1.CSIDriverSpec{}.SwaggerDoc()["storageCapacity"]}, } csiDriverColumnDefinitions = append(csiDriverColumnDefinitions, []metav1.TableColumnDefinition{ {Name: "TokenRequests", Type: "string", Description: storagev1.CSIDriverSpec{}.SwaggerDoc()["tokenRequests"]}, @@ -536,8 +529,8 @@ func AddHandlers(h printers.PrintHandler) { csiStorageCapacityColumnDefinitions := []metav1.TableColumnDefinition{ {Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]}, - {Name: "StorageClassName", Type: "string", Description: storagev1alpha1.CSIStorageCapacity{}.SwaggerDoc()["storageClassName"]}, - {Name: "Capacity", Type: "string", Description: storagev1alpha1.CSIStorageCapacity{}.SwaggerDoc()["capacity"]}, + {Name: "StorageClassName", Type: "string", Description: storagev1.CSIStorageCapacity{}.SwaggerDoc()["storageClassName"]}, + {Name: "Capacity", Type: "string", Description: storagev1.CSIStorageCapacity{}.SwaggerDoc()["capacity"]}, } h.TableHandler(csiStorageCapacityColumnDefinitions, printCSIStorageCapacity) h.TableHandler(csiStorageCapacityColumnDefinitions, printCSIStorageCapacityList) @@ -1413,13 +1406,11 @@ func printCSIDriver(obj *storage.CSIDriver, options printers.GenerateOptions) ([ } row.Cells = append(row.Cells, obj.Name, attachRequired, podInfoOnMount) - if utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) { - storageCapacity := false - if obj.Spec.StorageCapacity != nil { - storageCapacity = *obj.Spec.StorageCapacity - } - row.Cells = append(row.Cells, storageCapacity) + storageCapacity := false + if obj.Spec.StorageCapacity != nil { + storageCapacity = *obj.Spec.StorageCapacity } + row.Cells = append(row.Cells, storageCapacity) tokenRequests := "" if obj.Spec.TokenRequests != nil { diff --git a/pkg/registry/storage/csidriver/strategy.go b/pkg/registry/storage/csidriver/strategy.go index cabe8e8c5eaa..2bd1893899d4 100644 --- a/pkg/registry/storage/csidriver/strategy.go +++ b/pkg/registry/storage/csidriver/strategy.go @@ -47,9 +47,6 @@ func (csiDriverStrategy) NamespaceScoped() bool { // PrepareForCreate clears the fields for which the corresponding feature is disabled. func (csiDriverStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { csiDriver := obj.(*storage.CSIDriver) - if !utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) { - csiDriver.Spec.StorageCapacity = nil - } if !utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) { csiDriver.Spec.VolumeLifecycleModes = nil } @@ -84,10 +81,6 @@ func (csiDriverStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime. newCSIDriver := obj.(*storage.CSIDriver) oldCSIDriver := old.(*storage.CSIDriver) - if oldCSIDriver.Spec.StorageCapacity == nil && - !utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) { - newCSIDriver.Spec.StorageCapacity = nil - } if oldCSIDriver.Spec.VolumeLifecycleModes == nil && !utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) { newCSIDriver.Spec.VolumeLifecycleModes = nil diff --git a/pkg/registry/storage/csidriver/strategy_test.go b/pkg/registry/storage/csidriver/strategy_test.go index 5a97d6651a0a..59c25bdb92fb 100644 --- a/pkg/registry/storage/csidriver/strategy_test.go +++ b/pkg/registry/storage/csidriver/strategy_test.go @@ -92,9 +92,8 @@ func TestCSIDriverPrepareForCreate(t *testing.T) { requiresRepublish := true tests := []struct { - name string - withCapacity bool - withInline bool + name string + withInline bool }{ { name: "inline enabled", @@ -104,19 +103,10 @@ func TestCSIDriverPrepareForCreate(t *testing.T) { name: "inline disabled", withInline: false, }, - { - name: "capacity enabled", - withCapacity: true, - }, - { - name: "capacity disabled", - withCapacity: false, - }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, test.withCapacity)() defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, test.withInline)() csiDriver := &storage.CSIDriver{ @@ -139,14 +129,8 @@ func TestCSIDriverPrepareForCreate(t *testing.T) { if len(errs) != 0 { t.Errorf("unexpected validating errors: %v", errs) } - if test.withCapacity { - if csiDriver.Spec.StorageCapacity == nil || *csiDriver.Spec.StorageCapacity != storageCapacity { - t.Errorf("StorageCapacity modified: %v", csiDriver.Spec.StorageCapacity) - } - } else { - if csiDriver.Spec.StorageCapacity != nil { - t.Errorf("StorageCapacity not stripped: %v", csiDriver.Spec.StorageCapacity) - } + if csiDriver.Spec.StorageCapacity == nil || *csiDriver.Spec.StorageCapacity != storageCapacity { + t.Errorf("StorageCapacity modified: %v", csiDriver.Spec.StorageCapacity) } if test.withInline { if len(csiDriver.Spec.VolumeLifecycleModes) != 1 { @@ -231,31 +215,23 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) { resultPersistent := []storage.VolumeLifecycleMode{storage.VolumeLifecyclePersistent} tests := []struct { - name string - old, update *storage.CSIDriver - csiStorageCapacityEnabled bool - csiInlineVolumeEnabled bool - wantCapacity *bool - wantModes []storage.VolumeLifecycleMode - wantTokenRequests []storage.TokenRequest - wantRequiresRepublish *bool - wantGeneration int64 + name string + old, update *storage.CSIDriver + csiInlineVolumeEnabled bool + wantCapacity *bool + wantModes []storage.VolumeLifecycleMode + wantTokenRequests []storage.TokenRequest + wantRequiresRepublish *bool + wantGeneration int64 }{ { - name: "capacity feature enabled, before: none, update: enabled", - csiStorageCapacityEnabled: true, - old: driverWithNothing, - update: driverWithCapacityEnabled, - wantCapacity: &enabled, - }, - { - name: "capacity feature disabled, before: none, update: disabled", + name: "capacity feature enabled, before: none, update: enabled", old: driverWithNothing, - update: driverWithCapacityDisabled, - wantCapacity: nil, + update: driverWithCapacityEnabled, + wantCapacity: &enabled, }, { - name: "capacity feature disabled, before: enabled, update: disabled", + name: "capacity feature enabled, before: enabled, update: disabled", old: driverWithCapacityEnabled, update: driverWithCapacityDisabled, wantCapacity: &disabled, @@ -291,7 +267,6 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, test.csiStorageCapacityEnabled)() defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, test.csiInlineVolumeEnabled)() csiDriver := test.update.DeepCopy() diff --git a/pkg/registry/storage/csistoragecapacity/strategy_test.go b/pkg/registry/storage/csistoragecapacity/strategy_test.go index 048503274fcc..04e4cc88510c 100644 --- a/pkg/registry/storage/csistoragecapacity/strategy_test.go +++ b/pkg/registry/storage/csistoragecapacity/strategy_test.go @@ -24,10 +24,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/diff" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" - utilfeature "k8s.io/apiserver/pkg/util/feature" - featuregatetesting "k8s.io/component-base/featuregate/testing" "k8s.io/kubernetes/pkg/apis/storage" - "k8s.io/kubernetes/pkg/features" ) // getValidCSIStorageCapacity returns a fully-populated CSIStorageCapacity. @@ -159,8 +156,6 @@ func TestCSIStorageCapacityValidation(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, true)() - oldCapacity := test.old.DeepCopy() Strategy.PrepareForCreate(ctx, oldCapacity) errs := Strategy.Validate(ctx, oldCapacity) diff --git a/pkg/registry/storage/rest/storage_storage.go b/pkg/registry/storage/rest/storage_storage.go index b4d73aafe1d5..207c6f1b3202 100644 --- a/pkg/registry/storage/rest/storage_storage.go +++ b/pkg/registry/storage/rest/storage_storage.go @@ -131,6 +131,15 @@ func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.API storage[resource] = csiDriverStorage.CSIDriver } + // register csistoragecapacities + if resource := "csistoragecapacities"; apiResourceConfigSource.ResourceEnabled(storageapiv1.SchemeGroupVersion.WithResource(resource)) { + csiStorageStorage, err := csistoragecapacitystore.NewStorage(restOptionsGetter) + if err != nil { + return storage, err + } + storage[resource] = csiStorageStorage.CSIStorageCapacity + } + return storage, nil } diff --git a/pkg/scheduler/eventhandlers.go b/pkg/scheduler/eventhandlers.go index 96ae9536af57..0e579ea1549d 100644 --- a/pkg/scheduler/eventhandlers.go +++ b/pkg/scheduler/eventhandlers.go @@ -353,7 +353,7 @@ func addAllEventHandlers( buildEvtResHandler(at, framework.CSIDriver, "CSIDriver"), ) case framework.CSIStorageCapacity: - informerFactory.Storage().V1beta1().CSIStorageCapacities().Informer().AddEventHandler( + informerFactory.Storage().V1().CSIStorageCapacities().Informer().AddEventHandler( buildEvtResHandler(at, framework.CSIStorageCapacity, "CSIStorageCapacity"), ) case framework.PersistentVolume: diff --git a/pkg/scheduler/eventhandlers_test.go b/pkg/scheduler/eventhandlers_test.go index 81522ca98924..7b7d5ccf6b54 100644 --- a/pkg/scheduler/eventhandlers_test.go +++ b/pkg/scheduler/eventhandlers_test.go @@ -26,7 +26,7 @@ import ( appsv1 "k8s.io/api/apps/v1" batchv1 "k8s.io/api/batch/v1" v1 "k8s.io/api/core/v1" - storagev1beta1 "k8s.io/api/storage/v1beta1" + storagev1 "k8s.io/api/storage/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -383,11 +383,11 @@ func TestAddAllEventHandlers(t *testing.T) { "storage.k8s.io/CSIStorageCapacity": framework.Update, }, expectStaticInformers: map[reflect.Type]bool{ - reflect.TypeOf(&v1.Pod{}): true, - reflect.TypeOf(&v1.Node{}): true, - reflect.TypeOf(&v1.Namespace{}): true, - reflect.TypeOf(&v1.PersistentVolume{}): true, - reflect.TypeOf(&storagev1beta1.CSIStorageCapacity{}): true, + reflect.TypeOf(&v1.Pod{}): true, + reflect.TypeOf(&v1.Node{}): true, + reflect.TypeOf(&v1.Namespace{}): true, + reflect.TypeOf(&v1.PersistentVolume{}): true, + reflect.TypeOf(&storagev1.CSIStorageCapacity{}): true, }, expectDynamicInformers: map[schema.GroupVersionResource]bool{}, }, diff --git a/pkg/scheduler/framework/plugins/feature/feature.go b/pkg/scheduler/framework/plugins/feature/feature.go index 38ba8a779061..cc45a46c98ba 100644 --- a/pkg/scheduler/framework/plugins/feature/feature.go +++ b/pkg/scheduler/framework/plugins/feature/feature.go @@ -25,6 +25,5 @@ type Features struct { EnablePodOverhead bool EnableReadWriteOncePod bool EnableVolumeCapacityPriority bool - EnableCSIStorageCapacity bool EnableMinDomainsInPodTopologySpread bool } diff --git a/pkg/scheduler/framework/plugins/registry.go b/pkg/scheduler/framework/plugins/registry.go index 793b6c895b0b..aefb9bf43a99 100644 --- a/pkg/scheduler/framework/plugins/registry.go +++ b/pkg/scheduler/framework/plugins/registry.go @@ -49,7 +49,6 @@ func NewInTreeRegistry() runtime.Registry { EnablePodOverhead: feature.DefaultFeatureGate.Enabled(features.PodOverhead), EnableReadWriteOncePod: feature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod), EnableVolumeCapacityPriority: feature.DefaultFeatureGate.Enabled(features.VolumeCapacityPriority), - EnableCSIStorageCapacity: feature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity), EnableMinDomainsInPodTopologySpread: feature.DefaultFeatureGate.Enabled(features.MinDomainsInPodTopologySpread), } diff --git a/pkg/scheduler/framework/plugins/volumebinding/binder.go b/pkg/scheduler/framework/plugins/volumebinding/binder.go index 7e4405423f37..4930cea4d561 100644 --- a/pkg/scheduler/framework/plugins/volumebinding/binder.go +++ b/pkg/scheduler/framework/plugins/volumebinding/binder.go @@ -25,7 +25,6 @@ import ( v1 "k8s.io/api/core/v1" storagev1 "k8s.io/api/storage/v1" - storagev1beta1 "k8s.io/api/storage/v1beta1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -35,11 +34,9 @@ import ( utilfeature "k8s.io/apiserver/pkg/util/feature" coreinformers "k8s.io/client-go/informers/core/v1" storageinformers "k8s.io/client-go/informers/storage/v1" - storageinformersv1beta1 "k8s.io/client-go/informers/storage/v1beta1" clientset "k8s.io/client-go/kubernetes" corelisters "k8s.io/client-go/listers/core/v1" storagelisters "k8s.io/client-go/listers/storage/v1" - storagelistersv1beta1 "k8s.io/client-go/listers/storage/v1beta1" "k8s.io/component-helpers/storage/ephemeral" storagehelpers "k8s.io/component-helpers/storage/volume" csitrans "k8s.io/csi-translation-lib" @@ -209,9 +206,8 @@ type volumeBinder struct { translator InTreeToCSITranslator - capacityCheckEnabled bool csiDriverLister storagelisters.CSIDriverLister - csiStorageCapacityLister storagelistersv1beta1.CSIStorageCapacityLister + csiStorageCapacityLister storagelisters.CSIStorageCapacityLister } // CapacityCheck contains additional parameters for NewVolumeBinder that @@ -219,12 +215,12 @@ type volumeBinder struct { // capacity is desired. type CapacityCheck struct { CSIDriverInformer storageinformers.CSIDriverInformer - CSIStorageCapacityInformer storageinformersv1beta1.CSIStorageCapacityInformer + CSIStorageCapacityInformer storageinformers.CSIStorageCapacityInformer } // NewVolumeBinder sets up all the caches needed for the scheduler to make volume binding decisions. // -// capacityCheck determines whether storage capacity is checked (CSIStorageCapacity feature). +// capacityCheck determines how storage capacity is checked (CSIStorageCapacity feature). func NewVolumeBinder( kubeClient clientset.Interface, podInformer coreinformers.PodInformer, @@ -233,7 +229,7 @@ func NewVolumeBinder( pvcInformer coreinformers.PersistentVolumeClaimInformer, pvInformer coreinformers.PersistentVolumeInformer, storageClassInformer storageinformers.StorageClassInformer, - capacityCheck *CapacityCheck, + capacityCheck CapacityCheck, bindTimeout time.Duration) SchedulerVolumeBinder { b := &volumeBinder{ kubeClient: kubeClient, @@ -247,11 +243,8 @@ func NewVolumeBinder( translator: csitrans.New(), } - if capacityCheck != nil { - b.capacityCheckEnabled = true - b.csiDriverLister = capacityCheck.CSIDriverInformer.Lister() - b.csiStorageCapacityLister = capacityCheck.CSIStorageCapacityInformer.Lister() - } + b.csiDriverLister = capacityCheck.CSIDriverInformer.Lister() + b.csiStorageCapacityLister = capacityCheck.CSIStorageCapacityInformer.Lister() return b } @@ -922,12 +915,6 @@ func (b *volumeBinder) revertAssumedPVCs(claims []*v1.PersistentVolumeClaim) { // hasEnoughCapacity checks whether the provisioner has enough capacity left for a new volume of the given size // that is available from the node. func (b *volumeBinder) hasEnoughCapacity(provisioner string, claim *v1.PersistentVolumeClaim, storageClass *storagev1.StorageClass, node *v1.Node) (bool, error) { - // This is an optional feature. If disabled, we assume that - // there is enough storage. - if !b.capacityCheckEnabled { - return true, nil - } - quantity, ok := claim.Spec.Resources.Requests[v1.ResourceStorage] if !ok { // No capacity to check for. @@ -973,7 +960,7 @@ func (b *volumeBinder) hasEnoughCapacity(provisioner string, claim *v1.Persisten return false, nil } -func capacitySufficient(capacity *storagev1beta1.CSIStorageCapacity, sizeInBytes int64) bool { +func capacitySufficient(capacity *storagev1.CSIStorageCapacity, sizeInBytes int64) bool { limit := capacity.Capacity if capacity.MaximumVolumeSize != nil { // Prefer MaximumVolumeSize if available, it is more precise. @@ -982,7 +969,7 @@ func capacitySufficient(capacity *storagev1beta1.CSIStorageCapacity, sizeInBytes return limit != nil && limit.Value() >= sizeInBytes } -func (b *volumeBinder) nodeHasAccess(node *v1.Node, capacity *storagev1beta1.CSIStorageCapacity) bool { +func (b *volumeBinder) nodeHasAccess(node *v1.Node, capacity *storagev1.CSIStorageCapacity) bool { if capacity.NodeTopology == nil { // Unavailable return false diff --git a/pkg/scheduler/framework/plugins/volumebinding/binder_test.go b/pkg/scheduler/framework/plugins/volumebinding/binder_test.go index 8d45e646112a..555068a94a19 100644 --- a/pkg/scheduler/framework/plugins/volumebinding/binder_test.go +++ b/pkg/scheduler/framework/plugins/volumebinding/binder_test.go @@ -27,7 +27,6 @@ import ( v1 "k8s.io/api/core/v1" storagev1 "k8s.io/api/storage/v1" - storagev1beta1 "k8s.io/api/storage/v1beta1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -38,7 +37,6 @@ import ( "k8s.io/client-go/informers" coreinformers "k8s.io/client-go/informers/core/v1" storageinformers "k8s.io/client-go/informers/storage/v1" - storageinformersv1beta1 "k8s.io/client-go/informers/storage/v1beta1" clientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/fake" k8stesting "k8s.io/client-go/testing" @@ -141,10 +139,10 @@ type testEnv struct { // For CSIStorageCapacity feature testing: internalCSIDriverInformer storageinformers.CSIDriverInformer - internalCSIStorageCapacityInformer storageinformersv1beta1.CSIStorageCapacityInformer + internalCSIStorageCapacityInformer storageinformers.CSIStorageCapacityInformer } -func newTestBinder(t *testing.T, stopCh <-chan struct{}, csiStorageCapacity ...bool) *testEnv { +func newTestBinder(t *testing.T, stopCh <-chan struct{}) *testEnv { client := &fake.Clientset{} reactor := pvtesting.NewVolumeReactor(client, nil, nil, nil) // TODO refactor all tests to use real watch mechanism, see #72327 @@ -165,13 +163,10 @@ func newTestBinder(t *testing.T, stopCh <-chan struct{}, csiStorageCapacity ...b pvcInformer := informerFactory.Core().V1().PersistentVolumeClaims() classInformer := informerFactory.Storage().V1().StorageClasses() csiDriverInformer := informerFactory.Storage().V1().CSIDrivers() - csiStorageCapacityInformer := informerFactory.Storage().V1beta1().CSIStorageCapacities() - var capacityCheck *CapacityCheck - if len(csiStorageCapacity) > 0 && csiStorageCapacity[0] { - capacityCheck = &CapacityCheck{ - CSIDriverInformer: csiDriverInformer, - CSIStorageCapacityInformer: csiStorageCapacityInformer, - } + csiStorageCapacityInformer := informerFactory.Storage().V1().CSIStorageCapacities() + capacityCheck := CapacityCheck{ + CSIDriverInformer: csiDriverInformer, + CSIStorageCapacityInformer: csiStorageCapacityInformer, } binder := NewVolumeBinder( client, @@ -304,7 +299,7 @@ func (env *testEnv) addCSIDriver(csiDriver *storagev1.CSIDriver) { csiDriverInformer.GetIndexer().Add(csiDriver) } -func (env *testEnv) addCSIStorageCapacities(capacities []*storagev1beta1.CSIStorageCapacity) { +func (env *testEnv) addCSIStorageCapacities(capacities []*storagev1.CSIStorageCapacity) { csiStorageCapacityInformer := env.internalCSIStorageCapacityInformer.Informer() for _, capacity := range capacities { csiStorageCapacityInformer.GetIndexer().Add(capacity) @@ -739,8 +734,8 @@ func makeCSIDriver(name string, storageCapacity bool) *storagev1.CSIDriver { } } -func makeCapacity(name, storageClassName string, node *v1.Node, capacityStr, maximumVolumeSizeStr string) *storagev1beta1.CSIStorageCapacity { - c := &storagev1beta1.CSIStorageCapacity{ +func makeCapacity(name, storageClassName string, node *v1.Node, capacityStr, maximumVolumeSizeStr string) *storagev1.CSIStorageCapacity { + c := &storagev1.CSIStorageCapacity{ ObjectMeta: metav1.ObjectMeta{ Name: name, }, @@ -970,12 +965,12 @@ func TestFindPodVolumesWithoutProvisioning(t *testing.T) { }, } - run := func(t *testing.T, scenario scenarioType, csiStorageCapacity bool, csiDriver *storagev1.CSIDriver) { + run := func(t *testing.T, scenario scenarioType, csiDriver *storagev1.CSIDriver) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() // Setup - testEnv := newTestBinder(t, ctx.Done(), csiStorageCapacity) + testEnv := newTestBinder(t, ctx.Done()) testEnv.initVolumes(scenario.pvs, scenario.pvs) if csiDriver != nil { testEnv.addCSIDriver(csiDriver) @@ -1009,18 +1004,14 @@ func TestFindPodVolumesWithoutProvisioning(t *testing.T) { testEnv.validatePodCache(t, testNode.Name, scenario.pod, podVolumes, scenario.expectedBindings, nil) } - for prefix, csiStorageCapacity := range map[string]bool{"with": true, "without": false} { - t.Run(fmt.Sprintf("%s CSIStorageCapacity", prefix), func(t *testing.T) { - for description, csiDriver := range map[string]*storagev1.CSIDriver{ - "no CSIDriver": nil, - "CSIDriver with capacity tracking": makeCSIDriver(provisioner, true), - "CSIDriver without capacity tracking": makeCSIDriver(provisioner, false), - } { - t.Run(description, func(t *testing.T) { - for name, scenario := range scenarios { - t.Run(name, func(t *testing.T) { run(t, scenario, csiStorageCapacity, csiDriver) }) - } - }) + for description, csiDriver := range map[string]*storagev1.CSIDriver{ + "no CSIDriver": nil, + "CSIDriver with capacity tracking": makeCSIDriver(provisioner, true), + "CSIDriver without capacity tracking": makeCSIDriver(provisioner, false), + } { + t.Run(description, func(t *testing.T) { + for name, scenario := range scenarios { + t.Run(name, func(t *testing.T) { run(t, scenario, csiDriver) }) } }) } @@ -1101,12 +1092,12 @@ func TestFindPodVolumesWithProvisioning(t *testing.T) { }, } - run := func(t *testing.T, scenario scenarioType, csiStorageCapacity bool, csiDriver *storagev1.CSIDriver) { + run := func(t *testing.T, scenario scenarioType, csiDriver *storagev1.CSIDriver) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() // Setup - testEnv := newTestBinder(t, ctx.Done(), csiStorageCapacity) + testEnv := newTestBinder(t, ctx.Done()) testEnv.initVolumes(scenario.pvs, scenario.pvs) if csiDriver != nil { testEnv.addCSIDriver(csiDriver) @@ -1138,7 +1129,7 @@ func TestFindPodVolumesWithProvisioning(t *testing.T) { } expectedReasons := scenario.reasons expectedProvisions := scenario.expectedProvisions - if scenario.needsCapacity && csiStorageCapacity && + if scenario.needsCapacity && csiDriver != nil && csiDriver.Spec.StorageCapacity != nil && *csiDriver.Spec.StorageCapacity { // Without CSIStorageCapacity objects, provisioning is blocked. expectedReasons = append(expectedReasons, ErrReasonNotEnoughSpace) @@ -1148,18 +1139,14 @@ func TestFindPodVolumesWithProvisioning(t *testing.T) { testEnv.validatePodCache(t, testNode.Name, scenario.pod, podVolumes, scenario.expectedBindings, expectedProvisions) } - for prefix, csiStorageCapacity := range map[string]bool{"with": true, "without": false} { - t.Run(fmt.Sprintf("%s CSIStorageCapacity", prefix), func(t *testing.T) { - for description, csiDriver := range map[string]*storagev1.CSIDriver{ - "no CSIDriver": nil, - "CSIDriver with capacity tracking": makeCSIDriver(provisioner, true), - "CSIDriver without capacity tracking": makeCSIDriver(provisioner, false), - } { - t.Run(description, func(t *testing.T) { - for name, scenario := range scenarios { - t.Run(name, func(t *testing.T) { run(t, scenario, csiStorageCapacity, csiDriver) }) - } - }) + for description, csiDriver := range map[string]*storagev1.CSIDriver{ + "no CSIDriver": nil, + "CSIDriver with capacity tracking": makeCSIDriver(provisioner, true), + "CSIDriver without capacity tracking": makeCSIDriver(provisioner, false), + } { + t.Run(description, func(t *testing.T) { + for name, scenario := range scenarios { + t.Run(name, func(t *testing.T) { run(t, scenario, csiDriver) }) } }) } @@ -2170,7 +2157,7 @@ func TestCapacity(t *testing.T) { type scenarioType struct { // Inputs pvcs []*v1.PersistentVolumeClaim - capacities []*storagev1beta1.CSIStorageCapacity + capacities []*storagev1.CSIStorageCapacity // Expected return values reasons ConflictReasons @@ -2179,19 +2166,19 @@ func TestCapacity(t *testing.T) { scenarios := map[string]scenarioType{ "network-attached": { pvcs: []*v1.PersistentVolumeClaim{provisionedPVC}, - capacities: []*storagev1beta1.CSIStorageCapacity{ + capacities: []*storagev1.CSIStorageCapacity{ makeCapacity("net", waitClassWithProvisioner, nil, "1Gi", ""), }, }, "local-storage": { pvcs: []*v1.PersistentVolumeClaim{provisionedPVC}, - capacities: []*storagev1beta1.CSIStorageCapacity{ + capacities: []*storagev1.CSIStorageCapacity{ makeCapacity("net", waitClassWithProvisioner, node1, "1Gi", ""), }, }, "multiple": { pvcs: []*v1.PersistentVolumeClaim{provisionedPVC}, - capacities: []*storagev1beta1.CSIStorageCapacity{ + capacities: []*storagev1.CSIStorageCapacity{ makeCapacity("net", waitClassWithProvisioner, nil, "1Gi", ""), makeCapacity("net", waitClassWithProvisioner, node2, "1Gi", ""), makeCapacity("net", waitClassWithProvisioner, node1, "1Gi", ""), @@ -2203,49 +2190,49 @@ func TestCapacity(t *testing.T) { }, "wrong-node": { pvcs: []*v1.PersistentVolumeClaim{provisionedPVC}, - capacities: []*storagev1beta1.CSIStorageCapacity{ + capacities: []*storagev1.CSIStorageCapacity{ makeCapacity("net", waitClassWithProvisioner, node2, "1Gi", ""), }, reasons: ConflictReasons{ErrReasonNotEnoughSpace}, }, "wrong-storage-class": { pvcs: []*v1.PersistentVolumeClaim{provisionedPVC}, - capacities: []*storagev1beta1.CSIStorageCapacity{ + capacities: []*storagev1.CSIStorageCapacity{ makeCapacity("net", waitClass, node1, "1Gi", ""), }, reasons: ConflictReasons{ErrReasonNotEnoughSpace}, }, "insufficient-storage": { pvcs: []*v1.PersistentVolumeClaim{provisionedPVC}, - capacities: []*storagev1beta1.CSIStorageCapacity{ + capacities: []*storagev1.CSIStorageCapacity{ makeCapacity("net", waitClassWithProvisioner, node1, "1Mi", ""), }, reasons: ConflictReasons{ErrReasonNotEnoughSpace}, }, "insufficient-volume-size": { pvcs: []*v1.PersistentVolumeClaim{provisionedPVC}, - capacities: []*storagev1beta1.CSIStorageCapacity{ + capacities: []*storagev1.CSIStorageCapacity{ makeCapacity("net", waitClassWithProvisioner, node1, "1Gi", "1Mi"), }, reasons: ConflictReasons{ErrReasonNotEnoughSpace}, }, "zero-storage": { pvcs: []*v1.PersistentVolumeClaim{provisionedPVC}, - capacities: []*storagev1beta1.CSIStorageCapacity{ + capacities: []*storagev1.CSIStorageCapacity{ makeCapacity("net", waitClassWithProvisioner, node1, "0Mi", ""), }, reasons: ConflictReasons{ErrReasonNotEnoughSpace}, }, "zero-volume-size": { pvcs: []*v1.PersistentVolumeClaim{provisionedPVC}, - capacities: []*storagev1beta1.CSIStorageCapacity{ + capacities: []*storagev1.CSIStorageCapacity{ makeCapacity("net", waitClassWithProvisioner, node1, "", "0Mi"), }, reasons: ConflictReasons{ErrReasonNotEnoughSpace}, }, "nil-storage": { pvcs: []*v1.PersistentVolumeClaim{provisionedPVC}, - capacities: []*storagev1beta1.CSIStorageCapacity{ + capacities: []*storagev1.CSIStorageCapacity{ makeCapacity("net", waitClassWithProvisioner, node1, "", ""), }, reasons: ConflictReasons{ErrReasonNotEnoughSpace}, @@ -2261,13 +2248,12 @@ func TestCapacity(t *testing.T) { }, } - run := func(t *testing.T, scenario scenarioType, featureEnabled, optIn bool) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, featureEnabled)() + run := func(t *testing.T, scenario scenarioType, optIn bool) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() // Setup: the driver has the feature enabled, but the scheduler might not. - testEnv := newTestBinder(t, ctx.Done(), featureEnabled) + testEnv := newTestBinder(t, ctx.Done()) testEnv.addCSIDriver(makeCSIDriver(provisioner, optIn)) testEnv.addCSIStorageCapacities(scenario.capacities) @@ -2286,7 +2272,7 @@ func TestCapacity(t *testing.T) { // Validate shouldFail := scenario.shouldFail expectedReasons := scenario.reasons - if !featureEnabled || !optIn { + if !optIn { shouldFail = false expectedReasons = nil } @@ -2305,16 +2291,11 @@ func TestCapacity(t *testing.T) { } yesNo := []bool{true, false} - for _, featureEnabled := range yesNo { - name := fmt.Sprintf("CSIStorageCapacity=%v", featureEnabled) + for _, optIn := range yesNo { + name := fmt.Sprintf("CSIDriver.StorageCapacity=%v", optIn) t.Run(name, func(t *testing.T) { - for _, optIn := range yesNo { - name := fmt.Sprintf("CSIDriver.StorageCapacity=%v", optIn) - t.Run(name, func(t *testing.T) { - for name, scenario := range scenarios { - t.Run(name, func(t *testing.T) { run(t, scenario, featureEnabled, optIn) }) - } - }) + for name, scenario := range scenarios { + t.Run(name, func(t *testing.T) { run(t, scenario, optIn) }) } }) } diff --git a/pkg/scheduler/framework/plugins/volumebinding/volume_binding.go b/pkg/scheduler/framework/plugins/volumebinding/volume_binding.go index 34bfb0773bc4..54b1a8b47804 100644 --- a/pkg/scheduler/framework/plugins/volumebinding/volume_binding.go +++ b/pkg/scheduler/framework/plugins/volumebinding/volume_binding.go @@ -107,14 +107,10 @@ func (pl *VolumeBinding) EventsToRegister() []framework.ClusterEvent { {Resource: framework.Node, ActionType: framework.Add | framework.UpdateNodeLabel}, // We rely on CSI node to translate in-tree PV to CSI. {Resource: framework.CSINode, ActionType: framework.Add | framework.Update}, - } - if pl.fts.EnableCSIStorageCapacity { // When CSIStorageCapacity is enabled, pods may become schedulable // on CSI driver & storage capacity changes. - events = append(events, []framework.ClusterEvent{ - {Resource: framework.CSIDriver, ActionType: framework.Add | framework.Update}, - {Resource: framework.CSIStorageCapacity, ActionType: framework.Add | framework.Update}, - }...) + {Resource: framework.CSIDriver, ActionType: framework.Add | framework.Update}, + {Resource: framework.CSIStorageCapacity, ActionType: framework.Add | framework.Update}, } return events } @@ -379,12 +375,9 @@ func New(plArgs runtime.Object, fh framework.Handle, fts feature.Features) (fram pvInformer := fh.SharedInformerFactory().Core().V1().PersistentVolumes() storageClassInformer := fh.SharedInformerFactory().Storage().V1().StorageClasses() csiNodeInformer := fh.SharedInformerFactory().Storage().V1().CSINodes() - var capacityCheck *CapacityCheck - if fts.EnableCSIStorageCapacity { - capacityCheck = &CapacityCheck{ - CSIDriverInformer: fh.SharedInformerFactory().Storage().V1().CSIDrivers(), - CSIStorageCapacityInformer: fh.SharedInformerFactory().Storage().V1beta1().CSIStorageCapacities(), - } + capacityCheck := CapacityCheck{ + CSIDriverInformer: fh.SharedInformerFactory().Storage().V1().CSIDrivers(), + CSIStorageCapacityInformer: fh.SharedInformerFactory().Storage().V1().CSIStorageCapacities(), } binder := NewVolumeBinder(fh.ClientSet(), podInformer, nodeInformer, csiNodeInformer, pvcInformer, pvInformer, storageClassInformer, capacityCheck, time.Duration(args.BindTimeoutSeconds)*time.Second) diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go index 40e8a2535c99..514e9a5d916b 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go @@ -551,12 +551,8 @@ func ClusterRoles() []rbacv1.ClusterRole { rbacv1helpers.NewRule(Read...).Groups(storageGroup).Resources("csinodes").RuleOrDie(), // Needed for namespaceSelector feature in pod affinity rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("namespaces").RuleOrDie(), - } - if utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) { - kubeSchedulerRules = append(kubeSchedulerRules, - rbacv1helpers.NewRule(Read...).Groups(storageGroup).Resources("csidrivers").RuleOrDie(), - rbacv1helpers.NewRule(Read...).Groups(storageGroup).Resources("csistoragecapacities").RuleOrDie(), - ) + rbacv1helpers.NewRule(Read...).Groups(storageGroup).Resources("csidrivers").RuleOrDie(), + rbacv1helpers.NewRule(Read...).Groups(storageGroup).Resources("csistoragecapacities").RuleOrDie(), } roles = append(roles, rbacv1.ClusterRole{ // a role to use for the kube-scheduler diff --git a/staging/src/k8s.io/api/storage/v1/generated.pb.go b/staging/src/k8s.io/api/storage/v1/generated.pb.go index c5a8332e8443..a648c426aab1 100644 --- a/staging/src/k8s.io/api/storage/v1/generated.pb.go +++ b/staging/src/k8s.io/api/storage/v1/generated.pb.go @@ -28,6 +28,8 @@ import ( github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" k8s_io_api_core_v1 "k8s.io/api/core/v1" v11 "k8s.io/api/core/v1" + resource "k8s.io/apimachinery/pkg/api/resource" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" math "math" math_bits "math/bits" @@ -242,10 +244,66 @@ func (m *CSINodeSpec) XXX_DiscardUnknown() { var xxx_messageInfo_CSINodeSpec proto.InternalMessageInfo +func (m *CSIStorageCapacity) Reset() { *m = CSIStorageCapacity{} } +func (*CSIStorageCapacity) ProtoMessage() {} +func (*CSIStorageCapacity) Descriptor() ([]byte, []int) { + return fileDescriptor_3b530c1983504d8d, []int{7} +} +func (m *CSIStorageCapacity) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CSIStorageCapacity) 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 *CSIStorageCapacity) XXX_Merge(src proto.Message) { + xxx_messageInfo_CSIStorageCapacity.Merge(m, src) +} +func (m *CSIStorageCapacity) XXX_Size() int { + return m.Size() +} +func (m *CSIStorageCapacity) XXX_DiscardUnknown() { + xxx_messageInfo_CSIStorageCapacity.DiscardUnknown(m) +} + +var xxx_messageInfo_CSIStorageCapacity proto.InternalMessageInfo + +func (m *CSIStorageCapacityList) Reset() { *m = CSIStorageCapacityList{} } +func (*CSIStorageCapacityList) ProtoMessage() {} +func (*CSIStorageCapacityList) Descriptor() ([]byte, []int) { + return fileDescriptor_3b530c1983504d8d, []int{8} +} +func (m *CSIStorageCapacityList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CSIStorageCapacityList) 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 *CSIStorageCapacityList) XXX_Merge(src proto.Message) { + xxx_messageInfo_CSIStorageCapacityList.Merge(m, src) +} +func (m *CSIStorageCapacityList) XXX_Size() int { + return m.Size() +} +func (m *CSIStorageCapacityList) XXX_DiscardUnknown() { + xxx_messageInfo_CSIStorageCapacityList.DiscardUnknown(m) +} + +var xxx_messageInfo_CSIStorageCapacityList proto.InternalMessageInfo + func (m *StorageClass) Reset() { *m = StorageClass{} } func (*StorageClass) ProtoMessage() {} func (*StorageClass) Descriptor() ([]byte, []int) { - return fileDescriptor_3b530c1983504d8d, []int{7} + return fileDescriptor_3b530c1983504d8d, []int{9} } func (m *StorageClass) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -273,7 +331,7 @@ var xxx_messageInfo_StorageClass proto.InternalMessageInfo func (m *StorageClassList) Reset() { *m = StorageClassList{} } func (*StorageClassList) ProtoMessage() {} func (*StorageClassList) Descriptor() ([]byte, []int) { - return fileDescriptor_3b530c1983504d8d, []int{8} + return fileDescriptor_3b530c1983504d8d, []int{10} } func (m *StorageClassList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -301,7 +359,7 @@ var xxx_messageInfo_StorageClassList proto.InternalMessageInfo func (m *TokenRequest) Reset() { *m = TokenRequest{} } func (*TokenRequest) ProtoMessage() {} func (*TokenRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_3b530c1983504d8d, []int{9} + return fileDescriptor_3b530c1983504d8d, []int{11} } func (m *TokenRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -329,7 +387,7 @@ var xxx_messageInfo_TokenRequest proto.InternalMessageInfo func (m *VolumeAttachment) Reset() { *m = VolumeAttachment{} } func (*VolumeAttachment) ProtoMessage() {} func (*VolumeAttachment) Descriptor() ([]byte, []int) { - return fileDescriptor_3b530c1983504d8d, []int{10} + return fileDescriptor_3b530c1983504d8d, []int{12} } func (m *VolumeAttachment) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -357,7 +415,7 @@ var xxx_messageInfo_VolumeAttachment proto.InternalMessageInfo func (m *VolumeAttachmentList) Reset() { *m = VolumeAttachmentList{} } func (*VolumeAttachmentList) ProtoMessage() {} func (*VolumeAttachmentList) Descriptor() ([]byte, []int) { - return fileDescriptor_3b530c1983504d8d, []int{11} + return fileDescriptor_3b530c1983504d8d, []int{13} } func (m *VolumeAttachmentList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -385,7 +443,7 @@ var xxx_messageInfo_VolumeAttachmentList proto.InternalMessageInfo func (m *VolumeAttachmentSource) Reset() { *m = VolumeAttachmentSource{} } func (*VolumeAttachmentSource) ProtoMessage() {} func (*VolumeAttachmentSource) Descriptor() ([]byte, []int) { - return fileDescriptor_3b530c1983504d8d, []int{12} + return fileDescriptor_3b530c1983504d8d, []int{14} } func (m *VolumeAttachmentSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -413,7 +471,7 @@ var xxx_messageInfo_VolumeAttachmentSource proto.InternalMessageInfo func (m *VolumeAttachmentSpec) Reset() { *m = VolumeAttachmentSpec{} } func (*VolumeAttachmentSpec) ProtoMessage() {} func (*VolumeAttachmentSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_3b530c1983504d8d, []int{13} + return fileDescriptor_3b530c1983504d8d, []int{15} } func (m *VolumeAttachmentSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -441,7 +499,7 @@ var xxx_messageInfo_VolumeAttachmentSpec proto.InternalMessageInfo func (m *VolumeAttachmentStatus) Reset() { *m = VolumeAttachmentStatus{} } func (*VolumeAttachmentStatus) ProtoMessage() {} func (*VolumeAttachmentStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_3b530c1983504d8d, []int{14} + return fileDescriptor_3b530c1983504d8d, []int{16} } func (m *VolumeAttachmentStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -469,7 +527,7 @@ var xxx_messageInfo_VolumeAttachmentStatus proto.InternalMessageInfo func (m *VolumeError) Reset() { *m = VolumeError{} } func (*VolumeError) ProtoMessage() {} func (*VolumeError) Descriptor() ([]byte, []int) { - return fileDescriptor_3b530c1983504d8d, []int{15} + return fileDescriptor_3b530c1983504d8d, []int{17} } func (m *VolumeError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -497,7 +555,7 @@ var xxx_messageInfo_VolumeError proto.InternalMessageInfo func (m *VolumeNodeResources) Reset() { *m = VolumeNodeResources{} } func (*VolumeNodeResources) ProtoMessage() {} func (*VolumeNodeResources) Descriptor() ([]byte, []int) { - return fileDescriptor_3b530c1983504d8d, []int{16} + return fileDescriptor_3b530c1983504d8d, []int{18} } func (m *VolumeNodeResources) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -530,6 +588,8 @@ func init() { proto.RegisterType((*CSINodeDriver)(nil), "k8s.io.api.storage.v1.CSINodeDriver") proto.RegisterType((*CSINodeList)(nil), "k8s.io.api.storage.v1.CSINodeList") proto.RegisterType((*CSINodeSpec)(nil), "k8s.io.api.storage.v1.CSINodeSpec") + proto.RegisterType((*CSIStorageCapacity)(nil), "k8s.io.api.storage.v1.CSIStorageCapacity") + proto.RegisterType((*CSIStorageCapacityList)(nil), "k8s.io.api.storage.v1.CSIStorageCapacityList") proto.RegisterType((*StorageClass)(nil), "k8s.io.api.storage.v1.StorageClass") proto.RegisterMapType((map[string]string)(nil), "k8s.io.api.storage.v1.StorageClass.ParametersEntry") proto.RegisterType((*StorageClassList)(nil), "k8s.io.api.storage.v1.StorageClassList") @@ -549,101 +609,111 @@ func init() { } var fileDescriptor_3b530c1983504d8d = []byte{ - // 1504 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xcd, 0x6f, 0x1b, 0x45, - 0x1b, 0xcf, 0xc6, 0xce, 0xd7, 0x38, 0x69, 0x92, 0x49, 0xf2, 0xbe, 0x7e, 0x73, 0xb0, 0xa3, 0x6d, - 0xf5, 0x12, 0x0a, 0x5d, 0xb7, 0xa5, 0x54, 0x55, 0x51, 0x91, 0xb2, 0x89, 0x4b, 0x23, 0xf2, 0xa5, - 0x71, 0xa8, 0x10, 0x02, 0xd4, 0xc9, 0xee, 0xc4, 0xd9, 0xda, 0xbb, 0xb3, 0xdd, 0x19, 0x9b, 0xfa, - 0x06, 0x17, 0x6e, 0x48, 0x70, 0x45, 0xfc, 0x11, 0x20, 0xc1, 0x85, 0x23, 0xa7, 0x72, 0xab, 0x38, - 0xf5, 0x64, 0x51, 0x73, 0x86, 0x3f, 0x20, 0x27, 0x34, 0xb3, 0x63, 0xef, 0x87, 0xd7, 0x69, 0x7a, - 0xc9, 0xcd, 0xf3, 0x7c, 0xfc, 0x9e, 0x67, 0xe6, 0x79, 0xe6, 0xf7, 0xcc, 0x1a, 0xbc, 0xdf, 0xb8, - 0xc3, 0x0c, 0x87, 0x56, 0x1a, 0xad, 0x23, 0x12, 0x78, 0x84, 0x13, 0x56, 0x69, 0x13, 0xcf, 0xa6, - 0x41, 0x45, 0x29, 0xb0, 0xef, 0x54, 0x18, 0xa7, 0x01, 0xae, 0x93, 0x4a, 0xfb, 0x46, 0xa5, 0x4e, - 0x3c, 0x12, 0x60, 0x4e, 0x6c, 0xc3, 0x0f, 0x28, 0xa7, 0x70, 0x25, 0x34, 0x33, 0xb0, 0xef, 0x18, - 0xca, 0xcc, 0x68, 0xdf, 0x58, 0xbd, 0x56, 0x77, 0xf8, 0x49, 0xeb, 0xc8, 0xb0, 0xa8, 0x5b, 0xa9, - 0xd3, 0x3a, 0xad, 0x48, 0xeb, 0xa3, 0xd6, 0xb1, 0x5c, 0xc9, 0x85, 0xfc, 0x15, 0xa2, 0xac, 0xea, - 0xb1, 0x60, 0x16, 0x0d, 0xb2, 0x22, 0xad, 0xde, 0x8a, 0x6c, 0x5c, 0x6c, 0x9d, 0x38, 0x1e, 0x09, - 0x3a, 0x15, 0xbf, 0x51, 0x17, 0x02, 0x56, 0x71, 0x09, 0xc7, 0x59, 0x5e, 0x95, 0x51, 0x5e, 0x41, - 0xcb, 0xe3, 0x8e, 0x4b, 0x86, 0x1c, 0x6e, 0xbf, 0xca, 0x81, 0x59, 0x27, 0xc4, 0xc5, 0x69, 0x3f, - 0xfd, 0x17, 0x0d, 0xcc, 0x6c, 0xd6, 0xb6, 0xb7, 0x02, 0xa7, 0x4d, 0x02, 0xf8, 0x08, 0x4c, 0x8b, - 0x8c, 0x6c, 0xcc, 0x71, 0x51, 0x5b, 0xd3, 0xd6, 0x0b, 0x37, 0xaf, 0x1b, 0xd1, 0x49, 0x0d, 0x80, - 0x0d, 0xbf, 0x51, 0x17, 0x02, 0x66, 0x08, 0x6b, 0xa3, 0x7d, 0xc3, 0xd8, 0x3f, 0x7a, 0x4c, 0x2c, - 0xbe, 0x4b, 0x38, 0x36, 0xe1, 0xb3, 0x6e, 0x79, 0xac, 0xd7, 0x2d, 0x83, 0x48, 0x86, 0x06, 0xa8, - 0xf0, 0x3e, 0xc8, 0x33, 0x9f, 0x58, 0xc5, 0x71, 0x89, 0x7e, 0xc5, 0xc8, 0xac, 0x83, 0x31, 0xc8, - 0xa8, 0xe6, 0x13, 0xcb, 0x9c, 0x55, 0x88, 0x79, 0xb1, 0x42, 0xd2, 0x5f, 0xff, 0x59, 0x03, 0x73, - 0x03, 0xab, 0x1d, 0x87, 0x71, 0xf8, 0xe9, 0x50, 0xee, 0xc6, 0xf9, 0x72, 0x17, 0xde, 0x32, 0xf3, - 0x05, 0x15, 0x67, 0xba, 0x2f, 0x89, 0xe5, 0x5d, 0x05, 0x13, 0x0e, 0x27, 0x2e, 0x2b, 0x8e, 0xaf, - 0xe5, 0xd6, 0x0b, 0x37, 0xd7, 0x5e, 0x95, 0xb8, 0x39, 0xa7, 0xc0, 0x26, 0xb6, 0x85, 0x1b, 0x0a, - 0xbd, 0xf5, 0x1f, 0xf2, 0xb1, 0xb4, 0xc5, 0x76, 0xe0, 0x5d, 0x70, 0x09, 0x73, 0x8e, 0xad, 0x13, - 0x44, 0x9e, 0xb4, 0x9c, 0x80, 0xd8, 0x32, 0xf9, 0x69, 0x13, 0xf6, 0xba, 0xe5, 0x4b, 0x1b, 0x09, - 0x0d, 0x4a, 0x59, 0x0a, 0x5f, 0x9f, 0xda, 0xdb, 0xde, 0x31, 0xdd, 0xf7, 0x76, 0x69, 0xcb, 0xe3, - 0xf2, 0x58, 0x95, 0xef, 0x41, 0x42, 0x83, 0x52, 0x96, 0xd0, 0x02, 0xcb, 0x6d, 0xda, 0x6c, 0xb9, - 0x64, 0xc7, 0x39, 0x26, 0x56, 0xc7, 0x6a, 0x92, 0x5d, 0x6a, 0x13, 0x56, 0xcc, 0xad, 0xe5, 0xd6, - 0x67, 0xcc, 0x4a, 0xaf, 0x5b, 0x5e, 0x7e, 0x98, 0xa1, 0x3f, 0xed, 0x96, 0x97, 0x32, 0xe4, 0x28, - 0x13, 0x0c, 0xde, 0x03, 0xf3, 0xea, 0x70, 0x36, 0xb1, 0x8f, 0x2d, 0x87, 0x77, 0x8a, 0x79, 0x99, - 0xe1, 0x52, 0xaf, 0x5b, 0x9e, 0xaf, 0x25, 0x55, 0x28, 0x6d, 0x0b, 0x1f, 0x80, 0xb9, 0x63, 0xf6, - 0x41, 0x40, 0x5b, 0xfe, 0x01, 0x6d, 0x3a, 0x56, 0xa7, 0x38, 0xb1, 0xa6, 0xad, 0xcf, 0x98, 0x7a, - 0xaf, 0x5b, 0x9e, 0xbb, 0x5f, 0x8b, 0x29, 0x4e, 0xd3, 0x02, 0x94, 0x74, 0x84, 0x8f, 0xc0, 0x1c, - 0xa7, 0x0d, 0xe2, 0x89, 0xa3, 0x23, 0x8c, 0xb3, 0xe2, 0xa4, 0x2c, 0xe3, 0xe5, 0x11, 0x65, 0x3c, - 0x8c, 0xd9, 0x9a, 0x2b, 0xaa, 0x92, 0x73, 0x71, 0x29, 0x43, 0x49, 0x40, 0xb8, 0x09, 0x16, 0x83, - 0xb0, 0x2e, 0x0c, 0x11, 0xbf, 0x75, 0xd4, 0x74, 0xd8, 0x49, 0x71, 0x4a, 0x6e, 0x76, 0xa5, 0xd7, - 0x2d, 0x2f, 0xa2, 0xb4, 0x12, 0x0d, 0xdb, 0xeb, 0x3f, 0x69, 0x60, 0x6a, 0xb3, 0xb6, 0xbd, 0x47, - 0x6d, 0x72, 0x01, 0x77, 0x71, 0x2b, 0x71, 0x17, 0xf5, 0xd1, 0x2d, 0x2d, 0xf2, 0x19, 0x79, 0x13, - 0xff, 0x09, 0x6f, 0xa2, 0xb0, 0x51, 0x2c, 0xb2, 0x06, 0xf2, 0x1e, 0x76, 0x89, 0xcc, 0x7a, 0x26, - 0xf2, 0xd9, 0xc3, 0x2e, 0x41, 0x52, 0x03, 0xff, 0x0f, 0x26, 0x3d, 0x6a, 0x93, 0xed, 0x2d, 0x19, - 0x7b, 0xc6, 0xbc, 0xa4, 0x6c, 0x26, 0xf7, 0xa4, 0x14, 0x29, 0x2d, 0xbc, 0x05, 0x66, 0x39, 0xf5, - 0x69, 0x93, 0xd6, 0x3b, 0x1f, 0x92, 0x4e, 0xbf, 0x39, 0x17, 0x7a, 0xdd, 0xf2, 0xec, 0x61, 0x4c, - 0x8e, 0x12, 0x56, 0xf0, 0x33, 0x50, 0xc0, 0xcd, 0x26, 0xb5, 0x30, 0xc7, 0x47, 0x4d, 0x22, 0x3b, - 0xae, 0x70, 0xf3, 0xea, 0x88, 0xed, 0x85, 0xcd, 0x2c, 0xe2, 0x22, 0xc2, 0x68, 0x2b, 0xb0, 0x08, - 0x33, 0xe7, 0x7b, 0xdd, 0x72, 0x61, 0x23, 0x82, 0x40, 0x71, 0x3c, 0xfd, 0x47, 0x0d, 0x14, 0xd4, - 0x86, 0x2f, 0x80, 0x78, 0x36, 0x93, 0xc4, 0x53, 0x3a, 0xbb, 0x4a, 0x23, 0x68, 0xe7, 0xf3, 0x41, - 0xc6, 0x92, 0x73, 0xf6, 0xc1, 0x94, 0x2d, 0x4b, 0xc5, 0x8a, 0x9a, 0x44, 0xbd, 0x72, 0x36, 0xaa, - 0xa2, 0xb4, 0x79, 0x85, 0x3d, 0x15, 0xae, 0x19, 0xea, 0xa3, 0xe8, 0xdf, 0x4c, 0x82, 0xd9, 0xfe, - 0x6d, 0x6e, 0x62, 0xc6, 0x2e, 0xa0, 0x79, 0xdf, 0x05, 0x05, 0x3f, 0xa0, 0x6d, 0x87, 0x39, 0xd4, - 0x23, 0x81, 0xea, 0xa3, 0x25, 0xe5, 0x52, 0x38, 0x88, 0x54, 0x28, 0x6e, 0x07, 0xeb, 0x00, 0xf8, - 0x38, 0xc0, 0x2e, 0xe1, 0x62, 0xf7, 0x39, 0xb9, 0xfb, 0x77, 0x46, 0xec, 0x3e, 0xbe, 0x23, 0xe3, - 0x60, 0xe0, 0x55, 0xf5, 0x78, 0xd0, 0x89, 0xb2, 0x8b, 0x14, 0x28, 0x06, 0x0d, 0x1b, 0x60, 0x2e, - 0x20, 0x56, 0x13, 0x3b, 0xae, 0xe2, 0xae, 0xbc, 0xcc, 0xb0, 0x2a, 0x88, 0x04, 0xc5, 0x15, 0xa7, - 0xdd, 0xf2, 0xf5, 0xe1, 0x77, 0x84, 0x71, 0x40, 0x02, 0xe6, 0x30, 0x4e, 0x3c, 0x1e, 0x76, 0x68, - 0xc2, 0x07, 0x25, 0xb1, 0xc5, 0x3d, 0x71, 0x05, 0xab, 0xef, 0xfb, 0xdc, 0xa1, 0x1e, 0x2b, 0x4e, - 0x44, 0xf7, 0x64, 0x37, 0x26, 0x47, 0x09, 0x2b, 0xb8, 0x03, 0x96, 0x45, 0x5f, 0x7f, 0x11, 0x06, - 0xa8, 0x3e, 0xf5, 0xb1, 0x27, 0x4e, 0xa9, 0x38, 0x29, 0x59, 0xab, 0x28, 0x46, 0xc0, 0x46, 0x86, - 0x1e, 0x65, 0x7a, 0xc1, 0x8f, 0xc1, 0x62, 0x38, 0x03, 0x4c, 0xc7, 0xb3, 0x1d, 0xaf, 0x2e, 0x26, - 0x80, 0x24, 0xc0, 0x19, 0xf3, 0xaa, 0x20, 0xc0, 0x87, 0x69, 0xe5, 0x69, 0x96, 0x10, 0x0d, 0x83, - 0xc0, 0x27, 0x60, 0x51, 0x46, 0x24, 0xb6, 0xba, 0xf4, 0x0e, 0x61, 0xc5, 0x69, 0x59, 0xba, 0xf5, - 0x78, 0xe9, 0xc4, 0xd1, 0x85, 0xec, 0x1d, 0x92, 0x41, 0x8d, 0x34, 0x89, 0xc5, 0x69, 0x70, 0x48, - 0x02, 0xd7, 0xfc, 0x9f, 0xaa, 0xd7, 0xe2, 0x46, 0x1a, 0x0a, 0x0d, 0xa3, 0xaf, 0xde, 0x03, 0xf3, - 0xa9, 0x82, 0xc3, 0x05, 0x90, 0x6b, 0x90, 0x4e, 0x48, 0x6a, 0x48, 0xfc, 0x84, 0xcb, 0x60, 0xa2, - 0x8d, 0x9b, 0x2d, 0x12, 0x36, 0x1f, 0x0a, 0x17, 0x77, 0xc7, 0xef, 0x68, 0xfa, 0xaf, 0x1a, 0x58, - 0x88, 0x77, 0xcf, 0x05, 0xf0, 0xc4, 0x83, 0x24, 0x4f, 0x5c, 0x3e, 0x47, 0x4f, 0x8f, 0x20, 0x8b, - 0xaf, 0x34, 0x30, 0x1b, 0x1f, 0x75, 0xf0, 0x6d, 0x30, 0x8d, 0x5b, 0xb6, 0x43, 0x3c, 0xab, 0xcf, - 0xe9, 0x83, 0x44, 0x36, 0x94, 0x1c, 0x0d, 0x2c, 0xc4, 0x20, 0x24, 0x4f, 0x7d, 0x27, 0xc0, 0xa2, - 0xc9, 0x6a, 0xc4, 0xa2, 0x9e, 0xcd, 0xe4, 0x09, 0xe5, 0xc2, 0x41, 0x58, 0x4d, 0x2b, 0xd1, 0xb0, - 0xbd, 0xfe, 0xfd, 0x38, 0x58, 0x08, 0x7b, 0x23, 0x7c, 0x02, 0xb9, 0xc4, 0xe3, 0x17, 0x40, 0x2a, - 0xbb, 0x89, 0x89, 0xf8, 0xd6, 0x99, 0x23, 0x23, 0x4a, 0x6c, 0xd4, 0x68, 0x84, 0x1f, 0x81, 0x49, - 0xc6, 0x31, 0x6f, 0x09, 0xa2, 0x11, 0x80, 0xd7, 0xce, 0x0b, 0x28, 0x9d, 0xa2, 0xa9, 0x18, 0xae, - 0x91, 0x02, 0xd3, 0x7f, 0xd3, 0xc0, 0x72, 0xda, 0xe5, 0x02, 0x3a, 0x6c, 0x27, 0xd9, 0x61, 0x6f, - 0x9c, 0x73, 0x33, 0x23, 0xba, 0xec, 0x0f, 0x0d, 0xfc, 0x67, 0x68, 0xdf, 0x72, 0xfe, 0x0a, 0x5e, - 0xf2, 0x53, 0xec, 0xb7, 0x17, 0xbd, 0x27, 0x24, 0x2f, 0x1d, 0x64, 0xe8, 0x51, 0xa6, 0x17, 0x7c, - 0x0c, 0x16, 0x1c, 0xaf, 0xe9, 0x78, 0x24, 0x94, 0xd5, 0xa2, 0xfa, 0x66, 0x92, 0x47, 0x1a, 0x59, - 0x16, 0x77, 0xb9, 0xd7, 0x2d, 0x2f, 0x6c, 0xa7, 0x50, 0xd0, 0x10, 0xae, 0xfe, 0x7b, 0x46, 0x65, - 0xe4, 0xc4, 0x15, 0x57, 0x48, 0x4a, 0x48, 0x30, 0x74, 0x85, 0x94, 0x1c, 0x0d, 0x2c, 0x64, 0xdf, - 0xc8, 0xa3, 0x50, 0x89, 0x9e, 0xbb, 0x6f, 0xa4, 0x53, 0xac, 0x6f, 0xe4, 0x1a, 0x29, 0x30, 0x91, - 0x84, 0x78, 0x57, 0xc9, 0xb3, 0xcc, 0x25, 0x93, 0xd8, 0x53, 0x72, 0x34, 0xb0, 0xd0, 0xff, 0xce, - 0x65, 0x14, 0x48, 0x36, 0x60, 0x6c, 0x37, 0xfd, 0xaf, 0x95, 0xf4, 0x6e, 0xec, 0xc1, 0x6e, 0x6c, - 0xf8, 0x9d, 0x06, 0x20, 0x1e, 0x40, 0xec, 0xf6, 0x1b, 0x34, 0xec, 0xa2, 0xea, 0x6b, 0x5d, 0x09, - 0x63, 0x63, 0x08, 0x27, 0x9c, 0xc6, 0xab, 0x2a, 0x3e, 0x1c, 0x36, 0x40, 0x19, 0xc1, 0xa1, 0x0d, - 0x0a, 0xa1, 0xb4, 0x1a, 0x04, 0x34, 0x50, 0xd7, 0x53, 0x3f, 0x33, 0x17, 0x69, 0x69, 0x96, 0xe4, - 0xd3, 0x30, 0x72, 0x3d, 0xed, 0x96, 0x0b, 0x31, 0x3d, 0x8a, 0xc3, 0x8a, 0x28, 0x36, 0x89, 0xa2, - 0xe4, 0x5f, 0x2f, 0xca, 0x16, 0x19, 0x1d, 0x25, 0x06, 0xbb, 0x5a, 0x05, 0xff, 0x1d, 0x71, 0x2c, - 0xaf, 0x35, 0xb3, 0xbe, 0xd6, 0x40, 0x3c, 0x06, 0xdc, 0x01, 0x79, 0xee, 0xa8, 0x5b, 0x97, 0x7c, - 0x3e, 0x9f, 0x41, 0x24, 0x87, 0x8e, 0x4b, 0x22, 0x2a, 0x14, 0x2b, 0x24, 0x51, 0xe0, 0x9b, 0x60, - 0xca, 0x25, 0x8c, 0xe1, 0xba, 0x8a, 0x1c, 0x3d, 0x26, 0x77, 0x43, 0x31, 0xea, 0xeb, 0xf5, 0xdb, - 0x60, 0x29, 0xe3, 0x51, 0x0e, 0xcb, 0x60, 0xc2, 0x92, 0xdf, 0xb8, 0x22, 0xa1, 0x09, 0x73, 0x46, - 0x30, 0xca, 0xa6, 0xfc, 0xb4, 0x0d, 0xe5, 0xe6, 0x7b, 0xcf, 0x5e, 0x96, 0xc6, 0x9e, 0xbf, 0x2c, - 0x8d, 0xbd, 0x78, 0x59, 0x1a, 0xfb, 0xb2, 0x57, 0xd2, 0x9e, 0xf5, 0x4a, 0xda, 0xf3, 0x5e, 0x49, - 0x7b, 0xd1, 0x2b, 0x69, 0x7f, 0xf6, 0x4a, 0xda, 0xb7, 0x7f, 0x95, 0xc6, 0x3e, 0x59, 0xc9, 0xfc, - 0x83, 0xe8, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x95, 0xc1, 0x06, 0xb9, 0x51, 0x12, 0x00, 0x00, + // 1651 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xbd, 0x6f, 0x1b, 0xcb, + 0x11, 0xd7, 0x89, 0xd4, 0xd7, 0x52, 0xb2, 0xa4, 0x95, 0xe4, 0x30, 0x2a, 0x48, 0xe1, 0x6c, 0x24, + 0xb2, 0x13, 0x1f, 0x6d, 0xd9, 0x31, 0x0c, 0x07, 0x0e, 0xa0, 0x93, 0xe8, 0x58, 0x88, 0x28, 0x29, + 0x4b, 0xc5, 0x30, 0x82, 0x24, 0xf0, 0xea, 0x6e, 0x45, 0xad, 0xc5, 0xfb, 0xf0, 0xed, 0x92, 0x31, + 0x53, 0x25, 0x4d, 0xba, 0x00, 0x49, 0x1b, 0xe4, 0x8f, 0x48, 0x80, 0xa4, 0x49, 0x99, 0x22, 0x70, + 0x3a, 0x23, 0x95, 0x2b, 0xe2, 0x99, 0xaf, 0x7e, 0xaf, 0x7c, 0x85, 0xaa, 0x87, 0xdd, 0x5b, 0xf2, + 0x3e, 0x78, 0x94, 0xa5, 0x86, 0x1d, 0x77, 0x67, 0xe6, 0x37, 0xb3, 0x3b, 0xbf, 0x99, 0x9d, 0x23, + 0xf8, 0xc9, 0xf9, 0x13, 0x66, 0x50, 0xaf, 0x72, 0xde, 0x3a, 0x21, 0x81, 0x4b, 0x38, 0x61, 0x95, + 0x36, 0x71, 0x6d, 0x2f, 0xa8, 0x28, 0x01, 0xf6, 0x69, 0x85, 0x71, 0x2f, 0xc0, 0x0d, 0x52, 0x69, + 0x3f, 0xa8, 0x34, 0x88, 0x4b, 0x02, 0xcc, 0x89, 0x6d, 0xf8, 0x81, 0xc7, 0x3d, 0xb8, 0x16, 0xaa, + 0x19, 0xd8, 0xa7, 0x86, 0x52, 0x33, 0xda, 0x0f, 0xd6, 0xef, 0x35, 0x28, 0x3f, 0x6b, 0x9d, 0x18, + 0x96, 0xe7, 0x54, 0x1a, 0x5e, 0xc3, 0xab, 0x48, 0xed, 0x93, 0xd6, 0xa9, 0x5c, 0xc9, 0x85, 0xfc, + 0x15, 0xa2, 0xac, 0xeb, 0x31, 0x67, 0x96, 0x17, 0x64, 0x79, 0x5a, 0x7f, 0x14, 0xe9, 0x38, 0xd8, + 0x3a, 0xa3, 0x2e, 0x09, 0x3a, 0x15, 0xff, 0xbc, 0x21, 0x8d, 0x02, 0xc2, 0xbc, 0x56, 0x60, 0x91, + 0x6b, 0x59, 0xb1, 0x8a, 0x43, 0x38, 0xce, 0xf2, 0x55, 0x19, 0x65, 0x15, 0xb4, 0x5c, 0x4e, 0x9d, + 0x61, 0x37, 0x8f, 0x3f, 0x67, 0xc0, 0xac, 0x33, 0xe2, 0xe0, 0xb4, 0x9d, 0xfe, 0x2f, 0x0d, 0xcc, + 0xed, 0xd4, 0xf7, 0x76, 0x03, 0xda, 0x26, 0x01, 0x7c, 0x0d, 0x66, 0x45, 0x44, 0x36, 0xe6, 0xb8, + 0xa8, 0x6d, 0x68, 0x9b, 0x85, 0xad, 0xfb, 0x46, 0x74, 0xbf, 0x03, 0x60, 0xc3, 0x3f, 0x6f, 0x88, + 0x0d, 0x66, 0x08, 0x6d, 0xa3, 0xfd, 0xc0, 0x38, 0x3c, 0x79, 0x43, 0x2c, 0x5e, 0x23, 0x1c, 0x9b, + 0xf0, 0x7d, 0xb7, 0x3c, 0xd1, 0xeb, 0x96, 0x41, 0xb4, 0x87, 0x06, 0xa8, 0xf0, 0x39, 0xc8, 0x33, + 0x9f, 0x58, 0xc5, 0x49, 0x89, 0x7e, 0xdb, 0xc8, 0xcc, 0x9e, 0x31, 0x88, 0xa8, 0xee, 0x13, 0xcb, + 0x9c, 0x57, 0x88, 0x79, 0xb1, 0x42, 0xd2, 0x5e, 0xff, 0xa7, 0x06, 0x16, 0x06, 0x5a, 0xfb, 0x94, + 0x71, 0xf8, 0xab, 0xa1, 0xd8, 0x8d, 0xab, 0xc5, 0x2e, 0xac, 0x65, 0xe4, 0x4b, 0xca, 0xcf, 0x6c, + 0x7f, 0x27, 0x16, 0x77, 0x15, 0x4c, 0x51, 0x4e, 0x1c, 0x56, 0x9c, 0xdc, 0xc8, 0x6d, 0x16, 0xb6, + 0x36, 0x3e, 0x17, 0xb8, 0xb9, 0xa0, 0xc0, 0xa6, 0xf6, 0x84, 0x19, 0x0a, 0xad, 0xf5, 0xbf, 0xe5, + 0x63, 0x61, 0x8b, 0xe3, 0xc0, 0xa7, 0xe0, 0x06, 0xe6, 0x1c, 0x5b, 0x67, 0x88, 0xbc, 0x6d, 0xd1, + 0x80, 0xd8, 0x32, 0xf8, 0x59, 0x13, 0xf6, 0xba, 0xe5, 0x1b, 0xdb, 0x09, 0x09, 0x4a, 0x69, 0x0a, + 0x5b, 0xdf, 0xb3, 0xf7, 0xdc, 0x53, 0xef, 0xd0, 0xad, 0x79, 0x2d, 0x97, 0xcb, 0x6b, 0x55, 0xb6, + 0x47, 0x09, 0x09, 0x4a, 0x69, 0x42, 0x0b, 0xac, 0xb6, 0xbd, 0x66, 0xcb, 0x21, 0xfb, 0xf4, 0x94, + 0x58, 0x1d, 0xab, 0x49, 0x6a, 0x9e, 0x4d, 0x58, 0x31, 0xb7, 0x91, 0xdb, 0x9c, 0x33, 0x2b, 0xbd, + 0x6e, 0x79, 0xf5, 0x65, 0x86, 0xfc, 0xa2, 0x5b, 0x5e, 0xc9, 0xd8, 0x47, 0x99, 0x60, 0xf0, 0x19, + 0x58, 0x54, 0x97, 0xb3, 0x83, 0x7d, 0x6c, 0x51, 0xde, 0x29, 0xe6, 0x65, 0x84, 0x2b, 0xbd, 0x6e, + 0x79, 0xb1, 0x9e, 0x14, 0xa1, 0xb4, 0x2e, 0x7c, 0x01, 0x16, 0x4e, 0xd9, 0x4f, 0x03, 0xaf, 0xe5, + 0x1f, 0x79, 0x4d, 0x6a, 0x75, 0x8a, 0x53, 0x1b, 0xda, 0xe6, 0x9c, 0xa9, 0xf7, 0xba, 0xe5, 0x85, + 0xe7, 0xf5, 0x98, 0xe0, 0x22, 0xbd, 0x81, 0x92, 0x86, 0xf0, 0x35, 0x58, 0xe0, 0xde, 0x39, 0x71, + 0xc5, 0xd5, 0x11, 0xc6, 0x59, 0x71, 0x5a, 0xa6, 0xf1, 0xd6, 0x88, 0x34, 0x1e, 0xc7, 0x74, 0xcd, + 0x35, 0x95, 0xc9, 0x85, 0xf8, 0x2e, 0x43, 0x49, 0x40, 0xb8, 0x03, 0x96, 0x83, 0x30, 0x2f, 0x0c, + 0x11, 0xbf, 0x75, 0xd2, 0xa4, 0xec, 0xac, 0x38, 0x23, 0x0f, 0xbb, 0xd6, 0xeb, 0x96, 0x97, 0x51, + 0x5a, 0x88, 0x86, 0xf5, 0xf5, 0x7f, 0x68, 0x60, 0x66, 0xa7, 0xbe, 0x77, 0xe0, 0xd9, 0x64, 0x0c, + 0xb5, 0xb8, 0x9b, 0xa8, 0x45, 0x7d, 0x34, 0xa5, 0x45, 0x3c, 0x23, 0x2b, 0xf1, 0xeb, 0xb0, 0x12, + 0x85, 0x8e, 0xea, 0x22, 0x1b, 0x20, 0xef, 0x62, 0x87, 0xc8, 0xa8, 0xe7, 0x22, 0x9b, 0x03, 0xec, + 0x10, 0x24, 0x25, 0xf0, 0x7b, 0x60, 0xda, 0xf5, 0x6c, 0xb2, 0xb7, 0x2b, 0x7d, 0xcf, 0x99, 0x37, + 0x94, 0xce, 0xf4, 0x81, 0xdc, 0x45, 0x4a, 0x0a, 0x1f, 0x81, 0x79, 0xee, 0xf9, 0x5e, 0xd3, 0x6b, + 0x74, 0x7e, 0x46, 0x3a, 0x7d, 0x72, 0x2e, 0xf5, 0xba, 0xe5, 0xf9, 0xe3, 0xd8, 0x3e, 0x4a, 0x68, + 0xc1, 0x5f, 0x83, 0x02, 0x6e, 0x36, 0x3d, 0x0b, 0x73, 0x7c, 0xd2, 0x24, 0x92, 0x71, 0x85, 0xad, + 0xbb, 0x23, 0x8e, 0x17, 0x92, 0x59, 0xf8, 0x45, 0xaa, 0x85, 0x33, 0x73, 0xb1, 0xd7, 0x2d, 0x17, + 0xb6, 0x23, 0x08, 0x14, 0xc7, 0xd3, 0xff, 0xae, 0x81, 0x82, 0x3a, 0xf0, 0x18, 0x1a, 0xcf, 0x4e, + 0xb2, 0xf1, 0x94, 0x2e, 0xcf, 0xd2, 0x88, 0xb6, 0xf3, 0x9b, 0x41, 0xc4, 0xb2, 0xe7, 0x1c, 0x82, + 0x19, 0x5b, 0xa6, 0x8a, 0x15, 0x35, 0x89, 0x7a, 0xfb, 0x72, 0x54, 0xd5, 0xd2, 0x16, 0x15, 0xf6, + 0x4c, 0xb8, 0x66, 0xa8, 0x8f, 0xa2, 0x7f, 0x93, 0x03, 0x70, 0xa7, 0xbe, 0x97, 0x2a, 0xe8, 0x31, + 0x50, 0x98, 0x82, 0x79, 0x41, 0x95, 0x3e, 0x19, 0x14, 0x95, 0x1f, 0x5e, 0xf1, 0xfe, 0xf1, 0x09, + 0x69, 0xd6, 0x49, 0x93, 0x58, 0xdc, 0x0b, 0x42, 0x56, 0x1d, 0xc4, 0xc0, 0x50, 0x02, 0x1a, 0xee, + 0x82, 0xa5, 0x7e, 0x7f, 0x6a, 0x62, 0xc6, 0x04, 0x9b, 0x8b, 0x39, 0xc9, 0xde, 0xa2, 0x0a, 0x71, + 0xa9, 0x9e, 0x92, 0xa3, 0x21, 0x0b, 0xf8, 0x0a, 0xcc, 0x5a, 0xf1, 0x56, 0xf8, 0x19, 0xb2, 0x18, + 0xfd, 0xb9, 0xc2, 0xf8, 0x79, 0x0b, 0xbb, 0x9c, 0xf2, 0x8e, 0x39, 0x2f, 0x88, 0x32, 0xe8, 0x99, + 0x03, 0x34, 0xc8, 0xc0, 0xb2, 0x83, 0xdf, 0x51, 0xa7, 0xe5, 0x84, 0x94, 0xae, 0xd3, 0xdf, 0x11, + 0xd9, 0x30, 0xaf, 0xef, 0x42, 0x36, 0xac, 0x5a, 0x1a, 0x0c, 0x0d, 0xe3, 0xeb, 0xff, 0xd5, 0xc0, + 0xcd, 0xe1, 0xc4, 0x8f, 0xa1, 0x2c, 0x0e, 0x92, 0x65, 0x71, 0x67, 0x34, 0x81, 0x53, 0xb1, 0x8d, + 0xa8, 0x90, 0x3f, 0x4d, 0x83, 0xf9, 0x78, 0xfa, 0xc6, 0xc0, 0xdd, 0x1f, 0x81, 0x82, 0x1f, 0x78, + 0x6d, 0xca, 0xa8, 0xe7, 0x92, 0x40, 0x75, 0xc2, 0x15, 0x65, 0x52, 0x38, 0x8a, 0x44, 0x28, 0xae, + 0x07, 0x1b, 0x00, 0xf8, 0x38, 0xc0, 0x0e, 0xe1, 0xa2, 0x7e, 0x73, 0xf2, 0xf8, 0x0f, 0x47, 0x1c, + 0x3f, 0x7e, 0x22, 0xe3, 0x68, 0x60, 0x55, 0x75, 0x79, 0xd0, 0x89, 0xa2, 0x8b, 0x04, 0x28, 0x06, + 0x0d, 0xcf, 0xc1, 0x42, 0x40, 0xac, 0x26, 0xa6, 0x8e, 0x7a, 0x7d, 0xf3, 0x32, 0xc2, 0xaa, 0x78, + 0x0a, 0x51, 0x5c, 0x70, 0xd1, 0x2d, 0xdf, 0x1f, 0x9e, 0x9f, 0x8d, 0x23, 0x12, 0x30, 0xca, 0x38, + 0x71, 0x79, 0x48, 0x98, 0x84, 0x0d, 0x4a, 0x62, 0x8b, 0x4e, 0xef, 0x88, 0xb9, 0xe4, 0xd0, 0xe7, + 0xd4, 0x73, 0x59, 0x71, 0x2a, 0xea, 0xf4, 0xb5, 0xd8, 0x3e, 0x4a, 0x68, 0xc1, 0x7d, 0xb0, 0x2a, + 0x3a, 0xf3, 0x6f, 0x43, 0x07, 0xd5, 0x77, 0x3e, 0x76, 0xc5, 0x2d, 0x15, 0xa7, 0xe5, 0xbb, 0x5b, + 0x14, 0x43, 0xcc, 0x76, 0x86, 0x1c, 0x65, 0x5a, 0xc1, 0x57, 0x60, 0x39, 0x9c, 0x62, 0x4c, 0xea, + 0xda, 0xd4, 0x6d, 0x88, 0x19, 0x46, 0x3e, 0xe1, 0x73, 0xe6, 0x5d, 0x51, 0x11, 0x2f, 0xd3, 0xc2, + 0x8b, 0xac, 0x4d, 0x34, 0x0c, 0x02, 0xdf, 0x82, 0x65, 0xe9, 0x91, 0xd8, 0xaa, 0x9d, 0x50, 0xc2, + 0x8a, 0xb3, 0x32, 0x75, 0x9b, 0xf1, 0xd4, 0x89, 0xab, 0x0b, 0xe7, 0x8f, 0xb0, 0xe9, 0xf4, 0x9b, + 0xd3, 0x31, 0x09, 0x1c, 0xf3, 0xbb, 0x2a, 0x5f, 0xcb, 0xdb, 0x69, 0x28, 0x34, 0x8c, 0xbe, 0xfe, + 0x0c, 0x2c, 0xa6, 0x12, 0x0e, 0x97, 0x40, 0xee, 0x9c, 0x74, 0xc2, 0x67, 0x19, 0x89, 0x9f, 0x70, + 0x15, 0x4c, 0xb5, 0x71, 0xb3, 0x45, 0x42, 0xf2, 0xa1, 0x70, 0xf1, 0x74, 0xf2, 0x89, 0xa6, 0xff, + 0x5b, 0x03, 0x89, 0x76, 0x36, 0x86, 0x92, 0x7e, 0x91, 0x2c, 0xe9, 0x5b, 0x57, 0xe0, 0xf4, 0x88, + 0x62, 0xfe, 0x83, 0x06, 0xe6, 0xe3, 0xc3, 0x1a, 0xfc, 0x21, 0x98, 0xc5, 0x2d, 0x9b, 0x12, 0xd7, + 0xea, 0x4f, 0x25, 0x83, 0x40, 0xb6, 0xd5, 0x3e, 0x1a, 0x68, 0x88, 0x51, 0x8e, 0xbc, 0xf3, 0x69, + 0x80, 0x05, 0xc9, 0xea, 0xc4, 0xf2, 0x5c, 0x9b, 0xc9, 0x1b, 0xca, 0x85, 0x9d, 0xb1, 0x9a, 0x16, + 0xa2, 0x61, 0x7d, 0xfd, 0xaf, 0x93, 0x60, 0x29, 0xe4, 0x46, 0x38, 0xc4, 0x3b, 0xc4, 0xe5, 0x63, + 0x68, 0x2a, 0xb5, 0xc4, 0x4c, 0xf7, 0x83, 0x4b, 0x87, 0x9e, 0x28, 0xb0, 0x51, 0xc3, 0x1d, 0xfc, + 0x05, 0x98, 0x66, 0x1c, 0xf3, 0x16, 0x93, 0x4f, 0x5d, 0x61, 0xeb, 0xde, 0x55, 0x01, 0xa5, 0x51, + 0x34, 0xd7, 0x85, 0x6b, 0xa4, 0xc0, 0xf4, 0xff, 0x68, 0x60, 0x35, 0x6d, 0x32, 0x06, 0x86, 0xed, + 0x27, 0x19, 0xf6, 0xfd, 0x2b, 0x1e, 0x66, 0x04, 0xcb, 0xfe, 0xaf, 0x81, 0x9b, 0x43, 0xe7, 0x96, + 0x2f, 0xa9, 0xe8, 0x4b, 0x7e, 0xaa, 0xfb, 0x1d, 0x44, 0x13, 0xb1, 0xec, 0x4b, 0x47, 0x19, 0x72, + 0x94, 0x69, 0x05, 0xdf, 0x80, 0x25, 0xea, 0x36, 0xa9, 0x4b, 0xd4, 0xc3, 0x1b, 0xe5, 0x37, 0xb3, + 0x79, 0xa4, 0x91, 0x65, 0x72, 0x57, 0xc5, 0x7c, 0xb2, 0x97, 0x42, 0x41, 0x43, 0xb8, 0xfa, 0xff, + 0x32, 0x32, 0x23, 0x67, 0x46, 0x51, 0x42, 0x72, 0x87, 0x04, 0x43, 0x25, 0xa4, 0xf6, 0xd1, 0x40, + 0x43, 0xf2, 0x46, 0x5e, 0x85, 0x0a, 0xf4, 0xca, 0xbc, 0x91, 0x46, 0x31, 0xde, 0xc8, 0x35, 0x52, + 0x60, 0x22, 0x08, 0x31, 0x93, 0xc5, 0x66, 0xaf, 0x41, 0x10, 0x07, 0x6a, 0x1f, 0x0d, 0x34, 0xf4, + 0xaf, 0x72, 0x19, 0x09, 0x92, 0x04, 0x8c, 0x9d, 0xa6, 0xff, 0xbd, 0x9d, 0x3e, 0x8d, 0x3d, 0x38, + 0x8d, 0x0d, 0xff, 0xa2, 0x01, 0x88, 0x07, 0x10, 0xb5, 0x3e, 0x41, 0x43, 0x16, 0x55, 0xaf, 0x55, + 0x12, 0xc6, 0xf6, 0x10, 0x4e, 0xf8, 0x1a, 0xaf, 0x2b, 0xff, 0x70, 0x58, 0x01, 0x65, 0x38, 0x87, + 0x36, 0x28, 0x84, 0xbb, 0xd5, 0x20, 0xf0, 0x02, 0x55, 0x9e, 0xfa, 0xa5, 0xb1, 0x48, 0x4d, 0xb3, + 0x24, 0x3f, 0x6e, 0x22, 0xd3, 0x8b, 0x6e, 0xb9, 0x10, 0x93, 0xa3, 0x38, 0xac, 0xf0, 0x62, 0x93, + 0xc8, 0x4b, 0xfe, 0x7a, 0x5e, 0x76, 0xc9, 0x68, 0x2f, 0x31, 0xd8, 0xf5, 0x2a, 0xf8, 0xce, 0x88, + 0x6b, 0xb9, 0xd6, 0x9b, 0xf5, 0x47, 0x0d, 0xc4, 0x7d, 0xc0, 0x7d, 0x90, 0xe7, 0x54, 0x55, 0x5d, + 0xf2, 0x03, 0xf0, 0x92, 0x46, 0x72, 0x4c, 0x1d, 0x12, 0xb5, 0x42, 0xb1, 0x42, 0x12, 0x05, 0xde, + 0x01, 0x33, 0x0e, 0x61, 0x0c, 0x37, 0x94, 0xe7, 0xe8, 0x73, 0xa8, 0x16, 0x6e, 0xa3, 0xbe, 0x5c, + 0x7f, 0x0c, 0x56, 0x32, 0x3e, 0x2b, 0x61, 0x19, 0x4c, 0x59, 0xf2, 0x5f, 0x1a, 0x11, 0xd0, 0x94, + 0x39, 0x27, 0x3a, 0xca, 0x8e, 0xfc, 0x73, 0x26, 0xdc, 0x37, 0x7f, 0xfc, 0xfe, 0x53, 0x69, 0xe2, + 0xc3, 0xa7, 0xd2, 0xc4, 0xc7, 0x4f, 0xa5, 0x89, 0xdf, 0xf7, 0x4a, 0xda, 0xfb, 0x5e, 0x49, 0xfb, + 0xd0, 0x2b, 0x69, 0x1f, 0x7b, 0x25, 0xed, 0x8b, 0x5e, 0x49, 0xfb, 0xf3, 0x97, 0xa5, 0x89, 0x5f, + 0xae, 0x65, 0xfe, 0x31, 0xfa, 0x6d, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd7, 0x6e, 0x72, 0x7b, 0x49, + 0x15, 0x00, 0x00, } func (m *CSIDriver) Marshal() (dAtA []byte, err error) { @@ -1010,6 +1080,127 @@ func (m *CSINodeSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *CSIStorageCapacity) 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 *CSIStorageCapacity) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CSIStorageCapacity) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.MaximumVolumeSize != nil { + { + size, err := m.MaximumVolumeSize.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + if m.Capacity != nil { + { + size, err := m.Capacity.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + i -= len(m.StorageClassName) + copy(dAtA[i:], m.StorageClassName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.StorageClassName))) + i-- + dAtA[i] = 0x1a + if m.NodeTopology != nil { + { + size, err := m.NodeTopology.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 *CSIStorageCapacityList) 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 *CSIStorageCapacityList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CSIStorageCapacityList) 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 *StorageClass) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1675,6 +1866,48 @@ func (m *CSINodeSpec) Size() (n int) { return n } +func (m *CSIStorageCapacity) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if m.NodeTopology != nil { + l = m.NodeTopology.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + l = len(m.StorageClassName) + n += 1 + l + sovGenerated(uint64(l)) + if m.Capacity != nil { + l = m.Capacity.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.MaximumVolumeSize != nil { + l = m.MaximumVolumeSize.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *CSIStorageCapacityList) 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 *StorageClass) Size() (n int) { if m == nil { return 0 @@ -1974,6 +2207,36 @@ func (this *CSINodeSpec) String() string { }, "") return s } +func (this *CSIStorageCapacity) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&CSIStorageCapacity{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `NodeTopology:` + strings.Replace(fmt.Sprintf("%v", this.NodeTopology), "LabelSelector", "v1.LabelSelector", 1) + `,`, + `StorageClassName:` + fmt.Sprintf("%v", this.StorageClassName) + `,`, + `Capacity:` + strings.Replace(fmt.Sprintf("%v", this.Capacity), "Quantity", "resource.Quantity", 1) + `,`, + `MaximumVolumeSize:` + strings.Replace(fmt.Sprintf("%v", this.MaximumVolumeSize), "Quantity", "resource.Quantity", 1) + `,`, + `}`, + }, "") + return s +} +func (this *CSIStorageCapacityList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]CSIStorageCapacity{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "CSIStorageCapacity", "CSIStorageCapacity", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&CSIStorageCapacityList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} func (this *StorageClass) String() string { if this == nil { return "nil" @@ -3101,6 +3364,346 @@ func (m *CSINodeSpec) Unmarshal(dAtA []byte) error { } return nil } +func (m *CSIStorageCapacity) 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: CSIStorageCapacity: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CSIStorageCapacity: 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 NodeTopology", 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.NodeTopology == nil { + m.NodeTopology = &v1.LabelSelector{} + } + if err := m.NodeTopology.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StorageClassName", 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.StorageClassName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Capacity", 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.Capacity == nil { + m.Capacity = &resource.Quantity{} + } + if err := m.Capacity.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MaximumVolumeSize", 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.MaximumVolumeSize == nil { + m.MaximumVolumeSize = &resource.Quantity{} + } + if err := m.MaximumVolumeSize.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 *CSIStorageCapacityList) 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: CSIStorageCapacityList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CSIStorageCapacityList: 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, CSIStorageCapacity{}) + 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 *StorageClass) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/staging/src/k8s.io/api/storage/v1/generated.proto b/staging/src/k8s.io/api/storage/v1/generated.proto index 8ba7880e2914..45417116a1f0 100644 --- a/staging/src/k8s.io/api/storage/v1/generated.proto +++ b/staging/src/k8s.io/api/storage/v1/generated.proto @@ -22,6 +22,7 @@ syntax = "proto2"; package k8s.io.api.storage.v1; 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"; @@ -144,9 +145,6 @@ message CSIDriverSpec { // // This field was immutable in Kubernetes <= 1.22 and now is mutable. // - // This is a beta field and only available when the CSIStorageCapacity - // feature is enabled. The default is false. - // // +optional // +featureGate=CSIStorageCapacity optional bool storageCapacity = 4; @@ -270,6 +268,100 @@ message CSINodeSpec { repeated CSINodeDriver drivers = 1; } +// CSIStorageCapacity stores the result of one CSI GetCapacity call. +// For a given StorageClass, this describes the available capacity in a +// particular topology segment. This can be used when considering where to +// instantiate new PersistentVolumes. +// +// For example this can express things like: +// - StorageClass "standard" has "1234 GiB" available in "topology.kubernetes.io/zone=us-east1" +// - StorageClass "localssd" has "10 GiB" available in "kubernetes.io/hostname=knode-abc123" +// +// The following three cases all imply that no capacity is available for +// a certain combination: +// - no object exists with suitable topology and storage class name +// - such an object exists, but the capacity is unset +// - such an object exists, but the capacity is zero +// +// The producer of these objects can decide which approach is more suitable. +// +// They are consumed by the kube-scheduler when a CSI driver opts into +// capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler +// compares the MaximumVolumeSize against the requested size of pending volumes +// to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back +// to a comparison against the less precise Capacity. If that is also unset, +// the scheduler assumes that capacity is insufficient and tries some other +// node. +message CSIStorageCapacity { + // Standard object's metadata. The name has no particular meaning. It must be + // be a DNS subdomain (dots allowed, 253 characters). To ensure that + // there are no conflicts with other CSI drivers on the cluster, the recommendation + // is to use csisc-, a generated name, or a reverse-domain name which ends + // with the unique CSI driver name. + // + // Objects are namespaced. + // + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // NodeTopology defines which nodes have access to the storage + // for which capacity was reported. If not set, the storage is + // not accessible from any node in the cluster. If empty, the + // storage is accessible from all nodes. This field is + // immutable. + // + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector nodeTopology = 2; + + // The name of the StorageClass that the reported capacity applies to. + // It must meet the same requirements as the name of a StorageClass + // object (non-empty, DNS subdomain). If that object no longer exists, + // the CSIStorageCapacity object is obsolete and should be removed by its + // creator. + // This field is immutable. + optional string storageClassName = 3; + + // Capacity is the value reported by the CSI driver in its GetCapacityResponse + // for a GetCapacityRequest with topology and parameters that match the + // previous fields. + // + // The semantic is currently (CSI spec 1.2) defined as: + // The available capacity, in bytes, of the storage that can be used + // to provision volumes. If not set, that information is currently + // unavailable. + // + // +optional + optional k8s.io.apimachinery.pkg.api.resource.Quantity capacity = 4; + + // MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse + // for a GetCapacityRequest with topology and parameters that match the + // previous fields. + // + // This is defined since CSI spec 1.4.0 as the largest size + // that may be used in a + // CreateVolumeRequest.capacity_range.required_bytes field to + // create a volume with the same parameters as those in + // GetCapacityRequest. The corresponding value in the Kubernetes + // API is ResourceRequirements.Requests in a volume claim. + // + // +optional + optional k8s.io.apimachinery.pkg.api.resource.Quantity maximumVolumeSize = 5; +} + +// CSIStorageCapacityList is a collection of CSIStorageCapacity objects. +message CSIStorageCapacityList { + // Standard list metadata + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // Items is the list of CSIStorageCapacity objects. + // +listType=map + // +listMapKey=name + repeated CSIStorageCapacity items = 2; +} + // StorageClass describes the parameters for a class of storage for // which PersistentVolumes can be dynamically provisioned. // diff --git a/staging/src/k8s.io/api/storage/v1/register.go b/staging/src/k8s.io/api/storage/v1/register.go index 1a2f83d1b869..094fa2821738 100644 --- a/staging/src/k8s.io/api/storage/v1/register.go +++ b/staging/src/k8s.io/api/storage/v1/register.go @@ -55,6 +55,9 @@ func addKnownTypes(scheme *runtime.Scheme) error { &CSIDriver{}, &CSIDriverList{}, + + &CSIStorageCapacity{}, + &CSIStorageCapacityList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) diff --git a/staging/src/k8s.io/api/storage/v1/types.go b/staging/src/k8s.io/api/storage/v1/types.go index 6da0657ecc23..4812287abf62 100644 --- a/staging/src/k8s.io/api/storage/v1/types.go +++ b/staging/src/k8s.io/api/storage/v1/types.go @@ -18,6 +18,7 @@ package v1 import ( v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -344,9 +345,6 @@ type CSIDriverSpec struct { // // This field was immutable in Kubernetes <= 1.22 and now is mutable. // - // This is a beta field and only available when the CSIStorageCapacity - // feature is enabled. The default is false. - // // +optional // +featureGate=CSIStorageCapacity StorageCapacity *bool `json:"storageCapacity,omitempty" protobuf:"bytes,4,opt,name=storageCapacity"` @@ -560,3 +558,104 @@ type CSINodeList struct { // items is the list of CSINode Items []CSINode `json:"items" protobuf:"bytes,2,rep,name=items"` } + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CSIStorageCapacity stores the result of one CSI GetCapacity call. +// For a given StorageClass, this describes the available capacity in a +// particular topology segment. This can be used when considering where to +// instantiate new PersistentVolumes. +// +// For example this can express things like: +// - StorageClass "standard" has "1234 GiB" available in "topology.kubernetes.io/zone=us-east1" +// - StorageClass "localssd" has "10 GiB" available in "kubernetes.io/hostname=knode-abc123" +// +// The following three cases all imply that no capacity is available for +// a certain combination: +// - no object exists with suitable topology and storage class name +// - such an object exists, but the capacity is unset +// - such an object exists, but the capacity is zero +// +// The producer of these objects can decide which approach is more suitable. +// +// They are consumed by the kube-scheduler when a CSI driver opts into +// capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler +// compares the MaximumVolumeSize against the requested size of pending volumes +// to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back +// to a comparison against the less precise Capacity. If that is also unset, +// the scheduler assumes that capacity is insufficient and tries some other +// node. +type CSIStorageCapacity struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. The name has no particular meaning. It must be + // be a DNS subdomain (dots allowed, 253 characters). To ensure that + // there are no conflicts with other CSI drivers on the cluster, the recommendation + // is to use csisc-, a generated name, or a reverse-domain name which ends + // with the unique CSI driver name. + // + // Objects are namespaced. + // + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // NodeTopology defines which nodes have access to the storage + // for which capacity was reported. If not set, the storage is + // not accessible from any node in the cluster. If empty, the + // storage is accessible from all nodes. This field is + // immutable. + // + // +optional + NodeTopology *metav1.LabelSelector `json:"nodeTopology,omitempty" protobuf:"bytes,2,opt,name=nodeTopology"` + + // The name of the StorageClass that the reported capacity applies to. + // It must meet the same requirements as the name of a StorageClass + // object (non-empty, DNS subdomain). If that object no longer exists, + // the CSIStorageCapacity object is obsolete and should be removed by its + // creator. + // This field is immutable. + StorageClassName string `json:"storageClassName" protobuf:"bytes,3,name=storageClassName"` + + // Capacity is the value reported by the CSI driver in its GetCapacityResponse + // for a GetCapacityRequest with topology and parameters that match the + // previous fields. + // + // The semantic is currently (CSI spec 1.2) defined as: + // The available capacity, in bytes, of the storage that can be used + // to provision volumes. If not set, that information is currently + // unavailable. + // + // +optional + Capacity *resource.Quantity `json:"capacity,omitempty" protobuf:"bytes,4,opt,name=capacity"` + + // MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse + // for a GetCapacityRequest with topology and parameters that match the + // previous fields. + // + // This is defined since CSI spec 1.4.0 as the largest size + // that may be used in a + // CreateVolumeRequest.capacity_range.required_bytes field to + // create a volume with the same parameters as those in + // GetCapacityRequest. The corresponding value in the Kubernetes + // API is ResourceRequirements.Requests in a volume claim. + // + // +optional + MaximumVolumeSize *resource.Quantity `json:"maximumVolumeSize,omitempty" protobuf:"bytes,5,opt,name=maximumVolumeSize"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CSIStorageCapacityList is a collection of CSIStorageCapacity objects. +type CSIStorageCapacityList struct { + metav1.TypeMeta `json:",inline"` + // Standard list metadata + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Items is the list of CSIStorageCapacity objects. + // +listType=map + // +listMapKey=name + Items []CSIStorageCapacity `json:"items" protobuf:"bytes,2,rep,name=items"` +} diff --git a/staging/src/k8s.io/api/storage/v1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/storage/v1/types_swagger_doc_generated.go index ed5b18cb7a8e..7a407db46b21 100644 --- a/staging/src/k8s.io/api/storage/v1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/storage/v1/types_swagger_doc_generated.go @@ -52,7 +52,7 @@ var map_CSIDriverSpec = map[string]string{ "attachRequired": "attachRequired indicates this CSI volume driver requires an attach operation (because it implements the CSI ControllerPublishVolume() method), and that the Kubernetes attach detach controller should call the attach volume interface which checks the volumeattachment status and waits until the volume is attached before proceeding to mounting. The CSI external-attacher coordinates with CSI volume driver and updates the volumeattachment status when the attach operation is complete. If the CSIDriverRegistry feature gate is enabled and the value is specified to false, the attach operation will be skipped. Otherwise the attach operation will be called.\n\nThis field is immutable.", "podInfoOnMount": "If set to true, podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) during mount operations. If set to false, pod information will not be passed on mount. Default is false. The CSI driver specifies podInfoOnMount as part of driver deployment. If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. The following VolumeConext will be passed if podInfoOnMount is set to true. This list might grow, but the prefix will be used. \"csi.storage.k8s.io/pod.name\": pod.Name \"csi.storage.k8s.io/pod.namespace\": pod.Namespace \"csi.storage.k8s.io/pod.uid\": string(pod.UID) \"csi.storage.k8s.io/ephemeral\": \"true\" if the volume is an ephemeral inline volume\n defined by a CSIVolumeSource, otherwise \"false\"\n\n\"csi.storage.k8s.io/ephemeral\" is a new feature in Kubernetes 1.16. It is only required for drivers which support both the \"Persistent\" and \"Ephemeral\" VolumeLifecycleMode. Other drivers can leave pod info disabled and/or ignore this field. As Kubernetes 1.15 doesn't support this field, drivers can only support one mode when deployed on such a cluster and the deployment determines which mode that is, for example via a command line parameter of the driver.\n\nThis field is immutable.", "volumeLifecycleModes": "volumeLifecycleModes defines what kind of volumes this CSI volume driver supports. The default if the list is empty is \"Persistent\", which is the usage defined by the CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. The other mode is \"Ephemeral\". In this mode, volumes are defined inline inside the pod spec with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. For more information about implementing this mode, see https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html A driver can support one or more of these modes and more modes may be added in the future. This field is beta.\n\nThis field is immutable.", - "storageCapacity": "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis field was immutable in Kubernetes <= 1.22 and now is mutable.\n\nThis is a beta field and only available when the CSIStorageCapacity feature is enabled. The default is false.", + "storageCapacity": "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis field was immutable in Kubernetes <= 1.22 and now is mutable.", "fsGroupPolicy": "Defines if the underlying volume supports changing ownership and permission of the volume before being mounted. Refer to the specific FSGroupPolicy values for additional details.\n\nThis field is immutable.\n\nDefaults to ReadWriteOnceWithFSType, which will examine each volume to determine if Kubernetes should modify ownership and permissions of the volume. With the default policy the defined fsGroup will only be applied if a fstype is defined and the volume's access mode contains ReadWriteOnce.", "tokenRequests": "TokenRequests indicates the CSI driver needs pods' service account tokens it is mounting volume for to do necessary authentication. Kubelet will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. The CSI driver should parse and validate the following VolumeContext: \"csi.storage.k8s.io/serviceAccount.tokens\": {\n \"\": {\n \"token\": ,\n \"expirationTimestamp\": ,\n },\n ...\n}\n\nNote: Audience in each TokenRequest should be different and at most one token is empty string. To receive a new token after expiry, RequiresRepublish can be used to trigger NodePublishVolume periodically.", "requiresRepublish": "RequiresRepublish indicates the CSI driver wants `NodePublishVolume` being periodically called to reflect any possible change in the mounted volume. This field defaults to false.\n\nNote: After a successful initial NodePublishVolume call, subsequent calls to NodePublishVolume should only update the contents of the volume. New mount points will not be seen by a running container.", @@ -103,6 +103,29 @@ func (CSINodeSpec) SwaggerDoc() map[string]string { return map_CSINodeSpec } +var map_CSIStorageCapacity = map[string]string{ + "": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler when a CSI driver opts into capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler compares the MaximumVolumeSize against the requested size of pending volumes to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back to a comparison against the less precise Capacity. If that is also unset, the scheduler assumes that capacity is insufficient and tries some other node.", + "metadata": "Standard object's metadata. The name has no particular meaning. It must be be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name.\n\nObjects are namespaced.\n\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "nodeTopology": "NodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.", + "storageClassName": "The name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.", + "capacity": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable.", + "maximumVolumeSize": "MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThis is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.", +} + +func (CSIStorageCapacity) SwaggerDoc() map[string]string { + return map_CSIStorageCapacity +} + +var map_CSIStorageCapacityList = map[string]string{ + "": "CSIStorageCapacityList is a collection of CSIStorageCapacity objects.", + "metadata": "Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "items": "Items is the list of CSIStorageCapacity objects.", +} + +func (CSIStorageCapacityList) SwaggerDoc() map[string]string { + return map_CSIStorageCapacityList +} + var map_StorageClass = map[string]string{ "": "StorageClass describes the parameters for a class of storage for which PersistentVolumes can be dynamically provisioned.\n\nStorageClasses are non-namespaced; the name of the storage class according to etcd is in ObjectMeta.Name.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", diff --git a/staging/src/k8s.io/api/storage/v1/zz_generated.deepcopy.go b/staging/src/k8s.io/api/storage/v1/zz_generated.deepcopy.go index 300f42cbba4b..b14b7fbcd878 100644 --- a/staging/src/k8s.io/api/storage/v1/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/api/storage/v1/zz_generated.deepcopy.go @@ -23,6 +23,7 @@ package v1 import ( corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -248,6 +249,80 @@ func (in *CSINodeSpec) DeepCopy() *CSINodeSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CSIStorageCapacity) DeepCopyInto(out *CSIStorageCapacity) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.NodeTopology != nil { + in, out := &in.NodeTopology, &out.NodeTopology + *out = new(metav1.LabelSelector) + (*in).DeepCopyInto(*out) + } + if in.Capacity != nil { + in, out := &in.Capacity, &out.Capacity + x := (*in).DeepCopy() + *out = &x + } + if in.MaximumVolumeSize != nil { + in, out := &in.MaximumVolumeSize, &out.MaximumVolumeSize + x := (*in).DeepCopy() + *out = &x + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CSIStorageCapacity. +func (in *CSIStorageCapacity) DeepCopy() *CSIStorageCapacity { + if in == nil { + return nil + } + out := new(CSIStorageCapacity) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CSIStorageCapacity) 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 *CSIStorageCapacityList) DeepCopyInto(out *CSIStorageCapacityList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CSIStorageCapacity, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CSIStorageCapacityList. +func (in *CSIStorageCapacityList) DeepCopy() *CSIStorageCapacityList { + if in == nil { + return nil + } + out := new(CSIStorageCapacityList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CSIStorageCapacityList) 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 *StorageClass) DeepCopyInto(out *StorageClass) { *out = *in diff --git a/staging/src/k8s.io/api/storage/v1alpha1/generated.proto b/staging/src/k8s.io/api/storage/v1alpha1/generated.proto index eca1dfa21bf9..a5345122607d 100644 --- a/staging/src/k8s.io/api/storage/v1alpha1/generated.proto +++ b/staging/src/k8s.io/api/storage/v1alpha1/generated.proto @@ -47,9 +47,13 @@ option go_package = "k8s.io/api/storage/v1alpha1"; // // The producer of these objects can decide which approach is more suitable. // -// They are consumed by the kube-scheduler if the CSIStorageCapacity beta feature gate -// is enabled there and a CSI driver opts into capacity-aware scheduling with -// CSIDriver.StorageCapacity. +// They are consumed by the kube-scheduler when a CSI driver opts into +// capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler +// compares the MaximumVolumeSize against the requested size of pending volumes +// to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back +// to a comparison against the less precise Capacity. If that is also unset, +// the scheduler assumes that capacity is insufficient and tries some other +// node. message CSIStorageCapacity { // Standard object's metadata. The name has no particular meaning. It must be // be a DNS subdomain (dots allowed, 253 characters). To ensure that @@ -87,7 +91,7 @@ message CSIStorageCapacity { // The semantic is currently (CSI spec 1.2) defined as: // The available capacity, in bytes, of the storage that can be used // to provision volumes. If not set, that information is currently - // unavailable and treated like zero capacity. + // unavailable. // // +optional optional k8s.io.apimachinery.pkg.api.resource.Quantity capacity = 4; diff --git a/staging/src/k8s.io/api/storage/v1alpha1/types.go b/staging/src/k8s.io/api/storage/v1alpha1/types.go index afb0495db541..fe8c9e3cd0ae 100644 --- a/staging/src/k8s.io/api/storage/v1alpha1/types.go +++ b/staging/src/k8s.io/api/storage/v1alpha1/types.go @@ -17,7 +17,7 @@ limitations under the License. package v1alpha1 import ( - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -165,9 +165,13 @@ type VolumeError struct { // // The producer of these objects can decide which approach is more suitable. // -// They are consumed by the kube-scheduler if the CSIStorageCapacity beta feature gate -// is enabled there and a CSI driver opts into capacity-aware scheduling with -// CSIDriver.StorageCapacity. +// They are consumed by the kube-scheduler when a CSI driver opts into +// capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler +// compares the MaximumVolumeSize against the requested size of pending volumes +// to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back +// to a comparison against the less precise Capacity. If that is also unset, +// the scheduler assumes that capacity is insufficient and tries some other +// node. type CSIStorageCapacity struct { metav1.TypeMeta `json:",inline"` // Standard object's metadata. The name has no particular meaning. It must be @@ -206,7 +210,7 @@ type CSIStorageCapacity struct { // The semantic is currently (CSI spec 1.2) defined as: // The available capacity, in bytes, of the storage that can be used // to provision volumes. If not set, that information is currently - // unavailable and treated like zero capacity. + // unavailable. // // +optional Capacity *resource.Quantity `json:"capacity,omitempty" protobuf:"bytes,4,opt,name=capacity"` diff --git a/staging/src/k8s.io/api/storage/v1alpha1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/storage/v1alpha1/types_swagger_doc_generated.go index fa50e02896b1..a228a3fec7f5 100644 --- a/staging/src/k8s.io/api/storage/v1alpha1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/storage/v1alpha1/types_swagger_doc_generated.go @@ -28,11 +28,11 @@ package v1alpha1 // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_CSIStorageCapacity = map[string]string{ - "": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler if the CSIStorageCapacity beta feature gate is enabled there and a CSI driver opts into capacity-aware scheduling with CSIDriver.StorageCapacity.", + "": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler when a CSI driver opts into capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler compares the MaximumVolumeSize against the requested size of pending volumes to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back to a comparison against the less precise Capacity. If that is also unset, the scheduler assumes that capacity is insufficient and tries some other node.", "metadata": "Standard object's metadata. The name has no particular meaning. It must be be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name.\n\nObjects are namespaced.\n\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", "nodeTopology": "NodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.", "storageClassName": "The name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.", - "capacity": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable and treated like zero capacity.", + "capacity": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable.", "maximumVolumeSize": "MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThis is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.", } diff --git a/staging/src/k8s.io/api/storage/v1beta1/generated.proto b/staging/src/k8s.io/api/storage/v1beta1/generated.proto index 2edd631cb811..943900fa6902 100644 --- a/staging/src/k8s.io/api/storage/v1beta1/generated.proto +++ b/staging/src/k8s.io/api/storage/v1beta1/generated.proto @@ -146,11 +146,7 @@ message CSIDriverSpec { // // This field was immutable in Kubernetes <= 1.22 and now is mutable. // - // This is a beta field and only available when the CSIStorageCapacity - // feature is enabled. The default is false. - // // +optional - // +featureGate=CSIStorageCapacity optional bool storageCapacity = 4; // Defines if the underlying volume supports changing ownership and @@ -290,9 +286,13 @@ message CSINodeSpec { // // The producer of these objects can decide which approach is more suitable. // -// They are consumed by the kube-scheduler if the CSIStorageCapacity beta feature gate -// is enabled there and a CSI driver opts into capacity-aware scheduling with -// CSIDriver.StorageCapacity. +// They are consumed by the kube-scheduler when a CSI driver opts into +// capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler +// compares the MaximumVolumeSize against the requested size of pending volumes +// to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back +// to a comparison against the less precise Capacity. If that is also unset, +// the scheduler assumes that capacity is insufficient and tries some other +// node. message CSIStorageCapacity { // Standard object's metadata. The name has no particular meaning. It must be // be a DNS subdomain (dots allowed, 253 characters). To ensure that @@ -330,7 +330,7 @@ message CSIStorageCapacity { // The semantic is currently (CSI spec 1.2) defined as: // The available capacity, in bytes, of the storage that can be used // to provision volumes. If not set, that information is currently - // unavailable and treated like zero capacity. + // unavailable. // // +optional optional k8s.io.apimachinery.pkg.api.resource.Quantity capacity = 4; diff --git a/staging/src/k8s.io/api/storage/v1beta1/types.go b/staging/src/k8s.io/api/storage/v1beta1/types.go index 524d8b53414b..b39414b96059 100644 --- a/staging/src/k8s.io/api/storage/v1beta1/types.go +++ b/staging/src/k8s.io/api/storage/v1beta1/types.go @@ -364,11 +364,7 @@ type CSIDriverSpec struct { // // This field was immutable in Kubernetes <= 1.22 and now is mutable. // - // This is a beta field and only available when the CSIStorageCapacity - // feature is enabled. The default is false. - // // +optional - // +featureGate=CSIStorageCapacity StorageCapacity *bool `json:"storageCapacity,omitempty" protobuf:"bytes,4,opt,name=storageCapacity"` // Defines if the underlying volume supports changing ownership and @@ -588,6 +584,8 @@ type CSINodeList struct { // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.21 +// +k8s:prerelease-lifecycle-gen:deprecated=1.24 +// +k8s:prerelease-lifecycle-gen:replacement=storage.k8s.io,v1,CSIStorageCapacity // CSIStorageCapacity stores the result of one CSI GetCapacity call. // For a given StorageClass, this describes the available capacity in a @@ -606,9 +604,13 @@ type CSINodeList struct { // // The producer of these objects can decide which approach is more suitable. // -// They are consumed by the kube-scheduler if the CSIStorageCapacity beta feature gate -// is enabled there and a CSI driver opts into capacity-aware scheduling with -// CSIDriver.StorageCapacity. +// They are consumed by the kube-scheduler when a CSI driver opts into +// capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler +// compares the MaximumVolumeSize against the requested size of pending volumes +// to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back +// to a comparison against the less precise Capacity. If that is also unset, +// the scheduler assumes that capacity is insufficient and tries some other +// node. type CSIStorageCapacity struct { metav1.TypeMeta `json:",inline"` // Standard object's metadata. The name has no particular meaning. It must be @@ -647,7 +649,7 @@ type CSIStorageCapacity struct { // The semantic is currently (CSI spec 1.2) defined as: // The available capacity, in bytes, of the storage that can be used // to provision volumes. If not set, that information is currently - // unavailable and treated like zero capacity. + // unavailable. // // +optional Capacity *resource.Quantity `json:"capacity,omitempty" protobuf:"bytes,4,opt,name=capacity"` @@ -669,6 +671,8 @@ type CSIStorageCapacity struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.21 +// +k8s:prerelease-lifecycle-gen:deprecated=1.24 +// +k8s:prerelease-lifecycle-gen:replacement=storage.k8s.io,v1,CSIStorageCapacityList // CSIStorageCapacityList is a collection of CSIStorageCapacity objects. type CSIStorageCapacityList struct { diff --git a/staging/src/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go index f4dbf0fefa74..d810b4e4c8bb 100644 --- a/staging/src/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go @@ -52,7 +52,7 @@ var map_CSIDriverSpec = map[string]string{ "attachRequired": "attachRequired indicates this CSI volume driver requires an attach operation (because it implements the CSI ControllerPublishVolume() method), and that the Kubernetes attach detach controller should call the attach volume interface which checks the volumeattachment status and waits until the volume is attached before proceeding to mounting. The CSI external-attacher coordinates with CSI volume driver and updates the volumeattachment status when the attach operation is complete. If the CSIDriverRegistry feature gate is enabled and the value is specified to false, the attach operation will be skipped. Otherwise the attach operation will be called.\n\nThis field is immutable.", "podInfoOnMount": "If set to true, podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) during mount operations. If set to false, pod information will not be passed on mount. Default is false. The CSI driver specifies podInfoOnMount as part of driver deployment. If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. The following VolumeConext will be passed if podInfoOnMount is set to true. This list might grow, but the prefix will be used. \"csi.storage.k8s.io/pod.name\": pod.Name \"csi.storage.k8s.io/pod.namespace\": pod.Namespace \"csi.storage.k8s.io/pod.uid\": string(pod.UID) \"csi.storage.k8s.io/ephemeral\": \"true\" if the volume is an ephemeral inline volume\n defined by a CSIVolumeSource, otherwise \"false\"\n\n\"csi.storage.k8s.io/ephemeral\" is a new feature in Kubernetes 1.16. It is only required for drivers which support both the \"Persistent\" and \"Ephemeral\" VolumeLifecycleMode. Other drivers can leave pod info disabled and/or ignore this field. As Kubernetes 1.15 doesn't support this field, drivers can only support one mode when deployed on such a cluster and the deployment determines which mode that is, for example via a command line parameter of the driver.\n\nThis field is immutable.", "volumeLifecycleModes": "VolumeLifecycleModes defines what kind of volumes this CSI volume driver supports. The default if the list is empty is \"Persistent\", which is the usage defined by the CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. The other mode is \"Ephemeral\". In this mode, volumes are defined inline inside the pod spec with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. For more information about implementing this mode, see https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html A driver can support one or more of these modes and more modes may be added in the future.\n\nThis field is immutable.", - "storageCapacity": "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis field was immutable in Kubernetes <= 1.22 and now is mutable.\n\nThis is a beta field and only available when the CSIStorageCapacity feature is enabled. The default is false.", + "storageCapacity": "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis field was immutable in Kubernetes <= 1.22 and now is mutable.", "fsGroupPolicy": "Defines if the underlying volume supports changing ownership and permission of the volume before being mounted. Refer to the specific FSGroupPolicy values for additional details.\n\nThis field is immutable.\n\nDefaults to ReadWriteOnceWithFSType, which will examine each volume to determine if Kubernetes should modify ownership and permissions of the volume. With the default policy the defined fsGroup will only be applied if a fstype is defined and the volume's access mode contains ReadWriteOnce.", "tokenRequests": "TokenRequests indicates the CSI driver needs pods' service account tokens it is mounting volume for to do necessary authentication. Kubelet will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. The CSI driver should parse and validate the following VolumeContext: \"csi.storage.k8s.io/serviceAccount.tokens\": {\n \"\": {\n \"token\": ,\n \"expirationTimestamp\": ,\n },\n ...\n}\n\nNote: Audience in each TokenRequest should be different and at most one token is empty string. To receive a new token after expiry, RequiresRepublish can be used to trigger NodePublishVolume periodically.", "requiresRepublish": "RequiresRepublish indicates the CSI driver wants `NodePublishVolume` being periodically called to reflect any possible change in the mounted volume. This field defaults to false.\n\nNote: After a successful initial NodePublishVolume call, subsequent calls to NodePublishVolume should only update the contents of the volume. New mount points will not be seen by a running container.", @@ -104,11 +104,11 @@ func (CSINodeSpec) SwaggerDoc() map[string]string { } var map_CSIStorageCapacity = map[string]string{ - "": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler if the CSIStorageCapacity beta feature gate is enabled there and a CSI driver opts into capacity-aware scheduling with CSIDriver.StorageCapacity.", + "": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler when a CSI driver opts into capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler compares the MaximumVolumeSize against the requested size of pending volumes to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back to a comparison against the less precise Capacity. If that is also unset, the scheduler assumes that capacity is insufficient and tries some other node.", "metadata": "Standard object's metadata. The name has no particular meaning. It must be be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name.\n\nObjects are namespaced.\n\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", "nodeTopology": "NodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.", "storageClassName": "The name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.", - "capacity": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable and treated like zero capacity.", + "capacity": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable.", "maximumVolumeSize": "MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThis is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.", } diff --git a/staging/src/k8s.io/api/storage/v1beta1/zz_generated.prerelease-lifecycle.go b/staging/src/k8s.io/api/storage/v1beta1/zz_generated.prerelease-lifecycle.go index 7b69b2cbca33..c5d23e7d45e1 100644 --- a/staging/src/k8s.io/api/storage/v1beta1/zz_generated.prerelease-lifecycle.go +++ b/staging/src/k8s.io/api/storage/v1beta1/zz_generated.prerelease-lifecycle.go @@ -133,6 +133,12 @@ func (in *CSIStorageCapacity) APILifecycleDeprecated() (major, minor int) { return 1, 24 } +// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. +// It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. +func (in *CSIStorageCapacity) APILifecycleReplacement() schema.GroupVersionKind { + return schema.GroupVersionKind{Group: "storage.k8s.io", Version: "v1", Kind: "CSIStorageCapacity"} +} + // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. // It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. func (in *CSIStorageCapacity) APILifecycleRemoved() (major, minor int) { @@ -151,6 +157,12 @@ func (in *CSIStorageCapacityList) APILifecycleDeprecated() (major, minor int) { return 1, 24 } +// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. +// It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. +func (in *CSIStorageCapacityList) APILifecycleReplacement() schema.GroupVersionKind { + return schema.GroupVersionKind{Group: "storage.k8s.io", Version: "v1", Kind: "CSIStorageCapacityList"} +} + // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. // It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. func (in *CSIStorageCapacityList) APILifecycleRemoved() (major, minor int) { diff --git a/staging/src/k8s.io/api/testdata/HEAD/storage.k8s.io.v1.CSIStorageCapacity.json b/staging/src/k8s.io/api/testdata/HEAD/storage.k8s.io.v1.CSIStorageCapacity.json new file mode 100644 index 000000000000..329f5c268955 --- /dev/null +++ b/staging/src/k8s.io/api/testdata/HEAD/storage.k8s.io.v1.CSIStorageCapacity.json @@ -0,0 +1,64 @@ +{ + "kind": "CSIStorageCapacity", + "apiVersion": "storage.k8s.io/v1", + "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" + ], + "clusterName": "clusterNameValue", + "managedFields": [ + { + "manager": "managerValue", + "operation": "operationValue", + "apiVersion": "apiVersionValue", + "time": "2004-01-01T01:01:01Z", + "fieldsType": "fieldsTypeValue", + "fieldsV1": {}, + "subresource": "subresourceValue" + } + ] + }, + "nodeTopology": { + "matchLabels": { + "matchLabelsKey": "matchLabelsValue" + }, + "matchExpressions": [ + { + "key": "keyValue", + "operator": "operatorValue", + "values": [ + "valuesValue" + ] + } + ] + }, + "storageClassName": "storageClassNameValue", + "capacity": "0", + "maximumVolumeSize": "0" +} \ No newline at end of file diff --git a/staging/src/k8s.io/api/testdata/HEAD/storage.k8s.io.v1.CSIStorageCapacity.pb b/staging/src/k8s.io/api/testdata/HEAD/storage.k8s.io.v1.CSIStorageCapacity.pb new file mode 100644 index 000000000000..3d98a2fb7eaf Binary files /dev/null and b/staging/src/k8s.io/api/testdata/HEAD/storage.k8s.io.v1.CSIStorageCapacity.pb differ diff --git a/staging/src/k8s.io/api/testdata/HEAD/storage.k8s.io.v1.CSIStorageCapacity.yaml b/staging/src/k8s.io/api/testdata/HEAD/storage.k8s.io.v1.CSIStorageCapacity.yaml new file mode 100644 index 000000000000..01fbee2d89ae --- /dev/null +++ b/staging/src/k8s.io/api/testdata/HEAD/storage.k8s.io.v1.CSIStorageCapacity.yaml @@ -0,0 +1,46 @@ +apiVersion: storage.k8s.io/v1 +capacity: "0" +kind: CSIStorageCapacity +maximumVolumeSize: "0" +metadata: + annotations: + annotationsKey: annotationsValue + clusterName: clusterNameValue + 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 +nodeTopology: + matchExpressions: + - key: keyValue + operator: operatorValue + values: + - valuesValue + matchLabels: + matchLabelsKey: matchLabelsValue +storageClassName: storageClassNameValue 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 e17502d3485b..bd7f58d02dc0 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go @@ -10842,6 +10842,32 @@ var schemaYAML = typed.YAMLObject(`types: elementRelationship: associative keys: - name +- name: io.k8s.api.storage.v1.CSIStorageCapacity + map: + fields: + - name: apiVersion + type: + scalar: string + - name: capacity + type: + namedType: io.k8s.apimachinery.pkg.api.resource.Quantity + - name: kind + type: + scalar: string + - name: maximumVolumeSize + type: + namedType: io.k8s.apimachinery.pkg.api.resource.Quantity + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: nodeTopology + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector + - name: storageClassName + type: + scalar: string + default: "" - name: io.k8s.api.storage.v1.StorageClass map: fields: diff --git a/staging/src/k8s.io/client-go/applyconfigurations/storage/v1/csistoragecapacity.go b/staging/src/k8s.io/client-go/applyconfigurations/storage/v1/csistoragecapacity.go new file mode 100644 index 000000000000..a325c09f861e --- /dev/null +++ b/staging/src/k8s.io/client-go/applyconfigurations/storage/v1/csistoragecapacity.go @@ -0,0 +1,286 @@ +/* +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 v1 + +import ( + storagev1 "k8s.io/api/storage/v1" + resource "k8s.io/apimachinery/pkg/api/resource" + 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" +) + +// CSIStorageCapacityApplyConfiguration represents an declarative configuration of the CSIStorageCapacity type for use +// with apply. +type CSIStorageCapacityApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + NodeTopology *v1.LabelSelectorApplyConfiguration `json:"nodeTopology,omitempty"` + StorageClassName *string `json:"storageClassName,omitempty"` + Capacity *resource.Quantity `json:"capacity,omitempty"` + MaximumVolumeSize *resource.Quantity `json:"maximumVolumeSize,omitempty"` +} + +// CSIStorageCapacity constructs an declarative configuration of the CSIStorageCapacity type for use with +// apply. +func CSIStorageCapacity(name, namespace string) *CSIStorageCapacityApplyConfiguration { + b := &CSIStorageCapacityApplyConfiguration{} + b.WithName(name) + b.WithNamespace(namespace) + b.WithKind("CSIStorageCapacity") + b.WithAPIVersion("storage.k8s.io/v1") + return b +} + +// ExtractCSIStorageCapacity extracts the applied configuration owned by fieldManager from +// cSIStorageCapacity. If no managedFields are found in cSIStorageCapacity for fieldManager, a +// CSIStorageCapacityApplyConfiguration 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. +// cSIStorageCapacity must be a unmodified CSIStorageCapacity API object that was retrieved from the Kubernetes API. +// ExtractCSIStorageCapacity 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 ExtractCSIStorageCapacity(cSIStorageCapacity *storagev1.CSIStorageCapacity, fieldManager string) (*CSIStorageCapacityApplyConfiguration, error) { + return extractCSIStorageCapacity(cSIStorageCapacity, fieldManager, "") +} + +// ExtractCSIStorageCapacityStatus is the same as ExtractCSIStorageCapacity except +// that it extracts the status subresource applied configuration. +// Experimental! +func ExtractCSIStorageCapacityStatus(cSIStorageCapacity *storagev1.CSIStorageCapacity, fieldManager string) (*CSIStorageCapacityApplyConfiguration, error) { + return extractCSIStorageCapacity(cSIStorageCapacity, fieldManager, "status") +} + +func extractCSIStorageCapacity(cSIStorageCapacity *storagev1.CSIStorageCapacity, fieldManager string, subresource string) (*CSIStorageCapacityApplyConfiguration, error) { + b := &CSIStorageCapacityApplyConfiguration{} + err := managedfields.ExtractInto(cSIStorageCapacity, internal.Parser().Type("io.k8s.api.storage.v1.CSIStorageCapacity"), fieldManager, b, subresource) + if err != nil { + return nil, err + } + b.WithName(cSIStorageCapacity.Name) + b.WithNamespace(cSIStorageCapacity.Namespace) + + b.WithKind("CSIStorageCapacity") + b.WithAPIVersion("storage.k8s.io/v1") + 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 *CSIStorageCapacityApplyConfiguration) WithKind(value string) *CSIStorageCapacityApplyConfiguration { + 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 *CSIStorageCapacityApplyConfiguration) WithAPIVersion(value string) *CSIStorageCapacityApplyConfiguration { + 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 *CSIStorageCapacityApplyConfiguration) WithName(value string) *CSIStorageCapacityApplyConfiguration { + 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 *CSIStorageCapacityApplyConfiguration) WithGenerateName(value string) *CSIStorageCapacityApplyConfiguration { + 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 *CSIStorageCapacityApplyConfiguration) WithNamespace(value string) *CSIStorageCapacityApplyConfiguration { + 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 *CSIStorageCapacityApplyConfiguration) WithUID(value types.UID) *CSIStorageCapacityApplyConfiguration { + 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 *CSIStorageCapacityApplyConfiguration) WithResourceVersion(value string) *CSIStorageCapacityApplyConfiguration { + 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 *CSIStorageCapacityApplyConfiguration) WithGeneration(value int64) *CSIStorageCapacityApplyConfiguration { + 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 *CSIStorageCapacityApplyConfiguration) WithCreationTimestamp(value metav1.Time) *CSIStorageCapacityApplyConfiguration { + 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 *CSIStorageCapacityApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *CSIStorageCapacityApplyConfiguration { + 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 *CSIStorageCapacityApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *CSIStorageCapacityApplyConfiguration { + 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 *CSIStorageCapacityApplyConfiguration) WithLabels(entries map[string]string) *CSIStorageCapacityApplyConfiguration { + 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 *CSIStorageCapacityApplyConfiguration) WithAnnotations(entries map[string]string) *CSIStorageCapacityApplyConfiguration { + 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 *CSIStorageCapacityApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *CSIStorageCapacityApplyConfiguration { + 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 *CSIStorageCapacityApplyConfiguration) WithFinalizers(values ...string) *CSIStorageCapacityApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.Finalizers = append(b.Finalizers, values[i]) + } + return b +} + +// WithClusterName sets the ClusterName 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 ClusterName field is set to the value of the last call. +func (b *CSIStorageCapacityApplyConfiguration) WithClusterName(value string) *CSIStorageCapacityApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ClusterName = &value + return b +} + +func (b *CSIStorageCapacityApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithNodeTopology sets the NodeTopology 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 NodeTopology field is set to the value of the last call. +func (b *CSIStorageCapacityApplyConfiguration) WithNodeTopology(value *v1.LabelSelectorApplyConfiguration) *CSIStorageCapacityApplyConfiguration { + b.NodeTopology = value + return b +} + +// WithStorageClassName sets the StorageClassName 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 StorageClassName field is set to the value of the last call. +func (b *CSIStorageCapacityApplyConfiguration) WithStorageClassName(value string) *CSIStorageCapacityApplyConfiguration { + b.StorageClassName = &value + return b +} + +// WithCapacity sets the Capacity 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 Capacity field is set to the value of the last call. +func (b *CSIStorageCapacityApplyConfiguration) WithCapacity(value resource.Quantity) *CSIStorageCapacityApplyConfiguration { + b.Capacity = &value + return b +} + +// WithMaximumVolumeSize sets the MaximumVolumeSize 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 MaximumVolumeSize field is set to the value of the last call. +func (b *CSIStorageCapacityApplyConfiguration) WithMaximumVolumeSize(value resource.Quantity) *CSIStorageCapacityApplyConfiguration { + b.MaximumVolumeSize = &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 195b3ef79458..1bfd77a53fed 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/utils.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/utils.go @@ -1369,6 +1369,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &applyconfigurationsstoragev1.CSINodeDriverApplyConfiguration{} case storagev1.SchemeGroupVersion.WithKind("CSINodeSpec"): return &applyconfigurationsstoragev1.CSINodeSpecApplyConfiguration{} + case storagev1.SchemeGroupVersion.WithKind("CSIStorageCapacity"): + return &applyconfigurationsstoragev1.CSIStorageCapacityApplyConfiguration{} case storagev1.SchemeGroupVersion.WithKind("StorageClass"): return &applyconfigurationsstoragev1.StorageClassApplyConfiguration{} case storagev1.SchemeGroupVersion.WithKind("TokenRequest"): diff --git a/staging/src/k8s.io/client-go/informers/generic.go b/staging/src/k8s.io/client-go/informers/generic.go index 5b94a2d2a3a7..4c2e53c25759 100644 --- a/staging/src/k8s.io/client-go/informers/generic.go +++ b/staging/src/k8s.io/client-go/informers/generic.go @@ -347,6 +347,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource return &genericInformer{resource: resource.GroupResource(), informer: f.Storage().V1().CSIDrivers().Informer()}, nil case storagev1.SchemeGroupVersion.WithResource("csinodes"): return &genericInformer{resource: resource.GroupResource(), informer: f.Storage().V1().CSINodes().Informer()}, nil + case storagev1.SchemeGroupVersion.WithResource("csistoragecapacities"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Storage().V1().CSIStorageCapacities().Informer()}, nil case storagev1.SchemeGroupVersion.WithResource("storageclasses"): return &genericInformer{resource: resource.GroupResource(), informer: f.Storage().V1().StorageClasses().Informer()}, nil case storagev1.SchemeGroupVersion.WithResource("volumeattachments"): diff --git a/staging/src/k8s.io/client-go/informers/storage/v1/csistoragecapacity.go b/staging/src/k8s.io/client-go/informers/storage/v1/csistoragecapacity.go new file mode 100644 index 000000000000..9b9095f3aec1 --- /dev/null +++ b/staging/src/k8s.io/client-go/informers/storage/v1/csistoragecapacity.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 v1 + +import ( + "context" + time "time" + + storagev1 "k8s.io/api/storage/v1" + metav1 "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" + v1 "k8s.io/client-go/listers/storage/v1" + cache "k8s.io/client-go/tools/cache" +) + +// CSIStorageCapacityInformer provides access to a shared informer and lister for +// CSIStorageCapacities. +type CSIStorageCapacityInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.CSIStorageCapacityLister +} + +type cSIStorageCapacityInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewCSIStorageCapacityInformer constructs a new informer for CSIStorageCapacity 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 NewCSIStorageCapacityInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredCSIStorageCapacityInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredCSIStorageCapacityInformer constructs a new informer for CSIStorageCapacity 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 NewFilteredCSIStorageCapacityInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1().CSIStorageCapacities(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1().CSIStorageCapacities(namespace).Watch(context.TODO(), options) + }, + }, + &storagev1.CSIStorageCapacity{}, + resyncPeriod, + indexers, + ) +} + +func (f *cSIStorageCapacityInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredCSIStorageCapacityInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *cSIStorageCapacityInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&storagev1.CSIStorageCapacity{}, f.defaultInformer) +} + +func (f *cSIStorageCapacityInformer) Lister() v1.CSIStorageCapacityLister { + return v1.NewCSIStorageCapacityLister(f.Informer().GetIndexer()) +} diff --git a/staging/src/k8s.io/client-go/informers/storage/v1/interface.go b/staging/src/k8s.io/client-go/informers/storage/v1/interface.go index 157759140564..4f017b0864fb 100644 --- a/staging/src/k8s.io/client-go/informers/storage/v1/interface.go +++ b/staging/src/k8s.io/client-go/informers/storage/v1/interface.go @@ -28,6 +28,8 @@ type Interface interface { CSIDrivers() CSIDriverInformer // CSINodes returns a CSINodeInformer. CSINodes() CSINodeInformer + // CSIStorageCapacities returns a CSIStorageCapacityInformer. + CSIStorageCapacities() CSIStorageCapacityInformer // StorageClasses returns a StorageClassInformer. StorageClasses() StorageClassInformer // VolumeAttachments returns a VolumeAttachmentInformer. @@ -55,6 +57,11 @@ func (v *version) CSINodes() CSINodeInformer { return &cSINodeInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} } +// CSIStorageCapacities returns a CSIStorageCapacityInformer. +func (v *version) CSIStorageCapacities() CSIStorageCapacityInformer { + return &cSIStorageCapacityInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + // StorageClasses returns a StorageClassInformer. func (v *version) StorageClasses() StorageClassInformer { return &storageClassInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/storage/v1/csistoragecapacity.go b/staging/src/k8s.io/client-go/kubernetes/typed/storage/v1/csistoragecapacity.go new file mode 100644 index 000000000000..6bb50e0da98d --- /dev/null +++ b/staging/src/k8s.io/client-go/kubernetes/typed/storage/v1/csistoragecapacity.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 v1 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1 "k8s.io/api/storage/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + storagev1 "k8s.io/client-go/applyconfigurations/storage/v1" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// CSIStorageCapacitiesGetter has a method to return a CSIStorageCapacityInterface. +// A group's client should implement this interface. +type CSIStorageCapacitiesGetter interface { + CSIStorageCapacities(namespace string) CSIStorageCapacityInterface +} + +// CSIStorageCapacityInterface has methods to work with CSIStorageCapacity resources. +type CSIStorageCapacityInterface interface { + Create(ctx context.Context, cSIStorageCapacity *v1.CSIStorageCapacity, opts metav1.CreateOptions) (*v1.CSIStorageCapacity, error) + Update(ctx context.Context, cSIStorageCapacity *v1.CSIStorageCapacity, opts metav1.UpdateOptions) (*v1.CSIStorageCapacity, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CSIStorageCapacity, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CSIStorageCapacityList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CSIStorageCapacity, err error) + Apply(ctx context.Context, cSIStorageCapacity *storagev1.CSIStorageCapacityApplyConfiguration, opts metav1.ApplyOptions) (result *v1.CSIStorageCapacity, err error) + CSIStorageCapacityExpansion +} + +// cSIStorageCapacities implements CSIStorageCapacityInterface +type cSIStorageCapacities struct { + client rest.Interface + ns string +} + +// newCSIStorageCapacities returns a CSIStorageCapacities +func newCSIStorageCapacities(c *StorageV1Client, namespace string) *cSIStorageCapacities { + return &cSIStorageCapacities{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cSIStorageCapacity, and returns the corresponding cSIStorageCapacity object, and an error if there is any. +func (c *cSIStorageCapacities) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CSIStorageCapacity, err error) { + result = &v1.CSIStorageCapacity{} + err = c.client.Get(). + Namespace(c.ns). + Resource("csistoragecapacities"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CSIStorageCapacities that match those selectors. +func (c *cSIStorageCapacities) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CSIStorageCapacityList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CSIStorageCapacityList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("csistoragecapacities"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cSIStorageCapacities. +func (c *cSIStorageCapacities) Watch(ctx context.Context, opts metav1.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("csistoragecapacities"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cSIStorageCapacity and creates it. Returns the server's representation of the cSIStorageCapacity, and an error, if there is any. +func (c *cSIStorageCapacities) Create(ctx context.Context, cSIStorageCapacity *v1.CSIStorageCapacity, opts metav1.CreateOptions) (result *v1.CSIStorageCapacity, err error) { + result = &v1.CSIStorageCapacity{} + err = c.client.Post(). + Namespace(c.ns). + Resource("csistoragecapacities"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cSIStorageCapacity). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cSIStorageCapacity and updates it. Returns the server's representation of the cSIStorageCapacity, and an error, if there is any. +func (c *cSIStorageCapacities) Update(ctx context.Context, cSIStorageCapacity *v1.CSIStorageCapacity, opts metav1.UpdateOptions) (result *v1.CSIStorageCapacity, err error) { + result = &v1.CSIStorageCapacity{} + err = c.client.Put(). + Namespace(c.ns). + Resource("csistoragecapacities"). + Name(cSIStorageCapacity.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cSIStorageCapacity). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cSIStorageCapacity and deletes it. Returns an error if one occurs. +func (c *cSIStorageCapacities) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("csistoragecapacities"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cSIStorageCapacities) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.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("csistoragecapacities"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cSIStorageCapacity. +func (c *cSIStorageCapacities) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CSIStorageCapacity, err error) { + result = &v1.CSIStorageCapacity{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("csistoragecapacities"). + 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 cSIStorageCapacity. +func (c *cSIStorageCapacities) Apply(ctx context.Context, cSIStorageCapacity *storagev1.CSIStorageCapacityApplyConfiguration, opts metav1.ApplyOptions) (result *v1.CSIStorageCapacity, err error) { + if cSIStorageCapacity == nil { + return nil, fmt.Errorf("cSIStorageCapacity provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(cSIStorageCapacity) + if err != nil { + return nil, err + } + name := cSIStorageCapacity.Name + if name == nil { + return nil, fmt.Errorf("cSIStorageCapacity.Name must be provided to Apply") + } + result = &v1.CSIStorageCapacity{} + err = c.client.Patch(types.ApplyPatchType). + Namespace(c.ns). + Resource("csistoragecapacities"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_csistoragecapacity.go b/staging/src/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_csistoragecapacity.go new file mode 100644 index 000000000000..40c4171c8035 --- /dev/null +++ b/staging/src/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_csistoragecapacity.go @@ -0,0 +1,155 @@ +/* +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" + + storagev1 "k8s.io/api/storage/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + applyconfigurationsstoragev1 "k8s.io/client-go/applyconfigurations/storage/v1" + testing "k8s.io/client-go/testing" +) + +// FakeCSIStorageCapacities implements CSIStorageCapacityInterface +type FakeCSIStorageCapacities struct { + Fake *FakeStorageV1 + ns string +} + +var csistoragecapacitiesResource = schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1", Resource: "csistoragecapacities"} + +var csistoragecapacitiesKind = schema.GroupVersionKind{Group: "storage.k8s.io", Version: "v1", Kind: "CSIStorageCapacity"} + +// Get takes name of the cSIStorageCapacity, and returns the corresponding cSIStorageCapacity object, and an error if there is any. +func (c *FakeCSIStorageCapacities) Get(ctx context.Context, name string, options v1.GetOptions) (result *storagev1.CSIStorageCapacity, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(csistoragecapacitiesResource, c.ns, name), &storagev1.CSIStorageCapacity{}) + + if obj == nil { + return nil, err + } + return obj.(*storagev1.CSIStorageCapacity), err +} + +// List takes label and field selectors, and returns the list of CSIStorageCapacities that match those selectors. +func (c *FakeCSIStorageCapacities) List(ctx context.Context, opts v1.ListOptions) (result *storagev1.CSIStorageCapacityList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(csistoragecapacitiesResource, csistoragecapacitiesKind, c.ns, opts), &storagev1.CSIStorageCapacityList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &storagev1.CSIStorageCapacityList{ListMeta: obj.(*storagev1.CSIStorageCapacityList).ListMeta} + for _, item := range obj.(*storagev1.CSIStorageCapacityList).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 cSIStorageCapacities. +func (c *FakeCSIStorageCapacities) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(csistoragecapacitiesResource, c.ns, opts)) + +} + +// Create takes the representation of a cSIStorageCapacity and creates it. Returns the server's representation of the cSIStorageCapacity, and an error, if there is any. +func (c *FakeCSIStorageCapacities) Create(ctx context.Context, cSIStorageCapacity *storagev1.CSIStorageCapacity, opts v1.CreateOptions) (result *storagev1.CSIStorageCapacity, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(csistoragecapacitiesResource, c.ns, cSIStorageCapacity), &storagev1.CSIStorageCapacity{}) + + if obj == nil { + return nil, err + } + return obj.(*storagev1.CSIStorageCapacity), err +} + +// Update takes the representation of a cSIStorageCapacity and updates it. Returns the server's representation of the cSIStorageCapacity, and an error, if there is any. +func (c *FakeCSIStorageCapacities) Update(ctx context.Context, cSIStorageCapacity *storagev1.CSIStorageCapacity, opts v1.UpdateOptions) (result *storagev1.CSIStorageCapacity, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(csistoragecapacitiesResource, c.ns, cSIStorageCapacity), &storagev1.CSIStorageCapacity{}) + + if obj == nil { + return nil, err + } + return obj.(*storagev1.CSIStorageCapacity), err +} + +// Delete takes name of the cSIStorageCapacity and deletes it. Returns an error if one occurs. +func (c *FakeCSIStorageCapacities) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(csistoragecapacitiesResource, c.ns, name, opts), &storagev1.CSIStorageCapacity{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeCSIStorageCapacities) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(csistoragecapacitiesResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &storagev1.CSIStorageCapacityList{}) + return err +} + +// Patch applies the patch and returns the patched cSIStorageCapacity. +func (c *FakeCSIStorageCapacities) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *storagev1.CSIStorageCapacity, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(csistoragecapacitiesResource, c.ns, name, pt, data, subresources...), &storagev1.CSIStorageCapacity{}) + + if obj == nil { + return nil, err + } + return obj.(*storagev1.CSIStorageCapacity), err +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied cSIStorageCapacity. +func (c *FakeCSIStorageCapacities) Apply(ctx context.Context, cSIStorageCapacity *applyconfigurationsstoragev1.CSIStorageCapacityApplyConfiguration, opts v1.ApplyOptions) (result *storagev1.CSIStorageCapacity, err error) { + if cSIStorageCapacity == nil { + return nil, fmt.Errorf("cSIStorageCapacity provided to Apply must not be nil") + } + data, err := json.Marshal(cSIStorageCapacity) + if err != nil { + return nil, err + } + name := cSIStorageCapacity.Name + if name == nil { + return nil, fmt.Errorf("cSIStorageCapacity.Name must be provided to Apply") + } + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(csistoragecapacitiesResource, c.ns, *name, types.ApplyPatchType, data), &storagev1.CSIStorageCapacity{}) + + if obj == nil { + return nil, err + } + return obj.(*storagev1.CSIStorageCapacity), err +} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_storage_client.go b/staging/src/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_storage_client.go index 8878f5048447..5cb91b516640 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_storage_client.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_storage_client.go @@ -36,6 +36,10 @@ func (c *FakeStorageV1) CSINodes() v1.CSINodeInterface { return &FakeCSINodes{c} } +func (c *FakeStorageV1) CSIStorageCapacities(namespace string) v1.CSIStorageCapacityInterface { + return &FakeCSIStorageCapacities{c, namespace} +} + func (c *FakeStorageV1) StorageClasses() v1.StorageClassInterface { return &FakeStorageClasses{c} } diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/storage/v1/generated_expansion.go b/staging/src/k8s.io/client-go/kubernetes/typed/storage/v1/generated_expansion.go index af811177636d..aa318d7d36ed 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/storage/v1/generated_expansion.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/storage/v1/generated_expansion.go @@ -22,6 +22,8 @@ type CSIDriverExpansion interface{} type CSINodeExpansion interface{} +type CSIStorageCapacityExpansion interface{} + type StorageClassExpansion interface{} type VolumeAttachmentExpansion interface{} diff --git a/staging/src/k8s.io/client-go/kubernetes/typed/storage/v1/storage_client.go b/staging/src/k8s.io/client-go/kubernetes/typed/storage/v1/storage_client.go index b31862f439a3..750fe8b62b4e 100644 --- a/staging/src/k8s.io/client-go/kubernetes/typed/storage/v1/storage_client.go +++ b/staging/src/k8s.io/client-go/kubernetes/typed/storage/v1/storage_client.go @@ -30,6 +30,7 @@ type StorageV1Interface interface { RESTClient() rest.Interface CSIDriversGetter CSINodesGetter + CSIStorageCapacitiesGetter StorageClassesGetter VolumeAttachmentsGetter } @@ -47,6 +48,10 @@ func (c *StorageV1Client) CSINodes() CSINodeInterface { return newCSINodes(c) } +func (c *StorageV1Client) CSIStorageCapacities(namespace string) CSIStorageCapacityInterface { + return newCSIStorageCapacities(c, namespace) +} + func (c *StorageV1Client) StorageClasses() StorageClassInterface { return newStorageClasses(c) } diff --git a/staging/src/k8s.io/client-go/listers/storage/v1/csistoragecapacity.go b/staging/src/k8s.io/client-go/listers/storage/v1/csistoragecapacity.go new file mode 100644 index 000000000000..a72328c9a3f8 --- /dev/null +++ b/staging/src/k8s.io/client-go/listers/storage/v1/csistoragecapacity.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 v1 + +import ( + v1 "k8s.io/api/storage/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// CSIStorageCapacityLister helps list CSIStorageCapacities. +// All objects returned here must be treated as read-only. +type CSIStorageCapacityLister interface { + // List lists all CSIStorageCapacities in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.CSIStorageCapacity, err error) + // CSIStorageCapacities returns an object that can list and get CSIStorageCapacities. + CSIStorageCapacities(namespace string) CSIStorageCapacityNamespaceLister + CSIStorageCapacityListerExpansion +} + +// cSIStorageCapacityLister implements the CSIStorageCapacityLister interface. +type cSIStorageCapacityLister struct { + indexer cache.Indexer +} + +// NewCSIStorageCapacityLister returns a new CSIStorageCapacityLister. +func NewCSIStorageCapacityLister(indexer cache.Indexer) CSIStorageCapacityLister { + return &cSIStorageCapacityLister{indexer: indexer} +} + +// List lists all CSIStorageCapacities in the indexer. +func (s *cSIStorageCapacityLister) List(selector labels.Selector) (ret []*v1.CSIStorageCapacity, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.CSIStorageCapacity)) + }) + return ret, err +} + +// CSIStorageCapacities returns an object that can list and get CSIStorageCapacities. +func (s *cSIStorageCapacityLister) CSIStorageCapacities(namespace string) CSIStorageCapacityNamespaceLister { + return cSIStorageCapacityNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// CSIStorageCapacityNamespaceLister helps list and get CSIStorageCapacities. +// All objects returned here must be treated as read-only. +type CSIStorageCapacityNamespaceLister interface { + // List lists all CSIStorageCapacities in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.CSIStorageCapacity, err error) + // Get retrieves the CSIStorageCapacity from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.CSIStorageCapacity, error) + CSIStorageCapacityNamespaceListerExpansion +} + +// cSIStorageCapacityNamespaceLister implements the CSIStorageCapacityNamespaceLister +// interface. +type cSIStorageCapacityNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all CSIStorageCapacities in the indexer for a given namespace. +func (s cSIStorageCapacityNamespaceLister) List(selector labels.Selector) (ret []*v1.CSIStorageCapacity, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.CSIStorageCapacity)) + }) + return ret, err +} + +// Get retrieves the CSIStorageCapacity from the indexer for a given namespace and name. +func (s cSIStorageCapacityNamespaceLister) Get(name string) (*v1.CSIStorageCapacity, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("csistoragecapacity"), name) + } + return obj.(*v1.CSIStorageCapacity), nil +} diff --git a/staging/src/k8s.io/client-go/listers/storage/v1/expansion_generated.go b/staging/src/k8s.io/client-go/listers/storage/v1/expansion_generated.go index 172f835f71b3..196b787e7eac 100644 --- a/staging/src/k8s.io/client-go/listers/storage/v1/expansion_generated.go +++ b/staging/src/k8s.io/client-go/listers/storage/v1/expansion_generated.go @@ -26,6 +26,14 @@ type CSIDriverListerExpansion interface{} // CSINodeLister. type CSINodeListerExpansion interface{} +// CSIStorageCapacityListerExpansion allows custom methods to be added to +// CSIStorageCapacityLister. +type CSIStorageCapacityListerExpansion interface{} + +// CSIStorageCapacityNamespaceListerExpansion allows custom methods to be added to +// CSIStorageCapacityNamespaceLister. +type CSIStorageCapacityNamespaceListerExpansion interface{} + // StorageClassListerExpansion allows custom methods to be added to // StorageClassLister. type StorageClassListerExpansion interface{} diff --git a/test/e2e/storage/csi_mock_volume.go b/test/e2e/storage/csi_mock_volume.go index 8b14bbce45ea..8233bddf6bc5 100644 --- a/test/e2e/storage/csi_mock_volume.go +++ b/test/e2e/storage/csi_mock_volume.go @@ -31,7 +31,6 @@ import ( "google.golang.org/grpc/status" v1 "k8s.io/api/core/v1" storagev1 "k8s.io/api/storage/v1" - storagev1beta1 "k8s.io/api/storage/v1beta1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -1387,7 +1386,7 @@ var _ = utils.SIGDescribe("CSI mock volume", func() { // before adding CSIStorageCapacity objects for it. for _, capacityStr := range test.capacities { capacityQuantity := resource.MustParse(capacityStr) - capacity := &storagev1beta1.CSIStorageCapacity{ + capacity := &storagev1.CSIStorageCapacity{ ObjectMeta: metav1.ObjectMeta{ GenerateName: "fake-capacity-", }, @@ -1396,10 +1395,10 @@ var _ = utils.SIGDescribe("CSI mock volume", func() { NodeTopology: &metav1.LabelSelector{}, Capacity: &capacityQuantity, } - createdCapacity, err := f.ClientSet.StorageV1beta1().CSIStorageCapacities(f.Namespace.Name).Create(context.Background(), capacity, metav1.CreateOptions{}) + createdCapacity, err := f.ClientSet.StorageV1().CSIStorageCapacities(f.Namespace.Name).Create(context.Background(), capacity, metav1.CreateOptions{}) framework.ExpectNoError(err, "create CSIStorageCapacity %+v", *capacity) m.testCleanups = append(m.testCleanups, func() { - f.ClientSet.StorageV1beta1().CSIStorageCapacities(f.Namespace.Name).Delete(context.Background(), createdCapacity.Name, metav1.DeleteOptions{}) + f.ClientSet.StorageV1().CSIStorageCapacities(f.Namespace.Name).Delete(context.Background(), createdCapacity.Name, metav1.DeleteOptions{}) }) } diff --git a/test/e2e/storage/csistoragecapacity.go b/test/e2e/storage/csistoragecapacity.go new file mode 100644 index 000000000000..9c5401f85a40 --- /dev/null +++ b/test/e2e/storage/csistoragecapacity.go @@ -0,0 +1,258 @@ +/* +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 ( + "context" + "time" + + storagev1 "k8s.io/api/storage/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/kubernetes/test/e2e/framework" + "k8s.io/kubernetes/test/e2e/storage/utils" + + "github.com/onsi/ginkgo" +) + +var _ = utils.SIGDescribe("CSIStorageCapacity", func() { + f := framework.NewDefaultFramework("csistoragecapacity") + + /* + Release: v1.24 + Testname: CSIStorageCapacity API + Description: + The storage.k8s.io API group MUST exist in the /apis discovery document. + The storage.k8s.io/v1 API group/version MUST exist in the /apis/mode.k8s.io discovery document. + The csistoragecapacities resource MUST exist in the /apis/storage.k8s.io/v1 discovery document. + The csistoragecapacities resource must support create, get, list, watch, update, patch, delete, and deletecollection. + TODO (pohly): promote to framework.ConformanceIt + */ + ginkgo.It(" should support CSIStorageCapacities API operations", func() { + // Setup + cscVersion := "v1" + cscClient := f.ClientSet.StorageV1().CSIStorageCapacities(f.Namespace.Name) + cscClientNoNamespace := f.ClientSet.StorageV1().CSIStorageCapacities("") + + // The fictional StorageClass for these objects. + scName := "e2e.example.com" + + // All CRUD operations in this test are limited to the objects with the label test=f.UniqueName + newCSIStorageCapacity := func(nameSuffix string) *storagev1.CSIStorageCapacity { + return &storagev1.CSIStorageCapacity{ + ObjectMeta: metav1.ObjectMeta{ + Name: f.UniqueName + nameSuffix, + Labels: map[string]string{ + "test": f.UniqueName, + }, + }, + StorageClassName: scName, + } + } + csc := newCSIStorageCapacity("-csc1") + csc2 := newCSIStorageCapacity("-csc2") + csc3 := newCSIStorageCapacity("-csc3") + + // Discovery + + ginkgo.By("getting /apis") + { + discoveryGroups, err := f.ClientSet.Discovery().ServerGroups() + framework.ExpectNoError(err) + found := false + for _, group := range discoveryGroups.Groups { + if group.Name == storagev1.GroupName { + for _, version := range group.Versions { + if version.Version == cscVersion { + found = true + break + } + } + } + } + if !found { + framework.Failf("expected CSIStorageCapacity API group/version, got %#v", discoveryGroups.Groups) + } + } + + ginkgo.By("getting /apis/storage.k8s.io") + { + group := &metav1.APIGroup{} + err := f.ClientSet.Discovery().RESTClient().Get().AbsPath("/apis/storage.k8s.io").Do(context.TODO()).Into(group) + framework.ExpectNoError(err) + found := false + for _, version := range group.Versions { + if version.Version == cscVersion { + found = true + break + } + } + if !found { + framework.Failf("expected CSIStorageCapacity API version, got %#v", group.Versions) + } + } + + ginkgo.By("getting /apis/storage.k8s.io/" + cscVersion) + { + resources, err := f.ClientSet.Discovery().ServerResourcesForGroupVersion(storagev1.SchemeGroupVersion.String()) + framework.ExpectNoError(err) + found := false + for _, resource := range resources.APIResources { + switch resource.Name { + case "csistoragecapacities": + found = true + } + } + if !found { + framework.Failf("expected csistoragecapacities, got %#v", resources.APIResources) + } + } + + // Main resource create/read/update/watch operations + + ginkgo.By("creating") + createdCSC, err := cscClient.Create(context.TODO(), csc, metav1.CreateOptions{}) + framework.ExpectNoError(err) + _, err = cscClient.Create(context.TODO(), csc, metav1.CreateOptions{}) + if !apierrors.IsAlreadyExists(err) { + framework.Failf("expected 409, got %#v", err) + } + _, err = cscClient.Create(context.TODO(), csc2, metav1.CreateOptions{}) + framework.ExpectNoError(err) + + ginkgo.By("watching") + framework.Logf("starting watch") + cscWatch, err := cscClient.Watch(context.TODO(), metav1.ListOptions{LabelSelector: "test=" + f.UniqueName}) + framework.ExpectNoError(err) + cscWatchNoNamespace, err := cscClientNoNamespace.Watch(context.TODO(), metav1.ListOptions{LabelSelector: "test=" + f.UniqueName}) + framework.ExpectNoError(err) + + // added for a watch + _, err = cscClient.Create(context.TODO(), csc3, metav1.CreateOptions{}) + framework.ExpectNoError(err) + + ginkgo.By("getting") + gottenCSC, err := cscClient.Get(context.TODO(), csc.Name, metav1.GetOptions{}) + framework.ExpectNoError(err) + framework.ExpectEqual(gottenCSC.UID, createdCSC.UID) + + ginkgo.By("listing in namespace") + cscs, err := cscClient.List(context.TODO(), metav1.ListOptions{LabelSelector: "test=" + f.UniqueName}) + framework.ExpectNoError(err) + framework.ExpectEqual(len(cscs.Items), 3, "filtered list should have 3 items, got: %s", cscs) + + ginkgo.By("listing across namespaces") + cscs, err = cscClientNoNamespace.List(context.TODO(), metav1.ListOptions{LabelSelector: "test=" + f.UniqueName}) + framework.ExpectNoError(err) + framework.ExpectEqual(len(cscs.Items), 3, "filtered list should have 3 items, got: %s", cscs) + + ginkgo.By("patching") + patchedCSC, err := cscClient.Patch(context.TODO(), createdCSC.Name, types.MergePatchType, []byte(`{"metadata":{"annotations":{"patched":"true"}}}`), metav1.PatchOptions{}) + framework.ExpectNoError(err) + framework.ExpectEqual(patchedCSC.Annotations["patched"], "true", "patched object should have the applied annotation") + + ginkgo.By("updating") + csrToUpdate := patchedCSC.DeepCopy() + csrToUpdate.Annotations["updated"] = "true" + updatedCSC, err := cscClient.Update(context.TODO(), csrToUpdate, metav1.UpdateOptions{}) + framework.ExpectNoError(err) + framework.ExpectEqual(updatedCSC.Annotations["updated"], "true", "updated object should have the applied annotation") + + expectWatchResult := func(kind string, w watch.Interface) { + framework.Logf("waiting for watch events with expected annotations %s", kind) + for sawAdded, sawPatched, sawUpdated := false, false, false; !sawAdded && !sawPatched && !sawUpdated; { + select { + case evt, ok := <-w.ResultChan(): + if !ok { + framework.Failf("%s: watch channel should not close", kind) + } + if evt.Type == watch.Modified { + watchedCSC, isCSC := evt.Object.(*storagev1.CSIStorageCapacity) + if !isCSC { + framework.Failf("%s: expected CSC, got %T", kind, evt.Object) + } + if watchedCSC.Annotations["patched"] == "true" { + framework.Logf("%s: saw patched annotations", kind) + sawPatched = true + } else if watchedCSC.Annotations["updated"] == "true" { + framework.Logf("%s: saw updated annotations", kind) + sawUpdated = true + } else { + framework.Logf("%s: missing expected annotations, waiting: %#v", kind, watchedCSC.Annotations) + } + } else if evt.Type == watch.Added { + _, isCSC := evt.Object.(*storagev1.CSIStorageCapacity) + if !isCSC { + framework.Failf("%s: expected CSC, got %T", kind, evt.Object) + } + sawAdded = true + } + + case <-time.After(wait.ForeverTestTimeout): + framework.Failf("%s: timed out waiting for watch event", kind) + } + } + w.Stop() + } + expectWatchResult("in namespace", cscWatch) + expectWatchResult("across namespace", cscWatchNoNamespace) + + // main resource delete operations + + ginkgo.By("deleting") + err = cscClient.Delete(context.TODO(), createdCSC.Name, metav1.DeleteOptions{}) + framework.ExpectNoError(err) + csc, err = cscClient.Get(context.TODO(), createdCSC.Name, metav1.GetOptions{}) + min := 2 + max := min + switch { + case apierrors.IsNotFound(err): + // Okay, normal case. + case err != nil: + // Unexpected error. + framework.Failf("expected 404, got %#v", err) + case csc.DeletionTimestamp != nil && len(csc.Finalizers) > 0: + // Deletion was prevented by a finalizer, but it might + // still get deleted before we list them below. + max++ + default: + framework.Failf("CSIStorageCapacitity should have been deleted or have DeletionTimestamp and Finalizers, but instead got: %s", csc) + } + cscs, err = cscClient.List(context.TODO(), metav1.ListOptions{LabelSelector: "test=" + f.UniqueName}) + framework.ExpectNoError(err) + actualLen := len(cscs.Items) + if actualLen < min || actualLen > max { + framework.Failf("expected <= %d and >= %d remaining CSIStorageCapacity objects, got %d: %v", max, min, actualLen, cscs.Items) + } + + ginkgo.By("deleting a collection") + err = cscClient.DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{LabelSelector: "test=" + f.UniqueName}) + framework.ExpectNoError(err) + cscs, err = cscClient.List(context.TODO(), metav1.ListOptions{LabelSelector: "test=" + f.UniqueName}) + framework.ExpectNoError(err) + for _, csc := range cscs.Items { + // Any remaining objects should be marked for deletion + // and only held back by a Finalizer. + if csc.DeletionTimestamp == nil || len(csc.Finalizers) == 0 { + framework.Failf("CSIStorageCapacity should have been deleted or have DeletionTimestamp and Finalizers, but instead got: %s", &csc) + } + } + }) +}) diff --git a/test/e2e/storage/testsuites/capacity.go b/test/e2e/storage/testsuites/capacity.go index ac223be8e597..8dcfe0747e74 100644 --- a/test/e2e/storage/testsuites/capacity.go +++ b/test/e2e/storage/testsuites/capacity.go @@ -27,7 +27,6 @@ import ( "github.com/onsi/gomega/types" storagev1 "k8s.io/api/storage/v1" - storagev1beta1 "k8s.io/api/storage/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/kubernetes/test/e2e/framework" @@ -115,8 +114,8 @@ func (p *capacityTestSuite) DefineTests(driver storageframework.TestDriver, patt timeout := time.Minute pollInterval := time.Second matchSC := HaveCapacitiesForClass(sc.Name) - listAll := gomega.Eventually(func() (*storagev1beta1.CSIStorageCapacityList, error) { - return f.ClientSet.StorageV1beta1().CSIStorageCapacities("").List(context.Background(), metav1.ListOptions{}) + listAll := gomega.Eventually(func() (*storagev1.CSIStorageCapacityList, error) { + return f.ClientSet.StorageV1().CSIStorageCapacities("").List(context.Background(), metav1.ListOptions{}) }, timeout, pollInterval) // If we have further information about what storage @@ -150,7 +149,7 @@ func (p *capacityTestSuite) DefineTests(driver storageframework.TestDriver, patt }) } -func formatCapacities(capacities []storagev1beta1.CSIStorageCapacity) []string { +func formatCapacities(capacities []storagev1.CSIStorageCapacity) []string { lines := []string{} for _, capacity := range capacities { lines = append(lines, fmt.Sprintf(" %+v", capacity)) @@ -158,7 +157,7 @@ func formatCapacities(capacities []storagev1beta1.CSIStorageCapacity) []string { return lines } -// MatchCapacities runs some kind of check against *storagev1beta1.CSIStorageCapacityList. +// MatchCapacities runs some kind of check against *storagev1.CSIStorageCapacityList. // In case of failure, all actual objects are appended to the failure message. func MatchCapacities(match types.GomegaMatcher) types.GomegaMatcher { return matchCSIStorageCapacities{match: match} @@ -183,7 +182,7 @@ func (m matchCSIStorageCapacities) NegatedFailureMessage(actual interface{}) (me } func (m matchCSIStorageCapacities) dump(actual interface{}) string { - capacities, ok := actual.(*storagev1beta1.CSIStorageCapacityList) + capacities, ok := actual.(*storagev1.CSIStorageCapacityList) if !ok || capacities == nil { return "" } @@ -201,10 +200,10 @@ type CapacityMatcher interface { types.GomegaMatcher // MatchedCapacities returns all CSICapacityObjects which were // found during the preceding Match call. - MatchedCapacities() []storagev1beta1.CSIStorageCapacity + MatchedCapacities() []storagev1.CSIStorageCapacity } -// HaveCapacitiesForClass filters all storage capacity objects in a *storagev1beta1.CSIStorageCapacityList +// HaveCapacitiesForClass filters all storage capacity objects in a *storagev1.CSIStorageCapacityList // by storage class. Success is when when there is at least one. func HaveCapacitiesForClass(scName string) CapacityMatcher { return &haveCSIStorageCapacities{scName: scName} @@ -212,15 +211,15 @@ func HaveCapacitiesForClass(scName string) CapacityMatcher { type haveCSIStorageCapacities struct { scName string - matchingCapacities []storagev1beta1.CSIStorageCapacity + matchingCapacities []storagev1.CSIStorageCapacity } var _ CapacityMatcher = &haveCSIStorageCapacities{} func (h *haveCSIStorageCapacities) Match(actual interface{}) (success bool, err error) { - capacities, ok := actual.(*storagev1beta1.CSIStorageCapacityList) + capacities, ok := actual.(*storagev1.CSIStorageCapacityList) if !ok { - return false, fmt.Errorf("expected *storagev1beta1.CSIStorageCapacityList, got: %T", actual) + return false, fmt.Errorf("expected *storagev1.CSIStorageCapacityList, got: %T", actual) } h.matchingCapacities = nil for _, capacity := range capacities.Items { @@ -231,7 +230,7 @@ func (h *haveCSIStorageCapacities) Match(actual interface{}) (success bool, err return len(h.matchingCapacities) > 0, nil } -func (h *haveCSIStorageCapacities) MatchedCapacities() []storagev1beta1.CSIStorageCapacity { +func (h *haveCSIStorageCapacities) MatchedCapacities() []storagev1.CSIStorageCapacity { return h.matchingCapacities } @@ -264,8 +263,8 @@ type haveLocalStorageCapacities struct { topologyKey string matchSuccess bool - expectedCapacities []storagev1beta1.CSIStorageCapacity - unexpectedCapacities []storagev1beta1.CSIStorageCapacity + expectedCapacities []storagev1.CSIStorageCapacity + unexpectedCapacities []storagev1.CSIStorageCapacity missingTopologyValues []string } @@ -340,7 +339,7 @@ func (h *haveLocalStorageCapacities) Match(actual interface{}) (success bool, er return len(h.unexpectedCapacities) == 0 && len(h.missingTopologyValues) == 0, nil } -func (h *haveLocalStorageCapacities) MatchedCapacities() []storagev1beta1.CSIStorageCapacity { +func (h *haveLocalStorageCapacities) MatchedCapacities() []storagev1.CSIStorageCapacity { return h.match.MatchedCapacities() } diff --git a/test/integration/apiserver/print_test.go b/test/integration/apiserver/print_test.go index 8f8b52b802d4..e1bcc7b4afd6 100644 --- a/test/integration/apiserver/print_test.go +++ b/test/integration/apiserver/print_test.go @@ -30,16 +30,13 @@ import ( metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/cli-runtime/pkg/genericclioptions" diskcached "k8s.io/client-go/discovery/cached/disk" "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - featuregatetesting "k8s.io/component-base/featuregate/testing" "k8s.io/gengo/examples/set-gen/sets" "k8s.io/kubectl/pkg/cmd/util" "k8s.io/kubernetes/pkg/api/legacyscheme" - "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/printers" printersinternal "k8s.io/kubernetes/pkg/printers/internalversion" "k8s.io/kubernetes/test/integration/framework" @@ -123,8 +120,6 @@ var missingHanlders = sets.NewString( ) func TestServerSidePrint(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, true)() - s, _, closeFn := setupWithResources(t, // additional groupversions needed for the test to run []schema.GroupVersion{ diff --git a/test/integration/etcd/data.go b/test/integration/etcd/data.go index 8381ac30ea00..eeb5e99c025b 100644 --- a/test/integration/etcd/data.go +++ b/test/integration/etcd/data.go @@ -314,7 +314,6 @@ func GetEtcdStorageDataForNamespace(namespace string) map[schema.GroupVersionRes }, // -- - // k8s.io/kubernetes/pkg/apis/storage/v1beta1 // k8s.io/kubernetes/pkg/apis/storage/v1beta1 gvr("storage.k8s.io", "v1beta1", "csistoragecapacities"): { Stub: `{"metadata": {"name": "csc-12345-2"}, "storageClassName": "sc1"}`, @@ -327,6 +326,11 @@ func GetEtcdStorageDataForNamespace(namespace string) map[schema.GroupVersionRes Stub: `{"metadata": {"name": "sc2"}, "provisioner": "aws"}`, ExpectedEtcdPath: "/registry/storageclasses/sc2", }, + gvr("storage.k8s.io", "v1", "csistoragecapacities"): { + Stub: `{"metadata": {"name": "csc-12345-3"}, "storageClassName": "sc1"}`, + ExpectedEtcdPath: "/registry/csistoragecapacities/" + namespace + "/csc-12345-3", + ExpectedGVK: gvkP("storage.k8s.io", "v1beta1", "CSIStorageCapacity"), + }, // -- // k8s.io/kubernetes/pkg/apis/rbac/v1 diff --git a/test/integration/volumescheduling/util.go b/test/integration/volumescheduling/util.go index 4217b7d5d76c..ac23685fe7eb 100644 --- a/test/integration/volumescheduling/util.go +++ b/test/integration/volumescheduling/util.go @@ -29,14 +29,12 @@ import ( "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apiserver/pkg/admission" - utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/informers" clientset "k8s.io/client-go/kubernetes" restclient "k8s.io/client-go/rest" "k8s.io/client-go/tools/events" podutil "k8s.io/kubernetes/pkg/api/v1/pod" "k8s.io/kubernetes/pkg/controlplane" - "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/scheduler" "k8s.io/kubernetes/pkg/scheduler/profile" "k8s.io/kubernetes/test/integration/framework" @@ -73,12 +71,6 @@ func initTestAPIServer(t *testing.T, nsPrefix string, admission admission.Interf controlPlaneConfig := framework.NewIntegrationTestControlPlaneConfig() resourceConfig := controlplane.DefaultAPIResourceConfigSource() - if utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) { - resourceConfig.EnableVersions(schema.GroupVersion{ - Group: "storage.k8s.io", - Version: "v1alpha1", - }) - } controlPlaneConfig.ExtraConfig.APIResourceConfigSource = resourceConfig if admission != nil { diff --git a/test/integration/volumescheduling/volume_binding_test.go b/test/integration/volumescheduling/volume_binding_test.go index 2f81ddc0f089..99b2bd49f851 100644 --- a/test/integration/volumescheduling/volume_binding_test.go +++ b/test/integration/volumescheduling/volume_binding_test.go @@ -31,19 +31,15 @@ import ( v1 "k8s.io/api/core/v1" storagev1 "k8s.io/api/storage/v1" - storagev1beta1 "k8s.io/api/storage/v1beta1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/rand" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/wait" - utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/informers" clientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/util/workqueue" - featuregatetesting "k8s.io/component-base/featuregate/testing" "k8s.io/kubernetes/pkg/controller/volume/persistentvolume" - "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits" "k8s.io/kubernetes/pkg/volume" volumetest "k8s.io/kubernetes/pkg/volume/testing" @@ -704,13 +700,6 @@ func TestPVAffinityConflict(t *testing.T) { } func TestVolumeProvision(t *testing.T) { - t.Run("with CSIStorageCapacity", func(t *testing.T) { testVolumeProvision(t, true) }) - t.Run("without CSIStorageCapacity", func(t *testing.T) { testVolumeProvision(t, false) }) -} - -func testVolumeProvision(t *testing.T, storageCapacity bool) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, storageCapacity)() - config := setupCluster(t, "volume-scheduling", 1, 0, 0) defer config.teardown() @@ -859,8 +848,6 @@ func testVolumeProvision(t *testing.T, storageCapacity bool) { // TestCapacity covers different scenarios involving CSIStorageCapacity objects. func TestCapacity(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, true)() - config := setupCluster(t, "volume-scheduling", 1, 0, 0) defer config.teardown() @@ -941,8 +928,8 @@ func TestCapacity(t *testing.T) { // Create CSIStorageCapacity if test.haveCapacity { - if _, err := config.client.StorageV1beta1().CSIStorageCapacities("default").Create(context.TODO(), - &storagev1beta1.CSIStorageCapacity{ + if _, err := config.client.StorageV1().CSIStorageCapacities("default").Create(context.TODO(), + &storagev1.CSIStorageCapacity{ ObjectMeta: metav1.ObjectMeta{ GenerateName: "foo-", }, @@ -1155,7 +1142,7 @@ func deleteTestObjects(client clientset.Interface, ns string, option metav1.Dele client.CoreV1().PersistentVolumes().DeleteCollection(context.TODO(), option, metav1.ListOptions{}) client.StorageV1().StorageClasses().DeleteCollection(context.TODO(), option, metav1.ListOptions{}) client.StorageV1().CSIDrivers().DeleteCollection(context.TODO(), option, metav1.ListOptions{}) - client.StorageV1beta1().CSIStorageCapacities("default").DeleteCollection(context.TODO(), option, metav1.ListOptions{}) + client.StorageV1().CSIStorageCapacities("default").DeleteCollection(context.TODO(), option, metav1.ListOptions{}) } func makeStorageClass(name string, mode *storagev1.VolumeBindingMode) *storagev1.StorageClass {