From e5e1dff331070795f93ad9431ea20115aad0f52c Mon Sep 17 00:00:00 2001 From: elias Date: Tue, 31 Jan 2023 20:10:12 +0100 Subject: [PATCH] Added Structure to Code. Added automatic request of the UpdateURL. --- DDNSUpdater.sln | 16 ++++ DDNSUpdater/DDNSUpdater.csproj | 33 +++++++ DDNSUpdater/Interfaces/IDDNSService.cs | 8 ++ DDNSUpdater/Interfaces/ITimerService.cs | 6 ++ DDNSUpdater/Models/Requests/DynamicDns.cs | 12 +++ .../Models/Requests/DynamicDnsResponse.cs | 9 ++ DDNSUpdater/Program.cs | 27 ++++++ DDNSUpdater/Services/DDNSService.cs | 87 +++++++++++++++++++ DDNSUpdater/Services/TimerService.cs | 36 ++++++++ DDNSUpdater/appsettings.json | 14 +++ Dockerfile | 18 ++++ 11 files changed, 266 insertions(+) create mode 100644 DDNSUpdater.sln create mode 100644 DDNSUpdater/DDNSUpdater.csproj create mode 100644 DDNSUpdater/Interfaces/IDDNSService.cs create mode 100644 DDNSUpdater/Interfaces/ITimerService.cs create mode 100644 DDNSUpdater/Models/Requests/DynamicDns.cs create mode 100644 DDNSUpdater/Models/Requests/DynamicDnsResponse.cs create mode 100644 DDNSUpdater/Program.cs create mode 100644 DDNSUpdater/Services/DDNSService.cs create mode 100644 DDNSUpdater/Services/TimerService.cs create mode 100644 DDNSUpdater/appsettings.json create mode 100644 Dockerfile diff --git a/DDNSUpdater.sln b/DDNSUpdater.sln new file mode 100644 index 0000000..2a75291 --- /dev/null +++ b/DDNSUpdater.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DDNSUpdater", "DDNSUpdater\DDNSUpdater.csproj", "{EDEDF642-4CFC-4EEB-A8F2-3872DBEC63E3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EDEDF642-4CFC-4EEB-A8F2-3872DBEC63E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EDEDF642-4CFC-4EEB-A8F2-3872DBEC63E3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EDEDF642-4CFC-4EEB-A8F2-3872DBEC63E3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EDEDF642-4CFC-4EEB-A8F2-3872DBEC63E3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/DDNSUpdater/DDNSUpdater.csproj b/DDNSUpdater/DDNSUpdater.csproj new file mode 100644 index 0000000..cac29fc --- /dev/null +++ b/DDNSUpdater/DDNSUpdater.csproj @@ -0,0 +1,33 @@ + + + + Exe + net7.0 + enable + enable + Linux + + + + + .dockerignore + + + + + + + + + + + + + + + + PreserveNewest + + + + diff --git a/DDNSUpdater/Interfaces/IDDNSService.cs b/DDNSUpdater/Interfaces/IDDNSService.cs new file mode 100644 index 0000000..5066307 --- /dev/null +++ b/DDNSUpdater/Interfaces/IDDNSService.cs @@ -0,0 +1,8 @@ +namespace DDNSUpdater.Interfaces; + +public interface IDDNSService +{ + public void Start(); + public void Update(); + public void SetUpdateURL(); +} \ No newline at end of file diff --git a/DDNSUpdater/Interfaces/ITimerService.cs b/DDNSUpdater/Interfaces/ITimerService.cs new file mode 100644 index 0000000..c93ffff --- /dev/null +++ b/DDNSUpdater/Interfaces/ITimerService.cs @@ -0,0 +1,6 @@ +namespace DDNSUpdater.Interfaces; + +public interface ITimerService +{ + void Start(); +} \ No newline at end of file diff --git a/DDNSUpdater/Models/Requests/DynamicDns.cs b/DDNSUpdater/Models/Requests/DynamicDns.cs new file mode 100644 index 0000000..474ce95 --- /dev/null +++ b/DDNSUpdater/Models/Requests/DynamicDns.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace DDNSUpdater.Models.Requests; + +public class DynamicDns +{ + [JsonProperty("domains")] + public List Domains { get; set; } + + [JsonProperty("description")] + public string Description { get; set; } +} \ No newline at end of file diff --git a/DDNSUpdater/Models/Requests/DynamicDnsResponse.cs b/DDNSUpdater/Models/Requests/DynamicDnsResponse.cs new file mode 100644 index 0000000..eca4cc3 --- /dev/null +++ b/DDNSUpdater/Models/Requests/DynamicDnsResponse.cs @@ -0,0 +1,9 @@ +namespace DDNSUpdater.Models.Requests; + +public class DynamicDnsResponse +{ + public string BulkId { get; set; } + public string UpdateUrl { get; set; } + public List Domains { get; set; } + public string Description { get; set; } +} \ No newline at end of file diff --git a/DDNSUpdater/Program.cs b/DDNSUpdater/Program.cs new file mode 100644 index 0000000..492ec67 --- /dev/null +++ b/DDNSUpdater/Program.cs @@ -0,0 +1,27 @@ +using DDNSUpdater.Interfaces; +using DDNSUpdater.Services; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using RestSharp; + +var builder = new ConfigurationBuilder() + .AddJsonFile("appsettings.json", optional: false, reloadOnChange: false); + +var configuration = builder.Build(); + + +var serviceProvider = new ServiceCollection() + .AddSingleton(configuration) + .AddLogging(logging => logging.AddConsole()) + .AddSingleton() + .AddSingleton() + .BuildServiceProvider(); + +var dataAccess = serviceProvider.GetService(); +dataAccess.Start(); + +var timerService = serviceProvider.GetService(); +timerService.Start(); + +Console.ReadKey(); diff --git a/DDNSUpdater/Services/DDNSService.cs b/DDNSUpdater/Services/DDNSService.cs new file mode 100644 index 0000000..5316011 --- /dev/null +++ b/DDNSUpdater/Services/DDNSService.cs @@ -0,0 +1,87 @@ +using System.Net; +using DDNSUpdater.Interfaces; +using DDNSUpdater.Models.Requests; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using RestSharp; +using RestSharp.Serializers; + +namespace DDNSUpdater.Services; + +public class DDNSService : IDDNSService +{ + private string UpdateURL { get; set; } + public string APIKey { get; set; } + public List Domains { get; set; } + + private readonly ILogger _logger; + + public DDNSService(ILogger logger,IConfiguration configuration) + { + _logger = logger; + APIKey = configuration.GetValue("APIKey"); + Domains = configuration.GetSection("Domains").Get>(); + } + + public async void Start() + { + UpdateURL = await GetUpdateURL(); + _logger.LogInformation("Got new Update URL: " + UpdateURL); + } + + public async void Update() + { + var client = new RestClient(UpdateURL); + var request = new RestRequest("",Method.Get); + request.AddHeader("Cookie", "0b04270753322c986927738ac2b6c0d8=ea099cbd8a6109c688f9831d6bbfa7a1; 5b66c83e4535f5f6bef8295496cfe559=e85228fccae97f107478bf9ef664e4eb; DPX=v1:ghOJrOzFTj:htgOaKFW:63d3bf8f:de"); + var body = @""; + request.AddParameter("text/plain", body, ParameterType.RequestBody); + + try + { + var response = await client.ExecuteAsync(request); + _logger.LogInformation("Send Update to Ionos"); + } + catch (Exception e) + { + _logger.LogError(e.Message); + throw; + } + + } + + public async void SetUpdateURL() + { + UpdateURL = await GetUpdateURL(); + } + + private async Task GetUpdateURL() + { + var dyndns = new DynamicDns() + { + Domains = Domains, + Description = "My DynamicDns" + }; + var content = JsonConvert.SerializeObject(dyndns); + var client = new RestClient("https://api.hosting.ionos.com/dns/v1"); + var request = new RestRequest("/dyndns", Method.Post); + + + request.AddHeader("X-API-Key", APIKey); + + request.AddStringBody(content, ContentType.Json); + + + try + { + var response = client.ExecutePost(request); + return response.Data.UpdateUrl; + } + catch (Exception error) + { + _logger.LogError(error.Message); + return ""; + } + } +} \ No newline at end of file diff --git a/DDNSUpdater/Services/TimerService.cs b/DDNSUpdater/Services/TimerService.cs new file mode 100644 index 0000000..1a036f1 --- /dev/null +++ b/DDNSUpdater/Services/TimerService.cs @@ -0,0 +1,36 @@ +using DDNSUpdater.Interfaces; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace DDNSUpdater.Services; + +public class TimerService : ITimerService +{ + private Timer timer; + private readonly ILogger _logger; + private readonly IServiceScopeFactory _factory; + private readonly int intervalMinutes; + + public TimerService(ILogger logger,IServiceScopeFactory factory, IConfiguration configuration) + { + _logger = logger; + _factory = factory; + intervalMinutes = configuration.GetValue("TimerIntervalMinutes"); + timer = new Timer(TimerCallback, null, TimeSpan.Zero, TimeSpan.FromMinutes(intervalMinutes)); + } + + private async void TimerCallback(Object o) + { + _logger.LogDebug("Timer callback executed at " + DateTime.Now); + await using var asyncScope = _factory.CreateAsyncScope(); + var ddnsService = asyncScope.ServiceProvider.GetRequiredService(); + + ddnsService.Update(); + } + + public void Start() + { + _logger.LogInformation("Timer service started."); + } +} \ No newline at end of file diff --git a/DDNSUpdater/appsettings.json b/DDNSUpdater/appsettings.json new file mode 100644 index 0000000..3145070 --- /dev/null +++ b/DDNSUpdater/appsettings.json @@ -0,0 +1,14 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug" + } + }, + "TimerIntervalMinutes": 1, + "APIKey": "4dc281058e9648919a988315c84058fa.z0eKvfJSuUpeU-2W-quUCsM_6aSshAX8tdPrJ1NQUBtcaImOtoQCk82nT4kDWzBjj2l2PMo1vGXCc6vGW9bKHA", + "Domains": [ + "*.sailehd.de", + "*.sailehd.dev", + "*.sailehd.com" + ] +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9ce6e81 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,18 @@ +FROM mcr.microsoft.com/dotnet/runtime:7.0 AS base +WORKDIR /app + +FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build +WORKDIR /src +COPY ["DDNSUpdater/DDNSUpdater.csproj", "DDNSUpdater/"] +RUN dotnet restore "DDNSUpdater/DDNSUpdater.csproj" +COPY . . +WORKDIR "/src/DDNSUpdater" +RUN dotnet build "DDNSUpdater.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "DDNSUpdater.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "DDNSUpdater.dll"]