Skip to content

Commit ab5f1cc

Browse files
authored
Add support for names on Floating IPs (#59)
1 parent 2ddb78e commit ab5f1cc

File tree

6 files changed

+71
-18
lines changed

6 files changed

+71
-18
lines changed

CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ master (XXXX-XX-XX)
66
-------------------
77

88
* Fix: ServersClient.create_image fails when specifying the `labels`
9+
* Feature: Add support for `name` on Floating IPs
910

1011
1.4.1 (2019-08-19)
1112
------------------

hcloud/floating_ips/client.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,19 @@ def get_actions(self, status=None, sort=None):
5151
"""
5252
return self._client.get_actions(self, status, sort)
5353

54-
def update(self, description=None, labels=None):
55-
# type: (Optional[str], Optional[Dict[str, str]]) -> BoundFloatingIP
54+
def update(self, description=None, labels=None, name=None):
55+
# type: (Optional[str], Optional[Dict[str, str]], Optional[str]) -> BoundFloatingIP
5656
"""Updates the description or labels of a Floating IP.
5757
5858
:param description: str (optional)
5959
New Description to set
6060
:param labels: Dict[str, str] (optional)
6161
User-defined labels (key-value pairs)
62+
:param name: str (optional)
63+
New Name to set
6264
:return: :class:`BoundFloatingIP <hcloud.floating_ips.client.BoundFloatingIP>`
6365
"""
64-
return self._client.update(self, description, labels)
66+
return self._client.update(self, description, labels, name)
6567

6668
def delete(self):
6769
# type: () -> bool
@@ -225,6 +227,7 @@ def create(self,
225227
labels=None, # type: Optional[str]
226228
home_location=None, # type: Optional[Location]
227229
server=None, # type: Optional[Server]
230+
name=None, # type: Optinal[str]
228231
):
229232
# type: (...) -> CreateFloatingIPResponse
230233
"""Creates a new Floating IP assigned to a server.
@@ -238,6 +241,7 @@ def create(self,
238241
Home location (routing is optimized for that location). Only optional if server argument is passed.
239242
:param server: :class:`BoundServer <hcloud.servers.client.BoundServer>` or :class:`Server <hcloud.servers.domain.Server>`
240243
Server to assign the Floating IP to
244+
:param name: str (optional)
241245
:return: :class:`CreateFloatingIPResponse <hcloud.floating_ips.domain.CreateFloatingIPResponse>`
242246
"""
243247

@@ -252,6 +256,8 @@ def create(self,
252256
data['home_location'] = home_location.id_or_name
253257
if server is not None:
254258
data['server'] = server.id
259+
if name is not None:
260+
data['name'] = name
255261

256262
response = self._client.request(url="/floating_ips", json=data, method="POST")
257263

@@ -265,22 +271,26 @@ def create(self,
265271
)
266272
return result
267273

268-
def update(self, floating_ip, description=None, labels=None):
269-
# type: (FloatingIP, Optional[str], Optional[Dict[str, str]]) -> BoundFloatingIP
274+
def update(self, floating_ip, description=None, labels=None, name=None):
275+
# type: (FloatingIP, Optional[str], Optional[Dict[str, str]], Optional[str]) -> BoundFloatingIP
270276
"""Updates the description or labels of a Floating IP.
271277
272278
:param floating_ip: :class:`BoundFloatingIP <hcloud.floating_ips.client.BoundFloatingIP>` or :class:`FloatingIP <hcloud.floating_ips.domain.FloatingIP>`
273279
:param description: str (optional)
274280
New Description to set
275281
:param labels: Dict[str, str] (optional)
276282
User-defined labels (key-value pairs)
283+
:param name: str (optional)
284+
New name to set
277285
:return: :class:`BoundFloatingIP <hcloud.floating_ips.client.BoundFloatingIP>`
278286
"""
279287
data = {}
280288
if description is not None:
281289
data['description'] = description
282290
if labels is not None:
283291
data['labels'] = labels
292+
if name is not None:
293+
data['name'] = name
284294

285295
response = self._client.request(url="/floating_ips/{floating_ip_id}".format(floating_ip_id=floating_ip.id),
286296
method="PUT", json=data)

hcloud/floating_ips/domain.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ class FloatingIP(BaseDomain):
2929
User-defined labels (key-value pairs)
3030
:param created: datetime
3131
Point in time when the Floating IP was created
32+
:param name: str
33+
Name of the Floating IP
3234
"""
3335
__slots__ = (
3436
"id",
@@ -40,7 +42,8 @@ class FloatingIP(BaseDomain):
4042
"home_location",
4143
"blocked",
4244
"protection",
43-
"labels"
45+
"labels",
46+
"name"
4447
)
4548
created = ISODateTime()
4649
supported_fields = ("created",)
@@ -57,7 +60,8 @@ def __init__(
5760
blocked=None,
5861
protection=None,
5962
labels=None,
60-
created=None
63+
created=None,
64+
name=None
6165
):
6266
self.id = id
6367
self.type = type
@@ -70,6 +74,7 @@ def __init__(
7074
self.protection = protection
7175
self.labels = labels
7276
self.created = created
77+
self.name = name
7378

7479

7580
class CreateFloatingIPResponse(BaseDomain):

tests/integration/floating_ips/test_floating_ips.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,30 @@ def test_get_actions(self, bound_floating_ip):
2121
assert actions[0].command == "assign_floating_ip"
2222

2323
def test_update(self, bound_floating_ip):
24-
floating_ip = bound_floating_ip.update(description="New description", labels={})
24+
floating_ip = bound_floating_ip.update(description="New description", labels={}, name="Web Frontend")
2525
assert floating_ip.id == 4711
2626
assert floating_ip.description == "New description"
27+
assert floating_ip.name == "Web Frontend"
2728

2829
def test_delete(self, bound_floating_ip):
2930
delete_success = bound_floating_ip.delete()
3031
assert delete_success is True
3132

3233
@pytest.mark.parametrize("server",
3334
(Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))))
34-
def test_assign(self, hetzner_client, bound_floating_ip, server):
35+
def test_assign(self, bound_floating_ip, server):
3536
action = bound_floating_ip.assign(server)
3637
assert action.id == 13
3738
assert action.progress == 0
3839
assert action.command == "assign_floating_ip"
3940

40-
def test_unassign(self, hetzner_client, bound_floating_ip):
41+
def test_unassign(self, bound_floating_ip):
4142
action = bound_floating_ip.unassign()
4243
assert action.id == 13
4344
assert action.progress == 0
4445
assert action.command == "unassign_floating_ip"
4546

46-
def test_change_dns_ptr(self, hetzner_client, bound_floating_ip):
47+
def test_change_dns_ptr(self, bound_floating_ip):
4748
action = bound_floating_ip.change_dns_ptr("1.2.3.4", "server02.example.com")
4849
assert action.id == 13
4950
assert action.progress == 0
@@ -71,7 +72,8 @@ def test_create(self, hetzner_client, server):
7172
type="ipv4",
7273
description="Web Frontend",
7374
# home_location=Location(description="fsn1"),
74-
server=server
75+
server=server,
76+
name="Web Frontend"
7577
)
7678

7779
floating_ip = response.floating_ip
@@ -80,6 +82,7 @@ def test_create(self, hetzner_client, server):
8082
assert floating_ip.id == 4711
8183
assert floating_ip.description == "Web Frontend"
8284
assert floating_ip.type == "ipv4"
85+
assert floating_ip.name == "Web Frontend"
8386

8487
assert action.id == 13
8588
assert action.command == "assign_floating_ip"
@@ -94,10 +97,11 @@ def test_get_actions(self, hetzner_client, floating_ip):
9497

9598
@pytest.mark.parametrize("floating_ip", [FloatingIP(id=1), BoundFloatingIP(mock.MagicMock(), dict(id=1))])
9699
def test_update(self, hetzner_client, floating_ip):
97-
floating_ip = hetzner_client.floating_ips.update(floating_ip, description="New description", labels={})
100+
floating_ip = hetzner_client.floating_ips.update(floating_ip, description="New description", labels={}, name="Web Frontend")
98101

99102
assert floating_ip.id == 4711
100103
assert floating_ip.description == "New description"
104+
assert floating_ip.name == "Web Frontend"
101105

102106
@pytest.mark.parametrize("floating_ip", [FloatingIP(id=1), BoundFloatingIP(mock.MagicMock(), dict(id=1))])
103107
def test_delete(self, hetzner_client, floating_ip):

tests/unit/floating_ips/conftest.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ def floating_ip_response():
77
"floating_ip": {
88
"id": 4711,
99
"description": "Web Frontend",
10+
"name": "Web Frontend",
1011
"created": "2016-01-30T23:50+00:00",
1112
"ip": "131.232.99.1",
1213
"type": "ipv4",
@@ -42,6 +43,7 @@ def two_floating_ips_response():
4243
{
4344
"id": 4711,
4445
"description": "Web Frontend",
46+
"name": "Web Frontend",
4547
"created": "2016-01-30T23:50+00:00",
4648
"ip": "131.232.99.1",
4749
"type": "ipv4",
@@ -70,6 +72,7 @@ def two_floating_ips_response():
7072
{
7173
"id": 4712,
7274
"description": "Web Backend",
75+
"name": "Web Backend",
7376
"created": "2016-01-30T23:50+00:00",
7477
"ip": "131.232.99.2",
7578
"type": "ipv4",
@@ -105,6 +108,7 @@ def floating_ip_create_response():
105108
"floating_ip": {
106109
"id": 4711,
107110
"description": "Web Frontend",
111+
"name": "Web Frontend",
108112
"created": "2016-01-30T23:50+00:00",
109113
"ip": "131.232.99.1",
110114
"type": "ipv4",
@@ -155,9 +159,9 @@ def floating_ip_create_response():
155159
def response_update_floating_ip():
156160
return {
157161
"floating_ip": {
158-
159162
"id": 4711,
160163
"description": "New description",
164+
"name": "New name",
161165
"created": "2016-01-30T23:50+00:00",
162166
"ip": "131.232.99.1",
163167
"type": "ipv4",

tests/unit/floating_ips/test_client.py

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ def test_bound_floating_ip_init(self, floating_ip_response):
2424

2525
assert bound_floating_ip.id == 4711
2626
assert bound_floating_ip.description == "Web Frontend"
27+
assert bound_floating_ip.name == "Web Frontend"
2728
assert bound_floating_ip.ip == "131.232.99.1"
2829
assert bound_floating_ip.type == "ipv4"
2930
assert bound_floating_ip.protection == {"delete": False}
@@ -55,12 +56,13 @@ def test_get_actions(self, hetzner_client, bound_floating_ip, response_get_actio
5556

5657
def test_update(self, hetzner_client, bound_floating_ip, response_update_floating_ip):
5758
hetzner_client.request.return_value = response_update_floating_ip
58-
floating_ip = bound_floating_ip.update(description="New description")
59+
floating_ip = bound_floating_ip.update(description="New description", name="New name")
5960
hetzner_client.request.assert_called_with(url="/floating_ips/14", method="PUT",
60-
json={"description": "New description"})
61+
json={"description": "New description", "name": "New name"})
6162

6263
assert floating_ip.id == 4711
6364
assert floating_ip.description == "New description"
65+
assert floating_ip.name == "New name"
6466

6567
def test_delete(self, hetzner_client, bound_floating_ip, generic_action):
6668
hetzner_client.request.return_value = generic_action
@@ -221,6 +223,32 @@ def test_create_with_server(self, floating_ips_client, server, floating_ip_creat
221223
assert bound_floating_ip.description == "Web Frontend"
222224
assert action.id == 13
223225

226+
@pytest.mark.parametrize("server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
227+
def test_create_with_name(self, floating_ips_client, server, floating_ip_create_response):
228+
floating_ips_client._client.request.return_value = floating_ip_create_response
229+
response = floating_ips_client.create(
230+
type="ipv6",
231+
description="Web Frontend",
232+
name="Web Frontend"
233+
)
234+
floating_ips_client._client.request.assert_called_with(
235+
url="/floating_ips",
236+
method="POST",
237+
json={
238+
'description': "Web Frontend",
239+
'type': "ipv6",
240+
'name': "Web Frontend"
241+
}
242+
)
243+
bound_floating_ip = response.floating_ip
244+
action = response.action
245+
246+
assert bound_floating_ip._client is floating_ips_client
247+
assert bound_floating_ip.id == 4711
248+
assert bound_floating_ip.description == "Web Frontend"
249+
assert bound_floating_ip.name == "Web Frontend"
250+
assert action.id == 13
251+
224252
@pytest.mark.parametrize("floating_ip", [FloatingIP(id=1), BoundFloatingIP(mock.MagicMock(), dict(id=1))])
225253
def test_get_actions(self, floating_ips_client, floating_ip, response_get_actions):
226254
floating_ips_client._client.request.return_value = response_get_actions
@@ -238,12 +266,13 @@ def test_get_actions(self, floating_ips_client, floating_ip, response_get_action
238266
@pytest.mark.parametrize("floating_ip", [FloatingIP(id=1), BoundFloatingIP(mock.MagicMock(), dict(id=1))])
239267
def test_update(self, floating_ips_client, floating_ip, response_update_floating_ip):
240268
floating_ips_client._client.request.return_value = response_update_floating_ip
241-
floating_ip = floating_ips_client.update(floating_ip, description="New description")
269+
floating_ip = floating_ips_client.update(floating_ip, description="New description", name="New name")
242270
floating_ips_client._client.request.assert_called_with(url="/floating_ips/1", method="PUT",
243-
json={"description": "New description"})
271+
json={"description": "New description", "name": "New name"})
244272

245273
assert floating_ip.id == 4711
246274
assert floating_ip.description == "New description"
275+
assert floating_ip.name == "New name"
247276

248277
@pytest.mark.parametrize("floating_ip", [FloatingIP(id=1), BoundFloatingIP(mock.MagicMock(), dict(id=1))])
249278
def test_change_protection(self, floating_ips_client, floating_ip, generic_action):

0 commit comments

Comments
 (0)