if this dns record is not exits.create the dns record.

This commit is contained in:
2023-07-16 23:50:15 +08:00
parent ee85ccc8b9
commit 801061f4f2
9 changed files with 133 additions and 38 deletions

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
@@ -9,7 +9,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
<PackageReference Include="xunit" Version="2.4.1" /> <PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3"> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

View File

@@ -6,6 +6,7 @@ using System.Threading.Tasks;
using AlibabaCloud.OpenApiClient.Models; using AlibabaCloud.OpenApiClient.Models;
using AlibabaCloud.SDK.Alidns20150109; using AlibabaCloud.SDK.Alidns20150109;
using AlibabaCloud.SDK.Alidns20150109.Models; using AlibabaCloud.SDK.Alidns20150109.Models;
using AlibabaCloud.TeaUtil.Models;
using AutoMapper; using AutoMapper;
using Hua.DDNS.Common.Config.Options; using Hua.DDNS.Common.Config.Options;
using Hua.DDNS.Models; using Hua.DDNS.Models;
@@ -55,6 +56,12 @@ namespace Hua.DDNS.DDNSProviders.Ali
return _mapper.Map<IEnumerable<DnsRecord>>(record); return _mapper.Map<IEnumerable<DnsRecord>>(record);
} }
public async Task<DnsRecord> CreateDnsRecordAsync(DnsRecord record)
{
var rep = await _client.AddDomainRecordAsync(_mapper.Map<AddDomainRecordRequest>(record));
return record;
}
/// <summary> /// <summary>
/// 变更解析记录列表 /// 变更解析记录列表
/// </summary> /// </summary>

View File

@@ -12,12 +12,14 @@ using TencentCloud.Common;
using TencentCloud.Dnspod.V20210323; using TencentCloud.Dnspod.V20210323;
using System.Net; using System.Net;
using TencentCloud.Dnspod.V20210323.Models; using TencentCloud.Dnspod.V20210323.Models;
using Newtonsoft.Json.Linq;
namespace Hua.DDNS.DDNSProviders.Dnspod namespace Hua.DDNS.DDNSProviders.Dnspod
{ {
/// <summary> /// <summary>
/// DdnsProvider for Dnspod /// DdnsProvider for Dnspod
/// <remarks></remarks>
/// </summary> /// </summary>
public class DnspodDdnsProvider : IDdnsProvider public class DnspodDdnsProvider : IDdnsProvider
{ {
@@ -53,6 +55,19 @@ namespace Hua.DDNS.DDNSProviders.Dnspod
return _mapper.Map<IEnumerable<DnsRecord>>(recordList); return _mapper.Map<IEnumerable<DnsRecord>>(recordList);
} }
public async Task<DnsRecord> CreateDnsRecordAsync(DnsRecord record)
{
var response = await _client.CreateRecord(new CreateRecordRequest()
{
Domain = _ddnsOption.Domain,
Value = record.Ip,
RecordLine = "默认",
RecordType = record.RecordType,
TTL = Convert.ToUInt32(record.TTL),
});
return record;
}
public async Task<IEnumerable<DnsRecord>> ModifyRecordListAsync(string newIp, IEnumerable<DnsRecord> records) public async Task<IEnumerable<DnsRecord>> ModifyRecordListAsync(string newIp, IEnumerable<DnsRecord> records)
{ {
var rep = await _client.ModifyRecordBatch(new ModifyRecordBatchRequest() var rep = await _client.ModifyRecordBatch(new ModifyRecordBatchRequest()

View File

@@ -21,6 +21,13 @@ namespace Hua.DDNS.DDNSProviders
Task<IEnumerable<DnsRecord>?> GetRecordListAsync(); Task<IEnumerable<DnsRecord>?> GetRecordListAsync();
/// <summary>
/// 创建解析记录
/// </summary>
/// <param name="record"></param>
/// <returns></returns>
Task<DnsRecord> CreateDnsRecordAsync(DnsRecord record);
/// <summary> /// <summary>
/// 修改域名解析记录 /// 修改域名解析记录
/// </summary> /// </summary>

View File

@@ -1,7 +1,9 @@
using System.Xml; using System.Xml;
using AutoMapper; using AutoMapper;
using Hua.DDNS.Models; using Hua.DDNS.Models;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Newtonsoft.Json;
namespace Hua.DDNS.DDNSProviders.Namesilo namespace Hua.DDNS.DDNSProviders.Namesilo
{ {
@@ -60,6 +62,35 @@ namespace Hua.DDNS.DDNSProviders.Namesilo
}).ToList(); }).ToList();
} }
public async Task<DnsRecord> CreateDnsRecordAsync(DnsRecord dnsRecord)
{
var host = dnsRecord.Host[..(dnsRecord.Host.Length - dnsRecord.Domain.Length - 1)];
//https://www.namesilo.com/api/dnsAddRecord?version=1&type=xml&key=12345&domain=namesilo.com&rrtype=A&rrhost=test&rrvalue=55.55.55.55&rrttl=7207
var url = $"https://www.namesilo.com/api/dnsUpdateRecord?version=1&type=xml&key={_namesiloOption.ApiKey}&domain={dnsRecord.Domain}&rrtype={dnsRecord.RecordType}&rrid={dnsRecord.Id}&rrhost={host}&rrvalue={dnsRecord.Ip}&rrttl={dnsRecord.TTL}";
using var client = new HttpClient();
{
var response = await client.GetAsync(url);
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 create record: '{JsonConvert.SerializeObject(dnsRecord)}'");
}
if (status.Value == "300")
{
return null;
//continue;
}
}
return dnsRecord;
}
public async Task<IEnumerable<DnsRecord>> ModifyRecordListAsync(string newIp, IEnumerable<DnsRecord> records) public async Task<IEnumerable<DnsRecord>> ModifyRecordListAsync(string newIp, IEnumerable<DnsRecord> records)
{ {
foreach (var dnsRecord in records) foreach (var dnsRecord in records)

View File

@@ -1,37 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk.Worker"> <Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<PublishSingleFile>true</PublishSingleFile>
<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> <SelfContained>true</SelfContained>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AlibabaCloud.SDK.Alidns20150109" Version="3.0.0" /> <PackageReference Include="AlibabaCloud.SDK.Alidns20150109" Version="3.0.7" />
<PackageReference Include="AutoMapper" Version="12.0.1" /> <PackageReference Include="AutoMapper" Version="12.0.1" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" 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.11" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.15.1" /> <PackageReference Include="Dapper" Version="2.0.138" />
<PackageReference Include="Dapper" Version="2.0.123" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" /> <PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.0" />
<PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.2" /> <PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.2" />
<PackageReference Include="Npgsql" Version="6.0.3" /> <PackageReference Include="Npgsql" Version="7.0.4" />
<PackageReference Include="QRCoder" Version="1.4.1" /> <PackageReference Include="QRCoder" Version="1.4.3" />
<PackageReference Include="Quartz.Extensions.DependencyInjection" Version="3.4.0" /> <PackageReference Include="Quartz.Extensions.DependencyInjection" Version="3.6.2" />
<PackageReference Include="Quartz.Extensions.Hosting" Version="3.4.0" /> <PackageReference Include="Quartz.Extensions.Hosting" Version="3.6.2" />
<PackageReference Include="Serilog" Version="2.10.0" /> <PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="4.2.0" /> <PackageReference Include="Serilog.Extensions.Hosting" Version="7.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.3.0" /> <PackageReference Include="Serilog.Settings.Configuration" Version="7.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" /> <PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="TencentCloudSDK.Dnspod" Version="3.0.623" /> <PackageReference Include="TencentCloudSDK.Dnspod" Version="3.0.781" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -21,6 +21,7 @@ using TencentCloud.Dnspod.V20210323.Models;
using Tea; using Tea;
using Tea.Utils; using Tea.Utils;
using System.Net.Sockets;
namespace Hua.DDNS.Jobs namespace Hua.DDNS.Jobs
{ {
@@ -45,31 +46,47 @@ namespace Hua.DDNS.Jobs
public async Task Execute(IJobExecutionContext context) public async Task Execute(IJobExecutionContext context)
{ {
//2.获取DNS记录
IDdnsProvider? ddnsProvider = _ddnsOption.Platform switch
{
PlatformEnum.Namesilo => _serviceProvider.GetRequiredService<NamesiloDdnsProvider>(),
PlatformEnum.Tencent => _serviceProvider.GetRequiredService<DnspodDdnsProvider>(),
PlatformEnum.Ali => _serviceProvider.GetRequiredService<AliDdnsProvider>(),
_ => null
};
newIp = await _httpHelper.GetCurrentPublicIpv4();
try try
{ {
//1. 获取当前机器ip //1. 获取当前机器ip
var domain = $"{_ddnsOption.SubDomainArray.First()}.{_ddnsOption.Domain}"; var domain = $"{_ddnsOption.SubDomainArray.First()}.{_ddnsOption.Domain}";
var oldIp = (await Dns.GetHostEntryAsync(domain)).AddressList.First(); IPAddress oldIp = null;
newIp = await _httpHelper.GetCurrentPublicIpv4(); oldIp = (await Dns.GetHostEntryAsync(domain)).AddressList.First();
//1.1 如果当前dns记录与实际dns记录一致跳出本次执行 //1.1 如果当前dns记录与实际dns记录一致跳出本次执行
if (newIp == oldIp.ToString()) return; 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 dnsRecordList = await ddnsProvider!.GetRecordListAsync();
var record = dnsRecordList.FirstOrDefault(m => m.Ip == newIp && _ddnsOption.SubDomainArray.Any(n => m.SubDomain == n)); var record = dnsRecordList.FirstOrDefault(m =>
if (record != null && record.Ip == newIp) return;//如果记录已经变更,不调用更新接口 m.Ip == newIp && _ddnsOption.SubDomainArray.Any(n => m.SubDomain == n));
if (record != null && record.Ip == newIp) return; //如果记录已经变更,不调用更新接口
//3.比较并更新 //3.比较并更新
await ddnsProvider.ModifyRecordListAsync(newIp, dnsRecordList.Where(m => m.Ip != newIp && _ddnsOption.SubDomainArray.Any(n => m.SubDomain == n))); await ddnsProvider.ModifyRecordListAsync(newIp,
dnsRecordList.Where(m => m.Ip != newIp && _ddnsOption.SubDomainArray.Any(n => m.SubDomain == n)));
}
catch (SocketException e)
{
if (e.Message.Contains("不知道这样的主机"))
{
await ddnsProvider.CreateDnsRecordAsync(new DnsRecord()
{
Ip = newIp,
Host = _ddnsOption.SubDomainArray.First(),
Domain = _ddnsOption.Domain,
});
}
} }
catch (Exception e) catch (Exception e)
{ {

View File

@@ -13,6 +13,17 @@ public class DnsRecord
public string Host { get; set; } public string Host { get; set; }
public string SubDomain { get; set; } public string SubDomain { get; set; }
public string Domain { get; set; } public string Domain { get; set; }
public string TTL { get; set; } public string TTL { get; set; } = "10";
public string RecordType { get; set; } public string RecordType { get; set; } = "A";
public DnsRecord(string ip,string domain)
{
Ip = ip;
Host = domain;
}
public DnsRecord()
{
}
} }

View File

@@ -34,6 +34,14 @@ namespace Hua.DDNS.Models
.ForMember(dest => dest.Ip, opt => opt.MapFrom(src => src.Value)) .ForMember(dest => dest.Ip, opt => opt.MapFrom(src => src.Value))
.ForMember(dest => dest.SubDomain, opt => opt.MapFrom(src => src.Name)) .ForMember(dest => dest.SubDomain, opt => opt.MapFrom(src => src.Name))
; ;
CreateMap<DnsRecord, AddDomainRecordRequest>()
//.ForMember(dest => dest., 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))
.ForMember(dest => dest.DomainName, opt => opt.MapFrom(src => src.Domain))
;
} }
} }
} }