Esempio n. 1
1
        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);
            }
        }
Esempio n. 2
0
 public static int AddIisSite(IisSite site)
 {
     return(ConfigDb.IisSiteAdd(
                site.Sitename,
                site.Hostname,
                site.Group));
 }
Esempio n. 3
0
        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));
            }
        }
Esempio n. 4
0
        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");
        }
Esempio n. 5
0
        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);
                }
            }
        }
Esempio n. 6
0
        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;
        }
Esempio n. 7
0
        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);
        }
Esempio n. 8
0
        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;
        }
Esempio n. 9
0
        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);
        }
Esempio n. 10
0
        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();
            }
        }
Esempio n. 11
0
        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);
        }
Esempio n. 12
0
        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);
        }
Esempio n. 13
0
        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);
            }
        }
Esempio n. 14
0
        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();
            }
        }
Esempio n. 15
0
        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());
            }
        }
Esempio n. 16
0
        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");
            }
        }
Esempio n. 17
0
        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();
            }
        }
Esempio n. 18
0
        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);
            }
        }
Esempio n. 19
0
        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();
            }
        }
Esempio n. 20
0
        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();
            }
        }
Esempio n. 21
0
        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.");
        }
Esempio n. 22
0
        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;
            }
        }
Esempio n. 23
0
        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;
        }
Esempio n. 24
0
        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;
        }
Esempio n. 25
0
        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();
            }
        }
Esempio n. 26
0
        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;
                }
            }
        }
Esempio n. 27
0
        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);
        }
Esempio n. 28
0
        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);
            }
        }
Esempio n. 29
0
        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)));
        }
Esempio n. 31
0
        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
            });
        }