public static bool IsNodeListScaleMin(List <InfrastructureNodeType> nodeList)
        {
            bool nodeFound = false;

            foreach (var node in nodeList)
            {
                if (FabricValidatorUtility.IsNodeForThisMachine(node))
                {
                    if (nodeFound)
                    {
                        return(true);
                    }

                    nodeFound = true;
                }
            }

            return(false);
        }
Exemple #2
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;
            }
        }