private async Task AddNodesAsync(string clusterManifestPath, string destinationPackagePath, List <string> machines, List <NodeDescription> addedNodes)
        {
            UpgradeOrchestrationTrace.TraceSource.WriteInfo(TraceType, "Configuring nodes started.");
            await DeploymentManagerInternal.ConfigureNodesAsync(
                new MachineHealthContainer(machines),
                clusterManifestPath,
                null,
                null,
                null,
                null,
                FabricPackageType.XCopyPackage,
                destinationPackagePath,
                null).ConfigureAwait(false);

            Parallel.ForEach(
                addedNodes,
                async(NodeDescription node) =>
            {
                if (machines.Any(machine => machine == node.IPAddress))
                {
                    DeploymentManagerInternal.StartAndWaitForInstallerService(node.IPAddress);
                    UpgradeOrchestrationTrace.TraceSource.WriteInfo("Re-enabling the node {0}.", node.NodeName);
                    await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync(
                        () =>
                        this.fabricClient.ClusterManager.ActivateNodeAsync(node.NodeName, Constants.FabricQueryTimeoutInMinutes, this.cancellationToken),
                        Constants.FabricQueryRetryTimeoutInMinutes,
                        this.cancellationToken).ConfigureAwait(false);
                }
            });

            await this.PollAddedNodesActivatedAsync(addedNodes).ConfigureAwait(false);
        }
        internal async Task PerformAddNodeOperationGMSAAsync(List <NodeDescription> addedNodes, FabricClient fabricClient, List <NodeTypeDescription> allNodeTypes)
        {
            string destinationPackagePath = await this.DownloadProvisionedPackage().ConfigureAwait(false);

            var nodesFromFM = await StandaloneUtility.GetNodesFromFMAsync(fabricClient, this.cancellationToken).ConfigureAwait(false);

            string clusterManifestPath = await this.GenerateClusterManifestWithAddedNodes(addedNodes, nodesFromFM, allNodeTypes);

            List <string> machines = new List <string>();

            foreach (var addednode in addedNodes)
            {
                if (!nodesFromFM.Any(nodeFromFM => nodeFromFM.NodeName == addednode.NodeName))
                {
                    machines.Add(addednode.IPAddress);
                }
            }

            bool             successfulRun = true;
            List <Exception> exceptions    = new List <Exception>();

            try
            {
                await this.AddNodesAsync(clusterManifestPath, destinationPackagePath, machines, addedNodes);
            }
            catch (Exception ex)
            {
                successfulRun = false;
                exceptions.Add(ex);
                UpgradeOrchestrationTrace.TraceSource.WriteError("Adding nodes failed with exception {0}.", ex.ToString());
            }

            if (!successfulRun)
            {
                // Best-Effort Rollback
                try
                {
                    await DeploymentManagerInternal.RemoveNodeConfigurationAsync(machines, false, FabricPackageType.XCopyPackage, true);
                }
                catch (Exception ex)
                {
                    UpgradeOrchestrationTrace.TraceSource.WriteError("Rollback failed with {0}.", ex.ToString());
                    exceptions.Add(ex);
                }

                AggregateException ae = new AggregateException(exceptions);
                throw ae;
            }

            this.CleanUp(clusterManifestPath, destinationPackagePath);
            UpgradeOrchestrationTrace.TraceSource.WriteInfo("Nodes were succesfully added to the GMSA secured cluster");
        }
Esempio n. 3
0
 public static async Task AddNodeAsync(
     string nodeName,
     string nodeType,
     string ipAddressOrFqdn,
     string upgradeDomain,
     string faultDomain,
     string fabricRuntimePackagePath,
     FabricClient fabricClient)
 {
     await DeploymentManagerInternal.AddNodeAsyncInternal(
         nodeName,
         nodeType,
         ipAddressOrFqdn,
         upgradeDomain,
         faultDomain,
         fabricRuntimePackagePath,
         fabricClient).ConfigureAwait(false);
 }
Esempio n. 4
0
        public void DeploymentManagerTest_ValidateOptionalCertificateIssuerThumbprint()
        {
            string clusterConfigPath   = Path.Combine(BaseDir, JsonConfigX509SecureOptionalIssuerTPOct2017Filename);
            string clusterManifestPath = Path.Combine(Path.GetTempPath(), "cmtest.xml");
            var    clusterResource     = DeploymentManagerInternal.GetClusterResource(clusterConfigPath, System.Guid.NewGuid().ToString());
            var    cm = clusterResource.Current.ExternalState.ClusterManifest;

            Assert.IsNotNull(cm, "Cluster manifest was null.");
            XMLHelper.WriteXmlExclusive <ClusterManifestType>(clusterManifestPath, cm);
            Assert.IsTrue(File.Exists(clusterManifestPath), "Cluster manifest was not written.");

            ClusterManifestType manifest = XMLHelper.ReadClusterManifest(clusterManifestPath);

            Assert.IsNotNull(manifest, "Cluster manifest was null.");
            var fabricSettings             = manifest.FabricSettings;
            var securityAdminClientSetting = fabricSettings.Where <SettingsOverridesTypeSection>(p => p.Name == StringConstants.SectionName.SecurityAdminClientX509Names).First();

            foreach (var param in securityAdminClientSetting.Parameter)
            {
                Assert.IsNotNull(param.Value, param.Name + " Value was null");
            }

            var securityClusterSetting = fabricSettings.Where <SettingsOverridesTypeSection>(p => p.Name == StringConstants.SectionName.SecurityClusterX509Names).First();

            foreach (var param in securityClusterSetting.Parameter)
            {
                Assert.IsNotNull(param.Value, param.Name + " Value was null");
            }

            var securityServerSetting = fabricSettings.Where <SettingsOverridesTypeSection>(p => p.Name == StringConstants.SectionName.SecurityServerX509Names).First();

            foreach (var param in securityServerSetting.Parameter)
            {
                Assert.IsNotNull(param.Value, param.Name + " Value was null");
            }

            var securityClientSetting = fabricSettings.Where <SettingsOverridesTypeSection>(p => p.Name == StringConstants.SectionName.SecurityClientX509Names).First();

            foreach (var param in securityClientSetting.Parameter)
            {
                Assert.IsNotNull(param.Value, param.Name + " Value was null");
            }
        }
Esempio n. 5
0
 /// <summary>
 /// Creates a Service Fabric cluster based on an input JSON configuration file and Service Fabric runtime package CAB file.
 /// </summary>
 /// <param name="clusterConfigPath">Specifies the path to the JSON cluster configuration file where you define the cluster nodes & configuration settings. Templates are provided in the Standalone deployment package.</param>
 /// <param name="fabricRuntimePackagePath">Specifies the path to Service Fabric runtime package CAB file.</param>
 /// <param name="creationOptions">Options for cluster creation.</param>
 /// <param name="maxPercentFailedNodes">Maximum percentage of nodes allowed to fail during cluster creation. If more than this percentage of nodes fail, the cluster creation will fail and roll back. Default value is 0 percent.</param>
 /// <param name="timeout">Timeout for cluster creation. Default value null means there is no timeout for the creation process.</param>
 public static async Task CreateClusterAsync(
     string clusterConfigPath,
     string fabricRuntimePackagePath,
     ClusterCreationOptions creationOptions = ClusterCreationOptions.None,
     int maxPercentFailedNodes = 0,
     TimeSpan?timeout          = null)
 {
     await DeploymentManagerInternal.CreateClusterAsyncInternal(
         clusterConfigPath,
         null,
         null,
         true,
         FabricPackageType.XCopyPackage,
         fabricRuntimePackagePath,
         null,
         creationOptions,
         maxPercentFailedNodes,
         timeout).ConfigureAwait(false);
 }
Esempio n. 6
0
        public void DeploymentManagerTest_ConvertJsonToXml()
        {
            Console.WriteLine("Current directory: {0}", Environment.CurrentDirectory);
            string clusterConfigPath = Path.Combine(BaseDir, JsonConfigUnsecureJan2017Filename);

            Directory.SetCurrentDirectory(BaseDir);
            Console.WriteLine("New current directory changed to: {0}", Environment.CurrentDirectory);
            Assert.IsTrue(File.Exists(clusterConfigPath), string.Format("Config file {0} did not exist.", clusterConfigPath));
            string clusterManifestPath = Path.Combine(Path.GetTempPath(), "cmtest.xml");
            var    clusterResource     = DeploymentManagerInternal.GetClusterResource(clusterConfigPath, System.Guid.NewGuid().ToString());
            var    cm = clusterResource.Current.ExternalState.ClusterManifest;

            Assert.IsNotNull(cm, "Cluster manifest was null.");
            XMLHelper.WriteXmlExclusive <ClusterManifestType>(clusterManifestPath, cm);
            Assert.IsTrue(File.Exists(clusterManifestPath), "Cluster manifest was not written.");
            List <string> machines = StandaloneUtility.GetMachineNamesFromClusterManifest(clusterManifestPath);

            Assert.IsNotNull(machines);
            Assert.IsTrue(machines.Count > 0, "Cluster manifest was not written correctly. Machines missing.");
        }
Esempio n. 7
0
        public void DeploymentManagerTest_ValidateJsonConfigIssuerCertStoreOctober2017()
        {
            string clusterConfigPath = Path.Combine(BaseDir, JsonConfigX509SecureIssuerCNOct2017Filename);
            var    configModel       = StandAloneInstallerJsonModelBase.GetJsonConfigFromFile(clusterConfigPath);

            Assert.IsTrue(File.Exists(clusterConfigPath), string.Format("Config file {0} did not exist.", clusterConfigPath));
            Assert.IsNotNull(configModel, "JSON config was invalid.");

            var userConfig = configModel.GetUserConfig();

            Assert.IsTrue(userConfig.Security.CertificateInformation.ClusterCertificateIssuerStores.Count() == 2, "ClusterCertificateIssuerStore count should be 2.");
            Assert.IsTrue(userConfig.Security.CertificateInformation.ServerCertificateIssuerStores.Count() == 1, "ServerCertificateIssuerStore count should be 1.");
            Assert.IsTrue(userConfig.Security.CertificateInformation.ClientCertificateIssuerStores.Count() == 1, "ClientCertificateIssuerStore count should be 1.");

            var clusterResource = DeploymentManagerInternal.GetClusterResource(clusterConfigPath, System.Guid.NewGuid().ToString());
            var cm = clusterResource.Current.ExternalState.ClusterManifest;
            var clusterCertificateIssuerStore = cm.FabricSettings.ToList().Where(section => section.Name == StringConstants.SectionName.SecurityClusterCertificateIssuerStores).ToList();

            Assert.IsTrue(clusterCertificateIssuerStore.Count() == 1, "clusterCertificateIssuerStore count should be 1");
            Assert.IsTrue(clusterCertificateIssuerStore[0].Parameter.ToList().Count == 2, "clusterCertificateIssuerStore parameter count should be 2");
            Assert.AreEqual(clusterCertificateIssuerStore[0].Parameter[0].Name, "");
            Assert.AreEqual(clusterCertificateIssuerStore[0].Parameter[0].Value, "My");
            Assert.AreEqual(clusterCertificateIssuerStore[0].Parameter[1].Name, "ClusterIssuer");
            Assert.AreEqual(clusterCertificateIssuerStore[0].Parameter[1].Value, "My, Root");

            var serverCertificateIssuerStore = cm.FabricSettings.ToList().Where(section => section.Name == StringConstants.SectionName.SecurityServerCertificateIssuerStores).ToList();

            Assert.IsTrue(serverCertificateIssuerStore.Count() == 1, "serverCertificateIssuerStore count should be 1");
            Assert.IsTrue(serverCertificateIssuerStore[0].Parameter.ToList().Count == 1, "serverCertificateIssuerStore parameter count should be 1");
            Assert.AreEqual(serverCertificateIssuerStore[0].Parameter[0].Name, "ServerIssuer");
            Assert.AreEqual(serverCertificateIssuerStore[0].Parameter[0].Value, "My");

            var clientCertificateIssuerStore = cm.FabricSettings.ToList().Where(section => section.Name == StringConstants.SectionName.SecurityClientCertificateIssuerStores).ToList();

            Assert.IsTrue(clientCertificateIssuerStore.Count() == 1, "clientCertificateIssuerStore count should be 1");
            Assert.IsTrue(clientCertificateIssuerStore[0].Parameter.ToList().Count == 1, "clientCertificateIssuerStore parameter count should be 1");
            Assert.AreEqual(clientCertificateIssuerStore[0].Parameter[0].Name, "ClientIssuer");
            Assert.AreEqual(clientCertificateIssuerStore[0].Parameter[0].Value, "My");
        }
Esempio n. 8
0
        protected void TestConfig(string clusterConfigPath, string oldClusterConfigPath, string fabricPackagePath, int maxPercentFailedNodes)
        {
            this.ChangeCurrentDirectoryToSession();

            if (string.IsNullOrWhiteSpace(fabricPackagePath))
            {
                fabricPackagePath = null;
            }

            clusterConfigPath    = this.GetAbsolutePath(clusterConfigPath);
            oldClusterConfigPath = this.GetAbsolutePath(oldClusterConfigPath);
            fabricPackagePath    = this.GetAbsolutePath(fabricPackagePath);
            AnalysisSummary summary = DeploymentManagerInternal.BpaAnalyzeClusterSetup(clusterConfigPath, oldClusterConfigPath, fabricPackagePath, maxPercentFailedNodes);

            this.WriteObject(this.FormatOutput(summary));
            if (!summary.Passed)
            {
                this.ThrowTerminatingError(
                    new InvalidOperationException(StringResources.Error_BPABailing),
                    Constants.TestClusterConfigurationErrorId,
                    null);
            }
        }
Esempio n. 9
0
        public void CreateClusterManifest()
        {
            string jsonConfigPath = Path.Combine(Utility.TestDirectory, "ClusterConfig.Unsecure.DevCluster.json");

            Assert.IsTrue(System.IO.File.Exists(jsonConfigPath), string.Format("JSON config file {0} did not exist.", jsonConfigPath));
            var clusterResource = DeploymentManagerInternal.GetClusterResource(jsonConfigPath, System.Guid.NewGuid().ToString());
            var cm = clusterResource.Current.ExternalState.ClusterManifest;

            Assert.IsNotNull(cm, "Cluster manifest was null.");
            var settings = new XmlWriterSettings {
                Indent = true
            };

            using (var fs = new FileStream("ClusterManifest.xml", FileMode.Create))
            {
                using (var writer = XmlWriter.Create(fs, settings))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(ClusterManifestType));
                    serializer.Serialize(writer, cm);
                }
                fs.Close(); // Explicit close to reduce races.
            }
        }
Esempio n. 10
0
 protected void RemoveNode()
 {
     this.ChangeCurrentDirectoryToSession();
     DeploymentManagerInternal.RemoveNodeAsyncInternal(GetClusterConnection().FabricClient).Wait();
 }
Esempio n. 11
0
        public static FileInfo GetClusterManifestFromJsonConfig(string clusterConfigPath, string clusterName, string version)
        {
            var clusterResource = DeploymentManagerInternal.GetClusterResource(clusterConfigPath, System.Guid.NewGuid().ToString());

            return(StandaloneUtility.ClusterManifestToFile(clusterResource.Current.ExternalState.ClusterManifest, clusterName, version));
        }
Esempio n. 12
0
 /// <summary>
 /// Removes a Service Fabric cluster based on input JSON cluster configuration file.
 /// </summary>
 /// <param name="clusterConfigPath">Specifies the path to the JSON cluster configuration file where you define the cluster nodes & configuration settings. Templates are provided in the Standalone deployment package.</param>
 /// <param name="deleteLog">Determines whether operation cleans up Fabric logs as part of removal.</param>
 public static async Task RemoveClusterAsync(string clusterConfigPath, bool deleteLog)
 {
     await DeploymentManagerInternal.RemoveClusterAsyncInternal(clusterConfigPath, deleteLog, true, FabricPackageType.XCopyPackage)
     .ConfigureAwait(false);
 }
Esempio n. 13
0
 /// <summary>
 /// Gets all upgrade compatible runtime versions for the provided base version from the goal state file .
 /// </summary>
 /// <param name="baseVersion">Specifies the base version to retrieve all compatible versions.</param>
 public static List <RuntimePackageDetails> GetUpgradeableRuntimeVersions(
     string baseVersion)
 {
     return(DeploymentManagerInternal.GetUpgradeableRuntimeVersions(
                baseVersion));
 }
Esempio n. 14
0
 /// <summary>
 /// Gets all available Runtime versions from the Goal State File.
 /// </summary>
 /// <param name="DownloadableRuntimeVersionsReturnSet">Specifies the kind of Runtime version to be returned - All, Supported or Latest</param>
 public static List <RuntimePackageDetails> GetDownloadableRuntimeVersions(
     DownloadableRuntimeVersionReturnSet returnSet = DownloadableRuntimeVersionReturnSet.Supported)
 {
     return(DeploymentManagerInternal.GetDownloadableRuntimeVersions(
                returnSet));
 }
Esempio n. 15
0
 public static async Task RemoveNodeAsync(FabricClient fabricClient)
 {
     await DeploymentManagerInternal.RemoveNodeAsyncInternal(fabricClient).ConfigureAwait(false);
 }
Esempio n. 16
0
        internal void ConvertDevJsonToXml_Utility(int expectedReplicaSize, string inputFile, string outputFile, string sectionToChangeWin7, bool isSecure = false, bool testOverride = false)
        {
            Console.WriteLine("Current directory: {0}", Environment.CurrentDirectory);
            string clusterConfigPath = Path.Combine(DevJsonModelTest.BaseDir, inputFile);

            Directory.SetCurrentDirectory(DevJsonModelTest.BaseDir);
            Console.WriteLine("New current directory changed to: {0}", Environment.CurrentDirectory);
            string clusterManifestPath = Path.Combine(Path.GetTempPath(), outputFile);
            var    clusterResource     = DeploymentManagerInternal.GetClusterResource(clusterConfigPath, System.Guid.NewGuid().ToString());
            var    cm = clusterResource.Current.ExternalState.ClusterManifest;

            Assert.IsNotNull(cm, "Cluster manifest was null.");

            File.Delete(clusterManifestPath);
            XMLHelper.WriteXmlExclusive <ClusterManifestType>(clusterManifestPath, cm);
            List <string> machines = StandaloneUtility.GetMachineNamesFromClusterManifest(clusterManifestPath);

            Assert.IsNotNull(machines);

            Assert.AreEqual(expectedReplicaSize, ((WindowsInfrastructureType)cm.Infrastructure.Item).NodeList.ToList().Where(node => node.IsSeedNode).Count());

            if (isSecure)
            {
                Assert.AreEqual(InputEndpointTypeProtocol.https, cm.NodeTypes[0].Endpoints.HttpGatewayEndpoint.Protocol);
                Assert.IsNotNull(cm.NodeTypes[0].Certificates.ClientCertificate, "Client certificate was null.");
            }

            foreach (SettingsOverridesTypeSection setting in cm.FabricSettings)
            {
                Assert.IsTrue(IsSectionAllowed(cm.NodeTypes.Count(), setting.Name));
                if (setting.Name == StringConstants.SectionName.Setup)
                {
                    foreach (SettingsOverridesTypeSectionParameter param in setting.Parameter)
                    {
                        Assert.AreNotEqual(StringConstants.ParameterName.IsDevCluster, param.Name);
                        if (param.Name == StringConstants.ParameterName.FabricDataRoot)
                        {
                            Assert.AreEqual(Environment.ExpandEnvironmentVariables("%systemdrive%\\SfDevCluster\\Data"), param.Value);
                        }
                    }
                }
                if (setting.Name == StringConstants.SectionName.ClusterManager)
                {
                    SettingsOverridesTypeSectionParameter TargetReplicaSetSizeParam = setting.Parameter.FirstOrDefault(x => x.Name == StringConstants.ParameterName.TargetReplicaSetSize);
                    Assert.IsNotNull(TargetReplicaSetSizeParam, "Cannot find TargetReplicaSetSize for Cluster Manager");
                    Assert.AreEqual(expectedReplicaSize.ToString(), TargetReplicaSetSizeParam.Value);
                }
                if (DevJsonModel.IsWin7() && setting.Name == sectionToChangeWin7)
                {
                    SettingsOverridesTypeSectionParameter isEnabledParam = setting.Parameter.FirstOrDefault(x => x.Name == StringConstants.ParameterName.IsEnabled);
                    Assert.IsNotNull(isEnabledParam, "Cannot find isEnabled for " + sectionToChangeWin7);
                    Assert.AreEqual("false", isEnabledParam.Value);
                }
                if (setting.Name == StringConstants.SectionName.Diagnostics && testOverride)
                {
                    SettingsOverridesTypeSectionParameter isEnabledTraceSessionParam = setting.Parameter.FirstOrDefault(x => x.Name == StringConstants.ParameterName.EnableCircularTraceSession);
                    Assert.IsNotNull(isEnabledTraceSessionParam, "Cannot find isEnabled for EnableCircularTraceSession");
                    Assert.AreEqual("false", isEnabledTraceSessionParam.Value);
                }
                if (setting.Name == StringConstants.SectionName.FailoverManager && expectedReplicaSize == 1)
                {
                    SettingsOverridesTypeSectionParameter IsSingletonReplicaMoveAllowedDuringUpgradeParam = setting.Parameter.FirstOrDefault(x => x.Name == StringConstants.ParameterName.IsSingletonReplicaMoveAllowedDuringUpgrade);
                    Assert.IsNotNull(IsSingletonReplicaMoveAllowedDuringUpgradeParam, "Cannot find isEnabled for EnableCircularTraceSession");
                    Assert.AreEqual("false", IsSingletonReplicaMoveAllowedDuringUpgradeParam.Value);
                }
            }

            //DevCluster should have one distinct IPaddress, i.e. localhost
            Assert.AreEqual(1, machines.Count);
        }