Example #1
0
        public static IConfigurationBuilder UseAzureAppConfiguration(this IConfigurationBuilder builder)
        {
            if (AzureAppConfiguration.UseConnectionString)
            {
                builder.AddAzureAppConfiguration(AzureAppConfigurationSetup.WithConnectionString);
            }
            else
            {
                builder.AddAzureAppConfiguration(AzureAppConfigurationSetup.WithManagedIdentity);
            }

            return(builder);
        }
        public static void AddSharedAppConfiguration(this IConfigurationBuilder builder)
        {
            var config            = builder.Build();
            var appConfigEndpoint =
                config.GetValue <string>(ProspaConstants.SharedConfigurationKeys.SharedAzureAppConfigurationEndpoint);

            if (string.IsNullOrWhiteSpace(appConfigEndpoint))
            {
                throw new Exception(
                          $"Missing App Configuration, Key: {ProspaConstants.SharedConfigurationKeys.SharedAzureAppConfigurationEndpoint}");
            }

            var credentials = ProspaConstants.Environments.IsDevelopment
                ? new DefaultAzureCredential()
                : (TokenCredential) new ManagedIdentityCredential();

            builder.AddAzureAppConfiguration(
                options =>
            {
                options.Connect(new Uri(appConfigEndpoint), credentials);
                options.ConfigureKeyVault(kv => kv.SetCredential(credentials));
                options.Select("SHARED:*");
                options.TrimKeyPrefix("SHARED:");
            });
        }
        public static IConfigurationBuilder UseAzureAppConfiguration(this IConfigurationBuilder builder)
        {
            Action <AzureAppConfigurationOptions> setupConfig = AzureAppConfiguration.UseConnectionString switch
            {
                true => options => options.Connect(AzureAppConfiguration.ConnectionString),
                false => options => options.Connect(new Uri(AzureAppConfiguration.ManagedIdentityEndpoint), new ManagedIdentityCredential())
            };

            builder.AddAzureAppConfiguration(options =>
            {
                setupConfig(options);

                if (AzureAppConfiguration.UseCacheExpiration)
                {
                    options.ConfigureRefresh(config =>
                    {
                        config.SetCacheExpiration(TimeSpan.FromSeconds(AzureAppConfiguration.CacheExpiration));
                    });
                }

                if (AzureAppConfiguration.UseLabel)
                {
                    options.Select(KeyFilter.Any, AzureAppConfiguration.Label);
                }
                ;
            });

            return(builder);
        }
    }
Example #4
0
        public static IConfigurationBuilder AddConfigurationService(this IConfigurationBuilder configurationBuilder, string connectionString = null)
        {
            if (configurationBuilder is null)
            {
                throw new ArgumentNullException(nameof(configurationBuilder));
            }

            if (string.IsNullOrEmpty(connectionString))
            {
                connectionString = configurationBuilder.Build().GetConnectionString("ConfigurationService");
            }

            if (string.IsNullOrEmpty(connectionString))
            {
                throw new InvalidOperationException("Unable to add configuration service without connection string ('ConfigurationService')");
            }

            var connectionStringExpanded = Environment.ExpandEnvironmentVariables(connectionString);

            if (Uri.IsWellFormedUriString(connectionStringExpanded, UriKind.Absolute))
            {
                var configurationServiceFile = new Uri(connectionStringExpanded, UriKind.Absolute);

                if (!configurationServiceFile.IsFile)
                {
                    throw new NotSupportedException($"Scheme '{configurationServiceFile.Scheme}' is not supported - use file:// instead");
                }

                return(configurationBuilder.AddJsonFile(configurationServiceFile.LocalPath, false, true));
            }
            else
            {
                return(configurationBuilder.AddAzureAppConfiguration(connectionString, false));
            }
        }
Example #5
0
        public static IConfigurationBuilder AddAzureAppConfiguration(this IConfigurationBuilder builder, AzureAppConfigurationExtendedOptions extendedOptions)
        {
            Action <AzureAppConfigurationOptions> setupConfig = extendedOptions.UseConnectionString switch
            {
                true => options => options.Connect(extendedOptions.ConnectionString),
                false => options => options.Connect(extendedOptions.Endpoint,
                                                    new ManagedIdentityCredential(extendedOptions.ClientId))
            };

            builder.AddAzureAppConfiguration(options =>
            {
                setupConfig(options);

                if (extendedOptions.UseCacheExpiration)
                {
                    options.ConfigureRefresh(config =>
                    {
                        config.SetCacheExpiration(TimeSpan.FromSeconds(extendedOptions.CacheExpiration));
                    });
                }

                foreach (var label in extendedOptions.Labels)
                {
                    options.Select(KeyFilter.Any, label);
                }
            });

            return(builder);
        }
    }
Example #6
0
        private static void LoadConfiguration(IConfigurationBuilder configBuilder)
        {
            //
            // This application attempts to connect to Azure App Configuration to retrieve Azure Blob Storage name, and Queue Name for the Azure Web Job.
            // It reads the ConnectionString for the App Configuration Service from environment variables.
            configBuilder.AddEnvironmentVariables();

            var config = configBuilder.Build();

            if (string.IsNullOrEmpty(config["ConnectionString"]))
            {
                throw new ArgumentNullException("Please set the 'ConnectionString' environment variable to a valid Azure App Configuration connection string and re-run this example.");
            }

            configBuilder.AddAzureAppConfiguration(options =>
            {
                options.Connect(config["ConnectionString"])
                .Use("WebJob:*")
                .TrimKeyPrefix("WebJob:");
            });

            config = configBuilder.Build();

            if (string.IsNullOrEmpty(config["AzureWebJobsStorage"]))
            {
                throw new ArgumentNullException("AzureWebJobsStorage not found.");
            }
            else if (string.IsNullOrEmpty(config["QueueName"]))
            {
                throw new ArgumentNullException("QueueName not found.");
            }
        }
Example #7
0
        public static IConfigurationBuilder AddCatalogueScannerAzureAppConfiguration(this IConfigurationBuilder configurationBuilder, string connectionString, out Func <IConfigurationRefresher> refresherSupplier)
        {
            IConfigurationRefresher?refresher = null;

            configurationBuilder.AddAzureAppConfiguration(options =>
            {
                options.Connect(connectionString)
                // Load all keys that start with `CatalogueScanner:`
                .Select("CatalogueScanner:*")
                // Configure to reload configuration if the registered 'Sentinel' key is modified
                .ConfigureRefresh(refreshOptions =>
                                  refreshOptions.Register(ConfigurationConstants.SentinelKey, refreshAll: true)
                                  );

                refresher = options.GetRefresher();
            });

            refresherSupplier = () =>
            {
                if (refresher is null)
                {
                    throw new InvalidOperationException($"{nameof(IConfigurationRefresher)} hasn't been created yet");
                }
                return(refresher);
            };

            return(configurationBuilder);
        }
Example #8
0
 /// <summary>
 /// Adds key-value data from an Azure App Configuration store to a configuration builder.
 /// </summary>
 /// <param name="configurationBuilder">The configuration builder to add key-values to.</param>
 /// <param name="connectionString">The connection string used to connect to the configuration store.</param>
 /// <param name="optional">Determines the behavior of the App Configuration provider when an exception occurs. If false, the exception is thrown. If true, the exception is suppressed and no settings are populated from Azure App Configuration.</param>
 /// <returns>The provided configuration builder.</returns>
 public static IConfigurationBuilder AddAzureAppConfiguration(
     this IConfigurationBuilder configurationBuilder,
     string connectionString,
     bool optional = false)
 {
     return(configurationBuilder.AddAzureAppConfiguration(options => options.Connect(connectionString), optional));
 }
Example #9
0
        public static void AddAzureConfigAndKeyvault(this IConfigurationBuilder config, WebHostBuilderContext hostingContext)
        {
            var settings = config.Build();

            var credentials = new DefaultAzureCredential();

            config.AddAzureAppConfiguration(options =>
            {
                try
                {
                    options
                    .Connect(new Uri(settings["AppConfig:Endpoint"]), credentials)
                    .Select(KeyFilter.Any, LabelFilter.Null)
                    .Select(KeyFilter.Any, hostingContext.HostingEnvironment.EnvironmentName)
                    .ConfigureKeyVault(kv =>
                    {
                        kv.SetCredential(credentials);
                    });
                }
                catch (AuthenticationFailedException e)
                {
                    Console.WriteLine($"Authentication Failed. {e.Message}");
                }
            });
        }
        private static void ConfigureAzureAppConfiguration(WebHostBuilderContext hostingContext, IConfigurationBuilder config)
        {
            const string DefaultConfigurationSettingsLabel = "Default";
            string       environmentName = hostingContext.HostingEnvironment.EnvironmentName;

            var settings = config.Build();

            config.AddAzureAppConfiguration(o => o.Connect(settings["connectionStrings.AppConfiguration"])
                                            .ConfigureKeyVault(kv => { kv.SetCredential(new DefaultAzureCredential()); })
                                            .Select(KeyFilter.Any, labelFilter: DefaultConfigurationSettingsLabel)
                                            .Select(KeyFilter.Any, environmentName)
                                            .ConfigureRefresh(refresh => { refresh.Register("BLOG:blogSection:configVersion", label: DefaultConfigurationSettingsLabel, refreshAll: true); }));
        }
        internal static void AddSettings(this IConfigurationBuilder builder)
        {
            builder.AddJsonFile("appsettings.json", false);
            string endPoint = builder.Build().GetValue <string>("ConfigEndpoint");

            var managedIdentityCredential = new DefaultAzureCredential();

            builder.AddAzureAppConfiguration(
                options =>
                options.Connect(
                    new Uri(endPoint), managedIdentityCredential)
                .ConfigureKeyVault(kv => kv.SetCredential(managedIdentityCredential)))
            .Build();
        }
Example #12
0
        private static void ConfigureAzureAppConfiguration(ref IConfigurationBuilder config)
        {
            // For the production environment, we are going to use
            //Azure App Configuration as our provider of (1) App Configuration and (2) Feature Flags

            if (HostingEnvironment.IsProduction())
            {
                var settings = config.Build();

                var connectionString = settings["AzureAppConfigurationConnectionString"];
                config.AddAzureAppConfiguration(options =>
                {
                    options.Connect(connectionString)
                    .UseFeatureFlags(); // Very Important. It wires up the FeatureManagement capabilities to Azure App Configuration.
                });
            }
        }
Example #13
0
        public static IConfigurationBuilder AddAzureAppConfiguration(this IConfigurationBuilder builder)
        {
            IConfigurationRoot settings = builder.Build();

            builder.AddAzureAppConfiguration(options =>
            {
                var credentials = new DefaultAzureCredential();

                options.Connect(new Uri(settings["AppConfig:BaseUrl"]), credentials)
                .ConfigureKeyVault(kv =>
                {
                    kv.SetCredential(credentials);
                });
            });

            return(builder);
        }
Example #14
0
        internal static void AddSettings(this IConfigurationBuilder builder)
        {
            string environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

            builder
            .AddJsonFile("appsettings.json", false)
            .AddJsonFile($"appsettings.{environmentName}.json", true);
            string endPoint = builder.Build().GetValue <string>("ConfigEndpoint");

            var managedIdentityCredential = new DefaultAzureCredential();

            builder.AddAzureAppConfiguration(
                options =>
                options.Connect(
                    new Uri(endPoint), managedIdentityCredential)
                .ConfigureKeyVault(kv => kv.SetCredential(managedIdentityCredential)))
            .Build();
        }
        /// <summary>
        /// Adds the azure application configuration.
        /// </summary>
        /// <param name="config">The configuration.</param>
        /// <param name="environmentName">Environment name.</param>
        /// <param name="refreshConfiguration">A callback used to configure Azure App Configuration refresh options.</param>
        /// <returns>The same instance of the Microsoft.Extensions.Hosting.IHostBuilder for chaining.</returns>
        /// <remarks>
        /// Configuration should contain <b>AppConfig</b> section, which is mapped to <see cref="AppConfigOptions "/> class.
        /// </remarks>
        public static IConfigurationBuilder AddAzureAppConfig(
            this IConfigurationBuilder config,
            string environmentName,
            Action <AzureAppConfigurationRefreshOptions> refreshConfiguration = null)
        {
            IConfigurationRoot settings  = config.Build();
            AppConfigOptions   appConfig = new();

            settings.Bind("AppConfig", appConfig);

            if (string.IsNullOrWhiteSpace(appConfig.Endpoint))
            {
                return(config);
            }

            config.AddAzureAppConfiguration(options =>
            {
                DefaultAzureCredential credential = CreateAzureCredential(appConfig.IdentityClientId);
                options
                .Connect(new Uri(appConfig.Endpoint), credential)
                .ConfigureKeyVault(kv => kv.SetCredential(credential));

                ConfigureCacheRefresh(options, appConfig, refreshConfiguration);

                IEnumerable <string> prefixes = appConfig.Settings.Where(prefix => !prefix.IsNullOrWhiteSpace());
                foreach (string prefix in prefixes)
                {
                    options
                    .Select($"{prefix}:*", LabelFilter.Null)
                    .Select($"{prefix}:*", environmentName)
                    .TrimKeyPrefix($"{prefix}:");
                }

                if (appConfig.UseFeatureFlags)
                {
                    options
                    .Select("_", LabelFilter.Null)
                    .Select("_", environmentName)
                    .UseFeatureFlags();
                }
            });

            return(config);
        }
Example #16
0
        private static IConfigurationBuilder AddAppConfiguration(this IConfigurationBuilder configBuilder)
        {
            if (!string.IsNullOrEmpty(AppConfigConnectionString))
            {
                configBuilder.AddAzureAppConfiguration(options =>
                {
                    options.Connect(AppConfigConnectionString)
                    .UseFeatureFlags()
                    .ConfigureRefresh(refresh =>
                    {
                        refresh.Register("publishingengineoptions:GetCalculationResultsConcurrencyCount", refreshAll: true)
                        .Register($"{FileSystemCacheSettings.SectionName}:{nameof(IFileSystemCacheSettings.Prefix)}", true)
                        .SetCacheExpiration(TimeSpan.FromSeconds(1));
                    });
                });
            }

            return(configBuilder);
        }
Example #17
0
        public static IConfigurationBuilder AddConfigurationService(this IConfigurationBuilder configurationBuilder, string connectionString, bool optional = false)
        {
            var connectionStringExpanded = Environment.ExpandEnvironmentVariables(connectionString);

            if (Uri.IsWellFormedUriString(connectionStringExpanded, UriKind.Absolute))
            {
                var configurationServiceFile = new Uri(connectionStringExpanded, UriKind.Absolute);

                if (!configurationServiceFile.IsFile)
                {
                    throw new NotSupportedException($"Scheme '{configurationServiceFile.Scheme}' is not supported - use file:// instead");
                }

                return(configurationBuilder.AddJsonFile(configurationServiceFile.LocalPath, optional, true));
            }
            else
            {
                return(configurationBuilder.AddAzureAppConfiguration(connectionString, optional));
            }
        }
Example #18
0
        public static IConfigurationBuilder AddCloud(this IConfigurationBuilder builder)
        {
            var configuration = builder.Build();
            var useCloud      = configuration.GetValue <bool>("UseCloudServices");

            if (useCloud)
            {
                var azureServiceTokenProvider = new AzureServiceTokenProvider();
                var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));

                builder.AddAzureKeyVault(configuration["ConnectionStrings:KeyVault"], kv, new KeyValueSecretManager());
                builder.AddAzureAppConfiguration(options =>
                {
                    options.ConnectWithManagedIdentity(configuration["ConnectionStrings:AppConfiguration"])
                    .Use(KeyFilter.Any, LabelFilter.Null);
                });
            }

            return(builder);
        }
        public static IConfigurationBuilder AddAppConfiguration(this IConfigurationBuilder configurationBuilder, ConfigurationProviders options)
        {
            if (options?.SqlServer?.IsEnabled ?? false)
            {
                configurationBuilder.AddSqlConfigurationVariables(options.SqlServer);
            }

            if (options?.AzureAppConfiguration?.IsEnabled ?? false)
            {
                configurationBuilder.AddAzureAppConfiguration(options.AzureAppConfiguration.ConnectionString);
            }

            if (options?.AzureKeyVault?.IsEnabled ?? false)
            {
                var secretClient = new SecretClient(new Uri(options.AzureKeyVault.VaultName), new DefaultAzureCredential());
                configurationBuilder.AddAzureKeyVault(secretClient, new KeyVaultSecretManager());
            }

            return(configurationBuilder);
        }
Example #20
0
    public static IConfigurationBuilder AddConfigurationService(this IConfigurationBuilder configurationBuilder, string connectionString = null)
    {
        if (configurationBuilder is null)
        {
            throw new ArgumentNullException(nameof(configurationBuilder));
        }

        connectionString ??= configurationBuilder.Build()
        .GetConnectionString("ConfigurationService");

        if (string.IsNullOrWhiteSpace(connectionString))
        {
            return(configurationBuilder);
        }

        var connectionStringExpanded = Regex.Replace(Environment.ExpandEnvironmentVariables(connectionString), "%CWD%", Environment.CurrentDirectory.Replace('\\', '/'));

        if (Uri.IsWellFormedUriString(connectionStringExpanded, UriKind.Absolute))
        {
            var configurationServiceFile = new Uri(connectionStringExpanded, UriKind.Absolute);

            if (!configurationServiceFile.IsFile)
            {
                throw new NotSupportedException($"Scheme '{configurationServiceFile.Scheme}' is not supported - use file:// instead");
            }

            if (!File.Exists(configurationServiceFile.LocalPath))
            {
                Debug.WriteLine($"CAUTION !!! Configuration file {configurationServiceFile.LocalPath} could not be found.");
            }

            return(configurationBuilder.AddJsonFile(configurationServiceFile.LocalPath, false, true));
        }
        else
        {
            return(configurationBuilder.AddAzureAppConfiguration(connectionString, false));
        }
    }
        public static IConfigurationBuilder AddAzureAppConfiguration(
            this IConfigurationBuilder configurationBuilder,
            string currentEnvironment,
            Action <AzureAppConfigConnectOptions, FiltersOptions, FeatureFlagOptions>?configureConnect = default,
            string sectionName = Sections.AzureAppConfig,
            bool throwExceptionOnStoreNotFound = false,
            string?envSectionName = null)
        {
            var configuration = configurationBuilder.Build();

            return(configurationBuilder.AddAzureAppConfiguration(
                       options =>
            {
                var env = new Environments();
                if (!string.IsNullOrEmpty(envSectionName))
                {
                    env.Clear();
                    configuration.Bind(envSectionName, env);
                }

                // create connection options
                var connectOptions = new AzureAppConfigConnectOptions();
                configuration.Bind(sectionName, connectOptions);

                var filtersOptions = new FiltersOptions();
                configuration.Bind($"{sectionName}:Filters", filtersOptions);

                var featuresOptions = new FeatureFlagOptions();
                configuration.Bind($"{sectionName}:Features", featuresOptions);

                configureConnect?.Invoke(connectOptions, filtersOptions, featuresOptions);

                // configure features
                options.UseFeatureFlags(fo =>
                {
                    fo.CacheExpirationInterval = featuresOptions.CacheExpirationInterval;
                    if (!string.IsNullOrEmpty(featuresOptions.Label))
                    {
                        fo.Label = env[featuresOptions.Label];
                    }
                });

                if (!string.IsNullOrEmpty(connectOptions.ConnectionString))
                {
                    options.Connect(connectOptions.ConnectionString);
                }
                else if (connectOptions.Endpoint != null &&
                         string.IsNullOrEmpty(connectOptions.ConnectionString))
                {
                    var credentials = new DefaultAzureCredential();
                    options.Connect(connectOptions.Endpoint, credentials);
                }

                options.ConfigureClientOptions(clientOptions => clientOptions.Retry.MaxRetries = connectOptions.MaxRetries);

                foreach (var section in filtersOptions.Sections)
                {
                    // Load configuration values with no label, which means all of the configurations that are not specific to
                    // Environment
                    options.Select(section);

                    // Override with any configuration values specific to current hosting env
                    options.Select(section, env[currentEnvironment]);
                }

                foreach (var section in filtersOptions.RefresSections)
                {
                    options.ConfigureRefresh(refresh =>
                    {
                        refresh.Register(section, refreshAll: true);
                        refresh.Register(section, env[currentEnvironment], refreshAll: true);
                        refresh.SetCacheExpiration(filtersOptions.CacheExpirationTime);
                    });
                }
            },
                       throwExceptionOnStoreNotFound));
        }