diff --git a/Source/VaultSharp.Extensions.Configuration/VaultConfigurationProvider.cs b/Source/VaultSharp.Extensions.Configuration/VaultConfigurationProvider.cs index 4e1524a..e05c1bd 100644 --- a/Source/VaultSharp.Extensions.Configuration/VaultConfigurationProvider.cs +++ b/Source/VaultSharp.Extensions.Configuration/VaultConfigurationProvider.cs @@ -2,6 +2,7 @@ namespace VaultSharp.Extensions.Configuration { using System; using System.Collections.Generic; + using System.Globalization; using System.Threading.Tasks; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; @@ -122,24 +123,46 @@ private void SetData(IEnumerable> data, str case string sValue: this.Set(nestedKey, sValue); break; + case int intValue: + this.Set(nestedKey, intValue.ToString(CultureInfo.InvariantCulture)); + break; + case long longValue: + this.Set(nestedKey, longValue.ToString(CultureInfo.InvariantCulture)); + break; + case bool boolValue: + this.Set(nestedKey, boolValue.ToString(CultureInfo.InvariantCulture)); + break; case JToken token: switch (token.Type) { case JTokenType.Object: this.SetData(token.Value(), nestedKey); break; - case JTokenType.String: - this.Set(nestedKey, token.Value()); - break; case JTokenType.None: case JTokenType.Array: - case JTokenType.Constructor: + var array = (JArray)token; + for (var i = 0; i < array.Count; i++) + { + if (array[i].Type == JTokenType.Array) + { + this.SetData(array[i].Value(), $"{nestedKey}:{i}"); + } + else if (array[i].Type == JTokenType.Object) + { + this.SetData(array[i].Value(), $"{nestedKey}:{i}"); + } + else + { + this.Set($"{nestedKey}:{i}", array[i].Value()); + } + } + + break; + case JTokenType.Property: - case JTokenType.Comment: case JTokenType.Integer: case JTokenType.Float: case JTokenType.Boolean: - case JTokenType.Null: case JTokenType.Undefined: case JTokenType.Date: case JTokenType.Raw: @@ -147,6 +170,8 @@ private void SetData(IEnumerable> data, str case JTokenType.Guid: case JTokenType.Uri: case JTokenType.TimeSpan: + case JTokenType.String: + this.Set(nestedKey, token.Value()); break; } diff --git a/Tests/VaultSharp.Extensions.Configuration.Test/IntegrationTests.cs b/Tests/VaultSharp.Extensions.Configuration.Test/IntegrationTests.cs index 7fa9516..130b414 100644 --- a/Tests/VaultSharp.Extensions.Configuration.Test/IntegrationTests.cs +++ b/Tests/VaultSharp.Extensions.Configuration.Test/IntegrationTests.cs @@ -44,17 +44,23 @@ private TestcontainersContainer PrepareVaultContainer() return testcontainersBuilder.Build(); } - private async Task LoadDataAsync(Dictionary> values) + private async Task LoadDataAsync(Dictionary>> values) { var authMethod = new TokenAuthMethodInfo("root"); var vaultClientSettings = new VaultClientSettings("http://localhost:8200", authMethod); IVaultClient vaultClient = new VaultClient(vaultClientSettings); - foreach (var pair in values) + foreach (var sectionPair in values) { - var data = new Dictionary() { [pair.Value.Key] = pair.Value.Value }; - await vaultClient.V1.Secrets.KeyValue.V2.WriteSecretAsync(pair.Key, data).ConfigureAwait(false); + var data = new Dictionary(); + foreach (var pair in sectionPair.Value) + { + data.Add(pair.Key, pair.Value); + } + + await vaultClient.V1.Secrets.KeyValue.V2.WriteSecretAsync(sectionPair.Key, data) + .ConfigureAwait(false); } } @@ -62,11 +68,30 @@ private async Task LoadDataAsync(Dictionary> public async Task Success_SimpleTest_TokenAuth() { // arrange - Dictionary> values = - new Dictionary> + var values = + new Dictionary>> { - { "test", new KeyValuePair("option1", "value1") }, - { "test/subsection", new KeyValuePair("option2", "value2") }, + { + "test", new[] + { + new KeyValuePair("option1", "value1"), + new KeyValuePair("option3", 5), + new KeyValuePair("option4", true), + new KeyValuePair("option5", new[] {"v1", "v2", "v3"}), + new KeyValuePair("option6", + new[] + { + new TestConfigObject() {OptionA = "a1", OptionB = "b1"}, + new TestConfigObject() {OptionA = "a2", OptionB = "b2"}, + }), + } + }, + { + "test/subsection", new[] + { + new KeyValuePair("option2", "value2"), + } + }, }; var container = this.PrepareVaultContainer(); @@ -86,6 +111,19 @@ public async Task Success_SimpleTest_TokenAuth() // assert configurationRoot.GetValue("option1").Should().Be("value1"); + configurationRoot.GetValue("option3").Should().Be(5); + configurationRoot.GetValue("option4").Should().Be(true); + configurationRoot.GetValue("option5:0").Should().Be("v1"); + configurationRoot.GetValue("option5:1").Should().Be("v2"); + configurationRoot.GetValue("option5:2").Should().Be("v3"); + var t1 = new TestConfigObject(); + configurationRoot.Bind("option6:0", t1); + t1.OptionA.Should().Be("a1"); + t1.OptionB.Should().Be("b1"); + var t2 = new TestConfigObject(); + configurationRoot.Bind("option6:1", t2); + t2.OptionA.Should().Be("a2"); + t2.OptionB.Should().Be("b2"); configurationRoot.GetSection("subsection").GetValue("option2").Should().Be("value2"); } finally @@ -100,11 +138,11 @@ public async Task Success_WatcherTest_TokenAuth() // arrange using CancellationTokenSource cts = new CancellationTokenSource(); - Dictionary> values = - new Dictionary> + var values = + new Dictionary>> { - { "test", new KeyValuePair("option1", "value1") }, - { "test/subsection", new KeyValuePair("option2", "value2") }, + {"test", new[] {new KeyValuePair("option1", "value1"),}}, + {"test/subsection", new[] {new KeyValuePair("option2", "value2"),}}, }; var container = this.PrepareVaultContainer(); @@ -117,7 +155,8 @@ public async Task Success_WatcherTest_TokenAuth() // act ConfigurationBuilder builder = new ConfigurationBuilder(); builder.AddVaultConfiguration( - () => new VaultOptions("http://localhost:8200", "root", reloadOnChange: true, reloadCheckIntervalSeconds: 10), + () => new VaultOptions("http://localhost:8200", "root", reloadOnChange: true, + reloadCheckIntervalSeconds: 10), "test", "secret", this._logger); @@ -132,11 +171,11 @@ public async Task Success_WatcherTest_TokenAuth() reloadToken.HasChanged.Should().BeFalse(); // load new data and wait for reload - values = new Dictionary> + values = new Dictionary>> { - { "test", new KeyValuePair("option1", "value1_new") }, - { "test/subsection", new KeyValuePair("option2", "value2_new") }, - { "test/subsection3", new KeyValuePair("option3", "value3_new") }, + {"test", new[] {new KeyValuePair("option1", "value1_new"),}}, + {"test/subsection", new[] {new KeyValuePair("option2", "value2_new"),}}, + {"test/subsection3", new[] {new KeyValuePair("option3", "value3_new"),}}, }; await this.LoadDataAsync(values).ConfigureAwait(false); await Task.Delay(TimeSpan.FromSeconds(15)).ConfigureAwait(true); @@ -155,4 +194,11 @@ public async Task Success_WatcherTest_TokenAuth() } } } + + public class TestConfigObject + { + public string OptionA { get; set; } + + public string OptionB { get; set; } + } }