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); }
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); }