internal static bool IsJsonConfigModelValid(StandAloneInstallerJsonModelBase config, StandAloneInstallerJsonModelBase oldConfig, bool validateDownNodes, bool throwIfError = false)
        {
            try
            {
                config.ThrowValidationExceptionIfNull(StringResources.Error_BPAJsonModelInvalid);
                config.ValidateModel();
                var settingsValidator = new StandaloneSettingsValidator(config);
                settingsValidator.Validate(validateDownNodes);

                // UOS validates upgrade config diffs by calling ValidateUpdateFrom() method directly. Test-Configuration invokes IsJsonConfigModelValid() and it calls ValidateUpdateFrom inside.
                // The reason is from Test-Configuration, there is no cluster connection, so that we ignore ValidateTopologyAsync(). Therefore in the ValidateUpdateFrom here there is no need
                // to await the async call. However in UOS, we should call ValidateUpdateFrom in an async manner. That's why I am not trying to have the UOS/TestConfiguration going down the same path.
                if (oldConfig != null)
                {
                    settingsValidator.ValidateUpdateFrom(oldConfig.GetUserConfig(), oldConfig.GetClusterTopology(), connectedToCluster: false).GetAwaiter().GetResult();
                }
            }
            catch (FileNotFoundException ex)
            {
                SFDeployerTrace.WriteError(StringResources.Error_BPAPackageFileNotFound, ex.ToString());
                return(false);
            }
            catch (ValidationException ex)
            {
                SFDeployerTrace.WriteError(StringResources.Error_BPAModelSettingsValidationFailed, ex.GetMessage(System.Globalization.CultureInfo.InvariantCulture));
                if (throwIfError)
                {
                    throw;
                }

                return(false);
            }

            return(true);
        }
        internal static StandAloneCluster ConstructClusterFromJson(StandAloneInstallerJsonModelBase jsonModel, FabricNativeConfigStore configStore)
        {
            UpgradeOrchestrationTrace.TraceSource.WriteInfo(TraceType, "Creating userconfig, cluster topology, adminconfig.");

            var userConfig      = jsonModel.GetUserConfig();
            var clusterTopology = jsonModel.GetClusterTopology();
            var adminConfig     = new StandaloneAdminConfig();
            var logger          = new StandAloneTraceLogger("StandAloneDeploymentManager");

            UpgradeOrchestrationTrace.TraceSource.WriteInfo(TraceType, "Creating new StandAlone cluster resource.");

            var clusterId       = configStore.ReadUnencryptedString(Constants.SectionName, Constants.ClusterIdParameterName);
            var clusterResource = new StandAloneCluster(adminConfig, userConfig, clusterTopology, clusterId, logger);

            return(clusterResource);
        }
Beispiel #3
0
        internal static StandAloneCluster PopulateStandAloneClusterWithBaselineJson(string jsonFilePath)
        {
            StandAloneInstallerJsonModelBase jsonConfig = StandAloneInstallerJsonModelBase.GetJsonConfigFromFile(Path.Combine(Utility.TestDirectory, jsonFilePath));

            var userConfig      = jsonConfig.GetUserConfig();
            var clusterTopology = jsonConfig.GetClusterTopology();
            var adminConfig     = new StandaloneAdminConfig();
            var logger          = new StandAloneTraceLogger("StandAloneDeploymentManager");

            string customizedClusterId = jsonConfig.GetClusterRegistrationId();

            return(new StandAloneCluster(
                       adminConfig,
                       userConfig,
                       clusterTopology,
                       customizedClusterId ?? "acf4dc93-9b64-4504-8b6f-0b7fd052e096",
                       logger));
        }
        internal static bool ValidateClusterRemoval(
            string configPath,
            bool usingClusterManifest = false)
        {
            SFDeployerTrace.WriteInfo(StringResources.Info_BPAStart);
            var summary = new AnalysisSummary();

            // Check user has local admin privilege
            summary.LocalAdminPrivilege = CheckLocalAdminPrivilege();
            StandAloneInstallerJsonModelBase standAloneModel = null;

            if (!usingClusterManifest)
            {
                standAloneModel     = StandAloneInstallerJsonModelBase.GetJsonConfigFromFile(configPath);
                summary.IsJsonValid = IsJsonConfigModelValid(standAloneModel, null, validateDownNodes: false, throwIfError: false);
            }

            // Below depends on JSON being valid
            if (!summary.Passed)
            {
                SFDeployerTrace.WriteError(StringResources.Error_BPABailing);
                return(false);
            }

            // Get machine names from JSON config
            IEnumerable <string> machineNames = usingClusterManifest
                                        ? StandaloneUtility.GetMachineNamesFromClusterManifest(configPath)
                                        : standAloneModel.GetClusterTopology().Machines;

            MachineHealthContainer machineHealthContainer = new MachineHealthContainer(machineNames);

            // Log validations but don't fail
            StandaloneUtility.CheckRequiredPorts(machineHealthContainer);
            CheckRPCAccess(machineHealthContainer);

            // At least one machine should be removable
            bool anyMachinesRemovable = CheckAnyMachinesRemovable(machineNames);

            LogResult(summary, anyMachinesRemovable);

            return(summary.Passed);
        }
        internal static AnalysisSummary AnalyzeClusterSetup(
            string configPath,
            string oldConfigPath,
            string cabPath,
            bool usingClusterManifest           = false,
            FabricPackageType fabricPackageType = FabricPackageType.XCopyPackage,
            bool isForcedRun          = false,
            int maxPercentFailedNodes = 0)
        {
            SFDeployerTrace.WriteInfo(StringResources.Info_BPAStart);
            var summary = new AnalysisSummary();

            // Check user has local admin privilege
            summary.LocalAdminPrivilege = CheckLocalAdminPrivilege();

            // Validate JSON config
            StandAloneInstallerJsonModelBase standAloneModel    = null;
            StandAloneInstallerJsonModelBase oldStandAloneModel = null;

            if (!usingClusterManifest)
            {
                standAloneModel = StandAloneInstallerJsonModelBase.GetJsonConfigFromFile(configPath);

                if (!string.IsNullOrEmpty(oldConfigPath))
                {
                    oldStandAloneModel = StandAloneInstallerJsonModelBase.GetJsonConfigFromFile(oldConfigPath);
                }

                summary.IsJsonValid = IsJsonConfigModelValid(standAloneModel, oldStandAloneModel, validateDownNodes: true, throwIfError: false) && ValidateCodeVersionExists(standAloneModel);
            }

            // Deliberately not checking empty. Some invocations aren't intended to test cabPath.
            if (cabPath != null)
            {
                summary.IsCabValid = CheckIsCabFile(cabPath);
            }

            // Below depends on JSON being valid
            if (!summary.Passed)
            {
                SFDeployerTrace.WriteError(StringResources.Error_BPABailing);
                return(summary);
            }

            // Get machine names from JSON config
            IEnumerable <string> healthyMachineNames = usingClusterManifest
                                        ? StandaloneUtility.GetMachineNamesFromClusterManifest(configPath)
                                        : standAloneModel.GetClusterTopology().Machines;

            MachineHealthContainer machineHealthContainer = new MachineHealthContainer(healthyMachineNames, maxPercentFailedNodes);

            // Validate machine FQDNs, Check SMB ports opened
            summary.RequiredPortsOpen = StandaloneUtility.CheckRequiredPorts(machineHealthContainer);

            // Below depends on machines being reachable
            if (!summary.Passed)
            {
                SFDeployerTrace.WriteError(StringResources.Error_BPABailing);
                return(summary);
            }

            // Validate Remote Registry Service is not disabled on all machines
            summary.RemoteRegistryAvailable = CheckRemoteRegistryEnabled(machineHealthContainer);

            // Below depends on remote registry service
            if (!summary.Passed)
            {
                SFDeployerTrace.WriteError(StringResources.Error_BPABailing);
                return(summary);
            }

            summary.FirewallAvailable = CheckFirewallEnabled(machineHealthContainer);

            // Below depends on firewall service
            if (!summary.Passed)
            {
                SFDeployerTrace.WriteError(StringResources.Error_BPABailing);
                return(summary);
            }

            // Run RPC check to validate end-to-end registry access to all machines
            summary.RpcCheckPassed = CheckRPCAccess(machineHealthContainer);

            // Below depend on remote registry access
            if (!summary.Passed)
            {
                SFDeployerTrace.WriteError(StringResources.Error_BPABailing);
                return(summary);
            }

            summary.NoDomainController = CheckNoMachineIsDomainController(machineHealthContainer);

            // Below depends on machines not being domain controller
            if (!summary.Passed)
            {
                SFDeployerTrace.WriteError(StringResources.Error_BPABailing);
                return(summary);
            }

            if (fabricPackageType == FabricPackageType.XCopyPackage)
            {
                // Validate that Fabric runtime MSI is not installed since this will be conflicting with Standalone
                summary.NoConflictingInstallations = !StandaloneUtility.IsMsiInstalled(machineHealthContainer);
            }

            string fabricDataRoot = null;
            string fabricLogRoot  = null;

            if (!usingClusterManifest)
            {
                if (string.IsNullOrEmpty(oldConfigPath))
                {
                    summary.FabricInstallable = CheckForCleanInstall(standAloneModel, machineHealthContainer, isForcedRun); // Fabric is not installed on target machines
                }

                var importantSettings = standAloneModel.GetFabricSystemSettings();
                fabricDataRoot = importantSettings.ContainsKey(DMConstants.FabricDataRootString) ?
                                 importantSettings[DMConstants.FabricDataRootString] :
                                 null;
                fabricLogRoot = importantSettings.ContainsKey(DMConstants.FabricLogRootString) ?
                                importantSettings[DMConstants.FabricLogRootString] :
                                null;

                summary.DataDrivesAvailable = CheckDataSystemDrives(machineHealthContainer, fabricDataRoot, fabricLogRoot); // System drives for path-based settings, exist on target machines

                // Below depend on data system drives
                if (!summary.Passed)
                {
                    SFDeployerTrace.WriteError(StringResources.Error_BPABailing);
                    return(summary);
                }
            }

            summary.DrivesEnoughAvailableSpace = CheckDrivesAvailableSpace(machineHealthContainer, fabricDataRoot, fabricLogRoot);

            // Below depend on root drives having enough space available
            if (!summary.Passed)
            {
                SFDeployerTrace.WriteError(StringResources.Error_BPABailing);
                return(summary);
            }

            summary.IsAllOrNoneIOTDevice = CheckAllIOTDevices(machineHealthContainer);

            // Below depend on all or none machines being IOT Devices
            if (!summary.Passed)
            {
                SFDeployerTrace.WriteError(StringResources.Error_BPABailing);
                return(summary);
            }

            // Check dotnet.exe exists in %Path%
            // Currently we only need to check for IOTCore environment.
            summary.DotNetExeInPath = IsDotNetExeInPath(machineHealthContainer);

            // Below depend on IOT Devices having dotnet.exe in path
            if (!summary.Passed)
            {
                SFDeployerTrace.WriteError(StringResources.Error_BPABailing);
                return(summary);
            }

            summary.MachineHealthContainer = machineHealthContainer;
            LogResult(summary);

            return(summary);
        }