public static IConfigurationBuilder AddCreyConfigurations(this IConfigurationBuilder configurationBuilder, string[] args, string service, string azureDeploymentSlot, KeyVaultPolicy vaultPolicy)
        {
            // extract the minimal info required for early configuration, skip all irrelevant layers
            var earlyConfiguration = new ConfigurationBuilder()
                                     .AddEnvironmentVariables()
                                     .AddEnvironmentVariables("APPSETTING_")
                                     .AddJsonFile("appsettings.json", optional: false)
                                     .AddCommandLine(args)
                                     .Build();

            var deploymentSlot = earlyConfiguration.GetDeploymentSlot();
            var environment    = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "";
            var isCloud        = earlyConfiguration.IsRunningInCloud();

            Console.WriteLine($"Prepare configuration for {service} in {environment} environment for {deploymentSlot}...");
            if (string.IsNullOrEmpty(deploymentSlot))
            {
                throw new Exception("For debug build or tool usage set slot from command line (--DeploymentSlot dev) or from env variable (APPSETTING_DeploymentSlot=\"dev\")");
            }

            // add configuration sources
            configurationBuilder.AddEnvironmentVariables("APPSETTING_");

            // add key vault
            var serviceTruncated          = service.Substring(0, Math.Min(service.Length, 13));
            var slotTruncated             = deploymentSlot.Substring(0, Math.Min(deploymentSlot.Length, 7));
            var sharedKeyVaultAddress     = $"https://crey{slotTruncated}.vault.azure.net/";
            var privateKeyVaultAddress    = $"https://crey{serviceTruncated}{slotTruncated}.vault.azure.net/";
            var azureServiceTokenProvider = new AzureServiceTokenProvider();
            var keyVaultClient            = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));

            keyVaultClient.SetRetryPolicy(new RetryPolicy <HttpRequestExceptionErrorDetectionStrategy>(
                                              new IncrementalRetryStrategy(1000, TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(5.0))));
            if (vaultPolicy == KeyVaultPolicy.Shared || vaultPolicy == KeyVaultPolicy.All)
            {
                configurationBuilder.AddAzureKeyVault(sharedKeyVaultAddress, keyVaultClient, new DefaultKeyVaultSecretManager());
            }
            if (vaultPolicy == KeyVaultPolicy.Private || vaultPolicy == KeyVaultPolicy.All)
            {
                configurationBuilder.AddAzureKeyVault(privateKeyVaultAddress, keyVaultClient, new DefaultKeyVaultSecretManager());
            }

            // add common configs
            configurationBuilder.AddJsonFile("appsettings.common.json", false); // ! mandatory
            configurationBuilder.AddJsonFile($"appsettings.common.{deploymentSlot}.json", true);

            // service specific configs
            configurationBuilder.AddJsonFile("ratelimit.json", true);
            configurationBuilder.AddJsonFile("appsettings.json", false); // ! mandatory, ex: contains changeset
            configurationBuilder.AddJsonFile($"appsettings.logging.json", true);
            configurationBuilder.AddJsonFile($"appsettings.{deploymentSlot}.json", true);

            //add deprecated configs, service names are removed
            configurationBuilder.AddJsonFile($"appsettings.{service}.json", true)
            .AddJsonFile($"appsettings.logging.{service}.json", true)
            .AddJsonFile($"appsettings.{service}.{deploymentSlot}.json", true)
            .AddJsonFile($"appsettings.logging.{service}.{deploymentSlot}.json", true);

            //local and temp overrides (ex debug and cmd line arguments)
            if (!isCloud)
            {
                configurationBuilder.AddJsonFile($"appsettings.local.json", true);
            }
            configurationBuilder.AddCommandLine(args);

            var completeConfiguration = configurationBuilder.Build();

            if (deploymentSlot != completeConfiguration.GetDeploymentSlot())
            {
                throw new Exception("Early configuration refers to a different slot");
            }
            completeConfiguration.ValidateConfiguration(azureDeploymentSlot);

            return(configurationBuilder);
        }
Пример #2
0
        public static IConfigurationBuilder ConfigureService(this IConfigurationBuilder configurationBuilder, string[] args, IWebHostBuilder webHost, string service, string azureDeploymentSlot, KeyVaultPolicy vaultPolicy)
        {
            var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "";

            configurationBuilder.AddEnvironmentVariables("APPSETTING_");
            configurationBuilder.AddJsonFile("ratelimit.json", true);

            configurationBuilder.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
            configurationBuilder.AddCommandLine(args);

            var    earlyConfiguration = configurationBuilder.Build();
            string slot                   = earlyConfiguration.GetDeploymentSlot();
            string serviceTruncated       = service.Substring(0, Math.Min(service.Length, 13));
            string slotTruncated          = slot.Substring(0, Math.Min(slot.Length, 7));
            string sharedKeyVaultAddress  = $"https://crey{slotTruncated}.vault.azure.net/";
            string privateKeyVaultAddress = $"https://crey{serviceTruncated}{slotTruncated}.vault.azure.net/";

            var azureServiceTokenProvider = new AzureServiceTokenProvider();
            var keyVaultClient            = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));

            keyVaultClient.SetRetryPolicy(new RetryPolicy <HttpRequestExceptionErrorDetectionStrategy>(
                                              new IncrementalRetryStrategy(1000, TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(5.0))));
            if (vaultPolicy == KeyVaultPolicy.Shared || vaultPolicy == KeyVaultPolicy.All)
            {
                configurationBuilder.AddAzureKeyVault(sharedKeyVaultAddress, keyVaultClient, new DefaultKeyVaultSecretManager());
            }
            if (vaultPolicy == KeyVaultPolicy.Private || vaultPolicy == KeyVaultPolicy.All)
            {
                configurationBuilder.AddAzureKeyVault(privateKeyVaultAddress, keyVaultClient, new DefaultKeyVaultSecretManager());
            }


            // CHECK: ASP.NET provides intialized DiagnosticListener - use it instead of console if Console is always presented
            // OR add Console sink in basic startup (it may log into ASP.NET startup file sink either)
            Console.WriteLine($"Building configuration for {service} in {environment} environment...");
            var configuration = configurationBuilder.Build();

            if (string.IsNullOrEmpty(configuration.GetDeploymentSlot()))
            {
                throw new Exception("For debug build or tool usage set slot from command line (--DeploymentSlot dev) or from env varibale (APPSETTING_DeploymentSlot=\"dev\")");
            }

            var deploymentSlot     = configuration.GetDeploymentSlot();
            var normalizedSlotName = deploymentSlot.ToString().ToLower();

            bool isRunningInCloud      = configuration.IsRunningInCloud();
            var  coreLoggingConfig     = "Core/appsettings.logging.json";
            var  coreSlotLoggingConfig = $"Core/appsettings.logging.{normalizedSlotName}.json";

            if (isRunningInCloud)
            {
                configurationBuilder.AddJsonFile(coreLoggingConfig, true);
                configurationBuilder.AddJsonFile(coreSlotLoggingConfig, true);
            }
            else
            {
                if (webHost != null && environment == ConfigurationExtensions.LocalEnvironment)
                {
                    SetupLocalCertificationSettings(webHost);
                }

                var current = Directory.GetCurrentDirectory();
                var path    = current + $"/../../tmp/secrets/{service}/appsettings.{normalizedSlotName}.json";
                configurationBuilder.AddJsonFile(path, true);

                configurationBuilder.AddJsonFile(Path.Combine(current, "../Core/Core/", coreLoggingConfig), true);
                configurationBuilder.AddJsonFile(Path.Combine(current, "../Core/Core/", coreSlotLoggingConfig), true);
            }

            // allow overrides: 0. core (above) 1. per slot (above) 2. per service tuning. 3. per service and slot
            configurationBuilder.AddJsonFile($"appsettings.logging.{service}.json", true);
            configurationBuilder.AddJsonFile($"appsettings.logging.{service}.{normalizedSlotName}.json", true);

            var completeConfiguration = configurationBuilder.Build();

            completeConfiguration.ValidateConfiguration(azureDeploymentSlot);
            return(configurationBuilder);
        }