public async Task <object> Execute(ArgumentSyntax syntax) { var(serverUri, key) = await ReadAccountKey(syntax, true, false); var orderUri = syntax.GetParameter <Uri>(OrderIdParam, true); var domain = syntax.GetParameter <string>(DomainParam, true); var azureCredentials = await ReadAzureCredentials(syntax); var resourceGroup = syntax.GetOption <string>(AzureResourceGroupOption, true); var appName = syntax.GetParameter <string>(AppNameParam, true); var appSlot = syntax.GetOption <string>(SlotOption, false); var privKey = await syntax.ReadKey(PrivateKeyOption, "CERTES_CERT_KEY", File, environment, true); var acme = ContextFactory.Invoke(serverUri, key); var orderCtx = acme.Order(orderUri); var order = await orderCtx.Resource(); if (order.Certificate == null) { throw new CertesCliException(string.Format(Strings.ErrorOrderIncompleted, orderCtx.Location)); } var cert = await orderCtx.Download(); var x509Cert = new X509Certificate2(cert.Certificate.ToDer()); var thumbprint = x509Cert.Thumbprint; using (var client = clientFactory.Invoke(azureCredentials)) { client.SubscriptionId = azureCredentials.DefaultSubscriptionId; var certUploaded = await FindCertificate(client, resourceGroup, thumbprint); if (certUploaded == null) { certUploaded = await UploadCertificate( client, resourceGroup, appName, appSlot, cert.ToPfx(privKey), thumbprint); } var hostNameBinding = new HostNameBindingInner { SslState = SslState.SniEnabled, Thumbprint = certUploaded.Thumbprint, }; var hostName = string.IsNullOrWhiteSpace(appSlot) ? await client.WebApps.CreateOrUpdateHostNameBindingAsync( resourceGroup, appName, domain, hostNameBinding) : await client.WebApps.CreateOrUpdateHostNameBindingSlotAsync( resourceGroup, appName, domain, hostNameBinding, appSlot); return(new { data = hostName }); } }
///GENMHASH:405D133ADB31FC54FCFE6E63CC7CE6DF:528163E8A39CE260ED65B356ABCB872C internal HostNameBindingImpl(HostNameBindingInner innerObject, FluentImplT parent) : base(innerObject) { this.parent = parent; name = innerObject.Name; if (name != null && name.Contains("/")) { name = name.Replace(parent.Name + "/", ""); } }
private async Task UpdateAppBindingsAsync(AzureAppInstance appInstance, IAppServiceCertificate azureCertificate, string[] domains) { _logger.LogInformation("Checking host name bindings for app {AppName}", appInstance.DisplayName); string[] domainsToUpgrade = appInstance.HostNames .Where(boundDomain => DoesDomainMatch(boundDomain, domains)) .ToArray(); foreach (var domain in domainsToUpgrade) { _logger.LogDebug("Checking host name binding for domain {DomainName}", domain); HostNameBindingInner existingBinding = await appInstance.GetHostNameBindingAsync(_client, _azureOptions.ResourceGroupName, domain); if (DoesBindingNeedUpdating(existingBinding, azureCertificate.Thumbprint)) { _logger.LogDebug("Updating host name binding for app {AppName} domain {DomainName}", appInstance.DisplayName, domain); var newBinding = new HostNameBindingInner( azureResourceType: AzureResourceType.Website, hostNameType: HostNameType.Verified, customHostNameDnsRecordType: CustomHostNameDnsRecordType.CName, sslState: SslState.SniEnabled, thumbprint: azureCertificate.Thumbprint); await appInstance.SetHostNameBindingAsync(_client, _azureOptions.ResourceGroupName, domain, newBinding); } } }
private bool DoesBindingNeedUpdating(HostNameBindingInner existingBinding, string certificateThumbprint) { return(existingBinding == null || existingBinding.SslState != SslState.SniEnabled || existingBinding.Thumbprint != certificateThumbprint); }
public Command Define() { var cmd = new Command(CommandText, Strings.HelpCommandAzureApp) { new Option <string>(SlotOption, Strings.HelpSlot), new Option <string>(PrivateKeyOption, Strings.HelpPrivateKey), new Option <string>(PreferredChainOption, Strings.HelpPreferredChain), new Argument <Uri>(OrderIdParam, Strings.HelpOrderId), new Argument <string>(DomainParam, Strings.HelpDomain), new Argument <string>(AppNameParam, Strings.HelpAppName), }; AddCommonOptions(cmd); cmd.Handler = CommandHandler.Create(async(Args args, IConsole console) => { var(orderId, domain, app, slot, preferredChain, privateKey, server, keyPath, azureOptions) = args; var(serverUri, key) = await ReadAccountKey(server, keyPath, true, false); var azureCredentials = await CreateAzureRestClient(azureOptions); var privKey = await ReadKey(privateKey, "CERTES_CERT_KEY", File, environment); if (privKey == null) { throw new CertesCliException(Strings.ErrorNoPrivateKey); } var acme = ContextFactory.Invoke(serverUri, key); var orderCtx = acme.Order(orderId); var order = await orderCtx.Resource(); if (order.Certificate == null) { throw new CertesCliException(string.Format(Strings.ErrorOrderIncompleted, orderCtx.Location)); } var cert = await orderCtx.Download(preferredChain); var x509Cert = new X509Certificate2(cert.Certificate.ToDer()); var thumbprint = x509Cert.Thumbprint; using var client = clientFactory.Invoke(azureCredentials); client.SubscriptionId = azureCredentials.Credentials.DefaultSubscriptionId; var certUploaded = await FindCertificate(client, azureOptions.ResourceGroup, thumbprint); if (certUploaded == null) { certUploaded = await UploadCertificate( client, azureOptions.ResourceGroup, app, slot, cert.ToPfx(privKey), thumbprint); } var hostNameBinding = new HostNameBindingInner { SslState = SslState.SniEnabled, Thumbprint = certUploaded.Thumbprint, }; var hostName = string.IsNullOrWhiteSpace(slot) ? await client.WebApps.CreateOrUpdateHostNameBindingAsync( azureOptions.ResourceGroup, app, domain, hostNameBinding) : await client.WebApps.CreateOrUpdateHostNameBindingSlotAsync( azureOptions.ResourceGroup, app, domain, hostNameBinding, slot); var output = new { data = hostName }; console.WriteAsJson(output); }); return(cmd); }
public async Task Install(ICertificateInstallModel model) { logger.LogInformation("Starting installation of certificate {Thumbprint} for {Host}", model.CertificateInfo.Certificate.Thumbprint, model.Host); var cert = model.CertificateInfo; foreach (var setting in this.settings) { logger.LogInformation("Installing certificate for web app {WebApp}", setting.WebAppName); try { IAppServiceManager appServiceManager = GetAppServiceManager(setting); var s = appServiceManager.WebApps.GetByResourceGroup(setting.ResourceGroupName, setting.WebAppName); IWebAppBase siteOrSlot = s; if (!string.IsNullOrEmpty(setting.SiteSlotName)) { var slot = s.DeploymentSlots.GetByName(setting.SiteSlotName); siteOrSlot = slot; } var existingCerts = await appServiceManager.AppServiceCertificates.ListByResourceGroupAsync(setting.ServicePlanResourceGroupName ?? setting.ResourceGroupName); if (existingCerts.Where(_ => _.RegionName == s.RegionName).All(_ => _.Thumbprint != cert.Certificate.Thumbprint)) { await appServiceManager.AppServiceCertificates.Define($"{cert.Certificate.Thumbprint}-{model.Host}-{s.RegionName}").WithRegion(s.RegionName).WithExistingResourceGroup(setting.ServicePlanResourceGroupName ?? setting.ResourceGroupName).WithPfxByteArray(model.CertificateInfo.PfxCertificate).WithPfxPassword(model.CertificateInfo.Password).CreateAsync(); } var sslStates = siteOrSlot.HostNameSslStates; var domainSslMappings = new List <KeyValuePair <string, HostNameSslState> >(sslStates.Where(_ => _.Key.Contains($"{model.Host}"))); if (domainSslMappings.Any()) { foreach (var domainMapping in domainSslMappings) { string hostName = domainMapping.Value.Name; if (domainMapping.Value.Thumbprint == cert.Certificate.Thumbprint) { continue; } logger.LogInformation("Binding certificate {Thumbprint} to {Host}", model.CertificateInfo.Certificate.Thumbprint, hostName); var binding = new HostNameBindingInner() { SslState = setting.UseIPBasedSSL ? SslState.IpBasedEnabled : SslState.SniEnabled, Thumbprint = model.CertificateInfo.Certificate.Thumbprint }; if (!string.IsNullOrEmpty(setting.SiteSlotName)) { await appServiceManager.Inner.WebApps.CreateOrUpdateHostNameBindingSlotAsync(setting.ResourceGroupName, setting.WebAppName, hostName, binding, setting.SiteSlotName); } else { await appServiceManager.Inner.WebApps.CreateOrUpdateHostNameBindingAsync(setting.ResourceGroupName, setting.WebAppName, hostName, binding); } } } } catch (Exception e) { logger.LogCritical(e, "Unable to install certificate for '{WebApp}'", setting.WebAppName); throw; } } }
public Task SetHostNameBindingAsync(IAzure client, string resourceGroupName, string domain, HostNameBindingInner binding) { if (IsSlot) { return(client.WebApps.Inner.CreateOrUpdateHostNameBindingSlotWithHttpMessagesAsync( resourceGroupName, _app.Name, domain, binding, _slot.Name)); } else { return(client.WebApps.Inner.CreateOrUpdateHostNameBindingWithHttpMessagesAsync( resourceGroupName, _app.Name, domain, binding )); } }