Docker Label DNS

This commit is contained in:
root 2023-09-03 17:30:42 +00:00
parent e6b175a18c
commit 6473c518e3
8 changed files with 154 additions and 36 deletions

View File

@ -9,6 +9,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Docker.DotNet" Version="3.125.15" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.10" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />

View File

@ -0,0 +1,15 @@
using DDNSUpdater.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
namespace DDNSUpdater;
public class DataContext : DbContext
{
public DataContext(DbContextOptions<DataContext> options)
: base(options) { }
public DbSet<Domain> Domains { get; set; }
}

View File

@ -2,7 +2,7 @@
public interface IDDNSService
{
public void Start();
public void Update();
public void Init();
public void Update(bool changed);
public void SetUpdateURL();
}

View File

@ -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; }
}

View File

@ -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<ITimerService, TimerService>()
.AddSingleton<DDNSService>()
.AddSingleton(dockerClient)
.AddSingleton<DockerService>()
.AddDbContext<DataContext>(options => options.UseInMemoryDatabase(databaseName: "DataContext"))
.BuildServiceProvider();
var dockerService = serviceProvider.GetService<DockerService>();
dockerService?.UpdateDomainList();
var dataContext = serviceProvider.GetService<DataContext>();
var FoundDomains = dataContext.Domains.ToListAsync();
var dataAccess = serviceProvider.GetService<DDNSService>();
dataAccess.Start();
dataAccess?.Init();
var timerService = serviceProvider.GetService<ITimerService>();
timerService.Start();
timerService?.Start();
Console.ReadKey();

View File

@ -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<string>? UpdateURLs { get; set; }
public List<Domain> Domains { get; set; }
private readonly ILogger<DDNSService> _logger;
public DDNSService(ILogger<DDNSService> logger,IConfiguration configuration)
private readonly DataContext _dataContext;
public DDNSService(ILogger<DDNSService> logger,IConfiguration configuration, DataContext dataContext)
{
_logger = logger;
Domains = new List<Domain>();
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<string, List<string>> domainDict = new Dictionary<string, List<string>>();
Dictionary<string,Table> tables = new Dictionary<string,Table>();
foreach (var domain in Domains)
foreach (var domain in await _dataContext.Domains.ToListAsync())
{
if (!domainDict.ContainsKey(domain.Key))

View File

@ -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<TimerService> _logger;
private readonly IServiceScopeFactory _factory;
private readonly DockerClient _dockerClient;
private readonly DataContext _context;
private readonly int intervalMinutes;
public DockerService(ILogger<TimerService> logger,IServiceScopeFactory factory, IConfiguration configuration, DockerClient dockerClient, DataContext context)
{
_logger = logger;
_factory = factory;
_dockerClient = dockerClient;
_context = context;
}
public async Task GetDocker()
{
}
public async Task<bool> 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<string, string>("caddy", domain.DomainString)))
{
found = true;
}
}
if (!found)
{
_context.Domains.Remove(domain);
}
}
await _context.SaveChangesAsync();
return changed;
}
}

View File

@ -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>();
ddnsService.Update();
var dockerService = asyncScope.ServiceProvider.GetRequiredService<DockerService>();
bool changed = await dockerService.UpdateDomainList();
ddnsService.Update(changed);
}
public void Start()