From a1af1b1dc56dddd2ea2b9e82174c81ed14dafcf5 Mon Sep 17 00:00:00 2001 From: SDK Generator Bot Date: Thu, 2 Apr 2026 14:55:16 +0000 Subject: [PATCH] Generate ske --- services/ske/oas_commit | 2 +- services/ske/src/stackit/ske/__init__.py | 12 ++ .../ske/src/stackit/ske/api/default_api.py | 33 +---- .../ske/src/stackit/ske/models/__init__.py | 3 + .../src/stackit/ske/models/access_scope.py | 2 +- .../src/stackit/ske/models/cluster_status.py | 9 ++ services/ske/src/stackit/ske/models/cri.py | 4 +- .../models/expiration_status_kubernetes.py | 97 +++++++++++++ .../ske/models/expiration_status_nodepool.py | 130 ++++++++++++++++++ .../stackit/ske/models/expiratoaion_status.py | 108 +++++++++++++++ 10 files changed, 369 insertions(+), 31 deletions(-) create mode 100644 services/ske/src/stackit/ske/models/expiration_status_kubernetes.py create mode 100644 services/ske/src/stackit/ske/models/expiration_status_nodepool.py create mode 100644 services/ske/src/stackit/ske/models/expiratoaion_status.py diff --git a/services/ske/oas_commit b/services/ske/oas_commit index e3713dde3..6556a521f 100644 --- a/services/ske/oas_commit +++ b/services/ske/oas_commit @@ -1 +1 @@ -0e64886dd0847341800d7191ed193b75413be998 +18fae4fac0a9d9b1d0146a37d5513022ad3710cb diff --git a/services/ske/src/stackit/ske/__init__.py b/services/ske/src/stackit/ske/__init__.py index 1b2c7e0c8..a0af94dac 100644 --- a/services/ske/src/stackit/ske/__init__.py +++ b/services/ske/src/stackit/ske/__init__.py @@ -41,6 +41,9 @@ "CreateOrUpdateClusterPayload", "CredentialsRotationState", "DNS", + "ExpirationStatusKubernetes", + "ExpirationStatusNodepool", + "ExpiratoaionStatus", "Extension", "GetProviderOptionsRequestVersionState", "Hibernation", @@ -108,6 +111,15 @@ ) from stackit.ske.models.cri import CRI as CRI from stackit.ske.models.dns import DNS as DNS +from stackit.ske.models.expiration_status_kubernetes import ( + ExpirationStatusKubernetes as ExpirationStatusKubernetes, +) +from stackit.ske.models.expiration_status_nodepool import ( + ExpirationStatusNodepool as ExpirationStatusNodepool, +) +from stackit.ske.models.expiratoaion_status import ( + ExpiratoaionStatus as ExpiratoaionStatus, +) from stackit.ske.models.extension import Extension as Extension from stackit.ske.models.get_provider_options_request_version_state import ( GetProviderOptionsRequestVersionState as GetProviderOptionsRequestVersionState, diff --git a/services/ske/src/stackit/ske/api/default_api.py b/services/ske/src/stackit/ske/api/default_api.py index 50325e938..bc98e7451 100644 --- a/services/ske/src/stackit/ske/api/default_api.py +++ b/services/ske/src/stackit/ske/api/default_api.py @@ -110,7 +110,6 @@ def complete_credentials_rotation( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "object", "202": "object", "400": "object", "401": "object", @@ -182,7 +181,6 @@ def complete_credentials_rotation_with_http_info( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "object", "202": "object", "400": "object", "401": "object", @@ -254,7 +252,6 @@ def complete_credentials_rotation_without_preload_content( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "object", "202": "object", "400": "object", "401": "object", @@ -670,8 +667,7 @@ def create_or_update_cluster( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "Cluster", - "202": "object", + "202": "Cluster", "400": "object", "401": "object", "404": "object", @@ -746,8 +742,7 @@ def create_or_update_cluster_with_http_info( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "Cluster", - "202": "object", + "202": "Cluster", "400": "object", "401": "object", "404": "object", @@ -822,8 +817,7 @@ def create_or_update_cluster_without_preload_content( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "Cluster", - "202": "object", + "202": "Cluster", "400": "object", "401": "object", "404": "object", @@ -957,7 +951,6 @@ def delete_cluster( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "object", "202": "object", "400": "object", "401": "object", @@ -1029,7 +1022,6 @@ def delete_cluster_with_http_info( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "object", "202": "object", "400": "object", "401": "object", @@ -1101,7 +1093,6 @@ def delete_cluster_without_preload_content( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "object", "202": "object", "400": "object", "401": "object", @@ -2267,6 +2258,7 @@ def list_provider_options( _response_types_map: Dict[str, Optional[str]] = { "200": "ProviderOptions", + "400": "object", "401": "object", } response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) @@ -2332,6 +2324,7 @@ def list_provider_options_with_http_info( _response_types_map: Dict[str, Optional[str]] = { "200": "ProviderOptions", + "400": "object", "401": "object", } response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) @@ -2397,6 +2390,7 @@ def list_provider_options_without_preload_content( _response_types_map: Dict[str, Optional[str]] = { "200": "ProviderOptions", + "400": "object", "401": "object", } response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) @@ -2516,7 +2510,6 @@ def start_credentials_rotation( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "object", "202": "object", "400": "object", "401": "object", @@ -2588,7 +2581,6 @@ def start_credentials_rotation_with_http_info( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "object", "202": "object", "400": "object", "401": "object", @@ -2660,7 +2652,6 @@ def start_credentials_rotation_without_preload_content( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "object", "202": "object", "400": "object", "401": "object", @@ -2784,7 +2775,6 @@ def trigger_hibernate( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "object", "202": "object", "400": "object", "401": "object", @@ -2856,7 +2846,6 @@ def trigger_hibernate_with_http_info( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "object", "202": "object", "400": "object", "401": "object", @@ -2928,7 +2917,6 @@ def trigger_hibernate_without_preload_content( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "object", "202": "object", "400": "object", "401": "object", @@ -3052,7 +3040,6 @@ def trigger_maintenance( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "object", "202": "object", "400": "object", "401": "object", @@ -3124,7 +3111,6 @@ def trigger_maintenance_with_http_info( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "object", "202": "object", "400": "object", "401": "object", @@ -3196,7 +3182,6 @@ def trigger_maintenance_without_preload_content( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "object", "202": "object", "400": "object", "401": "object", @@ -3320,7 +3305,6 @@ def trigger_reconcile( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "object", "202": "object", "400": "object", "401": "object", @@ -3392,7 +3376,6 @@ def trigger_reconcile_with_http_info( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "object", "202": "object", "400": "object", "401": "object", @@ -3464,7 +3447,6 @@ def trigger_reconcile_without_preload_content( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "object", "202": "object", "400": "object", "401": "object", @@ -3588,7 +3570,6 @@ def trigger_wakeup( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "object", "202": "object", "400": "object", "401": "object", @@ -3660,7 +3641,6 @@ def trigger_wakeup_with_http_info( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "object", "202": "object", "400": "object", "401": "object", @@ -3732,7 +3712,6 @@ def trigger_wakeup_without_preload_content( ) _response_types_map: Dict[str, Optional[str]] = { - "200": "object", "202": "object", "400": "object", "401": "object", diff --git a/services/ske/src/stackit/ske/models/__init__.py b/services/ske/src/stackit/ske/models/__init__.py index 52102c18d..f2241c4e4 100644 --- a/services/ske/src/stackit/ske/models/__init__.py +++ b/services/ske/src/stackit/ske/models/__init__.py @@ -29,6 +29,9 @@ from stackit.ske.models.credentials_rotation_state import CredentialsRotationState from stackit.ske.models.cri import CRI from stackit.ske.models.dns import DNS +from stackit.ske.models.expiration_status_kubernetes import ExpirationStatusKubernetes +from stackit.ske.models.expiration_status_nodepool import ExpirationStatusNodepool +from stackit.ske.models.expiratoaion_status import ExpiratoaionStatus from stackit.ske.models.extension import Extension from stackit.ske.models.get_provider_options_request_version_state import ( GetProviderOptionsRequestVersionState, diff --git a/services/ske/src/stackit/ske/models/access_scope.py b/services/ske/src/stackit/ske/models/access_scope.py index eb18ac96b..c6ed690a1 100644 --- a/services/ske/src/stackit/ske/models/access_scope.py +++ b/services/ske/src/stackit/ske/models/access_scope.py @@ -21,7 +21,7 @@ class AccessScope(str, Enum): """ - The access scope of the Control Plane. It defines if the Kubernetes control plane is public or only available inside a STACKIT Network Area. ⚠️ Note: This feature is in private preview. Supplying this object is only permitted for enabled accounts. If your account does not have access, the request will be rejected. + The access scope of the Control Plane. It defines if the Kubernetes control plane is public or only available inside a STACKIT Network Area. This field is immutable. ⚠️ Note: This feature is in private preview. Supplying this object is only permitted for enabled accounts. If your account does not have access, the request will be rejected. """ """ diff --git a/services/ske/src/stackit/ske/models/cluster_status.py b/services/ske/src/stackit/ske/models/cluster_status.py index 508b36dbe..154cbbe29 100644 --- a/services/ske/src/stackit/ske/models/cluster_status.py +++ b/services/ske/src/stackit/ske/models/cluster_status.py @@ -32,6 +32,7 @@ from stackit.ske.models.cluster_error import ClusterError from stackit.ske.models.cluster_status_state import ClusterStatusState from stackit.ske.models.credentials_rotation_state import CredentialsRotationState +from stackit.ske.models.expiratoaion_status import ExpiratoaionStatus from stackit.ske.models.runtime_error import RuntimeError @@ -52,6 +53,7 @@ class ClusterStatus(BaseModel): ) error: Optional[RuntimeError] = None errors: Optional[List[ClusterError]] = None + expiration: Optional[ExpiratoaionStatus] = None hibernated: Optional[StrictBool] = None identity: Optional[StrictStr] = None pod_address_ranges: Optional[List[StrictStr]] = Field( @@ -66,6 +68,7 @@ class ClusterStatus(BaseModel): "egressAddressRanges", "error", "errors", + "expiration", "hibernated", "identity", "podAddressRanges", @@ -134,6 +137,9 @@ def to_dict(self) -> Dict[str, Any]: if _item_errors: _items.append(_item_errors.to_dict()) _dict["errors"] = _items + # override the default output from pydantic by calling `to_dict()` of expiration + if self.expiration: + _dict["expiration"] = self.expiration.to_dict() return _dict @classmethod @@ -161,6 +167,9 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: if obj.get("errors") is not None else None ), + "expiration": ( + ExpiratoaionStatus.from_dict(obj["expiration"]) if obj.get("expiration") is not None else None + ), "hibernated": obj.get("hibernated"), "identity": obj.get("identity"), "podAddressRanges": obj.get("podAddressRanges"), diff --git a/services/ske/src/stackit/ske/models/cri.py b/services/ske/src/stackit/ske/models/cri.py index 75029adb7..9a0c0e94e 100644 --- a/services/ske/src/stackit/ske/models/cri.py +++ b/services/ske/src/stackit/ske/models/cri.py @@ -35,8 +35,8 @@ def name_validate_enum(cls, value): if value is None: return value - if value not in set(["docker", "containerd"]): - raise ValueError("must be one of enum values ('docker', 'containerd')") + if value not in set(["containerd"]): + raise ValueError("must be one of enum values ('containerd')") return value model_config = ConfigDict( diff --git a/services/ske/src/stackit/ske/models/expiration_status_kubernetes.py b/services/ske/src/stackit/ske/models/expiration_status_kubernetes.py new file mode 100644 index 000000000..1710fa07e --- /dev/null +++ b/services/ske/src/stackit/ske/models/expiration_status_kubernetes.py @@ -0,0 +1,97 @@ +# coding: utf-8 + +""" + STACKIT Kubernetes Engine API + + The SKE API provides endpoints to create, update or delete clusters within STACKIT projects and to trigger further cluster management tasks. + + The version of the OpenAPI document: 2.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + +from __future__ import annotations + +import json +import pprint +import re # noqa: F401 +from datetime import datetime +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator +from typing_extensions import Self + + +class ExpirationStatusKubernetes(BaseModel): + """ + ExpirationStatusKubernetes + """ # noqa: E501 + + expiration_date: Optional[datetime] = Field(default=None, alias="expirationDate") + version: Optional[StrictStr] = None + __properties: ClassVar[List[str]] = ["expirationDate", "version"] + + @field_validator("expiration_date", mode="before") + def expiration_date_change_year_zero_to_one(cls, value): + """Workaround which prevents year 0 issue""" + if isinstance(value, str): + # Check for year "0000" at the beginning of the string + # This assumes common date formats like YYYY-MM-DDTHH:MM:SS+00:00 or YYYY-MM-DDTHH:MM:SSZ + if value.startswith("0000-01-01T") and re.match( + r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\+\d{2}:\d{2}|Z)$", value + ): + # Workaround: Replace "0000" with "0001" + return "0001" + value[4:] # Take "0001" and append the rest of the string + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ExpirationStatusKubernetes from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ExpirationStatusKubernetes from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({"expirationDate": obj.get("expirationDate"), "version": obj.get("version")}) + return _obj diff --git a/services/ske/src/stackit/ske/models/expiration_status_nodepool.py b/services/ske/src/stackit/ske/models/expiration_status_nodepool.py new file mode 100644 index 000000000..10190f203 --- /dev/null +++ b/services/ske/src/stackit/ske/models/expiration_status_nodepool.py @@ -0,0 +1,130 @@ +# coding: utf-8 + +""" + STACKIT Kubernetes Engine API + + The SKE API provides endpoints to create, update or delete clusters within STACKIT projects and to trigger further cluster management tasks. + + The version of the OpenAPI document: 2.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + +from __future__ import annotations + +import json +import pprint +import re # noqa: F401 +from datetime import datetime +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator +from typing_extensions import Self + + +class ExpirationStatusNodepool(BaseModel): + """ + ExpirationStatusNodepool + """ # noqa: E501 + + kubernetes_expiration_date: Optional[datetime] = Field(default=None, alias="kubernetesExpirationDate") + kubernetes_version: Optional[StrictStr] = Field(default=None, alias="kubernetesVersion") + name: Optional[StrictStr] = None + os_expiration_date: Optional[datetime] = Field(default=None, alias="osExpirationDate") + os_name: Optional[StrictStr] = Field(default=None, alias="osName") + os_version: Optional[StrictStr] = Field(default=None, alias="osVersion") + __properties: ClassVar[List[str]] = [ + "kubernetesExpirationDate", + "kubernetesVersion", + "name", + "osExpirationDate", + "osName", + "osVersion", + ] + + @field_validator("kubernetes_expiration_date", mode="before") + def kubernetes_expiration_date_change_year_zero_to_one(cls, value): + """Workaround which prevents year 0 issue""" + if isinstance(value, str): + # Check for year "0000" at the beginning of the string + # This assumes common date formats like YYYY-MM-DDTHH:MM:SS+00:00 or YYYY-MM-DDTHH:MM:SSZ + if value.startswith("0000-01-01T") and re.match( + r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\+\d{2}:\d{2}|Z)$", value + ): + # Workaround: Replace "0000" with "0001" + return "0001" + value[4:] # Take "0001" and append the rest of the string + return value + + @field_validator("os_expiration_date", mode="before") + def os_expiration_date_change_year_zero_to_one(cls, value): + """Workaround which prevents year 0 issue""" + if isinstance(value, str): + # Check for year "0000" at the beginning of the string + # This assumes common date formats like YYYY-MM-DDTHH:MM:SS+00:00 or YYYY-MM-DDTHH:MM:SSZ + if value.startswith("0000-01-01T") and re.match( + r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\+\d{2}:\d{2}|Z)$", value + ): + # Workaround: Replace "0000" with "0001" + return "0001" + value[4:] # Take "0001" and append the rest of the string + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ExpirationStatusNodepool from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ExpirationStatusNodepool from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "kubernetesExpirationDate": obj.get("kubernetesExpirationDate"), + "kubernetesVersion": obj.get("kubernetesVersion"), + "name": obj.get("name"), + "osExpirationDate": obj.get("osExpirationDate"), + "osName": obj.get("osName"), + "osVersion": obj.get("osVersion"), + } + ) + return _obj diff --git a/services/ske/src/stackit/ske/models/expiratoaion_status.py b/services/ske/src/stackit/ske/models/expiratoaion_status.py new file mode 100644 index 000000000..771a1d82a --- /dev/null +++ b/services/ske/src/stackit/ske/models/expiratoaion_status.py @@ -0,0 +1,108 @@ +# coding: utf-8 + +""" + STACKIT Kubernetes Engine API + + The SKE API provides endpoints to create, update or delete clusters within STACKIT projects and to trigger further cluster management tasks. + + The version of the OpenAPI document: 2.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + +from __future__ import annotations + +import json +import pprint +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict +from typing_extensions import Self + +from stackit.ske.models.expiration_status_kubernetes import ExpirationStatusKubernetes +from stackit.ske.models.expiration_status_nodepool import ExpirationStatusNodepool + + +class ExpiratoaionStatus(BaseModel): + """ + ExpiratoaionStatus + """ # noqa: E501 + + kubernetes: Optional[ExpirationStatusKubernetes] = None + nodepools: Optional[List[ExpirationStatusNodepool]] = None + __properties: ClassVar[List[str]] = ["kubernetes", "nodepools"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ExpiratoaionStatus from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of kubernetes + if self.kubernetes: + _dict["kubernetes"] = self.kubernetes.to_dict() + # override the default output from pydantic by calling `to_dict()` of each item in nodepools (list) + _items = [] + if self.nodepools: + for _item_nodepools in self.nodepools: + if _item_nodepools: + _items.append(_item_nodepools.to_dict()) + _dict["nodepools"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ExpiratoaionStatus from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "kubernetes": ( + ExpirationStatusKubernetes.from_dict(obj["kubernetes"]) + if obj.get("kubernetes") is not None + else None + ), + "nodepools": ( + [ExpirationStatusNodepool.from_dict(_item) for _item in obj["nodepools"]] + if obj.get("nodepools") is not None + else None + ), + } + ) + return _obj