chore: update project structure with contracts and services for CaddyManager, including configuration and Docker integration
All checks were successful
Caddy Manager CI build / docker (push) Successful in 1m16s

This commit is contained in:
2025-07-23 10:37:51 +07:00
parent 18c710d341
commit ec454d0346
56 changed files with 8511 additions and 34 deletions

View File

@@ -0,0 +1,38 @@
namespace CaddyManager.Contracts.Caddy;
/// <summary>
/// Contract for a service that parses Caddy configuration files.
/// </summary>
public interface ICaddyConfigurationParsingService
{
/// <summary>
/// Extracts outermost hostname declarations from a Caddyfile content.
/// i.e.
/// ```
/// caddy.domain.name {
/// route {
/// reverse_proxy localhost:8080
/// encode zstd gzip
/// }
/// }
/// ```
/// will return `["caddy.domain.name"]`.
/// </summary>
/// <param name="caddyfileContent"></param>
/// <returns></returns>
List<string> GetHostnamesFromCaddyfileContent(string caddyfileContent);
/// <summary>
/// Extracts the reverse proxy target from a Caddyfile content.
/// </summary>
/// <param name="caddyfileContent"></param>
/// <returns></returns>
string GetReverseProxyTargetFromCaddyfileContent(string caddyfileContent);
/// <summary>
/// Extracts the ports being used with the reverse proxy host
/// </summary>
/// <param name="caddyfileContent"></param>
/// <returns></returns>
List<int> GetReverseProxyPortsFromCaddyfileContent(string caddyfileContent);
}

View File

@@ -0,0 +1,60 @@
using CaddyManager.Contracts.Models.Caddy;
using CaddyManager.Contracts.Configurations.Caddy;
namespace CaddyManager.Contracts.Caddy;
using CaddyManager.Contracts.Models.Caddy;
using CaddyManager.Contracts.Configurations.Caddy;
/// <summary>
/// Contracts for Caddy Service to help monitor the available Caddy configurations
/// </summary>
public interface ICaddyService
{
/// <summary>
/// Returns the existing Caddy configurations within the configured directory
/// </summary>
/// <returns></returns>
List<CaddyConfigurationInfo> GetExistingCaddyConfigurations();
/// <summary>
/// Method to get the content of a Caddy configuration file by its name
/// The expected path to be [ConfigDir]/[configurationName].caddy
/// </summary>
/// <param name="configurationName"></param>
/// <returns></returns>
string GetCaddyConfigurationContent(string configurationName);
/// <summary>
/// Method to get the content of the global Caddy configuration file
/// </summary>
/// <returns></returns>
string GetCaddyGlobalConfigurationContent();
/// <summary>
/// Method to help save a Caddy configuration file
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
CaddyOperationResponse SaveCaddyConfiguration(CaddySaveConfigurationRequest request);
/// <summary>
/// Method to help save the global Caddyfile configuration
/// </summary>
/// <param name="content"></param>
/// <returns></returns>
CaddyOperationResponse SaveCaddyGlobalConfiguration(string content);
/// <summary>
/// Method to delete the given Caddy configurations by name
/// </summary>
/// <param name="configurationNames"></param>
/// <returns></returns>
CaddyDeleteOperationResponse DeleteCaddyConfigurations(List<string> configurationNames);
/// <summary>
/// Parse the Caddy configuration file and return the information about it
/// </summary>
/// <param name="configurationName"></param>
/// <returns></returns>
CaddyConfigurationInfo GetCaddyConfigurationInfo(string configurationName);
}

View File

@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,11 @@
namespace CaddyManager.Contracts.Configurations.Caddy;
/// <summary>
/// Wraps the configurations for Caddy service
/// </summary>
public class CaddyServiceConfigurations
{
public const string Caddy = "Caddy";
public string ConfigDir { get; set; } = "/config";
}

View File

@@ -0,0 +1,32 @@
namespace CaddyManager.Contracts.Configurations.Docker;
/// <summary>
/// Configuration for the Docker service
/// </summary>
public class DockerServiceConfiguration
{
public const string Docker = "Docker";
/// <summary>
/// Name of the Caddy container to be controlled (i.e restart)
/// </summary>
public string CaddyContainerName { get; set; } = "caddy";
/// <summary>
/// Uri to the Docker host
/// </summary>
public string DockerHost { get; set; } = "unix:///var/run/docker.sock";
/// <summary>
/// Returns the Docker host with environment check. If the environment variable DOCKER_HOST is set, it will return
/// that value, otherwise it will return the value of DockerHost
/// </summary>
public string DockerHostWithEnvCheck
{
get
{
var envValue = Environment.GetEnvironmentVariable("DOCKER_HOST");
return string.IsNullOrWhiteSpace(envValue) ? DockerHost : envValue;
}
}
}

View File

@@ -0,0 +1,18 @@
using CaddyManager.Contracts.Configurations.Caddy;
using CaddyManager.Contracts.Configurations.Docker;
namespace CaddyManager.Contracts.Configurations;
/// <summary>
/// Contract for the services providing the configurations for the application
/// </summary>
public interface IConfigurationsService
{
/// <summary>
/// Method extracting the configurations from the appsettings.json file or environment variables base on the
/// type of the configuration class to determine the section name
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
T Get<T>() where T : class;
}

View File

@@ -0,0 +1,13 @@
namespace CaddyManager.Contracts.Docker;
/// <summary>
/// Contract for the service to interact with Docker
/// </summary>
public interface IDockerService
{
/// <summary>
/// Method to help restart the Caddy container
/// </summary>
/// <returns></returns>
Task RestartCaddyContainerAsync();
}

View File

@@ -0,0 +1,44 @@
namespace CaddyManager.Contracts.Models.Caddy;
/// <summary>
/// Wraps the information parsed from the Caddy configuration file.
/// </summary>
public class CaddyConfigurationInfo
{
/// <summary>
/// Hostnames that are configured in the Caddyfile.
/// </summary>
public List<string> Hostnames { get; set; } = [];
/// <summary>
/// The hostname of the reverse proxy server.
/// </summary>
public string ReverseProxyHostname { get; set; } = string.Empty;
/// <summary>
/// Ports being used with the reverse proxy hostname
/// </summary>
public List<int> ReverseProxyPorts { get; set; } = [];
/// <summary>
/// The name of the configuration file.
/// </summary>
public string FileName { get; set; } = string.Empty;
/// <summary>
/// Aggregated ports for the reverse proxy hostname from all configurations.
/// </summary>
public List<int> AggregatedReverseProxyPorts { get; set; } = [];
public override bool Equals(object? obj)
{
if (obj is not CaddyConfigurationInfo other)
return false;
return FileName == other.FileName;
}
public override int GetHashCode()
{
return FileName.GetHashCode();
}
}

View File

@@ -0,0 +1,12 @@
namespace CaddyManager.Contracts.Models.Caddy;
/// <summary>
/// Class to wrap the response of a Caddy delete operation
/// </summary>
public class CaddyDeleteOperationResponse : CaddyOperationResponse
{
/// <summary>
/// List of configurations that were successfully deleted
/// </summary>
public List<string> DeletedConfigurations { get; set; } = [];
}

View File

@@ -0,0 +1,23 @@
namespace CaddyManager.Contracts.Models.Caddy;
/// <summary>
/// Class to wrap the response of a generic Caddy operation
/// </summary>
public class CaddyOperationResponse
{
private string _message = string.Empty;
/// <summary>
/// Indicates if the operation was successful
/// </summary>
public bool Success { get; set; }
/// <summary>
/// Message to describe the operation result to provide more context
/// </summary>
public string Message
{
get => _message;
set => _message = value ?? string.Empty;
}
}

View File

@@ -0,0 +1,22 @@
namespace CaddyManager.Contracts.Models.Caddy;
/// <summary>
/// Wraps the information needed to save a Caddy configuration
/// </summary>
public class CaddySaveConfigurationRequest
{
/// <summary>
/// Indicates if the configuration is new
/// </summary>
public bool IsNew { get; set; }
/// <summary>
/// Name of the Caddy configuration file
/// </summary>
public required string FileName { get; init; } = string.Empty;
/// <summary>
/// Content of the Caddy configuration file
/// </summary>
public string Content { get; set; } = string.Empty;
}