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:

+ * + * + * @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