diff --git a/src/main/java/com/hithomelabs/CFTunnels/Services/CloudflareAPIService.java b/src/main/java/com/hithomelabs/CFTunnels/Services/CloudflareAPIService.java
index cc7eaeb..6d0084a 100644
--- a/src/main/java/com/hithomelabs/CFTunnels/Services/CloudflareAPIService.java
+++ b/src/main/java/com/hithomelabs/CFTunnels/Services/CloudflareAPIService.java
@@ -22,21 +22,60 @@ import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.UUID;
+/**
+ * Service for interacting with the Cloudflare Tunnel API.
+ *
+ *
This service provides methods to manage Cloudflare Tunnels,
+ * including fetching tunnel configurations, creating/updating tunnels,
+ * and adding ingress mappings. It handles all communication with the
+ * Cloudflare API using the configured credentials.
+ *
+ * API Endpoints Used:
+ *
+ * - GET /accounts/{accountId}/cfd_tunnel - List all tunnels
+ * - GET /accounts/{accountId}/cfd_tunnel/{tunnelId}/configurations - Get tunnel config
+ * - PUT /accounts/{accountId}/cfd_tunnel/{tunnelId}/configurations - Update tunnel config
+ *
+ *
+ * @see CloudflareConfig
+ * @see Tunnel
+ * @see Ingress
+ */
@Service
public class CloudflareAPIService {
+ /**
+ * Configuration for Cloudflare API credentials and settings.
+ * Loaded from application.properties using the {@code cloudflare.*} prefix.
+ */
@Autowired
CloudflareConfig cloudflareConfig;
+ /**
+ * Header provider for Cloudflare API authentication.
+ * Generates the X-Auth-Key and X-Auth-Email headers.
+ */
@Autowired
AuthKeyEmailHeader authKeyEmailHeader;
+ /**
+ * HTTP client for making API requests.
+ */
@Autowired
RestTemplate restTemplate;
+ /**
+ * Repository for storing tunnel configurations locally.
+ */
@Autowired
TunnelRepository tunnelRepository;
+ /**
+ * Fetches all Cloudflare tunnels from the API.
+ *
+ * @return Response containing the list of tunnels from Cloudflare
+ * @see TunnelsResponse
+ */
public ResponseEntity getCloudflareTunnels() {
String url = "https://api.cloudflare.com/client/v4/accounts/" + cloudflareConfig.getAccountId() + "/cfd_tunnel";
@@ -46,9 +85,18 @@ public class CloudflareAPIService {
return responseEntity;
}
+ /**
+ * Fetches the configuration for a specific tunnel.
+ *
+ * @param tunnelId The Cloudflare tunnel ID (UUID string)
+ * @param restTemplate HTTP client to use for the request
+ * @param responseType Class to deserialize the response into
+ * @param Response type
+ * @return Response containing the tunnel configuration
+ */
public ResponseEntity getCloudflareTunnelConfigurations(String tunnelId, RestTemplate restTemplate, Class responseType) {
- // * * Resource URL to hit get request at
+ // Resource URL to hit get request at
String url = "https://api.cloudflare.com/client/v4/accounts/" + cloudflareConfig.getAccountId() + "/cfd_tunnel/" + tunnelId + "/configurations";
HttpEntity httpEntity = new HttpEntity<>("",authKeyEmailHeader.getHttpHeaders());
@@ -56,9 +104,22 @@ public class CloudflareAPIService {
return responseEntity;
}
+ /**
+ * Updates the configuration for a specific tunnel.
+ *
+ * This method is used to add, modify, or remove ingress mappings
+ * by providing a complete configuration object.
+ *
+ * @param tunnelId The Cloudflare tunnel ID (UUID string)
+ * @param restTemplate HTTP client to use for the request
+ * @param responseType Class to deserialize the response into
+ * @param config The new configuration to apply
+ * @param Response type
+ * @return Response containing the updated tunnel configuration
+ */
public ResponseEntity putCloudflareTunnelConfigurations(String tunnelId, RestTemplate restTemplate, Class responseType, Config config) {
- // * * Resource URL to hit get request at
+ // Resource URL to hit get request at
String url = "https://api.cloudflare.com/client/v4/accounts/" + cloudflareConfig.getAccountId() + "/cfd_tunnel/" + tunnelId + "/configurations";
HttpHeaders httpHeaders = authKeyEmailHeader.getHttpHeaders();
@@ -68,10 +129,29 @@ public class CloudflareAPIService {
return responseEntity;
}
+ /**
+ * Converts a Cloudflare API tunnel result to a local Tunnel entity.
+ *
+ * @param tunnelResult The tunnel result from Cloudflare API
+ * @param env The environment name to associate
+ * @return New Tunnel entity instance
+ */
private Tunnel getTunnelFromTunnelResponse(TunnelResult tunnelResult, String env){
return new Tunnel(UUID.fromString(tunnelResult.getId()), env, tunnelResult.getName());
}
+ /**
+ * Creates or updates a tunnel's local configuration.
+ *
+ * This method fetches the tunnel from Cloudflare API, validates it exists,
+ * and stores a local copy with the environment association.
+ *
+ * @param tunnelId The Cloudflare tunnel ID
+ * @param environment Environment name (e.g., "production", "staging")
+ * @return The created or updated Tunnel entity
+ * @throws ExternalServiceException if Cloudflare API returns an error
+ * @throws NoSuchElementException if the tunnel doesn't exist in Cloudflare
+ */
public Tunnel createOrUpdateTunnel(String tunnelId, String environment) throws ExternalServiceException, NoSuchElementException {
ResponseEntity responseEntity = getCloudflareTunnels();
@@ -92,10 +172,25 @@ public class CloudflareAPIService {
return toBeConfigured;
}
+ /**
+ * Retrieves all tunnels that have been locally configured.
+ *
+ * @return List of locally configured tunnels
+ */
public List getAllConfiguredTunnels() {
return tunnelRepository.findAll();
}
+ /**
+ * Adds an ingress mapping to an existing tunnel.
+ *
+ * The new ingress is inserted at the second-to-last position in the
+ * ingress list (Cloudflare requires a catch-all rule at the end).
+ *
+ * @param tunnelId The Cloudflare tunnel ID
+ * @param ingress The ingress configuration to add
+ * @return Response with the updated tunnel configuration
+ */
public ResponseEntity addTunnelIngress(String tunnelId, Ingress ingress) {
ResponseEntity currentConfig = getCloudflareTunnelConfigurations(tunnelId, restTemplate, TunnelResponse.class);
@@ -105,4 +200,4 @@ public class CloudflareAPIService {
return putCloudflareTunnelConfigurations(tunnelId, restTemplate, TunnelResponse.class, config);
}
-}
+}
\ No newline at end of file