diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..3729ff0 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,25 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/Hua.DDNS.Test/AppJobTest.cs b/Hua.DDNS.Test/AppJobTest.cs new file mode 100644 index 0000000..2ab5558 --- /dev/null +++ b/Hua.DDNS.Test/AppJobTest.cs @@ -0,0 +1,35 @@ +using Hua.DDNS.Jobs; +using Hua.DDNS.Test.Start; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Serilog; + +namespace Hua.DDNS.Test +{ + public class AppJobTest + { + [Theory] + [InlineData("appsetting.Ali.json")] + [InlineData("appsetting.Tencent.json")] + public void UpdateDNS(string configPath) + { + try + { + var config = new ConfigurationBuilder() + .SetBasePath(AppContext.BaseDirectory) + .AddJsonFile(configPath, true) + .AddEnvironmentVariables()// 把环境变量也放到 Configuraiton当中 + .Build(); + + var sc = DIConfig.ConfigureServices(config); + var job = sc.GetService(); + + job?.Execute(null); + } + catch (Exception e) + { + Assert.False(false, $"请求异常:{e.Message}"); + } + } + } +} \ No newline at end of file diff --git a/Hua.DDNS.Test/Hua.DDNS.Test.csproj b/Hua.DDNS.Test/Hua.DDNS.Test.csproj new file mode 100644 index 0000000..60b9d56 --- /dev/null +++ b/Hua.DDNS.Test/Hua.DDNS.Test.csproj @@ -0,0 +1,37 @@ +锘 + + + net6.0 + enable + enable + + false + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + + diff --git a/Hua.DDNS.Test/Start/DIConfig.cs b/Hua.DDNS.Test/Start/DIConfig.cs new file mode 100644 index 0000000..0059226 --- /dev/null +++ b/Hua.DDNS.Test/Start/DIConfig.cs @@ -0,0 +1,48 @@ +锘縰sing System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Hua.DDNS.Common.Config; +using Hua.DDNS.Common.Http; +using Hua.DDNS.Common; +using Hua.DDNS.Jobs; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Serilog; + +namespace Hua.DDNS.Test.Start +{ + public class DIConfig + { + public static IServiceProvider ConfigureServices(IConfiguration configuration) + { + Log.Logger = new LoggerConfiguration() + .Enrich.FromLogContext() + .WriteTo.Console() + .WriteTo.File( + Path.Combine("Log\\log-.log"), + rollingInterval: RollingInterval.Day) + .CreateLogger(); + + var services = new ServiceCollection(); + services.AddSingleton(configuration); + services.AddLogging(loggingBuilder => + { + loggingBuilder.AddConfiguration(configuration.GetSection("Logging")); //閰嶇疆logging鐨勪竴浜涗笢瑗 + // 涓嬮潰鐨勮繖琛岄渶瑕 Microsoft.Extensions.Logging.Console + loggingBuilder.AddConsole(); //鍔犲涓 姣忎竴涓狪looger涓嬮潰灏变細鏈夊涓猵rovider + }); + + // 娉ㄥ叆浜嗕竴涓粯璁ょ殑ILogger + services.AddSingleton(); + //services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddTransient(); + services.AddTransient(); + return services.BuildServiceProvider(); + } + } +} diff --git a/Hua.DDNS.Test/Usings.cs b/Hua.DDNS.Test/Usings.cs new file mode 100644 index 0000000..8c927eb --- /dev/null +++ b/Hua.DDNS.Test/Usings.cs @@ -0,0 +1 @@ +global using Xunit; \ No newline at end of file diff --git a/Hua.DDNS.Test/appsettings.Ali.json b/Hua.DDNS.Test/appsettings.Ali.json new file mode 100644 index 0000000..017d446 --- /dev/null +++ b/Hua.DDNS.Test/appsettings.Ali.json @@ -0,0 +1,32 @@ +{ + "ConnectionStrings": { + "pgConnection": "Host=127.0.0.1;Port=5432;Database=Worker;Username=Worker;Password=123456;" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "App": { + "AppJob": { + "Corn": "* * * * * ?" //https://cron.qqe2.com/ + }, + + "Domain": { + "Platform": "Ali", + // 闃块噷浜戠殑 Access Id + "Id": "AliId", + // 闃块噷浜戠殑 Access Key + "Key": "AliKey", + // 涓诲煙鍚 + "domain": "demoDomain.cn", + // 瀛愬煙鍚嶅墠缂 + "subDomainArray": [ "bjb", "git" ], + // 璁板綍绫诲瀷 + "type": "A", + //闂撮殧鏃堕棿 绉 + "time": "30" + } + } +} \ No newline at end of file diff --git a/Hua.DDNS.Test/appsettings.Tencent.json b/Hua.DDNS.Test/appsettings.Tencent.json new file mode 100644 index 0000000..6c1c090 --- /dev/null +++ b/Hua.DDNS.Test/appsettings.Tencent.json @@ -0,0 +1,32 @@ +{ + "ConnectionStrings": { + "pgConnection": "Host=127.0.0.1;Port=5432;Database=Worker;Username=Worker;Password=123456;" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "App": { + "AppJob": { + "Corn": "* * * * * ?" //https://cron.qqe2.com/ + }, + + "Domain": { + "Platform": "Tencent", + // 闃块噷浜戠殑 Access Id + "Id": "Id", + // 闃块噷浜戠殑 Access Key + "Key": "Key", + // 涓诲煙鍚 + "domain": "demoDomain.cn", + // 瀛愬煙鍚嶅墠缂 + "subDomainArray": [ "bjb", "git" ], + // 璁板綍绫诲瀷 + "type": "A", + //闂撮殧鏃堕棿 绉 + "time": "30" + } + } +} \ No newline at end of file diff --git a/Hua.DDNS.sln b/Hua.DDNS.sln new file mode 100644 index 0000000..0dabc6c --- /dev/null +++ b/Hua.DDNS.sln @@ -0,0 +1,31 @@ +锘 +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 diff --git a/Hua.DDNS/Common/Config/Options/AppOption.cs b/Hua.DDNS/Common/Config/Options/AppOption.cs new file mode 100644 index 0000000..9565706 --- /dev/null +++ b/Hua.DDNS/Common/Config/Options/AppOption.cs @@ -0,0 +1,8 @@ +锘縩amespace Hua.DDNS.Common.Config.Options +{ + + public class AppOption + { + public DomainOption Domain { get; set; } + } +} diff --git a/Hua.DDNS/Common/Config/Options/DomainOption.cs b/Hua.DDNS/Common/Config/Options/DomainOption.cs new file mode 100644 index 0000000..622d980 --- /dev/null +++ b/Hua.DDNS/Common/Config/Options/DomainOption.cs @@ -0,0 +1,50 @@ +锘縰sing System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Hua.DDNS.Common.Config.Options +{ + + + public class DomainOption + { + /// + /// 骞冲彴 + /// + public string Platform { get; set; } + + /// + /// Id + /// + public string Id { get; set; } + + /// + /// Key + /// + public string Key { get; set; } + + /// + /// 鍩熷悕 + /// + public string domain { get; set; } + + /// + /// 瀛愬煙鍒楄〃 + /// + public string[] subDomainArray { get; set; } + + + /// + /// 瑙f瀽璁板綍绫诲瀷 + /// + public string type { get; set; } + + /// + /// 闂撮殧鏃堕棿 绉 + /// + public string time { get; set; } + } + +} diff --git a/Hua.DDNS/Common/Config/SettingProvider.cs b/Hua.DDNS/Common/Config/SettingProvider.cs new file mode 100644 index 0000000..35dfaa6 --- /dev/null +++ b/Hua.DDNS/Common/Config/SettingProvider.cs @@ -0,0 +1,17 @@ +锘縰sing Hua.DDNS.Common.Config.Options; + +namespace Hua.DDNS.Common.Config +{ + public class SettingProvider + { + private readonly AppOption _app; + public SettingProvider(IConfiguration configuration) + { + _app = new AppOption(); + configuration.GetSection("App").Bind(_app); + } + + public AppOption App => _app; + } + +} diff --git a/Hua.DDNS/Common/FileHelper.cs b/Hua.DDNS/Common/FileHelper.cs new file mode 100644 index 0000000..5afd469 --- /dev/null +++ b/Hua.DDNS/Common/FileHelper.cs @@ -0,0 +1,13 @@ +锘縩amespace Hua.DDNS.Common +{ + public class FileHelper + { + public static void DeleteIfExists(string path) + { + if (File.Exists(path)) + { + File.Delete(path); + } + } + } +} diff --git a/Hua.DDNS/Common/Http/HttpHelper.cs b/Hua.DDNS/Common/Http/HttpHelper.cs new file mode 100644 index 0000000..06af31b --- /dev/null +++ b/Hua.DDNS/Common/Http/HttpHelper.cs @@ -0,0 +1,141 @@ +锘縰sing System.Net; +using System.Net.Http.Json; +using Newtonsoft.Json; + +namespace Hua.DDNS.Common.Http +{ + public class HttpHelper: IHttpHelper + { + private static ILogger _logger; + private static HttpClientHandler _handler; + + public HttpHelper(ILogger logger) + { + _logger = logger; + _handler = new HttpClientHandler(); + } + + public HttpClient GetHttpClient() + { + return new HttpClient(_handler){}; + } + + /// + /// PostAsync + /// + /// + /// + /// + /// + /// 瓒呮椂鏃堕棿 + /// + public async Task PostAsync(string url, TIn input, int timeOut = 10) + { + try + { + var client = GetHttpClient(); + client.Timeout = new TimeSpan(0, 10, timeOut); + _logger.LogDebug($"Post:{url}\n[{JsonConvert.SerializeObject(input)}]"); + var result = await client.PostAsync(url, JsonContent.Create(input)); + var strResult = await result.Content.ReadAsStringAsync(); + if (result.StatusCode != HttpStatusCode.OK) + { + _logger.LogDebug($"Error[{result.StatusCode}]:{url}\t{strResult}"); + } + return await result.Content.ReadFromJsonAsync(); + } + catch (Exception e) + { + _logger.LogError(url); + _logger.LogError(e.Message); + throw; + } + } + + /// + /// PostAsync + /// + /// + /// + /// + /// + public async Task GetAsync(string url,int timeOut = 10) + { + try + { + var client = GetHttpClient(); + client.Timeout = new TimeSpan(0, 10, timeOut); + _logger.LogDebug($"Get:{url}"); + var result = await client.GetAsync(url); + var strResult = await result.Content.ReadAsStringAsync(); + if (result.StatusCode != HttpStatusCode.OK) + { + _logger.LogDebug($"Error[{result.StatusCode}]:{url}\t{strResult}"); + } + return await result.Content.ReadFromJsonAsync(); + } + catch (Exception e) + { + _logger.LogError(url); + _logger.LogError(e.Message); + throw; + } + } + + #region 涓嬭浇鏂囦欢 + + /// + /// http涓嬭浇鏂囦欢 (浠呮敮鎸佸皬鏂囦欢) + /// + /// 涓嬭浇鏂囦欢鍦板潃 + /// 鏂囦欢瀛樻斁鍦板潃锛屽寘鍚枃浠跺悕 + /// + public bool DownloadFile(string url, string localPath) + { + ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true; + + var request = WebRequest.Create(url) as HttpWebRequest; + Stream stream = new FileStream(localPath, FileMode.CreateNew); + try + { + // 璁剧疆鍙傛暟 + //鍙戦佽姹傚苟鑾峰彇鐩稿簲鍥炲簲鏁版嵁 + var response = request?.GetResponse() as HttpWebResponse; + //鐩村埌request.GetResponse()绋嬪簭鎵嶅紑濮嬪悜鐩爣缃戦〉鍙戦丳ost璇锋眰 + var responseStream = response?.GetResponseStream(); + //鍒涘缓鏈湴鏂囦欢鍐欏叆娴 + stream.Close(); + responseStream?.Close(); + return true; + } + catch (Exception ex) + { + return false; + } + } + + #endregion + + + /// + /// 鑾峰緱褰撳墠鏈哄櫒鐨勫叕缃 IP + /// + public async Task GetCurrentPublicIpv4() + { + using var client = new HttpClient(); + using var request = new HttpRequestMessage(HttpMethod.Get, "http://175.24.175.136:8008/WebUtil/GetIp"); + using var response = await client.SendAsync(request); + return await response.Content.ReadAsStringAsync(); + } + } + + + public interface IHttpHelper + { + public Task GetCurrentPublicIpv4(); + public Task PostAsync(string url, TIn input, int timeOut = 10); + public Task GetAsync(string url, int timeOut = 10); + public bool DownloadFile(string url, string fileFullName); + public HttpClient GetHttpClient(); + } +} diff --git a/Hua.DDNS/Common/Http/HttpResult.cs b/Hua.DDNS/Common/Http/HttpResult.cs new file mode 100644 index 0000000..a48e482 --- /dev/null +++ b/Hua.DDNS/Common/Http/HttpResult.cs @@ -0,0 +1,14 @@ +锘縩amespace Hua.DDNS.Common.Http +{ + public class HttpResult + { + public virtual T Data { get; set; } + + public string DataDescription { get; set; } + + public int Result { get; set; } + + public string Message { get; set; } + + } +} \ No newline at end of file diff --git a/Hua.DDNS/Common/Http/Url.cs b/Hua.DDNS/Common/Http/Url.cs new file mode 100644 index 0000000..f6b844e --- /dev/null +++ b/Hua.DDNS/Common/Http/Url.cs @@ -0,0 +1,16 @@ +锘縰sing Hua.DDNS.Common.Config; +using Hua.DDNS.Start; + +namespace Hua.DDNS.Common.Http +{ + public class Url + { + private readonly SettingProvider _settingProvider; + + public Url(SettingProvider settingProvider) + { + _settingProvider = settingProvider; + } + + } +} diff --git a/Hua.DDNS/Common/SqlHelper.cs b/Hua.DDNS/Common/SqlHelper.cs new file mode 100644 index 0000000..6c39ca6 --- /dev/null +++ b/Hua.DDNS/Common/SqlHelper.cs @@ -0,0 +1,46 @@ +锘縰sing System.Data; +using Dapper; +using Npgsql; + +namespace Hua.DDNS.Common +{ + public class SqlHelper + { + + private readonly string _connectionString; + private readonly ILogger _logger; + + public SqlHelper(IConfiguration configuration, ILogger logger) + { + _logger = logger; + _connectionString = configuration.GetConnectionString("pgsql"); + } + + /// + /// 鏌ヨ鎵鏈夌粨鏋 + /// + /// + /// + /// + /// + public List GetList(string strSql) + { + var list = new List(); + + try + { + using IDbConnection connection = new NpgsqlConnection(_connectionString); + connection.Open(); + list = connection.Query(strSql).ToList(); + connection.Close(); + } + catch (Exception e) + { + _logger.LogError(e.Message); + throw; + } + return list; + } + + } +} diff --git a/Hua.DDNS/Dockerfile b/Hua.DDNS/Dockerfile new file mode 100644 index 0000000..36de2aa --- /dev/null +++ b/Hua.DDNS/Dockerfile @@ -0,0 +1,23 @@ +#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. + +#Depending on the operating system of the host machines(s) that will build or run the containers, the image specified in the FROM statement may need to be changed. +#For more information, please see https://aka.ms/containercompat + +FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base +WORKDIR /app + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +WORKDIR /src +COPY ["Hua.DDNS/Hua.DDNS.csproj", "Hua.DDNS/"] +RUN dotnet restore "Hua.DDNS/Hua.DDNS.csproj" +COPY . . +WORKDIR "/src/Hua.DDNS" +RUN dotnet build "Hua.DDNS.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "Hua.DDNS.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "Hua.DDNS.dll"] \ No newline at end of file diff --git a/Hua.DDNS/Hua.DDNS.csproj b/Hua.DDNS/Hua.DDNS.csproj new file mode 100644 index 0000000..b67525a --- /dev/null +++ b/Hua.DDNS/Hua.DDNS.csproj @@ -0,0 +1,41 @@ + + + + net6.0 + enable + enable + dotnet-Hua.DDNS-C4DADDFF-6D5B-4BD5-AB11-02F07B517CAC + Windows + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + diff --git a/Hua.DDNS/InstallServiceByNssm.bat b/Hua.DDNS/InstallServiceByNssm.bat new file mode 100644 index 0000000..1b0976c --- /dev/null +++ b/Hua.DDNS/InstallServiceByNssm.bat @@ -0,0 +1,32 @@ +cd /d %~dp0 +echo OFF +net.exe session 1>NUL 2>NUL && ( + goto as_admin +) || ( + goto not_admin +) +:not_admin +echo 请以管理员身份重新运行当前脚本。 +goto end + +:as_admin +SET basePath=%cd% +SET serviceName=Hua.DDNS +SET displayName="Hua.DDNS Demo" +SET description="Hua.DDNS Demo" +SET servicePath="%basePath%\%serviceName%.exe" +ECHO %servicePath% +net stop %serviceName% +sc delete %serviceName% +ping 1.1.1.1 -n 1 -w 10 > nul +nssm install %serviceName% %servicePath% +nssm set %serviceName% AppDirectory %basePath% +nssm set %serviceName% AppStopMethodSkip 6 +nssm set %serviceName% AppStopMethodConsole 1000 +nssm set %serviceName% AppThrottle 5000 +ping 1.1.1.1 -n 1 -w 10 > nul +nssm start %serviceName% +Echo 安装成功 +goto end +:end +Pause \ No newline at end of file diff --git a/Hua.DDNS/Jobs/AppJob.cs b/Hua.DDNS/Jobs/AppJob.cs new file mode 100644 index 0000000..392e3f6 --- /dev/null +++ b/Hua.DDNS/Jobs/AppJob.cs @@ -0,0 +1,134 @@ +using Hua.DDNS.Common; +using Hua.DDNS.Common.Config; +using Hua.DDNS.Common.Config.Options; +using Hua.DDNS.Common.Http; +using Hua.DDNS.Start; +using Quartz; +using System.Net; +using AlibabaCloud.OpenApiClient.Models; +using AlibabaCloud.SDK.Alidns20150109.Models; +using Hua.DotNet.Code.Extension; +using TencentCloud.Common; +using TencentCloud.Common.Profile; +using TencentCloud.Dnspod.V20210323; +using TencentCloud.Dnspod.V20210323.Models; + +using Tea; +using Tea.Utils; + +namespace Hua.DDNS.Jobs +{ + [DisallowConcurrentExecution] + public class AppJob : IJob, IDisposable + { + private readonly ILogger _logger; + private readonly SettingProvider _settingProvider; + private readonly DomainOption _domainOption; + private readonly IHttpHelper _httpHelper; + public string CurrentIpv4Address; + + + + public AppJob(ILogger logger,SettingProvider settingProvider, IHttpHelper httpHelper) + { + _logger = logger; + _settingProvider = settingProvider; + _httpHelper = httpHelper; + _domainOption = _settingProvider.App.Domain; + + + } + public async Task Execute(IJobExecutionContext context) + { + _logger.LogInformation("寮濮嬩换鍔℃墽琛"); + try + { + var oldIp = (await Dns.GetHostEntryAsync($"{_domainOption.subDomainArray.First()}.{_domainOption.domain}")).AddressList.First(); + CurrentIpv4Address = await _httpHelper.GetCurrentPublicIpv4(); + + if (CurrentIpv4Address!=oldIp.ToString()) + { + await UpdateDns(); + } + } + catch (Exception e) + { + _logger.LogError(e,e.Message); + } + finally + { + _logger.LogInformation("浠诲姟鎵ц瀹屾垚"); + } + } + + private async Task UpdateDns() + { + //鏇存柊Ip璁板綍 + switch (_domainOption.Platform) + { + case "Tencent": + var _dnspodClient = new DnspodClient( + // 瀹炰緥鍖栦竴涓璇佸璞★紝鍏ュ弬闇瑕佷紶鍏ヨ吘璁簯璐︽埛secretId锛宻ecretKey,姝ゅ杩橀渶娉ㄦ剰瀵嗛挜瀵圭殑淇濆瘑 + // 瀵嗛挜鍙墠寰https://console.cloud.tencent.com/cam/capi缃戠珯杩涜鑾峰彇 + new Credential { SecretId = _domainOption.Id, SecretKey = _domainOption.Key }, + "", + // 瀹炰緥鍖栦竴涓猚lient閫夐」锛屽彲閫夌殑锛屾病鏈夌壒娈婇渶姹傚彲浠ヨ烦杩 + new ClientProfile() + { + // 瀹炰緥鍖栦竴涓猦ttp閫夐」锛屽彲閫夌殑锛屾病鏈夌壒娈婇渶姹傚彲浠ヨ烦杩 + HttpProfile = new HttpProfile { Endpoint = ("dnspod.tencentcloudapi.com") } + }); + + //鑾峰彇鍩熷悕瑙f瀽璁板綍 + var describeRecordList = await _dnspodClient.DescribeRecordList(new DescribeRecordListRequest() { Domain = _domainOption.domain }); + var record = describeRecordList.RecordList.FirstOrDefault(m => + m.Value == CurrentIpv4Address && _domainOption.subDomainArray.Any(n => m.Name == n)); + if (record!=null && record.Value == CurrentIpv4Address) return;//濡傛灉璁板綍宸茬粡鍙樻洿锛屼笉璋冪敤鏇存柊鎺ュ彛 + + await _dnspodClient.ModifyRecordBatch(new ModifyRecordBatchRequest() + { + RecordIdList = + describeRecordList.RecordList + .Where(m => m.Value != CurrentIpv4Address && _domainOption.subDomainArray.Any(n => m.Name == n)) + .Select(m => m.RecordId) + .ToArray(), + Change = "value", + ChangeTo = CurrentIpv4Address + }); + + break; + case "Ali": + var aliClient = new AlibabaCloud.SDK.Alidns20150109.Client(new Config() + { + // 鎮ㄧ殑 AccessKey ID + AccessKeyId = _domainOption.Id, + // 鎮ㄧ殑 AccessKey Secret + AccessKeySecret = _domainOption.Key, + Endpoint = "alidns.cn-beijing.aliyuncs.com", + }); + + var aliDescribeRecordList = (await aliClient.DescribeDomainRecordsAsync(new DescribeDomainRecordsRequest() + { + DomainName = _domainOption.domain + })).Body.DomainRecords.Record; + + foreach (var aliDomainRecord in aliDescribeRecordList + .Where(m => m.Value != CurrentIpv4Address && _domainOption.subDomainArray.Any(n => m.Value == n))) + { + + await aliClient.UpdateDomainRecordAsync(new UpdateDomainRecordRequest() + { + RecordId = aliDomainRecord.RecordId, + Value = CurrentIpv4Address, + }); + } + break; + } + } + + public void Dispose() + { + _logger.LogInformation("AppJob宸查攢姣"); + } + } +} \ No newline at end of file diff --git a/Hua.DDNS/Jobs/AppJobContext.cs b/Hua.DDNS/Jobs/AppJobContext.cs new file mode 100644 index 0000000..ae01e28 --- /dev/null +++ b/Hua.DDNS/Jobs/AppJobContext.cs @@ -0,0 +1,10 @@ +锘縩amespace Hua.DDNS.Jobs +{ + + /// + /// Job涓婁笅鏂 + /// + public class AppJobContext + { + } +} diff --git a/Hua.DDNS/Properties/launchSettings.json b/Hua.DDNS/Properties/launchSettings.json new file mode 100644 index 0000000..5313207 --- /dev/null +++ b/Hua.DDNS/Properties/launchSettings.json @@ -0,0 +1,14 @@ +{ + "profiles": { + "Hua.DDNS": { + "commandName": "Project", + "environmentVariables": { + "DOTNET_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true + }, + "Docker": { + "commandName": "Docker" + } + } +} \ No newline at end of file diff --git a/Hua.DDNS/Start/Cache.cs b/Hua.DDNS/Start/Cache.cs new file mode 100644 index 0000000..0a15c41 --- /dev/null +++ b/Hua.DDNS/Start/Cache.cs @@ -0,0 +1,11 @@ +锘縩amespace Hua.DDNS.Start +{ + public class Cache + { + /// + /// Tocken + /// + public static string Tocken { get; set; } = null; + + } +} diff --git a/Hua.DDNS/Start/Program.cs b/Hua.DDNS/Start/Program.cs new file mode 100644 index 0000000..a88df73 --- /dev/null +++ b/Hua.DDNS/Start/Program.cs @@ -0,0 +1,94 @@ +using Hua.DDNS.Common; +using Hua.DDNS.Common.Config; +using Hua.DDNS.Common.Http; +using Hua.DDNS.Jobs; +using Quartz; +using Serilog; + +namespace Hua.DDNS.Start +{ + public static class Program + { + public static async Task Main(string[] args) + { + await CreateHostBuilder(args).Build().RunAsync(); + } + + private static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .UseWindowsService() + .UseSerilog() + .ConfigureServices((hostContext, services) => + { + Log.Logger = new LoggerConfiguration() + .Enrich.FromLogContext() + .WriteTo.Console() + .WriteTo.File( + Path.Combine("Log\\log-.log"), + rollingInterval: RollingInterval.Day) + .CreateLogger(); + ConfigDi(hostContext, services); + ConfigQuartz(hostContext, services); + }); + + public static IServiceProvider ConfigDi(HostBuilderContext hostContext, IServiceCollection services) + { + services.AddSingleton(); + //services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddTransient(); + return services.BuildServiceProvider(); + } + + private static void ConfigQuartz(HostBuilderContext hostContext, IServiceCollection services) + { + // if you are using persistent job store, you might want to alter some options + services.Configure(options => + { + options.Scheduling.IgnoreDuplicates = true; // default: false + options.Scheduling.OverWriteExistingData = true; // default: true + }); + + // base configuration for DI + 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 + var appJobKey = new JobKey("AppJob", "AppJobGroup"); + q.AddJob(j => j + .StoreDurably() + .WithIdentity(appJobKey) + .WithDescription("AppJob") + ); + + q.AddTrigger(t => t + .WithIdentity("AppJob Trigger") + .ForJob(appJobKey) + .WithCronSchedule(hostContext.Configuration.GetSection("App:AppJob:Corn").Value) + .WithDescription("AppJob trigger") + .StartNow() + ); + }); + + // Quartz.Extensions.Hosting hosting + 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); + }); + } + } +} \ No newline at end of file diff --git a/Hua.DDNS/appsettings.Development.json b/Hua.DDNS/appsettings.Development.json new file mode 100644 index 0000000..0d47edc --- /dev/null +++ b/Hua.DDNS/appsettings.Development.json @@ -0,0 +1,32 @@ +{ + "ConnectionStrings": { + "pgConnection": "Host=127.0.0.1;Port=5432;Database=Worker;Username=Worker;Password=123456;" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "App": { + "AppJob": { + "Corn": "* * * * * ?" //https://cron.qqe2.com/ + }, + + "Domain": { + "Platform": "Ali", + // Access Id/Secret Id + "Id": "Id", + // Access Key/Secret Key + "Key": "Key", + // 涓诲煙鍚 + "domain": "demo.cn", + // 瀛愬煙鍚嶅墠缂 + "subDomainArray": [ "bjb", "git"], + // 璁板綍绫诲瀷 + "type": "A", + //闂撮殧鏃堕棿 绉 + "time": "30" + } + } +} \ No newline at end of file diff --git a/Hua.DDNS/appsettings.json b/Hua.DDNS/appsettings.json new file mode 100644 index 0000000..a09b405 --- /dev/null +++ b/Hua.DDNS/appsettings.json @@ -0,0 +1,32 @@ +{ + "ConnectionStrings": { + "pgConnection": "Host=127.0.0.1;Port=5432;Database=Worker;Username=Worker;Password=123456;" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "App": { + "AppJob": { + "Corn": "* * * * * ?" //https://cron.qqe2.com/ + }, + + "Domain": { + "Platform": "Ali", + // Access Id/Secret Id + "Id": "Id", + // Access Key/Secret Key + "Key": "Key", + // 涓诲煙鍚 + "domain": "demo.cn", + // 瀛愬煙鍚嶅墠缂 + "subDomainArray": [ "bjb", "git" ], + // 璁板綍绫诲瀷 + "type": "A", + //闂撮殧鏃堕棿 绉 + "time": "30" + } + } +} \ No newline at end of file diff --git a/Hua.DDNS/nssm.exe b/Hua.DDNS/nssm.exe new file mode 100644 index 0000000..b81399d Binary files /dev/null and b/Hua.DDNS/nssm.exe differ