コード例 #1
0
        /*
         * TODO: currently AP safe config deployment is not supported to update configurations.
         * The only way to update the configurations is via an application upgrade.
         */
        public static bool GetCurrentConfigurations()
        {
            IConfiguration configuration = APConfiguration.GetConfiguration();

            CertificateManagerRunIntervalSeconds = configuration.GetInt32Value(StringConstants.CertificateManagerConfigurationSectionName, "CertificateManagerRunIntervalSeconds", 3600);

            CertificateManagerRetryIntervalSeconds = configuration.GetInt32Value(StringConstants.CertificateManagerConfigurationSectionName, "CertificateManagerRetryIntervalSeconds", 300);

            EnableSecretStorePersistentCaching = configuration.GetBoolValue(StringConstants.CertificateManagerConfigurationSectionName, "EnableSecretStoreClientSidePersistentCaching", true);

            string logLevelString = configuration.GetStringValue(StringConstants.EnvironmentSyncConfigurationSectionName, "LogLevel", "Info");

            LogLevel logLevel;

            if (!Enum.TryParse <LogLevel>(logLevelString, out logLevel))
            {
                TextLogger.LogError("Log level is invalid : {0}.", logLevelString);

                return(false);
            }

            LogLevel = logLevel;

            return(true);
        }
コード例 #2
0
        /*
         * TODO: currently AP safe config deployment is not supported to update configurations.
         * The only way to update the configurations is via an application upgrade.
         * This is OK since none of the configurations are critical.
         * To update all things critical in Service Fabric Autopilot Agent, an AP application upgrade is needed.
         */
        public static bool GetCurrentConfigurations(bool useTestMode = false)
        {
            if (useTestMode)
            {
                GetTestConfigurations();
            }
            else
            {
                IConfiguration configuration = APConfiguration.GetConfiguration();

                BackgroundStateMachineRunIntervalSeconds = configuration.GetInt32Value(StringConstants.AgentConfigurationSectionName, "BackgroundStateMachineRunIntervalSeconds", 10);

                DeploymentRetryIntervalSeconds = configuration.GetInt32Value(StringConstants.AgentConfigurationSectionName, "DeploymentRetryIntervalSeconds", 120);

                string bootstrapClusterManifestLocationString = configuration.GetStringValue(StringConstants.AgentConfigurationSectionName, "BootstrapClusterManifestLocation", string.Empty);

                BootstrapClusterManifestLocationType bootstrapClusterManifestLocation;
                if (!Enum.TryParse <BootstrapClusterManifestLocationType>(bootstrapClusterManifestLocationString, out bootstrapClusterManifestLocation))
                {
                    TextLogger.LogError("Bootstrap cluster manifest location is invalid or not specified : {0}.", bootstrapClusterManifestLocationString);

                    return(false);
                }

                BootstrapClusterManifestLocation = bootstrapClusterManifestLocation;

                DynamicPortRangeStart = configuration.GetInt32Value(StringConstants.AgentConfigurationSectionName, "DynamicPortRangeStart", -1);

                DynamicPortRangeEnd = configuration.GetInt32Value(StringConstants.AgentConfigurationSectionName, "DynamicPortRangeEnd", -1);

                // please refer to http://support.microsoft.com/kb/929851 for valid dynamic port range in Windows.
                if (DynamicPortRangeStart < 1025 || DynamicPortRangeEnd > 65535 || DynamicPortRangeEnd - DynamicPortRangeStart + 1 < 255)
                {
                    TextLogger.LogError("Dynamic port range is invalid or not specified : [{0}, {1}].", DynamicPortRangeStart, DynamicPortRangeEnd);

                    return(false);
                }

                DynamicTopologyUpdateMode = (DynamicTopologyUpdateMode)configuration.GetInt32Value(StringConstants.AgentConfigurationSectionName, "DynamicTopologyUpdateMode", 0);

                string logLevelString = configuration.GetStringValue(StringConstants.AgentConfigurationSectionName, "LogLevel", "Info");

                LogLevel logLevel;
                if (!Enum.TryParse <LogLevel>(logLevelString, out logLevel))
                {
                    TextLogger.LogError("Log level is invalid : {0}.", logLevelString);

                    return(false);
                }

                LogLevel = logLevel;

                PortFowardingRules = new List <PortFowardingRule>();
                if (configuration.SectionExists(StringConstants.PortForwardingConfigurationSectionName))
                {
                    string[] portFowardingRuleNames = configuration.GetSectionKeys(StringConstants.PortForwardingConfigurationSectionName);

                    if (portFowardingRuleNames != null)
                    {
                        foreach (string portFowardingRuleName in portFowardingRuleNames)
                        {
                            string[] portFowardingRuleComponents = configuration.GetStringValueAndSplit(StringConstants.PortForwardingConfigurationSectionName, portFowardingRuleName, ",");

                            if (portFowardingRuleComponents == null || portFowardingRuleComponents.Length != 3)
                            {
                                TextLogger.LogError("Port forwarding rule {0} is invalid. Valid rule format : RuleName=ListenPort,ConnectPort,MachineFunction", portFowardingRuleName);

                                return(false);
                            }

                            int listenPort;
                            if (!int.TryParse(portFowardingRuleComponents[0], out listenPort) || listenPort <= 0 || listenPort > 65535)
                            {
                                TextLogger.LogError("Port forwarding rule {0} is invalid with invalid listen port {1}. Valid rule format : RuleName=ListenPort,ConnectPort,MachineFunction", portFowardingRuleName, portFowardingRuleComponents[0]);

                                return(false);
                            }

                            int connectPort;
                            if (!int.TryParse(portFowardingRuleComponents[1], out connectPort) || connectPort <= 0 || connectPort > 65535)
                            {
                                TextLogger.LogError("Port forwarding rule {0} is invalid with invalid connect port {1}. Valid rule format : RuleName=ListenPort,ConnectPort,MachineFunction", portFowardingRuleName, portFowardingRuleComponents[1]);

                                return(false);
                            }

                            PortFowardingRules.Add(new PortFowardingRule {
                                RuleName = portFowardingRuleName, ListenPort = listenPort, ConnectPort = connectPort, MachineFunction = portFowardingRuleComponents[2]
                            });
                        }
                    }
                }
            }

            return(true);
        }
コード例 #3
0
        /*
         * Private key certificate files (each private key certificate has an encrypted private key file (.pfx.encr) and an encrypted password file (.pfx.password.encr) ) as well as public key certificate files (i.e. cer files) are part of ServiceFabricEnvironmentSync application packages.
         *
         * All certificates to be installed by ServiceFabricEnvironmentSync need to be listed in the form of "CertificateFriendlyName=CertificateDataDirectory" in certificate section of ServiceFabricEnvironmentSync configuration file.
         *      1) CertificateDataDirectory refers to a relative path from application package root directory.
         *      2) For a public key certificate, CertificateFriendlyName.cer should be present in CertificateDataDirectory.
         *      3) For a private key certificate, CertificateFriendlyName.pfx.encr + CertificateFriendlyName.password.encr should be present in CertificateDataDirectory.
         *
         * All certificates listed would be installed in LocalMachine\My or LocalMachine\CA certificate store.
         *
         * Sample certificate configuration sections
         * [ServiceFabricEnvironmentSync.Certificate.LocalMachine.My]
         *  certA=data\certificates
         *  certB=data\certificates
         *
         * [ServiceFabricEnvironmentSync.Certificate.LocalMachine.CertificateAuthority]
         *  certC=data\certificates
         *  certD=data\certificates
         */
        public bool GetEnvironmentCertificatesFromCurrentConfigurations(StoreName storeName)
        {
            try
            {
                if (storeName != StoreName.My && storeName != StoreName.CertificateAuthority)
                {
                    TextLogger.LogError("Certificate store name {0} is not supported. Supported store names : {1}, {2}.", storeName, StoreName.My, StoreName.CertificateAuthority);

                    return(false);
                }

                string certificateListConfigurationSectionName = string.Format(CultureInfo.InvariantCulture, StringConstants.CertificateListConfigurationSectionNameTemplate, storeName);

                IConfiguration configuration = APConfiguration.GetConfiguration();

                if (configuration != null && configuration.SectionExists(certificateListConfigurationSectionName))
                {
                    string[] certificateFriendlyNames = configuration.GetSectionKeys(certificateListConfigurationSectionName);

                    if (certificateFriendlyNames != null)
                    {
                        foreach (string certificateFriendlyName in certificateFriendlyNames)
                        {
                            string certificateDataDirectoryName = configuration.GetStringValue(certificateListConfigurationSectionName, certificateFriendlyName);

                            string certificateDataDirectory = Path.Combine(this.applicationDirectory, certificateDataDirectoryName);

                            string encryptedPrivateKeyFile = Path.Combine(
                                certificateDataDirectory,
                                string.Format(
                                    CultureInfo.InvariantCulture,
                                    StringConstants.EncryptedPrivateKeyFileNameTemplate,
                                    certificateFriendlyName));

                            bool encryptedPrivateKeyFileExists = File.Exists(encryptedPrivateKeyFile);

                            string encryptedPasswordFile = Path.Combine(
                                certificateDataDirectory,
                                string.Format(
                                    CultureInfo.InvariantCulture,
                                    StringConstants.EncryptedPasswordFileNameTemplate,
                                    certificateFriendlyName));

                            bool encryptedPasswordFileExists = File.Exists(encryptedPasswordFile);

                            string publicKeyFile = Path.Combine(
                                certificateDataDirectory,
                                string.Format(
                                    CultureInfo.InvariantCulture,
                                    StringConstants.PublicKeyFileNameTemplate,
                                    certificateFriendlyName));

                            bool publicKeyFileExists = File.Exists(publicKeyFile);

                            // TODO: report health
                            if (!encryptedPrivateKeyFileExists && !encryptedPasswordFileExists && !publicKeyFileExists)
                            {
                                TextLogger.LogError("Neither encrypted private key & encrypted password files nor public key file exist for certificate {0} in certificate data directory {1}. A certificate to be installed needs to be either a public key certificate or a private key certificate.", certificateFriendlyName, certificateDataDirectory);

                                return(false);
                            }

                            if ((encryptedPrivateKeyFileExists || encryptedPasswordFileExists) && publicKeyFileExists)
                            {
                                TextLogger.LogError("Both encrypted private key & encrypted password files and public key file exist for certificate {0} in certificate data directory {1}. A certificate to be installed needs to be either a public key certificate or a private key certificate but not both.", certificateFriendlyName, certificateDataDirectory);

                                return(false);
                            }

                            if (encryptedPrivateKeyFileExists ^ encryptedPasswordFileExists)
                            {
                                TextLogger.LogError("Only one of encrypted private key file and encrypted password file exist for certificate {0} in certificate data directory {1}. Both are required to install a private key certificate.", certificateFriendlyName, certificateDataDirectory);

                                return(false);
                            }

                            if (publicKeyFileExists)
                            {
                                PublicKeyCertificate publicKeyCertificate;
                                if (!PublicKeyCertificate.TryLoadFromFile(publicKeyFile, out publicKeyCertificate))
                                {
                                    return(false);
                                }

                                if (this.environmentCertificates[storeName].ContainsKey(publicKeyCertificate.Thumbprint) && this.environmentCertificates[storeName][publicKeyCertificate.Thumbprint].HasPrivateKey)
                                {
                                    TextLogger.LogError("Certificate with thumbprint {0}, subject {1} are requested to be installed as both public key certificate and private key certificate in configuration under different entries.", publicKeyCertificate.Thumbprint, publicKeyCertificate.Certificate.Subject);

                                    return(false);
                                }

                                this.environmentCertificates[storeName][publicKeyCertificate.Thumbprint] = publicKeyCertificate;

                                TextLogger.LogInfo("Public key certificate with thumbprint {0}, subject {1} needs to be present in certificate store {2}\\{3} in local environment based on current configurations.", publicKeyCertificate.Thumbprint, publicKeyCertificate.Certificate.Subject, StoreLocation.LocalMachine, storeName);
                            }
                            else
                            {
                                if (storeName == StoreName.CertificateAuthority)
                                {
                                    TextLogger.LogError("Private key certificate {0} cannot be installed in certificate store with name {1}.", certificateFriendlyName, storeName);

                                    return(false);
                                }

                                PrivateKeyCertificate privateKeyCertificate;
                                if (!PrivateKeyCertificate.TryLoadFromFile(encryptedPrivateKeyFile, encryptedPasswordFile, out privateKeyCertificate))
                                {
                                    return(false);
                                }

                                if (this.environmentCertificates[storeName].ContainsKey(privateKeyCertificate.Thumbprint) && !this.environmentCertificates[storeName][privateKeyCertificate.Thumbprint].HasPrivateKey)
                                {
                                    TextLogger.LogError("Certificate with thumbprint {0}, subject {1} are requested to be installed as both public key certificate and private key certificate in configuration under different entries.", privateKeyCertificate.Thumbprint, privateKeyCertificate.Certificate.Subject);

                                    return(false);
                                }

                                this.environmentCertificates[storeName][privateKeyCertificate.Thumbprint] = privateKeyCertificate;

                                TextLogger.LogInfo("Private key certificate with thumbprint {0}, subject {1} needs to be present in certificate store {2}\\{3} in local environment based on current configurations.", privateKeyCertificate.Thumbprint, privateKeyCertificate.Certificate.Subject, StoreLocation.LocalMachine, storeName);
                            }
                        }
                    }
                }

                return(true);
            }
            catch (Exception e)
            {
                TextLogger.LogError("Failed to get environment certificates based on current configurations : {0}", e);

                return(false);
            }
        }