public static WarmupResult Warmup(IisSite site, string warmupUrl) { var uri = new Uri(warmupUrl); var testUrl = uri.ToString().Replace(uri.Host, "127.0.0.1"); var request = WebRequest.Create(testUrl) as HttpWebRequest; request.Host = uri.Host + ":" + uri.Port; HttpWebResponse response; try { response = (HttpWebResponse)request.GetResponse(); return new WarmupResult(response); } catch (WebException ex) { var exceptionResponse = (HttpWebResponse) ex.Response; if (exceptionResponse == null) { return null; } return new WarmupResult(exceptionResponse); } }
public static int AddIisSite(IisSite site) { return(ConfigDb.IisSiteAdd( site.Sitename, site.Hostname, site.Group)); }
public static WarmupResult Warmup(IisSite site, string warmupUrl) { var uri = new Uri(warmupUrl); var testUrl = uri.ToString().Replace(uri.Host, "127.0.0.1"); var request = WebRequest.Create(testUrl) as HttpWebRequest; request.Host = uri.Host + ":" + uri.Port; HttpWebResponse response; try { response = (HttpWebResponse)request.GetResponse(); return(new WarmupResult(response)); } catch (WebException ex) { var exceptionResponse = (HttpWebResponse)ex.Response; if (exceptionResponse == null) { return(null); } return(new WarmupResult(exceptionResponse)); } }
private async Task ProcessSiteLogs(SiteInfo iisSite) { IisSite site = await _repo.GetIisSite(iisSite.HostName); if (site == null) { _logger.LogInformation($"Added site {iisSite.HostName}, Site Id:{iisSite.SiteId}."); site = await _repo.AddSite(iisSite.HostName, iisSite.SiteId); } string[] logFiles = _logFileProvider.GetLogFiles(iisSite.SiteId, iisSite.LogFileAndPath); DateTime processingDate = DateTime.Now; var logFileStopwatch = Stopwatch.StartNew(); var taskStopwatch = Stopwatch.StartNew(); _logger.LogInformation("Entering file processing loop"); foreach (string fileNameAndPath in logFiles) { await ProcessLogFiles(iisSite, logFileStopwatch, fileNameAndPath, site, taskStopwatch, processingDate); } _logger.LogInformation("Exiting file processing loop"); }
public static SiteStartResult StartSite(IisSite site) { using (var manager = new ServerManager()) { var iisSite = manager.Sites.SingleOrDefault(x => x.Id == site.IisId); if (iisSite == null) { throw new SiteNotFoundException("Site " + site.Name + " was not found on IIS"); } try { iisSite.Start(); return(SiteStartResult.Started); } catch (ServerManagerException) { return(SiteStartResult.BindingIsAlreadyInUse); } catch (FileLoadException e) { if (e.Message.Contains("being used by another")) { return(SiteStartResult.PortInUseByAnotherService); } return(SiteStartResult.CannotAccessSitePath); } } }
public void Rollback(int deploymentId) { SendResponse(deploymentId, DeploymentResponseType.Rollback, string.Format("Remote rollback requested received.")); var instance = _deploymentInstances.SingleOrDefault(x => x.DeploymentId == deploymentId && !x.RollbackCompleted); if (instance == null) { _deploymentInstances.Add(new DeploymentInstance() { DeploymentId = deploymentId, RollbackCompleted = true }); return; } IisSite site = SiteManager.GetSiteById(instance.IisSiteId); site.SitePath = instance.OriginalPath; SiteManager.UpdateSite(site); if (site.ApplicationPoolState == InstanceState.Started) { SiteManager.RecycleApplicationPool(site.ApplicationPool); } instance.RollbackCompleted = true; }
private static IisSite ParseSite(Microsoft.Web.Administration.Site site, bool excludeAppPools = false, List <Microsoft.Web.Administration.ApplicationPool> applicationPools = null) { if (site == null) { return(null); } var servantSite = new IisSite { IisId = (int)site.Id, Name = site.Name, ApplicationPool = site.Applications[0].ApplicationPoolName, SitePath = site.Applications[0].VirtualDirectories[0].PhysicalPath, SiteState = (InstanceState)Enum.Parse(typeof(Shared.Objects.Enums.InstanceState), site.State.ToString()), LogFileDirectory = site.LogFile.Directory, Bindings = GetBindings(site).ToList(), }; if (!excludeAppPools) { if (applicationPools == null) { using (var manager = new ServerManager()) { applicationPools = manager.ApplicationPools.ToList(); } } ObjectState applicationPoolState = applicationPools.Single(x => x.Name == site.Applications[0].ApplicationPoolName).State; servantSite.ApplicationPoolState = (InstanceState)Enum.Parse(typeof(InstanceState), applicationPoolState.ToString()); } foreach (var directory in site.Applications[0].VirtualDirectories.Skip(1)) { servantSite.Applications.Add(new SiteApplication { ApplicationPool = "", Path = directory.Path, DiskPath = directory.PhysicalPath, IsApplication = false }); } if (site.Applications.Count > 1) { foreach (var application in site.Applications.Skip(1)) { servantSite.Applications.Add(new SiteApplication { ApplicationPool = application.ApplicationPoolName, Path = application.Path, DiskPath = application.VirtualDirectories[0].PhysicalPath, IsApplication = true }); } } return(servantSite); }
public static ManageSiteResult ValidateSite(IisSite site, IisSite originalSite) { var certificates = SiteManager.GetCertificates(); var result = new ManageSiteResult(); if (!site.Bindings.Any()) { result.Errors.Add("Minimum one binding is required."); } if (string.IsNullOrWhiteSpace(site.Name)) result.Errors.Add("Name is required."); IisSite existingSite = SiteManager.GetSiteByName(site.Name); if (originalSite == null) { originalSite = new IisSite() { IisId = 0}; } if (site.Name != null && existingSite != null && site.Name.ToLower() == existingSite.Name.ToLower() && existingSite.IisId != originalSite.IisId) result.Errors.Add("There's already a site with this name."); if (string.IsNullOrWhiteSpace(site.SitePath)) result.Errors.Add("Site path is required."); else { if (!FileSystemHelper.IsPathValid(site.SitePath)) { result.Errors.Add("Path cannot contain the following characters: ?, ;, :, @, &, =, +, $, ,, |, \", <, >, *."); } else { if (!FileSystemHelper.DirectoryExists(site.SitePath)) { FileSystemHelper.CreateDirectory(site.SitePath); } } if (!FileSystemHelper.IsPathValid(site.LogFileDirectory)) { result.Errors.Add("Log File Directory cannot contain the following characters: ?, ;, :, @, &, =, +, $, ,, |, \", <, >, *."); } else { if (!FileSystemHelper.DirectoryExists(site.LogFileDirectory)) { FileSystemHelper.CreateDirectory(site.LogFileDirectory); } } } result.Result = result.Errors.Any() ? SiteResult.ValidationError : SiteResult.Success; return result; }
public static void RemoveSite(IisSite newSite) { var hosts = File.ReadAllLines(Path.Combine(Environment.SystemDirectory, "drivers", "etc", "hosts")).ToList(); string marker = string.Format("{0} - {1}", newSite.SiteName, newSite.Group); var domainEntries = newSite.Domains.Where(o => !string.IsNullOrWhiteSpace(o)).Select(o => $"127.0.0.1\t{o}").ToList(); RemoveDomains(hosts, domainEntries, marker); File.WriteAllLines(Path.Combine(Environment.SystemDirectory, "drivers", "etc", "hosts"), hosts); }
public static void StopSite(IisSite site) { using (var manager = new ServerManager()) { var iisSite = manager.Sites.SingleOrDefault(x => x.Id == site.IisId); if (iisSite == null) { throw new SiteNotFoundException("Site " + site.Name + " was not found on IIS"); } iisSite.Stop(); } }
public void GetApplications_ReturnsValidApplication() { // Arrange var ipath = _environment.GlobalPath + "\\Feature"; var snapshot = Mock.Of <IOptionsSnapshot <AcumaticaSettings> >(p => p.Value == _environment); var iapp = new IisApplication { Path = ipath + "\\App", Uris = new List <string> { "http://machine/app", "https://machine:533/app" }, Version = "7.00.0001" }; var site = new IisSite { IisApplications = Enumerable.Repeat(iapp, 1), Uris = new List <string> { "http://machine/", "https://machine:533/" } }; var iismanager = Mock.Of <IIisManager>(m => m.GetIisSite(_environment.DefaultSiteName) == site); var filewrapper = new Mock <IFileWrapper>(); filewrapper.Setup(f => f.GetChilds(_environment.GlobalPath)).Returns(Enumerable.Repeat(ipath, 1)); filewrapper.Setup(f => f.GetFileName(It.IsAny <string>())).Returns <string>(Path.GetFileNameWithoutExtension); filewrapper.Setup(f => f.GetParentPath(It.IsAny <string>())).Returns <string>(v => Directory.GetParent(v).FullName); filewrapper.Setup(f => f.GetVersion(It.IsAny <string>())).Returns(iapp.Version); filewrapper.Setup(f => f.IsExists(It.IsAny <string>())).Returns(true); filewrapper.Setup(f => f.IsFolder(It.IsAny <string>())).Returns(true); var service = new AcIisService(snapshot, iismanager, filewrapper.Object); // Act var result = service.GetApplications().ToList(); // Assert Assert.True(result.Count == 1); var app = result.First(); Assert.Equal("Feature", app.InstallationName); Assert.Equal("App", app.Name); Assert.Equal(iapp.Path, app.PhysicalPath); Assert.Equal(iapp.Version, app.Version); Assert.Equal(iapp.Uris, app.Uris); }
private IisSite ReadSiteInformation(Site site) { var result = new IisSite(); var sitePath = site.Applications["/"].VirtualDirectories["/"].PhysicalPath; result.Group = FindGroupAtPath(sitePath); result.SiteName = site.Name; result.Version = FindVersionAtPath(sitePath); result.Domains = FindDomainsInBindings(site); result.AddPictures = HasPicturesVirtDir(site); result.LocalPictures = HasLocalPicDir(site); return(result); }
private void ApplyRestrictions() { try { var data = ConfigDb.GetRestrictionsToUpdate(); // Nothing to do if (data == null) { return; } foreach (DataRow restrictionRow in data.Rows) { try { var info = new IisSite { Hostname = restrictionRow["Hostname"].ToString(), Sitename = restrictionRow["Sitename"].ToString() }; // Turn On/Off restriction if ((bool)restrictionRow["Switch"]) { IisConfigurator.AddRestriction(restrictionRow["TypeName"].ToString(), info, restrictionRow["Rule"].ToString()); } else { IisConfigurator.RemoveRestriction(restrictionRow["TypeName"].ToString(), info, restrictionRow["Rule"].ToString()); } // If no errors - update DB ConfigDb.IisRestrictionTurnOff((int)restrictionRow["ID"], (bool)restrictionRow["Switch"]); } catch (Exception ex) { Logger.Log.Warn("Unable to apply rule id:[{0}], content:[{1}]. Error: {2}", restrictionRow["ID"], restrictionRow["Rule"], ex.Message); ConfigDb.IisRestrictionReject((int)restrictionRow["ID"], ex.Message); } } } catch (Exception ex) { Logger.Log.Error("Connection to DB failed: {0}", ex.Message); } }
public static void AddUrlRestriction(IisSite info, UrlRestriction urlRule) { using (var serverManager = ServerManager.OpenRemote(info.Hostname)) { var conf = serverManager.GetWebConfiguration(info.Sitename); // Add URL restrictions var reqFilterSec = conf.GetSection("system.webServer/security/requestFiltering"); var denyUrlCollection = reqFilterSec.GetCollection("denyUrlSequences"); var addElement = denyUrlCollection.CreateElement("add"); addElement["sequence"] = urlRule.Sequence; denyUrlCollection.Add(addElement); // Save changes serverManager.CommitChanges(); } }
public async Task <int> AddLogs(IisSite site, IisLogFile iisLogFile, IEnumerable <IisLogEntry> iisLogEntries, IEnumerable <StagedIisLogEntry> stagedIisLogEntries) { string connStr = _configuration.GetConnectionString(DatabaseName.IisDb); DbContextOptionsBuilder <IisLogDbContext> builder = new DbContextOptionsBuilder <IisLogDbContext>() .UseSqlServer(connStr); await using (IisLogDbContext ctx = new IisLogDbContext(builder.Options)) { ctx.Attach(site); ctx.Entry(site).State = EntityState.Modified; site.LogFiles.Add(iisLogFile); iisLogFile.StagedLogEntries.AddRange(stagedIisLogEntries); site.LogEntries.AddRange(iisLogEntries); return(ctx.SaveChanges()); } }
public static void RemoveRestriction(string type, IisSite info, string restriction) { switch (type) { case RestrictionType.Url: RemoveUrlRestriction(info, XmlDeserializeFromString <UrlRestriction>(restriction)); break; case RestrictionType.Ip: RemoveIpRestriction(info, XmlDeserializeFromString <IpRestriction>(restriction)); break; case RestrictionType.Query: RemoveQueryStringRestriction(info, XmlDeserializeFromString <QueryStringRestriction>(restriction)); break; default: throw new Exception("Unknown restriction type"); } }
public static void RemoveUrlRestriction(IisSite info, UrlRestriction urlRule) { using (var serverManager = ServerManager.OpenRemote(info.Hostname)) { var conf = serverManager.GetWebConfiguration(info.Sitename); // Add URL restrictions var reqFilterSec = conf.GetSection("system.webServer/security/requestFiltering"); var denyUrlCollection = reqFilterSec.GetCollection("denyUrlSequences"); foreach (var element in denyUrlCollection.Where(element => (string)element.Attributes["sequence"].Value == urlRule.Sequence)) { denyUrlCollection.Remove(element); break; } // Save changes serverManager.CommitChanges(); } }
public async Task <IisSite> AddSite(string hostName, int siteId) { string connStr = _configuration.GetConnectionString(DatabaseName.IisDb); DbContextOptionsBuilder <IisLogDbContext> builder = new DbContextOptionsBuilder <IisLogDbContext>() .UseSqlServer(connStr); IisSite site = new IisSite() { HostName = hostName, IisId = siteId }; await using (IisLogDbContext ctx = new IisLogDbContext(builder.Options)) { ctx.Sites.Add(site); ctx.SaveChanges(); return(site); } }
public static void RemoveIpRestriction(IisSite info, IpRestriction restriction) { using (var serverManager = ServerManager.OpenRemote(info.Hostname)) { var hostConfig = serverManager.GetApplicationHostConfiguration(); // Add IP restrictions var ipSec = hostConfig.GetSection("system.webServer/security/ipSecurity", info.Sitename); var ipSecCollection = ipSec.GetCollection(); foreach (var element in ipSecCollection.Where(element => (string)element.Attributes["ipAddress"].Value == restriction.Ip && (string.IsNullOrEmpty(restriction.Netmask) || (string)element.Attributes["subnetMask"].Value == restriction.Netmask))) { ipSecCollection.Remove(element); break; } // Save changes serverManager.CommitChanges(); } }
public static void AddIpRestriction(IisSite info, IpRestriction restriction) { using (var serverManager = ServerManager.OpenRemote(info.Hostname)) { var hostConfig = serverManager.GetApplicationHostConfiguration(); // Add IP restrictions var ipSec = hostConfig.GetSection("system.webServer/security/ipSecurity", info.Sitename); var ipSecCollection = ipSec.GetCollection(); var ipElement = ipSecCollection.CreateElement("add"); ipElement["ipAddress"] = restriction.Ip; ipElement["allowed"] = false; if (!string.IsNullOrEmpty(restriction.Netmask)) { ipElement["subnetMask"] = restriction.Netmask; } ipSecCollection.Add(ipElement); // Save changes serverManager.CommitChanges(); } }
private async Task ProcessLogFiles(SiteInfo iisSite, Stopwatch logFileStopwatch, string fileNameAndPath, IisSite site, Stopwatch taskStopwatch, DateTime processingDate) { logFileStopwatch.Start(); var fileInfo = new FileInfo(fileNameAndPath); var processedLogFile = await _repo.GetProcessedLogFile(fileNameAndPath); if (processedLogFile?.DateImported < fileInfo.LastWriteTime && processedLogFile.Size != fileInfo.Length) { _logger.LogInformation($"Reprocessing log file:{fileNameAndPath}"); await _repo.DeleteProcessedLogFile(processedLogFile); } if (site.LogFiles.Exists(f => f.LogFileAndPath.Matches(fileNameAndPath))) { _logger.LogInformation($"Skipping log file:{fileNameAndPath}"); return; } _logger.LogInformation($"Importing StagedLogEntities."); List <StagedIisLogEntry> stagedLogEntries = _logFileProcessor.ImportLogFileIntoEntities(fileNameAndPath, iisSite.HostName).ToList(); _logger.LogInformation($"Converting StagedLogEntities to LogEntries."); taskStopwatch.Start(); List <IisLogEntry> logEntries = await Task.FromResult(IisLogEntry.FromEntities(stagedLogEntries)); taskStopwatch.Stop(); _logger.LogInformation( $"Elapse time Converting StagedLogEntities: {taskStopwatch.Elapsed.Seconds} seconds, {taskStopwatch.Elapsed.Milliseconds} milliseconds."); IisLogFile logFile = new IisLogFile(fileInfo, iisSite, stagedLogEntries, logEntries, site, processingDate, fileNameAndPath); _logger.LogInformation("Saving log results"); await _repo.AddLogs(site, logFile, logEntries, stagedLogEntries); logFileStopwatch.Stop(); _logger.LogInformation( $"Elapse time processing {fileNameAndPath}: {logFileStopwatch.Elapsed.Seconds} seconds, {logFileStopwatch.Elapsed.Milliseconds} milliseconds."); }
public static ManageSiteResult CreateSite(IisSite site) { var validationResult = Validators.ValidateSite(site, null); if (validationResult.Errors.Any()) { return validationResult; } var result = new ManageSiteResult(); var bindingInformations = site.Bindings.Select(x => x.ToIisBindingInformation()).ToList(); // Check bindings var bindingInUse = GetBindingInUse(0, bindingInformations); // 0 never exists if (bindingInUse != null) { result.Result = SiteResult.BindingAlreadyInUse; return result; } using (var manager = new ServerManager()) { if (manager.Sites.Any(x => x.Name == site.Name)) { result.Result = SiteResult.NameAlreadyInUse; return result; } // Create site manager.Sites.Add(site.Name, "http", bindingInformations.First(), site.SitePath); var iisSite = manager.Sites.SingleOrDefault(x => x.Name == site.Name); // Add bindings iisSite.Bindings.Clear(); foreach (var binding in bindingInformations) iisSite.Bindings.Add(binding, "http"); // Set/create application pool if (string.IsNullOrWhiteSpace(site.ApplicationPool)) // Auto create application pool { var appPoolName = site.Name; var existingApplicationPoolNames = manager.ApplicationPools.Select(x => x.Name).ToList(); var newNameCount = 1; while (existingApplicationPoolNames.Contains(appPoolName)) { appPoolName = site.Name + "_" + newNameCount; newNameCount++; } manager.ApplicationPools.Add(appPoolName); iisSite.ApplicationDefaults.ApplicationPoolName = appPoolName; } else { iisSite.ApplicationDefaults.ApplicationPoolName = site.ApplicationPool; } //Add Virtual apps/directories foreach (var application in site.Applications) { if (!application.Path.StartsWith("/")) application.Path = "/" + application.Path; if (application.IsApplication) { if (application.Path.EndsWith("/")) { application.Path.Remove(application.Path.Length - 1, 1); } iisSite.Applications.Add(application.Path, application.DiskPath); } else // Directory { iisSite.Applications.First().VirtualDirectories.Add(application.Path, application.DiskPath); } } manager.CommitChanges(); var created = false; var sw = new Stopwatch(); sw.Start(); while (!created && sw.Elapsed.TotalSeconds < 3) { try { if (iisSite.State == ObjectState.Started || iisSite.State == ObjectState.Stopped) { created = true; } } catch (COMException) { System.Threading.Thread.Sleep(100); } } sw.Stop(); if (created) { result.Result = SiteResult.Success; result.IisSiteId = (int) iisSite.Id; } else { result.Result = SiteResult.Failed; } return result; } }
private static IisSite ParseSite(Microsoft.Web.Administration.Site site, bool excludeAppPools = false, List<Microsoft.Web.Administration.ApplicationPool> applicationPools = null) { if (site == null) return null; var servantSite = new IisSite { IisId = (int)site.Id, Name = site.Name, ApplicationPool = site.Applications[0].ApplicationPoolName, SitePath = site.Applications[0].VirtualDirectories[0].PhysicalPath, SiteState = (InstanceState)Enum.Parse(typeof(Shared.Objects.Enums.InstanceState), site.State.ToString()), LogFileDirectory = site.LogFile.Directory, Bindings = GetBindings(site).ToList(), }; if (!excludeAppPools) { if (applicationPools == null) { using (var manager = new ServerManager()) { applicationPools = manager.ApplicationPools.ToList(); } } ObjectState applicationPoolState = applicationPools.Single(x => x.Name == site.Applications[0].ApplicationPoolName).State; servantSite.ApplicationPoolState = (InstanceState)Enum.Parse(typeof(InstanceState), applicationPoolState.ToString()); } foreach (var directory in site.Applications[0].VirtualDirectories.Skip(1)) { servantSite.Applications.Add(new SiteApplication { ApplicationPool = "", Path = directory.Path, DiskPath = directory.PhysicalPath, IsApplication = false }); } if (site.Applications.Count > 1) { foreach (var application in site.Applications.Skip(1)) { servantSite.Applications.Add(new SiteApplication { ApplicationPool = application.ApplicationPoolName, Path = application.Path, DiskPath = application.VirtualDirectories[0].PhysicalPath, IsApplication = true }); } } return servantSite; }
public static ManageSiteResult UpdateSite(IisSite site) { var result = new ManageSiteResult { IisSiteId = site.IisId }; using (var manager = new ServerManager()) { var iisSite = manager.Sites.SingleOrDefault(x => x.Id == site.IisId); if (iisSite == null) { result.Result = SiteResult.UnknownSiteId; return result; } var iisSiteWithSameName = manager.Sites.SingleOrDefault(x => x.Id != site.IisId && x.Name == site.Name); if (iisSiteWithSameName != null) { result.Result = SiteResult.NameAlreadyInUse; return result; } var mainApplication = iisSite.Applications.First(); var rootPathDirectory = mainApplication.VirtualDirectories.SingleOrDefault(x => x.Path == "/"); if (rootPathDirectory == null) { mainApplication.VirtualDirectories.Add("/", site.SitePath); } else { rootPathDirectory.PhysicalPath = site.SitePath; } // In some scenarios Microsoft.Web.Administation fails to save site if property-set is detected with same name. //I believe it deletes and insert sites on updates and this makes a name conflict. Fixed by the hack below: if(site.Name != iisSite.Name) iisSite.Name = site.Name; // If the application pool does not exists on the server, create it if (manager.ApplicationPools.SingleOrDefault(x => x.Name == site.ApplicationPool) == null) { manager.ApplicationPools.Add(site.ApplicationPool); } mainApplication.ApplicationPoolName = site.ApplicationPool; // Update log file path iisSite.LogFile.Directory = site.LogFileDirectory; // Commits bindings iisSite.Bindings.Clear(); foreach (var binding in site.Bindings) { if (binding.Protocol == Protocol.https) { var certificate = GetCertificates().Single(x => x.Thumbprint == binding.CertificateThumbprint); iisSite.Bindings.Add(binding.ToIisBindingInformation(), certificate.Hash, "My"); } else iisSite.Bindings.Add(binding.ToIisBindingInformation(), binding.Protocol.ToString()); } // Deletes virtual applications var applicationsToDelete = iisSite.Applications.Skip(1).Where(application => !site.Applications.Where(x => x.IsApplication).Select(a => a.Path).Contains(application.Path)).ToList(); foreach (var application in applicationsToDelete) { application.Delete(); iisSite.Applications.Remove(application); // Bug in Microsoft.Web.Administration when changing from directory - application } // Deletes virtual directories var directoriesToDelete = mainApplication.VirtualDirectories.Where(directory => directory.Path != "/" && !site.Applications.Where(x => !x.IsApplication).Select(a => a.Path).Contains(directory.Path)).ToList(); // Exclude "/" because it's the root application's directory. foreach (var directory in directoriesToDelete) { directory.Delete(); mainApplication.VirtualDirectories.Remove(directory); // Bug in Microsoft.Web.Administration when changing from directory - application } //Intelligently updates virtual applications + directories foreach (var application in site.Applications) { if (!application.Path.StartsWith("/")) application.Path = "/" + application.Path; if (application.IsApplication) { if (application.Path.EndsWith("/")) { application.Path = application.Path.Substring(0, application.Path.Length - 1); } var iisApp = iisSite.Applications.SingleOrDefault(x => x.Path == application.Path); if (iisApp == null) { iisSite.Applications.Add(application.Path, application.DiskPath); iisApp = iisSite.Applications.Single(x => x.Path == application.Path); } iisApp.VirtualDirectories[0].PhysicalPath = application.DiskPath; iisApp.ApplicationPoolName = application.ApplicationPool; } else // Directory { var virtualDirectory = mainApplication.VirtualDirectories.SingleOrDefault(x => x.Path == application.Path); if (virtualDirectory == null) { mainApplication.VirtualDirectories.Add(application.Path, application.DiskPath); } else { virtualDirectory.PhysicalPath = application.DiskPath; } } } manager.CommitChanges(); } return result; }
public static void StopSite(IisSite site) { using (var manager = new ServerManager()) { var iisSite = manager.Sites.SingleOrDefault(x => x.Id == site.IisId); if (iisSite == null) throw new SiteNotFoundException("Site " + site.Name + " was not found on IIS"); iisSite.Stop(); } }
public static SiteStartResult StartSite(IisSite site) { using (var manager = new ServerManager()) { var iisSite = manager.Sites.SingleOrDefault(x => x.Id == site.IisId); if (iisSite == null) throw new SiteNotFoundException("Site " + site.Name + " was not found on IIS"); try { iisSite.Start(); return SiteStartResult.Started; } catch (ServerManagerException) { return SiteStartResult.BindingIsAlreadyInUse; } catch (FileLoadException e) { if (e.Message.Contains("being used by another")) { return SiteStartResult.PortInUseByAnotherService; } return SiteStartResult.CannotAccessSitePath; } } }
public static ManageSiteResult UpdateSite(IisSite site) { var result = new ManageSiteResult { IisSiteId = site.IisId }; using (var manager = new ServerManager()) { var iisSite = manager.Sites.SingleOrDefault(x => x.Id == site.IisId); if (iisSite == null) { result.Result = SiteResult.UnknownSiteId; return(result); } var iisSiteWithSameName = manager.Sites.SingleOrDefault(x => x.Id != site.IisId && x.Name == site.Name); if (iisSiteWithSameName != null) { result.Result = SiteResult.NameAlreadyInUse; return(result); } var mainApplication = iisSite.Applications.First(); var rootPathDirectory = mainApplication.VirtualDirectories.SingleOrDefault(x => x.Path == "/"); if (rootPathDirectory == null) { mainApplication.VirtualDirectories.Add("/", site.SitePath); } else { rootPathDirectory.PhysicalPath = site.SitePath; } // In some scenarios Microsoft.Web.Administation fails to save site if property-set is detected with same name. //I believe it deletes and insert sites on updates and this makes a name conflict. Fixed by the hack below: if (site.Name != iisSite.Name) { iisSite.Name = site.Name; } // If the application pool does not exists on the server, create it if (manager.ApplicationPools.SingleOrDefault(x => x.Name == site.ApplicationPool) == null) { manager.ApplicationPools.Add(site.ApplicationPool); } mainApplication.ApplicationPoolName = site.ApplicationPool; // Update log file path iisSite.LogFile.Directory = site.LogFileDirectory; // Commits bindings iisSite.Bindings.Clear(); foreach (var binding in site.Bindings) { if (binding.Protocol == Protocol.https) { var certificate = GetCertificates().Single(x => x.Thumbprint == binding.CertificateThumbprint); iisSite.Bindings.Add(binding.ToIisBindingInformation(), certificate.Hash, "My"); } else { iisSite.Bindings.Add(binding.ToIisBindingInformation(), binding.Protocol.ToString()); } } // Deletes virtual applications var applicationsToDelete = iisSite.Applications.Skip(1).Where(application => !site.Applications.Where(x => x.IsApplication).Select(a => a.Path).Contains(application.Path)).ToList(); foreach (var application in applicationsToDelete) { application.Delete(); iisSite.Applications.Remove(application); // Bug in Microsoft.Web.Administration when changing from directory - application } // Deletes virtual directories var directoriesToDelete = mainApplication.VirtualDirectories.Where(directory => directory.Path != "/" && !site.Applications.Where(x => !x.IsApplication).Select(a => a.Path).Contains(directory.Path)).ToList(); // Exclude "/" because it's the root application's directory. foreach (var directory in directoriesToDelete) { directory.Delete(); mainApplication.VirtualDirectories.Remove(directory); // Bug in Microsoft.Web.Administration when changing from directory - application } //Intelligently updates virtual applications + directories foreach (var application in site.Applications) { if (!application.Path.StartsWith("/")) { application.Path = "/" + application.Path; } if (application.IsApplication) { if (application.Path.EndsWith("/")) { application.Path = application.Path.Substring(0, application.Path.Length - 1); } var iisApp = iisSite.Applications.SingleOrDefault(x => x.Path == application.Path); if (iisApp == null) { iisSite.Applications.Add(application.Path, application.DiskPath); iisApp = iisSite.Applications.Single(x => x.Path == application.Path); } iisApp.VirtualDirectories[0].PhysicalPath = application.DiskPath; iisApp.ApplicationPoolName = application.ApplicationPool; } else // Directory { var virtualDirectory = mainApplication.VirtualDirectories.SingleOrDefault(x => x.Path == application.Path); if (virtualDirectory == null) { mainApplication.VirtualDirectories.Add(application.Path, application.DiskPath); } else { virtualDirectory.PhysicalPath = application.DiskPath; } } } manager.CommitChanges(); } return(result); }
public static ManageSiteResult CreateSite(IisSite site) { var validationResult = Validators.ValidateSite(site, null); if (validationResult.Errors.Any()) { return(validationResult); } var result = new ManageSiteResult(); var bindingInformations = site.Bindings.Select(x => x.ToIisBindingInformation()).ToList(); // Check bindings var bindingInUse = GetBindingInUse(0, bindingInformations); // 0 never exists if (bindingInUse != null) { result.Result = SiteResult.BindingAlreadyInUse; return(result); } using (var manager = new ServerManager()) { if (manager.Sites.Any(x => x.Name == site.Name)) { result.Result = SiteResult.NameAlreadyInUse; return(result); } // Create site manager.Sites.Add(site.Name, "http", bindingInformations.First(), site.SitePath); var iisSite = manager.Sites.SingleOrDefault(x => x.Name == site.Name); // Add bindings iisSite.Bindings.Clear(); foreach (var binding in bindingInformations) { iisSite.Bindings.Add(binding, "http"); } // Set/create application pool if (string.IsNullOrWhiteSpace(site.ApplicationPool)) // Auto create application pool { var appPoolName = site.Name; var existingApplicationPoolNames = manager.ApplicationPools.Select(x => x.Name).ToList(); var newNameCount = 1; while (existingApplicationPoolNames.Contains(appPoolName)) { appPoolName = site.Name + "_" + newNameCount; newNameCount++; } manager.ApplicationPools.Add(appPoolName); iisSite.ApplicationDefaults.ApplicationPoolName = appPoolName; } else { iisSite.ApplicationDefaults.ApplicationPoolName = site.ApplicationPool; } //Add Virtual apps/directories foreach (var application in site.Applications) { if (!application.Path.StartsWith("/")) { application.Path = "/" + application.Path; } if (application.IsApplication) { if (application.Path.EndsWith("/")) { application.Path.Remove(application.Path.Length - 1, 1); } iisSite.Applications.Add(application.Path, application.DiskPath); } else // Directory { iisSite.Applications.First().VirtualDirectories.Add(application.Path, application.DiskPath); } } manager.CommitChanges(); var created = false; var sw = new Stopwatch(); sw.Start(); while (!created && sw.Elapsed.TotalSeconds < 3) { try { if (iisSite.State == ObjectState.Started || iisSite.State == ObjectState.Stopped) { created = true; } } catch (COMException) { System.Threading.Thread.Sleep(100); } } sw.Stop(); if (created) { result.Result = SiteResult.Success; result.IisSiteId = (int)iisSite.Id; } else { result.Result = SiteResult.Failed; } return(result); } }
public static ManageSiteResult ValidateSite(IisSite site, IisSite originalSite) { var certificates = SiteManager.GetCertificates(); var result = new ManageSiteResult(); if (!site.Bindings.Any()) { result.Errors.Add("Minimum one binding is required."); } if (string.IsNullOrWhiteSpace(site.Name)) { result.Errors.Add("Name is required."); } IisSite existingSite = SiteManager.GetSiteByName(site.Name); if (originalSite == null) { originalSite = new IisSite() { IisId = 0 }; } if (site.Name != null && existingSite != null && site.Name.ToLower() == existingSite.Name.ToLower() && existingSite.IisId != originalSite.IisId) { result.Errors.Add("There's already a site with this name."); } if (string.IsNullOrWhiteSpace(site.SitePath)) { result.Errors.Add("Site path is required."); } else { if (!FileSystemHelper.IsPathValid(site.SitePath)) { result.Errors.Add("Path cannot contain the following characters: ?, ;, :, @, &, =, +, $, ,, |, \", <, >, *."); } else { if (!FileSystemHelper.DirectoryExists(site.SitePath)) { FileSystemHelper.CreateDirectory(site.SitePath); } } if (!FileSystemHelper.IsPathValid(site.LogFileDirectory)) { result.Errors.Add("Log File Directory cannot contain the following characters: ?, ;, :, @, &, =, +, $, ,, |, \", <, >, *."); } else { if (!FileSystemHelper.DirectoryExists(site.LogFileDirectory)) { FileSystemHelper.CreateDirectory(site.LogFileDirectory); } } } result.Result = result.Errors.Any() ? SiteResult.ValidationError : SiteResult.Success; return(result); }
public HttpResponseMessage SiteAdd([FromBody] IisSite site) { Logger.Log.Trace("SiteAdd called."); return(Request.CreateResponse(HttpStatusCode.OK, IisConfigurator.AddIisSite(site))); }
public void Deploy(Deployment deployment) { var existingDeployment = _deploymentInstances.SingleOrDefault(x => x.DeploymentId == deployment.Id); if (existingDeployment != null) { if (existingDeployment.RollbackCompleted) // Deployment have been rolled back by other server already. { return; } _deploymentInstances.RemoveAll(x => x.DeploymentId == deployment.Id); } var sw = new Stopwatch(); var fullSw = new Stopwatch(); fullSw.Start(); SendResponse(deployment.Id, DeploymentResponseType.DeploymentRequestReceived, "Received deployment request."); IisSite site = SiteManager.GetSiteByName(deployment.SiteName); var originalPath = site.SitePath; var rootPath = site.SitePath; var directoryName = new DirectoryInfo(rootPath).Name; if (directoryName.StartsWith("servant-")) { rootPath = rootPath.Substring(0, rootPath.LastIndexOf(@"\", System.StringComparison.Ordinal)); } var newPath = Path.Combine(rootPath, "servant-" + deployment.Guid); var fullPath = Environment.ExpandEnvironmentVariables(newPath); Directory.CreateDirectory(fullPath); SendResponse(deployment.Id, DeploymentResponseType.CreateDirectory, "Created directory: " + fullPath); sw.Start(); var zipFile = DownloadUrl(deployment.Url); sw.Stop(); SendResponse(deployment.Id, DeploymentResponseType.PackageDownload, string.Format("Completed package download in {0} seconds.", sw.Elapsed.TotalSeconds)); var fastZip = new FastZip(); var stream = new MemoryStream(zipFile); fastZip.ExtractZip(stream, fullPath, FastZip.Overwrite.Always, null, null, null, true, true); SendResponse(deployment.Id, DeploymentResponseType.PackageUnzipping, "Completed package extracting."); site.SitePath = newPath; SiteManager.UpdateSite(site); if (site.ApplicationPoolState == InstanceState.Started) { SiteManager.RecycleApplicationPool(site.ApplicationPool); } fullSw.Stop(); SendResponse(deployment.Id, DeploymentResponseType.ChangeSitePath, string.Format("Changed site path to {0}. Deployment completed in {1} seconds.", fullPath, fullSw.Elapsed.TotalSeconds)); var rollbackCompleted = false; if (deployment.WarmupAfterDeploy) { System.Threading.Thread.Sleep(1000); // Waits for IIS to complete var warmupResult = Warmup(site, deployment.WarmupUrl); SendResponse(deployment.Id, DeploymentResponseType.WarmupResult, Json.SerializeToString(warmupResult)); var msg = warmupResult == null ? "Could not contact IIS site" : string.Format("Site locally returned HTTP {0} {1}.", (int)warmupResult.StatusCode, warmupResult.StatusCode); SendResponse(deployment.Id, DeploymentResponseType.Warmup, msg, warmupResult.StatusCode == HttpStatusCode.OK); if (deployment.RollbackOnError) { // Roll-back if not 200 OK if (warmupResult.StatusCode != HttpStatusCode.OK) { site.SitePath = originalPath; SiteManager.UpdateSite(site); if (site.ApplicationPoolState == InstanceState.Started) { SiteManager.RecycleApplicationPool(site.ApplicationPool); } rollbackCompleted = true; Warmup(site, deployment.WarmupUrl); SendResponse(deployment.Id, DeploymentResponseType.Rollback, string.Format("Rollback completed. Site path is now: {0}.", originalPath)); } } } _deploymentInstances.Add(new DeploymentInstance() { DeploymentId = deployment.Id, DeploymentGuid = deployment.Guid, NewPath = newPath, OriginalPath = originalPath, RollbackCompleted = rollbackCompleted, IisSiteId = site.IisId }); }