Skip to content

Commit 8db217a

Browse files
authored
Firewall: Add label selector resource support (#137)
Signed-off-by: Lukas Kämmerling <lukas.kaemmerling@hetzner-cloud.de>
1 parent 0172cf4 commit 8db217a

4 files changed

Lines changed: 53 additions & 5 deletions

File tree

hcloud/firewalls/client.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
from hcloud.core.client import BoundModelBase, ClientEntityBase, GetEntityByNameMixin
44
from hcloud.core.domain import add_meta_to_result
55

6-
from hcloud.firewalls.domain import Firewall, CreateFirewallResponse, FirewallRule, FirewallResource
6+
from hcloud.firewalls.domain import Firewall, CreateFirewallResponse, FirewallRule, FirewallResource, \
7+
FirewallResourceLabelSelector
78

89

910
class BoundFirewall(BoundModelBase):
@@ -22,9 +23,11 @@ def __init__(self, client, data, complete=True):
2223
from hcloud.servers.client import BoundServer
2324
ats = []
2425
for a in applied_to:
25-
if a["type"] == "server":
26+
if a["type"] == FirewallResource.TYPE_SERVER:
2627
ats.append(FirewallResource(type=a["type"], server=BoundServer(client._client.servers, a["server"],
2728
complete=False)))
29+
elif a["type"] == FirewallResource.TYPE_LABEL_SELECTOR:
30+
ats.append(FirewallResource(type=a["type"], label_selector=FirewallResourceLabelSelector(selector=a['label_selector']['selector'])))
2831
data['applied_to'] = ats
2932

3033
super(BoundFirewall, self).__init__(client, data, complete)

hcloud/firewalls/domain.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,32 +119,53 @@ class FirewallResource:
119119
Type of resource referenced
120120
:param server: Optional[Server]
121121
Server the Firewall is applied to
122+
:param label_selector: Optional[FirewallResourceLabelSelector]
123+
Label Selector for Servers the Firewall should be applied to
122124
"""
123125
__slots__ = (
124126
"type",
125127
"server",
128+
"label_selector"
126129
)
127130

128131
TYPE_SERVER = "server"
129132
"""Firewall Used By Type Server"""
133+
TYPE_LABEL_SELECTOR = "label_selector"
134+
"""Firewall Used By Type label_selector"""
130135

131136
def __init__(
132137
self,
133138
type, # type: str
134139
server=None, # type: Optional[Server]
140+
label_selector=None, # type: Optional[FirewallResourceLabelSelector]
141+
135142
):
136143
self.type = type
137144
self.server = server
145+
self.label_selector = label_selector
138146

139147
def to_payload(self):
140148
payload = {
141149
"type": self.type,
142150
}
143151
if self.server is not None:
144152
payload.update({"server": {"id": self.server.id}})
153+
154+
if self.label_selector is not None:
155+
payload.update({"label_selector": {"selector": self.label_selector.selector}})
145156
return payload
146157

147158

159+
class FirewallResourceLabelSelector(BaseDomain):
160+
"""FirewallResourceLabelSelector Domain
161+
162+
:param selector: str Target label selector
163+
"""
164+
165+
def __init__(self, selector=None):
166+
self.selector = selector
167+
168+
148169
class CreateFirewallResponse(BaseDomain):
149170
"""Create Firewall Response Domain
150171

tests/unit/firewalls/conftest.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ def response_create_firewall():
3939
"id": 42
4040
},
4141
"type": "server"
42+
},
43+
{
44+
"type": "label_selector",
45+
"label_selector": {
46+
"selector": "key==value"
47+
}
4248
}
4349
]
4450
},
@@ -125,6 +131,12 @@ def firewall_response():
125131
"id": 42
126132
},
127133
"type": "server"
134+
},
135+
{
136+
"type": "label_selector",
137+
"label_selector": {
138+
"selector": "key==value"
139+
}
128140
}
129141
]
130142
}

tests/unit/firewalls/test_client.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from hcloud.firewalls.client import FirewallsClient, BoundFirewall
55
from hcloud.actions.client import BoundAction
6-
from hcloud.firewalls.domain import Firewall, FirewallRule, FirewallResource
6+
from hcloud.firewalls.domain import Firewall, FirewallRule, FirewallResource, FirewallResourceLabelSelector
77
from hcloud.servers.domain import Server
88

99

@@ -26,9 +26,11 @@ def test_bound_firewall_init(self, firewall_response):
2626
assert len(bound_firewall.rules) == 2
2727

2828
assert isinstance(bound_firewall.applied_to, list)
29-
assert len(bound_firewall.applied_to) == 1
29+
assert len(bound_firewall.applied_to) == 2
3030
assert bound_firewall.applied_to[0].server.id == 42
3131
assert bound_firewall.applied_to[0].type == "server"
32+
assert bound_firewall.applied_to[1].label_selector.selector == "key==value"
33+
assert bound_firewall.applied_to[1].type == "label_selector"
3234

3335
firewall_in_rule = bound_firewall.rules[0]
3436
assert isinstance(firewall_in_rule, FirewallRule)
@@ -276,7 +278,10 @@ def test_create(self, firewalls_client, response_create_firewall):
276278
"Corporate Intranet Protection",
277279
rules=[FirewallRule(direction=FirewallRule.DIRECTION_IN, protocol=FirewallRule.PROTOCOL_ICMP,
278280
source_ips=["0.0.0.0/0"])],
279-
resources=[FirewallResource(type=FirewallResource.TYPE_SERVER, server=Server(id=4711))]
281+
resources=[
282+
FirewallResource(type=FirewallResource.TYPE_SERVER, server=Server(id=4711)),
283+
FirewallResource(type=FirewallResource.TYPE_LABEL_SELECTOR, label_selector=FirewallResourceLabelSelector(selector="key==value"))
284+
]
280285
)
281286
firewalls_client._client.request.assert_called_with(
282287
url="/firewalls",
@@ -298,6 +303,12 @@ def test_create(self, firewalls_client, response_create_firewall):
298303
"server": {
299304
"id": 4711
300305
}
306+
},
307+
{
308+
"type": "label_selector",
309+
"label_selector": {
310+
"selector": "key==value"
311+
}
301312
}
302313
],
303314
}
@@ -309,6 +320,7 @@ def test_create(self, firewalls_client, response_create_firewall):
309320
assert bound_firewall._client is firewalls_client
310321
assert bound_firewall.id == 38
311322
assert bound_firewall.name == "Corporate Intranet Protection"
323+
assert len(bound_firewall.applied_to) == 2
312324

313325
assert len(actions) == 2
314326

0 commit comments

Comments
 (0)