Skip to content

Commit 5739a51

Browse files
Add support for Linode-related endpoints and fields
1 parent 5727f10 commit 5739a51

22 files changed

+2320
-40
lines changed

linode_api4/groups/linode.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import base64
22
import os
3-
from collections.abc import Iterable
4-
from typing import Any, Dict, Optional, Union
3+
from typing import Any, Dict, List, Optional, Union
54

65
from linode_api4.common import load_and_validate_keys
76
from linode_api4.errors import UnexpectedResponseError
87
from linode_api4.groups import Group
98
from linode_api4.objects import (
10-
ConfigInterface,
119
Firewall,
1210
Instance,
1311
InstanceDiskEncryptionType,
@@ -21,8 +19,13 @@
2119
from linode_api4.objects.linode import (
2220
Backup,
2321
InstancePlacementGroupAssignment,
22+
InterfaceGeneration,
23+
NetworkInterface,
2424
_expand_placement_group_assignment,
2525
)
26+
from linode_api4.objects.linode_interfaces import (
27+
LinodeInterfaceOptions,
28+
)
2629
from linode_api4.util import drop_null_keys
2730

2831

@@ -153,6 +156,13 @@ def instance_create(
153156
int,
154157
]
155158
] = None,
159+
interfaces: Optional[
160+
List[
161+
Union[LinodeInterfaceOptions, NetworkInterface, Dict[str, Any]],
162+
]
163+
] = None,
164+
interface_generation: Optional[Union[InterfaceGeneration, str]] = None,
165+
network_helper: Optional[bool] = None,
156166
**kwargs,
157167
):
158168
"""
@@ -293,9 +303,13 @@ def instance_create(
293303
:type disk_encryption: InstanceDiskEncryptionType or str
294304
:param interfaces: An array of Network Interfaces to add to this Linode’s Configuration Profile.
295305
At least one and up to three Interface objects can exist in this array.
296-
:type interfaces: list[ConfigInterface] or list[dict[str, Any]]
306+
:type interfaces: List[LinodeInterfaceOptions], List[NetworkInterface], or List[dict[str, Any]]
297307
:param placement_group: A Placement Group to create this Linode under.
298308
:type placement_group: Union[InstancePlacementGroupAssignment, PlacementGroup, Dict[str, Any], int]
309+
:param interface_generation: The generation of network interfaces this Linode uses.
310+
:type interface_generation: InterfaceGeneration or str
311+
:param network_helper: Whether this instance should have Network Helper enabled.
312+
:type network_helper: bool
299313
300314
:returns: A new Instance object, or a tuple containing the new Instance and
301315
the generated password.
@@ -311,13 +325,6 @@ def instance_create(
311325
ret_pass = Instance.generate_root_password()
312326
kwargs["root_pass"] = ret_pass
313327

314-
interfaces = kwargs.get("interfaces", None)
315-
if interfaces is not None and isinstance(interfaces, Iterable):
316-
kwargs["interfaces"] = [
317-
i._serialize() if isinstance(i, ConfigInterface) else i
318-
for i in interfaces
319-
]
320-
321328
params = {
322329
"type": ltype,
323330
"region": region,
@@ -336,6 +343,9 @@ def instance_create(
336343
if placement_group
337344
else None
338345
),
346+
"interfaces": interfaces,
347+
"interface_generation": interface_generation,
348+
"network_helper": network_helper,
339349
}
340350

341351
params.update(kwargs)

linode_api4/groups/networking.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,64 @@ def ipv6_ranges(self, *filters):
180180
"""
181181
return self.client._get_and_filter(IPv6Range, *filters)
182182

183+
def ipv6_range_allocate(
184+
self,
185+
prefix_length: int,
186+
route_target: Optional[str] = None,
187+
linode: Optional[Union[Instance, int]] = None,
188+
**kwargs,
189+
) -> IPv6Range:
190+
"""
191+
Creates an IPv6 Range and assigns it based on the provided Linode or route target IPv6 SLAAC address.
192+
193+
API Documentation: https://techdocs.akamai.com/linode-api/reference/post-ipv6-range
194+
195+
Create an IPv6 range assigned to a Linode by ID::
196+
197+
range = client.networking.ipv6_range_allocate(64, linode_id=123)
198+
199+
200+
Create an IPv6 range assigned to a Linode by SLAAC::
201+
202+
range = client.networking.ipv6_range_allocate(
203+
64,
204+
route_target=instance.ipv6.split("/")[0]
205+
)
206+
207+
:param prefix_length: The prefix length of the IPv6 range.
208+
:type prefix_length: int
209+
:param route_target: The IPv6 SLAAC address to assign this range to. Required if linode is not specified.
210+
:type route_target: str
211+
:param linode: The ID of the Linode to assign this range to.
212+
The SLAAC address for the provided Linode is used as the range's route_target.
213+
Required if linode is not specified.
214+
:type linode: Instance or int
215+
216+
:returns: The new IPAddress.
217+
:rtype: IPAddress
218+
"""
219+
220+
params = {
221+
"prefix_length": prefix_length,
222+
"route_target": route_target,
223+
"linode_id": linode,
224+
}
225+
226+
params.update(**kwargs)
227+
228+
result = self.client.post(
229+
"/networking/ipv6/ranges",
230+
data=drop_null_keys(_flatten_request_body_recursive(params)),
231+
)
232+
233+
if not "range" in result:
234+
raise UnexpectedResponseError(
235+
"Unexpected response when allocating IPv6 range!", json=result
236+
)
237+
238+
result = IPv6Range(self.client, result["range"], result)
239+
return result
240+
183241
def ipv6_pools(self, *filters):
184242
"""
185243
Returns a list of IPv6 pools on this account.

linode_api4/objects/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from .region import Region
77
from .image import Image
88
from .linode import *
9+
from .linode_interfaces import *
910
from .volume import *
1011
from .domain import *
1112
from .account import *

linode_api4/objects/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ def __setattr__(self, name, value):
239239
"""
240240
Enforces allowing editing of only Properties defined as mutable
241241
"""
242+
242243
if name in type(self).properties.keys():
243244
if not type(self).properties[name].mutable:
244245
raise AttributeError(

0 commit comments

Comments
 (0)