Skip to content

Commit 58969fa

Browse files
committed
✨ Add support for resource actions
Signed-off-by: Richard Kosegi <[email protected]>
1 parent 39d8e78 commit 58969fa

File tree

5 files changed

+160
-2
lines changed

5 files changed

+160
-2
lines changed

src/main/java/cloud/dnation/hetznerclient/HetznerApi.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import retrofit2.http.Path;
2424
import retrofit2.http.Query;
2525

26+
import java.util.List;
27+
2628
/**
2729
* Trimmed-down version of Hetzner public cloud API.
2830
* For full version, check <a href="https://docs.hetzner.cloud/">official documentation</a>
@@ -298,4 +300,19 @@ Call<GetAllPrimaryIpsResponse> getPrimaryIpsBySelector(@Query("label_selector")
298300
Call<GetVolumesResponse> getVolumes(@Query("label_selector") String selector,
299301
@Query("page") int page,
300302
@Query("per_page") int perPage);
303+
304+
/**
305+
* Get actions for given resource type (servers/networks/load_balancers/floating_ips/firewalls/volumes).
306+
*
307+
* @param resource type of resource.
308+
* @param ids The response will only contain actions matching the specified IDs.
309+
* @param page page index.
310+
* @param perPage number of items per page. API imposes limit on top of this value.
311+
* @return paged list of actions for given resource type.
312+
*/
313+
@GET("/v1/{resource}/actions")
314+
Call<GetActionsResponse> getResourceActions(@Path("resource") String resource,
315+
@Query("id") List<Long> ids,
316+
@Query("page") int page,
317+
@Query("per_page") int perPage);
301318
}

src/main/resources/api.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,16 @@ components:
137137
$ref: "#/components/schemas/FirewallDetail"
138138
type: object
139139

140+
GetActionsResponse:
141+
allOf:
142+
- $ref: "#/components/schemas/AbstractSearchResponse"
143+
properties:
144+
actions:
145+
type: array
146+
items:
147+
$ref: "#/components/schemas/ActionDetail"
148+
type: object
149+
140150
GetServersBySelectorResponse:
141151
allOf:
142152
- $ref: "#/components/schemas/AbstractSearchResponse"
@@ -579,6 +589,15 @@ components:
579589
status:
580590
description: Status of the Action
581591
type: string
592+
progress:
593+
description: Operation progress, in percent.
594+
type: integer
595+
format: int32
596+
resources:
597+
description: List of resources the Action relates to
598+
type: array
599+
items:
600+
$ref: "#/components/schemas/IdentifiableResource"
582601
title: Action
583602
type: object
584603

src/test/java/cloud/dnation/hetznerclient/BasicTest.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,12 @@
2626
import java.io.IOException;
2727
import java.util.ArrayList;
2828
import java.util.List;
29-
import java.util.function.BiFunction;
30-
import java.util.function.Function;
3129

3230
import static cloud.dnation.hetznerclient.TestHelper.resourceAsString;
3331
import static org.junit.Assert.assertEquals;
3432
import static org.junit.Assert.assertNull;
3533

34+
@SuppressWarnings("DataFlowIssue")
3635
public class BasicTest {
3736
private static MockWebServer ws;
3837
private static HetznerApi api;
@@ -129,6 +128,26 @@ public void testGetFirewallById() throws IOException {
129128
assertEquals("22", result.getFirewall().getRules().get(0).getPort());
130129
}
131130

131+
@Test
132+
public void testGetServerActions() throws IOException{
133+
ws.enqueue(new MockResponse().setBody(resourceAsString("get-lb-actions.json")));
134+
Call<GetActionsResponse> call;
135+
GetActionsResponse result;
136+
call = api.getResourceActions("load_balancers", null, 0, 25);
137+
result = call.execute().body();
138+
assertEquals(4, result.getActions().size());
139+
assertEquals(100, (int) result.getActions().get(0).getProgress());
140+
assertEquals("remove_target", result.getActions().get(0).getCommand());
141+
142+
List<Long> ids = new ArrayList<>();
143+
ids.add(99999L);
144+
ws.enqueue(new MockResponse().setBody(resourceAsString("get-lb-actions-with-id.json")));
145+
call = api.getResourceActions("load_balancers", ids, 0, 25);
146+
result = call.execute().body();
147+
assertEquals(1, result.getActions().size());
148+
assertEquals(100, (int) result.getActions().get(0).getProgress());
149+
assertEquals("remove_target", result.getActions().get(0).getCommand());
150+
}
132151

133152
@Test
134153
public void testGetFirewallByIdInvalid() throws IOException {
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"actions": [
3+
{
4+
"id": 123456,
5+
"command": "remove_target",
6+
"status": "success",
7+
"progress": 100,
8+
"started": "2025-07-15T08:59:51+00:00",
9+
"finished": "2025-07-15T08:59:51+00:00",
10+
"resources": [
11+
{
12+
"id": 99999,
13+
"type": "load_balancer"
14+
}
15+
],
16+
"error": null
17+
}
18+
],
19+
"meta": {
20+
"pagination": {
21+
"page": 1,
22+
"per_page": 25,
23+
"previous_page": null,
24+
"next_page": null,
25+
"last_page": 1,
26+
"total_entries": 4
27+
}
28+
}
29+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
{
2+
"actions": [
3+
{
4+
"id": 123456,
5+
"command": "remove_target",
6+
"status": "success",
7+
"progress": 100,
8+
"started": "2025-07-15T08:59:51+00:00",
9+
"finished": "2025-07-15T08:59:51+00:00",
10+
"resources": [
11+
{
12+
"id": 99999,
13+
"type": "load_balancer"
14+
}
15+
],
16+
"error": null
17+
},
18+
{
19+
"id": 456789,
20+
"command": "add_target",
21+
"status": "success",
22+
"progress": 100,
23+
"started": "2025-07-15T09:00:07+00:00",
24+
"finished": "2025-07-15T09:00:07+00:00",
25+
"resources": [
26+
{
27+
"id": 88888,
28+
"type": "load_balancer"
29+
}
30+
],
31+
"error": null
32+
},
33+
{
34+
"id": 47356,
35+
"command": "remove_target",
36+
"status": "success",
37+
"progress": 100,
38+
"started": "2025-07-15T09:00:35+00:00",
39+
"finished": "2025-07-15T09:00:35+00:00",
40+
"resources": [
41+
{
42+
"id": 99999,
43+
"type": "load_balancer"
44+
}
45+
],
46+
"error": null
47+
},
48+
{
49+
"id": 763542384,
50+
"command": "add_target",
51+
"status": "success",
52+
"progress": 100,
53+
"started": "2025-07-15T09:00:42+00:00",
54+
"finished": "2025-07-15T09:00:42+00:00",
55+
"resources": [
56+
{
57+
"id": 99999,
58+
"type": "load_balancer"
59+
}
60+
],
61+
"error": null
62+
}
63+
],
64+
"meta": {
65+
"pagination": {
66+
"page": 1,
67+
"per_page": 25,
68+
"previous_page": null,
69+
"next_page": null,
70+
"last_page": 1,
71+
"total_entries": 4
72+
}
73+
}
74+
}

0 commit comments

Comments
 (0)