Skip to content

Commit cfb2d33

Browse files
WIP
1 parent 70169d7 commit cfb2d33

File tree

10 files changed

+149
-3
lines changed

10 files changed

+149
-3
lines changed

linode_api4/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# isort: skip_file
22
from linode_api4.objects import *
3+
from linode_api4.paths import *
34
from linode_api4.errors import ApiError, UnexpectedResponseError
45
from linode_api4.linode_client import LinodeClient
56
from linode_api4.login_client import LinodeLoginClient, OAuthScopes

linode_api4/groups/lke.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, Dict, Union
1+
from typing import Any, Dict, Optional, Union
22

33
from linode_api4.errors import UnexpectedResponseError
44
from linode_api4.groups import Group
@@ -11,6 +11,7 @@
1111
drop_null_keys,
1212
)
1313
from linode_api4.objects.base import _flatten_request_body_recursive
14+
from linode_api4.paths import LKETier
1415

1516

1617
class LKEGroup(Group):
@@ -67,6 +68,7 @@ def cluster_create(
6768
LKEClusterControlPlaneOptions, Dict[str, Any]
6869
] = None,
6970
apl_enabled: bool = False,
71+
tier: Optional[str] = None,
7072
**kwargs,
7173
):
7274
"""
@@ -104,9 +106,13 @@ def cluster_create(
104106
:param control_plane: The control plane configuration of this LKE cluster.
105107
:type control_plane: Dict[str, Any] or LKEClusterControlPlaneRequest
106108
:param apl_enabled: Whether this cluster should use APL.
107-
NOTE: This endpoint is in beta and may only
109+
NOTE: This field is in beta and may only
108110
function if base_url is set to `https://api.linode.com/v4beta`.
109111
:type apl_enabled: bool
112+
:param tier: The tier of LKE cluster to create.
113+
NOTE: This field is in beta and may only
114+
function if base_url is set to `https://api.linode.com/v4beta`.
115+
:type tier: str
110116
:param kwargs: Any other arguments to pass along to the API. See the API
111117
docs for possible values.
112118
@@ -122,6 +128,7 @@ def cluster_create(
122128
node_pools if isinstance(node_pools, list) else [node_pools]
123129
),
124130
"control_plane": control_plane,
131+
"tier": tier,
125132
}
126133
params.update(kwargs)
127134

@@ -183,3 +190,16 @@ def types(self, *filters):
183190
return self.client._get_and_filter(
184191
LKEType, *filters, endpoint="/lke/types"
185192
)
193+
194+
def tier(self, id: str) -> LKETier:
195+
"""
196+
Returns an object representing the LKE tier API path.
197+
198+
:param id: The ID of the tier.
199+
:type id: str
200+
201+
:returns: An object representing the LKE tier API path.
202+
:rtype: LKETier
203+
"""
204+
205+
return LKETier(self.client, id)

linode_api4/objects/lke.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,24 @@ class KubeVersion(Base):
4949
}
5050

5151

52+
class TieredKubeVersion(DerivedBase):
53+
"""
54+
A TieredKubeVersion is a version of Kubernetes that is specific to a certain LKE tier.
55+
56+
API Documentation: https://techdocs.akamai.com/linode-api/reference/get-lke-version
57+
"""
58+
59+
api_endpoint = "/lke/tiers/{tier}/versions/{id}"
60+
parent_id_name = "tier"
61+
id_attribute = "id"
62+
derived_url_path = "versions"
63+
64+
properties = {
65+
"id": Property(identifier=True),
66+
"tier": Property(identifier=True),
67+
}
68+
69+
5270
@dataclass
5371
class LKENodePoolTaint(JSONObject):
5472
"""
@@ -255,6 +273,7 @@ class LKECluster(Base):
255273
"pools": Property(derived_class=LKENodePool),
256274
"control_plane": Property(mutable=True),
257275
"apl_enabled": Property(),
276+
"tier": Property(),
258277
}
259278

260279
def invalidate(self):

linode_api4/paths/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# isort: skip_file
2+
from .api_path import *
3+
from .lke import *

linode_api4/paths/api_path.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from abc import ABC, abstractmethod
2+
3+
4+
class ApiPath(ABC):
5+
"""
6+
ApiPath is an abstract class that represents a single static API path.
7+
"""
8+
9+
@property
10+
@abstractmethod
11+
def endpoint(self):
12+
pass
13+
14+
def __repr__(self):
15+
return f"{type(self).__name__}: {self.endpoint}"

linode_api4/paths/lke.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from linode_api4.objects.lke import TieredKubeVersion
2+
from linode_api4.paths.api_path import ApiPath
3+
4+
5+
class LKETier(ApiPath):
6+
"""
7+
The API path for a single LKE tier.
8+
"""
9+
10+
def __init__(
11+
self,
12+
client: "LinodeClient",
13+
id: str,
14+
):
15+
self.client = client
16+
self.id = id
17+
18+
@property
19+
def endpoint(self) -> str:
20+
return f"/lke/tiers/{self.id}"
21+
22+
def versions(self, *filters):
23+
"""
24+
Returns a paginated list of versions for this tier matching the given filters.
25+
26+
API Documentation: Not Yet Available
27+
28+
:param filters: Any number of filters to apply to this query.
29+
See :doc:`Filtering Collections</linode_api4/objects/filtering>`
30+
for more details on filtering.
31+
32+
:returns: A paginated list of kube versions that match the query.
33+
:rtype: PaginatedList of TieredKubeVersion
34+
"""
35+
36+
return self.client._get_and_filter(
37+
TieredKubeVersion,
38+
endpoint=f"{self.endpoint}/versions",
39+
*filters,
40+
)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"data": [
3+
{
4+
"id": "1.32",
5+
"tier": "standard"
6+
},
7+
{
8+
"id": "1.31",
9+
"tier": "standard"
10+
},
11+
{
12+
"id": "1.30",
13+
"tier": "standard"
14+
}
15+
],
16+
"page": 1,
17+
"pages": 1,
18+
"results": 3
19+
}

test/unit/objects/lke_test.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from test.unit.base import ClientBaseCase
33
from unittest.mock import MagicMock
44

5-
from linode_api4 import InstanceDiskEncryptionType
5+
from linode_api4 import InstanceDiskEncryptionType, TieredKubeVersion
66
from linode_api4.objects import (
77
LKECluster,
88
LKEClusterControlPlaneACLAddressesOptions,
@@ -536,3 +536,13 @@ def test_cluster_update_acl_null_addresses(self):
536536
# Addresses should not be included in the API request if it's null
537537
# See: TPT-3489
538538
assert m.call_data == {"acl": {"enabled": True}}
539+
540+
def test_lke_tiered_version(self):
541+
version = TieredKubeVersion(self.client, "1.32", "standard")
542+
543+
assert version.id == "1.32"
544+
545+
# Ensure the version is properly refreshed
546+
version.invalidate()
547+
548+
assert version.id == "1.32"

test/unit/paths/__init__.py

Whitespace-only changes.

test/unit/paths/tier_test.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from test.unit.base import ClientBaseCase
2+
3+
4+
5+
class LKETierPathTest(ClientBaseCase):
6+
"""
7+
Tests methods of the LKETierPath
8+
"""
9+
10+
def test_list_versions(self):
11+
"""
12+
Tests that LKE versions can be listed for a given tier.
13+
"""
14+
15+
tiers = self.client.lke.tier("standard").versions()
16+
17+
assert tiers[0].id == "1.32"
18+
assert tiers[1].id == "1.31"
19+
assert tiers[2].id == "1.30"

0 commit comments

Comments
 (0)