private void ValidateInfrastructureWithServiceRuntimeTopologyProvider(ClusterManifestTypeInfrastructureWindowsAzure azureInfrastructure) { IEnumerable <AzureRoleType> seedNodes = azureInfrastructure.Roles.Where(roleType => roleType.SeedNodeCount > 0); if (seedNodes.Count() != 1) { throw new ArgumentException("Exactly one role has to have a non zero seed node count."); } if (this.clusterManifest.NodeTypes.Length != azureInfrastructure.Roles.Length) { // Meaning there are more than 1 more infrastructure roles than are types. throw new ArgumentException("Roles and node types should have a one to one mapping."); } Array.Sort(this.clusterManifest.NodeTypes, NodeTypeNameComparator); Array.Sort(azureInfrastructure.Roles, AzureRoleTypeNodeTypeRefComparator); for (int i = 0; i < this.clusterManifest.NodeTypes.Length; i++) { if (this.clusterManifest.NodeTypes[i].Name != azureInfrastructure.Roles[i].NodeTypeRef) { throw new ArgumentException( string.Format( "Role {0} found but corresponding node type not found. or Node type {1} found but corresponding role not found.", azureInfrastructure.Roles[i].RoleName, this.clusterManifest.NodeTypes[i].Name)); } if (this.clusterManifest.NodeTypes[i].Endpoints != null) { throw new ArgumentException( string.Format("Node type {0} should not define endpoint section on Windows Azure infrastructure.", this.clusterManifest.NodeTypes[i].Name)); } } }
internal static void CompareAndAnalyze(ClusterManifestType currentClusterManifest, ClusterManifestType targetClusterManifest, Infrastructure infrastructure, DeploymentParameters parameters) { // If the infrastructure elements are different, the update cannot continue if (targetClusterManifest.Infrastructure.Item.GetType() != currentClusterManifest.Infrastructure.Item.GetType()) { DeployerTrace.WriteError("Invalid Operation. Cannot update from 1 infrastructure type to another"); throw new ClusterManifestValidationException(StringResources.Error_FabricDeployer_InvalidClusterManifest_Formatted); } // Validate that the new cluster manifest and the node list are valid try { var currentWindowsFabricSettings = new WindowsFabricSettings(currentClusterManifest); var targetWindowsFabricSettings = new WindowsFabricSettings(targetClusterManifest); FabricValidator.Create(targetClusterManifest, infrastructure.InfrastructureNodes, targetWindowsFabricSettings, parameters.Operation).Validate(); //Validate if the SeedNodeCount increases by one int currentSeedNodes = 0, targetSeedNodes = 0; List <String> currentSeedNodesList = new List <String>(); List <String> targetSeedNodesList = new List <String>(); if (currentClusterManifest.Infrastructure.Item is ClusterManifestTypeInfrastructureWindowsAzure) { ClusterManifestTypeInfrastructureWindowsAzure currentInfrastructure = currentClusterManifest.Infrastructure.Item as ClusterManifestTypeInfrastructureWindowsAzure; ClusterManifestTypeInfrastructureWindowsAzure targetInfrastructure = targetClusterManifest.Infrastructure.Item as ClusterManifestTypeInfrastructureWindowsAzure; for (int i = 0; i < currentInfrastructure.Roles.Length; i++) { currentSeedNodes += currentInfrastructure.Roles[i].SeedNodeCount; } for (int j = 0; j < targetInfrastructure.Roles.Length; j++) { targetSeedNodes += targetInfrastructure.Roles[j].SeedNodeCount; } } else if (currentClusterManifest.Infrastructure.Item is ClusterManifestTypeInfrastructureWindowsAzureStaticTopology) { ClusterManifestTypeInfrastructureWindowsAzureStaticTopology currentInfrastructure = currentClusterManifest.Infrastructure.Item as ClusterManifestTypeInfrastructureWindowsAzureStaticTopology; ClusterManifestTypeInfrastructureWindowsAzureStaticTopology targetInfrastructure = targetClusterManifest.Infrastructure.Item as ClusterManifestTypeInfrastructureWindowsAzureStaticTopology; foreach (FabricNodeType nodelist in currentInfrastructure.NodeList) { if (nodelist.IsSeedNode) { currentSeedNodes++; } } foreach (FabricNodeType nodelist in targetInfrastructure.NodeList) { if (nodelist.IsSeedNode) { targetSeedNodes++; } } } #if DotNetCoreClrLinux else if (currentClusterManifest.Infrastructure.Item is ClusterManifestTypeInfrastructureLinux) { var currentInfrastructure = currentClusterManifest.Infrastructure.Item as ClusterManifestTypeInfrastructureLinux; var targetInfrastructure = targetClusterManifest.Infrastructure.Item as ClusterManifestTypeInfrastructureLinux; #else else if (currentClusterManifest.Infrastructure.Item is ClusterManifestTypeInfrastructureWindowsServer) { var currentInfrastructure = currentClusterManifest.Infrastructure.Item as ClusterManifestTypeInfrastructureWindowsServer; var targetInfrastructure = targetClusterManifest.Infrastructure.Item as ClusterManifestTypeInfrastructureWindowsServer; #endif foreach (FabricNodeType nodelist in currentInfrastructure.NodeList) { if (nodelist.IsSeedNode) { currentSeedNodes++; currentSeedNodesList.Add(nodelist.NodeName); } } foreach (FabricNodeType nodelist in targetInfrastructure.NodeList) { if (nodelist.IsSeedNode) { targetSeedNodes++; targetSeedNodesList.Add(nodelist.NodeName); } } } if (System.Math.Abs(currentSeedNodes - targetSeedNodes) > 1) { DeployerTrace.WriteError(StringResources.Warning_SeedNodeCountCanOnlyChangeByOne); throw new ClusterManifestValidationException(StringResources.Warning_SeedNodeCountCanOnlyChangeByOne); } else if (currentSeedNodesList.Except(targetSeedNodesList).Union(targetSeedNodesList.Except(currentSeedNodesList)).Count() > 1) { DeployerTrace.WriteError(StringResources.Warning_SeedNodeSetCannotHaveMultipleChanges); throw new ClusterManifestValidationException(StringResources.Warning_SeedNodeSetCannotHaveMultipleChanges); } var fabricValidator = FabricValidator.Create(currentClusterManifest, null, currentWindowsFabricSettings, parameters.Operation); // Finally, compare the settings and decide if fabric must restart or not IEnumerable <KeyValuePair <string, string> > modifiedStaticSettings = fabricValidator.CompareAndAnalyze(targetClusterManifest, parameters.NodeTypeName); if (modifiedStaticSettings.Count() > 0) { WriteModifiedStaticSettingsToFile(modifiedStaticSettings, targetClusterManifest.FabricSettings, parameters.OutputFile); throw new FabricHostRestartRequiredException("Fabric host restart is required"); } else { throw new FabricHostRestartNotRequiredException("Fabric host restart is not required"); } } catch (Exception e) { if (e is FabricHostRestartRequiredException || e is FabricHostRestartNotRequiredException) { throw e; } else { throw new ClusterManifestValidationException( string.Format(StringResources.Error_FabricDeployer_InvalidClusterManifest_Formatted, e)); } } }
private void InitializeInfrastructureSettings(InfrastructureType infrastructureType, bool isScaleMin, int nNodeTypes, int[] nSeedNodes) { switch (infrastructureType) { case InfrastructureType.Blackbird: return; case InfrastructureType.VMM: return; case InfrastructureType.PaaS: var paasInfra = new ClusterManifestTypeInfrastructurePaaS(); paasInfra.Roles = new PaaSRoleType[nNodeTypes]; for (int i = 0; i < nNodeTypes; i++) { paasInfra.Roles[i] = new PaaSRoleType(); paasInfra.Roles[i].RoleName = GetRoleOrTiername(i); paasInfra.Roles[i].NodeTypeRef = GetRoleOrTiername(i); paasInfra.Roles[i].RoleNodeCount = nSeedNodes[i]; } var paasVotes = new List <PaaSVoteType>(); foreach (var node in this.infraNodes) { if (node.IsSeedNode) { paasVotes.Add(new PaaSVoteType() { NodeName = node.NodeName, IPAddressOrFQDN = node.IPAddressOrFQDN, Port = Convert.ToInt32(node.Endpoints.ClusterConnectionEndpoint.Port) }); } } paasInfra.Votes = paasVotes.ToArray(); this.infrastructure = new ClusterManifestTypeInfrastructure(); this.infrastructure.Item = paasInfra; return; case InfrastructureType.WindowsAzure: var azureInfra = new ClusterManifestTypeInfrastructureWindowsAzure(); azureInfra.Roles = new AzureRoleType[nNodeTypes]; for (int i = 0; i < nNodeTypes; i++) { azureInfra.Roles[i] = new AzureRoleType(); azureInfra.Roles[i].RoleName = GetRoleOrTiername(i); azureInfra.Roles[i].NodeTypeRef = GetRoleOrTiername(i); azureInfra.Roles[i].SeedNodeCount = nSeedNodes[i]; } this.infrastructure = new ClusterManifestTypeInfrastructure(); this.infrastructure.Item = azureInfra; return; case InfrastructureType.WindowsServer: var infra = new ClusterManifestTypeInfrastructureWindowsServer(); infra.IsScaleMin = isScaleMin; infra.NodeList = this.nodes; this.infrastructure = new ClusterManifestTypeInfrastructure(); this.infrastructure.Item = infra; return; } }
private void InitializeFromServiceRuntimeTopologyProvider(ClusterManifestTypeInfrastructureWindowsAzure azureInfrastructure, InfrastructureNodeType[] inputInfrastructureNodes, Dictionary <string, ClusterManifestTypeNodeType> nameToNodeTypeMap) { // For service runtime topology provider, source of cluster topology is infrastructure manifest provided by azure wrapper service. // Seed nodes are determined as the first SeedNodeCount nodes of the seed node role. ReleaseAssert.AssertIfNull(inputInfrastructureNodes, "inputInfrastructureNodes"); Dictionary <string, int> seedInfo = new Dictionary <string, int>(); Dictionary <string, string> roleToTypeMap = new Dictionary <string, string>(); foreach (var role in azureInfrastructure.Roles) { try { seedInfo.Add(role.RoleName, role.SeedNodeCount); roleToTypeMap.Add(role.RoleName, role.NodeTypeRef); } catch (ArgumentException) { throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Role name {0} is duplicate", role.RoleName)); } } foreach (var nodeInfo in inputInfrastructureNodes) { string nodeIndex = nodeInfo.NodeName.Split(".".ToCharArray()).Last(); int index = int.Parse(nodeIndex); ClusterManifestTypeNodeType nodeType = null; if (roleToTypeMap.ContainsKey(nodeInfo.RoleOrTierName)) { var nodeTypeName = roleToTypeMap[nodeInfo.RoleOrTierName]; if (nameToNodeTypeMap.ContainsKey(nodeTypeName)) { nodeType = nameToNodeTypeMap[nodeTypeName]; } else { throw new ArgumentException( string.Format( CultureInfo.InvariantCulture, "Node type {0} specified for role {1} in node {2} not found", nodeTypeName, nodeInfo.RoleOrTierName, nodeInfo.NodeName)); } } else { throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Role name {0} specified in node {1} not found", nodeInfo.NodeName, nodeInfo.RoleOrTierName)); } var node = new InfrastructureNodeType() { FaultDomain = nodeInfo.FaultDomain, IPAddressOrFQDN = nodeInfo.IPAddressOrFQDN, IsSeedNode = index < seedInfo[nodeInfo.RoleOrTierName], NodeName = nodeInfo.NodeName, NodeTypeRef = roleToTypeMap[nodeInfo.RoleOrTierName], UpgradeDomain = nodeInfo.UpgradeDomain, RoleOrTierName = nodeInfo.RoleOrTierName, Endpoints = nodeInfo.Endpoints, Certificates = nodeType.Certificates }; this.nodes.Add(node); if (node.IsSeedNode) { // Add vote mappings string connectionAddress = string.Format(CultureInfo.InvariantCulture, "{0}:{1}", node.IPAddressOrFQDN, node.Endpoints.ClusterConnectionEndpoint.Port); this.voteMappings.Add(node.NodeName, connectionAddress); FabricValidator.TraceSource.WriteNoise(FabricValidatorUtility.TraceTag, "Mapping {0}-{1} added", node.NodeName, connectionAddress); // Add votes. string key = node.NodeName; string value = string.Format(CultureInfo.InvariantCulture, "{0},{1}", "WindowsAzure", node.NodeName); this.votes.Add(new SettingsTypeSectionParameter() { Name = key, Value = value, MustOverride = false }); FabricValidator.TraceSource.WriteNoise(FabricValidatorUtility.TraceTag, "Vote {0}-{1} added", key, value); string clientConnectionAddress = string.Format(CultureInfo.InvariantCulture, "{0}:{1}", node.IPAddressOrFQDN, node.Endpoints.ClientConnectionEndpoint.Port); this.seedNodeClientConnectionAddresses.Add(new SettingsTypeSectionParameter() { Name = key, Value = clientConnectionAddress, MustOverride = false }); FabricValidator.TraceSource.WriteNoise(FabricValidatorUtility.TraceTag, "Seed Nodes {0}-{1} added", key, clientConnectionAddress); } } this.isScaleMin = FabricValidatorUtility.IsAddressLoopback(nodes[0].IPAddressOrFQDN); }