132 lines
3.9 KiB
C#
132 lines
3.9 KiB
C#
using System.Text.Json;
|
|
using PlanTempusAdmin.Models;
|
|
|
|
namespace PlanTempusAdmin.Services;
|
|
|
|
public class CaddyService
|
|
{
|
|
private readonly HttpClient _httpClient;
|
|
private readonly ILogger<CaddyService> _logger;
|
|
private readonly string _caddyAdminUrl;
|
|
|
|
public CaddyService(HttpClient httpClient, ILogger<CaddyService> logger, IConfiguration configuration)
|
|
{
|
|
_httpClient = httpClient;
|
|
_logger = logger;
|
|
_caddyAdminUrl = configuration.GetValue<string>("Caddy:AdminUrl") ?? "http://localhost:2019";
|
|
}
|
|
|
|
public async Task<bool> IsRunningAsync()
|
|
{
|
|
try
|
|
{
|
|
var response = await _httpClient.GetAsync($"{_caddyAdminUrl}/config/");
|
|
return response.IsSuccessStatusCode;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogWarning(ex, "Could not connect to Caddy Admin API");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public async Task<CaddyConfig?> GetConfigAsync()
|
|
{
|
|
try
|
|
{
|
|
var response = await _httpClient.GetAsync($"{_caddyAdminUrl}/config/");
|
|
if (!response.IsSuccessStatusCode)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var json = await response.Content.ReadAsStringAsync();
|
|
var options = new JsonSerializerOptions
|
|
{
|
|
PropertyNameCaseInsensitive = true
|
|
};
|
|
return JsonSerializer.Deserialize<CaddyConfig>(json, options);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error fetching Caddy config");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public async Task<List<CaddyHost>> GetHostsAsync()
|
|
{
|
|
var hosts = new List<CaddyHost>();
|
|
|
|
try
|
|
{
|
|
var config = await GetConfigAsync();
|
|
if (config?.Apps?.Http?.Servers == null)
|
|
{
|
|
return hosts;
|
|
}
|
|
|
|
foreach (var server in config.Apps.Http.Servers.Values)
|
|
{
|
|
if (server.Routes == null) continue;
|
|
|
|
foreach (var route in server.Routes)
|
|
{
|
|
if (route.Match == null) continue;
|
|
|
|
foreach (var match in route.Match)
|
|
{
|
|
if (match.Host == null) continue;
|
|
|
|
foreach (var hostname in match.Host)
|
|
{
|
|
var host = new CaddyHost
|
|
{
|
|
Hostname = hostname,
|
|
Addresses = server.Listen ?? Array.Empty<string>(),
|
|
Tls = server.Listen?.Any(l => l.Contains(":443")) ?? false
|
|
};
|
|
|
|
// Try to get upstream from handlers
|
|
if (route.Handle != null)
|
|
{
|
|
var reverseProxy = route.Handle.FirstOrDefault(h => h.Handler == "reverse_proxy");
|
|
if (reverseProxy?.Upstreams?.Length > 0)
|
|
{
|
|
host.Upstream = reverseProxy.Upstreams[0].Dial;
|
|
}
|
|
}
|
|
|
|
hosts.Add(host);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error parsing Caddy hosts");
|
|
}
|
|
|
|
return hosts;
|
|
}
|
|
|
|
public async Task<string?> GetRawConfigAsync()
|
|
{
|
|
try
|
|
{
|
|
var response = await _httpClient.GetAsync($"{_caddyAdminUrl}/config/");
|
|
if (!response.IsSuccessStatusCode)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return await response.Content.ReadAsStringAsync();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error fetching raw Caddy config");
|
|
return null;
|
|
}
|
|
}
|
|
}
|