1+ from typing import Any , Dict , Optional , Union
2+
13from linode_api4 .errors import UnexpectedResponseError
24from linode_api4 .groups import Group
35from linode_api4 .objects import (
46 VLAN ,
57 Base ,
68 Firewall ,
9+ FirewallCreateDevicesOptions ,
10+ FirewallSettings ,
11+ FirewallTemplate ,
712 Instance ,
813 IPAddress ,
914 IPv6Pool ,
1015 IPv6Range ,
1116 NetworkTransferPrice ,
1217 Region ,
1318)
19+ from linode_api4 .objects .base import _flatten_request_body_recursive
20+ from linode_api4 .util import drop_null_keys
1421
1522
1623class NetworkingGroup (Group ):
@@ -33,7 +40,15 @@ def firewalls(self, *filters):
3340 """
3441 return self .client ._get_and_filter (Firewall , * filters )
3542
36- def firewall_create (self , label , rules , ** kwargs ):
43+ def firewall_create (
44+ self ,
45+ label : str ,
46+ rules : Dict [str , Any ],
47+ devices : Optional [
48+ Union [FirewallCreateDevicesOptions , Dict [str , Any ]]
49+ ] = None ,
50+ ** kwargs ,
51+ ):
3752 """
3853 Creates a new Firewall, either in the given Region or
3954 attached to the given Instance.
@@ -44,6 +59,8 @@ def firewall_create(self, label, rules, **kwargs):
4459 :type label: str
4560 :param rules: The rules to apply to the new Firewall. For more information on Firewall rules, see our `Firewalls Documentation`_.
4661 :type rules: dict
62+ :param devices: Represents devices to create created alongside a Linode Firewall.
63+ :type devices: Optional[Union[FirewallCreateDevicesOptions, Dict[str, Any]]]
4764
4865 :returns: The new Firewall.
4966 :rtype: Firewall
@@ -81,10 +98,14 @@ def firewall_create(self, label, rules, **kwargs):
8198 params = {
8299 "label" : label ,
83100 "rules" : rules ,
101+ "devices" : devices ,
84102 }
85103 params .update (kwargs )
86104
87- result = self .client .post ("/networking/firewalls" , data = params )
105+ result = self .client .post (
106+ "/networking/firewalls" ,
107+ data = drop_null_keys (_flatten_request_body_recursive (params )),
108+ )
88109
89110 if not "id" in result :
90111 raise UnexpectedResponseError (
@@ -94,6 +115,43 @@ def firewall_create(self, label, rules, **kwargs):
94115 f = Firewall (self .client , result ["id" ], result )
95116 return f
96117
118+ def firewall_templates (self , * filters ):
119+ """
120+ Returns a list of Firewall Templates available to the current user.
121+
122+ API Documentation: https://techdocs.akamai.com/linode-api/reference/get-firewall-templates
123+
124+ NOTE: This feature may not currently be available to all users.
125+
126+ :param filters: Any number of filters to apply to this query.
127+ See :doc:`Filtering Collections</linode_api4/objects/filtering>`
128+ for more details on filtering.
129+
130+ :returns: A list of Firewall Templates available to the current user.
131+ :rtype: PaginatedList of FirewallTemplate
132+ """
133+ return self .client ._get_and_filter (FirewallTemplate , * filters )
134+
135+ def firewall_settings (self ) -> FirewallSettings :
136+ """
137+ Returns an object representing the Linode Firewall settings for the current user.
138+
139+ API Documentation: https://techdocs.akamai.com/linode-api/reference/get-firewall-settings
140+
141+ NOTE: This feature may not currently be available to all users.
142+ :returns: An object representing the Linode Firewall settings for the current user.
143+ :rtype: FirewallSettings
144+ """
145+ result = self .client .get ("/networking/firewalls/settings" )
146+
147+ if "default_firewall_ids" not in result :
148+ raise UnexpectedResponseError (
149+ "Unexpected response when getting firewall settings!" ,
150+ json = result ,
151+ )
152+
153+ return FirewallSettings (self .client , None , result )
154+
97155 def ips (self , * filters ):
98156 """
99157 Returns a list of IP addresses on this account, excluding private addresses.
@@ -124,6 +182,64 @@ def ipv6_ranges(self, *filters):
124182 """
125183 return self .client ._get_and_filter (IPv6Range , * filters )
126184
185+ def ipv6_range_allocate (
186+ self ,
187+ prefix_length : int ,
188+ route_target : Optional [str ] = None ,
189+ linode : Optional [Union [Instance , int ]] = None ,
190+ ** kwargs ,
191+ ) -> IPv6Range :
192+ """
193+ Creates an IPv6 Range and assigns it based on the provided Linode or route target IPv6 SLAAC address.
194+
195+ API Documentation: https://techdocs.akamai.com/linode-api/reference/post-ipv6-range
196+
197+ Create an IPv6 range assigned to a Linode by ID::
198+
199+ range = client.networking.ipv6_range_allocate(64, linode_id=123)
200+
201+
202+ Create an IPv6 range assigned to a Linode by SLAAC::
203+
204+ range = client.networking.ipv6_range_allocate(
205+ 64,
206+ route_target=instance.ipv6.split("/")[0]
207+ )
208+
209+ :param prefix_length: The prefix length of the IPv6 range.
210+ :type prefix_length: int
211+ :param route_target: The IPv6 SLAAC address to assign this range to. Required if linode is not specified.
212+ :type route_target: str
213+ :param linode: The ID of the Linode to assign this range to.
214+ The SLAAC address for the provided Linode is used as the range's route_target.
215+ Required if linode is not specified.
216+ :type linode: Instance or int
217+
218+ :returns: The new IPAddress.
219+ :rtype: IPAddress
220+ """
221+
222+ params = {
223+ "prefix_length" : prefix_length ,
224+ "route_target" : route_target ,
225+ "linode_id" : linode ,
226+ }
227+
228+ params .update (** kwargs )
229+
230+ result = self .client .post (
231+ "/networking/ipv6/ranges" ,
232+ data = drop_null_keys (_flatten_request_body_recursive (params )),
233+ )
234+
235+ if not "range" in result :
236+ raise UnexpectedResponseError (
237+ "Unexpected response when allocating IPv6 range!" , json = result
238+ )
239+
240+ result = IPv6Range (self .client , result ["range" ], result )
241+ return result
242+
127243 def ipv6_pools (self , * filters ):
128244 """
129245 Returns a list of IPv6 pools on this account.
0 commit comments