From e7d74047c1165e114a3a19aba6d1187395e93f4e Mon Sep 17 00:00:00 2001 From: yliao Date: Mon, 13 Jan 2025 20:30:24 +0000 Subject: [PATCH 01/30] update version constants for 32.0.0a1 release --- scripts/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/constants.py b/scripts/constants.py index 2f9c44228b..7e9db65bd8 100644 --- a/scripts/constants.py +++ b/scripts/constants.py @@ -18,7 +18,7 @@ KUBERNETES_BRANCH = "release-1.32" # client version for packaging and releasing. -CLIENT_VERSION = "32.0.0+snapshot" +CLIENT_VERSION = "32.0.0a1" # Name of the release package PACKAGE_NAME = "kubernetes" From 412300b2e099cab33be6d401d274b07a3b75a2eb Mon Sep 17 00:00:00 2001 From: yliao Date: Mon, 13 Jan 2025 20:30:25 +0000 Subject: [PATCH 02/30] update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b1ed49521..f750e89057 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# v32.0.0+snapshot +# v32.0.0a1 Kubernetes API Version: v1.32.0 From 7cedb076c0fca5216af5f757b454cc9de039cebe Mon Sep 17 00:00:00 2001 From: yliao Date: Mon, 13 Jan 2025 20:30:57 +0000 Subject: [PATCH 03/30] generated API change --- kubernetes/client/models/v1alpha3_resource_claim_status.py | 4 ++-- kubernetes/client/models/v1beta1_resource_claim_status.py | 4 ++-- kubernetes/docs/V1alpha3ResourceClaimStatus.md | 2 +- kubernetes/docs/V1beta1ResourceClaimStatus.md | 2 +- kubernetes/swagger.json.unprocessed | 4 ++-- scripts/swagger.json | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/kubernetes/client/models/v1alpha3_resource_claim_status.py b/kubernetes/client/models/v1alpha3_resource_claim_status.py index bb8a470e1d..b5083f8f90 100644 --- a/kubernetes/client/models/v1alpha3_resource_claim_status.py +++ b/kubernetes/client/models/v1alpha3_resource_claim_status.py @@ -110,7 +110,7 @@ def devices(self, devices): def reserved_for(self): """Gets the reserved_for of this V1alpha3ResourceClaimStatus. # noqa: E501 - ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started. A claim that is in use or might be in use because it has been reserved must not get deallocated. In a cluster with multiple scheduler instances, two pods might get scheduled concurrently by different schedulers. When they reference the same ResourceClaim which already has reached its maximum number of consumers, only one pod can be scheduled. Both schedulers try to add their pod to the claim.status.reservedFor field, but only the update that reaches the API server first gets stored. The other one fails with an error and the scheduler which issued it knows that it must put the pod back into the queue, waiting for the ResourceClaim to become usable again. There can be at most 32 such reservations. This may get increased in the future, but not reduced. # noqa: E501 + ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started. A claim that is in use or might be in use because it has been reserved must not get deallocated. In a cluster with multiple scheduler instances, two pods might get scheduled concurrently by different schedulers. When they reference the same ResourceClaim which already has reached its maximum number of consumers, only one pod can be scheduled. Both schedulers try to add their pod to the claim.status.reservedFor field, but only the update that reaches the API server first gets stored. The other one fails with an error and the scheduler which issued it knows that it must put the pod back into the queue, waiting for the ResourceClaim to become usable again. There can be at most 256 such reservations. This may get increased in the future, but not reduced. # noqa: E501 :return: The reserved_for of this V1alpha3ResourceClaimStatus. # noqa: E501 :rtype: list[V1alpha3ResourceClaimConsumerReference] @@ -121,7 +121,7 @@ def reserved_for(self): def reserved_for(self, reserved_for): """Sets the reserved_for of this V1alpha3ResourceClaimStatus. - ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started. A claim that is in use or might be in use because it has been reserved must not get deallocated. In a cluster with multiple scheduler instances, two pods might get scheduled concurrently by different schedulers. When they reference the same ResourceClaim which already has reached its maximum number of consumers, only one pod can be scheduled. Both schedulers try to add their pod to the claim.status.reservedFor field, but only the update that reaches the API server first gets stored. The other one fails with an error and the scheduler which issued it knows that it must put the pod back into the queue, waiting for the ResourceClaim to become usable again. There can be at most 32 such reservations. This may get increased in the future, but not reduced. # noqa: E501 + ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started. A claim that is in use or might be in use because it has been reserved must not get deallocated. In a cluster with multiple scheduler instances, two pods might get scheduled concurrently by different schedulers. When they reference the same ResourceClaim which already has reached its maximum number of consumers, only one pod can be scheduled. Both schedulers try to add their pod to the claim.status.reservedFor field, but only the update that reaches the API server first gets stored. The other one fails with an error and the scheduler which issued it knows that it must put the pod back into the queue, waiting for the ResourceClaim to become usable again. There can be at most 256 such reservations. This may get increased in the future, but not reduced. # noqa: E501 :param reserved_for: The reserved_for of this V1alpha3ResourceClaimStatus. # noqa: E501 :type: list[V1alpha3ResourceClaimConsumerReference] diff --git a/kubernetes/client/models/v1beta1_resource_claim_status.py b/kubernetes/client/models/v1beta1_resource_claim_status.py index 67cf633317..38d7efce72 100644 --- a/kubernetes/client/models/v1beta1_resource_claim_status.py +++ b/kubernetes/client/models/v1beta1_resource_claim_status.py @@ -110,7 +110,7 @@ def devices(self, devices): def reserved_for(self): """Gets the reserved_for of this V1beta1ResourceClaimStatus. # noqa: E501 - ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started. A claim that is in use or might be in use because it has been reserved must not get deallocated. In a cluster with multiple scheduler instances, two pods might get scheduled concurrently by different schedulers. When they reference the same ResourceClaim which already has reached its maximum number of consumers, only one pod can be scheduled. Both schedulers try to add their pod to the claim.status.reservedFor field, but only the update that reaches the API server first gets stored. The other one fails with an error and the scheduler which issued it knows that it must put the pod back into the queue, waiting for the ResourceClaim to become usable again. There can be at most 32 such reservations. This may get increased in the future, but not reduced. # noqa: E501 + ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started. A claim that is in use or might be in use because it has been reserved must not get deallocated. In a cluster with multiple scheduler instances, two pods might get scheduled concurrently by different schedulers. When they reference the same ResourceClaim which already has reached its maximum number of consumers, only one pod can be scheduled. Both schedulers try to add their pod to the claim.status.reservedFor field, but only the update that reaches the API server first gets stored. The other one fails with an error and the scheduler which issued it knows that it must put the pod back into the queue, waiting for the ResourceClaim to become usable again. There can be at most 256 such reservations. This may get increased in the future, but not reduced. # noqa: E501 :return: The reserved_for of this V1beta1ResourceClaimStatus. # noqa: E501 :rtype: list[V1beta1ResourceClaimConsumerReference] @@ -121,7 +121,7 @@ def reserved_for(self): def reserved_for(self, reserved_for): """Sets the reserved_for of this V1beta1ResourceClaimStatus. - ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started. A claim that is in use or might be in use because it has been reserved must not get deallocated. In a cluster with multiple scheduler instances, two pods might get scheduled concurrently by different schedulers. When they reference the same ResourceClaim which already has reached its maximum number of consumers, only one pod can be scheduled. Both schedulers try to add their pod to the claim.status.reservedFor field, but only the update that reaches the API server first gets stored. The other one fails with an error and the scheduler which issued it knows that it must put the pod back into the queue, waiting for the ResourceClaim to become usable again. There can be at most 32 such reservations. This may get increased in the future, but not reduced. # noqa: E501 + ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started. A claim that is in use or might be in use because it has been reserved must not get deallocated. In a cluster with multiple scheduler instances, two pods might get scheduled concurrently by different schedulers. When they reference the same ResourceClaim which already has reached its maximum number of consumers, only one pod can be scheduled. Both schedulers try to add their pod to the claim.status.reservedFor field, but only the update that reaches the API server first gets stored. The other one fails with an error and the scheduler which issued it knows that it must put the pod back into the queue, waiting for the ResourceClaim to become usable again. There can be at most 256 such reservations. This may get increased in the future, but not reduced. # noqa: E501 :param reserved_for: The reserved_for of this V1beta1ResourceClaimStatus. # noqa: E501 :type: list[V1beta1ResourceClaimConsumerReference] diff --git a/kubernetes/docs/V1alpha3ResourceClaimStatus.md b/kubernetes/docs/V1alpha3ResourceClaimStatus.md index d2466fe164..c058e540a6 100644 --- a/kubernetes/docs/V1alpha3ResourceClaimStatus.md +++ b/kubernetes/docs/V1alpha3ResourceClaimStatus.md @@ -6,7 +6,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **allocation** | [**V1alpha3AllocationResult**](V1alpha3AllocationResult.md) | | [optional] **devices** | [**list[V1alpha3AllocatedDeviceStatus]**](V1alpha3AllocatedDeviceStatus.md) | Devices contains the status of each device allocated for this claim, as reported by the driver. This can include driver-specific information. Entries are owned by their respective drivers. | [optional] -**reserved_for** | [**list[V1alpha3ResourceClaimConsumerReference]**](V1alpha3ResourceClaimConsumerReference.md) | ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started. A claim that is in use or might be in use because it has been reserved must not get deallocated. In a cluster with multiple scheduler instances, two pods might get scheduled concurrently by different schedulers. When they reference the same ResourceClaim which already has reached its maximum number of consumers, only one pod can be scheduled. Both schedulers try to add their pod to the claim.status.reservedFor field, but only the update that reaches the API server first gets stored. The other one fails with an error and the scheduler which issued it knows that it must put the pod back into the queue, waiting for the ResourceClaim to become usable again. There can be at most 32 such reservations. This may get increased in the future, but not reduced. | [optional] +**reserved_for** | [**list[V1alpha3ResourceClaimConsumerReference]**](V1alpha3ResourceClaimConsumerReference.md) | ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started. A claim that is in use or might be in use because it has been reserved must not get deallocated. In a cluster with multiple scheduler instances, two pods might get scheduled concurrently by different schedulers. When they reference the same ResourceClaim which already has reached its maximum number of consumers, only one pod can be scheduled. Both schedulers try to add their pod to the claim.status.reservedFor field, but only the update that reaches the API server first gets stored. The other one fails with an error and the scheduler which issued it knows that it must put the pod back into the queue, waiting for the ResourceClaim to become usable again. There can be at most 256 such reservations. This may get increased in the future, but not reduced. | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/kubernetes/docs/V1beta1ResourceClaimStatus.md b/kubernetes/docs/V1beta1ResourceClaimStatus.md index 401b53eae1..5c46654337 100644 --- a/kubernetes/docs/V1beta1ResourceClaimStatus.md +++ b/kubernetes/docs/V1beta1ResourceClaimStatus.md @@ -6,7 +6,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **allocation** | [**V1beta1AllocationResult**](V1beta1AllocationResult.md) | | [optional] **devices** | [**list[V1beta1AllocatedDeviceStatus]**](V1beta1AllocatedDeviceStatus.md) | Devices contains the status of each device allocated for this claim, as reported by the driver. This can include driver-specific information. Entries are owned by their respective drivers. | [optional] -**reserved_for** | [**list[V1beta1ResourceClaimConsumerReference]**](V1beta1ResourceClaimConsumerReference.md) | ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started. A claim that is in use or might be in use because it has been reserved must not get deallocated. In a cluster with multiple scheduler instances, two pods might get scheduled concurrently by different schedulers. When they reference the same ResourceClaim which already has reached its maximum number of consumers, only one pod can be scheduled. Both schedulers try to add their pod to the claim.status.reservedFor field, but only the update that reaches the API server first gets stored. The other one fails with an error and the scheduler which issued it knows that it must put the pod back into the queue, waiting for the ResourceClaim to become usable again. There can be at most 32 such reservations. This may get increased in the future, but not reduced. | [optional] +**reserved_for** | [**list[V1beta1ResourceClaimConsumerReference]**](V1beta1ResourceClaimConsumerReference.md) | ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started. A claim that is in use or might be in use because it has been reserved must not get deallocated. In a cluster with multiple scheduler instances, two pods might get scheduled concurrently by different schedulers. When they reference the same ResourceClaim which already has reached its maximum number of consumers, only one pod can be scheduled. Both schedulers try to add their pod to the claim.status.reservedFor field, but only the update that reaches the API server first gets stored. The other one fails with an error and the scheduler which issued it knows that it must put the pod back into the queue, waiting for the ResourceClaim to become usable again. There can be at most 256 such reservations. This may get increased in the future, but not reduced. | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/kubernetes/swagger.json.unprocessed b/kubernetes/swagger.json.unprocessed index ad115fd0ad..ffbe70c72e 100644 --- a/kubernetes/swagger.json.unprocessed +++ b/kubernetes/swagger.json.unprocessed @@ -15123,7 +15123,7 @@ "x-kubernetes-list-type": "map" }, "reservedFor": { - "description": "ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started. A claim that is in use or might be in use because it has been reserved must not get deallocated.\n\nIn a cluster with multiple scheduler instances, two pods might get scheduled concurrently by different schedulers. When they reference the same ResourceClaim which already has reached its maximum number of consumers, only one pod can be scheduled.\n\nBoth schedulers try to add their pod to the claim.status.reservedFor field, but only the update that reaches the API server first gets stored. The other one fails with an error and the scheduler which issued it knows that it must put the pod back into the queue, waiting for the ResourceClaim to become usable again.\n\nThere can be at most 32 such reservations. This may get increased in the future, but not reduced.", + "description": "ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started. A claim that is in use or might be in use because it has been reserved must not get deallocated.\n\nIn a cluster with multiple scheduler instances, two pods might get scheduled concurrently by different schedulers. When they reference the same ResourceClaim which already has reached its maximum number of consumers, only one pod can be scheduled.\n\nBoth schedulers try to add their pod to the claim.status.reservedFor field, but only the update that reaches the API server first gets stored. The other one fails with an error and the scheduler which issued it knows that it must put the pod back into the queue, waiting for the ResourceClaim to become usable again.\n\nThere can be at most 256 such reservations. This may get increased in the future, but not reduced.", "items": { "$ref": "#/definitions/io.k8s.api.resource.v1alpha3.ResourceClaimConsumerReference" }, @@ -15956,7 +15956,7 @@ "x-kubernetes-list-type": "map" }, "reservedFor": { - "description": "ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started. A claim that is in use or might be in use because it has been reserved must not get deallocated.\n\nIn a cluster with multiple scheduler instances, two pods might get scheduled concurrently by different schedulers. When they reference the same ResourceClaim which already has reached its maximum number of consumers, only one pod can be scheduled.\n\nBoth schedulers try to add their pod to the claim.status.reservedFor field, but only the update that reaches the API server first gets stored. The other one fails with an error and the scheduler which issued it knows that it must put the pod back into the queue, waiting for the ResourceClaim to become usable again.\n\nThere can be at most 32 such reservations. This may get increased in the future, but not reduced.", + "description": "ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started. A claim that is in use or might be in use because it has been reserved must not get deallocated.\n\nIn a cluster with multiple scheduler instances, two pods might get scheduled concurrently by different schedulers. When they reference the same ResourceClaim which already has reached its maximum number of consumers, only one pod can be scheduled.\n\nBoth schedulers try to add their pod to the claim.status.reservedFor field, but only the update that reaches the API server first gets stored. The other one fails with an error and the scheduler which issued it knows that it must put the pod back into the queue, waiting for the ResourceClaim to become usable again.\n\nThere can be at most 256 such reservations. This may get increased in the future, but not reduced.", "items": { "$ref": "#/definitions/io.k8s.api.resource.v1beta1.ResourceClaimConsumerReference" }, diff --git a/scripts/swagger.json b/scripts/swagger.json index 151f99da50..1c3b32f4c1 100644 --- a/scripts/swagger.json +++ b/scripts/swagger.json @@ -15199,7 +15199,7 @@ "x-kubernetes-list-type": "map" }, "reservedFor": { - "description": "ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started. A claim that is in use or might be in use because it has been reserved must not get deallocated.\n\nIn a cluster with multiple scheduler instances, two pods might get scheduled concurrently by different schedulers. When they reference the same ResourceClaim which already has reached its maximum number of consumers, only one pod can be scheduled.\n\nBoth schedulers try to add their pod to the claim.status.reservedFor field, but only the update that reaches the API server first gets stored. The other one fails with an error and the scheduler which issued it knows that it must put the pod back into the queue, waiting for the ResourceClaim to become usable again.\n\nThere can be at most 32 such reservations. This may get increased in the future, but not reduced.", + "description": "ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started. A claim that is in use or might be in use because it has been reserved must not get deallocated.\n\nIn a cluster with multiple scheduler instances, two pods might get scheduled concurrently by different schedulers. When they reference the same ResourceClaim which already has reached its maximum number of consumers, only one pod can be scheduled.\n\nBoth schedulers try to add their pod to the claim.status.reservedFor field, but only the update that reaches the API server first gets stored. The other one fails with an error and the scheduler which issued it knows that it must put the pod back into the queue, waiting for the ResourceClaim to become usable again.\n\nThere can be at most 256 such reservations. This may get increased in the future, but not reduced.", "items": { "$ref": "#/definitions/v1alpha3.ResourceClaimConsumerReference" }, @@ -16032,7 +16032,7 @@ "x-kubernetes-list-type": "map" }, "reservedFor": { - "description": "ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started. A claim that is in use or might be in use because it has been reserved must not get deallocated.\n\nIn a cluster with multiple scheduler instances, two pods might get scheduled concurrently by different schedulers. When they reference the same ResourceClaim which already has reached its maximum number of consumers, only one pod can be scheduled.\n\nBoth schedulers try to add their pod to the claim.status.reservedFor field, but only the update that reaches the API server first gets stored. The other one fails with an error and the scheduler which issued it knows that it must put the pod back into the queue, waiting for the ResourceClaim to become usable again.\n\nThere can be at most 32 such reservations. This may get increased in the future, but not reduced.", + "description": "ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started. A claim that is in use or might be in use because it has been reserved must not get deallocated.\n\nIn a cluster with multiple scheduler instances, two pods might get scheduled concurrently by different schedulers. When they reference the same ResourceClaim which already has reached its maximum number of consumers, only one pod can be scheduled.\n\nBoth schedulers try to add their pod to the claim.status.reservedFor field, but only the update that reaches the API server first gets stored. The other one fails with an error and the scheduler which issued it knows that it must put the pod back into the queue, waiting for the ResourceClaim to become usable again.\n\nThere can be at most 256 such reservations. This may get increased in the future, but not reduced.", "items": { "$ref": "#/definitions/v1beta1.ResourceClaimConsumerReference" }, From d615a834cd68e4bc969ae8eac1f988167d44e134 Mon Sep 17 00:00:00 2001 From: yliao Date: Mon, 13 Jan 2025 20:30:58 +0000 Subject: [PATCH 04/30] generated client change --- kubernetes/.openapi-generator/swagger.json.sha256 | 2 +- kubernetes/README.md | 2 +- kubernetes/__init__.py | 2 +- kubernetes/client/__init__.py | 2 +- kubernetes/client/api_client.py | 2 +- kubernetes/client/configuration.py | 2 +- setup.py | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/kubernetes/.openapi-generator/swagger.json.sha256 b/kubernetes/.openapi-generator/swagger.json.sha256 index 9d3273afe1..343524c1e5 100644 --- a/kubernetes/.openapi-generator/swagger.json.sha256 +++ b/kubernetes/.openapi-generator/swagger.json.sha256 @@ -1 +1 @@ -5f773c685cb5e7b97c1b3be4a7cff387a8077a4789c738dac715ba91b1c50eda \ No newline at end of file +b20f45563c8a98d4f6f0ccc8fea807c5a646510c40aee9183d87b0be22104194 \ No newline at end of file diff --git a/kubernetes/README.md b/kubernetes/README.md index 2886ef83a9..af06c24cf4 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -4,7 +4,7 @@ No description provided (generated by Openapi Generator https://github.com/opena This Python package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: - API version: release-1.32 -- Package version: 32.0.0+snapshot +- Package version: 32.0.0a1 - Build package: org.openapitools.codegen.languages.PythonClientCodegen ## Requirements. diff --git a/kubernetes/__init__.py b/kubernetes/__init__.py index e46fe7c902..5f1bb54d71 100644 --- a/kubernetes/__init__.py +++ b/kubernetes/__init__.py @@ -14,7 +14,7 @@ __project__ = 'kubernetes' # The version is auto-updated. Please do not edit. -__version__ = "32.0.0+snapshot" +__version__ = "32.0.0a1" from . import client from . import config diff --git a/kubernetes/client/__init__.py b/kubernetes/client/__init__.py index e46821316b..3f5250a5fa 100644 --- a/kubernetes/client/__init__.py +++ b/kubernetes/client/__init__.py @@ -14,7 +14,7 @@ from __future__ import absolute_import -__version__ = "32.0.0+snapshot" +__version__ = "32.0.0a1" # import apis into sdk package from kubernetes.client.api.well_known_api import WellKnownApi diff --git a/kubernetes/client/api_client.py b/kubernetes/client/api_client.py index 53d94ce40b..c9ed6c2136 100644 --- a/kubernetes/client/api_client.py +++ b/kubernetes/client/api_client.py @@ -78,7 +78,7 @@ def __init__(self, configuration=None, header_name=None, header_value=None, self.default_headers[header_name] = header_value self.cookie = cookie # Set default User-Agent. - self.user_agent = 'OpenAPI-Generator/32.0.0+snapshot/python' + self.user_agent = 'OpenAPI-Generator/32.0.0a1/python' self.client_side_validation = configuration.client_side_validation def __enter__(self): diff --git a/kubernetes/client/configuration.py b/kubernetes/client/configuration.py index e1c0ff2dc5..f29025affa 100644 --- a/kubernetes/client/configuration.py +++ b/kubernetes/client/configuration.py @@ -354,7 +354,7 @@ def to_debug_report(self): "OS: {env}\n"\ "Python Version: {pyversion}\n"\ "Version of the API: release-1.32\n"\ - "SDK Package Version: 32.0.0+snapshot".\ + "SDK Package Version: 32.0.0a1".\ format(env=sys.platform, pyversion=sys.version) def get_host_settings(self): diff --git a/setup.py b/setup.py index 44a353a20f..5d29758ec8 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ # Do not edit these constants. They will be updated automatically # by scripts/update-client.sh. -CLIENT_VERSION = "32.0.0+snapshot" +CLIENT_VERSION = "32.0.0a1" PACKAGE_NAME = "kubernetes" DEVELOPMENT_STATUS = "3 - Alpha" From 8b6125c4eeb10f108bdbc3dea54ca00e6a0b708e Mon Sep 17 00:00:00 2001 From: yliao Date: Mon, 13 Jan 2025 20:34:07 +0000 Subject: [PATCH 05/30] updated compatibility matrix and maintenance status. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 6fb1b4a03b..2b3dc63ed4 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,7 @@ supported versions of Kubernetes clusters. - [client 29.y.z](https://pypi.org/project/kubernetes/29.0.0/): Kubernetes 1.28 or below (+-), Kubernetes 1.29 (✓), Kubernetes 1.30 or above (+-) - [client 30.y.z](https://pypi.org/project/kubernetes/30.1.0/): Kubernetes 1.29 or below (+-), Kubernetes 1.30 (✓), Kubernetes 1.31 or above (+-) - [client 31.y.z](https://pypi.org/project/kubernetes/31.0.0/): Kubernetes 1.30 or below (+-), Kubernetes 1.31 (✓), Kubernetes 1.32 or above (+-) +- [client 32.y.z](https://pypi.org/project/kubernetes/32.0.0a1/): Kubernetes 1.31 or below (+-), Kubernetes 1.32 (✓), Kubernetes 1.33 or above (+-) > See [here](#homogenizing-the-kubernetes-python-client-versions) for an explanation of why there is no v13-v16 release. @@ -168,6 +169,7 @@ between client-python versions. | 30.0 | Kubernetes main repo, 1.30 branch | ✓ | | 31.0 Alpha/Beta | Kubernetes main repo, 1.31 branch | ✗ | | 31.0 | Kubernetes main repo, 1.31 branch | ✓ | +| 32.0 Alpha/Beta | Kubernetes main repo, 1.32 branch | ✓ | > See [here](#homogenizing-the-kubernetes-python-client-versions) for an explanation of why there is no v13-v16 release. From ac25d7ccda99d890978d91210c3f04c6abea4f28 Mon Sep 17 00:00:00 2001 From: yliao Date: Mon, 13 Jan 2025 22:38:43 +0000 Subject: [PATCH 06/30] replaced python 3.7 version, it is no longer supported by ubuntu 24.04. The version '3.7' with architecture 'x64' was not found for Ubuntu 24.04. The list of all available versions can be found here: https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json fix --- .github/workflows/e2e-master.yaml | 2 +- .github/workflows/test.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e-master.yaml b/.github/workflows/e2e-master.yaml index 35927c2547..e318d161e5 100644 --- a/.github/workflows/e2e-master.yaml +++ b/.github/workflows/e2e-master.yaml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.7, 3.8, 3.9] + python-version: ["3.8", "3.9", "3.10"] steps: - uses: actions/checkout@v4 with: diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index dca23462f5..79059f246b 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.7", "3.8", "3.10", "3.11"] + python-version: ["3.8", "3.10", "3.11", "3.12"] include: - python-version: "3.9" use_coverage: 'coverage' From 1103634eaa69cf596c6951083287bdff80e5fc42 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Dec 2024 03:32:15 +0000 Subject: [PATCH 07/30] Bump helm/kind-action from 1.11.0 to 1.12.0 Bumps [helm/kind-action](https://github.com/helm/kind-action) from 1.11.0 to 1.12.0. - [Release notes](https://github.com/helm/kind-action/releases) - [Commits](https://github.com/helm/kind-action/compare/v1.11.0...v1.12.0) --- updated-dependencies: - dependency-name: helm/kind-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/e2e-master.yaml | 2 +- .github/workflows/e2e-release-11.0.yaml | 2 +- .github/workflows/e2e-release-12.0.yaml | 2 +- .github/workflows/e2e-release-17.0.yaml | 2 +- .github/workflows/e2e-release-18.0.yaml | 2 +- .github/workflows/e2e-release-26.0.yaml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/e2e-master.yaml b/.github/workflows/e2e-master.yaml index e318d161e5..43d27864b6 100644 --- a/.github/workflows/e2e-master.yaml +++ b/.github/workflows/e2e-master.yaml @@ -19,7 +19,7 @@ jobs: with: submodules: true - name: Create Kind Cluster - uses: helm/kind-action@v1.11.0 + uses: helm/kind-action@v1.12.0 with: cluster_name: kubernetes-python-e2e-master-${{ matrix.python-version }} # The kind version to be used to spin the cluster up diff --git a/.github/workflows/e2e-release-11.0.yaml b/.github/workflows/e2e-release-11.0.yaml index 4938c55513..fe83d2713a 100644 --- a/.github/workflows/e2e-release-11.0.yaml +++ b/.github/workflows/e2e-release-11.0.yaml @@ -19,7 +19,7 @@ jobs: with: submodules: true - name: Create Kind Cluster - uses: helm/kind-action@v1.11.0 + uses: helm/kind-action@v1.12.0 with: cluster_name: kubernetes-python-e2e-release-11.0-${{ matrix.python-version }} # The kind version to be used to spin the cluster up diff --git a/.github/workflows/e2e-release-12.0.yaml b/.github/workflows/e2e-release-12.0.yaml index d951cbb0ad..576a5f3f5f 100644 --- a/.github/workflows/e2e-release-12.0.yaml +++ b/.github/workflows/e2e-release-12.0.yaml @@ -19,7 +19,7 @@ jobs: with: submodules: true - name: Create Kind Cluster - uses: helm/kind-action@v1.11.0 + uses: helm/kind-action@v1.12.0 with: cluster_name: kubernetes-python-e2e-release-12.0-${{ matrix.python-version }} # The kind version to be used to spin the cluster up diff --git a/.github/workflows/e2e-release-17.0.yaml b/.github/workflows/e2e-release-17.0.yaml index 434667e9ca..bd13b3c4df 100644 --- a/.github/workflows/e2e-release-17.0.yaml +++ b/.github/workflows/e2e-release-17.0.yaml @@ -19,7 +19,7 @@ jobs: with: submodules: true - name: Create Kind Cluster - uses: helm/kind-action@v1.11.0 + uses: helm/kind-action@v1.12.0 with: cluster_name: kubernetes-python-e2e-release-17.0-${{ matrix.python-version }} # The kind version to be used to spin the cluster up diff --git a/.github/workflows/e2e-release-18.0.yaml b/.github/workflows/e2e-release-18.0.yaml index 4fc692b1ff..e7a4d4065d 100644 --- a/.github/workflows/e2e-release-18.0.yaml +++ b/.github/workflows/e2e-release-18.0.yaml @@ -19,7 +19,7 @@ jobs: with: submodules: true - name: Create Kind Cluster - uses: helm/kind-action@v1.11.0 + uses: helm/kind-action@v1.12.0 with: cluster_name: kubernetes-python-e2e-release-18.0-${{ matrix.python-version }} # The kind version to be used to spin the cluster up diff --git a/.github/workflows/e2e-release-26.0.yaml b/.github/workflows/e2e-release-26.0.yaml index 3d9b273a24..e41d54e233 100644 --- a/.github/workflows/e2e-release-26.0.yaml +++ b/.github/workflows/e2e-release-26.0.yaml @@ -19,7 +19,7 @@ jobs: with: submodules: true - name: Create Kind Cluster - uses: helm/kind-action@v1.11.0 + uses: helm/kind-action@v1.12.0 with: cluster_name: kubernetes-python-e2e-release-26.0-${{ matrix.python-version }} # The kind version to be used to spin the cluster up From ccb2f88b8825cb8d99a9817b8804c2b152fbc783 Mon Sep 17 00:00:00 2001 From: yliao Date: Thu, 16 Jan 2025 22:07:22 +0000 Subject: [PATCH 08/30] update version constants for 32.0.0b1 release --- scripts/constants.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/constants.py b/scripts/constants.py index 7e9db65bd8..e52e3fab1a 100644 --- a/scripts/constants.py +++ b/scripts/constants.py @@ -18,13 +18,13 @@ KUBERNETES_BRANCH = "release-1.32" # client version for packaging and releasing. -CLIENT_VERSION = "32.0.0a1" +CLIENT_VERSION = "32.0.0b1" # Name of the release package PACKAGE_NAME = "kubernetes" # Stage of development, mainly used in setup.py's classifiers. -DEVELOPMENT_STATUS = "3 - Alpha" +DEVELOPMENT_STATUS = "4 - Beta" # If called directly, return the constant value given From 43b6175463ddbc3aebd214a4162f0f4bcd0115f3 Mon Sep 17 00:00:00 2001 From: yliao Date: Thu, 16 Jan 2025 22:07:23 +0000 Subject: [PATCH 09/30] update changelog --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f750e89057..74d60d176d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# v32.0.0b1 + +Kubernetes API Version: v1.32.1 + +### API Change +- DRA API: the maximum number of pods which can use the same ResourceClaim is now 256 instead of 32. Beware that downgrading a cluster where this relaxed limit is in use to Kubernetes 1.32.0 is not supported because 1.32.0 would refuse to update ResourceClaims with more than 32 entries in the status.reservedFor field. ([kubernetes/kubernetes#129544](https://github.com/kubernetes/kubernetes/pull/129544), [@pohly](https://github.com/pohly)) [SIG API Machinery, Node and Testing] +- NONE ([kubernetes/kubernetes#129598](https://github.com/kubernetes/kubernetes/pull/129598), [@aravindhp](https://github.com/aravindhp)) [SIG API Machinery and Node] + + # v32.0.0a1 Kubernetes API Version: v1.32.0 From b42b60c688955744bd79856b7e394255a282791f Mon Sep 17 00:00:00 2001 From: yliao Date: Thu, 16 Jan 2025 22:07:56 +0000 Subject: [PATCH 10/30] generated client change --- kubernetes/README.md | 2 +- kubernetes/__init__.py | 2 +- kubernetes/client/__init__.py | 2 +- kubernetes/client/api_client.py | 2 +- kubernetes/client/configuration.py | 2 +- setup.py | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/kubernetes/README.md b/kubernetes/README.md index af06c24cf4..1ba588bb5d 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -4,7 +4,7 @@ No description provided (generated by Openapi Generator https://github.com/opena This Python package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: - API version: release-1.32 -- Package version: 32.0.0a1 +- Package version: 32.0.0b1 - Build package: org.openapitools.codegen.languages.PythonClientCodegen ## Requirements. diff --git a/kubernetes/__init__.py b/kubernetes/__init__.py index 5f1bb54d71..cba8dbd665 100644 --- a/kubernetes/__init__.py +++ b/kubernetes/__init__.py @@ -14,7 +14,7 @@ __project__ = 'kubernetes' # The version is auto-updated. Please do not edit. -__version__ = "32.0.0a1" +__version__ = "32.0.0b1" from . import client from . import config diff --git a/kubernetes/client/__init__.py b/kubernetes/client/__init__.py index 3f5250a5fa..7277dc8f99 100644 --- a/kubernetes/client/__init__.py +++ b/kubernetes/client/__init__.py @@ -14,7 +14,7 @@ from __future__ import absolute_import -__version__ = "32.0.0a1" +__version__ = "32.0.0b1" # import apis into sdk package from kubernetes.client.api.well_known_api import WellKnownApi diff --git a/kubernetes/client/api_client.py b/kubernetes/client/api_client.py index c9ed6c2136..b0abd35881 100644 --- a/kubernetes/client/api_client.py +++ b/kubernetes/client/api_client.py @@ -78,7 +78,7 @@ def __init__(self, configuration=None, header_name=None, header_value=None, self.default_headers[header_name] = header_value self.cookie = cookie # Set default User-Agent. - self.user_agent = 'OpenAPI-Generator/32.0.0a1/python' + self.user_agent = 'OpenAPI-Generator/32.0.0b1/python' self.client_side_validation = configuration.client_side_validation def __enter__(self): diff --git a/kubernetes/client/configuration.py b/kubernetes/client/configuration.py index f29025affa..b9fbddcbf2 100644 --- a/kubernetes/client/configuration.py +++ b/kubernetes/client/configuration.py @@ -354,7 +354,7 @@ def to_debug_report(self): "OS: {env}\n"\ "Python Version: {pyversion}\n"\ "Version of the API: release-1.32\n"\ - "SDK Package Version: 32.0.0a1".\ + "SDK Package Version: 32.0.0b1".\ format(env=sys.platform, pyversion=sys.version) def get_host_settings(self): diff --git a/setup.py b/setup.py index 5d29758ec8..d6cd8c5019 100644 --- a/setup.py +++ b/setup.py @@ -16,9 +16,9 @@ # Do not edit these constants. They will be updated automatically # by scripts/update-client.sh. -CLIENT_VERSION = "32.0.0a1" +CLIENT_VERSION = "32.0.0b1" PACKAGE_NAME = "kubernetes" -DEVELOPMENT_STATUS = "3 - Alpha" +DEVELOPMENT_STATUS = "4 - Beta" # To install the library, run the following # From fc8b2b65028a640f68b850b0254cc8b5d2cd6092 Mon Sep 17 00:00:00 2001 From: yliao Date: Thu, 16 Jan 2025 22:12:07 +0000 Subject: [PATCH 11/30] updated compatibility matrix and maintenance status --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2b3dc63ed4..29812669f5 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ supported versions of Kubernetes clusters. - [client 29.y.z](https://pypi.org/project/kubernetes/29.0.0/): Kubernetes 1.28 or below (+-), Kubernetes 1.29 (✓), Kubernetes 1.30 or above (+-) - [client 30.y.z](https://pypi.org/project/kubernetes/30.1.0/): Kubernetes 1.29 or below (+-), Kubernetes 1.30 (✓), Kubernetes 1.31 or above (+-) - [client 31.y.z](https://pypi.org/project/kubernetes/31.0.0/): Kubernetes 1.30 or below (+-), Kubernetes 1.31 (✓), Kubernetes 1.32 or above (+-) -- [client 32.y.z](https://pypi.org/project/kubernetes/32.0.0a1/): Kubernetes 1.31 or below (+-), Kubernetes 1.32 (✓), Kubernetes 1.33 or above (+-) +- [client 32.y.z](https://pypi.org/project/kubernetes/32.0.0b1/): Kubernetes 1.31 or below (+-), Kubernetes 1.32 (✓), Kubernetes 1.33 or above (+-) > See [here](#homogenizing-the-kubernetes-python-client-versions) for an explanation of why there is no v13-v16 release. From 2af3cf360dc0a9d44f008bed297da4d0e7dd1c00 Mon Sep 17 00:00:00 2001 From: Pete Date: Mon, 6 Jan 2025 08:17:09 +0000 Subject: [PATCH 12/30] Close the Python sockets when the Websocket closes This allows the client to detect when the connection has been interrupted --- kubernetes/base/stream/ws_client.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/kubernetes/base/stream/ws_client.py b/kubernetes/base/stream/ws_client.py index 3c854ea741..10c6c1bcd5 100644 --- a/kubernetes/base/stream/ws_client.py +++ b/kubernetes/base/stream/ws_client.py @@ -30,7 +30,7 @@ from six.moves.urllib.parse import urlencode, urlparse, urlunparse from six import StringIO, BytesIO -from websocket import WebSocket, ABNF, enableTrace +from websocket import WebSocket, ABNF, enableTrace, WebSocketConnectionClosedException from base64 import urlsafe_b64decode from requests.utils import should_bypass_proxies @@ -379,7 +379,12 @@ def _proxy(self): if sock == self.websocket: pending = True while pending: - opcode, frame = self.websocket.recv_data_frame(True) + try: + opcode, frame = self.websocket.recv_data_frame(True) + except WebSocketConnectionClosedException: + for port in self.local_ports.values(): + port.python.close() + return if opcode == ABNF.OPCODE_BINARY: if not frame.data: raise RuntimeError("Unexpected frame data size") From 0d9f4f87fc9519c73de960dd8591e990c944d956 Mon Sep 17 00:00:00 2001 From: yliao Date: Thu, 23 Jan 2025 19:12:47 +0000 Subject: [PATCH 13/30] update changelog with release notes from master branch --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74d60d176d..97d8be5f7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# v32.0.0 + +Kubernetes API Version: v1.32.1 + +### Bug or Regression +- Fixed PortForward proxy to close local Python sockets when the WebSocket closes. (#2316, @anvilpete) + # v32.0.0b1 Kubernetes API Version: v1.32.1 From dbedb4d9207b6a73515d2c732b38b8e6d991a21a Mon Sep 17 00:00:00 2001 From: yliao Date: Thu, 23 Jan 2025 19:12:47 +0000 Subject: [PATCH 14/30] update version constants for 32.0.0 release --- scripts/constants.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/constants.py b/scripts/constants.py index e52e3fab1a..e9a768c365 100644 --- a/scripts/constants.py +++ b/scripts/constants.py @@ -18,13 +18,13 @@ KUBERNETES_BRANCH = "release-1.32" # client version for packaging and releasing. -CLIENT_VERSION = "32.0.0b1" +CLIENT_VERSION = "32.0.0" # Name of the release package PACKAGE_NAME = "kubernetes" # Stage of development, mainly used in setup.py's classifiers. -DEVELOPMENT_STATUS = "4 - Beta" +DEVELOPMENT_STATUS = "5 - Production/Stable" # If called directly, return the constant value given From b9091e3f8426436c0285ef3035ea8d2828f49cb0 Mon Sep 17 00:00:00 2001 From: yliao Date: Thu, 23 Jan 2025 19:13:25 +0000 Subject: [PATCH 15/30] generated client change --- kubernetes/README.md | 2 +- kubernetes/__init__.py | 2 +- kubernetes/client/__init__.py | 2 +- kubernetes/client/api_client.py | 2 +- kubernetes/client/configuration.py | 2 +- setup.py | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/kubernetes/README.md b/kubernetes/README.md index 1ba588bb5d..7e31c7aa28 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -4,7 +4,7 @@ No description provided (generated by Openapi Generator https://github.com/opena This Python package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: - API version: release-1.32 -- Package version: 32.0.0b1 +- Package version: 32.0.0 - Build package: org.openapitools.codegen.languages.PythonClientCodegen ## Requirements. diff --git a/kubernetes/__init__.py b/kubernetes/__init__.py index cba8dbd665..5ea666bf69 100644 --- a/kubernetes/__init__.py +++ b/kubernetes/__init__.py @@ -14,7 +14,7 @@ __project__ = 'kubernetes' # The version is auto-updated. Please do not edit. -__version__ = "32.0.0b1" +__version__ = "32.0.0" from . import client from . import config diff --git a/kubernetes/client/__init__.py b/kubernetes/client/__init__.py index 7277dc8f99..7368d6a4ee 100644 --- a/kubernetes/client/__init__.py +++ b/kubernetes/client/__init__.py @@ -14,7 +14,7 @@ from __future__ import absolute_import -__version__ = "32.0.0b1" +__version__ = "32.0.0" # import apis into sdk package from kubernetes.client.api.well_known_api import WellKnownApi diff --git a/kubernetes/client/api_client.py b/kubernetes/client/api_client.py index b0abd35881..3e21219d7e 100644 --- a/kubernetes/client/api_client.py +++ b/kubernetes/client/api_client.py @@ -78,7 +78,7 @@ def __init__(self, configuration=None, header_name=None, header_value=None, self.default_headers[header_name] = header_value self.cookie = cookie # Set default User-Agent. - self.user_agent = 'OpenAPI-Generator/32.0.0b1/python' + self.user_agent = 'OpenAPI-Generator/32.0.0/python' self.client_side_validation = configuration.client_side_validation def __enter__(self): diff --git a/kubernetes/client/configuration.py b/kubernetes/client/configuration.py index b9fbddcbf2..1a234595c3 100644 --- a/kubernetes/client/configuration.py +++ b/kubernetes/client/configuration.py @@ -354,7 +354,7 @@ def to_debug_report(self): "OS: {env}\n"\ "Python Version: {pyversion}\n"\ "Version of the API: release-1.32\n"\ - "SDK Package Version: 32.0.0b1".\ + "SDK Package Version: 32.0.0".\ format(env=sys.platform, pyversion=sys.version) def get_host_settings(self): diff --git a/setup.py b/setup.py index d6cd8c5019..01e26edf87 100644 --- a/setup.py +++ b/setup.py @@ -16,9 +16,9 @@ # Do not edit these constants. They will be updated automatically # by scripts/update-client.sh. -CLIENT_VERSION = "32.0.0b1" +CLIENT_VERSION = "32.0.0" PACKAGE_NAME = "kubernetes" -DEVELOPMENT_STATUS = "4 - Beta" +DEVELOPMENT_STATUS = "5 - Production/Stable" # To install the library, run the following # From 8db4744ce483f9a715edcc3e7bc7c616846f4ee9 Mon Sep 17 00:00:00 2001 From: yliao Date: Thu, 23 Jan 2025 19:17:00 +0000 Subject: [PATCH 16/30] updated compatibility matrix and maintenance status --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 29812669f5..7f148915e1 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ supported versions of Kubernetes clusters. - [client 29.y.z](https://pypi.org/project/kubernetes/29.0.0/): Kubernetes 1.28 or below (+-), Kubernetes 1.29 (✓), Kubernetes 1.30 or above (+-) - [client 30.y.z](https://pypi.org/project/kubernetes/30.1.0/): Kubernetes 1.29 or below (+-), Kubernetes 1.30 (✓), Kubernetes 1.31 or above (+-) - [client 31.y.z](https://pypi.org/project/kubernetes/31.0.0/): Kubernetes 1.30 or below (+-), Kubernetes 1.31 (✓), Kubernetes 1.32 or above (+-) -- [client 32.y.z](https://pypi.org/project/kubernetes/32.0.0b1/): Kubernetes 1.31 or below (+-), Kubernetes 1.32 (✓), Kubernetes 1.33 or above (+-) +- [client 32.y.z](https://pypi.org/project/kubernetes/32.0.0/): Kubernetes 1.31 or below (+-), Kubernetes 1.32 (✓), Kubernetes 1.33 or above (+-) > See [here](#homogenizing-the-kubernetes-python-client-versions) for an explanation of why there is no v13-v16 release. @@ -164,12 +164,13 @@ between client-python versions. | 28.0 Alpha/Beta | Kubernetes main repo, 1.28 branch | ✗ | | 28.0 | Kubernetes main repo, 1.28 branch | ✗ | | 29.0 Alpha/Beta | Kubernetes main repo, 1.29 branch | ✗ | -| 29.0 | Kubernetes main repo, 1.29 branch | ✓ | +| 29.0 | Kubernetes main repo, 1.29 branch | ✗ | | 30.0 Alpha/Beta | Kubernetes main repo, 1.30 branch | ✗ | | 30.0 | Kubernetes main repo, 1.30 branch | ✓ | | 31.0 Alpha/Beta | Kubernetes main repo, 1.31 branch | ✗ | | 31.0 | Kubernetes main repo, 1.31 branch | ✓ | -| 32.0 Alpha/Beta | Kubernetes main repo, 1.32 branch | ✓ | +| 32.0 Alpha/Beta | Kubernetes main repo, 1.32 branch | ✗ | +| 32.0 | Kubernetes main repo, 1.32 branch | ✓ | > See [here](#homogenizing-the-kubernetes-python-client-versions) for an explanation of why there is no v13-v16 release. From ff49ce9a32decb781e04112b7b41f55b1c55125d Mon Sep 17 00:00:00 2001 From: Rene Kschamer <26967205+rkschamer@users.noreply.github.com> Date: Thu, 4 Apr 2024 17:27:23 +0200 Subject: [PATCH 17/30] Adding utils.format_quantity --- kubernetes/utils/quantity.py | 78 ++++++++++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 7 deletions(-) diff --git a/kubernetes/utils/quantity.py b/kubernetes/utils/quantity.py index 68e57d9807..e6042a4fa7 100644 --- a/kubernetes/utils/quantity.py +++ b/kubernetes/utils/quantity.py @@ -13,6 +13,19 @@ # limitations under the License. from decimal import Decimal, InvalidOperation +_EXPONENTS = { + "n": -3, + "u": -2, + "m": -1, + "K": 1, + "k": 1, + "M": 2, + "G": 3, + "T": 4, + "P": 5, + "E": 6, +} + def parse_quantity(quantity): """ @@ -35,17 +48,14 @@ def parse_quantity(quantity): if isinstance(quantity, (int, float, Decimal)): return Decimal(quantity) - exponents = {"n": -3, "u": -2, "m": -1, "K": 1, "k": 1, "M": 2, - "G": 3, "T": 4, "P": 5, "E": 6} - quantity = str(quantity) number = quantity suffix = None if len(quantity) >= 2 and quantity[-1] == "i": - if quantity[-2] in exponents: + if quantity[-2] in _EXPONENTS: number = quantity[:-2] suffix = quantity[-2:] - elif len(quantity) >= 1 and quantity[-1] in exponents: + elif len(quantity) >= 1 and quantity[-1] in _EXPONENTS: number = quantity[:-1] suffix = quantity[-1:] @@ -68,8 +78,62 @@ def parse_quantity(quantity): if suffix == "ki": raise ValueError("{} has unknown suffix".format(quantity)) - if suffix[0] not in exponents: + if suffix[0] not in _EXPONENTS: raise ValueError("{} has unknown suffix".format(quantity)) - exponent = Decimal(exponents[suffix[0]]) + exponent = Decimal(_EXPONENTS[suffix[0]]) return number * (base ** exponent) + + +def format_quantity(quantity_value, suffix, quantize=None) -> str: + """ + Takes a decimal and produces a string value in kubernetes' canonical quantity form, + like "200Mi".Users can specify an additional decimal number to quantize the output. + + Example - Relatively increase pod memory limits: + + # retrieve my_pod + current_memory: Decimal = parse_quantity(my_pod.spec.containers[0].resources.limits.memory) + desired_memory = current_memory * 1.2 + desired_memory_str = format_quantity(desired_memory, suffix="Gi", quantize=Decimal(1)) + # patch pod with desired_memory_str + + 'quantize=Decimal(1)' ensures that the result does not contain any fractional digits. + + Supported SI suffixes: + base1024: Ki | Mi | Gi | Ti | Pi | Ei + base1000: n | u | m | "" | k | M | G | T | P | E + + See https://github.com/kubernetes/apimachinery/blob/master/pkg/api/resource/quantity.go + + Input: + quantity: Decimal. Quantity as a number which is supposed to converted to a string + with SI suffix. + suffix: string. The desired suffix/unit-of-measure of the output string + quantize: Decimal. Can be used to round/quantize the value before the string + is returned. Defaults to None. + + Returns: + string. Canonical Kubernetes quantity string containing the SI suffix. + + Raises: + ValueError if the SI suffix is not supported. + """ + + if suffix.endswith("i"): + base = 1024 + elif len(suffix) == 1: + base = 1000 + else: + raise ValueError(f"{quantity_value} has unknown suffix") + + if suffix == "ki": + raise ValueError(f"{quantity_value} has unknown suffix") + + if suffix[0] not in _EXPONENTS: + raise ValueError(f"{quantity_value} has unknown suffix") + + different_scale = quantity_value / Decimal(base ** _EXPONENTS[suffix[0]]) + if quantize: + different_scale = different_scale.quantize(quantize) + return str(different_scale) + suffix From 0ea3c06a7a12f4ce303a6e6c9ad02c4460ca5385 Mon Sep 17 00:00:00 2001 From: Rene Kschamer <26967205+rkschamer@users.noreply.github.com> Date: Fri, 5 Apr 2024 14:14:00 +0200 Subject: [PATCH 18/30] adding format_quantity tests --- kubernetes/e2e_test/test_utils.py | 71 ++++++++++++++++++++++++++++++- kubernetes/utils/quantity.py | 3 ++ 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/kubernetes/e2e_test/test_utils.py b/kubernetes/e2e_test/test_utils.py index 6579423c8b..bea3bfbb7f 100644 --- a/kubernetes/e2e_test/test_utils.py +++ b/kubernetes/e2e_test/test_utils.py @@ -13,13 +13,15 @@ # under the License. import unittest +from decimal import Decimal from os import path import yaml -from kubernetes import utils, client +from kubernetes import client, utils from kubernetes.client.rest import ApiException from kubernetes.e2e_test import base +from kubernetes.utils import quantity class TestUtils(unittest.TestCase): @@ -605,3 +607,70 @@ def test_create_from_list_in_multi_resource_yaml_namespaced(self): name="mock-pod-1", namespace=self.test_namespace, body={}) app_api.delete_namespaced_deployment( name="mock", namespace=self.test_namespace, body={}) + + +class TestUtilsUnitTests(unittest.TestCase): + + def test_format_quantity(self): + """Unit test for quantity.format_quantity. Testing the different SI suffixes and + function should return the expected string""" + + # == unknown suffixes == + self.assertRaises( + ValueError, lambda: quantity.format_quantity(Decimal(1_000), "kb") + ) + self.assertRaises( + ValueError, lambda: quantity.format_quantity(Decimal(1_000), "ki") + ) + self.assertRaises( + ValueError, lambda: quantity.format_quantity(Decimal(1_000), "foo") + ) + + # == no suffix == + self.assertEqual(quantity.format_quantity(Decimal(1_000), ""), "1000") + self.assertEqual(quantity.format_quantity(Decimal(1_000), None), "1000") + + # == base 1024 == + self.assertEqual(quantity.format_quantity(Decimal(1024), "Ki"), "1Ki") + self.assertEqual(quantity.format_quantity(Decimal(1024**2), "Mi"), "1Mi") + self.assertEqual(quantity.format_quantity(Decimal(1024**3), "Gi"), "1Gi") + self.assertEqual(quantity.format_quantity(Decimal(1024**4), "Ti"), "1Ti") + self.assertEqual(quantity.format_quantity(Decimal(1024**5), "Pi"), "1Pi") + self.assertEqual(quantity.format_quantity(Decimal(1024**6), "Ei"), "1Ei") + self.assertEqual(quantity.format_quantity(Decimal(1024**2), "Ki"), "1024Ki") + self.assertEqual(quantity.format_quantity(Decimal((1024**3) / 2), "Gi"), "0.5Gi") + # Decimal((1024**3)/3) are 0.3333333333333333148296162562Gi; expecting to + # be quantized to 0.3Gi + self.assertEqual( + quantity.format_quantity( + Decimal( + (1024**3) / 3), + "Gi", + quantize=Decimal(.5)), + "0.3Gi") + + # == base 1000 == + self.assertEqual(quantity.format_quantity(Decimal(0.000_000_001), "n"), "1n") + self.assertEqual(quantity.format_quantity(Decimal(0.000_001), "u"), "1u") + self.assertEqual(quantity.format_quantity(Decimal(0.001), "m"), "1m") + self.assertEqual(quantity.format_quantity(Decimal(1_000), "k"), "1k") + self.assertEqual(quantity.format_quantity(Decimal(1_000_000), "M"), "1M") + self.assertEqual(quantity.format_quantity(Decimal(1_000_000_000), "G"), "1G") + self.assertEqual( + quantity.format_quantity(Decimal(1_000_000_000_000), "T"), "1T" + ) + self.assertEqual( + quantity.format_quantity(Decimal(1_000_000_000_000_000), "P"), "1P" + ) + self.assertEqual( + quantity.format_quantity(Decimal(1_000_000_000_000_000_000), "E"), "1E" + ) + self.assertEqual(quantity.format_quantity(Decimal(1_000_000), "k"), "1000k") + # Decimal(1_000_000/3) are 333.3333333333333139307796955k; expecting to + # be quantized to 333k + self.assertEqual( + quantity.format_quantity( + Decimal(1_000_000 / 3), "k", quantize=Decimal(1000) + ), + "333k", + ) diff --git a/kubernetes/utils/quantity.py b/kubernetes/utils/quantity.py index e6042a4fa7..484f347193 100644 --- a/kubernetes/utils/quantity.py +++ b/kubernetes/utils/quantity.py @@ -120,6 +120,9 @@ def format_quantity(quantity_value, suffix, quantize=None) -> str: ValueError if the SI suffix is not supported. """ + if not suffix: + return str(quantity_value) + if suffix.endswith("i"): base = 1024 elif len(suffix) == 1: From e06dc4158e2a275ba18113ae4aa926b3498fcc26 Mon Sep 17 00:00:00 2001 From: Rene Kschamer <26967205+rkschamer@users.noreply.github.com> Date: Fri, 5 Apr 2024 14:44:05 +0200 Subject: [PATCH 19/30] add test_parse_quantity --- kubernetes/e2e_test/test_utils.py | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/kubernetes/e2e_test/test_utils.py b/kubernetes/e2e_test/test_utils.py index bea3bfbb7f..646081b8c7 100644 --- a/kubernetes/e2e_test/test_utils.py +++ b/kubernetes/e2e_test/test_utils.py @@ -611,6 +611,49 @@ def test_create_from_list_in_multi_resource_yaml_namespaced(self): class TestUtilsUnitTests(unittest.TestCase): + def test_parse_quantity(self): + # == trivial returns == + self.assertEqual(quantity.parse_quantity(Decimal(1)), Decimal(1)) + self.assertEqual(quantity.parse_quantity(float(1)), Decimal(1)) + self.assertEqual(quantity.parse_quantity(1), Decimal(1)) + + # == exceptions == + self.assertRaises( + ValueError, lambda: quantity.parse_quantity("1000kb") + ) + self.assertRaises( + ValueError, lambda: quantity.parse_quantity("1000ki") + ) + self.assertRaises(ValueError, lambda: quantity.parse_quantity("1000foo")) + self.assertRaises(ValueError, lambda: quantity.parse_quantity("foo")) + + # == no suffix == + self.assertEqual(quantity.parse_quantity("1000"), Decimal(1000)) + + # == base 1024 == + self.assertEqual(quantity.parse_quantity("1Ki"), Decimal(1024)) + self.assertEqual(quantity.parse_quantity("1Mi"), Decimal(1024**2)) + self.assertEqual(quantity.parse_quantity("1Gi"), Decimal(1024**3)) + self.assertEqual(quantity.parse_quantity("1Ti"), Decimal(1024**4)) + self.assertEqual(quantity.parse_quantity("1Pi"), Decimal(1024**5)) + self.assertEqual(quantity.parse_quantity("1Ei"), Decimal(1024**6)) + self.assertEqual(quantity.parse_quantity("1024Ki"), Decimal(1024**2)) + self.assertEqual(quantity.parse_quantity("0.5Ki"), Decimal(512)) + + # == base 1000 == + self.assertAlmostEqual(quantity.parse_quantity("1n"), Decimal(0.000_000_001)) + self.assertAlmostEqual(quantity.parse_quantity("1u"), Decimal(0.000_001)) + self.assertAlmostEqual(quantity.parse_quantity("1m"), Decimal(0.001)) + self.assertEqual(quantity.parse_quantity("1k"), Decimal(1_000)) + self.assertEqual(quantity.parse_quantity("1M"), Decimal(1_000_000)) + self.assertEqual(quantity.parse_quantity("1G"), Decimal(1_000_000_000)) + self.assertEqual(quantity.parse_quantity("1T"), Decimal(1_000_000_000_000)) + self.assertEqual(quantity.parse_quantity("1P"), Decimal(1_000_000_000_000_000)) + self.assertEqual( + quantity.parse_quantity("1E"), Decimal(1_000_000_000_000_000_000)) + self.assertEqual(quantity.parse_quantity("1000k"), Decimal(1_000_000)) + self.assertEqual(quantity.parse_quantity("500k"), Decimal(500_000)) + def test_format_quantity(self): """Unit test for quantity.format_quantity. Testing the different SI suffixes and function should return the expected string""" From a0d4580529c4f49ec653de65fbfd19ba2e5ba0d1 Mon Sep 17 00:00:00 2001 From: Akhil Lawrence Date: Wed, 29 Jan 2025 07:32:34 +0530 Subject: [PATCH 20/30] mark shell=False in ExecProvider for linux/darwin platforms --- kubernetes/base/config/exec_provider.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/kubernetes/base/config/exec_provider.py b/kubernetes/base/config/exec_provider.py index 317a566955..c11c2a5f45 100644 --- a/kubernetes/base/config/exec_provider.py +++ b/kubernetes/base/config/exec_provider.py @@ -58,6 +58,15 @@ def __init__(self, exec_config, cwd, cluster=None): else: self.cluster = None self.cwd = cwd or None + + @property + def shell(self): + # for windows systems `shell` should be `True` + # for other systems like linux or darwin `shell` should be `False` + # referenes: + # https://github.com/kubernetes-client/python/pull/2289 + # https://docs.python.org/3/library/sys.html#sys.platform + return sys.platform in ("win32", "cygwin") def run(self, previous_response=None): is_interactive = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty() @@ -82,7 +91,7 @@ def run(self, previous_response=None): cwd=self.cwd, env=self.env, universal_newlines=True, - shell=True) + shell=self.shell) (stdout, stderr) = process.communicate() exit_code = process.wait() if exit_code != 0: From ca32d9a66ca54f5c32d8e43214f49550551ff25e Mon Sep 17 00:00:00 2001 From: h-ema-r Date: Sat, 18 Jan 2025 21:02:26 +0545 Subject: [PATCH 21/30] Add introduction to Kubernetes patch types --- devel/patch_types.md | 315 +++++++++++++++++++++++++++++++++++++++++++ doc/patch_types.md | 315 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 630 insertions(+) create mode 100644 devel/patch_types.md create mode 100644 doc/patch_types.md diff --git a/devel/patch_types.md b/devel/patch_types.md new file mode 100644 index 0000000000..ac1395934a --- /dev/null +++ b/devel/patch_types.md @@ -0,0 +1,315 @@ +# Introduction to Kubernetes Patch Types +In Kubernetes, patches are a way to make updates or changes to resources (like Pods, ConfigMaps, Deployments, etc.) without having to replace the entire resource. Patches allow you to modify specific parts of a resource while leaving the rest unchanged. + +## Types of Kubernetes Patches + +There are several types of patches that Kubernetes supports: + +1. JSON Merge Patch (Standard JSON Patch) +2. Strategic Merge Patch +3. JSON Patch +4. Apply Patch (Server-Side Apply) + +## 1. JSON Merge Patch +- JSON Merge Patch is based on the concept of merging JSON objects. When you apply a patch, you only need to specify the changes you want to make. Kubernetes will take your partial update and merge it with the existing resource. + +- This patch type is simple and works well when you need to update fields, such as changing a value or adding a new key. + + +### Example Scenario: +Imagine you have a Kubernetes Pod resource that looks like this: + +``` +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + containers: + - name: nginx + image: nginx:1.14 + - name: redis + image: redis:5 +``` +Now, you want to change the image of the nginx container from nginx:1.14 to nginx:1.16. Instead of sending the entire resource, you can send only the part you want to change, like this: +``` +{ + "spec": { + "containers": [ + { + "name": "nginx", + "image": "nginx:1.16" + } + ] + } +} +``` + +When you send this patch to Kubernetes: + +It will replace the image of the nginx container with the new one (nginx:1.16). +It will leave the redis container unchanged, because it's not included in the patch. + +### Example Code (Python): +``` +from kubernetes import client, config + +def main(): + config.load_kube_config() + v1 = client.CoreV1Api() + + namespace = "default" + name = "mypod" + + patch = { + "spec": { + "containers": [ + { + "name": "nginx", + "image": "nginx:1.16" + } + ] + } + } + + v1.patch_namespaced_pod(name=name, namespace=namespace, body=patch, content_type="application/merge-patch+json") + +if __name__ == "__main__": + main() + +``` + +### After the JSON Merge patch + +``` +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + containers: + - name: nginx + image: nginx:1.16 # Updated image version + - name: redis + image: redis:5 # Unchanged +``` + + +## 2. Strategic Merge Patch +Strategic Merge Patch is another type of patching mechanism, mostly used in Kubernetes, that allows updates to objects in a way that is more aware of the structure and semantics of the resource being modified. It is strategic because it understands the structure of the object, rather than blindly replacing it, and applies the changes in a smart way. +- The patch itself is typically a JSON or YAML object, which contains the fields to be updated +- **Adds New Fields:** You can use it to add new fields or modify existing ones without affecting the rest of the object. +- **Handle Lists or Arrays:** When dealing with lists (e.g., arrays or dictionaries), Strategic Merge Patch handles merging and updates intelligently. + +### Example of Strategic Merge Patch: +let's suppose we have a yaml file Target Resource (Kubernetes ConfigMap): + +``` +apiVersion: v1 +kind: ConfigMap +metadata: + name: my-configmap +data: + key1: value1 + key2: value2 + list1: + - item1 + - item2 + +``` + +Strategic Merge Patch +``` +data: + key1: updated_value1 # Update key1 + key3: value3 # Add new key3 + list1: + - item1 + - item2 + - item3 # Add item3 to list1 + +``` + +Result after Strategic Merge Patch + +``` +apiVersion: v1 +kind: ConfigMap +metadata: + name: my-configmap +data: + key1: updated_value1 # key1 is updated + key2: value2 # key2 is unchanged + key3: value3 # key3 is added + list1: + - item1 + - item2 + - item3 # item3 is added to list1 + + +``` + + +## 3. JSON Patch +- JSON Patch is a standard format that specifies a way to apply updates to a JSON document. Instead of sending a new or merged version of the object, JSON Patch describes how to modify the object step-by-step. +- Operation-Based: A JSON Patch is an array of operations that describe modifications to a target JSON object. +- Ideal when you need to perform multiple, specific operations on resource fields (e.g., replacing a value, adding new fields, or deleting specific values). + +### Patch Structure: +A JSON Patch is an array of operations. Each operation is an object with: +• op: The operation type (e.g., add, remove, replace, etc.). +• path: A JSON Pointer string (defined in RFC 6901) that specifies the location in the document to apply the operation. +• value: (Optional) The new value to apply (used with operations like add, replace, or test). +• from: (Optional) Used in operations like move and copy to specify the source path. + +### Supported Operations for JSON Patch + +#### 1. **add** +- Adds a value to a specified path. +- If the path already exists, it adds the value to a list or object. + +Example: +```json +{ "op": "add", "path": "/a/b/c", "value": "foo" } +``` + +#### 2. **remove** +- Removes the value at the specified path. + +Example: +```json +{ "op": "remove", "path": "/a/b/c" } +``` + +#### 3. **replace** +- Replaces the value at the specified path. +- Functionally similar to remove followed by add. + +Example: +```json +{ "op": "replace", "path": "/a/b/c", "value": "bar" } +``` + +#### 4. **move** +- Moves a value from one path to another. + +Example: +```json +{ "op": "move", "from": "/a/b/c", "path": "/x/y/z" } +``` + +#### 5. **copy** +- Copies a value from one path to another. + +Example: +```json +{ "op": "copy", "from": "/a/b/c", "path": "/x/y/z" } +``` + +#### 6. **test** +- Tests whether a value at a specified path matches a given value. +- Used for validation in transactional updates. + +Example: +```json +{ "op": "test", "path": "/a/b/c", "value": "foo" } +``` + +--- + +#### Example: Applying a JSON Patch + +##### Target JSON Document: +```json +{ + "a": { + "b": { + "c": "foo" + } + }, + "x": { + "y": "bar" + } +} +``` + +##### JSON Patch: +```json +[ + { "op": "replace", "path": "/a/b/c", "value": "baz" }, + { "op": "add", "path": "/a/d", "value": ["new", "value"] }, + { "op": "remove", "path": "/x/y" } +] +``` + +##### Result: +```json +{ + "a": { + "b": { + "c": "baz" + }, + "d": ["new", "value"] + }, + "x": {} +} +``` + + +## 4. Apply Patch (Server-Side Apply) +Server-Side Apply is a feature in Kubernetes that allows you to declaratively update resources by specifying their desired state. It provides an intuitive and robust way to manage resources without having to manually modify every field. It tracks which fields belong to which manager, which helps prevent conflicts when multiple clients (such as different controllers or users) update the same resource. + +Key Features: +- Declarative Management: You provide the desired final state, and Kubernetes ensures the actual state matches it. +- Conflict Detection: Ensures changes from different clients don’t conflict with each other. +- Field Ownership: Kubernetes tracks which client or manager owns which fields of a resource. + +##### Example Scenario: + +You have a ConfigMap and want to update certain keys but leave others unchanged. +``` +apiVersion: v1 +kind: ConfigMap +metadata: + name: example-config + namespace: default +data: + key1: value1 + key2: value2 +``` +**Goal:** +- You want to update key2 to new_value2 and +- add a new key key3 with a value value3. +- leave key1 unchanged + +##### Apply Patch YAML(Desired State): +``` +apiVersion: v1 +kind: ConfigMap +metadata: + name: example-config + namespace: default +data: + key2: new_value2 # Update existing key + key3: value3 # Add new key + +``` + +##### Resulting ConfigMap (after apply): +``` +apiVersion: v1 +kind: ConfigMap +metadata: + name: example-config + namespace: default +data: + key1: value1 # Remains unchanged + key2: new_value2 # Updated value + key3: value3 # New key added + +``` + + + + + diff --git a/doc/patch_types.md b/doc/patch_types.md new file mode 100644 index 0000000000..ac1395934a --- /dev/null +++ b/doc/patch_types.md @@ -0,0 +1,315 @@ +# Introduction to Kubernetes Patch Types +In Kubernetes, patches are a way to make updates or changes to resources (like Pods, ConfigMaps, Deployments, etc.) without having to replace the entire resource. Patches allow you to modify specific parts of a resource while leaving the rest unchanged. + +## Types of Kubernetes Patches + +There are several types of patches that Kubernetes supports: + +1. JSON Merge Patch (Standard JSON Patch) +2. Strategic Merge Patch +3. JSON Patch +4. Apply Patch (Server-Side Apply) + +## 1. JSON Merge Patch +- JSON Merge Patch is based on the concept of merging JSON objects. When you apply a patch, you only need to specify the changes you want to make. Kubernetes will take your partial update and merge it with the existing resource. + +- This patch type is simple and works well when you need to update fields, such as changing a value or adding a new key. + + +### Example Scenario: +Imagine you have a Kubernetes Pod resource that looks like this: + +``` +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + containers: + - name: nginx + image: nginx:1.14 + - name: redis + image: redis:5 +``` +Now, you want to change the image of the nginx container from nginx:1.14 to nginx:1.16. Instead of sending the entire resource, you can send only the part you want to change, like this: +``` +{ + "spec": { + "containers": [ + { + "name": "nginx", + "image": "nginx:1.16" + } + ] + } +} +``` + +When you send this patch to Kubernetes: + +It will replace the image of the nginx container with the new one (nginx:1.16). +It will leave the redis container unchanged, because it's not included in the patch. + +### Example Code (Python): +``` +from kubernetes import client, config + +def main(): + config.load_kube_config() + v1 = client.CoreV1Api() + + namespace = "default" + name = "mypod" + + patch = { + "spec": { + "containers": [ + { + "name": "nginx", + "image": "nginx:1.16" + } + ] + } + } + + v1.patch_namespaced_pod(name=name, namespace=namespace, body=patch, content_type="application/merge-patch+json") + +if __name__ == "__main__": + main() + +``` + +### After the JSON Merge patch + +``` +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + containers: + - name: nginx + image: nginx:1.16 # Updated image version + - name: redis + image: redis:5 # Unchanged +``` + + +## 2. Strategic Merge Patch +Strategic Merge Patch is another type of patching mechanism, mostly used in Kubernetes, that allows updates to objects in a way that is more aware of the structure and semantics of the resource being modified. It is strategic because it understands the structure of the object, rather than blindly replacing it, and applies the changes in a smart way. +- The patch itself is typically a JSON or YAML object, which contains the fields to be updated +- **Adds New Fields:** You can use it to add new fields or modify existing ones without affecting the rest of the object. +- **Handle Lists or Arrays:** When dealing with lists (e.g., arrays or dictionaries), Strategic Merge Patch handles merging and updates intelligently. + +### Example of Strategic Merge Patch: +let's suppose we have a yaml file Target Resource (Kubernetes ConfigMap): + +``` +apiVersion: v1 +kind: ConfigMap +metadata: + name: my-configmap +data: + key1: value1 + key2: value2 + list1: + - item1 + - item2 + +``` + +Strategic Merge Patch +``` +data: + key1: updated_value1 # Update key1 + key3: value3 # Add new key3 + list1: + - item1 + - item2 + - item3 # Add item3 to list1 + +``` + +Result after Strategic Merge Patch + +``` +apiVersion: v1 +kind: ConfigMap +metadata: + name: my-configmap +data: + key1: updated_value1 # key1 is updated + key2: value2 # key2 is unchanged + key3: value3 # key3 is added + list1: + - item1 + - item2 + - item3 # item3 is added to list1 + + +``` + + +## 3. JSON Patch +- JSON Patch is a standard format that specifies a way to apply updates to a JSON document. Instead of sending a new or merged version of the object, JSON Patch describes how to modify the object step-by-step. +- Operation-Based: A JSON Patch is an array of operations that describe modifications to a target JSON object. +- Ideal when you need to perform multiple, specific operations on resource fields (e.g., replacing a value, adding new fields, or deleting specific values). + +### Patch Structure: +A JSON Patch is an array of operations. Each operation is an object with: +• op: The operation type (e.g., add, remove, replace, etc.). +• path: A JSON Pointer string (defined in RFC 6901) that specifies the location in the document to apply the operation. +• value: (Optional) The new value to apply (used with operations like add, replace, or test). +• from: (Optional) Used in operations like move and copy to specify the source path. + +### Supported Operations for JSON Patch + +#### 1. **add** +- Adds a value to a specified path. +- If the path already exists, it adds the value to a list or object. + +Example: +```json +{ "op": "add", "path": "/a/b/c", "value": "foo" } +``` + +#### 2. **remove** +- Removes the value at the specified path. + +Example: +```json +{ "op": "remove", "path": "/a/b/c" } +``` + +#### 3. **replace** +- Replaces the value at the specified path. +- Functionally similar to remove followed by add. + +Example: +```json +{ "op": "replace", "path": "/a/b/c", "value": "bar" } +``` + +#### 4. **move** +- Moves a value from one path to another. + +Example: +```json +{ "op": "move", "from": "/a/b/c", "path": "/x/y/z" } +``` + +#### 5. **copy** +- Copies a value from one path to another. + +Example: +```json +{ "op": "copy", "from": "/a/b/c", "path": "/x/y/z" } +``` + +#### 6. **test** +- Tests whether a value at a specified path matches a given value. +- Used for validation in transactional updates. + +Example: +```json +{ "op": "test", "path": "/a/b/c", "value": "foo" } +``` + +--- + +#### Example: Applying a JSON Patch + +##### Target JSON Document: +```json +{ + "a": { + "b": { + "c": "foo" + } + }, + "x": { + "y": "bar" + } +} +``` + +##### JSON Patch: +```json +[ + { "op": "replace", "path": "/a/b/c", "value": "baz" }, + { "op": "add", "path": "/a/d", "value": ["new", "value"] }, + { "op": "remove", "path": "/x/y" } +] +``` + +##### Result: +```json +{ + "a": { + "b": { + "c": "baz" + }, + "d": ["new", "value"] + }, + "x": {} +} +``` + + +## 4. Apply Patch (Server-Side Apply) +Server-Side Apply is a feature in Kubernetes that allows you to declaratively update resources by specifying their desired state. It provides an intuitive and robust way to manage resources without having to manually modify every field. It tracks which fields belong to which manager, which helps prevent conflicts when multiple clients (such as different controllers or users) update the same resource. + +Key Features: +- Declarative Management: You provide the desired final state, and Kubernetes ensures the actual state matches it. +- Conflict Detection: Ensures changes from different clients don’t conflict with each other. +- Field Ownership: Kubernetes tracks which client or manager owns which fields of a resource. + +##### Example Scenario: + +You have a ConfigMap and want to update certain keys but leave others unchanged. +``` +apiVersion: v1 +kind: ConfigMap +metadata: + name: example-config + namespace: default +data: + key1: value1 + key2: value2 +``` +**Goal:** +- You want to update key2 to new_value2 and +- add a new key key3 with a value value3. +- leave key1 unchanged + +##### Apply Patch YAML(Desired State): +``` +apiVersion: v1 +kind: ConfigMap +metadata: + name: example-config + namespace: default +data: + key2: new_value2 # Update existing key + key3: value3 # Add new key + +``` + +##### Resulting ConfigMap (after apply): +``` +apiVersion: v1 +kind: ConfigMap +metadata: + name: example-config + namespace: default +data: + key1: value1 # Remains unchanged + key2: new_value2 # Updated value + key3: value3 # New key added + +``` + + + + + From 4c7757b1a728bade2683a2d869691374114b9b26 Mon Sep 17 00:00:00 2001 From: Tomas Aschan Date: Wed, 29 Jan 2025 14:57:38 +0100 Subject: [PATCH 22/30] Tweak test to fail like the production code does --- kubernetes/base/config/exec_provider_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubernetes/base/config/exec_provider_test.py b/kubernetes/base/config/exec_provider_test.py index 9ff62d12e2..fc4944b229 100644 --- a/kubernetes/base/config/exec_provider_test.py +++ b/kubernetes/base/config/exec_provider_test.py @@ -175,7 +175,7 @@ def test_with_cluster_info(self, mock): instance = mock.return_value instance.wait.return_value = 0 instance.communicate.return_value = (self.output_ok, '') - ep = ExecProvider(self.input_with_cluster, None, {'server': 'name.company.com'}) + ep = ExecProvider(self.input_with_cluster, None, ConfigNode("cluster", {'server': 'name.company.com'})) result = ep.run() self.assertTrue(isinstance(result, dict)) self.assertTrue('token' in result) From c665cab8e4416c7cc34dba3cd556d4add13cf92a Mon Sep 17 00:00:00 2001 From: Tomas Aschan Date: Wed, 29 Jan 2025 15:00:41 +0100 Subject: [PATCH 23/30] fix: Extract value from ConfigNode before storing it --- kubernetes/base/config/exec_provider.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubernetes/base/config/exec_provider.py b/kubernetes/base/config/exec_provider.py index c11c2a5f45..3d497392ca 100644 --- a/kubernetes/base/config/exec_provider.py +++ b/kubernetes/base/config/exec_provider.py @@ -54,7 +54,7 @@ def __init__(self, exec_config, cwd, cluster=None): additional_vars[name] = value self.env.update(additional_vars) if exec_config.safe_get('provideClusterInfo'): - self.cluster = cluster + self.cluster = cluster.value else: self.cluster = None self.cwd = cwd or None From dcc27f964eab7d80c2a75563513c3c868cae9ef9 Mon Sep 17 00:00:00 2001 From: Tomas Aschan Date: Fri, 14 Feb 2025 15:43:39 +0100 Subject: [PATCH 24/30] Address review feedback --- kubernetes/base/config/exec_provider.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kubernetes/base/config/exec_provider.py b/kubernetes/base/config/exec_provider.py index 3d497392ca..ae7049ada3 100644 --- a/kubernetes/base/config/exec_provider.py +++ b/kubernetes/base/config/exec_provider.py @@ -54,7 +54,7 @@ def __init__(self, exec_config, cwd, cluster=None): additional_vars[name] = value self.env.update(additional_vars) if exec_config.safe_get('provideClusterInfo'): - self.cluster = cluster.value + self.cluster = cluster else: self.cluster = None self.cwd = cwd or None @@ -80,7 +80,7 @@ def run(self, previous_response=None): if previous_response: kubernetes_exec_info['spec']['response'] = previous_response if self.cluster: - kubernetes_exec_info['spec']['cluster'] = self.cluster + kubernetes_exec_info['spec']['cluster'] = self.cluster.value self.env['KUBERNETES_EXEC_INFO'] = json.dumps(kubernetes_exec_info) process = subprocess.Popen( From 3c848c277bd28d962bb47bafb044c2fb6eac001c Mon Sep 17 00:00:00 2001 From: yliao Date: Fri, 14 Feb 2025 21:41:09 +0000 Subject: [PATCH 25/30] update changelog with release notes from master branch --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97d8be5f7c..3369e03844 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ +# v32.0.1 + +Kubernetes API Version: v1.32.2 + +### Uncategorized +- Adds support for providing cluster information to the exec credential provider if requested. (#2303, @brendandburns) +- Remove py from test dependencies (#2288, @jelly) + +### Bug or Regression +- Fix dynamic client watch of named resource (#2076, @bobh66) +- Fixed PortForward proxy to close local Python sockets when the WebSocket closes. (#2316, @anvilpete) +- Fixes bug that would fail authentication when using the exec-provider with a specific cluster selected (#2340, @tomasaschan) + +### Feature +- Add utility functions kubernetes.utils.duration.parse_duration and kubernetes.utils.duration.format_duration to manage Gateway API Duration strings as specified by GEP-2257. (#2261, @kflynn) +- Added the ability to use the optional `apply` parameter for functions within the `utils.create_from_yaml` submodule. This allows these functions to optionally use the `DynamicClient.server_side_apply` function to apply yaml manifests. (#2252, @dcmcand) +- Adding `utils.format_quantity` to convert decimal numbers into a canonical Kubernetes quantity. (#2216, @rkschamer) + # v32.0.0 Kubernetes API Version: v1.32.1 From 49df23708338ab319bcb5df096e33c6d6c72bed5 Mon Sep 17 00:00:00 2001 From: yliao Date: Fri, 14 Feb 2025 21:41:09 +0000 Subject: [PATCH 26/30] update version constants for 32.0.1 release --- scripts/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/constants.py b/scripts/constants.py index e9a768c365..0b00b28414 100644 --- a/scripts/constants.py +++ b/scripts/constants.py @@ -18,7 +18,7 @@ KUBERNETES_BRANCH = "release-1.32" # client version for packaging and releasing. -CLIENT_VERSION = "32.0.0" +CLIENT_VERSION = "32.0.1" # Name of the release package PACKAGE_NAME = "kubernetes" From 7ea787c17bcece03bc9a1d4c2e33979b2363e4f7 Mon Sep 17 00:00:00 2001 From: yliao Date: Fri, 14 Feb 2025 21:41:43 +0000 Subject: [PATCH 27/30] generated client change for custom_objects --- kubernetes/client/api/custom_objects_api.py | 30 ++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/kubernetes/client/api/custom_objects_api.py b/kubernetes/client/api/custom_objects_api.py index 08eda56466..18b2441225 100644 --- a/kubernetes/client/api/custom_objects_api.py +++ b/kubernetes/client/api/custom_objects_api.py @@ -2234,19 +2234,19 @@ def list_cluster_custom_object_with_http_info(self, group, version, plural, **kw _request_timeout=local_var_params.get('_request_timeout'), collection_formats=collection_formats) - def list_custom_object_for_all_namespaces(self, group, version, plural, **kwargs): # noqa: E501 + def list_custom_object_for_all_namespaces(self, group, version, resource_plural, **kwargs): # noqa: E501 """list_custom_object_for_all_namespaces # noqa: E501 list or watch namespace scoped custom objects # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True - >>> thread = api.list_custom_object_for_all_namespaces(group, version, plural, async_req=True) + >>> thread = api.list_custom_object_for_all_namespaces(group, version, resource_plural, async_req=True) >>> result = thread.get() :param async_req bool: execute request asynchronously :param str group: The custom resource's group name (required) :param str version: The custom resource's version (required) - :param str plural: The custom resource's plural name. For TPRs this would be lowercase plural kind. (required) + :param str resource_plural: The custom resource's plural name. For TPRs this would be lowercase plural kind. (required) :param str pretty: If 'true', then the output is pretty printed. :param bool allow_watch_bookmarks: 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. If the feature gate WatchBookmarks is not enabled in apiserver, this field is ignored. :param str _continue: 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\". This 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. @@ -2269,21 +2269,21 @@ def list_custom_object_for_all_namespaces(self, group, version, plural, **kwargs returns the request thread. """ kwargs['_return_http_data_only'] = True - return self.list_custom_object_for_all_namespaces_with_http_info(group, version, plural, **kwargs) # noqa: E501 + return self.list_custom_object_for_all_namespaces_with_http_info(group, version, resource_plural, **kwargs) # noqa: E501 - def list_custom_object_for_all_namespaces_with_http_info(self, group, version, plural, **kwargs): # noqa: E501 + def list_custom_object_for_all_namespaces_with_http_info(self, group, version, resource_plural, **kwargs): # noqa: E501 """list_custom_object_for_all_namespaces # noqa: E501 list or watch namespace scoped custom objects # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True - >>> thread = api.list_custom_object_for_all_namespaces_with_http_info(group, version, plural, async_req=True) + >>> thread = api.list_custom_object_for_all_namespaces_with_http_info(group, version, resource_plural, async_req=True) >>> result = thread.get() :param async_req bool: execute request asynchronously :param str group: The custom resource's group name (required) :param str version: The custom resource's version (required) - :param str plural: The custom resource's plural name. For TPRs this would be lowercase plural kind. (required) + :param str resource_plural: The custom resource's plural name. For TPRs this would be lowercase plural kind. (required) :param str pretty: If 'true', then the output is pretty printed. :param bool allow_watch_bookmarks: 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. If the feature gate WatchBookmarks is not enabled in apiserver, this field is ignored. :param str _continue: 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\". This 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. @@ -2313,7 +2313,7 @@ def list_custom_object_for_all_namespaces_with_http_info(self, group, version, p all_params = [ 'group', 'version', - 'plural', + 'resource_plural', 'pretty', 'allow_watch_bookmarks', '_continue', @@ -2350,10 +2350,10 @@ def list_custom_object_for_all_namespaces_with_http_info(self, group, version, p if self.api_client.client_side_validation and ('version' not in local_var_params or # noqa: E501 local_var_params['version'] is None): # noqa: E501 raise ApiValueError("Missing the required parameter `version` when calling `list_custom_object_for_all_namespaces`") # noqa: E501 - # verify the required parameter 'plural' is set - if self.api_client.client_side_validation and ('plural' not in local_var_params or # noqa: E501 - local_var_params['plural'] is None): # noqa: E501 - raise ApiValueError("Missing the required parameter `plural` when calling `list_custom_object_for_all_namespaces`") # noqa: E501 + # verify the required parameter 'resource_plural' is set + if self.api_client.client_side_validation and ('resource_plural' not in local_var_params or # noqa: E501 + local_var_params['resource_plural'] is None): # noqa: E501 + raise ApiValueError("Missing the required parameter `resource_plural` when calling `list_custom_object_for_all_namespaces`") # noqa: E501 collection_formats = {} @@ -2362,8 +2362,8 @@ def list_custom_object_for_all_namespaces_with_http_info(self, group, version, p path_params['group'] = local_var_params['group'] # noqa: E501 if 'version' in local_var_params: path_params['version'] = local_var_params['version'] # noqa: E501 - if 'plural' in local_var_params: - path_params['plural'] = local_var_params['plural'] # noqa: E501 + if 'resource_plural' in local_var_params: + path_params['resource_plural'] = local_var_params['resource_plural'] # noqa: E501 query_params = [] if 'pretty' in local_var_params and local_var_params['pretty'] is not None: # noqa: E501 @@ -2401,7 +2401,7 @@ def list_custom_object_for_all_namespaces_with_http_info(self, group, version, p auth_settings = ['BearerToken'] # noqa: E501 return self.api_client.call_api( - '/apis/{group}/{version}/{plural}#‎', 'GET', + '/apis/{group}/{version}/{resource_plural}', 'GET', path_params, query_params, header_params, From 641f59a7e4dba95e3c83a17a044c3672dcebcf5e Mon Sep 17 00:00:00 2001 From: yliao Date: Fri, 14 Feb 2025 21:41:43 +0000 Subject: [PATCH 28/30] generated API change --- kubernetes/docs/CustomObjectsApi.md | 10 +++++----- scripts/swagger.json | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/kubernetes/docs/CustomObjectsApi.md b/kubernetes/docs/CustomObjectsApi.md index e366aae9c7..48ecb5fe04 100644 --- a/kubernetes/docs/CustomObjectsApi.md +++ b/kubernetes/docs/CustomObjectsApi.md @@ -18,7 +18,7 @@ Method | HTTP request | Description [**get_namespaced_custom_object_scale**](CustomObjectsApi.md#get_namespaced_custom_object_scale) | **GET** /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name}/scale | [**get_namespaced_custom_object_status**](CustomObjectsApi.md#get_namespaced_custom_object_status) | **GET** /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name}/status | [**list_cluster_custom_object**](CustomObjectsApi.md#list_cluster_custom_object) | **GET** /apis/{group}/{version}/{plural} | -[**list_custom_object_for_all_namespaces**](CustomObjectsApi.md#list_custom_object_for_all_namespaces) | **GET** /apis/{group}/{version}/{plural}#‎ | +[**list_custom_object_for_all_namespaces**](CustomObjectsApi.md#list_custom_object_for_all_namespaces) | **GET** /apis/{group}/{version}/{resource_plural} | [**list_namespaced_custom_object**](CustomObjectsApi.md#list_namespaced_custom_object) | **GET** /apis/{group}/{version}/namespaces/{namespace}/{plural} | [**patch_cluster_custom_object**](CustomObjectsApi.md#patch_cluster_custom_object) | **PATCH** /apis/{group}/{version}/{plural}/{name} | [**patch_cluster_custom_object_scale**](CustomObjectsApi.md#patch_cluster_custom_object_scale) | **PATCH** /apis/{group}/{version}/{plural}/{name}/scale | @@ -1117,7 +1117,7 @@ Name | Type | Description | Notes [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) # **list_custom_object_for_all_namespaces** -> object list_custom_object_for_all_namespaces(group, version, plural, pretty=pretty, allow_watch_bookmarks=allow_watch_bookmarks, _continue=_continue, field_selector=field_selector, label_selector=label_selector, limit=limit, resource_version=resource_version, resource_version_match=resource_version_match, timeout_seconds=timeout_seconds, watch=watch) +> object list_custom_object_for_all_namespaces(group, version, resource_plural, pretty=pretty, allow_watch_bookmarks=allow_watch_bookmarks, _continue=_continue, field_selector=field_selector, label_selector=label_selector, limit=limit, resource_version=resource_version, resource_version_match=resource_version_match, timeout_seconds=timeout_seconds, watch=watch) @@ -1147,7 +1147,7 @@ with kubernetes.client.ApiClient(configuration) as api_client: api_instance = kubernetes.client.CustomObjectsApi(api_client) group = 'group_example' # str | The custom resource's group name version = 'version_example' # str | The custom resource's version -plural = 'plural_example' # str | The custom resource's plural name. For TPRs this would be lowercase plural kind. +resource_plural = 'resource_plural_example' # str | The custom resource's plural name. For TPRs this would be lowercase plural kind. pretty = 'pretty_example' # str | If 'true', then the output is pretty printed. (optional) allow_watch_bookmarks = True # bool | 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. If the feature gate WatchBookmarks is not enabled in apiserver, this field is ignored. (optional) _continue = '_continue_example' # str | The continue option should be set when retrieving more results from the server. Since this value is server defined, kubernetes.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 kubernetes.client needs a consistent list, it must restart their list without the continue field. Otherwise, the kubernetes.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\". This 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. (optional) @@ -1160,7 +1160,7 @@ timeout_seconds = 56 # int | Timeout for the list/watch call. This limits the du watch = True # bool | Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. (optional) try: - api_response = api_instance.list_custom_object_for_all_namespaces(group, version, plural, pretty=pretty, allow_watch_bookmarks=allow_watch_bookmarks, _continue=_continue, field_selector=field_selector, label_selector=label_selector, limit=limit, resource_version=resource_version, resource_version_match=resource_version_match, timeout_seconds=timeout_seconds, watch=watch) + api_response = api_instance.list_custom_object_for_all_namespaces(group, version, resource_plural, pretty=pretty, allow_watch_bookmarks=allow_watch_bookmarks, _continue=_continue, field_selector=field_selector, label_selector=label_selector, limit=limit, resource_version=resource_version, resource_version_match=resource_version_match, timeout_seconds=timeout_seconds, watch=watch) pprint(api_response) except ApiException as e: print("Exception when calling CustomObjectsApi->list_custom_object_for_all_namespaces: %s\n" % e) @@ -1172,7 +1172,7 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **group** | **str**| The custom resource's group name | **version** | **str**| The custom resource's version | - **plural** | **str**| The custom resource's plural name. For TPRs this would be lowercase plural kind. | + **resource_plural** | **str**| The custom resource's plural name. For TPRs this would be lowercase plural kind. | **pretty** | **str**| If 'true', then the output is pretty printed. | [optional] **allow_watch_bookmarks** | **bool**| 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. If the feature gate WatchBookmarks is not enabled in apiserver, this field is ignored. | [optional] **_continue** | **str**| The continue option should be set when retrieving more results from the server. Since this value is server defined, kubernetes.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 kubernetes.client needs a consistent list, it must restart their list without the continue field. Otherwise, the kubernetes.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\". This 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. | [optional] diff --git a/scripts/swagger.json b/scripts/swagger.json index 1c3b32f4c1..6f54c947ae 100644 --- a/scripts/swagger.json +++ b/scripts/swagger.json @@ -98896,7 +98896,7 @@ } } }, - "/apis/{group}/{version}/{plural}#\u200e": { + "/apis/{group}/{version}/{resource_plural}": { "parameters": [ { "uniqueItems": true, @@ -98920,7 +98920,7 @@ "type": "string" }, { - "name": "plural", + "name": "resource_plural", "in": "path", "required": true, "description": "The custom resource's plural name. For TPRs this would be lowercase plural kind.", From 893d70aa5f83f7dca61f63181165266a961916da Mon Sep 17 00:00:00 2001 From: yliao Date: Fri, 14 Feb 2025 21:41:43 +0000 Subject: [PATCH 29/30] generated client change --- kubernetes/.openapi-generator/swagger.json.sha256 | 2 +- kubernetes/README.md | 4 ++-- kubernetes/__init__.py | 2 +- kubernetes/client/__init__.py | 2 +- kubernetes/client/api_client.py | 2 +- kubernetes/client/configuration.py | 2 +- setup.py | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/kubernetes/.openapi-generator/swagger.json.sha256 b/kubernetes/.openapi-generator/swagger.json.sha256 index 343524c1e5..a3edfaa83c 100644 --- a/kubernetes/.openapi-generator/swagger.json.sha256 +++ b/kubernetes/.openapi-generator/swagger.json.sha256 @@ -1 +1 @@ -b20f45563c8a98d4f6f0ccc8fea807c5a646510c40aee9183d87b0be22104194 \ No newline at end of file +b8cfb7a44bc989e127fbe1964c22b7da75c915c0e43925c6ac5c3592254696c5 \ No newline at end of file diff --git a/kubernetes/README.md b/kubernetes/README.md index 7e31c7aa28..328fc2d087 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -4,7 +4,7 @@ No description provided (generated by Openapi Generator https://github.com/opena This Python package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: - API version: release-1.32 -- Package version: 32.0.0 +- Package version: 32.0.1 - Build package: org.openapitools.codegen.languages.PythonClientCodegen ## Requirements. @@ -560,7 +560,7 @@ Class | Method | HTTP request | Description *CustomObjectsApi* | [**get_namespaced_custom_object_scale**](docs/CustomObjectsApi.md#get_namespaced_custom_object_scale) | **GET** /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name}/scale | *CustomObjectsApi* | [**get_namespaced_custom_object_status**](docs/CustomObjectsApi.md#get_namespaced_custom_object_status) | **GET** /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name}/status | *CustomObjectsApi* | [**list_cluster_custom_object**](docs/CustomObjectsApi.md#list_cluster_custom_object) | **GET** /apis/{group}/{version}/{plural} | -*CustomObjectsApi* | [**list_custom_object_for_all_namespaces**](docs/CustomObjectsApi.md#list_custom_object_for_all_namespaces) | **GET** /apis/{group}/{version}/{plural}#‎ | +*CustomObjectsApi* | [**list_custom_object_for_all_namespaces**](docs/CustomObjectsApi.md#list_custom_object_for_all_namespaces) | **GET** /apis/{group}/{version}/{resource_plural} | *CustomObjectsApi* | [**list_namespaced_custom_object**](docs/CustomObjectsApi.md#list_namespaced_custom_object) | **GET** /apis/{group}/{version}/namespaces/{namespace}/{plural} | *CustomObjectsApi* | [**patch_cluster_custom_object**](docs/CustomObjectsApi.md#patch_cluster_custom_object) | **PATCH** /apis/{group}/{version}/{plural}/{name} | *CustomObjectsApi* | [**patch_cluster_custom_object_scale**](docs/CustomObjectsApi.md#patch_cluster_custom_object_scale) | **PATCH** /apis/{group}/{version}/{plural}/{name}/scale | diff --git a/kubernetes/__init__.py b/kubernetes/__init__.py index 5ea666bf69..2d97aed23e 100644 --- a/kubernetes/__init__.py +++ b/kubernetes/__init__.py @@ -14,7 +14,7 @@ __project__ = 'kubernetes' # The version is auto-updated. Please do not edit. -__version__ = "32.0.0" +__version__ = "32.0.1" from . import client from . import config diff --git a/kubernetes/client/__init__.py b/kubernetes/client/__init__.py index 7368d6a4ee..f43baaee85 100644 --- a/kubernetes/client/__init__.py +++ b/kubernetes/client/__init__.py @@ -14,7 +14,7 @@ from __future__ import absolute_import -__version__ = "32.0.0" +__version__ = "32.0.1" # import apis into sdk package from kubernetes.client.api.well_known_api import WellKnownApi diff --git a/kubernetes/client/api_client.py b/kubernetes/client/api_client.py index 3e21219d7e..f77e97c7a9 100644 --- a/kubernetes/client/api_client.py +++ b/kubernetes/client/api_client.py @@ -78,7 +78,7 @@ def __init__(self, configuration=None, header_name=None, header_value=None, self.default_headers[header_name] = header_value self.cookie = cookie # Set default User-Agent. - self.user_agent = 'OpenAPI-Generator/32.0.0/python' + self.user_agent = 'OpenAPI-Generator/32.0.1/python' self.client_side_validation = configuration.client_side_validation def __enter__(self): diff --git a/kubernetes/client/configuration.py b/kubernetes/client/configuration.py index 1a234595c3..1ad1c8ebfa 100644 --- a/kubernetes/client/configuration.py +++ b/kubernetes/client/configuration.py @@ -354,7 +354,7 @@ def to_debug_report(self): "OS: {env}\n"\ "Python Version: {pyversion}\n"\ "Version of the API: release-1.32\n"\ - "SDK Package Version: 32.0.0".\ + "SDK Package Version: 32.0.1".\ format(env=sys.platform, pyversion=sys.version) def get_host_settings(self): diff --git a/setup.py b/setup.py index 01e26edf87..804f331fb9 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ # Do not edit these constants. They will be updated automatically # by scripts/update-client.sh. -CLIENT_VERSION = "32.0.0" +CLIENT_VERSION = "32.0.1" PACKAGE_NAME = "kubernetes" DEVELOPMENT_STATUS = "5 - Production/Stable" From 79690bcfa48263b24fc7ede39f9f473e9a4a2067 Mon Sep 17 00:00:00 2001 From: yliao Date: Fri, 14 Feb 2025 21:43:52 +0000 Subject: [PATCH 30/30] Update the compatibility matrix and maintenance status --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7f148915e1..18b916eb77 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ supported versions of Kubernetes clusters. - [client 29.y.z](https://pypi.org/project/kubernetes/29.0.0/): Kubernetes 1.28 or below (+-), Kubernetes 1.29 (✓), Kubernetes 1.30 or above (+-) - [client 30.y.z](https://pypi.org/project/kubernetes/30.1.0/): Kubernetes 1.29 or below (+-), Kubernetes 1.30 (✓), Kubernetes 1.31 or above (+-) - [client 31.y.z](https://pypi.org/project/kubernetes/31.0.0/): Kubernetes 1.30 or below (+-), Kubernetes 1.31 (✓), Kubernetes 1.32 or above (+-) -- [client 32.y.z](https://pypi.org/project/kubernetes/32.0.0/): Kubernetes 1.31 or below (+-), Kubernetes 1.32 (✓), Kubernetes 1.33 or above (+-) +- [client 32.y.z](https://pypi.org/project/kubernetes/32.0.1/): Kubernetes 1.31 or below (+-), Kubernetes 1.32 (✓), Kubernetes 1.33 or above (+-) > See [here](#homogenizing-the-kubernetes-python-client-versions) for an explanation of why there is no v13-v16 release. @@ -170,7 +170,7 @@ between client-python versions. | 31.0 Alpha/Beta | Kubernetes main repo, 1.31 branch | ✗ | | 31.0 | Kubernetes main repo, 1.31 branch | ✓ | | 32.0 Alpha/Beta | Kubernetes main repo, 1.32 branch | ✗ | -| 32.0 | Kubernetes main repo, 1.32 branch | ✓ | +| 32.1 | Kubernetes main repo, 1.32 branch | ✓ | > See [here](#homogenizing-the-kubernetes-python-client-versions) for an explanation of why there is no v13-v16 release.