|
1 | | -from typing import Any, Dict, Optional, Union |
| 1 | +from typing import Any, Dict, List, Optional, Union |
2 | 2 |
|
3 | 3 | from linode_api4.errors import UnexpectedResponseError |
4 | 4 | from linode_api4.groups import Group |
|
17 | 17 | Region, |
18 | 18 | ) |
19 | 19 | from linode_api4.objects.base import _flatten_request_body_recursive |
| 20 | +from linode_api4.objects.networking import ReservedIPAddress, ReservedIPType |
| 21 | +from linode_api4.paginated_list import PaginatedList |
20 | 22 | from linode_api4.util import drop_null_keys |
21 | 23 |
|
22 | 24 |
|
@@ -328,29 +330,66 @@ def ips_assign(self, region, *assignments): |
328 | 330 | }, |
329 | 331 | ) |
330 | 332 |
|
331 | | - def ip_allocate(self, linode, public=True): |
| 333 | + def ip_allocate( |
| 334 | + self, |
| 335 | + linode: Optional[Union[Instance, int]] = None, |
| 336 | + public: bool = True, |
| 337 | + reserved: bool = False, |
| 338 | + region: Optional[Union[Region, str]] = None, |
| 339 | + ) -> IPAddress: |
332 | 340 | """ |
333 | | - Allocates an IP to a Instance you own. Additional IPs must be requested |
334 | | - by opening a support ticket first. |
| 341 | + Allocates an IP to an Instance you own, or reserves a new IP address. |
| 342 | +
|
| 343 | + When ``reserved`` is False (default), ``linode`` is required and an |
| 344 | + ephemeral IP is allocated and assigned to that Instance. |
| 345 | +
|
| 346 | + When ``reserved`` is True, either ``region`` or ``linode`` must be |
| 347 | + provided. Passing only ``region`` creates an unassigned reserved IP. |
| 348 | + Passing ``linode`` (with or without ``region``) creates a reserved IP |
| 349 | + in the Instance's region and assigns it to that Instance. |
335 | 350 |
|
336 | 351 | API Documentation: https://techdocs.akamai.com/linode-api/reference/post-allocate-ip |
337 | 352 |
|
338 | 353 | :param linode: The Instance to allocate the new IP for. |
339 | 354 | :type linode: Instance or int |
340 | 355 | :param public: If True, allocate a public IP address. Defaults to True. |
341 | 356 | :type public: bool |
| 357 | + :param reserved: If True, reserve the new IP address. |
| 358 | + NOTE: Reserved IP feature may not currently be available to all users. |
| 359 | + :type reserved: bool |
| 360 | + :param region: The region for the reserved IP (required when reserved=True and linode is not set). |
| 361 | + NOTE: Reserved IP feature may not currently be available to all users. |
| 362 | + :type region: str or Region |
342 | 363 |
|
343 | 364 | :returns: The new IPAddress. |
344 | 365 | :rtype: IPAddress |
345 | 366 | """ |
346 | | - result = self.client.post( |
347 | | - "/networking/ips/", |
348 | | - data={ |
349 | | - "linode_id": linode.id if isinstance(linode, Base) else linode, |
350 | | - "type": "ipv4", |
351 | | - "public": public, |
352 | | - }, |
353 | | - ) |
| 367 | + if not reserved and linode is None: |
| 368 | + raise ValueError("linode is required when reserved is False.") |
| 369 | + if reserved and linode is None and region is None: |
| 370 | + raise ValueError( |
| 371 | + "Either linode or region must be provided when reserved is True." |
| 372 | + ) |
| 373 | + if not reserved and region is not None: |
| 374 | + raise ValueError("region is only valid when reserved is True.") |
| 375 | + |
| 376 | + data = { |
| 377 | + "type": "ipv4", |
| 378 | + "public": public, |
| 379 | + } |
| 380 | + |
| 381 | + if linode is not None: |
| 382 | + data["linode_id"] = ( |
| 383 | + linode.id if isinstance(linode, Base) else linode |
| 384 | + ) |
| 385 | + |
| 386 | + if reserved: |
| 387 | + data["reserved"] = True |
| 388 | + |
| 389 | + if region is not None: |
| 390 | + data["region"] = region.id if isinstance(region, Base) else region |
| 391 | + |
| 392 | + result = self.client.post("/networking/ips/", data=data) |
354 | 393 |
|
355 | 394 | if not "address" in result: |
356 | 395 | raise UnexpectedResponseError( |
@@ -510,3 +549,76 @@ def delete_vlan(self, vlan, region): |
510 | 549 | return False |
511 | 550 |
|
512 | 551 | return True |
| 552 | + |
| 553 | + def reserved_ips(self, *filters) -> PaginatedList: |
| 554 | + """ |
| 555 | + Returns a list of reserved IPv4 addresses on your account. |
| 556 | +
|
| 557 | + NOTE: Reserved IP feature may not currently be available to all users. |
| 558 | +
|
| 559 | + API Documentation: https://techdocs.akamai.com/linode-api/reference/get-reserved-ips |
| 560 | +
|
| 561 | + :param filters: Any number of filters to apply to this query. |
| 562 | + See :doc:`Filtering Collections</linode_api4/objects/filtering>` |
| 563 | + for more details on filtering. |
| 564 | +
|
| 565 | + :returns: A list of reserved IP addresses on the account. |
| 566 | + :rtype: PaginatedList of ReservedIPAddress |
| 567 | + """ |
| 568 | + return self.client._get_and_filter(ReservedIPAddress, *filters) |
| 569 | + |
| 570 | + def reserved_ip_create( |
| 571 | + self, |
| 572 | + region: Union[Region, str], |
| 573 | + tags: Optional[List[str]] = None, |
| 574 | + **kwargs, |
| 575 | + ) -> ReservedIPAddress: |
| 576 | + """ |
| 577 | + Reserves a new IPv4 address in the given region. |
| 578 | +
|
| 579 | + NOTE: Reserved IP feature may not currently be available to all users. |
| 580 | +
|
| 581 | + API Documentation: https://techdocs.akamai.com/linode-api/reference/post-reserved-ip |
| 582 | +
|
| 583 | + :param region: The region in which to reserve the IP. |
| 584 | + :type region: str or Region |
| 585 | + :param tags: Tags to apply to the reserved IP. |
| 586 | + :type tags: list of str |
| 587 | +
|
| 588 | + :returns: The new reserved IP address. |
| 589 | + :rtype: ReservedIPAddress |
| 590 | + """ |
| 591 | + params = { |
| 592 | + "region": region.id if isinstance(region, Region) else region, |
| 593 | + } |
| 594 | + if tags is not None: |
| 595 | + params["tags"] = tags |
| 596 | + params.update(kwargs) |
| 597 | + |
| 598 | + result = self.client.post("/networking/reserved/ips", data=params) |
| 599 | + |
| 600 | + if "address" not in result: |
| 601 | + raise UnexpectedResponseError( |
| 602 | + "Unexpected response when reserving IP address!", json=result |
| 603 | + ) |
| 604 | + |
| 605 | + return ReservedIPAddress(self.client, result["address"], result) |
| 606 | + |
| 607 | + def reserved_ip_types(self, *filters) -> PaginatedList: |
| 608 | + """ |
| 609 | + Returns a list of reserved IP types with pricing information. |
| 610 | +
|
| 611 | + NOTE: Reserved IP feature may not currently be available to all users. |
| 612 | +
|
| 613 | + API Documentation: https://techdocs.akamai.com/linode-api/reference/get-reserved-ip-types |
| 614 | +
|
| 615 | + :param filters: Any number of filters to apply to this query. |
| 616 | + See :doc:`Filtering Collections</linode_api4/objects/filtering>` |
| 617 | + for more details on filtering. |
| 618 | +
|
| 619 | + :returns: A list of reserved IP types. |
| 620 | + :rtype: PaginatedList of ReservedIPType |
| 621 | + """ |
| 622 | + return self.client._get_and_filter( |
| 623 | + ReservedIPType, *filters, endpoint="/networking/reserved/ips/types" |
| 624 | + ) |
0 commit comments