Skip to content

Commit 2278ebf

Browse files
authored
Feature: Add vSwitch support to add_subnet on NetworksClient (#106)
Signed-off-by: Lukas Kämmerling <lukas.kaemmerling@hetzner-cloud.de>
1 parent f399cf1 commit 2278ebf

4 files changed

Lines changed: 39 additions & 10 deletions

File tree

CHANGELOG.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ master (XXXX-XX-XX)
66
-------------------
77

88
* Feature: Add `include_deprecated` filter to `get_list` and `get_all` on `ImagesClient`
9+
* Feature: Add vSwitch support to `add_subnet` on `NetworksClient`
10+
* Feature: Add subnet type constants to `NetworkSubnet` domain (`NetworkSubnet.TYPE_CLOUD`, `NetworkSubnet.TYPE_VSWITCH`)
911

1012
v1.9.1 (2020-08-11)
1113
--------------------

hcloud/networks/client.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,8 @@ def add_subnet(self, network, subnet):
351351
}
352352
if subnet.ip_range is not None:
353353
data["ip_range"] = subnet.ip_range
354+
if subnet.vswitch_id is not None:
355+
data["vswitch_id"] = subnet.vswitch_id
354356

355357
response = self._client.request(
356358
url="/networks/{network_id}/actions/add_subnet".format(network_id=network.id),

hcloud/networks/domain.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,23 @@ class NetworkSubnet(BaseDomain):
7171
Name of network zone.
7272
:param gateway: str
7373
Gateway for the route.
74+
:param vswitch_id: int
75+
ID of the vSwitch.
7476
"""
75-
__slots__ = ("type", "ip_range", "network_zone", "gateway")
76-
77-
def __init__(self, ip_range, type=None, network_zone=None, gateway=None):
77+
TYPE_SERVER = "server"
78+
"""Subnet Type server, deprecated, use TYPE_CLOUD instead"""
79+
TYPE_CLOUD = "cloud"
80+
"""Subnet Type cloud"""
81+
TYPE_VSWITCH = "vswitch"
82+
"""Subnet Type vSwitch"""
83+
__slots__ = ("type", "ip_range", "network_zone", "gateway", "vswitch_id")
84+
85+
def __init__(self, ip_range, type=None, network_zone=None, gateway=None, vswitch_id=None):
7886
self.type = type
7987
self.ip_range = ip_range
8088
self.network_zone = network_zone
8189
self.gateway = gateway
90+
self.vswitch_id = vswitch_id
8291

8392

8493
class NetworkRoute(BaseDomain):

tests/unit/networks/test_client.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def test_bound_network_init(self, network_response):
3333

3434
assert len(bound_network.subnets) == 2
3535
assert isinstance(bound_network.subnets[0], NetworkSubnet)
36-
assert bound_network.subnets[0].type == "cloud"
36+
assert bound_network.subnets[0].type == NetworkSubnet.TYPE_CLOUD
3737
assert bound_network.subnets[0].ip_range == "10.0.1.0/24"
3838
assert bound_network.subnets[0].network_zone == "eu-central"
3939
assert bound_network.subnets[0].gateway == "10.0.0.1"
@@ -80,10 +80,10 @@ def test_change_protection(self, hetzner_client, bound_network, generic_action):
8080

8181
def test_add_subnet(self, hetzner_client, bound_network, generic_action):
8282
hetzner_client.request.return_value = generic_action
83-
subnet = NetworkSubnet(type="cloud", ip_range="10.0.1.0/24", network_zone="eu-central")
83+
subnet = NetworkSubnet(type=NetworkSubnet.TYPE_CLOUD, ip_range="10.0.1.0/24", network_zone="eu-central")
8484
action = bound_network.add_subnet(subnet)
8585
hetzner_client.request.assert_called_with(url="/networks/14/actions/add_subnet", method="POST",
86-
json={"type": "cloud", "ip_range": "10.0.1.0/24",
86+
json={"type": NetworkSubnet.TYPE_CLOUD, "ip_range": "10.0.1.0/24",
8787
"network_zone": "eu-central"})
8888

8989
assert action.id == 1
@@ -137,7 +137,11 @@ def networks_client(self):
137137

138138
@pytest.fixture()
139139
def network_subnet(self):
140-
return NetworkSubnet(type="cloud", ip_range="10.0.1.0/24", network_zone="eu-central")
140+
return NetworkSubnet(type=NetworkSubnet.TYPE_CLOUD, ip_range="10.0.1.0/24", network_zone="eu-central")
141+
142+
@pytest.fixture()
143+
def network_vswitch_subnet(self):
144+
return NetworkSubnet(type=NetworkSubnet.TYPE_VSWITCH, ip_range="10.0.1.0/24", network_zone="eu-central", vswitch_id=123)
141145

142146
@pytest.fixture()
143147
def network_route(self):
@@ -244,7 +248,7 @@ def test_create_with_subnet(self, networks_client, network_subnet, network_creat
244248
'ip_range': "10.0.0.0/8",
245249
'subnets': [
246250
{
247-
'type': "cloud",
251+
'type': NetworkSubnet.TYPE_CLOUD,
248252
'ip_range': "10.0.1.0/24",
249253
'network_zone': "eu-central"
250254
}
@@ -291,7 +295,7 @@ def test_create_with_route_and_subnet(self, networks_client, network_subnet, net
291295
'ip_range': "10.0.0.0/8",
292296
'subnets': [
293297
{
294-
'type': "cloud",
298+
'type': NetworkSubnet.TYPE_CLOUD,
295299
'ip_range': "10.0.1.0/24",
296300
'network_zone': "eu-central"
297301
}
@@ -353,12 +357,24 @@ def test_add_subnet(self, networks_client, network, generic_action, network_subn
353357

354358
action = networks_client.add_subnet(network, network_subnet)
355359
networks_client._client.request.assert_called_with(url="/networks/1/actions/add_subnet", method="POST",
356-
json={"type": "cloud", "ip_range": "10.0.1.0/24",
360+
json={"type": NetworkSubnet.TYPE_CLOUD, "ip_range": "10.0.1.0/24",
357361
"network_zone": "eu-central"})
358362

359363
assert action.id == 1
360364
assert action.progress == 0
361365

366+
@pytest.mark.parametrize("network", [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=1))])
367+
def test_add_subnet_vswitch(self, networks_client, network, generic_action, network_vswitch_subnet):
368+
networks_client._client.request.return_value = generic_action
369+
370+
action = networks_client.add_subnet(network, network_vswitch_subnet)
371+
networks_client._client.request.assert_called_with(url="/networks/1/actions/add_subnet", method="POST",
372+
json={"type": NetworkSubnet.TYPE_VSWITCH, "ip_range": "10.0.1.0/24",
373+
"network_zone": "eu-central", "vswitch_id": 123})
374+
375+
assert action.id == 1
376+
assert action.progress == 0
377+
362378
@pytest.mark.parametrize("network", [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=1))])
363379
def test_delete_subnet(self, networks_client, network, generic_action, network_subnet):
364380
networks_client._client.request.return_value = generic_action

0 commit comments

Comments
 (0)