11# -*- coding: utf-8 -*-
22from .baseapi import BaseAPI , POST , DELETE , PUT
3+ import jsonpickle
4+
5+
6+ class _targets (object ):
7+ """
8+ An internal object that both `Sources` and `Destinations` derive from.
9+
10+ Not for direct use by end users.
11+ """
12+ def __init__ (self , ** kwargs ):
13+ self .addresses = []
14+ self .droplet_ids = []
15+ self .load_balancer_uids = []
16+ self .tags = []
17+
18+ for attr in kwargs .keys ():
19+ setattr (self , attr , kwargs [attr ])
20+
21+
22+ class Sources (_targets ):
23+ """
24+ An object holding information about an InboundRule's sources.
25+
26+ Args:
27+ addresses (obj:`list`): An array of strings containing the IPv4
28+ addresses, IPv6 addresses, IPv4 CIDRs, and/or IPv6 CIDRs to which
29+ the Firewall will allow traffic.
30+ droplet_ids (obj:`list`): An array containing the IDs of the Droplets
31+ to which the Firewall will allow traffic.
32+ load_balancer_uids (obj:`list`): An array containing the IDs of the
33+ Load Balancers to which the Firewall will allow traffic.
34+ tags (obj:`list`): An array containing the names of Tags corresponding
35+ to groups of Droplets to which the Firewall will allow traffic.
36+ """
37+ pass
38+
39+
40+ class Destinations (_targets ):
41+ """
42+ An object holding information about an OutboundRule's destinations.
43+
44+ Args:
45+ addresses (obj:`list`): An array of strings containing the IPv4
46+ addresses, IPv6 addresses, IPv4 CIDRs, and/or IPv6 CIDRs to which
47+ the Firewall will allow traffic.
48+ droplet_ids (obj:`list`): An array containing the IDs of the Droplets
49+ to which the Firewall will allow traffic.
50+ load_balancer_uids (obj:`list`): An array containing the IDs of the
51+ Load Balancers to which the Firewall will allow traffic.
52+ tags (obj:`list`): An array containing the names of Tags corresponding
53+ to groups of Droplets to which the Firewall will allow traffic.
54+ """
55+ pass
56+
57+
58+ class InboundRule (object ):
59+ """
60+ An object holding information about a Firewall's inbound rule.
61+
62+ Args:
63+ protocol (str): The type of traffic to be allowed. This may be one
64+ of "tcp", "udp", or "icmp".
65+ port (str): The ports on which traffic will be allowed specified as a
66+ string containing a single port, a range (e.g. "8000-9000"), or
67+ "all" to open all ports for a protocol.
68+ sources (obj): A `Sources` object.
69+ """
70+ def __init__ (self , protocol = "" , ports = "" , sources = "" ):
71+ self .protocol = protocol
72+ self .ports = ports
73+
74+ if isinstance (sources , Sources ):
75+ self .sources = sources
76+ else :
77+ for source in sources :
78+ self .sources = Sources (** sources )
79+
80+
81+ class OutboundRule (object ):
82+ """
83+ An object holding information about a Firewall's outbound rule.
84+
85+ Args:
86+ protocol (str): The type of traffic to be allowed. This may be one
87+ of "tcp", "udp", or "icmp".
88+ port (str): The ports on which traffic will be allowed specified as a
89+ string containing a single port, a range (e.g. "8000-9000"), or
90+ "all" to open all ports for a protocol.
91+ destinations (obj): A `Destinations` object.
92+ """
93+ def __init__ (self , protocol = "" , ports = "" , destinations = "" ):
94+ self .protocol = protocol
95+ self .ports = ports
96+
97+ if isinstance (destinations , Destinations ):
98+ self .destinations = destinations
99+ else :
100+ for destination in destinations :
101+ self .destinations = Destinations (** destinations )
3102
4103
5104class Firewall (BaseAPI ):
105+ """
106+ An object representing an DigitalOcean Firewall.
107+
108+ Attributes accepted at creation time:
109+
110+ Args:
111+ name (str): The Firewall's name.
112+ droplet_ids (obj:`list` of `int`): A list of Droplet IDs to be assigned
113+ to the Firewall.
114+ tags (obj:`list` of `str`): A list Tag names to be assigned to the
115+ Firewall.
116+ inbound_rules (obj:`list`): A list of `InboundRules` objects
117+ outbound_rules (obj:`list`): A list of `OutboundRules` objects
118+
119+ Attributes returned by API:
120+ id (str): A UUID to identify and reference a Firewall.
121+ status (str): A status string indicating the current state of the
122+ Firewall. This can be "waiting", "succeeded", or "failed".
123+ created_at (str): The time at which the Firewall was created.
124+ name (str): The Firewall's name.
125+ pending_changes (obj:`list`): Details exactly which Droplets are having
126+ their security policies updated.
127+ droplet_ids (obj:`list` of `int`): A list of Droplet IDs to be assigned
128+ to the Firewall.
129+ tags (obj:`list` of `str`): A list Tag names to be assigned to the
130+ Firewall.
131+ inbound_rules (obj:`list`): A list of `InboundRules` objects
132+ outbound_rules (obj:`list`): A list of `OutboundRules` objects
133+ """
6134 def __init__ (self , * args , ** kwargs ):
7135 self .id = None
8136 self .status = None
9137 self .created_at = None
10138 self .pending_changes = []
11139 self .name = None
12- self .inbound_rules = None
13- self .outbound_rules = None
140+ self .inbound_rules = []
141+ self .outbound_rules = []
14142 self .droplet_ids = None
15143 self .tags = None
16144
@@ -25,13 +153,45 @@ def get_object(cls, api_token, firewall_id):
25153 firewall .load ()
26154 return firewall
27155
156+ def _set_firewall_attributes (self , data ):
157+ self .id = data ['firewall' ]['id' ]
158+ self .name = data ['firewall' ]['name' ]
159+ self .status = data ['firewall' ]['status' ]
160+ self .created_at = data ['firewall' ]['created_at' ]
161+ self .pending_changes = data ['firewall' ]['pending_changes' ]
162+ self .droplet_ids = data ['firewall' ]['droplet_ids' ]
163+ self .tags = data ['firewall' ]['tags' ]
164+
165+ in_rules = list ()
166+ for rule in data ['firewall' ]['inbound_rules' ]:
167+ in_rules .append (InboundRule (** rule ))
168+ self .inbound_rules = in_rules
169+
170+ out_rules = list ()
171+ for rule in data ['firewall' ]['outbound_rules' ]:
172+ out_rules .append (OutboundRule (** rule ))
173+ self .outbound_rules = out_rules
174+
28175 def load (self ):
29176 data = self .get_data ("firewalls/%s" % self .id )
30- firewall_dict = data ['firewall' ]
177+ if data :
178+ self ._set_firewall_attributes (data )
179+
180+ return self
181+
182+ def create (self , * args , ** kwargs ):
183+ inbound = jsonpickle .encode (self .inbound_rules , unpicklable = False )
184+ outbound = jsonpickle .encode (self .outbound_rules , unpicklable = False )
185+ params = {'name' : self .name ,
186+ 'droplet_ids' : self .droplet_ids ,
187+ 'inbound_rules' : jsonpickle .decode (inbound ),
188+ 'outbound_rules' : jsonpickle .decode (outbound ),
189+ 'tags' : self .tags }
190+
191+ data = self .get_data ('firewalls/' , type = POST , params = params )
31192
32- # Setting the attribute values
33- for attr in firewall_dict .keys ():
34- setattr (self , attr , firewall_dict [attr ])
193+ if data :
194+ self ._set_firewall_attributes (data )
35195
36196 return self
37197
0 commit comments