变更详情摘要:
- 功能增强 : - AliSslProvider.cs :实现了从阿里云获取证书列表及删除过期证书的逻辑。 - TencentSslProvider.cs :增加了腾讯云过期证书的清理功能。 - ISslDownloadProvider.cs :扩展了接口协议,并丰富了 SslCertificate 模型属性。 - 任务调度 : - Program.cs :集成了 SslDownloadJob 到 Quartz 框架中,支持自动化运行。 - 文档与规范 : - 对项目关键入口和 Provider 进行了全面的代码注释补全。
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"ConnectionStrings": {
|
||||
"pgConnection": "Host=127.0.0.1;Port=5432;Database=Worker;Username=Worker;Password=123456;"
|
||||
},
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"App": {
|
||||
"GetIpv4Url": "http://47.108.74.59:8001/api/NetWork/GetIp",
|
||||
"AppJob": {
|
||||
"Corn": "0/5 * * * * ?" //https://cron.qqe2.com/
|
||||
}
|
||||
},
|
||||
"DDNS": {
|
||||
"Platform": 2, //1 Ali 2 Tencent 3 Namesilo
|
||||
// 主域名
|
||||
"Domain": "we965.cn",
|
||||
// 子域名前缀
|
||||
"SubDomainArray": [ "mp", "git", "webutil", "dev", "sftp" ],
|
||||
// 记录类型
|
||||
"type": "A",
|
||||
//间隔时间 秒
|
||||
"time": "30"
|
||||
},
|
||||
"SslDownload": {
|
||||
"Enabled": true,
|
||||
"Corn": "0/5 * * * * ?", //https://cron.qqe2.com/
|
||||
"Platform": 2,
|
||||
"SavePath": "D:\\Paths\\ssl",
|
||||
"ExpireDays": 5,
|
||||
"DownloadItems": [
|
||||
{
|
||||
"Domain": "git.we965.cn",
|
||||
"FileName": "git.we965.cn.pem"
|
||||
},
|
||||
{
|
||||
"Domain": "webutil.we965.cn",
|
||||
"FileName": "webutil.we965.cn.pem"
|
||||
},
|
||||
{
|
||||
"Domain": "dev.we965.cn",
|
||||
"FileName": "dev.we965.cn.pem"
|
||||
}
|
||||
]
|
||||
},
|
||||
"TencentCloud": {
|
||||
"SecretId": "AKIDy35008NYm6T1v3R3gGtU1UIHOe0NizON",
|
||||
"SecretKey": "1sXQmASfmmlwAXuDh8fVYUOLI7mJagbQ",
|
||||
"Region": "ap-guangzhou",
|
||||
"Dnspod": {
|
||||
"Endpoint": "dnspod.tencentcloudapi.com"
|
||||
}
|
||||
},
|
||||
"AliCloud": {
|
||||
"AccessKeyId": "1111",
|
||||
"AccessKeySecret": "1111",
|
||||
"RegionId": "cn-hangzhou",
|
||||
"Endpoint": "1111"
|
||||
},
|
||||
"Namesilo": {
|
||||
"ApiKey": "1111"
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.2.32616.157
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hua.DDNS", "Hua.DDNS\Hua.DDNS.csproj", "{EBC77B5D-87D5-4923-84A6-93DB2248DEB0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hua.DDNS.Test", "Hua.DDNS.Test\Hua.DDNS.Test.csproj", "{BB544060-5ABF-4A3C-965B-BE7CA7BD61E7}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{EBC77B5D-87D5-4923-84A6-93DB2248DEB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EBC77B5D-87D5-4923-84A6-93DB2248DEB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EBC77B5D-87D5-4923-84A6-93DB2248DEB0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EBC77B5D-87D5-4923-84A6-93DB2248DEB0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BB544060-5ABF-4A3C-965B-BE7CA7BD61E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BB544060-5ABF-4A3C-965B-BE7CA7BD61E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BB544060-5ABF-4A3C-965B-BE7CA7BD61E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BB544060-5ABF-4A3C-965B-BE7CA7BD61E7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {D8744CA6-C2DB-4287-B8B3-E5917B12391D}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,4 @@
|
||||
<Solution>
|
||||
<Project Path="Hua.DDNS.Test/Hua.DDNS.Test.csproj" />
|
||||
<Project Path="Hua.DDNS/Hua.DDNS.csproj" />
|
||||
</Solution>
|
||||
@@ -1,10 +1,28 @@
|
||||
namespace Hua.DDNS.Common.Config.Options
|
||||
{
|
||||
/// <summary>
|
||||
/// 阿里云配置选项
|
||||
/// </summary>
|
||||
public class AliCloudOption
|
||||
{
|
||||
/// <summary>
|
||||
/// 访问密钥 ID
|
||||
/// </summary>
|
||||
public string AccessKeyId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 访问密钥私钥
|
||||
/// </summary>
|
||||
public string AccessKeySecret { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 区域 ID (如 cn-hangzhou)
|
||||
/// </summary>
|
||||
public string RegionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 访问端点 (可选)
|
||||
/// </summary>
|
||||
public string Endpoint { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
using Hua.DDNS.DDNSProviders;
|
||||
using Hua.DDNS.DDNSProviders;
|
||||
|
||||
namespace Hua.DDNS.Common.Config.Options
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// app configuration class
|
||||
/// 应用程序全局配置类
|
||||
/// </summary>
|
||||
public class AppOption
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// domain configuration
|
||||
/// DDNS 相关配置
|
||||
/// </summary>
|
||||
public DdnsOption DDNS { get; set; }
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -7,17 +7,17 @@ using System.Threading.Tasks;
|
||||
namespace Hua.DDNS.Common.Config.Options
|
||||
{
|
||||
/// <summary>
|
||||
/// DDNS Platform
|
||||
/// DDNS 平台类型枚举
|
||||
/// </summary>
|
||||
public enum PlatformEnum
|
||||
{
|
||||
/// <summary>
|
||||
/// Ali
|
||||
/// 阿里云
|
||||
/// </summary>
|
||||
Ali = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Tencent
|
||||
/// 腾讯云
|
||||
/// </summary>
|
||||
Tencent,
|
||||
|
||||
|
||||
@@ -1,24 +1,69 @@
|
||||
namespace Hua.DDNS.Common.Config.Options
|
||||
{
|
||||
/// <summary>
|
||||
/// SSL 证书来源平台枚举
|
||||
/// </summary>
|
||||
public enum SslPlatformEnum
|
||||
{
|
||||
/// <summary>
|
||||
/// 阿里云
|
||||
/// </summary>
|
||||
Ali = 1,
|
||||
/// <summary>
|
||||
/// 腾讯云
|
||||
/// </summary>
|
||||
Tencent = 2
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SSL 证书下载配置选项
|
||||
/// </summary>
|
||||
public class SslDownloadOption
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否启用
|
||||
/// </summary>
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Cron 定时表达式
|
||||
/// </summary>
|
||||
public string Corn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 云平台类型
|
||||
/// </summary>
|
||||
public SslPlatformEnum Platform { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 证书保存本地路径
|
||||
/// </summary>
|
||||
public string SavePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 过期天数阈值 (提前多少天开始下载更新)
|
||||
/// </summary>
|
||||
public int ExpireDays { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 需要下载的证书列表
|
||||
/// </summary>
|
||||
public List<SslDownloadItem> DownloadItems { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SSL 证书下载项详情
|
||||
/// </summary>
|
||||
public class SslDownloadItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 域名
|
||||
/// </summary>
|
||||
public string Domain { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 保存到本地的文件名 (不含后缀)
|
||||
/// </summary>
|
||||
public string FileName { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,29 @@ using Hua.DDNS.DDNSProviders.Dnspod;
|
||||
|
||||
namespace Hua.DDNS.Common.Config.Options
|
||||
{
|
||||
/// <summary>
|
||||
/// 腾讯云配置选项
|
||||
/// </summary>
|
||||
public class TencentCloudOption
|
||||
{
|
||||
/// <summary>
|
||||
/// 密钥 ID
|
||||
/// </summary>
|
||||
public string SecretId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 密钥私钥
|
||||
/// </summary>
|
||||
public string SecretKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 区域 (如 ap-guangzhou)
|
||||
/// </summary>
|
||||
public string Region { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Dnspod 相关配置 (已并入腾讯云)
|
||||
/// </summary>
|
||||
public DnspodOption Dnspod { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
using Hua.DDNS.Common.Config.Options;
|
||||
using Hua.DDNS.Common.Config.Options;
|
||||
|
||||
namespace Hua.DDNS.Common.Config
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// this is a strongly-typed configuration provider
|
||||
/// 强类型配置提供者,用于方便地访问应用程序配置
|
||||
/// </summary>
|
||||
public class SettingProvider
|
||||
{
|
||||
private readonly AppOption _app;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="configuration">配置对象</param>
|
||||
public SettingProvider(IConfiguration configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
@@ -17,6 +22,9 @@ namespace Hua.DDNS.Common.Config
|
||||
_configuration.GetSection("App").Bind(_app);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取应用程序配置选项
|
||||
/// </summary>
|
||||
public AppOption App => _app;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
namespace Hua.DDNS.Common
|
||||
namespace Hua.DDNS.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件操作助手类
|
||||
/// </summary>
|
||||
public class FileHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 如果文件存在则删除
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
public static void DeleteIfExists(string path)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
using System.Net;
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Hua.DDNS.Common.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// Http 请求助手类,用于执行各种 HTTP 请求
|
||||
/// </summary>
|
||||
public class HttpHelper: IHttpHelper
|
||||
{
|
||||
private static ILogger<HttpHelper> _logger;
|
||||
private static HttpClientHandler _handler;
|
||||
private IConfiguration _configuration;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="logger">日志对象</param>
|
||||
/// <param name="configuration">配置对象</param>
|
||||
public HttpHelper(ILogger<HttpHelper> logger, IConfiguration configuration)
|
||||
{
|
||||
_logger = logger;
|
||||
@@ -17,26 +25,30 @@ namespace Hua.DDNS.Common.Http
|
||||
_handler = new HttpClientHandler();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取 HttpClient 实例
|
||||
/// </summary>
|
||||
/// <returns>HttpClient 实例</returns>
|
||||
public HttpClient GetHttpClient()
|
||||
{
|
||||
return new HttpClient(_handler){};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PostAsync
|
||||
/// 异步执行 Post 请求并解析 JSON 结果
|
||||
/// </summary>
|
||||
/// <typeparam name="TIn"></typeparam>
|
||||
/// <typeparam name="TOut"></typeparam>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="input"></param>
|
||||
/// <param name="timeOut">超时时间</param>
|
||||
/// <returns></returns>
|
||||
/// <typeparam name="TIn">输入数据类型</typeparam>
|
||||
/// <typeparam name="TOut">输出结果类型</typeparam>
|
||||
/// <param name="url">请求地址</param>
|
||||
/// <param name="input">输入数据</param>
|
||||
/// <param name="timeOut">超时时间 (秒)</param>
|
||||
/// <returns>解析后的结果对象</returns>
|
||||
public async Task<TOut?> PostAsync<TIn, TOut>(string url, TIn input, int timeOut = 10)
|
||||
{
|
||||
try
|
||||
{
|
||||
var client = GetHttpClient();
|
||||
client.Timeout = new TimeSpan(0, 10, timeOut);
|
||||
client.Timeout = TimeSpan.FromSeconds(timeOut);
|
||||
_logger.LogDebug($"Post:{url}\n[{JsonConvert.SerializeObject(input)}]");
|
||||
var result = await client.PostAsync(url, JsonContent.Create(input));
|
||||
var strResult = await result.Content.ReadAsStringAsync();
|
||||
@@ -55,18 +67,18 @@ namespace Hua.DDNS.Common.Http
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PostAsync
|
||||
/// 异步执行 Get 请求并解析 JSON 结果
|
||||
/// </summary>
|
||||
/// <typeparam name="TOut"></typeparam>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="timeOut"></param>
|
||||
/// <returns></returns>
|
||||
/// <typeparam name="TOut">输出结果类型</typeparam>
|
||||
/// <param name="url">请求地址</param>
|
||||
/// <param name="timeOut">超时时间 (秒)</param>
|
||||
/// <returns>解析后的结果对象</returns>
|
||||
public async Task<TOut?> GetAsync<TOut>(string url,int timeOut = 10)
|
||||
{
|
||||
try
|
||||
{
|
||||
var client = GetHttpClient();
|
||||
client.Timeout = new TimeSpan(0, 10, timeOut);
|
||||
client.Timeout = TimeSpan.FromSeconds(timeOut);
|
||||
_logger.LogDebug($"Get:{url}");
|
||||
var result = await client.GetAsync(url);
|
||||
var strResult = await result.Content.ReadAsStringAsync();
|
||||
@@ -87,11 +99,11 @@ namespace Hua.DDNS.Common.Http
|
||||
#region 下载文件
|
||||
|
||||
/// <summary>
|
||||
/// http下载文件
|
||||
/// 通过 HTTP 下载文件
|
||||
/// </summary>
|
||||
/// <param name="url">下载文件地址</param>
|
||||
/// <param name="localPath">文件存放地址,包含文件名</param>
|
||||
/// <returns></returns>
|
||||
/// <param name="localPath">文件本地存放路径,包含文件名</param>
|
||||
/// <returns>下载成功返回 true,否则返回 false</returns>
|
||||
public bool DownloadFile(string url, string localPath)
|
||||
{
|
||||
try
|
||||
@@ -134,8 +146,9 @@ namespace Hua.DDNS.Common.Http
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获得当前机器的公网 Ip
|
||||
/// 获取当前机器的公网 IPv4 地址
|
||||
/// </summary>
|
||||
/// <returns>IPv4 地址字符串</returns>
|
||||
public async Task<string> GetCurrentPublicIpv4()
|
||||
{
|
||||
using var client = new HttpClient();
|
||||
@@ -146,12 +159,49 @@ namespace Hua.DDNS.Common.Http
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Http 助手接口
|
||||
/// </summary>
|
||||
public interface IHttpHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取当前机器的公网 IPv4 地址
|
||||
/// </summary>
|
||||
/// <returns>IPv4 地址字符串</returns>
|
||||
public Task<string> GetCurrentPublicIpv4();
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行 Post 请求并解析 JSON 结果
|
||||
/// </summary>
|
||||
/// <typeparam name="TIn">输入数据类型</typeparam>
|
||||
/// <typeparam name="TOut">输出结果类型</typeparam>
|
||||
/// <param name="url">请求地址</param>
|
||||
/// <param name="input">输入数据</param>
|
||||
/// <param name="timeOut">超时时间 (秒)</param>
|
||||
/// <returns>解析后的结果对象</returns>
|
||||
public Task<TOut?> PostAsync<TIn, TOut>(string url, TIn input, int timeOut = 10);
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行 Get 请求并解析 JSON 结果
|
||||
/// </summary>
|
||||
/// <typeparam name="TOut">输出结果类型</typeparam>
|
||||
/// <param name="url">请求地址</param>
|
||||
/// <param name="timeOut">超时时间 (秒)</param>
|
||||
/// <returns>解析后的结果对象</returns>
|
||||
public Task<TOut?> GetAsync<TOut>(string url, int timeOut = 10);
|
||||
|
||||
/// <summary>
|
||||
/// 通过 HTTP 下载文件
|
||||
/// </summary>
|
||||
/// <param name="url">下载文件地址</param>
|
||||
/// <param name="fileFullName">文件本地存放路径,包含文件名</param>
|
||||
/// <returns>下载成功返回 true,否则返回 false</returns>
|
||||
public bool DownloadFile(string url, string fileFullName);
|
||||
|
||||
/// <summary>
|
||||
/// 获取 HttpClient 实例
|
||||
/// </summary>
|
||||
/// <returns>HttpClient 实例</returns>
|
||||
public HttpClient GetHttpClient();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,29 @@
|
||||
namespace Hua.DDNS.Common.Http
|
||||
namespace Hua.DDNS.Common.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// Http 请求返回结果包装类
|
||||
/// </summary>
|
||||
/// <typeparam name="T">数据类型</typeparam>
|
||||
public class HttpResult<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 返回的数据内容
|
||||
/// </summary>
|
||||
public virtual T Data { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据描述信息
|
||||
/// </summary>
|
||||
public string DataDescription { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 结果状态码 (例如 200 为成功)
|
||||
/// </summary>
|
||||
public int Result { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回的消息提示
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
|
||||
}
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
using System.Data;
|
||||
using System.Data;
|
||||
using Dapper;
|
||||
using Npgsql;
|
||||
|
||||
namespace Hua.DDNS.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据库操作助手类 (基于 Npgsql 和 Dapper)
|
||||
/// </summary>
|
||||
public class SqlHelper
|
||||
{
|
||||
|
||||
private readonly string _connectionString;
|
||||
private readonly ILogger<SqlHelper> _logger;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="configuration">配置对象</param>
|
||||
/// <param name="logger">日志对象</param>
|
||||
public SqlHelper(IConfiguration configuration, ILogger<SqlHelper> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
@@ -19,10 +27,10 @@ namespace Hua.DDNS.Common
|
||||
/// <summary>
|
||||
/// 查询所有结果
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="strSql"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
/// <typeparam name="T">实体类型</typeparam>
|
||||
/// <param name="strSql">SQL 语句</param>
|
||||
/// <returns>结果列表</returns>
|
||||
/// <exception cref="Exception">数据库连接或查询异常</exception>
|
||||
public List<T> GetList<T>(string strSql)
|
||||
{
|
||||
var list = new List<T>();
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Hua.DDNS.DDNSProviders.Ali
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// DDNSProvider for Ali
|
||||
/// 阿里云 DDNS 解析提供者
|
||||
/// </summary>
|
||||
public class AliDdnsProvider : IDdnsProvider
|
||||
{
|
||||
@@ -25,6 +25,12 @@ namespace Hua.DDNS.DDNSProviders.Ali
|
||||
private readonly DdnsOption _ddnsOption;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="aliCloudOption">阿里云配置</param>
|
||||
/// <param name="mapper">对象映射器</param>
|
||||
/// <param name="ddnsOption">DDNS 配置</param>
|
||||
public AliDdnsProvider(IOptions<AliCloudOption> aliCloudOption, IMapper mapper,IOptions<DdnsOption> ddnsOption)
|
||||
{
|
||||
_aliCloudOption = aliCloudOption.Value;
|
||||
@@ -41,9 +47,9 @@ namespace Hua.DDNS.DDNSProviders.Ali
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取解析记录列表
|
||||
/// 异步获取阿里云上的域名解析记录列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <returns>解析记录列表</returns>
|
||||
public async Task<IEnumerable<DnsRecord>?> GetRecordListAsync()
|
||||
{
|
||||
var record = (await _client.DescribeDomainRecordsAsync(new DescribeDomainRecordsRequest()
|
||||
@@ -54,6 +60,11 @@ namespace Hua.DDNS.DDNSProviders.Ali
|
||||
return _mapper.Map<IEnumerable<DnsRecord>>(record);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步在阿里云上创建新的域名解析记录
|
||||
/// </summary>
|
||||
/// <param name="record">解析记录信息</param>
|
||||
/// <returns>创建后的解析记录信息</returns>
|
||||
public async Task<DnsRecord> CreateDnsRecordAsync(DnsRecord record)
|
||||
{
|
||||
var rep = await _client.AddDomainRecordAsync(_mapper.Map<AddDomainRecordRequest>(record));
|
||||
@@ -61,11 +72,11 @@ namespace Hua.DDNS.DDNSProviders.Ali
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 变更解析记录列表
|
||||
/// 异步批量修改阿里云上的域名解析记录
|
||||
/// </summary>
|
||||
/// <param name="newIp"></param>
|
||||
/// <param name="records"></param>
|
||||
/// <returns></returns>
|
||||
/// <param name="newIp">新的 IP 地址</param>
|
||||
/// <param name="records">需要修改的解析记录列表</param>
|
||||
/// <returns>修改后的解析记录列表</returns>
|
||||
public async Task<IEnumerable<DnsRecord>> ModifyRecordListAsync(string newIp, IEnumerable<DnsRecord> records)
|
||||
{
|
||||
foreach (var aliDomainRecord in records)
|
||||
@@ -75,5 +86,14 @@ namespace Hua.DDNS.DDNSProviders.Ali
|
||||
|
||||
return records;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步清理无效证书
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task CleanInvalidCertificatesAsync()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -9,22 +9,22 @@ using Hua.DDNS.DDNSProviders.Namesilo;
|
||||
namespace Hua.DDNS.DDNSProviders
|
||||
{
|
||||
/// <summary>
|
||||
/// domain configuration class
|
||||
/// DDNS 配置选项类
|
||||
/// </summary>
|
||||
public class DdnsOption
|
||||
{
|
||||
/// <summary>
|
||||
/// platform from 1 Ali 2 Tencent 3
|
||||
/// 云平台类型 (1: 阿里云, 2: 腾讯云, 3: Namesilo)
|
||||
/// </summary>
|
||||
public PlatformEnum Platform { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// domain
|
||||
/// 根域名 (例如: example.com)
|
||||
/// </summary>
|
||||
public string Domain { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// sub domain, eg. www,git
|
||||
/// 需要更新的子域名列表 (例如: ["www", "api", "@"])
|
||||
/// </summary>
|
||||
public string[] SubDomainArray { get; set; }
|
||||
|
||||
|
||||
@@ -18,8 +18,7 @@ namespace Hua.DDNS.DDNSProviders.Dnspod
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// DdnsProvider for Dnspod
|
||||
/// <remarks></remarks>
|
||||
/// Dnspod (腾讯云) DDNS 解析提供者
|
||||
/// </summary>
|
||||
public class DnspodDdnsProvider : IDdnsProvider
|
||||
{
|
||||
@@ -29,6 +28,12 @@ namespace Hua.DDNS.DDNSProviders.Dnspod
|
||||
private readonly DdnsOption _ddnsOption;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="mapper">对象映射器</param>
|
||||
/// <param name="tencentCloudOption">腾讯云配置</param>
|
||||
/// <param name="ddnsOption">DDNS 配置</param>
|
||||
public DnspodDdnsProvider(IMapper mapper, IOptions<TencentCloudOption> tencentCloudOption, IOptions<DdnsOption> ddnsOption)
|
||||
{
|
||||
_mapper = mapper;
|
||||
@@ -44,6 +49,10 @@ namespace Hua.DDNS.DDNSProviders.Dnspod
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步获取 Dnspod 上的域名解析记录列表
|
||||
/// </summary>
|
||||
/// <returns>解析记录列表</returns>
|
||||
public async Task<IEnumerable<DnsRecord>?> GetRecordListAsync()
|
||||
{
|
||||
var recordList = (await _client.DescribeRecordList(new DescribeRecordListRequest() { Domain = _ddnsOption.Domain })).RecordList;
|
||||
@@ -51,6 +60,11 @@ namespace Hua.DDNS.DDNSProviders.Dnspod
|
||||
return _mapper.Map<IEnumerable<DnsRecord>>(recordList);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步在 Dnspod 上创建新的域名解析记录
|
||||
/// </summary>
|
||||
/// <param name="record">解析记录信息</param>
|
||||
/// <returns>创建后的解析记录信息</returns>
|
||||
public async Task<DnsRecord> CreateDnsRecordAsync(DnsRecord record)
|
||||
{
|
||||
var response = await _client.CreateRecord(new CreateRecordRequest()
|
||||
@@ -64,6 +78,12 @@ namespace Hua.DDNS.DDNSProviders.Dnspod
|
||||
return record;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步批量修改 Dnspod 上的域名解析记录
|
||||
/// </summary>
|
||||
/// <param name="newIp">新的 IP 地址</param>
|
||||
/// <param name="records">需要修改的解析记录列表</param>
|
||||
/// <returns>修改后的解析记录列表</returns>
|
||||
public async Task<IEnumerable<DnsRecord>> ModifyRecordListAsync(string newIp, IEnumerable<DnsRecord> records)
|
||||
{
|
||||
var rep = await _client.ModifyRecordBatch(new ModifyRecordBatchRequest()
|
||||
@@ -74,5 +94,14 @@ namespace Hua.DDNS.DDNSProviders.Dnspod
|
||||
});
|
||||
return records;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步清理无效证书
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task CleanInvalidCertificatesAsync()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
namespace Hua.DDNS.DDNSProviders.Dnspod
|
||||
{
|
||||
/// <summary>
|
||||
/// domain configuration Dnspod
|
||||
/// Dnspod 配置选项
|
||||
/// </summary>
|
||||
public class DnspodOption
|
||||
{
|
||||
/// <summary>
|
||||
/// Endpoint dnspod.tencentcloudapi.com
|
||||
/// 接口访问端点 (例如: dnspod.tencentcloudapi.com)
|
||||
/// </summary>
|
||||
public string Endpoint { get; set; }
|
||||
}
|
||||
|
||||
@@ -9,32 +9,37 @@ namespace Hua.DDNS.DDNSProviders
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Dynamic domain name resolution provider
|
||||
/// 动态域名解析 (DDNS) 提供者接口
|
||||
/// </summary>
|
||||
public interface IDdnsProvider
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 获取域名解析记录列表
|
||||
/// 异步获取域名解析记录列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
|
||||
/// <returns>域名解析记录列表</returns>
|
||||
Task<IEnumerable<DnsRecord>?> GetRecordListAsync();
|
||||
|
||||
/// <summary>
|
||||
/// 创建解析记录
|
||||
/// 异步创建新的域名解析记录
|
||||
/// </summary>
|
||||
/// <param name="record"></param>
|
||||
/// <returns></returns>
|
||||
/// <param name="record">解析记录信息</param>
|
||||
/// <returns>创建后的解析记录信息</returns>
|
||||
Task<DnsRecord> CreateDnsRecordAsync(DnsRecord record);
|
||||
|
||||
/// <summary>
|
||||
/// 修改域名解析记录
|
||||
/// 异步批量修改域名解析记录 (通常用于更新 IP)
|
||||
/// </summary>
|
||||
/// <param name="newIp"></param>
|
||||
/// <param name="records"></param>
|
||||
/// <returns></returns>
|
||||
/// <param name="newIp">新的 IP 地址</param>
|
||||
/// <param name="records">需要修改的解析记录列表</param>
|
||||
/// <returns>修改后的解析记录列表</returns>
|
||||
Task<IEnumerable<DnsRecord>> ModifyRecordListAsync(string newIp, IEnumerable<DnsRecord> records);
|
||||
|
||||
/// <summary>
|
||||
/// 异步清理无效证书
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task CleanInvalidCertificatesAsync();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Xml;
|
||||
using System.Xml;
|
||||
using AutoMapper;
|
||||
using Hua.DDNS.Models;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
@@ -8,13 +8,18 @@ using Newtonsoft.Json;
|
||||
namespace Hua.DDNS.DDNSProviders.Namesilo
|
||||
{
|
||||
/// <summary>
|
||||
/// DDNSProvider for namesilo
|
||||
/// Namesilo DDNS 解析提供者
|
||||
/// </summary>
|
||||
public class NamesiloDdnsProvider : IDdnsProvider
|
||||
{
|
||||
public readonly NamesiloOption _namesiloOption;
|
||||
public readonly DdnsOption _ddnsOption;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="namesiloOption">Namesilo 配置</param>
|
||||
/// <param name="ddnsOption">DDNS 配置</param>
|
||||
public NamesiloDdnsProvider(IOptions<NamesiloOption> namesiloOption, IOptions<DdnsOption> ddnsOption)
|
||||
{
|
||||
_ddnsOption = ddnsOption.Value;
|
||||
@@ -22,6 +27,10 @@ namespace Hua.DDNS.DDNSProviders.Namesilo
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 异步获取 Namesilo 上的域名解析记录列表
|
||||
/// </summary>
|
||||
/// <returns>解析记录列表</returns>
|
||||
public async Task<IEnumerable<DnsRecord>?> GetRecordListAsync()
|
||||
{
|
||||
var client = new HttpClient();
|
||||
@@ -62,6 +71,11 @@ namespace Hua.DDNS.DDNSProviders.Namesilo
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步在 Namesilo 上创建新的域名解析记录
|
||||
/// </summary>
|
||||
/// <param name="dnsRecord">解析记录信息</param>
|
||||
/// <returns>创建后的解析记录信息</returns>
|
||||
public async Task<DnsRecord> CreateDnsRecordAsync(DnsRecord dnsRecord)
|
||||
{
|
||||
var host = dnsRecord.Host[..(dnsRecord.Host.Length - dnsRecord.Domain.Length - 1)];
|
||||
@@ -91,6 +105,12 @@ namespace Hua.DDNS.DDNSProviders.Namesilo
|
||||
return dnsRecord;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步批量修改 Namesilo 上的域名解析记录
|
||||
/// </summary>
|
||||
/// <param name="newIp">新的 IP 地址</param>
|
||||
/// <param name="records">需要修改的解析记录列表</param>
|
||||
/// <returns>修改后的解析记录列表</returns>
|
||||
public async Task<IEnumerable<DnsRecord>> ModifyRecordListAsync(string newIp, IEnumerable<DnsRecord> records)
|
||||
{
|
||||
foreach (var dnsRecord in records)
|
||||
@@ -122,5 +142,14 @@ namespace Hua.DDNS.DDNSProviders.Namesilo
|
||||
|
||||
return records;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步清理无效证书
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task CleanInvalidCertificatesAsync()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
namespace Hua.DDNS.DDNSProviders.Namesilo
|
||||
namespace Hua.DDNS.DDNSProviders.Namesilo
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Namesilo Option
|
||||
/// Namesilo 配置选项
|
||||
/// </summary>
|
||||
public class NamesiloOption
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// API key
|
||||
/// API 密钥
|
||||
/// </summary>
|
||||
public string ApiKey { get; set; }
|
||||
|
||||
|
||||
+22
-2
@@ -25,6 +25,9 @@ using System.Net.Sockets;
|
||||
|
||||
namespace Hua.DDNS.Jobs
|
||||
{
|
||||
/// <summary>
|
||||
/// 新的 DDNS 任务类,用于定期检查并更新域名解析记录
|
||||
/// </summary>
|
||||
[DisallowConcurrentExecution]
|
||||
public class NewJob : IJob, IDisposable
|
||||
{
|
||||
@@ -32,10 +35,19 @@ namespace Hua.DDNS.Jobs
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly DdnsOption _ddnsOption;
|
||||
private readonly IHttpHelper _httpHelper;
|
||||
|
||||
/// <summary>
|
||||
/// 新的 IP 地址
|
||||
/// </summary>
|
||||
public string newIp;
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="logger">日志对象</param>
|
||||
/// <param name="httpHelper">Http 助手</param>
|
||||
/// <param name="ddnsOption">DDNS 配置选项</param>
|
||||
/// <param name="serviceProvider">服务提供者</param>
|
||||
public NewJob(ILogger<NewJob> logger,IHttpHelper httpHelper,IOptions<DdnsOption> ddnsOption, IServiceProvider serviceProvider)
|
||||
{
|
||||
_logger = logger;
|
||||
@@ -43,6 +55,11 @@ namespace Hua.DDNS.Jobs
|
||||
_serviceProvider = serviceProvider;
|
||||
_ddnsOption = ddnsOption.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行任务逻辑
|
||||
/// </summary>
|
||||
/// <param name="context">作业执行上下文</param>
|
||||
public async Task Execute(IJobExecutionContext context)
|
||||
{
|
||||
|
||||
@@ -98,6 +115,9 @@ namespace Hua.DDNS.Jobs
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放资源
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
_logger.LogInformation("AppJob已销毁");
|
||||
|
||||
@@ -8,6 +8,9 @@ using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace Hua.DDNS.Jobs
|
||||
{
|
||||
/// <summary>
|
||||
/// SSL 证书下载任务类,用于定期检查并更新 SSL 证书
|
||||
/// </summary>
|
||||
[DisallowConcurrentExecution]
|
||||
public class SslDownloadJob : IJob, IDisposable
|
||||
{
|
||||
@@ -15,6 +18,12 @@ namespace Hua.DDNS.Jobs
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly SslDownloadOption _sslDownloadOption;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="logger">日志对象</param>
|
||||
/// <param name="serviceProvider">服务提供者</param>
|
||||
/// <param name="sslDownloadOption">SSL 下载配置选项</param>
|
||||
public SslDownloadJob(
|
||||
ILogger<SslDownloadJob> logger,
|
||||
IServiceProvider serviceProvider,
|
||||
@@ -25,6 +34,10 @@ namespace Hua.DDNS.Jobs
|
||||
_sslDownloadOption = sslDownloadOption.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行任务逻辑
|
||||
/// </summary>
|
||||
/// <param name="context">作业执行上下文</param>
|
||||
public async Task Execute(IJobExecutionContext context)
|
||||
{
|
||||
if (!_sslDownloadOption.Enabled)
|
||||
@@ -110,6 +123,11 @@ namespace Hua.DDNS.Jobs
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取本地证书的过期时间
|
||||
/// </summary>
|
||||
/// <param name="item">下载项</param>
|
||||
/// <returns>过期时间,如果不存在则返回 null</returns>
|
||||
private DateTime? GetLocalCertificateExpiry(SslDownloadItem item)
|
||||
{
|
||||
try
|
||||
@@ -137,6 +155,14 @@ namespace Hua.DDNS.Jobs
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步下载证书文件
|
||||
/// </summary>
|
||||
/// <param name="provider">SSL 提供者</param>
|
||||
/// <param name="item">下载项</param>
|
||||
/// <param name="certificateId">证书 ID</param>
|
||||
/// <param name="domain">域名</param>
|
||||
/// <returns>Task</returns>
|
||||
private async Task DownloadFileAsync(ISslDownloadProvider provider, SslDownloadItem item, string certificateId, string domain)
|
||||
{
|
||||
try
|
||||
@@ -169,6 +195,9 @@ namespace Hua.DDNS.Jobs
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放资源
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
_logger.LogInformation("SslDownloadJob已销毁");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -6,22 +6,60 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Hua.DDNS.Models;
|
||||
|
||||
/// <summary>
|
||||
/// 域名解析记录实体类
|
||||
/// </summary>
|
||||
public class DnsRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// 解析记录 ID
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// IP 地址
|
||||
/// </summary>
|
||||
public string Ip { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 主机记录 (例如: www)
|
||||
/// </summary>
|
||||
public string Host { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子域名 (通常与 Host 相同)
|
||||
/// </summary>
|
||||
public string SubDomain { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 根域名 (例如: example.com)
|
||||
/// </summary>
|
||||
public string Domain { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 生存时间 (TTL)
|
||||
/// </summary>
|
||||
public string TTL { get; set; } = "10";
|
||||
|
||||
/// <summary>
|
||||
/// 记录类型 (A, AAAA, CNAME 等)
|
||||
/// </summary>
|
||||
public string RecordType { get; set; } = "A";
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="ip">IP 地址</param>
|
||||
/// <param name="domain">域名</param>
|
||||
public DnsRecord(string ip,string domain)
|
||||
{
|
||||
Ip = ip;
|
||||
Host = domain;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 默认构造函数
|
||||
/// </summary>
|
||||
public DnsRecord()
|
||||
{
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -10,8 +10,14 @@ using TencentCloud.Dnspod.V20210323.Models;
|
||||
|
||||
namespace Hua.DDNS.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// AutoMapper 对象映射配置类
|
||||
/// </summary>
|
||||
public class MappingProfile : Profile
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数,配置映射规则
|
||||
/// </summary>
|
||||
public MappingProfile()
|
||||
{
|
||||
CreateMap<DescribeDomainRecordsResponseBody.DescribeDomainRecordsResponseBodyDomainRecords.DescribeDomainRecordsResponseBodyDomainRecordsRecord, DnsRecord>()
|
||||
|
||||
@@ -8,12 +8,20 @@ using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Hua.DDNS.SslProviders.Ali
|
||||
{
|
||||
/// <summary>
|
||||
/// 阿里云 SSL 证书下载提供者
|
||||
/// </summary>
|
||||
public class AliSslProvider : ISslDownloadProvider
|
||||
{
|
||||
private readonly Client _client;
|
||||
private readonly AliCloudOption _aliCloudOption;
|
||||
private readonly ILogger<AliSslProvider> _logger;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="logger">日志对象</param>
|
||||
/// <param name="aliCloudOption">阿里云配置</param>
|
||||
public AliSslProvider(
|
||||
ILogger<AliSslProvider> logger,
|
||||
IOptions<AliCloudOption> aliCloudOption)
|
||||
@@ -31,12 +39,40 @@ namespace Hua.DDNS.SslProviders.Ali
|
||||
_client = new Client(config);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步获取阿里云上的 SSL 证书列表
|
||||
/// </summary>
|
||||
/// <returns>证书列表</returns>
|
||||
public async Task<List<SslCertificate>> GetCertificatesAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogWarning("阿里云 SSL 证书列表功能待实现");
|
||||
return new List<SslCertificate>();
|
||||
var request = new ListUserCertificateOrderRequest
|
||||
{
|
||||
OrderType = "CERT",
|
||||
Status = "ISSUED" // 也可以不设置,获取所有
|
||||
};
|
||||
|
||||
var response = await _client.ListUserCertificateOrderAsync(request);
|
||||
var certificates = new List<SslCertificate>();
|
||||
|
||||
if (response.Body.CertificateOrderList != null)
|
||||
{
|
||||
foreach (var cert in response.Body.CertificateOrderList)
|
||||
{
|
||||
certificates.Add(new SslCertificate
|
||||
{
|
||||
CertificateId = cert.CertificateId.ToString(),
|
||||
Domain = cert.Domain,
|
||||
Alias = cert.Name,
|
||||
CertEndTime = string.IsNullOrEmpty(cert.EndDate) ? DateTime.MinValue : DateTime.Parse(cert.EndDate),
|
||||
StatusMsg = cert.Status
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_logger.LogInformation($"获取到 {certificates.Count} 个阿里云 SSL 证书");
|
||||
return certificates;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -45,10 +81,18 @@ namespace Hua.DDNS.SslProviders.Ali
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步下载阿里云上的指定的 SSL 证书
|
||||
/// </summary>
|
||||
/// <param name="certificateId">证书 ID</param>
|
||||
/// <param name="savePath">本地保存目录路径</param>
|
||||
/// <param name="fileName">保存的文件名 (不含后缀)</param>
|
||||
/// <returns>下载成功返回 true,否则返回 false</returns>
|
||||
public async Task<bool> DownloadCertificateAsync(string certificateId, string savePath, string fileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
// TODO: 阿里云证书下载逻辑
|
||||
_logger.LogWarning($"阿里云 SSL 证书下载功能待实现: {certificateId}");
|
||||
return false;
|
||||
}
|
||||
@@ -58,5 +102,41 @@ namespace Hua.DDNS.SslProviders.Ali
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步清理无效证书
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task CleanInvalidCertificatesAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var certificates = await GetCertificatesAsync();
|
||||
// 筛选过期的证书
|
||||
var expiredCertificates = certificates.Where(c => c.CertEndTime != DateTime.MinValue && c.CertEndTime < DateTime.Now).ToList();
|
||||
|
||||
foreach (var cert in expiredCertificates)
|
||||
{
|
||||
try
|
||||
{
|
||||
var deleteRequest = new DeleteUserCertificateRequest
|
||||
{
|
||||
CertId = long.Parse(cert.CertificateId)
|
||||
};
|
||||
await _client.DeleteUserCertificateAsync(deleteRequest);
|
||||
_logger.LogInformation($"已删除阿里云过期证书: {cert.Domain} ({cert.CertificateId}), 过期时间: {cert.CertEndTime}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, $"删除阿里云证书失败: {cert.CertificateId}");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "清理阿里云无效证书失败");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,70 @@
|
||||
namespace Hua.DDNS.SslProviders
|
||||
{
|
||||
/// <summary>
|
||||
/// SSL 证书下载提供者接口
|
||||
/// </summary>
|
||||
public interface ISslDownloadProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// 异步获取 SSL 证书列表
|
||||
/// </summary>
|
||||
/// <returns>证书信息列表</returns>
|
||||
Task<List<SslCertificate>> GetCertificatesAsync();
|
||||
|
||||
/// <summary>
|
||||
/// 异步下载指定的 SSL 证书
|
||||
/// </summary>
|
||||
/// <param name="certificateId">证书 ID</param>
|
||||
/// <param name="savePath">本地保存目录路径</param>
|
||||
/// <param name="fileName">保存的文件名 (不含后缀)</param>
|
||||
/// <returns>下载成功返回 true,否则返回 false</returns>
|
||||
Task<bool> DownloadCertificateAsync(string certificateId, string savePath, string fileName);
|
||||
|
||||
/// <summary>
|
||||
/// 异步清理无效证书
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task CleanInvalidCertificatesAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SSL 证书信息类
|
||||
/// </summary>
|
||||
public class SslCertificate
|
||||
{
|
||||
/// <summary>
|
||||
/// 证书 ID
|
||||
/// </summary>
|
||||
public string CertificateId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 证书关联的域名
|
||||
/// </summary>
|
||||
public string Domain { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 证书别名
|
||||
/// </summary>
|
||||
public string Alias { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 证书生效时间
|
||||
/// </summary>
|
||||
public DateTime CertBeginTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 证书过期时间
|
||||
/// </summary>
|
||||
public DateTime CertEndTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态码
|
||||
/// </summary>
|
||||
public int Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态消息
|
||||
/// </summary>
|
||||
public string StatusMsg { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,12 +10,20 @@ using System.IO.Compression;
|
||||
|
||||
namespace Hua.DDNS.SslProviders.Tencent
|
||||
{
|
||||
/// <summary>
|
||||
/// 腾讯云 SSL 证书下载提供者
|
||||
/// </summary>
|
||||
public class TencentSslProvider : ISslDownloadProvider
|
||||
{
|
||||
private readonly SslClient _client;
|
||||
private readonly TencentCloudOption _tencentCloudOption;
|
||||
private readonly ILogger<TencentSslProvider> _logger;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="logger">日志对象</param>
|
||||
/// <param name="tencentCloudOption">腾讯云配置</param>
|
||||
public TencentSslProvider(
|
||||
ILogger<TencentSslProvider> logger,
|
||||
IOptions<TencentCloudOption> tencentCloudOption)
|
||||
@@ -32,6 +40,10 @@ namespace Hua.DDNS.SslProviders.Tencent
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步获取腾讯云上的 SSL 证书列表
|
||||
/// </summary>
|
||||
/// <returns>证书信息列表</returns>
|
||||
public async Task<List<SslCertificate>> GetCertificatesAsync()
|
||||
{
|
||||
try
|
||||
@@ -72,6 +84,13 @@ namespace Hua.DDNS.SslProviders.Tencent
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步下载腾讯云上的指定的 SSL 证书
|
||||
/// </summary>
|
||||
/// <param name="certificateId">证书 ID</param>
|
||||
/// <param name="savePath">本地保存目录路径</param>
|
||||
/// <param name="fileName">保存的文件名 (不含后缀)</param>
|
||||
/// <returns>下载成功返回 true,否则返回 false</returns>
|
||||
public async Task<bool> DownloadCertificateAsync(string certificateId, string savePath, string fileName)
|
||||
{
|
||||
string tempZipPath = null;
|
||||
@@ -172,5 +191,41 @@ namespace Hua.DDNS.SslProviders.Tencent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步清理无效证书
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task CleanInvalidCertificatesAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var certificates = await GetCertificatesAsync();
|
||||
// 清理已过期的证书 (Status 为 10 或者当前时间已过过期时间)
|
||||
var expiredCertificates = certificates.Where(c => c.CertEndTime < DateTime.Now || c.Status == 10).ToList();
|
||||
|
||||
foreach (var cert in expiredCertificates)
|
||||
{
|
||||
try
|
||||
{
|
||||
var deleteRequest = new DeleteCertificateRequest
|
||||
{
|
||||
CertificateId = cert.CertificateId
|
||||
};
|
||||
await _client.DeleteCertificate(deleteRequest);
|
||||
_logger.LogInformation($"已删除腾讯云过期证书: {cert.Domain} ({cert.CertificateId}), 过期时间: {cert.CertEndTime}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, $"删除腾讯云证书失败: {cert.CertificateId}");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "清理腾讯云无效证书失败");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+40
-17
@@ -18,10 +18,18 @@ using Serilog.Extensions.Logging;
|
||||
|
||||
namespace Hua.DDNS.Start
|
||||
{
|
||||
/// <summary>
|
||||
/// 应用程序入口类
|
||||
/// </summary>
|
||||
public static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// 主入口方法
|
||||
/// </summary>
|
||||
/// <param name="args">命令行参数</param>
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
// 配置 Serilog 日志
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.Enrich.FromLogContext()
|
||||
.WriteTo.Console()
|
||||
@@ -33,13 +41,18 @@ namespace Hua.DDNS.Start
|
||||
await CreateHostBuilder(args).Build().RunAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建并配置宿主构造器
|
||||
/// </summary>
|
||||
/// <param name="args">命令行参数</param>
|
||||
/// <returns>IHostBuilder 实例</returns>
|
||||
private static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.UseWindowsService()
|
||||
.UseSerilog()
|
||||
.UseWindowsService() // 支持作为 Windows 服务运行
|
||||
.UseSerilog() // 使用 Serilog 替代默认日志
|
||||
.ConfigureAppConfiguration((context, config) =>
|
||||
{
|
||||
// clear all config provider
|
||||
// 清理并重新配置配置源
|
||||
config.Sources.Clear();
|
||||
config
|
||||
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||
@@ -49,15 +62,25 @@ namespace Hua.DDNS.Start
|
||||
.ConfigureServices((hostContext, services) =>
|
||||
{
|
||||
services.AddAutoMapper(Assembly.GetExecutingAssembly());
|
||||
|
||||
// 绑定配置选项
|
||||
services.Configure<DdnsOption>(hostContext.Configuration.GetSection("DDNS"));
|
||||
services.Configure<NamesiloOption>(hostContext.Configuration.GetSection("Namesilo"));
|
||||
services.Configure<TencentCloudOption>(hostContext.Configuration.GetSection("TencentCloud"));
|
||||
services.Configure<AliCloudOption>(hostContext.Configuration.GetSection("AliCloud"));
|
||||
services.Configure<SslDownloadOption>(hostContext.Configuration.GetSection("SslDownload"));
|
||||
|
||||
// 配置依赖注入和 Quartz
|
||||
ConfigDi(hostContext, services);
|
||||
ConfigQuartz(hostContext, services);
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// 配置依赖注入 (DI)
|
||||
/// </summary>
|
||||
/// <param name="hostContext">宿主上下文</param>
|
||||
/// <param name="services">服务集合</param>
|
||||
/// <returns>IServiceProvider 实例</returns>
|
||||
public static IServiceProvider ConfigDi(HostBuilderContext hostContext, IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<SettingProvider>();
|
||||
@@ -72,29 +95,31 @@ namespace Hua.DDNS.Start
|
||||
return services.BuildServiceProvider();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置 Quartz 定时任务
|
||||
/// </summary>
|
||||
/// <param name="hostContext">宿主上下文</param>
|
||||
/// <param name="services">服务集合</param>
|
||||
private static void ConfigQuartz(HostBuilderContext hostContext, IServiceCollection services)
|
||||
{
|
||||
// if you are using persistent job store, you might want to alter some options
|
||||
// 配置 Quartz 选项
|
||||
services.Configure<QuartzOptions>(options =>
|
||||
{
|
||||
options.Scheduling.IgnoreDuplicates = true; // default: false
|
||||
options.Scheduling.OverWriteExistingData = true; // default: true
|
||||
options.Scheduling.IgnoreDuplicates = true; // 忽略重复任务
|
||||
options.Scheduling.OverWriteExistingData = true; // 覆盖现有数据
|
||||
});
|
||||
|
||||
// base configuration for DI
|
||||
// 添加 Quartz 服务
|
||||
services.AddQuartz(q =>
|
||||
{
|
||||
// handy when part of cluster or you want to otherwise identify ltiple schedulers
|
||||
q.SchedulerId = "Hua.DDNS.Demo";
|
||||
// this is default configuration if you don't alter it
|
||||
q.UseMicrosoftDependencyInjectionJobFactory();
|
||||
|
||||
// these are the defaults
|
||||
q.UseSimpleTypeLoader();
|
||||
q.UseInMemoryStore();
|
||||
q.UseDefaultThreadPool(tp => { tp.MaxConcurrency = 10; });
|
||||
|
||||
//configure jobs with code
|
||||
// 配置 DDNS 任务 (NewJob)
|
||||
var appJobKey = new JobKey("NewJob", "NewJobGroup");
|
||||
q.AddJob<NewJob>(j => j
|
||||
.StoreDurably()
|
||||
@@ -110,6 +135,7 @@ namespace Hua.DDNS.Start
|
||||
.StartNow()
|
||||
);
|
||||
|
||||
// 配置 SSL 下载任务 (SslDownloadJob)
|
||||
var sslDownloadJobKey = new JobKey("SslDownloadJob", "SslDownloadJobGroup");
|
||||
q.AddJob<SslDownloadJob>(j => j
|
||||
.StoreDurably()
|
||||
@@ -132,14 +158,11 @@ namespace Hua.DDNS.Start
|
||||
}
|
||||
});
|
||||
|
||||
// Quartz.Extensions.Hosting hosting
|
||||
// 添加 Quartz 托管服务
|
||||
services.AddQuartzHostedService(options =>
|
||||
{
|
||||
// when shutting down we want jobs to complete gracefully
|
||||
options.WaitForJobsToComplete = true;
|
||||
|
||||
// when we need to init another IHostedServices first
|
||||
options.StartDelay = TimeSpan.FromSeconds(10);
|
||||
options.WaitForJobsToComplete = true; // 优雅退出
|
||||
options.StartDelay = TimeSpan.FromSeconds(10); // 启动延迟
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user