using CaddyManager.Contracts.Configurations.Caddy; using CaddyManager.Contracts.Caddy; using CaddyManager.Contracts.Configurations; using CaddyManager.Contracts.Models.Caddy; namespace CaddyManager.Services.Caddy; /// public class CaddyService( IConfigurationsService configurationsService, ICaddyConfigurationParsingService parsingService) : ICaddyService { /// /// File name of the global configuration Caddyfile /// private const string CaddyGlobalConfigName = "Caddyfile"; private CaddyServiceConfigurations Configurations => configurationsService.Get(); /// public List GetExistingCaddyConfigurations() { if (!Directory.Exists(Configurations.ConfigDir)) { Directory.CreateDirectory(Configurations.ConfigDir); } return [.. Directory.GetFiles(Configurations.ConfigDir) .Where(filePath => Path.GetFileName(filePath) != CaddyGlobalConfigName) .Select(filePath => { var fileName = Path.GetFileNameWithoutExtension(filePath); var info = GetCaddyConfigurationInfo(fileName); info.FileName = fileName; return info; }) .OrderBy(info => info.FileName)]; } /// public string GetCaddyConfigurationContent(string configurationName) { var path = configurationName == CaddyGlobalConfigName ? Path.Combine(Configurations.ConfigDir, CaddyGlobalConfigName) : Path.Combine(Configurations.ConfigDir, $"{configurationName}.caddy"); if (File.Exists(path)) { return File.ReadAllText(path); } return string.Empty; } /// public string GetCaddyGlobalConfigurationContent() => GetCaddyConfigurationContent(CaddyGlobalConfigName); /// public CaddyOperationResponse SaveCaddyConfiguration(CaddySaveConfigurationRequest request) { if (string.IsNullOrWhiteSpace(request.FileName)) { return new CaddyOperationResponse { Success = false, Message = "The configuration file name is required" }; } var filePath = Path.Combine(Configurations.ConfigDir, request.FileName == CaddyGlobalConfigName ? CaddyGlobalConfigName : $"{request.FileName}.caddy"); // if in the new mode, we would have to check if the file already exists if (request.IsNew && File.Exists(filePath)) { return new CaddyOperationResponse { Success = false, Message = "The configuration file already exists" }; } try { File.WriteAllText(filePath, request.Content); return new CaddyOperationResponse { Success = true, Message = "Configuration file saved successfully" }; } catch (Exception e) { return new CaddyOperationResponse { Success = false, Message = e.Message }; } } /// public CaddyOperationResponse SaveCaddyGlobalConfiguration(string content) => SaveCaddyConfiguration( new CaddySaveConfigurationRequest { FileName = CaddyGlobalConfigName, Content = content }); /// public CaddyDeleteOperationResponse DeleteCaddyConfigurations(List configurationNames) { var failed = new List(); foreach (var configurationName in configurationNames) { var filePath = Path.Combine(Configurations.ConfigDir, configurationName == CaddyGlobalConfigName ? CaddyGlobalConfigName : $"{configurationName}.caddy"); if (File.Exists(filePath)) { try { File.Delete(filePath); } catch { failed.Add(configurationName); } } else { failed.Add(configurationName); } } return new CaddyDeleteOperationResponse { Success = failed.Count == 0, Message = failed.Count == 0 ? "Configuration(s) deleted successfully" : $"Failed to delete the following configuration(s): {string.Join(", ", failed)}", DeletedConfigurations = configurationNames.Except(failed).ToList() }; } /// public CaddyConfigurationInfo GetCaddyConfigurationInfo(string configurationName) { var result = new CaddyConfigurationInfo { FileName = configurationName }; var content = GetCaddyConfigurationContent(configurationName); if (string.IsNullOrWhiteSpace(content)) { return result; } result.Hostnames = parsingService.GetHostnamesFromCaddyfileContent(content); result.ReverseProxyHostname = parsingService.GetReverseProxyTargetFromCaddyfileContent(content); result.ReverseProxyPorts = parsingService.GetReverseProxyPortsFromCaddyfileContent(content); result.Tags = parsingService.GetTagsFromCaddyfileContent(content); return result; } }