private async Task <List <ActionStep> > DeployToAllTargetBindings(IBindingDeploymentTarget deploymentTarget, ManagedCertificate managedCertificate, CertRequestConfig requestConfig, string certStoreName, byte[] certHash, List <string> dnsHosts, bool isPreviewOnly = false ) { var actions = new List <ActionStep>(); var targetSites = new List <IBindingDeploymentTargetItem>(); // ensure defaults applied for deployment mode requestConfig.ApplyDeploymentOptionDefaults(); // if single site, add that if (requestConfig.DeploymentSiteOption == DeploymentOption.SingleSite) { if (!string.IsNullOrEmpty(managedCertificate.ServerSiteId)) { var site = await deploymentTarget.GetTargetItem(managedCertificate.ServerSiteId); if (site != null) { targetSites.Add(site); } } } // or add all sites (if required) if (requestConfig.DeploymentSiteOption == DeploymentOption.AllSites || requestConfig.DeploymentSiteOption == DeploymentOption.Auto) { targetSites.AddRange(await deploymentTarget.GetAllTargetItems()); } // for each sites we want to target, identify bindings to add/update as required foreach (var site in targetSites) { try { var existingBindings = await deploymentTarget.GetBindings(site.Id); var existingHttps = existingBindings.Where(e => e.Protocol == "https").ToList(); //remove https bindings which already have an https equivalent (specific hostname or blank) existingBindings.RemoveAll(b => existingHttps.Any(e => e.Host == b.Host) && b.Protocol == "http"); existingBindings = existingBindings.OrderBy(b => b.Protocol).ThenBy(b => b.Host).ToList(); // for each binding create or update an https binding foreach (var b in existingBindings) { var updateBinding = false; //if binding is http and there is no https binding, create one var hostname = b.Host; // install the cert for this binding if the hostname matches, or we have a // matching wildcard, or if there is no hostname specified in the binding if (requestConfig.DeploymentBindingReplacePrevious || requestConfig.DeploymentSiteOption == DeploymentOption.Auto) { // if replacing previous, check if current binding cert hash matches // previous cert hash if (b.CertificateHash != null && (managedCertificate.CertificatePreviousThumbprintHash != null || managedCertificate.CertificateThumbprintHash != null)) { if (string.Equals(b.CertificateHash, managedCertificate.CertificatePreviousThumbprintHash)) { updateBinding = true; } else if (string.Equals(b.CertificateHash, managedCertificate.CertificateThumbprintHash)) { updateBinding = true; } } } if (updateBinding == false) { // TODO: add wildcard match if (string.IsNullOrEmpty(hostname) && requestConfig.DeploymentBindingBlankHostname) { updateBinding = true; } else { if (requestConfig.DeploymentBindingMatchHostname) { updateBinding = ManagedCertificate.IsDomainOrWildcardMatch(dnsHosts, hostname); } } } if (requestConfig.DeploymentBindingOption == DeploymentBindingOption.UpdateOnly) { // update existing bindings only, so only update if this is already an // https binding if (b.Protocol != "https") { updateBinding = false; } } if (b.Protocol != "http" && b.Protocol != "https") { // skip bindings for other service types updateBinding = false; } if (updateBinding) { //SSL port defaults to 443 or the config default, unless we already have an https binding, in which case re-use same port var sslPort = 443; var targetIPAddress = "*"; if (!string.IsNullOrWhiteSpace(requestConfig.BindingPort)) { sslPort = int.Parse(requestConfig.BindingPort); } if (b.Protocol == "https") { if (b.Port > 0) { sslPort = b.Port; } if (!unassignedIPs.Contains(b.IP)) { targetIPAddress = b.IP; } } else { if (!unassignedIPs.Contains(requestConfig.BindingIPAddress)) { targetIPAddress = requestConfig.BindingIPAddress; } } //create/update binding and associate new cert //if any binding elements configured, use those, otherwise auto bind using defaults and SNI var stepActions = await UpdateBinding( deploymentTarget, site, existingBindings, certStoreName, certHash, hostname, sslPort : sslPort, useSNI : (requestConfig.BindingUseSNI != null ? (bool)requestConfig.BindingUseSNI : true), ipAddress : targetIPAddress, alwaysRecreateBindings : requestConfig.AlwaysRecreateBindings, isPreviewOnly : isPreviewOnly ); actions.AddRange(stepActions); } } // } catch (Exception exp) { actions.Add(new ActionStep { Title = site.Name, Category = "Deploy.AddOrUpdateBindings", HasError = true, Description = exp.ToString() }); } } return(actions); }