// ---------------------------------------------------------------------------------- // Unified Logging // // Copyright (c) UL Analytics, LLC. All rights reserved. // // ---------------------------------------------------------------------------------- using System; using System.Collections.Generic; using System.IO; using System.Security.AccessControl; using System.Xml; using System.Xml.Linq; using System.Xml.XPath; using Microsoft.WindowsAzure.ServiceRuntime; namespace UnifiedLogging.Web.Site { public static class UmbracoAzureSetup { #region public Static Methods /// /// Sets up umbraco for load balancing in Azure. /// Things to Note: /// 1) This is coded to work with one Site element under Sites in the RoleModel.xml. /// Update the code if this is not your case. /// 2) Sets permissions for NETWORK SERVICE, if the app pool is different update the code. /// public static void Setup() { SetPermissions(); UpdateUmbracoSettings(); } #endregion #region private Static Methods /// /// This will get the attribute of the first Site under Sites in the RoleModel.xml. /// If there are multpile site elements be sure to update this method to return the correct physical path. /// /// private static string GetWebSiteDirectory() { var rootPath = string.Empty; var roleRootDir = Environment.GetEnvironmentVariable("RdRoleRoot"); var roleModelDoc = XDocument.Load(Path.Combine(roleRootDir, "RoleModel.xml")); var namespaceManager = new XmlNamespaceManager(new NameTable()); namespaceManager.AddNamespace("empty", "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition"); var siteElement = roleModelDoc.XPathSelectElement("/empty:RoleModel/empty:Sites/empty:Site", namespaceManager); if (siteElement != null) { var attr = siteElement.Attribute("physicalDirectory"); if (attr != null) { rootPath = Path.Combine(roleRootDir, attr.Value); } } return rootPath + Path.DirectorySeparatorChar; } /// /// Will set full control permissions for NETWORK SERVICE on the entire web directory. /// private static void SetPermissions() { var roleRootDir = GetWebSiteDirectory(); if (String.IsNullOrEmpty(roleRootDir) == false) { roleRootDir = roleRootDir.TrimEnd('\\'); var accessControl = Directory.GetAccessControl(roleRootDir); accessControl.AddAccessRule(new FileSystemAccessRule("NETWORK SERVICE", FileSystemRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow)); Directory.SetAccessControl(roleRootDir, accessControl); } } /// /// Updates the umbracosetting.config with the ip addresses of the instances in the role. /// private static void UpdateUmbracoSettings() { var serverIps = new List(); if (RoleEnvironment.IsAvailable) { foreach (RoleInstance roleInstance in RoleEnvironment.CurrentRoleInstance.Role.Instances) { foreach (RoleInstanceEndpoint endpoint in roleInstance.InstanceEndpoints.Values) { var ipString = endpoint.IPEndpoint.Address.ToString(); if (serverIps.Contains(ipString) == false) { serverIps.Add(ipString); } } } } WriteDistributedServers(serverIps); } private static void WriteDistributedServers(List serverIps) { var websiteRoot = GetWebSiteDirectory(); //taken from umbraco source:) var configPath = websiteRoot + "config" + Path.DirectorySeparatorChar + "umbracoSettings.config"; var umbracoSettings = XDocument.Load(configPath); var serversElement = umbracoSettings.XPathSelectElement("/settings/distributedCall/servers"); if (serversElement != null) { serversElement.RemoveNodes(); foreach (var serverIp in serverIps) { var serverElement = new XElement("server", serverIp); serversElement.Add(serverElement); } umbracoSettings.Save(configPath); } } #endregion } }