Skip to content

Commit

Permalink
Proper status code from function. Added null certificate consumer.
Browse files Browse the repository at this point in the history
  • Loading branch information
sjkp committed Apr 28, 2019
1 parent 21a6141 commit bafb426
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 18 deletions.
1 change: 1 addition & 0 deletions LetsEncrypt.Azure.DotNetCore.sln
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.dockerignore = .dockerignore
.gitignore = .gitignore
Dockerfile = Dockerfile
readme.md = readme.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LetsEncrypt.Azure.FunctionV2", "examples\LetsEncrypt.Azure.FunctionV2\LetsEncrypt.Azure.FunctionV2.csproj", "{FF8A14C9-8AC7-4057-A2EC-BA31C3965079}"
Expand Down
15 changes: 12 additions & 3 deletions examples/LetsEncrypt.Azure.FunctionV2/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,18 @@ public static async Task InstallOrRenewCertificate(ILogger log)
IServiceCollection serviceCollection = new ServiceCollection();

serviceCollection.AddSingleton<ILogger>(log)
.Configure<LoggerFilterOptions>(options => options.MinLevel = LogLevel.Information)
.AddAzureAppService(Configuration.GetSection("AzureAppService").Get<AzureWebAppSettings>())
.AddSingleton<IKeyVaultClient>(kvClient)
.Configure<LoggerFilterOptions>(options => options.MinLevel = LogLevel.Information);
var certificateConsumer = Configuration.GetValue<string>("CertificateConsumer");
if (string.IsNullOrEmpty(certificateConsumer))
{
serviceCollection.AddAzureAppService(Configuration.GetSection("AzureAppService").Get<AzureWebAppSettings>());
}
else if (certificateConsumer.Equals("NullCertificateConsumer"))
{
serviceCollection.AddNullCertificateConsumer();
}

serviceCollection.AddSingleton<IKeyVaultClient>(kvClient)
.AddKeyVaultCertificateStore(vaultBaseUrl);


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Azure.Services.AppAuthentication;
using Microsoft.Azure.KeyVault;
using System.Web.Http;

namespace LetsEncrypt.Azure.FunctionV2
{
Expand All @@ -31,8 +32,8 @@ public static async Task<IActionResult> Run(
return new OkResult();
} catch(Exception ex)
{

return new ObjectResult(ex.ToString());
log.LogError(ex.ToString());
return new ExceptionResult(ex, true);

}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
using LetsEncrypt.Azure.Core.V2.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using LetsEncrypt.Azure.Core.V2.CertificateConsumers;

namespace LetsEncrypt.Azure.Core.V2
{
public class AzureWebAppService
public class AzureWebAppService : ICertificateConsumer
{
private readonly AzureWebAppSettings[] settings;
private readonly ILogger<AzureWebAppService> logger;
Expand Down Expand Up @@ -88,26 +89,30 @@ private static IAppServiceManager GetAppServiceManager(AzureWebAppSettings setti
return new AppServiceManager(restClient, settings.AzureSubscription.SubscriptionId, settings.AzureSubscription.Tenant);
}

public List<string> RemoveExpired(int removeXNumberOfDaysBeforeExpiration = 0)
public async Task<List<string>> CleanUp()
{
return await this.CleanUp(0);
}
public async Task<List<string>> CleanUp(int removeXNumberOfDaysBeforeExpiration = 0)
{
var removedCerts = new List<string>();
foreach (var setting in this.settings)
{
var appServiceManager = GetAppServiceManager(setting);
var certs = appServiceManager.AppServiceCertificates.ListByResourceGroup(setting.ServicePlanResourceGroupName ?? setting.ResourceGroupName);
var certs = await appServiceManager.AppServiceCertificates.ListByResourceGroupAsync(setting.ServicePlanResourceGroupName ?? setting.ResourceGroupName);

var tobeRemoved = certs.Where(s => s.ExpirationDate < DateTime.UtcNow.AddDays(removeXNumberOfDaysBeforeExpiration) && (s.Issuer.Contains("Let's Encrypt") || s.Issuer.Contains("Fake LE"))).ToList();

tobeRemoved.ForEach(s => RemoveCertificate(appServiceManager, s, setting));
tobeRemoved.ForEach(async s => await RemoveCertificate(appServiceManager, s, setting));

removedCerts.AddRange(tobeRemoved.Select(s => s.Thumbprint).ToList());
}
return removedCerts;
}

private void RemoveCertificate(IAppServiceManager webSiteClient, IAppServiceCertificate s, AzureWebAppSettings setting)
private async Task RemoveCertificate(IAppServiceManager webSiteClient, IAppServiceCertificate s, AzureWebAppSettings setting)
{
webSiteClient.AppServiceCertificates.DeleteByResourceGroup(setting.ServicePlanResourceGroupName ?? setting.ResourceGroupName, s.Name);
await webSiteClient.AppServiceCertificates.DeleteByResourceGroupAsync(setting.ServicePlanResourceGroupName ?? setting.ResourceGroupName, s.Name);
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using LetsEncrypt.Azure.Core.V2.Models;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace LetsEncrypt.Azure.Core.V2.CertificateConsumers
{
public interface ICertificateConsumer
{
/// <summary>
/// Installs/assigns the new certificate.
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
Task Install(ICertificateInstallModel model);

/// <summary>
/// Remove any expired certificates
/// </summary>
/// <returns>List of thumbprint for certificates removed</returns>
Task<List<string>> CleanUp();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LetsEncrypt.Azure.Core.V2.Models;

namespace LetsEncrypt.Azure.Core.V2.CertificateConsumers
{
/// <summary>
/// Certificate consumer that does do anything.
/// </summary>
public class NullCertificateConsumer : ICertificateConsumer
{
public Task<List<string>> CleanUp()
{
return Task.FromResult(new List<string>());
}

public Task Install(ICertificateInstallModel model)
{
return Task.CompletedTask;
}
}
}
12 changes: 7 additions & 5 deletions src/LetsEncrypt.Azure.Core.V2/LetsencryptService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using LetsEncrypt.Azure.Core.V2.CertificateStores;
using LetsEncrypt.Azure.Core.V2.CertificateConsumers;
using LetsEncrypt.Azure.Core.V2.CertificateStores;
using LetsEncrypt.Azure.Core.V2.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
Expand All @@ -11,14 +12,15 @@ public class LetsencryptService
{
private readonly AcmeClient acmeClient;
private readonly ICertificateStore certificateStore;
private readonly ICertificateConsumer certificateConsumer;
private readonly AzureWebAppService azureWebAppService;
private readonly ILogger<LetsencryptService> logger;

public LetsencryptService(AcmeClient acmeClient, ICertificateStore certificateStore, AzureWebAppService azureWebAppService, ILogger<LetsencryptService> logger = null)
public LetsencryptService(AcmeClient acmeClient, ICertificateStore certificateStore, ICertificateConsumer certificateConsumer, ILogger<LetsencryptService> logger = null)
{
this.acmeClient = acmeClient;
this.certificateStore = certificateStore;
this.azureWebAppService = azureWebAppService;
this.certificateConsumer = certificateConsumer;
this.logger = logger ?? NullLogger<LetsencryptService>.Instance;
}
public async Task Run(AcmeDnsRequest acmeDnsRequest, int renewXNumberOfDaysBeforeExpiration)
Expand All @@ -45,10 +47,10 @@ public async Task Run(AcmeDnsRequest acmeDnsRequest, int renewXNumberOfDaysBefor
Host = acmeDnsRequest.Host
};
}
await azureWebAppService.Install(model);
await certificateConsumer.Install(model);

logger.LogInformation("Removing expired certificates");
var expired = azureWebAppService.RemoveExpired();
var expired = await certificateConsumer.CleanUp();
logger.LogInformation("The following certificates was removed {Thumbprints}", string.Join(", ", expired.ToArray()));

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using LetsEncrypt.Azure.Core.V2.CertificateStores;
using LetsEncrypt.Azure.Core.V2.CertificateConsumers;
using LetsEncrypt.Azure.Core.V2.CertificateStores;
using LetsEncrypt.Azure.Core.V2.DnsProviders;
using LetsEncrypt.Azure.Core.V2.Models;
using Microsoft.Azure.KeyVault;
Expand Down Expand Up @@ -64,6 +65,16 @@ public static IServiceCollection AddAcmeClient<TDnsProvider>(this IServiceCollec
.AddTransient<IDnsProvider, TDnsProvider>();
}

public static IServiceCollection AddNullCertificateConsumer(this IServiceCollection serviceCollection)
{

return serviceCollection
.AddTransient<ICertificateConsumer, NullCertificateConsumer>()
.AddTransient<LetsencryptService>();
}



public static IServiceCollection AddAzureAppService(this IServiceCollection serviceCollection, params AzureWebAppSettings[] settings)
{
if (settings == null || settings.Length == 0)
Expand All @@ -73,7 +84,7 @@ public static IServiceCollection AddAzureAppService(this IServiceCollection serv

return serviceCollection
.AddSingleton(settings)
.AddTransient<AzureWebAppService>()
.AddTransient<ICertificateConsumer, AzureWebAppService>()
.AddTransient<LetsencryptService>();
}
}
Expand Down

0 comments on commit bafb426

Please sign in to comment.