Пример #1
0
        private void ValidateNodeList()
        {
            if (this.infrastructureInformation == null)
            {
                FabricValidator.TraceSource.WriteWarning(
                    FabricValidatorUtility.TraceTag,
                    "Skipping node list validation as it is empty");
                return;
            }

            //Validate StartPort and EndPort number and range
            if (clusterManifest.Infrastructure.Item is ClusterManifestTypeInfrastructureWindowsAzure)
            {
                foreach (InfrastructureNodeType infra in this.infrastructureInformation)
                {
                    try
                    {
                        if (infra.Endpoints.ApplicationEndpoints.StartPort < 0 || infra.Endpoints.ApplicationEndpoints.EndPort < 0)
                        {
                            throw new ArgumentException(
                                      string.Format(
                                          StringResources.Warning_FabricValidatorStartEndPortNegative, infra.NodeName));
                        }

                        if (infra.Endpoints.ApplicationEndpoints.StartPort > infra.Endpoints.ApplicationEndpoints.EndPort)
                        {
                            throw new ArgumentException(
                                      string.Format(
                                          StringResources.Warning_FabricValidatorPortRangeInvalid, infra.NodeName));
                        }

                        //Validate the other five ports
                        ValidateEndpointsPortsHelper(infra.Endpoints.ClientConnectionEndpoint.Port, infra.NodeName, "ClientConnectionEndpoint");
                        ValidateEndpointsPortsHelper(infra.Endpoints.LeaseDriverEndpoint.Port, infra.NodeName, "LeaseDriverEndpoint");
                        ValidateEndpointsPortsHelper(infra.Endpoints.ClusterConnectionEndpoint.Port, infra.NodeName, "ClusterConnectionEndpoint");
                        ValidateEndpointsPortsHelper(infra.Endpoints.HttpGatewayEndpoint.Port, infra.NodeName, "HttpGatewayEndpoint");
                        // TODO add validation for http app gateway endpoint
                        // ValidateEndpointsPortsHelper(infra.Endpoints.HttpApplicationGatewayEndpoint.Port, infra.NodeName, "HttpApplicationGatewayEndpoint");
                        ValidateEndpointsPortsHelper(infra.Endpoints.ServiceConnectionEndpoint.Port, infra.NodeName, "ServiceConnectionEndpoint");
                    }
                    catch (NullReferenceException)
                    {
                        FabricValidator.TraceSource.WriteWarning(
                            FabricValidatorUtility.TraceTag,
                            StringResources.Info_FabricValidatorPortsNull);
                        return;
                    }
                }
            }


#if DotNetCoreClrLinux
            var isServer = clusterManifest.Infrastructure.Item is ClusterManifestTypeInfrastructureLinux;
#else
            var isServer = clusterManifest.Infrastructure.Item is ClusterManifestTypeInfrastructureWindowsServer;
#endif
            if (isServer || clusterManifest.Infrastructure.Item is ClusterManifestTypeInfrastructureWindowsAzureStaticTopology)
            {
                foreach (InfrastructureNodeType infra in this.infrastructureInformation)
                {
                    if (Helpers.isIPV6AddressAndNoBracket(infra.IPAddressOrFQDN))
                    {
                        throw new ArgumentException(StringResources.Error_BracketsAroundIPV6AddressAreMandatory, infra.NodeName);
                    }
                }
            }

            int voteCount = this.NonSeedVoteCount;
            ClusterManifestTypeInfrastructurePaaS paasInfrastructure = clusterManifest.Infrastructure.Item as ClusterManifestTypeInfrastructurePaaS;
            if (paasInfrastructure != null)
            {
                voteCount += paasInfrastructure.Votes.Count();
            }

            bool   matchingLocalNodeFound = false;
            string prevMachine            = this.infrastructureInformation[0].IPAddressOrFQDN;

            if (this.IsScaleMin && !NetworkApiHelper.IsNodeForThisMachine(this.infrastructureInformation[0]))
            {
                this.DoMachineAndNodeHaveSameIPInScaleMin = false;
            }

            bool             hasLoopbackAddressDefined = false;
            HashSet <string> nodeNameDuplicateDetector = new HashSet <string>();
            List <string>    faultDomains = new List <string>();
            foreach (InfrastructureNodeType fabricNode in this.infrastructureInformation)
            {
                ClusterManifestTypeNodeType nodeType = this.clusterManifest.NodeTypes.FirstOrDefault(nodeTypeVar => FabricValidatorUtility.EqualsIgnoreCase(nodeTypeVar.Name, fabricNode.NodeTypeRef));

                if (nodeType == null)
                {
                    if (!(this.DeploymentOperation == DeploymentOperations.Update && this.clusterManifest.Infrastructure.Item is ClusterManifestTypeInfrastructurePaaS))
                    {
                        throw new ArgumentException(
                                  string.Format(
                                      "Node '{0}' has attribute NodeTypeRef='{1}'. However, no NodeType with name {1} exists.",
                                      fabricNode.NodeName,
                                      fabricNode.NodeTypeRef));
                    }
                }

                if (fabricNode.IsSeedNode)
                {
                    voteCount++;
                }

                faultDomains.Add(fabricNode.FaultDomain);
                if (!FabricValidatorUtility.IsValidFileName(fabricNode.NodeName))
                {
                    throw new ArgumentException(
                              string.Format(
                                  "Invalid character found in node name {0}. Node name should be a valid file name.",
                                  fabricNode.NodeName));
                }

                if (!FabricValidatorUtility.IsValidIPAddressOrFQDN(fabricNode.IPAddressOrFQDN))
                {
                    throw new ArgumentException(
                              string.Format(
                                  "Malformed IPAddressOrFQDN found {0}.",
                                  fabricNode.IPAddressOrFQDN));
                }

                if (nodeNameDuplicateDetector.Contains(fabricNode.NodeName))
                {
                    throw new ArgumentException(
                              string.Format(
                                  "Duplicate node name {0} found.",
                                  fabricNode.NodeName));
                }
                else
                {
                    nodeNameDuplicateDetector.Add(fabricNode.NodeName);
                }

                if (fabricNode.IPAddressOrFQDN != prevMachine &&
                    !FabricValidatorUtility.IsNodeAddressLoopback(fabricNode))
                {
                    this.IsSingleMachineDeployment = false;
                }

                if (!hasLoopbackAddressDefined)
                {
                    hasLoopbackAddressDefined = FabricValidatorUtility.IsNodeAddressLoopback(fabricNode);
                }

                FabricValidator.TraceSource.WriteNoise(
                    FabricValidatorUtility.TraceTag,
                    "fabricNode is {0}", fabricNode);

                if (!FabricValidatorUtility.IsNodeForThisMachine(fabricNode))
                {
                    continue;
                }

                if (matchingLocalNodeFound && !this.IsScaleMin)
                {
                    throw new ArgumentException(
                              string.Format(
                                  "The IPAddressorFQDN value in node '{0}' is {1}. Another node is also configured to run on the same machine. " +
                                  "Running multiple nodes on the same machine is not valid in the specified infrastructure.",
                                  fabricNode.NodeName,
                                  fabricNode.IPAddressOrFQDN));
                }
                else
                {
                    matchingLocalNodeFound = true;
                    FabricValidatorUtility.ValidateDomainUri(fabricNode.FaultDomain, fabricNode.NodeName);
                }
            }

            int fdPathCount = -1;
            foreach (string faultDomain in faultDomains)
            {
                if (!string.IsNullOrEmpty(faultDomain))
                {
                    int currentfdPathCount = faultDomain.Split('/').Length;
                    if (fdPathCount == -1)
                    {
                        fdPathCount = currentfdPathCount;
                    }
                    if (fdPathCount != currentfdPathCount)
                    {
                        throw new ArgumentException("All FaultDomains should have the same depth.");
                    }
                }
            }

            if (!matchingLocalNodeFound)
            {
                FabricValidator.TraceSource.WriteWarning(
                    FabricValidatorUtility.TraceTag,
                    "None of the declared nodes is for the current machine.");
            }

            if (!this.IsSingleMachineDeployment && hasLoopbackAddressDefined)
            {
                throw new ArgumentException("Even though the deployment is split over multiple machines there is at least one node with a loopback address");
            }

            if (voteCount == 0)
            {
                throw new ArgumentException("No votes specified. Either seed nodes or sql vote specification is required for cluster to bootstrap");
            }

            if (!this.DoMachineAndNodeHaveSameIPInScaleMin)
            {
                FabricValidator.TraceSource.WriteWarning(
                    FabricValidatorUtility.TraceTag,
                    StringResources.Warning_FirstNodeAndMachineHaveDifferentIP);
                return;
            }
        }
Пример #2
0
        public ServerInfrastructure(ClusterManifestTypeInfrastructure cmInfrastructure, InfrastructureNodeType[] infrastructureNodes, Dictionary <string, ClusterManifestTypeNodeType> nameToNodeTypeMap)
        {
            this.votes = new List <SettingsTypeSectionParameter>();
            this.seedNodeClientConnectionAddresses = new List <SettingsTypeSectionParameter>();
            this.nodes = new List <InfrastructureNodeType>();
#if DotNetCoreClrLinux
            var infrastructure = cmInfrastructure.Item as ClusterManifestTypeInfrastructureLinux;
#else
            var infrastructure = cmInfrastructure.Item as ClusterManifestTypeInfrastructureWindowsServer;
#endif

            foreach (var nodeInfo in infrastructure.NodeList)
            {
                if (!nameToNodeTypeMap.ContainsKey(nodeInfo.NodeTypeRef))
                {
                    throw new ArgumentException(
                              string.Format(CultureInfo.InvariantCulture, "Node {0} has NodeType {1}, which is not present in node types definition", nodeInfo.NodeName, nodeInfo.NodeTypeRef));
                }

                var nodeType = nameToNodeTypeMap[nodeInfo.NodeTypeRef];
                var node     = (new InfrastructureNodeType()
                {
                    Certificates = nodeType.Certificates,
                    Endpoints = nodeType.Endpoints,
                    FaultDomain = nodeInfo.FaultDomain,
                    IPAddressOrFQDN = Helpers.isIPV6AddressAndNoBracket(nodeInfo.IPAddressOrFQDN) ?
                                      Helpers.AddBracketsAroundIPV6(nodeInfo.IPAddressOrFQDN) : nodeInfo.IPAddressOrFQDN,
                    IsSeedNode = nodeInfo.IsSeedNode,
                    NodeName = nodeInfo.NodeName,
                    NodeTypeRef = nodeInfo.NodeTypeRef,
                    RoleOrTierName = nodeInfo.NodeTypeRef,
                    UpgradeDomain = nodeInfo.UpgradeDomain
                });
                this.nodes.Add(node);
                if (node.IsSeedNode)
                {
                    string key = node.NodeName;
                    string connectionAddress = string.Format(CultureInfo.InvariantCulture, "{0}:{1}", node.IPAddressOrFQDN, node.Endpoints.ClusterConnectionEndpoint.Port);
                    string value             = string.Format(CultureInfo.InvariantCulture, "{0},{1}", "SeedNode", connectionAddress);
                    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);
                }
            }

            if (infrastructureNodes != null)
            {
                foreach (var infraNode in infrastructureNodes)
                {
                    /* If the current machine node name is present in the infrastructure manifest but not present in the cluster manifest, then
                     * it should be added back to this.nodes */
                    if (this.nodes.Find(node => infraNode.NodeName == node.NodeName) == null &&
                        NetworkApiHelper.IsNodeForThisMachine(infraNode))
                    {
                        this.nodes.Add(infraNode);
                    }
                }
            }

            this.isScaleMin = infrastructure.IsScaleMin;
        }