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> </PropertyGroup>
<ItemGroup> <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" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" 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 interface IDDNSService
{ {
public void Start(); public void Init();
public void Update(); public void Update(bool changed);
public void SetUpdateURL(); public void SetUpdateURL();
} }

View File

@ -1,13 +1,12 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DDNSUpdater.Models; namespace DDNSUpdater.Models;
public class Domain public class Domain
{ {
public Domain(string domain, string key) [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
{ public int Id { get; set; }
DomainString = domain;
Key = key;
}
public string DomainString { get; set; } public string DomainString { get; set; }
public string Key { get; set; } public string Key { get; set; }
} }

View File

@ -1,7 +1,10 @@
using System; using System;
using DDNSUpdater;
using DDNSUpdater.Interfaces; using DDNSUpdater.Interfaces;
using DDNSUpdater.Logging; using DDNSUpdater.Logging;
using DDNSUpdater.Services; using DDNSUpdater.Services;
using Docker.DotNet;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -11,7 +14,8 @@ using RestSharp;
var builder = new ConfigurationBuilder() var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: false); .AddJsonFile("appsettings.json", optional: false, reloadOnChange: false);
DockerClient dockerClient = new DockerClientConfiguration()
.CreateClient();
var configuration = builder.Build(); var configuration = builder.Build();
@ -30,15 +34,23 @@ var serviceProvider = new ServiceCollection()
})) }))
.AddSingleton<ITimerService, TimerService>() .AddSingleton<ITimerService, TimerService>()
.AddSingleton<DDNSService>() .AddSingleton<DDNSService>()
.AddSingleton(dockerClient)
.AddSingleton<DockerService>()
.AddDbContext<DataContext>(options => options.UseInMemoryDatabase(databaseName: "DataContext"))
.BuildServiceProvider(); .BuildServiceProvider();
var dockerService = serviceProvider.GetService<DockerService>();
dockerService?.UpdateDomainList();
var dataContext = serviceProvider.GetService<DataContext>();
var FoundDomains = dataContext.Domains.ToListAsync();
var dataAccess = serviceProvider.GetService<DDNSService>(); var dataAccess = serviceProvider.GetService<DDNSService>();
dataAccess.Start(); dataAccess?.Init();
var timerService = serviceProvider.GetService<ITimerService>(); var timerService = serviceProvider.GetService<ITimerService>();
timerService.Start(); timerService?.Start();
Console.ReadKey(); Console.ReadKey();

View File

@ -8,6 +8,7 @@ using DDNSUpdater.Interfaces;
using DDNSUpdater.Logging; using DDNSUpdater.Logging;
using DDNSUpdater.Models; using DDNSUpdater.Models;
using DDNSUpdater.Models.Requests; using DDNSUpdater.Models.Requests;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Newtonsoft.Json; using Newtonsoft.Json;
@ -21,46 +22,46 @@ namespace DDNSUpdater.Services;
public class DDNSService : IDDNSService public class DDNSService : IDDNSService
{ {
private List<string>? UpdateURLs { get; set; } private List<string>? UpdateURLs { get; set; }
public List<Domain> Domains { get; set; }
private readonly ILogger<DDNSService> _logger; private readonly ILogger<DDNSService> _logger;
private readonly DataContext _dataContext;
public DDNSService(ILogger<DDNSService> logger,IConfiguration configuration)
public DDNSService(ILogger<DDNSService> logger,IConfiguration configuration, DataContext dataContext)
{ {
_logger = logger; _logger = logger;
Domains = new List<Domain>(); _dataContext = dataContext;
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]));
}
}
} }
public async void Start()
public async void Init()
{ {
int count = 0;
_logger.LogInformation("Fetching UpdateURLs"); _logger.LogInformation("Fetching UpdateURLs");
var domains = await _dataContext.Domains.ToListAsync();
if (domains.Count == 0)
{
return;
}
UpdateURLs = await GetUpdateURLs(); UpdateURLs = await GetUpdateURLs();
while (UpdateURLs == null || UpdateURLs.Count == 0 ) while (UpdateURLs == null || UpdateURLs.Count == 0 || count > 50)
{ {
_logger.LogInformation($"Fetching UpdateURLs again."); _logger.LogInformation($"Fetching UpdateURLs again.");
UpdateURLs = await GetUpdateURLs(); UpdateURLs = await GetUpdateURLs();
count++;
} }
_logger.LogInformation($"Fetched {UpdateURLs.Count} UpdateURLs"); _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) foreach (var UpdateURL in UpdateURLs)
{ {
var client = new RestClient(UpdateURL); 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, List<string>> domainDict = new Dictionary<string, List<string>>();
Dictionary<string,Table> tables = new Dictionary<string,Table>(); 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)) 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); _logger.LogDebug("Timer callback executed at " + DateTime.Now);
await using var asyncScope = _factory.CreateAsyncScope(); await using var asyncScope = _factory.CreateAsyncScope();
var ddnsService = asyncScope.ServiceProvider.GetRequiredService<DDNSService>(); var ddnsService = asyncScope.ServiceProvider.GetRequiredService<DDNSService>();
var dockerService = asyncScope.ServiceProvider.GetRequiredService<DockerService>();
ddnsService.Update();
bool changed = await dockerService.UpdateDomainList();
ddnsService.Update(changed);
} }
public void Start() public void Start()