|
1 | 1 | using LetsEncrypt.Azure.Core.V2.CertificateStores;
|
2 |
| -using LetsEncrypt.Azure.Core.V2.DnsProviders; |
3 | 2 | using LetsEncrypt.Azure.Core.V2.Models;
|
4 |
| -using Microsoft.Extensions.DependencyInjection; |
| 3 | +using Microsoft.Extensions.Logging; |
| 4 | +using Microsoft.Extensions.Logging.Abstractions; |
5 | 5 | using System;
|
| 6 | +using System.Threading.Tasks; |
6 | 7 |
|
7 | 8 | namespace LetsEncrypt.Azure.Core.V2
|
8 | 9 | {
|
9 |
| - public static class LetsencryptService |
| 10 | + public class LetsencryptService |
10 | 11 | {
|
11 |
| - public static IServiceCollection AddAcmeClient<TDnsProvider>(this IServiceCollection serviceCollection, object dnsProviderConfig, string azureStorageConnectionString = null) where TDnsProvider : class, IDnsProvider |
12 |
| - { |
13 |
| - if (serviceCollection == null) |
14 |
| - { |
15 |
| - throw new ArgumentNullException(nameof(serviceCollection)); |
16 |
| - } |
| 12 | + private readonly AcmeClient acmeClient; |
| 13 | + private readonly ICertificateStore certificateStore; |
| 14 | + private readonly AzureWebAppService azureWebAppService; |
| 15 | + private readonly ILogger<LetsencryptService> logger; |
17 | 16 |
|
18 |
| - if (dnsProviderConfig == null) |
19 |
| - { |
20 |
| - throw new ArgumentNullException(nameof(dnsProviderConfig)); |
21 |
| - } |
22 |
| - if (string.IsNullOrEmpty(azureStorageConnectionString)) |
23 |
| - { |
24 |
| - serviceCollection |
25 |
| - .AddTransient<IFileSystem, FileSystem>() |
26 |
| - .AddTransient<ICertificateStore, FileSystemCertificateStore>(); |
27 |
| - } |
28 |
| - else |
| 17 | + public LetsencryptService(AcmeClient acmeClient, ICertificateStore certificateStore, AzureWebAppService azureWebAppService, ILogger<LetsencryptService> logger = null) |
| 18 | + { |
| 19 | + this.acmeClient = acmeClient; |
| 20 | + this.certificateStore = certificateStore; |
| 21 | + this.azureWebAppService = azureWebAppService; |
| 22 | + this.logger = logger ?? NullLogger<LetsencryptService>.Instance; |
| 23 | + } |
| 24 | + public async Task Run(AcmeDnsRequest acmeDnsRequest, int renewXNumberOfDaysBeforeExpiration) |
| 25 | + { |
| 26 | + try |
29 | 27 | {
|
30 |
| - serviceCollection |
31 |
| - .AddTransient<IFileSystem, AzureBlobStorage>(s => |
| 28 | + CertificateInstallModel model = null; |
| 29 | + |
| 30 | + var certname = acmeDnsRequest.Host.Substring(2) + "-" + acmeDnsRequest.AcmeEnvironment.Name; |
| 31 | + var cert = await certificateStore.GetCertificate(certname, acmeDnsRequest.PFXPassword); |
| 32 | + if (cert == null || cert.Certificate.NotAfter < DateTime.UtcNow.AddDays(renewXNumberOfDaysBeforeExpiration)) //Cert doesnt exist or expires in less than renewXNumberOfDaysBeforeExpiration days, lets renew. |
| 33 | + { |
| 34 | + logger.LogInformation("Certificate store didn't contain certificate or certificate was expired starting renewing"); |
| 35 | + model = await acmeClient.RequestDnsChallengeCertificate(acmeDnsRequest); |
| 36 | + model.CertificateInfo.Name = certname; |
| 37 | + await certificateStore.SaveCertificate(model.CertificateInfo); |
| 38 | + } |
| 39 | + else |
| 40 | + { |
| 41 | + logger.LogInformation("Certificate expires in more than {renewXNumberOfDaysBeforeExpiration} days, reusing certificate from certificate store", renewXNumberOfDaysBeforeExpiration); |
| 42 | + model = new CertificateInstallModel() |
32 | 43 | {
|
33 |
| - return new AzureBlobStorage(azureStorageConnectionString); |
34 |
| - }) |
35 |
| - .AddTransient<AzureBlobStorage, AzureBlobStorage>(s => |
36 |
| - { |
37 |
| - return new AzureBlobStorage(azureStorageConnectionString); |
38 |
| - }) |
39 |
| - .AddTransient<ICertificateStore, AzureBlobCertificateStore>(); |
40 |
| - } |
41 |
| - return serviceCollection |
42 |
| - .AddTransient<AcmeClient>() |
43 |
| - .AddTransient<DnsLookupService>() |
44 |
| - .AddSingleton(dnsProviderConfig.GetType(), dnsProviderConfig) |
45 |
| - .AddTransient<IDnsProvider, TDnsProvider>(); |
46 |
| - } |
| 44 | + CertificateInfo = cert, |
| 45 | + Host = acmeDnsRequest.Host |
| 46 | + }; |
| 47 | + } |
| 48 | + await azureWebAppService.Install(model); |
47 | 49 |
|
48 |
| - public static IServiceCollection AddAzureAppService(this IServiceCollection serviceCollection, params AzureWebAppSettings[] settings) |
49 |
| - { |
50 |
| - if (settings == null || settings.Length == 0) |
| 50 | + logger.LogInformation("Removing expired certificates"); |
| 51 | + var expired = azureWebAppService.RemoveExpired(); |
| 52 | + logger.LogInformation("The following certificates was removed {Thumbprints}", string.Join(", ", expired.ToArray())); |
| 53 | + |
| 54 | + } |
| 55 | + catch (Exception e) |
51 | 56 | {
|
52 |
| - throw new ArgumentNullException(nameof(settings)); |
| 57 | + logger.LogError(e, "Failed"); |
| 58 | + throw; |
53 | 59 | }
|
54 |
| - |
55 |
| - return serviceCollection |
56 |
| - .AddSingleton(settings) |
57 |
| - .AddTransient<AzureWebAppService>(); |
58 | 60 | }
|
59 | 61 | }
|
60 | 62 | }
|
0 commit comments