重写Job实现方式

This commit is contained in:
2023-05-28 23:42:43 +08:00
parent f8df2fe468
commit 7c3f039911
21 changed files with 732 additions and 227 deletions

View File

@@ -22,7 +22,7 @@ namespace Hua.DDNS.Test
.Build(); .Build();
var sc = DIConfig.ConfigureServices(config); var sc = DIConfig.ConfigureServices(config);
var job = sc.GetService<AppJob>(); var job = sc.GetService<NewJob>();
job?.Execute(null); job?.Execute(null);
} }

View File

@@ -1,4 +1,6 @@
namespace Hua.DDNS.Common.Config.Options using Hua.DDNS.DDNSProviders;
namespace Hua.DDNS.Common.Config.Options
{ {
/// <summary> /// <summary>
@@ -10,6 +12,7 @@
/// <summary> /// <summary>
/// domain configuration /// domain configuration
/// </summary> /// </summary>
public DomainOption Domain { get; set; } public DdnsOption DDNS { get; set; }
} }
} }

View File

@@ -19,6 +19,11 @@ namespace Hua.DDNS.Common.Config.Options
/// <summary> /// <summary>
/// Tencent /// Tencent
/// </summary> /// </summary>
Tencent Tencent,
/// <summary>
/// Namesilo
/// </summary>
Namesilo
} }
} }

View File

@@ -118,7 +118,7 @@ namespace Hua.DDNS.Common.Http
/// <summary> /// <summary>
/// 获得当前机器的公网 IP /// 获得当前机器的公网 Ip
/// </summary> /// </summary>
public async Task<string> GetCurrentPublicIpv4() public async Task<string> GetCurrentPublicIpv4()
{ {

View File

@@ -0,0 +1,25 @@
namespace Hua.DDNS.DDNSProviders.Ali
{
/// <summary>
/// domain configuration Ali
/// </summary>
public class AliDdnsOption
{
/// <summary>
/// Id, the id and key from DnsPod
/// </summary>
public string Id { get; set; }
/// <summary>
/// Key
/// </summary>
public string Key { get; set; }
/// <summary>
/// Endpoint
/// </summary>
public string Endpoint { get; set; }
}
}

View File

@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AlibabaCloud.OpenApiClient.Models;
using AlibabaCloud.SDK.Alidns20150109;
using AlibabaCloud.SDK.Alidns20150109.Models;
using AutoMapper;
using Hua.DDNS.Common.Config.Options;
using Hua.DDNS.Models;
using Microsoft.Extensions.Options;
namespace Hua.DDNS.DDNSProviders.Ali
{
/// <summary>
/// DDNSProvider for Ali
/// </summary>
public class AliDdnsProvider : IDdnsProvider
{
private readonly Client _client;
private readonly AliDdnsOption _aliDDNSOption;
private readonly DdnsOption _ddnsOption;
private readonly IMapper _mapper;
public AliDdnsProvider(IOptions<AliDdnsOption> aliDDNSOption, IMapper mapper,IOptions<DdnsOption> ddnsOption)
{
_aliDDNSOption = aliDDNSOption.Value;
_ddnsOption = ddnsOption.Value;
_mapper = mapper;
_client = new Client(new Config()
{
// 您的 AccessKey ID
AccessKeyId = _aliDDNSOption.Id,
// 您的 AccessKey Secret
AccessKeySecret = _aliDDNSOption.Key,
Endpoint = _aliDDNSOption.Endpoint,//alidns.cn-beijing.aliyuncs.com
});
}
/// <summary>
/// 获取解析记录列表
/// </summary>
/// <returns></returns>
public async Task<IEnumerable<DnsRecord>?> GetRecordListAsync()
{
var record = (await _client.DescribeDomainRecordsAsync(new DescribeDomainRecordsRequest()
{
DomainName = _ddnsOption.Domain
})).Body.DomainRecords.Record;
return _mapper.Map<IEnumerable<DnsRecord>>(record);
}
/// <summary>
/// 变更解析记录列表
/// </summary>
/// <param name="newIp"></param>
/// <param name="records"></param>
/// <returns></returns>
public async Task<IEnumerable<DnsRecord>> ModifyRecordListAsync(string newIp, IEnumerable<DnsRecord> records)
{
foreach (var aliDomainRecord in records)
{
await _client.UpdateDomainRecordAsync(_mapper.Map<UpdateDomainRecordRequest>(aliDomainRecord));
}
return records;
}
}
}

View File

@@ -3,38 +3,30 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Hua.DDNS.Common.Config.Options;
using Hua.DDNS.DDNSProviders.Namesilo;
namespace Hua.DDNS.Common.Config.Options namespace Hua.DDNS.DDNSProviders
{ {
/// <summary> /// <summary>
/// domain configuration class /// domain configuration class
/// </summary> /// </summary>
public class DomainOption public class DdnsOption
{ {
/// <summary> /// <summary>
/// platform from 1 Ali 2 Tencent /// platform from 1 Ali 2 Tencent 3
/// </summary> /// </summary>
public PlatformEnum Platform { get; set; } public PlatformEnum Platform { get; set; }
/// <summary>
/// Id, the id and key from AliCould or DnsPod
/// </summary>
public string Id { get; set; }
/// <summary>
/// Key
/// </summary>
public string Key { get; set; }
/// <summary> /// <summary>
/// domain /// domain
/// </summary> /// </summary>
public string domain { get; set; } public string Domain { get; set; }
/// <summary> /// <summary>
/// sub domain, eg. www,git /// sub domain, eg. www,git
/// </summary> /// </summary>
public string[] subDomainArray { get; set; } public string[] SubDomainArray { get; set; }
} }

View File

@@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AutoMapper;
using Hua.DDNS.DDNSProviders.Ali;
using Hua.DDNS.Models;
using Microsoft.Extensions.Options;
using TencentCloud.Common.Profile;
using TencentCloud.Common;
using TencentCloud.Dnspod.V20210323;
using System.Net;
using TencentCloud.Dnspod.V20210323.Models;
namespace Hua.DDNS.DDNSProviders.Dnspod
{
/// <summary>
/// DdnsProvider for Dnspod
/// </summary>
public class DnspodDdnsProvider : IDdnsProvider
{
private readonly DnspodClient _client;
private readonly DnspodOption _dnspodOption;
private readonly DdnsOption _ddnsOption;
private readonly IMapper _mapper;
public DnspodDdnsProvider(IMapper mapper, IOptions<DnspodOption> dnspodOption, IOptions<DdnsOption> ddnsOption)
{
_mapper = mapper;
_dnspodOption = dnspodOption.Value;
_ddnsOption = ddnsOption.Value;
_client = new DnspodClient(
// 实例化一个认证对象入参需要传入腾讯云账户secretIdsecretKey,此处还需注意密钥对的保密
// 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
new Credential { SecretId = _dnspodOption.Id, SecretKey = _dnspodOption.Key },
"",
// 实例化一个client选项可选的没有特殊需求可以跳过
new ClientProfile()
{
// 实例化一个http选项可选的没有特殊需求可以跳过
HttpProfile = new HttpProfile { Endpoint = (_dnspodOption.Endpoint) }//"dnspod.tencentcloudapi.com"
});
}
public async Task<IEnumerable<DnsRecord>?> GetRecordListAsync()
{
var recordList = (await _client.DescribeRecordList(new DescribeRecordListRequest() { Domain = _ddnsOption.Domain })).RecordList;
return _mapper.Map<IEnumerable<DnsRecord>>(recordList);
}
public async Task<IEnumerable<DnsRecord>> ModifyRecordListAsync(string newIp, IEnumerable<DnsRecord> records)
{
var rep = await _client.ModifyRecordBatch(new ModifyRecordBatchRequest()
{
RecordIdList = records.Select(m => (ulong?)Convert.ToUInt64(m.Id)).ToArray(),
Change = "value",
ChangeTo = newIp
});
return records;
}
}
}

View File

@@ -0,0 +1,25 @@
namespace Hua.DDNS.DDNSProviders.Dnspod
{
/// <summary>
/// domain configuration Dnspod
/// </summary>
public class DnspodOption
{
/// <summary>
/// Id, the id and key from AliCould or DnsPod
/// </summary>
public string Id { get; set; }
/// <summary>
/// Key
/// </summary>
public string Key { get; set; }
/// <summary>
/// Endpoint
/// </summary>
public string Endpoint { get; set; }
}
}

View File

@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Hua.DDNS.Models;
namespace Hua.DDNS.DDNSProviders
{
/// <summary>
/// Dynamic domain name resolution provider
/// </summary>
public interface IDdnsProvider
{
/// <summary>
/// 获取域名解析记录列表
/// </summary>
/// <returns></returns>
Task<IEnumerable<DnsRecord>?> GetRecordListAsync();
/// <summary>
/// 修改域名解析记录
/// </summary>
/// <param name="newIp"></param>
/// <param name="records"></param>
/// <returns></returns>
Task<IEnumerable<DnsRecord>> ModifyRecordListAsync(string newIp, IEnumerable<DnsRecord> records);
}
}

View File

@@ -0,0 +1,95 @@
using System.Xml;
using AutoMapper;
using Hua.DDNS.Models;
using Microsoft.Extensions.Options;
namespace Hua.DDNS.DDNSProviders.Namesilo
{
/// <summary>
/// DDNSProvider for namesilo
/// </summary>
public class NamesiloDdnsProvider : IDdnsProvider
{
public readonly NamesiloOption _namesiloOption;
public readonly DdnsOption _ddnsOption;
public NamesiloDdnsProvider(IOptions<NamesiloOption> namesiloOption, IOptions<DdnsOption> ddnsOption)
{
_ddnsOption = ddnsOption.Value;
_namesiloOption = namesiloOption.Value;
}
public async Task<IEnumerable<DnsRecord>?> GetRecordListAsync()
{
var client = new HttpClient();
var response =
await client.GetAsync($"https://www.namesilo.com/api/dnsListRecords?version=1&type=xml&key={_namesiloOption.ApiKey}&domain={_ddnsOption.Domain}");
var content = response.Content.ReadAsStringAsync().Result;
var reply = new XmlDocument();
reply.LoadXml(content);
var status = reply.SelectSingleNode("/namesilo/reply/code/text()");
if (status == null)
{
return null;
}
if (status.Value != "300")
{
throw new Exception($"Failed to retrieve value. Check API key.{status}");
}
var records = reply.SelectNodes($"/namesilo/reply/resource_record/host");
if (records == null)
{
return new List<DnsRecord>();
}
return (from record in records.Cast<XmlNode>()
let subDomain = record.ParentNode.SelectSingleNode("host/text()").Value.Replace(_ddnsOption.Domain, "")
where _ddnsOption.SubDomainArray.Contains(subDomain)
select new DnsRecord
{
Id = record.ParentNode.SelectSingleNode("record_id/text()").Value,
Ip = record.ParentNode.SelectSingleNode("value/text()").Value,
Host = record.ParentNode.SelectSingleNode("host/text()").Value,
Domain = _ddnsOption.Domain,
TTL = record.ParentNode.SelectSingleNode("ttl/text()").Value,
SubDomain = subDomain,
}).ToList();
}
public async Task<IEnumerable<DnsRecord>> ModifyRecordListAsync(string newIp, IEnumerable<DnsRecord> records)
{
foreach (var dnsRecord in records)
{
using var client = new HttpClient();
{
var host = dnsRecord.Host[..(dnsRecord.Host.Length - dnsRecord.Domain.Length - 1)];
var request =
$"https://www.namesilo.com/api/dnsUpdateRecord?version=1&type=xml&key={_namesiloOption.ApiKey}&domain={dnsRecord.Domain}&rrid={dnsRecord.Id}&rrhost={host}&rrvalue={newIp}&rrttl={dnsRecord.TTL}";
//Console.WriteLine(request);
var response = await client.GetAsync(request);
var content = await response.Content.ReadAsStringAsync();
var reply = new XmlDocument();
reply.LoadXml(content);
var status = reply.SelectSingleNode("/namesilo/reply/code/text()");
if (status == null)
{
await Console.Error.WriteLineAsync($"Failed to update record: '{dnsRecord.Id}' with Ip: '{newIp}'.");
continue; //return false;
}
if (status.Value == "300") continue;
}
await Console.Error.WriteLineAsync($"Failed to update record: '{dnsRecord.Id}' with Ip: '{newIp}'.");
continue; //return false;
}
return records;
}
}
}

View File

@@ -0,0 +1,16 @@
namespace Hua.DDNS.DDNSProviders.Namesilo
{
/// <summary>
/// Namesilo Option
/// </summary>
public class NamesiloOption
{
/// <summary>
/// API key
/// </summary>
public string ApiKey { get; set; }
}
}

View File

@@ -6,10 +6,14 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>dotnet-Hua.DDNS-C4DADDFF-6D5B-4BD5-AB11-02F07B517CAC</UserSecretsId> <UserSecretsId>dotnet-Hua.DDNS-C4DADDFF-6D5B-4BD5-AB11-02F07B517CAC</UserSecretsId>
<DockerDefaultTargetOS>Windows</DockerDefaultTargetOS> <DockerDefaultTargetOS>Windows</DockerDefaultTargetOS>
<PublishSingleFile>true</PublishSingleFile>
<SelfContained>true</SelfContained>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AlibabaCloud.SDK.Alidns20150109" Version="3.0.0" /> <PackageReference Include="AlibabaCloud.SDK.Alidns20150109" Version="3.0.0" />
<PackageReference Include="AutoMapper" Version="12.0.1" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
<PackageReference Include="Hua.DotNet.Code" Version="0.0.8" /> <PackageReference Include="Hua.DotNet.Code" Version="0.0.8" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.15.1" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.15.1" />

View File

@@ -1,136 +1,138 @@
using Hua.DDNS.Common; //using Hua.DDNS.Common;
using Hua.DDNS.Common.Config; //using Hua.DDNS.Common.Config;
using Hua.DDNS.Common.Config.Options; //using Hua.DDNS.Common.Config.Options;
using Hua.DDNS.Common.Http; //using Hua.DDNS.Common.Http;
using Hua.DDNS.Start; //using Hua.DDNS.Start;
using Quartz; //using Quartz;
using System.Net; //using System.Net;
using AlibabaCloud.OpenApiClient.Models; //using AlibabaCloud.OpenApiClient.Models;
using AlibabaCloud.SDK.Alidns20150109.Models; //using AlibabaCloud.SDK.Alidns20150109.Models;
using Hua.DotNet.Code.Extension; //using Hua.DotNet.Code.Extension;
using TencentCloud.Common; //using TencentCloud.Common;
using TencentCloud.Common.Profile; //using TencentCloud.Common.Profile;
using TencentCloud.Dnspod.V20210323; //using TencentCloud.Dnspod.V20210323;
using TencentCloud.Dnspod.V20210323.Models; //using TencentCloud.Dnspod.V20210323.Models;
using Tea; //using Tea;
using Tea.Utils; //using Tea.Utils;
//using Hua.DDNS.DDNSProviders;
namespace Hua.DDNS.Jobs //namespace Hua.DDNS.Jobs
{ //{
[DisallowConcurrentExecution] // [DisallowConcurrentExecution]
public class AppJob : IJob, IDisposable // public class AppJob : IJob, IDisposable
{ // {
private readonly ILogger<AppJob> _logger; // private readonly ILogger<AppJob> _logger;
private readonly SettingProvider _settingProvider; // private readonly SettingProvider _settingProvider;
private readonly DomainOption _domainOption; // private readonly DdnsOption _ddnsOption;
private readonly IHttpHelper _httpHelper; // private readonly IHttpHelper _httpHelper;
public string CurrentIpv4Address; // public string CurrentIpv4Address;
public AppJob(ILogger<AppJob> logger,SettingProvider settingProvider, IHttpHelper httpHelper) // public AppJob(ILogger<AppJob> logger,SettingProvider settingProvider, IHttpHelper httpHelper)
{ // {
_logger = logger; // _logger = logger;
_settingProvider = settingProvider; // _settingProvider = settingProvider;
_httpHelper = httpHelper; // _httpHelper = httpHelper;
_domainOption = _settingProvider.App.Domain; // _ddnsOption = _settingProvider.App.DDNS;
} // }
public async Task Execute(IJobExecutionContext context) // public async Task Execute(IJobExecutionContext context)
{ // {
_logger.LogInformation("开始任务执行"); // _logger.LogInformation("开始任务执行");
try // try
{ // {
var oldIp = (await Dns.GetHostEntryAsync($"{_domainOption.subDomainArray.First()}.{_domainOption.domain}")).AddressList.First(); // var oldIp = (await Dns.GetHostEntryAsync($"{_ddnsOption.SubDomainArray.First()}.{_ddnsOption.Domain}")).AddressList.First();
CurrentIpv4Address = await _httpHelper.GetCurrentPublicIpv4(); // CurrentIpv4Address = await _httpHelper.GetCurrentPublicIpv4();
if (CurrentIpv4Address!=oldIp.ToString()) // if (CurrentIpv4Address!=oldIp.ToString())
{ // {
await UpdateDns(); // await UpdateDns();
} // }
} // }
catch (Exception e) // catch (Exception e)
{ // {
_logger.LogError(e,e.Message); // _logger.LogError(e,e.Message);
} // }
finally // finally
{ // {
_logger.LogInformation("任务执行完成"); // _logger.LogInformation("任务执行完成");
} // }
} // }
private async Task UpdateDns() // private async Task UpdateDns()
{ // {
//更新Ip记录 // //更新Ip记录
switch (_domainOption.Platform) // switch (_ddnsOption.Platform)
{ // {
case PlatformEnum.Tencent: // case PlatformEnum.Namesilo:
var _dnspodClient = new DnspodClient( // case PlatformEnum.Tencent:
// 实例化一个认证对象入参需要传入腾讯云账户secretIdsecretKey,此处还需注意密钥对的保密 // var _dnspodClient = new DnspodClient(
// 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取 // // 实例化一个认证对象入参需要传入腾讯云账户secretIdsecretKey,此处还需注意密钥对的保密
new Credential { SecretId = _domainOption.Id, SecretKey = _domainOption.Key }, // // 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
"", // new Credential { SecretId = _ddnsOption.Id, SecretKey = _ddnsOption.Key },
// 实例化一个client选项可选的没有特殊需求可以跳过 // "",
new ClientProfile() // // 实例化一个client选项可选的没有特殊需求可以跳过
{ // new ClientProfile()
// 实例化一个http选项可选的没有特殊需求可以跳过 // {
HttpProfile = new HttpProfile { Endpoint = ("dnspod.tencentcloudapi.com") } // // 实例化一个http选项可选的没有特殊需求可以跳过
}); // HttpProfile = new HttpProfile { Endpoint = ("dnspod.tencentcloudapi.com") }
// });
//获取域名解析记录 // //获取域名解析记录
var describeRecordList = await _dnspodClient.DescribeRecordList(new DescribeRecordListRequest() { Domain = _domainOption.domain }); // var describeRecordList = await _dnspodClient.DescribeRecordList(new DescribeRecordListRequest() { Domain = _ddnsOption.Domain });
var record = describeRecordList.RecordList.FirstOrDefault(m => // var record = describeRecordList.RecordList.FirstOrDefault(m =>
m.Value == CurrentIpv4Address && _domainOption.subDomainArray.Any(n => m.Name == n)); // m.Value == CurrentIpv4Address && _ddnsOption.SubDomainArray.Any(n => m.Name == n));
if (record!=null && record.Value == CurrentIpv4Address) return;//如果记录已经变更,不调用更新接口 // if (record!=null && record.Value == CurrentIpv4Address) return;//如果记录已经变更,不调用更新接口
await _dnspodClient.ModifyRecordBatch(new ModifyRecordBatchRequest() // await _dnspodClient.ModifyRecordBatch(new ModifyRecordBatchRequest()
{ // {
RecordIdList = // RecordIdList =
describeRecordList.RecordList // describeRecordList.RecordList
.Where(m => m.Value != CurrentIpv4Address && _domainOption.subDomainArray.Any(n => m.Name == n)) // .Where(m => m.Value != CurrentIpv4Address && _ddnsOption.SubDomainArray.Any(n => m.Name == n))
.Select(m => m.RecordId) // .Select(m => m.RecordId)
.ToArray(), // .ToArray(),
Change = "value", // Change = "value",
ChangeTo = CurrentIpv4Address // ChangeTo = CurrentIpv4Address
}); // });
break; // break;
case PlatformEnum.Ali: // case PlatformEnum.Ali:
var aliClient = new AlibabaCloud.SDK.Alidns20150109.Client(new Config() // var aliClient = new AlibabaCloud.SDK.Alidns20150109.Client(new Config()
{ // {
// 您的 AccessKey ID // // 您的 AccessKey ID
AccessKeyId = _domainOption.Id, // AccessKeyId = _ddnsOption.Id,
// 您的 AccessKey Secret // // 您的 AccessKey Secret
AccessKeySecret = _domainOption.Key, // AccessKeySecret = _ddnsOption.Key,
Endpoint = "alidns.cn-beijing.aliyuncs.com", // Endpoint = "alidns.cn-beijing.aliyuncs.com",
}); // });
var aliDescribeRecordList = (await aliClient.DescribeDomainRecordsAsync(new DescribeDomainRecordsRequest() // var aliDescribeRecordList = (await aliClient.DescribeDomainRecordsAsync(new DescribeDomainRecordsRequest()
{ // {
DomainName = _domainOption.domain // DomainName = _ddnsOption.Domain
})).Body.DomainRecords.Record; // })).Body.DomainRecords.Record;
foreach (var aliDomainRecord in aliDescribeRecordList // foreach (var aliDomainRecord in aliDescribeRecordList
.Where(m => m.Value != CurrentIpv4Address && _domainOption.subDomainArray.Any(n => m.RR == n))) // .Where(m => m.Value != CurrentIpv4Address && _ddnsOption.SubDomainArray.Any(n => m.RR == n)))
{ // {
await aliClient.UpdateDomainRecordAsync(new UpdateDomainRecordRequest() // await aliClient.UpdateDomainRecordAsync(new UpdateDomainRecordRequest()
{ // {
RecordId = aliDomainRecord.RecordId, // RecordId = aliDomainRecord.RecordId,
RR = aliDomainRecord.RR, // RR = aliDomainRecord.RR,
Type = aliDomainRecord.Type, // Type = aliDomainRecord.Type,
Value = CurrentIpv4Address, // Value = CurrentIpv4Address,
}); // });
_logger.LogInformation($"Update SubDomain[{aliDomainRecord.RR}.{aliDomainRecord.DomainName}] Value {aliDomainRecord.Value} To {CurrentIpv4Address}"); // _logger.LogInformation($"Update SubDomain[{aliDomainRecord.RR}.{aliDomainRecord.DomainName}] Value {aliDomainRecord.Value} To {CurrentIpv4Address}");
} // }
break; // break;
} // }
} // }
public void Dispose() // public void Dispose()
{ // {
_logger.LogInformation("AppJob已销毁"); // _logger.LogInformation("AppJob已销毁");
} // }
} // }
} //}

88
Hua.DDNS/Jobs/NewJob.cs Normal file
View File

@@ -0,0 +1,88 @@
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.DDNS.DDNSProviders;
using Hua.DDNS.DDNSProviders.Ali;
using Hua.DDNS.DDNSProviders.Dnspod;
using Hua.DDNS.DDNSProviders.Namesilo;
using Hua.DDNS.Models;
using Hua.DotNet.Code.Extension;
using Microsoft.Extensions.Options;
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 NewJob : IJob, IDisposable
{
private readonly ILogger<NewJob> _logger;
private readonly IServiceProvider _serviceProvider;
private readonly DdnsOption _ddnsOption;
private readonly IHttpHelper _httpHelper;
public string newIp;
public NewJob(ILogger<NewJob> logger,SettingProvider settingProvider, IHttpHelper httpHelper,IOptions<DdnsOption> ddnsOption)
{
_logger = logger;
_httpHelper = httpHelper;
_ddnsOption = ddnsOption.Value;
}
public async Task Execute(IJobExecutionContext context)
{
try
{
//1. 获取当前机器ip
var domain = $"{_ddnsOption.SubDomainArray.First()}.{_ddnsOption.Domain}";
var oldIp = (await Dns.GetHostEntryAsync(domain)).AddressList.First();
newIp = await _httpHelper.GetCurrentPublicIpv4();
//1.1 如果当前dns记录与实际dns记录一致跳出本次执行
if (newIp == oldIp.ToString()) return;
//2.获取DNS记录
IDdnsProvider? ddnsProvider = _ddnsOption.Platform switch
{
PlatformEnum.Namesilo => _serviceProvider.GetRequiredService<NamesiloDdnsProvider>(),
PlatformEnum.Tencent => _serviceProvider.GetRequiredService<DnspodDdnsProvider>(),
PlatformEnum.Ali => _serviceProvider.GetRequiredService<AliDdnsProvider>(),
_ => null
};
var dnsRecordList = await ddnsProvider!.GetRecordListAsync();
var record = dnsRecordList.FirstOrDefault(m => m.Ip == newIp && _ddnsOption.SubDomainArray.Any(n => m.SubDomain == n));
if (record != null && record.Ip == newIp) return;//如果记录已经变更,不调用更新接口
//3.比较并更新
await ddnsProvider.ModifyRecordListAsync(newIp, dnsRecordList.Where(m => m.Ip != newIp && _ddnsOption.SubDomainArray.Any(n => m.SubDomain == n)));
}
catch (Exception e)
{
_logger.LogError(e,e.Message);
}
finally
{
_logger.LogInformation("任务执行完成");
}
}
public void Dispose()
{
_logger.LogInformation("AppJob已销毁");
}
}
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Hua.DDNS.Models;
public class DnsRecord
{
public string Id { get; set; }
public string Ip { get; set; }
public string Host { get; set; }
public string SubDomain { get; set; }
public string Domain { get; set; }
public string TTL { get; set; }
public string RecordType { get; set; }
}

View File

@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AlibabaCloud.SDK.Alidns20150109.Models;
using AutoMapper;
using TencentCloud.Dnspod.V20210323.Models;
namespace Hua.DDNS.Models
{
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<DescribeDomainRecordsResponseBody.DescribeDomainRecordsResponseBodyDomainRecords.DescribeDomainRecordsResponseBodyDomainRecordsRecord, DnsRecord>()
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.RecordId))
.ForMember(dest => dest.RecordType, opt => opt.MapFrom(src => src.Type))
.ForMember(dest => dest.Ip, opt => opt.MapFrom(src => src.Value))
.ForMember(dest => dest.SubDomain, opt => opt.MapFrom(src => src.RR))
;
CreateMap<DnsRecord, UpdateDomainRecordRequest> ()
.ForMember(dest => dest.RecordId, opt => opt.MapFrom(src => src.Id))
.ForMember(dest => dest.Type, opt => opt.MapFrom(src => src.RecordType))
.ForMember(dest => dest.Value, opt => opt.MapFrom(src => src.Ip))
.ForMember(dest => dest.RR, opt => opt.MapFrom(src => src.SubDomain))
;
CreateMap<RecordListItem, DnsRecord>()
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.RecordId))
.ForMember(dest => dest.RecordType, opt => opt.MapFrom(src => src.Type))
.ForMember(dest => dest.Ip, opt => opt.MapFrom(src => src.Value))
.ForMember(dest => dest.SubDomain, opt => opt.MapFrom(src => src.Name))
;
}
}
}

View File

@@ -1,11 +0,0 @@
namespace Hua.DDNS.Start
{
public class Cache
{
/// <summary>
/// Token
/// </summary>
public static string? Token { get; set; } = null;
}
}

View File

@@ -1,8 +1,14 @@
using System.Configuration; using System.Configuration;
using System.Reflection;
using Hua.DDNS.Common; using Hua.DDNS.Common;
using Hua.DDNS.Common.Config; using Hua.DDNS.Common.Config;
using Hua.DDNS.Common.Http; using Hua.DDNS.Common.Http;
using Hua.DDNS.DDNSProviders;
using Hua.DDNS.DDNSProviders.Ali;
using Hua.DDNS.DDNSProviders.Dnspod;
using Hua.DDNS.DDNSProviders.Namesilo;
using Hua.DDNS.Jobs; using Hua.DDNS.Jobs;
using Microsoft.Extensions.DependencyInjection;
using Quartz; using Quartz;
using Serilog; using Serilog;
using Serilog.Extensions.Logging; using Serilog.Extensions.Logging;
@@ -34,10 +40,16 @@ namespace Hua.DDNS.Start
config.Sources.Clear(); config.Sources.Clear();
config config
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true); .AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: true,
reloadOnChange: true);
}) })
.ConfigureServices((hostContext, services) => .ConfigureServices((hostContext, services) =>
{ {
services.AddAutoMapper(Assembly.GetExecutingAssembly());
services.Configure<DdnsOption>(hostContext.Configuration.GetSection("DDNS"));
services.Configure<NamesiloOption>(hostContext.Configuration.GetSection("Namesilo"));
services.Configure<DnspodOption>(hostContext.Configuration.GetSection("Dnspod"));
services.Configure<AliDdnsOption>(hostContext.Configuration.GetSection("Ali"));
ConfigDi(hostContext, services); ConfigDi(hostContext, services);
ConfigQuartz(hostContext, services); ConfigQuartz(hostContext, services);
}); });
@@ -45,10 +57,12 @@ namespace Hua.DDNS.Start
public static IServiceProvider ConfigDi(HostBuilderContext hostContext, IServiceCollection services) public static IServiceProvider ConfigDi(HostBuilderContext hostContext, IServiceCollection services)
{ {
services.AddSingleton<SettingProvider>(); services.AddSingleton<SettingProvider>();
//services.AddSingleton<SyncECMFileProvider>();
services.AddSingleton<Url>(); services.AddSingleton<Url>();
services.AddSingleton<SqlHelper>(); services.AddSingleton<SqlHelper>();
services.AddTransient<IHttpHelper, HttpHelper>(); services.AddTransient<IHttpHelper, HttpHelper>();
services.AddTransient<NamesiloDdnsProvider>();
services.AddTransient<AliDdnsProvider>();
services.AddTransient<DnspodDdnsProvider>();
return services.BuildServiceProvider(); return services.BuildServiceProvider();
} }
@@ -75,18 +89,18 @@ namespace Hua.DDNS.Start
q.UseDefaultThreadPool(tp => { tp.MaxConcurrency = 10; }); q.UseDefaultThreadPool(tp => { tp.MaxConcurrency = 10; });
//configure jobs with code //configure jobs with code
var appJobKey = new JobKey("AppJob", "AppJobGroup"); var appJobKey = new JobKey("NewJob", "NewJobGroup");
q.AddJob<AppJob>(j => j q.AddJob<NewJob>(j => j
.StoreDurably() .StoreDurably()
.WithIdentity(appJobKey) .WithIdentity(appJobKey)
.WithDescription("AppJob") .WithDescription("NewJob")
); );
q.AddTrigger(t => t q.AddTrigger(t => t
.WithIdentity("AppJob Trigger") .WithIdentity("NewJob Trigger")
.ForJob(appJobKey) .ForJob(appJobKey)
.WithCronSchedule(hostContext.Configuration.GetSection("App:AppJob:Corn").Value) .WithCronSchedule(hostContext.Configuration.GetSection("App:AppJob:Corn").Value)
.WithDescription("AppJob trigger") .WithDescription("NewJob trigger")
.StartNow() .StartNow()
); );
}); });

View File

@@ -11,22 +11,30 @@
"App": { "App": {
"AppJob": { "AppJob": {
"Corn": "* * * * * ?" //https://cron.qqe2.com/ "Corn": "* * * * * ?" //https://cron.qqe2.com/
}
}, },
"DDNS": {
"Domain": { "Platform": 3, //1 Ali 2 Tencent 3 Namesilo
"Platform": "Ali",
// Access Id/Secret Id
"Id": "Id",
// Access Key/Secret Key
"Key": "Key",
// 主域名 // 主域名
"domain": "demo.cn", "Domain": "we965.com",
// 子域名前缀 // 子域名前缀
"subDomainArray": [ "bjb", "git"], "SubDomainArray": [ "git", "webutil", "dev" ],
// 记录类型 // 记录类型
"type": "A", "type": "A",
//间隔时间 秒 //间隔时间 秒
"time": "30" "time": "30"
} },
"Namesilo": {
"ApiKey": "1111"
},
"Dnspod": {
"Id": "1111",
"Key": "1111",
"Endpoint": "1111"
},
"Ali": {
"Id": "1111",
"Key": "1111",
"Endpoint": "1111"
} }
} }

View File

@@ -11,22 +11,30 @@
"App": { "App": {
"AppJob": { "AppJob": {
"Corn": "* * * * * ?" //https://cron.qqe2.com/ "Corn": "* * * * * ?" //https://cron.qqe2.com/
}
}, },
"DDNS": {
"Domain": { "Platform": 3, //1 Ali 2 Tencent 3 Namesilo
"Platform": 1, //1 Ali 2 Tencent
// Access Id/Secret Id
"Id": "Id",
// Access Key/Secret Key
"Key": "Key",
// 主域名 // 主域名
"domain": "demo.cn", "Domain": "we965.com",
// 子域名前缀 // 子域名前缀
"subDomainArray": [ "bjb", "git" ], "SubDomainArray": [ "git", "webutil", "dev" ],
// 记录类型 // 记录类型
"type": "A", "type": "A",
//间隔时间 秒 //间隔时间 秒
"time": "30" "time": "30"
} },
"Namesilo": {
"ApiKey": "1111"
},
"Dnspod": {
"Id": "1111",
"Key": "1111",
"Endpoint": "1111"
},
"Ali": {
"Id": "1111",
"Key": "1111",
"Endpoint": "1111"
} }
} }