From 6473c518e36d669d95bbd5a5baad4220587145a8 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 3 Sep 2023 17:30:42 +0000 Subject: [PATCH] Docker Label DNS --- DDNSUpdater/DDNSUpdater.csproj | 2 + DDNSUpdater/DataContext.cs | 15 +++++ DDNSUpdater/Interfaces/IDDNSService.cs | 4 +- DDNSUpdater/Models/Domain.cs | 11 ++-- DDNSUpdater/Program.cs | 18 +++++- DDNSUpdater/Services/DDNSService.cs | 47 +++++++------- DDNSUpdater/Services/DockerService.cs | 87 ++++++++++++++++++++++++++ DDNSUpdater/Services/TimerService.cs | 6 +- 8 files changed, 154 insertions(+), 36 deletions(-) create mode 100644 DDNSUpdater/DataContext.cs create mode 100644 DDNSUpdater/Services/DockerService.cs diff --git a/DDNSUpdater/DDNSUpdater.csproj b/DDNSUpdater/DDNSUpdater.csproj index 5a51d44..43e2c8f 100644 --- a/DDNSUpdater/DDNSUpdater.csproj +++ b/DDNSUpdater/DDNSUpdater.csproj @@ -9,6 +9,8 @@ + + diff --git a/DDNSUpdater/DataContext.cs b/DDNSUpdater/DataContext.cs new file mode 100644 index 0000000..d4d5a10 --- /dev/null +++ b/DDNSUpdater/DataContext.cs @@ -0,0 +1,15 @@ +using DDNSUpdater.Models; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; + +namespace DDNSUpdater; + +public class DataContext : DbContext +{ + + public DataContext(DbContextOptions options) + : base(options) { } + + + public DbSet Domains { get; set; } +} \ No newline at end of file diff --git a/DDNSUpdater/Interfaces/IDDNSService.cs b/DDNSUpdater/Interfaces/IDDNSService.cs index 5066307..65e70b3 100644 --- a/DDNSUpdater/Interfaces/IDDNSService.cs +++ b/DDNSUpdater/Interfaces/IDDNSService.cs @@ -2,7 +2,7 @@ public interface IDDNSService { - public void Start(); - public void Update(); + public void Init(); + public void Update(bool changed); public void SetUpdateURL(); } \ No newline at end of file diff --git a/DDNSUpdater/Models/Domain.cs b/DDNSUpdater/Models/Domain.cs index 4561060..9577d69 100644 --- a/DDNSUpdater/Models/Domain.cs +++ b/DDNSUpdater/Models/Domain.cs @@ -1,13 +1,12 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + namespace DDNSUpdater.Models; public class Domain { - public Domain(string domain, string key) - { - DomainString = domain; - Key = key; - } - + [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } public string DomainString { get; set; } public string Key { get; set; } } \ No newline at end of file diff --git a/DDNSUpdater/Program.cs b/DDNSUpdater/Program.cs index c5c6692..97a48ed 100644 --- a/DDNSUpdater/Program.cs +++ b/DDNSUpdater/Program.cs @@ -1,7 +1,10 @@ using System; +using DDNSUpdater; using DDNSUpdater.Interfaces; using DDNSUpdater.Logging; using DDNSUpdater.Services; +using Docker.DotNet; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -11,7 +14,8 @@ using RestSharp; var builder = new ConfigurationBuilder() .AddJsonFile("appsettings.json", optional: false, reloadOnChange: false); - +DockerClient dockerClient = new DockerClientConfiguration() + .CreateClient(); var configuration = builder.Build(); @@ -30,15 +34,23 @@ var serviceProvider = new ServiceCollection() })) .AddSingleton() .AddSingleton() + .AddSingleton(dockerClient) + .AddSingleton() + .AddDbContext(options => options.UseInMemoryDatabase(databaseName: "DataContext")) .BuildServiceProvider(); +var dockerService = serviceProvider.GetService(); +dockerService?.UpdateDomainList(); + +var dataContext = serviceProvider.GetService(); +var FoundDomains = dataContext.Domains.ToListAsync(); var dataAccess = serviceProvider.GetService(); -dataAccess.Start(); +dataAccess?.Init(); var timerService = serviceProvider.GetService(); -timerService.Start(); +timerService?.Start(); Console.ReadKey(); diff --git a/DDNSUpdater/Services/DDNSService.cs b/DDNSUpdater/Services/DDNSService.cs index 93f0089..706147f 100644 --- a/DDNSUpdater/Services/DDNSService.cs +++ b/DDNSUpdater/Services/DDNSService.cs @@ -8,6 +8,7 @@ using DDNSUpdater.Interfaces; using DDNSUpdater.Logging; using DDNSUpdater.Models; using DDNSUpdater.Models.Requests; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Newtonsoft.Json; @@ -21,46 +22,46 @@ namespace DDNSUpdater.Services; public class DDNSService : IDDNSService { private List? UpdateURLs { get; set; } - public List Domains { get; set; } private readonly ILogger _logger; - - public DDNSService(ILogger logger,IConfiguration configuration) + private readonly DataContext _dataContext; + + public DDNSService(ILogger logger,IConfiguration configuration, DataContext dataContext) { _logger = logger; - Domains = new List(); - - foreach (DictionaryEntry de in Environment.GetEnvironmentVariables()) - { - - if (de.Key.ToString().ToLower().Contains("domain-")) - { - // domain;key - var env = de.Value.ToString().Split(";").ToList(); - - - Domains.Add(new Domain(env[0], env[1])); - } - } - - + _dataContext = dataContext; } - public async void Start() + + public async void Init() { + int count = 0; _logger.LogInformation("Fetching UpdateURLs"); + var domains = await _dataContext.Domains.ToListAsync(); + if (domains.Count == 0) + { + return; + } UpdateURLs = await GetUpdateURLs(); - while (UpdateURLs == null || UpdateURLs.Count == 0 ) + while (UpdateURLs == null || UpdateURLs.Count == 0 || count > 50) { _logger.LogInformation($"Fetching UpdateURLs again."); UpdateURLs = await GetUpdateURLs(); + count++; } _logger.LogInformation($"Fetched {UpdateURLs.Count} UpdateURLs"); } - public async void Update() + public async void Update(bool changed) { + if (changed) + { + Init(); + } + + if(UpdateURLs.Count == 0) return; + foreach (var UpdateURL in UpdateURLs) { var client = new RestClient(UpdateURL); @@ -94,7 +95,7 @@ public class DDNSService : IDDNSService Dictionary> domainDict = new Dictionary>(); Dictionary tables = new Dictionary(); - foreach (var domain in Domains) + foreach (var domain in await _dataContext.Domains.ToListAsync()) { if (!domainDict.ContainsKey(domain.Key)) diff --git a/DDNSUpdater/Services/DockerService.cs b/DDNSUpdater/Services/DockerService.cs new file mode 100644 index 0000000..1e3522f --- /dev/null +++ b/DDNSUpdater/Services/DockerService.cs @@ -0,0 +1,87 @@ +using DDNSUpdater.Models; +using Docker.DotNet; +using Docker.DotNet.Models; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace DDNSUpdater.Services; + +public class DockerService +{ + private Timer timer; + private readonly ILogger _logger; + private readonly IServiceScopeFactory _factory; + private readonly DockerClient _dockerClient; + private readonly DataContext _context; + private readonly int intervalMinutes; + + public DockerService(ILogger logger,IServiceScopeFactory factory, IConfiguration configuration, DockerClient dockerClient, DataContext context) + { + _logger = logger; + _factory = factory; + _dockerClient = dockerClient; + _context = context; + } + + public async Task GetDocker() + { + + } + + public async Task UpdateDomainList() + { + var changed = false; + + + var containers = await _dockerClient.Containers.ListContainersAsync(new ContainersListParameters()); + var domains = await _context.Domains.ToListAsync(); + foreach (var container in containers) + { + if (container.Labels.ContainsKey("caddy") && container.Labels.ContainsKey("caddy.tls.dns")) + { + var domain = container.Labels["caddy"]; + var apiKey = container.Labels["caddy.tls.dns"].Replace("ionos ", ""); + + Domain? find = domains.Find(d => d.DomainString.Equals(domain)); + + + if (find == null) + { + changed = true; + await _context.Domains.AddAsync(new Domain(){DomainString = domain, Key = apiKey}); + } + + await _context.SaveChangesAsync(); + + } + } + domains = await _context.Domains.ToListAsync(); + foreach (var domain in domains) + { + var found = false; + foreach (var containerListResponse in containers) + { + if (!containerListResponse.Labels.Contains( + new KeyValuePair("caddy", domain.DomainString))) + { + found = true; + } + } + + if (!found) + { + _context.Domains.Remove(domain); + } + } + + + await _context.SaveChangesAsync(); + + + + return changed; + + } +} \ No newline at end of file diff --git a/DDNSUpdater/Services/TimerService.cs b/DDNSUpdater/Services/TimerService.cs index b4bf798..5ff6bd7 100644 --- a/DDNSUpdater/Services/TimerService.cs +++ b/DDNSUpdater/Services/TimerService.cs @@ -27,8 +27,10 @@ public class TimerService : ITimerService _logger.LogDebug("Timer callback executed at " + DateTime.Now); await using var asyncScope = _factory.CreateAsyncScope(); var ddnsService = asyncScope.ServiceProvider.GetRequiredService(); - - ddnsService.Update(); + var dockerService = asyncScope.ServiceProvider.GetRequiredService(); + + bool changed = await dockerService.UpdateDomainList(); + ddnsService.Update(changed); } public void Start()