From 340996f6b8f341c74a0df3211ea373e0bb99337d Mon Sep 17 00:00:00 2001 From: Mikhail Merkulov Date: Tue, 30 Jan 2024 20:57:08 +0200 Subject: [PATCH] .NET 8 support (#50) * updated code to support .net 8 * ci/cd updates to support .net 8 and general updates * fixed dotnet install action --- .github/workflows/build.yml | 13 ++-- .github/workflows/master.yml | 13 ++-- .github/workflows/release.yml | 15 ++-- ...VaultSharp.Extensions.Configuration.csproj | 23 +++++- .../IntegrationTests.cs | 74 +++++++++---------- .../IntegrationTests_SSL.cs | 17 ++--- ...Sharp.Extensions.Configuration.Test.csproj | 20 ++++- 7 files changed, 104 insertions(+), 71 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1c97f9b..5fcff5e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: lfs: true fetch-depth: 0 @@ -25,9 +25,12 @@ jobs: run: git fetch --tags shell: pwsh - name: 'Install .NET Core SDK' - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: - dotnet-version: '7.0.x' + dotnet-version: | + 6.0.x + 7.0.x + 8.0.x - name: 'Fix permissions' run: chmod +x ./Tests/VaultSharp.Extensions.Configuration.Test/approle.sh && chmod +x ./Tests/VaultSharp.Extensions.Configuration.Test/approle_nolist.sh shell: bash @@ -44,12 +47,12 @@ jobs: if: github.event_name == 'pull_request' run: cp coverage/*/coverage.cobertura.xml coverage/coverage.cobertura.xml - name: 'Publish Code Coverage' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: Coverage Cobertura Report path: './coverage/coverage.cobertura.xml' - name: 'Publish Test Results' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: Tests HTML Report path: './coverage/VaultSharp.Extensions.Configuration.Test.html' diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index ff39c8a..0274839 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -19,14 +19,17 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: lfs: true fetch-depth: 0 - name: 'Install .NET Core SDK' - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: - dotnet-version: '7.0.x' + dotnet-version: | + 6.0.x + 7.0.x + 8.0.x - name: 'Fix permissions' run: chmod +x ./Tests/VaultSharp.Extensions.Configuration.Test/approle.sh && chmod +x ./Tests/VaultSharp.Extensions.Configuration.Test/approle_nolist.sh shell: bash @@ -49,7 +52,7 @@ jobs: echo "COVERAGE=$COVERAGE%" >> $GITHUB_ENV echo "BRANCH=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_ENV - name: Create the Badgegg - uses: schneegans/dynamic-badges-action@v1.6.0 + uses: schneegans/dynamic-badges-action@v1.7.0 with: auth: ${{ secrets.GIST_SECRET }} gistID: 5242a4e2d58a428062b3a59824d5864e @@ -57,4 +60,4 @@ jobs: label: Coverage message: ${{ env.COVERAGE }} color: "#3fbe25" - namedLogo: dotnet \ No newline at end of file + namedLogo: dotnet diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0f5ab87..8033ada 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: lfs: true fetch-depth: 0 @@ -19,9 +19,12 @@ jobs: run: git fetch --tags shell: pwsh - name: 'Install .NET Core SDK' - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: - dotnet-version: '7.0.x' + dotnet-version: | + 6.0.x + 7.0.x + 8.0.x - name: 'Fix permissions' run: chmod +x ./Tests/VaultSharp.Extensions.Configuration.Test/approle.sh && chmod +x ./Tests/VaultSharp.Extensions.Configuration.Test/approle_nolist.sh shell: bash @@ -41,12 +44,12 @@ jobs: run: dotnet cake --target=Publish --nuget-key="${{secrets.NUGET_API_KEY}}" shell: pwsh - name: 'Publish Code Coverage' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: tests path: './Artefacts/**/coverage.opencover.xml' - name: 'Publish Test Results' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: tests - path: './Artefacts/VaultSharp.Extensions.Configuration.Test.html' \ No newline at end of file + path: './Artefacts/VaultSharp.Extensions.Configuration.Test.html' diff --git a/Source/VaultSharp.Extensions.Configuration/VaultSharp.Extensions.Configuration.csproj b/Source/VaultSharp.Extensions.Configuration/VaultSharp.Extensions.Configuration.csproj index 6e0d0aa..de2cd95 100644 --- a/Source/VaultSharp.Extensions.Configuration/VaultSharp.Extensions.Configuration.csproj +++ b/Source/VaultSharp.Extensions.Configuration/VaultSharp.Extensions.Configuration.csproj @@ -7,17 +7,17 @@ VaultSharp.Extensions.Configuration MIT enable - net6.0;net7.0;netstandard2.0;netstandard2.1 + net6.0;net7.0;net8.0;netstandard2.0;netstandard2.1 true snupkg - Copyright 2023 © Mikhail Merkulov. All rights Reserved + Copyright 2024 © Mikhail Merkulov. All rights Reserved VaultSharp.Extensions.Configuration Configuration extension that allows you to use Hashicorp Vault as a configuration backend. - This library is built with .NET Standard 2.0, 2.1, .NET 6 & .NET 7 + This library is built with .NET Standard 2.0, 2.1, .NET 6, .NET 7, .NET 8 Vault;Configuration;Data protection;Hashicorp @@ -80,7 +80,7 @@ - + @@ -90,6 +90,17 @@ + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + VaultSharp configuration extensions .NET Standard 2.0 @@ -106,6 +117,10 @@ VaultSharp configuration extensions .NET 7 + + VaultSharp configuration extensions .NET 8 + + 5 diff --git a/Tests/VaultSharp.Extensions.Configuration.Test/IntegrationTests.cs b/Tests/VaultSharp.Extensions.Configuration.Test/IntegrationTests.cs index 0008009..c05d31f 100644 --- a/Tests/VaultSharp.Extensions.Configuration.Test/IntegrationTests.cs +++ b/Tests/VaultSharp.Extensions.Configuration.Test/IntegrationTests.cs @@ -24,7 +24,7 @@ namespace VaultSharp.Extensions.Configuration.Test [CollectionDefinition("VaultSharp.Extensions.Configuration.Tests", DisableParallelization = true)] public partial class IntegrationTests { - private ILogger _logger; + private readonly ILogger logger; public IntegrationTests() { @@ -32,7 +32,7 @@ public IntegrationTests() .MinimumLevel.Debug() .WriteTo.Console() .CreateLogger(); - this._logger = new SerilogLoggerProvider(Log.Logger).CreateLogger(nameof(IntegrationTests)); + this.logger = new SerilogLoggerProvider(Log.Logger).CreateLogger(nameof(IntegrationTests)); } private IContainer PrepareVaultContainer(bool enableSSL = false, string? script = null) @@ -155,12 +155,12 @@ public async Task Success_SimpleTest_TokenAuth() await this.LoadDataAsync("http://localhost:8200", values).ConfigureAwait(false); // act - ConfigurationBuilder builder = new ConfigurationBuilder(); + var builder = new ConfigurationBuilder(); builder.AddVaultConfiguration( () => new VaultOptions("http://localhost:8200", "root", additionalCharactersForConfigurationPath: new[] { '.' }), "test", "secret", - this._logger); + this.logger); var configurationRoot = builder.Build(); // assert @@ -168,7 +168,7 @@ public async Task Success_SimpleTest_TokenAuth() 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:1").Should().Be("v2"); configurationRoot.GetValue("option5:2").Should().Be("v3"); var t1 = new TestConfigObject(); configurationRoot.Bind("option6:0", t1); @@ -215,12 +215,12 @@ public async Task Success_SimpleTestOmitVaultKey_TokenAuth() await this.LoadDataAsync("http://localhost:8200", values).ConfigureAwait(false); // act - ConfigurationBuilder builder = new ConfigurationBuilder(); + var builder = new ConfigurationBuilder(); builder.AddVaultConfiguration( () => new VaultOptions("http://localhost:8200", "root", omitVaultKeyName: true), "myservice-config", "secret", - this._logger); + this.logger); var configurationRoot = builder.Build(); // assert @@ -237,7 +237,7 @@ public async Task Success_SimpleTestOmitVaultKey_TokenAuth() public async Task Success_WatcherTest_TokenAuth() { // arrange - using CancellationTokenSource cts = new CancellationTokenSource(); + using var cts = new CancellationTokenSource(); var values = new Dictionary>> @@ -254,14 +254,14 @@ public async Task Success_WatcherTest_TokenAuth() // act - ConfigurationBuilder builder = new ConfigurationBuilder(); + var builder = new ConfigurationBuilder(); builder.AddVaultConfiguration( () => new VaultOptions("http://localhost:8200", "root", reloadOnChange: true, reloadCheckIntervalSeconds: 10), "test", "secret", - this._logger); + this.logger); var configurationRoot = builder.Build(); - VaultChangeWatcher changeWatcher = new VaultChangeWatcher(configurationRoot, this._logger); + var changeWatcher = new VaultChangeWatcher(configurationRoot, this.logger); await changeWatcher.StartAsync(cts.Token).ConfigureAwait(false); var reloadToken = configurationRoot.GetReloadToken(); @@ -291,7 +291,7 @@ public async Task Success_WatcherTest_TokenAuth() } finally { - cts.Cancel(); + await cts.CancelAsync(); await container.DisposeAsync().ConfigureAwait(false); } } @@ -300,7 +300,7 @@ public async Task Success_WatcherTest_TokenAuth() public async Task Success_WatcherTest_NoChanges() { // arrange - using CancellationTokenSource cts = new CancellationTokenSource(); + using var cts = new CancellationTokenSource(); var values = new Dictionary>> @@ -317,14 +317,14 @@ public async Task Success_WatcherTest_NoChanges() // act - ConfigurationBuilder builder = new ConfigurationBuilder(); + var builder = new ConfigurationBuilder(); builder.AddVaultConfiguration( () => new VaultOptions("http://localhost:8200", "root", reloadOnChange: true, reloadCheckIntervalSeconds: 10), "test", "secret", - this._logger); + this.logger); var configurationRoot = builder.Build(); - VaultChangeWatcher changeWatcher = new VaultChangeWatcher(configurationRoot, this._logger); + var changeWatcher = new VaultChangeWatcher(configurationRoot, this.logger); await changeWatcher.StartAsync(cts.Token).ConfigureAwait(false); var reloadToken = configurationRoot.GetReloadToken(); @@ -345,7 +345,7 @@ public async Task Success_WatcherTest_NoChanges() } finally { - cts.Cancel(); + await cts.CancelAsync(); await container.DisposeAsync().ConfigureAwait(false); } } @@ -354,7 +354,7 @@ public async Task Success_WatcherTest_NoChanges() public async Task Success_WatcherTest_OmitVaultKey_TokenAuth() { // arrange - using CancellationTokenSource cts = new CancellationTokenSource(); + using var cts = new CancellationTokenSource(); var values = new Dictionary>> { @@ -375,14 +375,14 @@ public async Task Success_WatcherTest_OmitVaultKey_TokenAuth() // act - ConfigurationBuilder builder = new ConfigurationBuilder(); + var builder = new ConfigurationBuilder(); builder.AddVaultConfiguration( () => new VaultOptions("http://localhost:8200", "root", reloadOnChange: true, reloadCheckIntervalSeconds: 10, omitVaultKeyName: true), "myservice-config", "secret", - this._logger); + this.logger); var configurationRoot = builder.Build(); - VaultChangeWatcher changeWatcher = new VaultChangeWatcher(configurationRoot, this._logger); + var changeWatcher = new VaultChangeWatcher(configurationRoot, this.logger); await changeWatcher.StartAsync(cts.Token).ConfigureAwait(false); var reloadToken = configurationRoot.GetReloadToken(); @@ -417,7 +417,7 @@ public async Task Success_WatcherTest_OmitVaultKey_TokenAuth() } finally { - cts.Cancel(); + await cts.CancelAsync(); await container.DisposeAsync().ConfigureAwait(false); } } @@ -426,7 +426,7 @@ public async Task Success_WatcherTest_OmitVaultKey_TokenAuth() public async Task Success_TokenAuthMethod() { // arrange - using CancellationTokenSource cts = new CancellationTokenSource(); + using var cts = new CancellationTokenSource(); var values = new Dictionary>> { @@ -446,12 +446,12 @@ public async Task Success_TokenAuthMethod() await this.LoadDataAsync("http://localhost:8200", values).ConfigureAwait(false); // act - ConfigurationBuilder builder = new ConfigurationBuilder(); + var builder = new ConfigurationBuilder(); builder.AddVaultConfiguration( () => new VaultOptions("http://localhost:8200", new TokenAuthMethodInfo("root"), reloadOnChange: true, reloadCheckIntervalSeconds: 10, omitVaultKeyName: true), "myservice-config", "secret", - this._logger); + this.logger); var configurationRoot = builder.Build(); // assert @@ -460,7 +460,7 @@ public async Task Success_TokenAuthMethod() } finally { - cts.Cancel(); + await cts.CancelAsync(); await container.DisposeAsync().ConfigureAwait(false); } } @@ -469,7 +469,7 @@ public async Task Success_TokenAuthMethod() public async Task Success_AppRoleAuthMethod() { // arrange - using CancellationTokenSource cts = new CancellationTokenSource(); + using var cts = new CancellationTokenSource(); var values = new Dictionary>> { @@ -489,19 +489,19 @@ public async Task Success_AppRoleAuthMethod() var execResult = await container.ExecAsync(new[] { "/tmp/script.sh" }); if (execResult.ExitCode != 0) { - string msg = execResult.Stdout + Environment.NewLine + execResult.Stderr; + var msg = execResult.Stdout + Environment.NewLine + execResult.Stderr; throw new Exception(msg); } var (RoleId, SecretId) = await this.GetAppRoleCreds("test-role"); await this.LoadDataAsync("http://localhost:8200", values).ConfigureAwait(false); // act - ConfigurationBuilder builder = new ConfigurationBuilder(); + var builder = new ConfigurationBuilder(); builder.AddVaultConfiguration( () => new VaultOptions("http://localhost:8200", new AppRoleAuthMethodInfo(RoleId, SecretId), reloadOnChange: true, reloadCheckIntervalSeconds: 10, omitVaultKeyName: true), "myservice-config", "secret", - this._logger); + this.logger); var configurationRoot = builder.Build(); // assert @@ -510,7 +510,7 @@ public async Task Success_AppRoleAuthMethod() } finally { - cts.Cancel(); + await cts.CancelAsync(); await container.DisposeAsync().ConfigureAwait(false); } } @@ -519,7 +519,7 @@ public async Task Success_AppRoleAuthMethod() public async Task Success_AppRoleAuthMethodNoListPermissions() { // arrange - using CancellationTokenSource cts = new CancellationTokenSource(); + using var cts = new CancellationTokenSource(); var values = new Dictionary>> { @@ -539,19 +539,19 @@ public async Task Success_AppRoleAuthMethodNoListPermissions() var execResult = await container.ExecAsync(new[] { "/tmp/script.sh" }); if (execResult.ExitCode != 0) { - string msg = execResult.Stdout + Environment.NewLine + execResult.Stderr; + var msg = execResult.Stdout + Environment.NewLine + execResult.Stderr; throw new Exception(msg); } var (RoleId, SecretId) = await this.GetAppRoleCreds("test-role"); await this.LoadDataAsync("http://localhost:8200", values).ConfigureAwait(false); // act - ConfigurationBuilder builder = new ConfigurationBuilder(); + var builder = new ConfigurationBuilder(); builder.AddVaultConfiguration( () => new VaultOptions("http://localhost:8200", new AppRoleAuthMethodInfo(RoleId, SecretId), reloadOnChange: true, reloadCheckIntervalSeconds: 10, omitVaultKeyName: true, alwaysAddTrailingSlashToBasePath: false), "myservice-config", "secret", - this._logger); + this.logger); var configurationRoot = builder.Build(); // assert @@ -560,7 +560,7 @@ public async Task Success_AppRoleAuthMethodNoListPermissions() } finally { - cts.Cancel(); + await cts.CancelAsync(); await container.DisposeAsync().ConfigureAwait(false); } } @@ -602,7 +602,7 @@ public async Task Failure_PermissionDenied() } finally { - cts.Cancel(); + await cts.CancelAsync(); await container.DisposeAsync().ConfigureAwait(false); } diff --git a/Tests/VaultSharp.Extensions.Configuration.Test/IntegrationTests_SSL.cs b/Tests/VaultSharp.Extensions.Configuration.Test/IntegrationTests_SSL.cs index c276bb1..17a4473 100644 --- a/Tests/VaultSharp.Extensions.Configuration.Test/IntegrationTests_SSL.cs +++ b/Tests/VaultSharp.Extensions.Configuration.Test/IntegrationTests_SSL.cs @@ -36,12 +36,12 @@ public async Task SSL_Enabled_InsecureConnection() await this.LoadDataAsync("https://localhost:8200", values).ConfigureAwait(false); // act - ConfigurationBuilder builder = new ConfigurationBuilder(); + var builder = new ConfigurationBuilder(); builder.AddVaultConfiguration( () => new VaultOptions("https://localhost:8200", "root", additionalCharactersForConfigurationPath: new[] { '.' }, insecureConnection: true), "test", "secret", - this._logger); + this.logger); var configurationRoot = builder.Build(); // assert @@ -76,12 +76,12 @@ public async Task SSL_Enabled_CannotVerifyCert() await this.LoadDataAsync("https://localhost:8200", values).ConfigureAwait(false); // act - ConfigurationBuilder builder = new ConfigurationBuilder(); + var builder = new ConfigurationBuilder(); builder.AddVaultConfiguration( () => new VaultOptions("https://localhost:8200", "root", additionalCharactersForConfigurationPath: new[] { '.' }, insecureConnection: false), "test", "secret", - this._logger); + this.logger); Action act = () => builder.Build(); @@ -117,15 +117,12 @@ public async Task SSL_Enabled_ManuallyVerifyCert() await this.LoadDataAsync("https://localhost:8200", values).ConfigureAwait(false); // act - ConfigurationBuilder builder = new ConfigurationBuilder(); + var builder = new ConfigurationBuilder(); builder.AddVaultConfiguration( - () => new VaultOptions("https://localhost:8200", "root", additionalCharactersForConfigurationPath: new[] { '.' }, insecureConnection: false, serverCertificateCustomValidationCallback: (message, cert, chain, errors) => - { - return true; - }), + () => new VaultOptions("https://localhost:8200", "root", additionalCharactersForConfigurationPath: new[] { '.' }, insecureConnection: false, serverCertificateCustomValidationCallback: (message, cert, chain, errors) => true), "test", "secret", - this._logger); + this.logger); var configurationRoot = builder.Build(); // assert diff --git a/Tests/VaultSharp.Extensions.Configuration.Test/VaultSharp.Extensions.Configuration.Test.csproj b/Tests/VaultSharp.Extensions.Configuration.Test/VaultSharp.Extensions.Configuration.Test.csproj index 1b7f3a4..51b7bc9 100644 --- a/Tests/VaultSharp.Extensions.Configuration.Test/VaultSharp.Extensions.Configuration.Test.csproj +++ b/Tests/VaultSharp.Extensions.Configuration.Test/VaultSharp.Extensions.Configuration.Test.csproj @@ -4,7 +4,7 @@ enable false false - net7.0 + net8.0 VSTHRD200;CS1591;CS8618 @@ -39,9 +39,9 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -84,7 +84,7 @@ - + @@ -95,6 +95,18 @@ + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + PreserveNewest