From 9a8e9f451c63eb4706fd5a626cabd44f710a393c Mon Sep 17 00:00:00 2001 From: Simon Jones Date: Thu, 11 Apr 2024 13:52:56 +0100 Subject: [PATCH] Support for Dapr 1.12.0+ (#62) * #61 : Updated target frameworks, package versions, and method for adding headers Updated the target frameworks across multiple projects to `net8.0` and updated various package versions in `dapr_sidekick_csharp.props`, `ActorSample.ActorClient.csproj`, `ActorSample.DemoActor.csproj`, `ActorSample.IDemoActor.csproj`, `AppConfigurationSample.csproj`, `ConsulSample.Receiver.csproj`, `ConsulSample.Sender.csproj`, `ControllerSample.csproj`, `ServiceInvocationSample.csproj`, `Directory.build.props`, `Man.Dapr.Sidekick.csproj`, `Man.Dapr.Sidekick.AspNetCore.Tests.csproj`, `Man.Dapr.Sidekick.Extensions.Logging.Tests.csproj`, and `Man.Dapr.Sidekick.Tests.csproj`. Also replaced the `Add` method with the `Append` method for adding headers in `HttpContextInvocationHandlerTests.cs`. * #61 : Add Sentry compatibility with Dapr 1.12+, and SentrySample project * #61 : Add Placement compatibility with Dapr 1.12+, and PlacementSample project --- .github/workflows/build.yaml | 6 +-- all.sln | 50 +++++++++++++++-- properties/dapr_sidekick_csharp.props | 12 ++--- .../ActorSample.ActorClient.csproj | 4 +- .../ActorSample.DemoActor.csproj | 8 +-- .../ActorSample.IDemoActor.csproj | 4 +- .../AppConfigurationSample.csproj | 14 ++--- .../ConsulSample.Receiver.csproj | 6 +-- .../ConsulSample.Sender.csproj | 7 +-- samples/AspNetCore/ConsulSample/README.md | 2 +- .../ControllerSample/Account.cs | 4 +- .../ControllerSample/ControllerSample.csproj | 6 +-- .../ControllerSample/Transaction.cs | 4 +- .../PlacementSample/PlacementSample.csproj | 26 +++++++++ .../PlacementSample/Program.cs | 39 ++++++++++++++ .../Properties/launchSettings.json | 13 +++++ .../appsettings.Development.json | 8 +++ .../PlacementSample/appsettings.json | 19 +++++++ .../PlacementSample/dapr/config.yaml | 8 +++ .../PlacementSample/placement/config.yaml | 6 +++ samples/AspNetCore/PlacementSample/README.md | 42 +++++++++++++++ samples/AspNetCore/SentrySample/README.md | 54 +++++++++++++++++++ .../SentrySample/SentrySample/Program.cs | 49 +++++++++++++++++ .../Properties/launchSettings.json | 13 +++++ .../SentrySample/SentrySample.csproj | 26 +++++++++ .../SentrySample/appsettings.Development.json | 8 +++ .../SentrySample/appsettings.json | 20 +++++++ .../SentrySample/dapr/config.yaml | 8 +++ .../SentrySample/sentry/certs/ca.crt | 10 ++++ .../SentrySample/sentry/certs/issuer.crt | 11 ++++ .../SentrySample/sentry/certs/issuer.key | 5 ++ .../SentrySample/sentry/config.yaml | 12 +++++ .../ServiceInvocationSample.csproj | 5 +- src/Directory.build.props | 2 +- .../DaprHostedService.cs | 3 +- .../Man.Dapr.Sidekick.AspNetCore.csproj | 4 +- .../Metrics/IDaprMetricsCollector.cs | 2 +- .../Metrics/PrometheusTextReader.cs | 2 +- .../DaprPlacementSidecarHostedService.cs | 3 +- .../Sentry/DaprSentrySidecarHostedService.cs | 3 +- ...an.Dapr.Sidekick.Extensions.Logging.csproj | 10 ++-- .../Man.Dapr.Sidekick.csproj | 4 +- .../Options/DaprPlacementOptions.cs | 13 +++++ .../Options/DaprProcessOptions.cs | 30 +++++++++++ .../Process/DaprPlacementProcess.cs | 16 +++++- .../Process/DaprProcessLogger.cs | 10 ++++ tests/Directory.build.props | 4 +- ...idekickServiceCollectionExtensionsTests.cs | 6 ++- .../Http/HttpContextInvocationHandlerTests.cs | 6 +-- .../Man.Dapr.Sidekick.AspNetCore.Tests.csproj | 2 +- .../DaprMetricsMiddlewareExtensionsTests.cs | 6 ++- ...r.Sidekick.Extensions.Logging.Tests.csproj | 2 +- .../Man.Dapr.Sidekick.Tests.csproj | 4 +- .../Options/DaprPlacementOptionsTests.cs | 4 +- .../Options/DaprProcessOptionsTests.cs | 21 ++++++++ .../Process/DaprPlacementProcessTests.cs | 20 +++++-- .../Process/DaprProcessLoggerTests.cs | 1 + 57 files changed, 608 insertions(+), 79 deletions(-) create mode 100644 samples/AspNetCore/PlacementSample/PlacementSample/PlacementSample.csproj create mode 100644 samples/AspNetCore/PlacementSample/PlacementSample/Program.cs create mode 100644 samples/AspNetCore/PlacementSample/PlacementSample/Properties/launchSettings.json create mode 100644 samples/AspNetCore/PlacementSample/PlacementSample/appsettings.Development.json create mode 100644 samples/AspNetCore/PlacementSample/PlacementSample/appsettings.json create mode 100644 samples/AspNetCore/PlacementSample/PlacementSample/dapr/config.yaml create mode 100644 samples/AspNetCore/PlacementSample/PlacementSample/placement/config.yaml create mode 100644 samples/AspNetCore/PlacementSample/README.md create mode 100644 samples/AspNetCore/SentrySample/README.md create mode 100644 samples/AspNetCore/SentrySample/SentrySample/Program.cs create mode 100644 samples/AspNetCore/SentrySample/SentrySample/Properties/launchSettings.json create mode 100644 samples/AspNetCore/SentrySample/SentrySample/SentrySample.csproj create mode 100644 samples/AspNetCore/SentrySample/SentrySample/appsettings.Development.json create mode 100644 samples/AspNetCore/SentrySample/SentrySample/appsettings.json create mode 100644 samples/AspNetCore/SentrySample/SentrySample/dapr/config.yaml create mode 100644 samples/AspNetCore/SentrySample/SentrySample/sentry/certs/ca.crt create mode 100644 samples/AspNetCore/SentrySample/SentrySample/sentry/certs/issuer.crt create mode 100644 samples/AspNetCore/SentrySample/SentrySample/sentry/certs/issuer.key create mode 100644 samples/AspNetCore/SentrySample/SentrySample/sentry/config.yaml diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 6785c41..27abf91 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -32,7 +32,7 @@ jobs: runs-on: windows-latest strategy: matrix: - dotnet-version: ['net35', 'net48', 'net50'] + dotnet-version: ['net35', 'net48', 'net80'] include: - dotnet-version: 'net35' display-name: '.NET Framework 3.5' @@ -43,8 +43,8 @@ jobs: framework: 'net48' logger: '--logger="GitHubActions;report-warnings=false" --logger="trx"' - dotnet-version: 'net50' - display-name: '.NET 5.0' - framework: 'net5.0' + display-name: '.NET 8.0' + framework: 'net8.0' logger: '--logger="GitHubActions;report-warnings=false" --logger="trx"' steps: - uses: actions/checkout@v2 diff --git a/all.sln b/all.sln index 94e364e..2ebeb4c 100644 --- a/all.sln +++ b/all.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.6.30114.105 +# Visual Studio Version 17 +VisualStudioVersion = 17.10.34707.107 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A985DBAA-87F6-4860-A5D3-96376165BE17}" ProjectSection(SolutionItems) = preProject @@ -80,13 +80,27 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ControllerSample", "Control EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControllerSample", "samples\AspNetCore\ControllerSample\ControllerSample\ControllerSample.csproj", "{FE082318-2993-42A3-B2DB-28EDA77F7136}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppConfigurationSample", "samples\AspNetCore\AppConfigurationSample\AppConfigurationSample\AppConfigurationSample.csproj", "{C6911A37-51F3-4E29-8E67-39B460EE7ABA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppConfigurationSample", "samples\AspNetCore\AppConfigurationSample\AppConfigurationSample\AppConfigurationSample.csproj", "{C6911A37-51F3-4E29-8E67-39B460EE7ABA}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AppConfigurationSample", "AppConfigurationSample", "{3AD6FEBE-37E9-436E-BE86-29668A9DDB3E}" ProjectSection(SolutionItems) = preProject samples\AspNetCore\AppConfigurationSample\README.md = samples\AspNetCore\AppConfigurationSample\README.md EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SentrySample", "SentrySample", "{7F6A5D8C-9780-4824-8284-CC3149683C70}" + ProjectSection(SolutionItems) = preProject + samples\AspNetCore\SentrySample\README.md = samples\AspNetCore\SentrySample\README.md + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SentrySample", "samples\AspNetCore\SentrySample\SentrySample\SentrySample.csproj", "{9F4DA8E9-F253-4312-A0BB-E2873A21C41A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PlacementSample", "PlacementSample", "{AE430C04-78BD-4CAE-86D7-EBC599774D9C}" + ProjectSection(SolutionItems) = preProject + samples\AspNetCore\PlacementSample\README.md = samples\AspNetCore\PlacementSample\README.md + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlacementSample", "samples\AspNetCore\PlacementSample\PlacementSample\PlacementSample.csproj", "{2FC86574-6A81-4E2B-A0D4-78D46528A917}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -277,6 +291,30 @@ Global {C6911A37-51F3-4E29-8E67-39B460EE7ABA}.Release|x64.Build.0 = Release|Any CPU {C6911A37-51F3-4E29-8E67-39B460EE7ABA}.Release|x86.ActiveCfg = Release|Any CPU {C6911A37-51F3-4E29-8E67-39B460EE7ABA}.Release|x86.Build.0 = Release|Any CPU + {9F4DA8E9-F253-4312-A0BB-E2873A21C41A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9F4DA8E9-F253-4312-A0BB-E2873A21C41A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9F4DA8E9-F253-4312-A0BB-E2873A21C41A}.Debug|x64.ActiveCfg = Debug|Any CPU + {9F4DA8E9-F253-4312-A0BB-E2873A21C41A}.Debug|x64.Build.0 = Debug|Any CPU + {9F4DA8E9-F253-4312-A0BB-E2873A21C41A}.Debug|x86.ActiveCfg = Debug|Any CPU + {9F4DA8E9-F253-4312-A0BB-E2873A21C41A}.Debug|x86.Build.0 = Debug|Any CPU + {9F4DA8E9-F253-4312-A0BB-E2873A21C41A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9F4DA8E9-F253-4312-A0BB-E2873A21C41A}.Release|Any CPU.Build.0 = Release|Any CPU + {9F4DA8E9-F253-4312-A0BB-E2873A21C41A}.Release|x64.ActiveCfg = Release|Any CPU + {9F4DA8E9-F253-4312-A0BB-E2873A21C41A}.Release|x64.Build.0 = Release|Any CPU + {9F4DA8E9-F253-4312-A0BB-E2873A21C41A}.Release|x86.ActiveCfg = Release|Any CPU + {9F4DA8E9-F253-4312-A0BB-E2873A21C41A}.Release|x86.Build.0 = Release|Any CPU + {2FC86574-6A81-4E2B-A0D4-78D46528A917}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2FC86574-6A81-4E2B-A0D4-78D46528A917}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2FC86574-6A81-4E2B-A0D4-78D46528A917}.Debug|x64.ActiveCfg = Debug|Any CPU + {2FC86574-6A81-4E2B-A0D4-78D46528A917}.Debug|x64.Build.0 = Debug|Any CPU + {2FC86574-6A81-4E2B-A0D4-78D46528A917}.Debug|x86.ActiveCfg = Debug|Any CPU + {2FC86574-6A81-4E2B-A0D4-78D46528A917}.Debug|x86.Build.0 = Debug|Any CPU + {2FC86574-6A81-4E2B-A0D4-78D46528A917}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2FC86574-6A81-4E2B-A0D4-78D46528A917}.Release|Any CPU.Build.0 = Release|Any CPU + {2FC86574-6A81-4E2B-A0D4-78D46528A917}.Release|x64.ActiveCfg = Release|Any CPU + {2FC86574-6A81-4E2B-A0D4-78D46528A917}.Release|x64.Build.0 = Release|Any CPU + {2FC86574-6A81-4E2B-A0D4-78D46528A917}.Release|x86.ActiveCfg = Release|Any CPU + {2FC86574-6A81-4E2B-A0D4-78D46528A917}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -304,8 +342,12 @@ Global {A3C52771-3B41-43F6-A4DD-7B3F7BAA598D} = {D625B898-1677-4DCA-B067-C7BFB07F1314} {C5B72F44-C52D-471D-BE29-DB1C34699220} = {DA3D8137-F2DD-465D-81AA-3CA5C75087D2} {FE082318-2993-42A3-B2DB-28EDA77F7136} = {C5B72F44-C52D-471D-BE29-DB1C34699220} - {3AD6FEBE-37E9-436E-BE86-29668A9DDB3E} = {DA3D8137-F2DD-465D-81AA-3CA5C75087D2} {C6911A37-51F3-4E29-8E67-39B460EE7ABA} = {3AD6FEBE-37E9-436E-BE86-29668A9DDB3E} + {3AD6FEBE-37E9-436E-BE86-29668A9DDB3E} = {DA3D8137-F2DD-465D-81AA-3CA5C75087D2} + {7F6A5D8C-9780-4824-8284-CC3149683C70} = {DA3D8137-F2DD-465D-81AA-3CA5C75087D2} + {9F4DA8E9-F253-4312-A0BB-E2873A21C41A} = {7F6A5D8C-9780-4824-8284-CC3149683C70} + {AE430C04-78BD-4CAE-86D7-EBC599774D9C} = {DA3D8137-F2DD-465D-81AA-3CA5C75087D2} + {2FC86574-6A81-4E2B-A0D4-78D46528A917} = {AE430C04-78BD-4CAE-86D7-EBC599774D9C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E906E97D-7D56-4E02-A13F-1C48AEB47A88} diff --git a/properties/dapr_sidekick_csharp.props b/properties/dapr_sidekick_csharp.props index 86427a7..e75a343 100644 --- a/properties/dapr_sidekick_csharp.props +++ b/properties/dapr_sidekick_csharp.props @@ -3,13 +3,13 @@ Debug - 8.0 + latest true 4 false false - 1.0.2 + 1.0.3 @@ -42,7 +42,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -50,15 +50,15 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/samples/Actor/ActorSample/ActorSample.ActorClient/ActorSample.ActorClient.csproj b/samples/Actor/ActorSample/ActorSample.ActorClient/ActorSample.ActorClient.csproj index 0715dde..df0e1df 100644 --- a/samples/Actor/ActorSample/ActorSample.ActorClient/ActorSample.ActorClient.csproj +++ b/samples/Actor/ActorSample/ActorSample.ActorClient/ActorSample.ActorClient.csproj @@ -2,11 +2,11 @@ Exe - netcoreapp3.1 + net8.0 - + diff --git a/samples/Actor/ActorSample/ActorSample.DemoActor/ActorSample.DemoActor.csproj b/samples/Actor/ActorSample/ActorSample.DemoActor/ActorSample.DemoActor.csproj index 09dd8e9..e65cb06 100644 --- a/samples/Actor/ActorSample/ActorSample.DemoActor/ActorSample.DemoActor.csproj +++ b/samples/Actor/ActorSample/ActorSample.DemoActor/ActorSample.DemoActor.csproj @@ -1,13 +1,13 @@  - netcoreapp3.1 + net8.0 - - - + + + diff --git a/samples/Actor/ActorSample/ActorSample.IDemoActor/ActorSample.IDemoActor.csproj b/samples/Actor/ActorSample/ActorSample.IDemoActor/ActorSample.IDemoActor.csproj index e76e752..1a2e873 100644 --- a/samples/Actor/ActorSample/ActorSample.IDemoActor/ActorSample.IDemoActor.csproj +++ b/samples/Actor/ActorSample/ActorSample.IDemoActor/ActorSample.IDemoActor.csproj @@ -1,11 +1,11 @@  - netcoreapp3.1 + net8.0 - + diff --git a/samples/AspNetCore/AppConfigurationSample/AppConfigurationSample/AppConfigurationSample.csproj b/samples/AspNetCore/AppConfigurationSample/AppConfigurationSample/AppConfigurationSample.csproj index c0a030a..e10f5f8 100644 --- a/samples/AspNetCore/AppConfigurationSample/AppConfigurationSample/AppConfigurationSample.csproj +++ b/samples/AspNetCore/AppConfigurationSample/AppConfigurationSample/AppConfigurationSample.csproj @@ -1,18 +1,18 @@ - + - net7.0 + net8.0 enable enable 10 - - - - - + + + + + diff --git a/samples/AspNetCore/ConsulSample/ConsulSample.Receiver/ConsulSample.Receiver.csproj b/samples/AspNetCore/ConsulSample/ConsulSample.Receiver/ConsulSample.Receiver.csproj index bacc515..f10af88 100644 --- a/samples/AspNetCore/ConsulSample/ConsulSample.Receiver/ConsulSample.Receiver.csproj +++ b/samples/AspNetCore/ConsulSample/ConsulSample.Receiver/ConsulSample.Receiver.csproj @@ -1,12 +1,12 @@ - net5.0 + net8.0 - - + + diff --git a/samples/AspNetCore/ConsulSample/ConsulSample.Sender/ConsulSample.Sender.csproj b/samples/AspNetCore/ConsulSample/ConsulSample.Sender/ConsulSample.Sender.csproj index bacc515..08dae24 100644 --- a/samples/AspNetCore/ConsulSample/ConsulSample.Sender/ConsulSample.Sender.csproj +++ b/samples/AspNetCore/ConsulSample/ConsulSample.Sender/ConsulSample.Sender.csproj @@ -1,12 +1,13 @@ - net5.0 + net8.0 - - + + + diff --git a/samples/AspNetCore/ConsulSample/README.md b/samples/AspNetCore/ConsulSample/README.md index a576d7d..612ca64 100644 --- a/samples/AspNetCore/ConsulSample/README.md +++ b/samples/AspNetCore/ConsulSample/README.md @@ -1,6 +1,6 @@ # Consul Sample -This example is based on the standard ASP.NET Core 5.0 Web API WeatherForecast template and demonstrates the Service Discovery and Invocation feature of standalone Dapr using Hashicorp Consul as a service discovery provider. While this sample runs on a single machine, it would work exactly the same way if the two services were on different machines with a central Consul cluster. +This example is based on the standard ASP.NET Core Web API WeatherForecast template and demonstrates the Service Discovery and Invocation feature of standalone Dapr using Hashicorp Consul as a service discovery provider. While this sample runs on a single machine, it would work exactly the same way if the two services were on different machines with a central Consul cluster. ## Features diff --git a/samples/AspNetCore/ControllerSample/ControllerSample/Account.cs b/samples/AspNetCore/ControllerSample/ControllerSample/Account.cs index 1f5b0c9..2e82b21 100644 --- a/samples/AspNetCore/ControllerSample/ControllerSample/Account.cs +++ b/samples/AspNetCore/ControllerSample/ControllerSample/Account.cs @@ -1,4 +1,4 @@ -// ------------------------------------------------------------ +// ------------------------------------------------------------ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. // ------------------------------------------------------------ @@ -20,4 +20,4 @@ public class Account /// public decimal Balance { get; set; } } -} \ No newline at end of file +} diff --git a/samples/AspNetCore/ControllerSample/ControllerSample/ControllerSample.csproj b/samples/AspNetCore/ControllerSample/ControllerSample/ControllerSample.csproj index 1890472..8416539 100644 --- a/samples/AspNetCore/ControllerSample/ControllerSample/ControllerSample.csproj +++ b/samples/AspNetCore/ControllerSample/ControllerSample/ControllerSample.csproj @@ -1,12 +1,12 @@  - netcoreapp3.1 + net8.0 - - + + diff --git a/samples/AspNetCore/ControllerSample/ControllerSample/Transaction.cs b/samples/AspNetCore/ControllerSample/ControllerSample/Transaction.cs index c602180..3ed7556 100644 --- a/samples/AspNetCore/ControllerSample/ControllerSample/Transaction.cs +++ b/samples/AspNetCore/ControllerSample/ControllerSample/Transaction.cs @@ -1,4 +1,4 @@ -// ------------------------------------------------------------ +// ------------------------------------------------------------ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. // ------------------------------------------------------------ @@ -24,4 +24,4 @@ public class Transaction [Range(0, double.MaxValue)] public decimal Amount { get; set; } } -} \ No newline at end of file +} diff --git a/samples/AspNetCore/PlacementSample/PlacementSample/PlacementSample.csproj b/samples/AspNetCore/PlacementSample/PlacementSample/PlacementSample.csproj new file mode 100644 index 0000000..3de976a --- /dev/null +++ b/samples/AspNetCore/PlacementSample/PlacementSample/PlacementSample.csproj @@ -0,0 +1,26 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + Always + + + Always + + + + diff --git a/samples/AspNetCore/PlacementSample/PlacementSample/Program.cs b/samples/AspNetCore/PlacementSample/PlacementSample/Program.cs new file mode 100644 index 0000000..d2980e1 --- /dev/null +++ b/samples/AspNetCore/PlacementSample/PlacementSample/Program.cs @@ -0,0 +1,39 @@ +using Man.Dapr.Sidekick; +using Serilog; + +// Add Serilog for enhanced console logging. +Log.Logger = new LoggerConfiguration() + .Enrich.FromLogContext() + .WriteTo.Console() + .CreateLogger(); + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddControllers(); + +// Add Dapr Sidekick with Placement +builder.Services.AddDaprSidekick(builder.Configuration) + .AddPlacement(); + +builder.Host.UseSerilog(); + +var app = builder.Build(); + +app.MapGet("/status", (IDaprSidecarHost sidecarHost, IDaprPlacementHost placementHost) => Results.Ok(new +{ + sidecar = new + { + process = sidecarHost.GetProcessInfo(), // Information about the sidecar process such as if it is running + options = sidecarHost.GetProcessOptions() // The sidecar options if running, including ports and locations + }, + placement = new + { + process = placementHost.GetProcessInfo(), // Information about the sentry process such as if it is running + options = placementHost.GetProcessOptions() // The sentry options if running, including ports and locations + }, +})); + +// For Dapr +app.MapHealthChecks("/health"); + +app.Run(); diff --git a/samples/AspNetCore/PlacementSample/PlacementSample/Properties/launchSettings.json b/samples/AspNetCore/PlacementSample/PlacementSample/Properties/launchSettings.json new file mode 100644 index 0000000..31b5f24 --- /dev/null +++ b/samples/AspNetCore/PlacementSample/PlacementSample/Properties/launchSettings.json @@ -0,0 +1,13 @@ +{ + "profiles": { + "PlacementSample": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "status", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:5000" + } + } +} \ No newline at end of file diff --git a/samples/AspNetCore/PlacementSample/PlacementSample/appsettings.Development.json b/samples/AspNetCore/PlacementSample/PlacementSample/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/samples/AspNetCore/PlacementSample/PlacementSample/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/samples/AspNetCore/PlacementSample/PlacementSample/appsettings.json b/samples/AspNetCore/PlacementSample/PlacementSample/appsettings.json new file mode 100644 index 0000000..409dad1 --- /dev/null +++ b/samples/AspNetCore/PlacementSample/PlacementSample/appsettings.json @@ -0,0 +1,19 @@ +{ + "DaprSidekick": { + "Sidecar": { + "RuntimeDirectory": "dapr" + }, + "Placement": { + "RuntimeDirectory": "placement", + "Id": "dapr-placement-0", // Optional unique identifier when used in a cluster + "Port": 6051 // To avoid conflicts with local Dapr Placement container. Sidecar will use this automatically as well. + } + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/samples/AspNetCore/PlacementSample/PlacementSample/dapr/config.yaml b/samples/AspNetCore/PlacementSample/PlacementSample/dapr/config.yaml new file mode 100644 index 0000000..4b11e3a --- /dev/null +++ b/samples/AspNetCore/PlacementSample/PlacementSample/dapr/config.yaml @@ -0,0 +1,8 @@ +apiVersion: dapr.io/v1alpha1 +kind: Configuration +metadata: + name: daprsystem + namespace: default +spec: + mtls: + enabled: true \ No newline at end of file diff --git a/samples/AspNetCore/PlacementSample/PlacementSample/placement/config.yaml b/samples/AspNetCore/PlacementSample/PlacementSample/placement/config.yaml new file mode 100644 index 0000000..60702f9 --- /dev/null +++ b/samples/AspNetCore/PlacementSample/PlacementSample/placement/config.yaml @@ -0,0 +1,6 @@ +apiVersion: dapr.io/v1alpha1 +kind: Configuration +metadata: + name: daprsystem + namespace: default +spec: diff --git a/samples/AspNetCore/PlacementSample/README.md b/samples/AspNetCore/PlacementSample/README.md new file mode 100644 index 0000000..ac72ff5 --- /dev/null +++ b/samples/AspNetCore/PlacementSample/README.md @@ -0,0 +1,42 @@ +# Placement example + +This sample shows how Dapr Sidekick can be used to host the Dapr Placement service alongside a Dapr Sidecar instance. Sidekick will launch the Placement service and wait for it +to enter a healthy running state, then will launch the Sidecar alongside. The Sidecar will be configured to use the launched Placement service by default. +As with the Sidecar, the Placement service will be continually monitored and maintained for the lifetime of the application. + +## How Dapr Sidekick was added + +This is an ASP.NET Core minimal Web API project. Dapr Sidekick was added to the [Program.cs](PlacementSample\Program.cs) file as follows: + +```csharp +// Add Dapr Sidekick with Placement +builder.Services.AddDaprSidekick(builder.Configuration) + .AddPlacement(); +``` + +Typically when installing Dapr in self-hosted mode, a Placement service container is added to Docker exposing the default port 6500. If this samle is run +while that container is up it will be unable to start due to a port conflict. Instead a different port 6501 is assigned to Placement in configuration: + +```json5 +"Placement": { + "RuntimeDirectory": "placement", + "Id": "dapr-placement-0", // Optional unique identifier when used in a cluster + "Port": 6051 // To avoid conflicts with local Dapr Placement container. Sidecar will use this automatically as well. +} +``` + +By default the Sidecar that is launched alongside the Placement service will look for the Placement service locally on this custom port, +unless a specific remote address is defined. For example the following specifies a three-host remote Placement cluster: + +```json5 +"Sidecar": { + "PlacementHostAddress": "remote-host-1:6050,remote-host-2:6050,remote-host-3:6050" +} +``` + +## Running the sample + + To run the sample simply set `PlacementSample` as the startup project and run it in Visual Studio, + it will launch first the Placement service then the Dapr sidecar, then open a browser and display + the configured launch options for both. + diff --git a/samples/AspNetCore/SentrySample/README.md b/samples/AspNetCore/SentrySample/README.md new file mode 100644 index 0000000..ccec37a --- /dev/null +++ b/samples/AspNetCore/SentrySample/README.md @@ -0,0 +1,54 @@ +# Sentry example + +This sample shows how Dapr Sidekick can be used to host the Dapr Sentry service alongside a Dapr Sidecar instance. Sidekick will launch the Sentry service and wait for it +to enter a healthy running state, then will launch the Sidecar alongside. The Sidecar will be configured to use the launched Sentry service by default. +As with the Sidecar, the Sentry service will be continually monitored and maintained for the lifetime of the application. + +## How Dapr Sidekick was added + +This is an ASP.NET Core minimal Web API project. Dapr Sidekick was added to the [Program.cs](SentrySample\Program.cs) file as follows: + +```csharp +// Add Dapr Sidekick with Sentry +builder.Services.AddDaprSidekick(builder.Configuration) + .AddSentry(); +``` + +Sentry requires some certificates on startup to configure the trust chain for its internal CA and the mTLS certificates it generates. +By default it will look for these in a `certs` subfolder under the runtime configuration folder, although this can +be overridden using the `--issuer-credentials` command-line argument which Sidekick supports via the `CertsDirectory` property: + +```json5 +"Sentry": { + "CertsDirectory": "/path/to/certs/directory" +} +``` + +For this sample a `certs` folder has been included in the project which Sidekick will automatically use to configure Sentry. +The files contained in the folder were auto-generated by Sentry itself on startup. + +The Sidecar is also configured to use the same certificates to enable mTLS, and on startup the launched Sentry +instance will assign an mTLS certificate to the sidecar with a TTL value defined by [configuration](SentrySample/sentry/config.yaml). +The Sidecar mTLS secrest are typically injected using environment variables, Sidekick supports also defining these +via configuration and will inject them as necessary. One way of achieving this is demonstrated in [Program.cs](SentrySample\Program.cs): + +```csharp +// Inject Sentry certificates into the Dapr sidecar to verify mTLS operation +builder.Services.PostConfigure(options => +{ + var certsFolder = "sentry/certs/"; + + // Assign security defaults (trust chain, certificates and keys) from embedded resources. + // This needs to be replaced with proper certificate distribution in the future. + options.TrustAnchorsCertificate ??= File.ReadAllText(certsFolder + DaprConstants.TrustAnchorsCertificateFilename); + options.IssuerCertificate ??= File.ReadAllText(certsFolder + DaprConstants.IssuerCertificateFilename); + options.IssuerKey ??= File.ReadAllText(certsFolder + DaprConstants.IssuerKeyFilename); +}); +``` + +## Running the sample + + To run the sample simply set `SentrySample` as the startup project and run it in Visual Studio, + it will launch first the Sentry service then the Dapr sidecar, then open a browser and display + the configured launch options for both. + diff --git a/samples/AspNetCore/SentrySample/SentrySample/Program.cs b/samples/AspNetCore/SentrySample/SentrySample/Program.cs new file mode 100644 index 0000000..b1aba75 --- /dev/null +++ b/samples/AspNetCore/SentrySample/SentrySample/Program.cs @@ -0,0 +1,49 @@ +using Man.Dapr.Sidekick; +using Serilog; + +// Add Serilog for enhanced console logging. +Log.Logger = new LoggerConfiguration() + .Enrich.FromLogContext() + .WriteTo.Console() + .CreateLogger(); + +var builder = WebApplication.CreateBuilder(args); + +// Add Dapr Sidekick with Sentry +builder.Services.AddDaprSidekick(builder.Configuration) + .AddSentry(); + +// Inject Sentry certificates into the Dapr sidecar to verify mTLS operation +builder.Services.PostConfigure(options => +{ + var certsFolder = "sentry/certs/"; + + // Assign security defaults (trust chain, certificates and keys) from embedded resources. + // This needs to be replaced with proper certificate distribution in the future. + options.TrustAnchorsCertificate ??= File.ReadAllText(certsFolder + DaprConstants.TrustAnchorsCertificateFilename); + options.IssuerCertificate ??= File.ReadAllText(certsFolder + DaprConstants.IssuerCertificateFilename); + options.IssuerKey ??= File.ReadAllText(certsFolder + DaprConstants.IssuerKeyFilename); +}); + +builder.Host.UseSerilog(); + +var app = builder.Build(); + +app.MapGet("/status", (IDaprSidecarHost sidecarHost, IDaprSentryHost sentryHost) => Results.Ok(new +{ + sidecar = new + { + process = sidecarHost.GetProcessInfo(), // Information about the sidecar process such as if it is running + options = sidecarHost.GetProcessOptions() // The sidecar options if running, including ports and locations + }, + sentry = new + { + process = sentryHost.GetProcessInfo(), // Information about the sentry process such as if it is running + options = sentryHost.GetProcessOptions() // The sentry options if running, including ports and locations + }, +})); + +// For Dapr +app.MapHealthChecks("/health"); + +app.Run(); diff --git a/samples/AspNetCore/SentrySample/SentrySample/Properties/launchSettings.json b/samples/AspNetCore/SentrySample/SentrySample/Properties/launchSettings.json new file mode 100644 index 0000000..85dbf4d --- /dev/null +++ b/samples/AspNetCore/SentrySample/SentrySample/Properties/launchSettings.json @@ -0,0 +1,13 @@ +{ + "profiles": { + "SentrySample": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "status", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:5000" + } + } +} \ No newline at end of file diff --git a/samples/AspNetCore/SentrySample/SentrySample/SentrySample.csproj b/samples/AspNetCore/SentrySample/SentrySample/SentrySample.csproj new file mode 100644 index 0000000..ee1b7b3 --- /dev/null +++ b/samples/AspNetCore/SentrySample/SentrySample/SentrySample.csproj @@ -0,0 +1,26 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + Always + + + Always + + + + diff --git a/samples/AspNetCore/SentrySample/SentrySample/appsettings.Development.json b/samples/AspNetCore/SentrySample/SentrySample/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/samples/AspNetCore/SentrySample/SentrySample/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/samples/AspNetCore/SentrySample/SentrySample/appsettings.json b/samples/AspNetCore/SentrySample/SentrySample/appsettings.json new file mode 100644 index 0000000..c9ccc93 --- /dev/null +++ b/samples/AspNetCore/SentrySample/SentrySample/appsettings.json @@ -0,0 +1,20 @@ +{ + "DaprSidekick": { + "Sidecar": { + "mTLS": true, + "RuntimeDirectory": "dapr", + "SentryAddress": "localhost:50001" + }, + "Sentry": { + "RuntimeDirectory": "sentry", + "TrustDomain": "cluster.local" // Certificates in /certs folder generated for this domain + } + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/samples/AspNetCore/SentrySample/SentrySample/dapr/config.yaml b/samples/AspNetCore/SentrySample/SentrySample/dapr/config.yaml new file mode 100644 index 0000000..4b11e3a --- /dev/null +++ b/samples/AspNetCore/SentrySample/SentrySample/dapr/config.yaml @@ -0,0 +1,8 @@ +apiVersion: dapr.io/v1alpha1 +kind: Configuration +metadata: + name: daprsystem + namespace: default +spec: + mtls: + enabled: true \ No newline at end of file diff --git a/samples/AspNetCore/SentrySample/SentrySample/sentry/certs/ca.crt b/samples/AspNetCore/SentrySample/SentrySample/sentry/certs/ca.crt new file mode 100644 index 0000000..9c769d6 --- /dev/null +++ b/samples/AspNetCore/SentrySample/SentrySample/sentry/certs/ca.crt @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBcjCCARegAwIBAgIRAPNjhmnvu5t1cT4RleqbpIgwCgYIKoZIzj0EAwIwGDEW +MBQGA1UEChMNY2x1c3Rlci5sb2NhbDAeFw0yNDA0MDkxNjMxNDVaFw0yNTA0MDkx +NjQ2NDVaMBgxFjAUBgNVBAoTDWNsdXN0ZXIubG9jYWwwWTATBgcqhkjOPQIBBggq +hkjOPQMBBwNCAAQnuU4Xu2OicVtxHSvpByI4Q3v3Ld4UKpMKvR3+iPs0goJRmkOd ++rgKfUJRu99Al89iF1Jc0xp2G3hqsTJzRNGmo0IwQDAOBgNVHQ8BAf8EBAMCAqQw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUClFVts/NEUrgwtxGRVHYdsr5MkAw +CgYIKoZIzj0EAwIDSQAwRgIhAL1kZ/CgvaVstjh6Wl7Xpq9S5cqL/uDBP8qA535J +gEEhAiEAiPkgINWSCjvunsyCS2MzGRqzXS5F9hSMsl8JJvAAk3A= +-----END CERTIFICATE----- diff --git a/samples/AspNetCore/SentrySample/SentrySample/sentry/certs/issuer.crt b/samples/AspNetCore/SentrySample/SentrySample/sentry/certs/issuer.crt new file mode 100644 index 0000000..a314822 --- /dev/null +++ b/samples/AspNetCore/SentrySample/SentrySample/sentry/certs/issuer.crt @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBqzCCAVGgAwIBAgIRAIwB5uvnwvPxdYpnXs68vxAwCgYIKoZIzj0EAwIwGDEW +MBQGA1UEChMNY2x1c3Rlci5sb2NhbDAeFw0yNDA0MDkxNjMxNDVaFw0yNTA0MDkx +NjQ2NDVaMDgxNjA0BgNVBAoTLXNwaWZmZTovL2NsdXN0ZXIubG9jYWwvbnMvZGVm +YXVsdC9kYXByLXNlbnRyeTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABIlCFe0s +g2hyCoT+jtFfIUKPLcJmT6kI1cOWhd9lEdKxRQQK0WAIpgLoBU1dV/bQEh2vTI7h ++UP8JYTib6RLy5mjXDBaMA4GA1UdDwEB/wQEAwIBpjAPBgNVHRMBAf8EBTADAQH/ +MB0GA1UdDgQWBBRDRvGl7xL2km4sd7pln3ayKZEv3DAYBgNVHREEETAPgg1jbHVz +dGVyLmxvY2FsMAoGCCqGSM49BAMCA0gAMEUCIGMbBjjNPM2lgSojy4Zdr3EZO4qZ +7QUC39qit7zrHEaUAiEA2GHEgHHu7gJdDoTz9Up+jSjIfDIRNgOqUpHsldEwN0c= +-----END CERTIFICATE----- diff --git a/samples/AspNetCore/SentrySample/SentrySample/sentry/certs/issuer.key b/samples/AspNetCore/SentrySample/SentrySample/sentry/certs/issuer.key new file mode 100644 index 0000000..ac1534a --- /dev/null +++ b/samples/AspNetCore/SentrySample/SentrySample/sentry/certs/issuer.key @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgwVI9SsqI5owZm19/ +NI2uN4yp9WkqE8W8/zhM4AZOvwahRANCAASJQhXtLINocgqE/o7RXyFCjy3CZk+p +CNXDloXfZRHSsUUECtFgCKYC6AVNXVf20BIdr0yO4flD/CWE4m+kS8uZ +-----END PRIVATE KEY----- diff --git a/samples/AspNetCore/SentrySample/SentrySample/sentry/config.yaml b/samples/AspNetCore/SentrySample/SentrySample/sentry/config.yaml new file mode 100644 index 0000000..ac427af --- /dev/null +++ b/samples/AspNetCore/SentrySample/SentrySample/sentry/config.yaml @@ -0,0 +1,12 @@ +apiVersion: dapr.io/v1alpha1 +kind: Configuration +metadata: + name: daprsystem + namespace: default +spec: + mtls: + enabled: true + workloadCertTTL: "24h" + allowedClockSkew: "15m" + accessControl: + defaultAction: allow \ No newline at end of file diff --git a/samples/AspNetCore/ServiceInvocationSample/ServiceInvocationSample/ServiceInvocationSample.csproj b/samples/AspNetCore/ServiceInvocationSample/ServiceInvocationSample/ServiceInvocationSample.csproj index 4b8af5e..3b7c285 100644 --- a/samples/AspNetCore/ServiceInvocationSample/ServiceInvocationSample/ServiceInvocationSample.csproj +++ b/samples/AspNetCore/ServiceInvocationSample/ServiceInvocationSample/ServiceInvocationSample.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1 + net8.0 @@ -9,7 +9,8 @@ - + + diff --git a/src/Directory.build.props b/src/Directory.build.props index 3b8173e..d77e0c8 100644 --- a/src/Directory.build.props +++ b/src/Directory.build.props @@ -15,7 +15,7 @@ true - + diff --git a/src/Man.Dapr.Sidekick.AspNetCore/DaprHostedService.cs b/src/Man.Dapr.Sidekick.AspNetCore/DaprHostedService.cs index af04314..0107751 100644 --- a/src/Man.Dapr.Sidekick.AspNetCore/DaprHostedService.cs +++ b/src/Man.Dapr.Sidekick.AspNetCore/DaprHostedService.cs @@ -31,7 +31,8 @@ public virtual Task StartAsync(CancellationToken cancellationToken) var options = _optionsAccessor.CurrentValue; OnStarting(options, cancellationToken); return options; - }, new DaprCancellationToken(cancellationToken)); + }, + new DaprCancellationToken(cancellationToken)); return Task.CompletedTask; } diff --git a/src/Man.Dapr.Sidekick.AspNetCore/Man.Dapr.Sidekick.AspNetCore.csproj b/src/Man.Dapr.Sidekick.AspNetCore/Man.Dapr.Sidekick.AspNetCore.csproj index 467666c..17c4d94 100644 --- a/src/Man.Dapr.Sidekick.AspNetCore/Man.Dapr.Sidekick.AspNetCore.csproj +++ b/src/Man.Dapr.Sidekick.AspNetCore/Man.Dapr.Sidekick.AspNetCore.csproj @@ -1,7 +1,7 @@  - net462;netstandard2.0;netcoreapp3.1;net5.0 + net462;netstandard2.0;net6.0;net8.0 This package contains the reference assemblies for developing services using Dapr Sidekick and ASP.NET Core. Man.Dapr.Sidekick.AspNetCore @@ -16,7 +16,7 @@ - + diff --git a/src/Man.Dapr.Sidekick.AspNetCore/Metrics/IDaprMetricsCollector.cs b/src/Man.Dapr.Sidekick.AspNetCore/Metrics/IDaprMetricsCollector.cs index 0aa6bc4..98d1ffd 100644 --- a/src/Man.Dapr.Sidekick.AspNetCore/Metrics/IDaprMetricsCollector.cs +++ b/src/Man.Dapr.Sidekick.AspNetCore/Metrics/IDaprMetricsCollector.cs @@ -3,4 +3,4 @@ internal interface IDaprMetricsCollector { } -} \ No newline at end of file +} diff --git a/src/Man.Dapr.Sidekick.AspNetCore/Metrics/PrometheusTextReader.cs b/src/Man.Dapr.Sidekick.AspNetCore/Metrics/PrometheusTextReader.cs index 41c62d0..93bd04d 100644 --- a/src/Man.Dapr.Sidekick.AspNetCore/Metrics/PrometheusTextReader.cs +++ b/src/Man.Dapr.Sidekick.AspNetCore/Metrics/PrometheusTextReader.cs @@ -76,7 +76,7 @@ public async Task ReadAsync(Stream source, CancellationToken cancellationToken) } } - private (LineType lineType, string name) IdentifyLine(string line) + private (LineType LineType, string Name) IdentifyLine(string line) { if (string.IsNullOrEmpty(line)) { diff --git a/src/Man.Dapr.Sidekick.AspNetCore/Placement/DaprPlacementSidecarHostedService.cs b/src/Man.Dapr.Sidekick.AspNetCore/Placement/DaprPlacementSidecarHostedService.cs index 1636fe3..87263f7 100644 --- a/src/Man.Dapr.Sidekick.AspNetCore/Placement/DaprPlacementSidecarHostedService.cs +++ b/src/Man.Dapr.Sidekick.AspNetCore/Placement/DaprPlacementSidecarHostedService.cs @@ -46,7 +46,8 @@ await Task.Run( processInfo = _daprPlacementHost.GetProcessInfo(); } - }, cancellationToken) + }, + cancellationToken) .ContinueWith(_ => base.StartAsync(cancellationToken)); } } diff --git a/src/Man.Dapr.Sidekick.AspNetCore/Sentry/DaprSentrySidecarHostedService.cs b/src/Man.Dapr.Sidekick.AspNetCore/Sentry/DaprSentrySidecarHostedService.cs index df8331a..23e3067 100644 --- a/src/Man.Dapr.Sidekick.AspNetCore/Sentry/DaprSentrySidecarHostedService.cs +++ b/src/Man.Dapr.Sidekick.AspNetCore/Sentry/DaprSentrySidecarHostedService.cs @@ -46,7 +46,8 @@ await Task.Run( processInfo = _daprSentryHost.GetProcessInfo(); } - }, cancellationToken) + }, + cancellationToken) .ContinueWith(_ => base.StartAsync(cancellationToken)); } } diff --git a/src/Man.Dapr.Sidekick.Extensions.Logging/Man.Dapr.Sidekick.Extensions.Logging.csproj b/src/Man.Dapr.Sidekick.Extensions.Logging/Man.Dapr.Sidekick.Extensions.Logging.csproj index 2de5e2c..e403712 100644 --- a/src/Man.Dapr.Sidekick.Extensions.Logging/Man.Dapr.Sidekick.Extensions.Logging.csproj +++ b/src/Man.Dapr.Sidekick.Extensions.Logging/Man.Dapr.Sidekick.Extensions.Logging.csproj @@ -1,7 +1,7 @@  - net45;net461;netstandard2.0;netcoreapp3.1;net5.0 + net45;net461;netstandard2.0;net6.0;net8.0 This package contains the reference assemblies for routing Dapr Sidekick logging messages through the Microsoft Extensions Logging framework. Man.Dapr.Sidekick.Extensions.Logging @@ -18,12 +18,12 @@ - - + + - - + + diff --git a/src/Man.Dapr.Sidekick/Man.Dapr.Sidekick.csproj b/src/Man.Dapr.Sidekick/Man.Dapr.Sidekick.csproj index d028bc4..0306226 100644 --- a/src/Man.Dapr.Sidekick/Man.Dapr.Sidekick.csproj +++ b/src/Man.Dapr.Sidekick/Man.Dapr.Sidekick.csproj @@ -1,14 +1,14 @@  - net35;net45;net461;netstandard2.0;netcoreapp3.1;net5.0 + net35;net45;net461;netstandard2.0;net6.0;net8.0 true This package contains the reference assemblies for developing services using Dapr Sidekick. Man.Dapr.Sidekick - + diff --git a/src/Man.Dapr.Sidekick/Options/DaprPlacementOptions.cs b/src/Man.Dapr.Sidekick/Options/DaprPlacementOptions.cs index 9a87da6..da8729f 100644 --- a/src/Man.Dapr.Sidekick/Options/DaprPlacementOptions.cs +++ b/src/Man.Dapr.Sidekick/Options/DaprPlacementOptions.cs @@ -7,6 +7,7 @@ public class DaprPlacementOptions : Options.DaprProcessOptions /// /// Gets or sets the path to the credentials directory holding the issuer data. /// If not specified this will default to a directory called "certs" under the runtime folder. + /// Deprecated since 1.12.0. /// public string CertsDirectory { get; set; } @@ -65,6 +66,18 @@ public class DaprPlacementOptions : Options.DaprProcessOptions /// public int? ReplicationFactor { get; set; } + /// + /// Gets or sets the filepath to the trust anchors for the Dapr control plane (default "/var/run/secrets/dapr.io/tls/ca.crt"). + /// Available since 1.12.0. + /// + public string TrustAnchorsFile { get; set; } + + /// + /// Gets or sets the trust domain for the Dapr control plane (default "localhost"). + /// Available since 1.12.0. + /// + public string TrustDomain { get; set; } + /// /// Creates a deep clone of this instance. /// diff --git a/src/Man.Dapr.Sidekick/Options/DaprProcessOptions.cs b/src/Man.Dapr.Sidekick/Options/DaprProcessOptions.cs index 6ffb172..22e19d5 100644 --- a/src/Man.Dapr.Sidekick/Options/DaprProcessOptions.cs +++ b/src/Man.Dapr.Sidekick/Options/DaprProcessOptions.cs @@ -112,6 +112,13 @@ public abstract class DaprProcessOptions /// public Dictionary EnvironmentVariables { get; set; } + /// + /// Gets or sets the minimum version of the Dapr runtime being used with Sidekick. + /// Certain features/behaviour will be configured based on this value. + /// Defaults to latest known version. + /// + public Version RuntimeVersion { get; set; } + /// /// Creates a deep clone of this instance. /// @@ -146,6 +153,7 @@ public void EnrichFrom(DaprProcessOptions source) RestartAfterMillseconds ??= source.RestartAfterMillseconds; RetainPortsOnRestart ??= source.RetainPortsOnRestart; RuntimeDirectory ??= source.RuntimeDirectory; + RuntimeVersion ??= (Version)source.RuntimeVersion?.Clone(); WaitForShutdownSeconds ??= source.WaitForShutdownSeconds; TrustAnchorsCertificate ??= source.TrustAnchorsCertificate; @@ -179,6 +187,28 @@ public void EnrichFrom(DaprProcessOptions source) /// The metrics endpoint address. public Uri GetMetricsUri() => GetLocalUri(builder => AddMetricsUri(builder)); + internal bool IsRuntimeVersionEarlierThan(string version) + { + if (RuntimeVersion == null) + { + // Assume latest + return false; + } +#if NET35 + try + { + return RuntimeVersion < new Version(version); + } + catch + { + // Cannot parse + return false; + } +#else + return Version.TryParse(version, out var v) && RuntimeVersion < v; +#endif + } + protected virtual bool AddHealthUri(UriBuilder builder) => false; protected virtual bool AddMetricsUri(UriBuilder builder) => false; diff --git a/src/Man.Dapr.Sidekick/Process/DaprPlacementProcess.cs b/src/Man.Dapr.Sidekick/Process/DaprPlacementProcess.cs index a8dbed4..64fafcc 100644 --- a/src/Man.Dapr.Sidekick/Process/DaprPlacementProcess.cs +++ b/src/Man.Dapr.Sidekick/Process/DaprPlacementProcess.cs @@ -18,6 +18,8 @@ internal class DaprPlacementProcess : DaprProcess, IDaprPl private const string RaftLogstorePathArgument = "raft-logstore-path"; private const string ReplicationFactorArgument = "replicationfactor"; private const string TlsEnabledArgument = "tls-enabled"; + private const string TrustAnchorsFileArgument = "trust-anchors-file"; + private const string TrustDomainArgument = "trust-domain"; public DaprPlacementProcess() : base(DaprConstants.DaprPlacementProcessName) @@ -54,8 +56,16 @@ protected override void AssignLocations(DaprPlacementOptions options, string dap // Write any defined certificate options WriteDefaultCertificates(certsDirectory, options); - // Update the values - options.CertsDirectory = certsDirectory; + if (options.IsRuntimeVersionEarlierThan("1.12.0")) + { + // < 1.12.0 : Pass the certs directory to placement + options.CertsDirectory ??= certsDirectory; + } + else + { + // >= 1.12.0 : Pass the trust anchors file to placement + options.TrustAnchorsFile ??= Path.Combine(certsDirectory, DaprConstants.TrustAnchorsCertificateFilename); + } } protected override void AddCommandLineArguments(DaprPlacementOptions source, CommandLineArgumentBuilder builder) => builder @@ -72,6 +82,8 @@ protected override void AddCommandLineArguments(DaprPlacementOptions source, Com .Add(RaftLogstorePathArgument, source.RaftLogstorePath) .Add(ReplicationFactorArgument, source.ReplicationFactor) .Add(TlsEnabledArgument, source.Mtls) + .Add(TrustAnchorsFileArgument, source.TrustAnchorsFile) + .Add(TrustDomainArgument, source.TrustDomain) .Add(source.CustomArguments, requiresValue: false); protected override void AddEnvironmentVariables(DaprPlacementOptions source, EnvironmentVariableBuilder builder) => builder diff --git a/src/Man.Dapr.Sidekick/Process/DaprProcessLogger.cs b/src/Man.Dapr.Sidekick/Process/DaprProcessLogger.cs index dc7cd60..293674c 100644 --- a/src/Man.Dapr.Sidekick/Process/DaprProcessLogger.cs +++ b/src/Man.Dapr.Sidekick/Process/DaprProcessLogger.cs @@ -135,6 +135,16 @@ private void InterpretMessage(string message) { // Dapr Sentry // "sentry certificate authority is running, protecting ya'll" + // Removed in v1.12 by this commit: + // https://github.com/dapr/dapr/commit/c5857298afb76a8391af661c60f871f619f5e802#diff-3632294a2f84c023f9eb91f36196518238d6c2c1497167573b10ea986f128203L106 + _processUpdater.UpdateStatus(DaprProcessStatus.Started); + } + else if (Regex.Match(message, "([Rr]unning [Gg][Rr][Pp][Cc]) server").Success) + { + // Dapr Sentry + // "running grpc server on port 50001" + // Added in v1.12 by this commit: + // https://github.com/dapr/dapr/commit/c5857298afb76a8391af661c60f871f619f5e802#diff-5a930421edf435ae1ca5033ee89f375cd66781a7fd90f7c99db494242eda0eb1R83 _processUpdater.UpdateStatus(DaprProcessStatus.Started); } else if (Regex.Match(message, "([Ss]top).+([Ss]hutting).+([Dd]own)").Success) diff --git a/tests/Directory.build.props b/tests/Directory.build.props index 4c8c623..48172dc 100644 --- a/tests/Directory.build.props +++ b/tests/Directory.build.props @@ -20,8 +20,8 @@ - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/tests/Man.Dapr.Sidekick.AspNetCore.Tests/DaprSidekickServiceCollectionExtensionsTests.cs b/tests/Man.Dapr.Sidekick.AspNetCore.Tests/DaprSidekickServiceCollectionExtensionsTests.cs index 3a76745..c1ea275 100644 --- a/tests/Man.Dapr.Sidekick.AspNetCore.Tests/DaprSidekickServiceCollectionExtensionsTests.cs +++ b/tests/Man.Dapr.Sidekick.AspNetCore.Tests/DaprSidekickServiceCollectionExtensionsTests.cs @@ -55,7 +55,8 @@ public void Should_add_core_services_with_configure_action() services.AddDaprSidekick(options => { options.ProcessName = "PROCESS_NAME"; - }), Is.InstanceOf()); + }), + Is.InstanceOf()); var provider = services.BuildServiceProvider(); var options = provider.GetRequiredService>(); @@ -81,7 +82,8 @@ public void Should_add_core_services_with_post_configure_action() services.AddDaprSidekick(configuration, options => { options.ProcessName = "PROCESS_NAME"; - }), Is.InstanceOf()); + }), + Is.InstanceOf()); var provider = services.BuildServiceProvider(); var options = provider.GetRequiredService>(); diff --git a/tests/Man.Dapr.Sidekick.AspNetCore.Tests/Http/HttpContextInvocationHandlerTests.cs b/tests/Man.Dapr.Sidekick.AspNetCore.Tests/Http/HttpContextInvocationHandlerTests.cs index 01ec3f6..10a7907 100644 --- a/tests/Man.Dapr.Sidekick.AspNetCore.Tests/Http/HttpContextInvocationHandlerTests.cs +++ b/tests/Man.Dapr.Sidekick.AspNetCore.Tests/Http/HttpContextInvocationHandlerTests.cs @@ -38,7 +38,7 @@ public void Should_add_authorization_header() httpContextAccessor.HttpContext.Returns(httpContext); var handler = new MockHttpContextInvocationHandler(httpContextAccessor); - httpRequest.Headers.Add("Authorization", "AUTH1"); + httpRequest.Headers.Append("Authorization", "AUTH1"); var request = new HttpRequestMessage(); var cancellationToken = CancellationToken.None; @@ -57,7 +57,7 @@ public void Should_throw_exception_when_multiple_authorization_header_values() var handler = new MockHttpContextInvocationHandler(httpContextAccessor); var values = new StringValues(new[] { "AUTH1", "AUTH2" }); - httpRequest.Headers.Add("Authorization", values); + httpRequest.Headers.Append("Authorization", values); var request = new HttpRequestMessage(); var cancellationToken = CancellationToken.None; @@ -94,7 +94,7 @@ public void Should_remove_authorization_header() httpContextAccessor.HttpContext.Returns(httpContext); var handler = new MockHttpContextInvocationHandler(httpContextAccessor); - httpRequest.Headers.Add("Authorization", "AUTH1"); + httpRequest.Headers.Append("Authorization", "AUTH1"); var request = new HttpRequestMessage(); request.Headers.Add("Authorization", "AUTH1"); var cancellationToken = CancellationToken.None; diff --git a/tests/Man.Dapr.Sidekick.AspNetCore.Tests/Man.Dapr.Sidekick.AspNetCore.Tests.csproj b/tests/Man.Dapr.Sidekick.AspNetCore.Tests/Man.Dapr.Sidekick.AspNetCore.Tests.csproj index 7e98994..79d5caf 100644 --- a/tests/Man.Dapr.Sidekick.AspNetCore.Tests/Man.Dapr.Sidekick.AspNetCore.Tests.csproj +++ b/tests/Man.Dapr.Sidekick.AspNetCore.Tests/Man.Dapr.Sidekick.AspNetCore.Tests.csproj @@ -1,7 +1,7 @@ - net5.0 + net8.0 false Man.Dapr.Sidekick.AspNetCore diff --git a/tests/Man.Dapr.Sidekick.AspNetCore.Tests/Metrics/DaprMetricsMiddlewareExtensionsTests.cs b/tests/Man.Dapr.Sidekick.AspNetCore.Tests/Metrics/DaprMetricsMiddlewareExtensionsTests.cs index ab620da..e8a8d01 100644 --- a/tests/Man.Dapr.Sidekick.AspNetCore.Tests/Metrics/DaprMetricsMiddlewareExtensionsTests.cs +++ b/tests/Man.Dapr.Sidekick.AspNetCore.Tests/Metrics/DaprMetricsMiddlewareExtensionsTests.cs @@ -1,4 +1,6 @@ -using Microsoft.AspNetCore.Builder; +using System; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; using NSubstitute; using NUnit.Framework; @@ -51,7 +53,7 @@ public void Should_add_without_url() { var builder = Substitute.For(); builder.UseDaprMetricsServer(null); - builder.Received(1).UseMiddleware(typeof(DaprMetricsServerMiddleware)); + builder.Received(1).Use(Arg.Any>()); } } } diff --git a/tests/Man.Dapr.Sidekick.Extensions.Logging.Tests/Man.Dapr.Sidekick.Extensions.Logging.Tests.csproj b/tests/Man.Dapr.Sidekick.Extensions.Logging.Tests/Man.Dapr.Sidekick.Extensions.Logging.Tests.csproj index 098399d..24f646c 100644 --- a/tests/Man.Dapr.Sidekick.Extensions.Logging.Tests/Man.Dapr.Sidekick.Extensions.Logging.Tests.csproj +++ b/tests/Man.Dapr.Sidekick.Extensions.Logging.Tests/Man.Dapr.Sidekick.Extensions.Logging.Tests.csproj @@ -1,7 +1,7 @@ - net5.0 + net8.0 Man.Dapr.Sidekick.Extensions.Logging false diff --git a/tests/Man.Dapr.Sidekick.Tests/Man.Dapr.Sidekick.Tests.csproj b/tests/Man.Dapr.Sidekick.Tests/Man.Dapr.Sidekick.Tests.csproj index 1df72b3..b2e78b6 100644 --- a/tests/Man.Dapr.Sidekick.Tests/Man.Dapr.Sidekick.Tests.csproj +++ b/tests/Man.Dapr.Sidekick.Tests/Man.Dapr.Sidekick.Tests.csproj @@ -1,7 +1,7 @@  - net35;net48;net5.0 + net35;net48;net8.0 8.0 false Man.Dapr.Sidekick @@ -23,7 +23,7 @@ - + diff --git a/tests/Man.Dapr.Sidekick.Tests/Options/DaprPlacementOptionsTests.cs b/tests/Man.Dapr.Sidekick.Tests/Options/DaprPlacementOptionsTests.cs index c20a30a..93696a6 100644 --- a/tests/Man.Dapr.Sidekick.Tests/Options/DaprPlacementOptionsTests.cs +++ b/tests/Man.Dapr.Sidekick.Tests/Options/DaprPlacementOptionsTests.cs @@ -82,6 +82,7 @@ private static void Compare(DaprPlacementOptions source, DaprPlacementOptions ta Assert.That(target.Port, Is.EqualTo(source.Port)); Assert.That(target.RaftLogstorePath, Is.EqualTo(source.RaftLogstorePath)); Assert.That(target.ReplicationFactor, Is.EqualTo(source.ReplicationFactor)); + Assert.That(target.TrustAnchorsFile, Is.EqualTo(source.TrustAnchorsFile)); } private static DaprPlacementOptions InitValue() => new DaprPlacementOptions @@ -97,7 +98,8 @@ private static void Compare(DaprPlacementOptions source, DaprPlacementOptions ta Mtls = true, Port = 300, RaftLogstorePath = "RaftLogstorePath", - ReplicationFactor = 400 + ReplicationFactor = 400, + TrustAnchorsFile = "TrustAnchorsFile" }; } } diff --git a/tests/Man.Dapr.Sidekick.Tests/Options/DaprProcessOptionsTests.cs b/tests/Man.Dapr.Sidekick.Tests/Options/DaprProcessOptionsTests.cs index 728a91b..d1dab1e 100644 --- a/tests/Man.Dapr.Sidekick.Tests/Options/DaprProcessOptionsTests.cs +++ b/tests/Man.Dapr.Sidekick.Tests/Options/DaprProcessOptionsTests.cs @@ -141,6 +141,25 @@ public void Should_return_null_when_not_overridden() } } + public class IsRuntimeVersionEarlierThan + { + [TestCase(null, null, false)] + [TestCase(null, "0.0.0", false)] + [TestCase("0.0.0", "0.0.0", false)] + [TestCase("1.0.0", "0.1.1", false)] + [TestCase("1.2.3", "1.2.3", false)] + [TestCase("1.0.0", "1.0.1", true)] + public void Should_compare_versions(string runtimeVersion, string inputVersion, bool expected) + { + var source = new MockDaprProcessOptions + { + RuntimeVersion = runtimeVersion != null ? new System.Version(runtimeVersion) : null + }; + + Assert.That(source.IsRuntimeVersionEarlierThan(inputVersion), Is.EqualTo(expected)); + } + } + private static void Compare(DaprProcessOptions source, DaprProcessOptions target, bool sameInstances = false) { if (!sameInstances) @@ -162,6 +181,7 @@ private static void Compare(DaprProcessOptions source, DaprProcessOptions target Assert.That(target.RestartAfterMillseconds, Is.EqualTo(source.RestartAfterMillseconds)); Assert.That(target.RetainPortsOnRestart, Is.EqualTo(source.RetainPortsOnRestart)); Assert.That(target.RuntimeDirectory, Is.EqualTo(source.RuntimeDirectory)); + Assert.That(target.RuntimeVersion, Is.EqualTo(source.RuntimeVersion)); Assert.That(target.WaitForShutdownSeconds, Is.EqualTo(source.WaitForShutdownSeconds)); Assert.That(target.TrustAnchorsCertificate, Is.EqualTo(source.TrustAnchorsCertificate)); } @@ -184,6 +204,7 @@ private static void Compare(DaprProcessOptions source, DaprProcessOptions target RestartAfterMillseconds = 100, RetainPortsOnRestart = true, RuntimeDirectory = "RuntimeDirectory", + RuntimeVersion = new System.Version("1.2.3.4"), WaitForShutdownSeconds = 200, TrustAnchorsCertificate = "TrustAnchorsCertificate" }; diff --git a/tests/Man.Dapr.Sidekick.Tests/Process/DaprPlacementProcessTests.cs b/tests/Man.Dapr.Sidekick.Tests/Process/DaprPlacementProcessTests.cs index bb64be4..ed5fba1 100644 --- a/tests/Man.Dapr.Sidekick.Tests/Process/DaprPlacementProcessTests.cs +++ b/tests/Man.Dapr.Sidekick.Tests/Process/DaprPlacementProcessTests.cs @@ -1,4 +1,5 @@ -using System.IO; +using System; +using System.IO; using Man.Dapr.Sidekick.Logging; using NSubstitute; using NUnit.Framework; @@ -65,12 +66,23 @@ public class AssignLocations public void Should_assign_default_paths() { var p = new MockDaprPlacementProcess(); - var options = new DaprPlacementOptions(); var folder = Path.GetTempPath(); + var options_1_11_2 = new DaprPlacementOptions + { + RuntimeVersion = new Version("1.11.2") + }; + var options_1_12_0 = new DaprPlacementOptions + { + RuntimeVersion = new Version("1.12.0") + }; - p.AssignLocations(options, folder); + p.AssignLocations(options_1_11_2, folder); + Assert.That(options_1_11_2.CertsDirectory, Is.EqualTo(Path.Combine(folder, DaprConstants.DaprCertsDirectory))); + Assert.That(options_1_11_2.TrustAnchorsFile, Is.Null); - Assert.That(options.CertsDirectory, Is.EqualTo(Path.Combine(folder, "certs"))); + p.AssignLocations(options_1_12_0, folder); + Assert.That(options_1_12_0.CertsDirectory, Is.Null); + Assert.That(options_1_12_0.TrustAnchorsFile, Is.EqualTo(Path.Combine(folder, Path.Combine(DaprConstants.DaprCertsDirectory, DaprConstants.TrustAnchorsCertificateFilename)))); } [Test] diff --git a/tests/Man.Dapr.Sidekick.Tests/Process/DaprProcessLoggerTests.cs b/tests/Man.Dapr.Sidekick.Tests/Process/DaprProcessLoggerTests.cs index 9937611..01c94ec 100644 --- a/tests/Man.Dapr.Sidekick.Tests/Process/DaprProcessLoggerTests.cs +++ b/tests/Man.Dapr.Sidekick.Tests/Process/DaprProcessLoggerTests.cs @@ -60,6 +60,7 @@ public void Should_log_invalid_data() [TestCase("placement service started on port 50005", DaprProcessStatus.Started)] [TestCase("some placement service Started on port 54321!", DaprProcessStatus.Started)] [TestCase("sentry certificate authority is running, protecting ya'll", DaprProcessStatus.Started)] + [TestCase("Running gRPC server on port 50001", DaprProcessStatus.Started)] [TestCase("your Sentry service is now Running and protecting everything", DaprProcessStatus.Started)] [TestCase("stop command issued. Shutting down all operations", DaprProcessStatus.Stopping)] [TestCase("stop shutting down", DaprProcessStatus.Stopping)]