134 lines
5.1 KiB
C#
134 lines
5.1 KiB
C#
using Hua.DDNS.Common.Config.Options;
|
||
using Hua.DDNS.SslProviders;
|
||
using Hua.DDNS.SslProviders.Ali;
|
||
using Hua.DDNS.SslProviders.Tencent;
|
||
using Quartz;
|
||
using Microsoft.Extensions.Options;
|
||
|
||
namespace Hua.DDNS.Jobs
|
||
{
|
||
[DisallowConcurrentExecution]
|
||
public class SslDownloadJob : IJob, IDisposable
|
||
{
|
||
private readonly ILogger<SslDownloadJob> _logger;
|
||
private readonly IServiceProvider _serviceProvider;
|
||
private readonly SslDownloadOption _sslDownloadOption;
|
||
|
||
public SslDownloadJob(
|
||
ILogger<SslDownloadJob> logger,
|
||
IServiceProvider serviceProvider,
|
||
IOptions<SslDownloadOption> sslDownloadOption)
|
||
{
|
||
_logger = logger;
|
||
_serviceProvider = serviceProvider;
|
||
_sslDownloadOption = sslDownloadOption.Value;
|
||
}
|
||
|
||
public async Task Execute(IJobExecutionContext context)
|
||
{
|
||
if (!_sslDownloadOption.Enabled)
|
||
{
|
||
_logger.LogInformation("SSL下载任务已禁用,跳过执行");
|
||
return;
|
||
}
|
||
|
||
_logger.LogInformation("开始SSL文件下载任务");
|
||
|
||
try
|
||
{
|
||
ISslDownloadProvider? sslProvider = _sslDownloadOption.Platform switch
|
||
{
|
||
SslPlatformEnum.Ali => _serviceProvider.GetService(typeof(AliSslProvider)) as ISslDownloadProvider,
|
||
SslPlatformEnum.Tencent => _serviceProvider.GetService(typeof(TencentSslProvider)) as ISslDownloadProvider,
|
||
_ => null
|
||
};
|
||
|
||
if (sslProvider == null)
|
||
{
|
||
_logger.LogError($"未找到 SSL 下载提供者: {_sslDownloadOption.Platform}");
|
||
return;
|
||
}
|
||
;
|
||
if (!Directory.Exists(_sslDownloadOption.SavePath))
|
||
{
|
||
Directory.CreateDirectory(_sslDownloadOption.SavePath);
|
||
_logger.LogInformation($"创建目录: {_sslDownloadOption.SavePath}");
|
||
}
|
||
|
||
var certificates = await sslProvider.GetCertificatesAsync();
|
||
var downloadTasks = new List<Task>();
|
||
|
||
foreach (var item in _sslDownloadOption.DownloadItems)
|
||
{
|
||
var matchingCertificates = certificates.Where(c => c.Domain == item.Domain).ToList();
|
||
|
||
if (matchingCertificates.Count == 0)
|
||
{
|
||
_logger.LogWarning($"未找到域名 {item.Domain} 的证书,跳过下载");
|
||
continue;
|
||
}
|
||
|
||
var certificate = matchingCertificates.OrderByDescending(c => c.CertEndTime).First();
|
||
|
||
var daysUntilExpiry = (certificate.CertEndTime - DateTime.Now).Days;
|
||
|
||
if (daysUntilExpiry <= _sslDownloadOption.ExpireDays)
|
||
{
|
||
_logger.LogInformation($"证书 {certificate.CertificateId} ({certificate.Domain}) 将在 {daysUntilExpiry} 天后过期,开始下载");
|
||
downloadTasks.Add(DownloadFileAsync(sslProvider, item, certificate.CertificateId, certificate.Domain));
|
||
}
|
||
else
|
||
{
|
||
_logger.LogInformation($"证书 {certificate.CertificateId} ({certificate.Domain}) 还有 {daysUntilExpiry} 天过期,跳过下载");
|
||
}
|
||
}
|
||
|
||
await Task.WhenAll(downloadTasks);
|
||
|
||
_logger.LogInformation($"SSL文件下载任务完成,共下载 {downloadTasks.Count} 个文件");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "SSL文件下载任务执行失败");
|
||
}
|
||
}
|
||
|
||
private async Task DownloadFileAsync(ISslDownloadProvider provider, SslDownloadItem item, string certificateId, string domain)
|
||
{
|
||
try
|
||
{
|
||
var domainPath = Path.Combine(_sslDownloadOption.SavePath, domain);
|
||
|
||
if (!Directory.Exists(domainPath))
|
||
{
|
||
Directory.CreateDirectory(domainPath);
|
||
_logger.LogInformation($"创建域名目录: {domainPath}");
|
||
}
|
||
|
||
var localPath = Path.Combine(domainPath, item.FileName);
|
||
_logger.LogInformation($"开始下载证书: {certificateId} -> {localPath}");
|
||
|
||
var success = await provider.DownloadCertificateAsync(certificateId, domainPath, item.FileName);
|
||
|
||
if (success)
|
||
{
|
||
_logger.LogInformation($"证书下载成功: {domain}/{item.FileName}");
|
||
}
|
||
else
|
||
{
|
||
_logger.LogError($"证书下载失败: {domain}/{item.FileName}");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, $"下载证书时发生错误: {item.FileName}");
|
||
}
|
||
}
|
||
|
||
public void Dispose()
|
||
{
|
||
_logger.LogInformation("SslDownloadJob已销毁");
|
||
}
|
||
}
|
||
}
|