Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add firewall support #79

Merged
merged 8 commits into from
Aug 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 157 additions & 3 deletions src/main/java/me/tomsdevsn/hetznercloud/HetznerCloudAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import me.tomsdevsn.hetznercloud.exception.InvalidParametersException;
import me.tomsdevsn.hetznercloud.objects.general.FWApplicationTarget;
import me.tomsdevsn.hetznercloud.objects.general.FirewallRule;
import me.tomsdevsn.hetznercloud.objects.general.PlacementGroupType;
import me.tomsdevsn.hetznercloud.objects.pagination.PaginationParameters;
import me.tomsdevsn.hetznercloud.objects.request.*;
Expand All @@ -15,9 +17,7 @@
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Optional;
import java.util.TimeZone;
import java.util.*;
import java.util.concurrent.TimeUnit;

public class HetznerCloudAPI {
Expand Down Expand Up @@ -689,6 +689,160 @@ public DatacentersResponse getDatacenter(String name) {
DatacentersResponse.class);
}

/**
* Returns 25 Firewall objects.
*
* @return a FirewallsResponse containing all Firewalls of the requested page and paging metadata
* @see #getFirewalls(PaginationParameters)
*/
public FirewallsResponse getFirewalls() {
return getFirewalls(new PaginationParameters(null, null));
}

/**
* Returns all Firewall objects.
*
* @param paginationParameters
* @return a FirewallsResponse containing all Firewalls of the requested page and paging metadata
*/
public FirewallsResponse getFirewalls(PaginationParameters paginationParameters) {
return get(
UrlBuilder.from(API_URL + "/firewalls")
.queryParamIfPresent("page", Optional.ofNullable(paginationParameters.page))
.queryParamIfPresent("per_page", Optional.ofNullable(paginationParameters.perPage))
.toUri(),
FirewallsResponse.class);
}

/**
* Creates a new Firewall.
*
* @param createFirewallRequest the config of the Firewall you want to create
* @return a FirewallResponse containing the created Firewall and taken Actions
*/
public FirewallResponse createFirewall(CreateFirewallRequest createFirewallRequest) {
return post(
API_URL + "/firewalls",
createFirewallRequest,
FirewallResponse.class);
}

/**
* Deletes a Firewall.
*
* @param id
*/
public void deleteFirewall(long id) {
delete(
API_URL + "/firewalls/" + id,
String.class);
}

/**
* Gets a specific Firewall.
*
* @param id
* @return the FirewallResponse containing the searched Firewall
*/
private FirewallResponse getFirewall(long id) {
return get(
API_URL + "/firewalls/" + id,
FirewallResponse.class);
}

/**
* Updates the Firewall. This replaces the current labels with the given
*
* @param id
* @param updateFirewallRequest the changes you want to perform
* @return the FirewallResponse of the request, containing the new Firewall and Metadata
*/
public FirewallResponse updateFirewall(long id, UpdateFirewallRequest updateFirewallRequest) {
return put(
API_URL + "/firewalls/" + id,
updateFirewallRequest,
FirewallResponse.class);
}

/**
* Returns all Action objects for a Firewall.
*
* @param id
* @return an ActionsResponse with the executed actions
*/
public ActionsResponse getActionsOfFirewall(long id) {
return get(
String.format("%s/firewalls/%s/actions", API_URL, id),
ActionsResponse.class);
}

/**
* Returns a specific Action for a Firewall.
*
* @param firewallId
* @param actionId
* @return an ActionsResponse with the executed actions
*/
public ActionResponse getActionOfFirewall(long firewallId, long actionId) {
return get(
String.format("%s/firewalls/%s/actions/%s", API_URL, firewallId, actionId),
ActionResponse.class);
}

/**
* Applies one Firewall to multiple resources.
*
* @param id of the firewall you want to add to resources
* @param applicationTargets you want to add
* @return an ActionsResponse with the executed actions
*/
public ActionsResponse applyFirewallToResources(long id, List<FWApplicationTarget> applicationTargets) {
return post(
API_URL + "/firewalls/" + id + "/actions/apply_to_resources",
Map.of("apply_to", applicationTargets),
ActionsResponse.class);
}

/**
* Removes one Firewall from multiple resources.
*
* @param id of the firewall you want to remove resources from
* @param removalTargets you want to remove
* @return an ActionsResponse with the executed actions
*/
public ActionsResponse removeFirewallFromResources(long id, List<FWApplicationTarget> removalTargets) {
return post(
API_URL + "/firewalls/" + id + "/actions/remove_from_resources",
Map.of("remove_from", removalTargets),
ActionsResponse.class);
}

/**
* Removes all rules of a Firewall.
*
* @param id the firewall you want to remove the rules from
* @return an ActionsResponse with the executed actions
* @see #setFirewallRules(long, List)
*/
public ActionsResponse removeAllRulesFromFirewall(long id) {
return setFirewallRules(id, Collections.EMPTY_LIST);
}

/**
* Sets the rules of a Firewall. All existing rules will be overwritten.
* If the firewallRules are empty, all rules are deleted.
*
* @param id of the Firewall you want to set the Rules on.
* @param firewallRules you want to set.
* @return an ActionsResponse with the executed actions
*/
public ActionsResponse setFirewallRules(long id, List<FirewallRule> firewallRules) {
return post(
API_URL + "/firewalls/" + id + "/actions/set_rules",
Map.of("rules", firewallRules),
ActionsResponse.class);
}

/**
* Get all prices from the products
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package me.tomsdevsn.hetznercloud.objects.general;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class FWApplicationTarget {

@JsonProperty("label_selector")
private FWLabelSelector labelSelector;
private FWServerRef server;
private TargetType type;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package me.tomsdevsn.hetznercloud.objects.general;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class FWLabelSelector {

private String selector;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package me.tomsdevsn.hetznercloud.objects.general;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class FWServerRef {

private Long id;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package me.tomsdevsn.hetznercloud.objects.general;

import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class FWTargetedResource {

private FWServerRef server;
private TargetType type = TargetType.server;

public FWTargetedResource(FWServerRef serverRef) {
this.server = serverRef;
}

public FWTargetedResource(Long serverId) {
this.server = new FWServerRef(serverId);
}

public FWTargetedResource(Server server) {
this.server = new FWServerRef(server.getId());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package me.tomsdevsn.hetznercloud.objects.general;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import me.tomsdevsn.hetznercloud.deserialize.DateDeserializer;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Firewall {

@JsonProperty("applied_to")
private List<FWApplicationTarget> appliedTo;
@JsonDeserialize(contentUsing = DateDeserializer.class)
private Date created;
private Long id;
private Map<String, String> labels;
private String name;
@JsonProperty("rules")
private List<FirewallRule> firewallRules;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package me.tomsdevsn.hetznercloud.objects.general;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;

import java.util.List;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class FirewallRule {

private String description;
@Singular("desinationIP")
@JsonProperty("destination_ips")
private List<String> destinationIPs;
private Direction direction;
@Builder.Default
private String port = "";
private Protocol protocol;
@Singular("sourceIP")
@JsonProperty("source_ips")
private List<String> sourceIPs;

public enum Direction {
in, out
}

public enum Protocol {
tcp, udp, icmp, esp, gre
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package me.tomsdevsn.hetznercloud.objects.request;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.Singular;
import me.tomsdevsn.hetznercloud.objects.general.FWApplicationTarget;
import me.tomsdevsn.hetznercloud.objects.general.FirewallRule;

import java.util.List;
import java.util.Map;

@Data
@Builder
@AllArgsConstructor
public class CreateFirewallRequest {

@Singular("applicationTarget")
@JsonProperty("apply_to")
private List<FWApplicationTarget> applyTo;
@Singular("label")
private Map<String, String> labels;
private String name;
@Singular("firewallRule")
@JsonProperty("rules")
private List<FirewallRule> firewallRules;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package me.tomsdevsn.hetznercloud.objects.request;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Builder;
import lombok.Data;
import lombok.Singular;

import java.util.Map;

@Data
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public class UpdateFirewallRequest {

@Singular
private Map<String, String> labels;
private String name;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package me.tomsdevsn.hetznercloud.objects.response;

import lombok.Data;
import me.tomsdevsn.hetznercloud.objects.general.Action;
import me.tomsdevsn.hetznercloud.objects.general.Firewall;

import java.util.List;

@Data
public class FirewallResponse {

private List<Action> actions;
private Firewall firewall;

}
Loading