From 531cbde56b7b3600202baa85e79ee4905c3328e8 Mon Sep 17 00:00:00 2001 From: witskeeper Date: Sun, 28 Jan 2024 10:57:45 +0800 Subject: [PATCH] refact package --- .github/workflows/dotnet.yml | 2 +- .github/workflows/release.yml | 29 ++++ Directory.Build.targets | 39 +++++ NuGet.config | 3 + README.md | 34 +++- eng/versions.props | 2 +- netcorepal-extensions-yarp.sln | 27 +++- .../IngressServerCertificateManager.cs | 148 ++++++++++++++++++ .../IngressServerCertificateSelector.cs | 55 +++++++ ...etes.Controller.IngressCertificates.csproj | 13 ++ .../ReverseProxyBuilderExtensions.cs | 17 ++ ...orePal.Yarp.ReverseProxy.Dashboard.csproj} | 4 +- .../Pages/_State.cshtml | 2 +- .../Pages/_State.cshtml.cs | 8 +- .../ServiceCollectionExtensions.cs | 15 +- .../wwwroot/css/bootstrap-theme.css | 0 .../wwwroot/css/bootstrap-theme.css.map | 0 .../wwwroot/css/bootstrap-theme.min.css | 0 .../wwwroot/css/bootstrap-theme.min.css.map | 0 .../wwwroot/css/bootstrap.css | 0 .../wwwroot/css/bootstrap.css.map | 0 .../wwwroot/css/bootstrap.min.css | 0 .../wwwroot/css/bootstrap.min.css.map | 0 .../fonts/glyphicons-halflings-regular.eot | Bin .../fonts/glyphicons-halflings-regular.svg | 0 .../fonts/glyphicons-halflings-regular.ttf | Bin .../fonts/glyphicons-halflings-regular.woff | Bin .../fonts/glyphicons-halflings-regular.woff2 | Bin .../wwwroot/js/bootstrap.js | 0 .../wwwroot/js/bootstrap.min.js | 0 .../wwwroot/js/npm.js | 0 .../NetCorePal.Yarp.ServiceDiscovery.csproj} | 1 + .../ReverseProxyBuilderExtensions.cs | 2 +- .../ServiceDiscoveryProxyConfig.cs | 2 +- .../ServiceDiscoveryProxyConfigProvider.cs | 2 +- test/Directory.Build.props | 9 ++ .../IngressControllerTestWebHost.csproj | 14 ++ test/IngressControllerTestWebHost/Program.cs | 26 +++ .../Properties/launchSettings.json | 38 +++++ .../appsettings.Development.json | 15 ++ .../appsettings.json | 9 ++ .../GlobalUsings.cs | 1 + .../IngressServerCertificateSelectorTests.cs | 47 ++++++ ...ontroller.IngressCertificates.Tests.csproj | 30 ++++ 44 files changed, 566 insertions(+), 28 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100644 Directory.Build.targets create mode 100644 src/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates/IngressServerCertificateManager.cs create mode 100644 src/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates/IngressServerCertificateSelector.cs create mode 100644 src/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.csproj create mode 100644 src/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates/ReverseProxyBuilderExtensions.cs rename src/{NetCorePal.Extensions.YarpProxyStateUI/NetCorePal.Extensions.YarpProxyStateUI.csproj => NetCorePal.Yarp.ReverseProxy.Dashboard/NetCorePal.Yarp.ReverseProxy.Dashboard.csproj} (91%) rename src/{NetCorePal.Extensions.YarpProxyStateUI => NetCorePal.Yarp.ReverseProxy.Dashboard}/Pages/_State.cshtml (94%) rename src/{NetCorePal.Extensions.YarpProxyStateUI => NetCorePal.Yarp.ReverseProxy.Dashboard}/Pages/_State.cshtml.cs (78%) rename src/{NetCorePal.Extensions.YarpProxyStateUI => NetCorePal.Yarp.ReverseProxy.Dashboard}/ServiceCollectionExtensions.cs (51%) rename src/{NetCorePal.Extensions.YarpProxyStateUI => NetCorePal.Yarp.ReverseProxy.Dashboard}/wwwroot/css/bootstrap-theme.css (100%) rename src/{NetCorePal.Extensions.YarpProxyStateUI => NetCorePal.Yarp.ReverseProxy.Dashboard}/wwwroot/css/bootstrap-theme.css.map (100%) rename src/{NetCorePal.Extensions.YarpProxyStateUI => NetCorePal.Yarp.ReverseProxy.Dashboard}/wwwroot/css/bootstrap-theme.min.css (100%) rename src/{NetCorePal.Extensions.YarpProxyStateUI => NetCorePal.Yarp.ReverseProxy.Dashboard}/wwwroot/css/bootstrap-theme.min.css.map (100%) rename src/{NetCorePal.Extensions.YarpProxyStateUI => NetCorePal.Yarp.ReverseProxy.Dashboard}/wwwroot/css/bootstrap.css (100%) rename src/{NetCorePal.Extensions.YarpProxyStateUI => NetCorePal.Yarp.ReverseProxy.Dashboard}/wwwroot/css/bootstrap.css.map (100%) rename src/{NetCorePal.Extensions.YarpProxyStateUI => NetCorePal.Yarp.ReverseProxy.Dashboard}/wwwroot/css/bootstrap.min.css (100%) rename src/{NetCorePal.Extensions.YarpProxyStateUI => NetCorePal.Yarp.ReverseProxy.Dashboard}/wwwroot/css/bootstrap.min.css.map (100%) rename src/{NetCorePal.Extensions.YarpProxyStateUI => NetCorePal.Yarp.ReverseProxy.Dashboard}/wwwroot/fonts/glyphicons-halflings-regular.eot (100%) rename src/{NetCorePal.Extensions.YarpProxyStateUI => NetCorePal.Yarp.ReverseProxy.Dashboard}/wwwroot/fonts/glyphicons-halflings-regular.svg (100%) rename src/{NetCorePal.Extensions.YarpProxyStateUI => NetCorePal.Yarp.ReverseProxy.Dashboard}/wwwroot/fonts/glyphicons-halflings-regular.ttf (100%) rename src/{NetCorePal.Extensions.YarpProxyStateUI => NetCorePal.Yarp.ReverseProxy.Dashboard}/wwwroot/fonts/glyphicons-halflings-regular.woff (100%) rename src/{NetCorePal.Extensions.YarpProxyStateUI => NetCorePal.Yarp.ReverseProxy.Dashboard}/wwwroot/fonts/glyphicons-halflings-regular.woff2 (100%) rename src/{NetCorePal.Extensions.YarpProxyStateUI => NetCorePal.Yarp.ReverseProxy.Dashboard}/wwwroot/js/bootstrap.js (100%) rename src/{NetCorePal.Extensions.YarpProxyStateUI => NetCorePal.Yarp.ReverseProxy.Dashboard}/wwwroot/js/bootstrap.min.js (100%) rename src/{NetCorePal.Extensions.YarpProxyStateUI => NetCorePal.Yarp.ReverseProxy.Dashboard}/wwwroot/js/npm.js (100%) rename src/{NetCorePal.Extensions.Yarp.ServiceDiscovery/NetCorePal.Extensions.Yarp.ServiceDiscovery.csproj => NetCorePal.Yarp.ServiceDiscovery/NetCorePal.Yarp.ServiceDiscovery.csproj} (92%) rename src/{NetCorePal.Extensions.Yarp.ServiceDiscovery => NetCorePal.Yarp.ServiceDiscovery}/ReverseProxyBuilderExtensions.cs (93%) rename src/{NetCorePal.Extensions.Yarp.ServiceDiscovery => NetCorePal.Yarp.ServiceDiscovery}/ServiceDiscoveryProxyConfig.cs (91%) rename src/{NetCorePal.Extensions.Yarp.ServiceDiscovery => NetCorePal.Yarp.ServiceDiscovery}/ServiceDiscoveryProxyConfigProvider.cs (94%) create mode 100644 test/Directory.Build.props create mode 100644 test/IngressControllerTestWebHost/IngressControllerTestWebHost.csproj create mode 100644 test/IngressControllerTestWebHost/Program.cs create mode 100644 test/IngressControllerTestWebHost/Properties/launchSettings.json create mode 100644 test/IngressControllerTestWebHost/appsettings.Development.json create mode 100644 test/IngressControllerTestWebHost/appsettings.json create mode 100644 test/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.Tests/GlobalUsings.cs create mode 100644 test/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.Tests/IngressServerCertificateSelectorTests.cs create mode 100644 test/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.Tests/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.Tests.csproj diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 7791fce..fc8f0cd 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -26,5 +26,5 @@ jobs: - name: Pack NuGet run: dotnet pack -c Release --version-suffix preview.1.`date +%y%m%d%H%M` -o ./ - name: Push NuGet - run: dotnet nuget push '*.nupkg' -s https://api.nuget.org/v3/index.json -k ${{ secrets.NUGET_API_KEY }} -n true --skip-duplicate + run: dotnet nuget push '*.nupkg' -s https://www.myget.org/F/netcorepal/api/v3/index.json -k ${{ secrets.MYGET_API_KEY }} -n true --skip-duplicate diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..821637a --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,29 @@ +name: .NET + +on: + push: + tags: + - 'v*' + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Setup .NET + uses: actions/setup-dotnet@v2 + with: + dotnet-version: 6.0.104 + - name: Restore dependencies + run: dotnet restore + - name: Build + run: dotnet build --no-restore + - name: Test + run: dotnet test --no-build --verbosity normal + - name: Pack NuGet + run: dotnet pack -c Release --version-suffix preview.1.`date +%y%m%d%H%M` -o ./ + - name: Push NuGet + run: dotnet nuget push '*.nupkg' -s https://api.nuget.org/v3/index.json -k ${{ secrets.NUGET_API_KEY }} -n true --skip-duplicate + diff --git a/Directory.Build.targets b/Directory.Build.targets new file mode 100644 index 0000000..a9c2664 --- /dev/null +++ b/Directory.Build.targets @@ -0,0 +1,39 @@ + + + 6.0.0 + 6.0.0 + + + 7.0.0 + 7.0.0 + + + 8.0.0 + 8.0.0 + + + + + + + + + + + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + diff --git a/NuGet.config b/NuGet.config index 7ef1014..ad39e34 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,6 +1,9 @@  + + + diff --git a/README.md b/README.md index ccb694b..350ca31 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,35 @@ # netcorepal-extensions-yarp -NetCorePal Extensions for YAEP \ No newline at end of file +[![Release Build](https://img.shields.io/github/actions/workflow/status/netcorepal/netcorepal-extensions-yarp/release.yml?label=release%20build)](https://github.com/netcorepal/netcorepal-extensions-yarp/actions/workflows/release.yml) +[![Preview Build](https://img.shields.io/github/actions/workflow/status/netcorepal/netcorepal-extensions-yarp/dotnet.yml?label=preview%20build)](https://github.com/netcorepal/netcorepal-extensions-yarp/actions/workflows/dotnet.yml) +[![NuGet](https://img.shields.io/nuget/v/NetCorePal.Yarp.ReverseProxy.Dashboard.svg)](https://www.nuget.org/packages/NetCorePal.Yarp.ReverseProxy.Dashboard) +[![MyGet Preview](https://img.shields.io/myget/netcorepal/vpre/NetCorePal.Yarp.ReverseProxy.Dashboard?label=preview)](https://www.myget.org/feed/netcorepal/package/nuget/NetCorePal.Yarp.ReverseProxy.Dashboard) +[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/netcorepal/netcorepal-extensions-yarp/blob/main/LICENSE) + +The Extensions for [YAEP](https://github.com/microsoft/reverse-proxy) + +## Package List + +|Package|Release|Preview| +|---|---|---| +|NetCorePal.Yarp.ReverseProxy.Dashboard|[![NuGet](https://img.shields.io/nuget/v/NetCorePal.Yarp.ReverseProxy.Dashboard.svg)](https://www.nuget.org/packages/NetCorePal.Yarp.ReverseProxy.Dashboard)|[![MyGet Preview](https://img.shields.io/myget/netcorepal/vpre/NetCorePal.Yarp.ReverseProxy.Dashboard?label=preview)](https://www.myget.org/feed/netcorepal/package/nuget/NetCorePal.Yarp.ReverseProxy.Dashboard)| +|NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates|[![NuGet](https://img.shields.io/nuget/v/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.svg)](https://www.nuget.org/packages/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates)|[![MyGet Preview](https://img.shields.io/myget/netcorepal/vpre/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates?label=preview)](https://www.myget.org/feed/netcorepal/package/nuget/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates)| + +## Preview Build + +Preview NuGet Feed: + +```text +https://www.myget.org/F/netcorepal/api/v3/index.json +``` + +NuGet.config: + +```xml + + + + + + +``` diff --git a/eng/versions.props b/eng/versions.props index b02cfd4..ee7f7a8 100644 --- a/eng/versions.props +++ b/eng/versions.props @@ -1,6 +1,6 @@ - 0.1.0 + 0.2.0 diff --git a/netcorepal-extensions-yarp.sln b/netcorepal-extensions-yarp.sln index aaf556d..19a522d 100644 --- a/netcorepal-extensions-yarp.sln +++ b/netcorepal-extensions-yarp.sln @@ -13,9 +13,17 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "解决方案项", "解决 eng\versions.props = eng\versions.props EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetCorePal.Extensions.Yarp.ServiceDiscovery", "src\NetCorePal.Extensions.Yarp.ServiceDiscovery\NetCorePal.Extensions.Yarp.ServiceDiscovery.csproj", "{B9913396-5C97-4296-97A4-9F0D7716A1E6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetCorePal.Yarp.ServiceDiscovery", "src\NetCorePal.Yarp.ServiceDiscovery\NetCorePal.Yarp.ServiceDiscovery.csproj", "{B9913396-5C97-4296-97A4-9F0D7716A1E6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetCorePal.Extensions.YarpProxyStateUI", "src\NetCorePal.Extensions.YarpProxyStateUI\NetCorePal.Extensions.YarpProxyStateUI.csproj", "{10DFF0FD-CF81-4C18-AFA5-2EEACEAC0845}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetCorePal.Yarp.ReverseProxy.Dashboard", "src\NetCorePal.Yarp.ReverseProxy.Dashboard\NetCorePal.Yarp.ReverseProxy.Dashboard.csproj", "{10DFF0FD-CF81-4C18-AFA5-2EEACEAC0845}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates", "src\NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates\NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.csproj", "{EF55F855-1B26-47A0-A0F4-61C0B482BADF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{BEE4A397-41B9-4EFC-A37C-C74F1A97ACBE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.Tests", "test\NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.Tests\NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.Tests.csproj", "{85BA9DE7-5526-4937-8C40-4EC3D2DD4455}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IngressControllerTestWebHost", "test\IngressControllerTestWebHost\IngressControllerTestWebHost.csproj", "{4AB4F9D3-6C63-44E3-8484-2CC0DD460E33}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -31,6 +39,18 @@ Global {10DFF0FD-CF81-4C18-AFA5-2EEACEAC0845}.Debug|Any CPU.Build.0 = Debug|Any CPU {10DFF0FD-CF81-4C18-AFA5-2EEACEAC0845}.Release|Any CPU.ActiveCfg = Release|Any CPU {10DFF0FD-CF81-4C18-AFA5-2EEACEAC0845}.Release|Any CPU.Build.0 = Release|Any CPU + {EF55F855-1B26-47A0-A0F4-61C0B482BADF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EF55F855-1B26-47A0-A0F4-61C0B482BADF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EF55F855-1B26-47A0-A0F4-61C0B482BADF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EF55F855-1B26-47A0-A0F4-61C0B482BADF}.Release|Any CPU.Build.0 = Release|Any CPU + {85BA9DE7-5526-4937-8C40-4EC3D2DD4455}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {85BA9DE7-5526-4937-8C40-4EC3D2DD4455}.Debug|Any CPU.Build.0 = Debug|Any CPU + {85BA9DE7-5526-4937-8C40-4EC3D2DD4455}.Release|Any CPU.ActiveCfg = Release|Any CPU + {85BA9DE7-5526-4937-8C40-4EC3D2DD4455}.Release|Any CPU.Build.0 = Release|Any CPU + {4AB4F9D3-6C63-44E3-8484-2CC0DD460E33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4AB4F9D3-6C63-44E3-8484-2CC0DD460E33}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4AB4F9D3-6C63-44E3-8484-2CC0DD460E33}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4AB4F9D3-6C63-44E3-8484-2CC0DD460E33}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -38,6 +58,9 @@ Global GlobalSection(NestedProjects) = preSolution {B9913396-5C97-4296-97A4-9F0D7716A1E6} = {07187FF1-BBBA-4EC6-A16B-A88BFB309065} {10DFF0FD-CF81-4C18-AFA5-2EEACEAC0845} = {07187FF1-BBBA-4EC6-A16B-A88BFB309065} + {EF55F855-1B26-47A0-A0F4-61C0B482BADF} = {07187FF1-BBBA-4EC6-A16B-A88BFB309065} + {85BA9DE7-5526-4937-8C40-4EC3D2DD4455} = {BEE4A397-41B9-4EFC-A37C-C74F1A97ACBE} + {4AB4F9D3-6C63-44E3-8484-2CC0DD460E33} = {BEE4A397-41B9-4EFC-A37C-C74F1A97ACBE} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {82B031CC-A5AC-4C7B-BC85-EFBC09207DBB} diff --git a/src/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates/IngressServerCertificateManager.cs b/src/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates/IngressServerCertificateManager.cs new file mode 100644 index 0000000..3eaa01e --- /dev/null +++ b/src/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates/IngressServerCertificateManager.cs @@ -0,0 +1,148 @@ +using System.Collections.Concurrent; +using System.Security.Cryptography.X509Certificates; +using k8s; +using k8s.Models; +using Microsoft.AspNetCore.Connections; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Yarp.Kubernetes.Controller; +using Yarp.Kubernetes.Controller.Caching; +using Yarp.Kubernetes.Controller.Certificates; +using Yarp.Kubernetes.Controller.Client; + +namespace NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates; + +public class IngressServerCertificateManager : IHostedService +{ + private readonly IngressServerCertificateSelector _certificateSelector; + + private readonly object _lock = new object(); + + private readonly ICache _cache; + + private readonly ILogger _logger; + + private readonly ConcurrentDictionary _secrets = new(); + + private readonly ICertificateHelper _certificateHelper; + + public IngressServerCertificateManager( + IngressServerCertificateSelector certificateSelector, + ICache cache, + ICertificateHelper certificateHelper, + IResourceInformer secretInformer, + IResourceInformer ingressInformer, + ILogger logger) + { + _certificateSelector = certificateSelector; + _cache = cache; + _certificateHelper = certificateHelper; + secretInformer.Register(Update); + ingressInformer.Register(Update); + _logger = logger; + } + + private void Update(WatchEventType eventType, V1Ingress ingress) + { + try + { + ResetCertificates(); + } + catch (Exception e) + { + _logger.LogError(e, "Update ingress certificate error when update ingress"); + } + } + + private void Update(WatchEventType eventType, V1Secret resource) + { + try + { + NamespacedName n = new NamespacedName(resource.Namespace(), resource.Name()); + switch (eventType) + { + case WatchEventType.Added: + case WatchEventType.Modified: + _secrets.TryAdd(n, _certificateHelper.ConvertCertificate(n, resource)); + break; + case WatchEventType.Deleted: + _secrets.TryRemove(n, out _); + break; + } + + ResetCertificates(); + } + catch (Exception e) + { + _logger.LogError(e, "Update ingress certificate error when update secret"); + } + } + + + private void ResetCertificates() + { + lock (_lock) + { + var certs = new Dictionary(); + var wildcardCerts = new Dictionary(); + foreach (var ingress in _cache.GetIngresses()) + { + if (ingress.Spec?.Tls == null) continue; + + foreach (var tls in ingress.Spec.Tls) + { + if (!string.IsNullOrEmpty(tls.SecretName)) + { + var secretName = new NamespacedName(ingress.Metadata.Namespace(), tls.SecretName); + if (_secrets.TryGetValue(secretName, out var certificate)) + { + foreach (var host in tls.Hosts) + { + if (IsWildcardDomain(host)) + { + wildcardCerts[host] = certificate; + } + else + { + certs[host] = certificate; + } + } + } + } + } + } + + Interlocked.Exchange(ref _certificateSelector._domainCertificates, certs); + Interlocked.Exchange(ref _certificateSelector._wildcardDomainCertificates, wildcardCerts); + } + } + + + bool IsWildcardDomain(string domainName) + { + return domainName.StartsWith("*", StringComparison.Ordinal); + } + + bool TryToWildcardDomain(string domainName, out string wildcardDomainName) + { + wildcardDomainName = string.Empty; + var index = domainName.IndexOf(".", StringComparison.Ordinal); + if (index == -1) + { + return false; + } + + wildcardDomainName = string.Concat("*", domainName.AsSpan(index)); + return true; + } + + public Task StartAsync(CancellationToken cancellationToken) + { + return Task.CompletedTask; + } + + public Task StopAsync(CancellationToken cancellationToken) + { + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/src/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates/IngressServerCertificateSelector.cs b/src/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates/IngressServerCertificateSelector.cs new file mode 100644 index 0000000..f962e39 --- /dev/null +++ b/src/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates/IngressServerCertificateSelector.cs @@ -0,0 +1,55 @@ +using System.Security.Cryptography.X509Certificates; +using Microsoft.AspNetCore.Connections; +using Yarp.Kubernetes.Controller; +using Yarp.Kubernetes.Controller.Certificates; + +namespace NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates; + +public class IngressServerCertificateSelector : IServerCertificateSelector +{ + private X509Certificate2? _defaultCertificate = null; + + internal volatile Dictionary _domainCertificates = new(); + + internal volatile Dictionary _wildcardDomainCertificates = new(); + + + public X509Certificate2? GetCertificate(ConnectionContext connectionContext, string domainName) + { + if (_domainCertificates.TryGetValue(domainName, out var certificate)) + { + return certificate; + } + + if (TryToWildcardDomain(domainName, out var wildcardDomainName) + && _wildcardDomainCertificates.TryGetValue(wildcardDomainName, out var certificate1)) + { + return certificate1; + } + + return _defaultCertificate; + } + + public void AddCertificate(NamespacedName certificateName, X509Certificate2 certificate) + { + _defaultCertificate = certificate; + } + + public void RemoveCertificate(NamespacedName certificateName) + { + _defaultCertificate = null; + } + + bool TryToWildcardDomain(string domainName, out string wildcardDomainName) + { + wildcardDomainName = string.Empty; + var index = domainName.IndexOf(".", StringComparison.Ordinal); + if (index == -1) + { + return false; + } + + wildcardDomainName = string.Concat("*", domainName.AsSpan(index)); + return true; + } +} \ No newline at end of file diff --git a/src/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.csproj b/src/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.csproj new file mode 100644 index 0000000..5abd457 --- /dev/null +++ b/src/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.csproj @@ -0,0 +1,13 @@ + + + + net6.0;net7.0;net8.0 + enable + enable + + + + + + + diff --git a/src/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates/ReverseProxyBuilderExtensions.cs b/src/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates/ReverseProxyBuilderExtensions.cs new file mode 100644 index 0000000..9e0cca7 --- /dev/null +++ b/src/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates/ReverseProxyBuilderExtensions.cs @@ -0,0 +1,17 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Yarp.Kubernetes.Controller.Certificates; + +namespace NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates; + +public static class ReverseProxyBuilderExtensions +{ + public static IReverseProxyBuilder UseIngressServerCertificateSelector(this IReverseProxyBuilder builder) + { + builder.Services.TryAddSingleton(); + builder.Services.AddHostedService(); + builder.Services.Replace(ServiceDescriptor + .Singleton(p => p.GetRequiredService())); + return builder; + } +} \ No newline at end of file diff --git a/src/NetCorePal.Extensions.YarpProxyStateUI/NetCorePal.Extensions.YarpProxyStateUI.csproj b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/NetCorePal.Yarp.ReverseProxy.Dashboard.csproj similarity index 91% rename from src/NetCorePal.Extensions.YarpProxyStateUI/NetCorePal.Extensions.YarpProxyStateUI.csproj rename to src/NetCorePal.Yarp.ReverseProxy.Dashboard/NetCorePal.Yarp.ReverseProxy.Dashboard.csproj index 3167c30..9d46a43 100644 --- a/src/NetCorePal.Extensions.YarpProxyStateUI/NetCorePal.Extensions.YarpProxyStateUI.csproj +++ b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/NetCorePal.Yarp.ReverseProxy.Dashboard.csproj @@ -1,7 +1,7 @@ - net6.0 + net6.0;net7.0;net8.0 enable enable true @@ -12,7 +12,7 @@ - + diff --git a/src/NetCorePal.Extensions.YarpProxyStateUI/Pages/_State.cshtml b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/Pages/_State.cshtml similarity index 94% rename from src/NetCorePal.Extensions.YarpProxyStateUI/Pages/_State.cshtml rename to src/NetCorePal.Yarp.ReverseProxy.Dashboard/Pages/_State.cshtml index 8567753..19dc0ac 100644 --- a/src/NetCorePal.Extensions.YarpProxyStateUI/Pages/_State.cshtml +++ b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/Pages/_State.cshtml @@ -1,6 +1,6 @@ @page @using System.Text.Json -@model NetCorePal.Extensions.YarpProxyStateUI.Pages.ProxyStateModel +@model NetCorePal.Yarp.ReverseProxy.Dashboard.Pages.ProxyStateModel diff --git a/src/NetCorePal.Extensions.YarpProxyStateUI/Pages/_State.cshtml.cs b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/Pages/_State.cshtml.cs similarity index 78% rename from src/NetCorePal.Extensions.YarpProxyStateUI/Pages/_State.cshtml.cs rename to src/NetCorePal.Yarp.ReverseProxy.Dashboard/Pages/_State.cshtml.cs index 59a8a40..5b5a933 100644 --- a/src/NetCorePal.Extensions.YarpProxyStateUI/Pages/_State.cshtml.cs +++ b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/Pages/_State.cshtml.cs @@ -1,7 +1,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Yarp.ReverseProxy; -namespace NetCorePal.Extensions.YarpProxyStateUI.Pages; +namespace NetCorePal.Yarp.ReverseProxy.Dashboard.Pages; public class ProxyStateModel : PageModel { @@ -13,11 +13,5 @@ public ProxyStateModel(IProxyStateLookup proxyStateLookup) { this.ProxyStateLookup = proxyStateLookup; } - - - public void OnGet() - { - - } } diff --git a/src/NetCorePal.Extensions.YarpProxyStateUI/ServiceCollectionExtensions.cs b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/ServiceCollectionExtensions.cs similarity index 51% rename from src/NetCorePal.Extensions.YarpProxyStateUI/ServiceCollectionExtensions.cs rename to src/NetCorePal.Yarp.ReverseProxy.Dashboard/ServiceCollectionExtensions.cs index a04238b..51b308c 100644 --- a/src/NetCorePal.Extensions.YarpProxyStateUI/ServiceCollectionExtensions.cs +++ b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/ServiceCollectionExtensions.cs @@ -1,32 +1,27 @@ -using System; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Routing; -using Microsoft.Extensions.DependencyInjection; -using NetCorePal.Extensions.YarpProxyStateUI; +using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.FileProviders; -using Microsoft.AspNetCore.Builder; namespace Microsoft.Extensions.DependencyInjection { public static class ServiceCollectionExtensions { - public static IServiceCollection AddYarpProxyStateUI(this IServiceCollection services) + public static IServiceCollection AddYarpDashboard(this IServiceCollection services) { services.AddRazorPages(); return services; } - public static IApplicationBuilder UseYarpProxyStateUIStaticFiles(this IApplicationBuilder builder) + public static IApplicationBuilder UseYarpDashboardStaticFiles(this IApplicationBuilder builder) { builder.UseStaticFiles(new StaticFileOptions { RequestPath = "/_static", - FileProvider = new EmbeddedFileProvider(typeof(ServiceCollectionExtensions).Assembly, "NetCorePal.Extensions.YarpProxyStateUI.wwwroot") + FileProvider = new EmbeddedFileProvider(typeof(ServiceCollectionExtensions).Assembly, "NetCorePal.Yarp.ReverseProxy.Dashboard.wwwroot") }); return builder; } - public static IApplicationBuilder UseYarpProxyStateUI(this IApplicationBuilder builder, int? port = null) + public static IApplicationBuilder UseYarpDashboard(this IApplicationBuilder builder, int? port = null) { if (port == null) diff --git a/src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/css/bootstrap-theme.css b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/css/bootstrap-theme.css similarity index 100% rename from src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/css/bootstrap-theme.css rename to src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/css/bootstrap-theme.css diff --git a/src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/css/bootstrap-theme.css.map b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/css/bootstrap-theme.css.map similarity index 100% rename from src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/css/bootstrap-theme.css.map rename to src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/css/bootstrap-theme.css.map diff --git a/src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/css/bootstrap-theme.min.css b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/css/bootstrap-theme.min.css similarity index 100% rename from src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/css/bootstrap-theme.min.css rename to src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/css/bootstrap-theme.min.css diff --git a/src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/css/bootstrap-theme.min.css.map b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/css/bootstrap-theme.min.css.map similarity index 100% rename from src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/css/bootstrap-theme.min.css.map rename to src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/css/bootstrap-theme.min.css.map diff --git a/src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/css/bootstrap.css b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/css/bootstrap.css similarity index 100% rename from src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/css/bootstrap.css rename to src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/css/bootstrap.css diff --git a/src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/css/bootstrap.css.map b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/css/bootstrap.css.map similarity index 100% rename from src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/css/bootstrap.css.map rename to src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/css/bootstrap.css.map diff --git a/src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/css/bootstrap.min.css b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/css/bootstrap.min.css similarity index 100% rename from src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/css/bootstrap.min.css rename to src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/css/bootstrap.min.css diff --git a/src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/css/bootstrap.min.css.map b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/css/bootstrap.min.css.map similarity index 100% rename from src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/css/bootstrap.min.css.map rename to src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/css/bootstrap.min.css.map diff --git a/src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/fonts/glyphicons-halflings-regular.eot b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/fonts/glyphicons-halflings-regular.eot similarity index 100% rename from src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/fonts/glyphicons-halflings-regular.eot rename to src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/fonts/glyphicons-halflings-regular.eot diff --git a/src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/fonts/glyphicons-halflings-regular.svg b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/fonts/glyphicons-halflings-regular.svg similarity index 100% rename from src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/fonts/glyphicons-halflings-regular.svg rename to src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/fonts/glyphicons-halflings-regular.svg diff --git a/src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/fonts/glyphicons-halflings-regular.ttf b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/fonts/glyphicons-halflings-regular.ttf similarity index 100% rename from src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/fonts/glyphicons-halflings-regular.ttf rename to src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/fonts/glyphicons-halflings-regular.ttf diff --git a/src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/fonts/glyphicons-halflings-regular.woff b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/fonts/glyphicons-halflings-regular.woff similarity index 100% rename from src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/fonts/glyphicons-halflings-regular.woff rename to src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/fonts/glyphicons-halflings-regular.woff diff --git a/src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/fonts/glyphicons-halflings-regular.woff2 b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/fonts/glyphicons-halflings-regular.woff2 similarity index 100% rename from src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/fonts/glyphicons-halflings-regular.woff2 rename to src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/fonts/glyphicons-halflings-regular.woff2 diff --git a/src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/js/bootstrap.js b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/js/bootstrap.js similarity index 100% rename from src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/js/bootstrap.js rename to src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/js/bootstrap.js diff --git a/src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/js/bootstrap.min.js b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/js/bootstrap.min.js similarity index 100% rename from src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/js/bootstrap.min.js rename to src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/js/bootstrap.min.js diff --git a/src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/js/npm.js b/src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/js/npm.js similarity index 100% rename from src/NetCorePal.Extensions.YarpProxyStateUI/wwwroot/js/npm.js rename to src/NetCorePal.Yarp.ReverseProxy.Dashboard/wwwroot/js/npm.js diff --git a/src/NetCorePal.Extensions.Yarp.ServiceDiscovery/NetCorePal.Extensions.Yarp.ServiceDiscovery.csproj b/src/NetCorePal.Yarp.ServiceDiscovery/NetCorePal.Yarp.ServiceDiscovery.csproj similarity index 92% rename from src/NetCorePal.Extensions.Yarp.ServiceDiscovery/NetCorePal.Extensions.Yarp.ServiceDiscovery.csproj rename to src/NetCorePal.Yarp.ServiceDiscovery/NetCorePal.Yarp.ServiceDiscovery.csproj index 00d80ad..7b051a3 100644 --- a/src/NetCorePal.Extensions.Yarp.ServiceDiscovery/NetCorePal.Extensions.Yarp.ServiceDiscovery.csproj +++ b/src/NetCorePal.Yarp.ServiceDiscovery/NetCorePal.Yarp.ServiceDiscovery.csproj @@ -4,6 +4,7 @@ net6.0 enable enable + false diff --git a/src/NetCorePal.Extensions.Yarp.ServiceDiscovery/ReverseProxyBuilderExtensions.cs b/src/NetCorePal.Yarp.ServiceDiscovery/ReverseProxyBuilderExtensions.cs similarity index 93% rename from src/NetCorePal.Extensions.Yarp.ServiceDiscovery/ReverseProxyBuilderExtensions.cs rename to src/NetCorePal.Yarp.ServiceDiscovery/ReverseProxyBuilderExtensions.cs index 33ef7d3..f7eea95 100644 --- a/src/NetCorePal.Extensions.Yarp.ServiceDiscovery/ReverseProxyBuilderExtensions.cs +++ b/src/NetCorePal.Yarp.ServiceDiscovery/ReverseProxyBuilderExtensions.cs @@ -1,5 +1,5 @@ using System; -using NetCorePal.Extensions.Yarp.ServiceDiscovery; +using NetCorePal.Yarp.ServiceDiscovery; using Yarp.ReverseProxy.Configuration; namespace Microsoft.Extensions.DependencyInjection diff --git a/src/NetCorePal.Extensions.Yarp.ServiceDiscovery/ServiceDiscoveryProxyConfig.cs b/src/NetCorePal.Yarp.ServiceDiscovery/ServiceDiscoveryProxyConfig.cs similarity index 91% rename from src/NetCorePal.Extensions.Yarp.ServiceDiscovery/ServiceDiscoveryProxyConfig.cs rename to src/NetCorePal.Yarp.ServiceDiscovery/ServiceDiscoveryProxyConfig.cs index 2c70437..a8b7d39 100644 --- a/src/NetCorePal.Extensions.Yarp.ServiceDiscovery/ServiceDiscoveryProxyConfig.cs +++ b/src/NetCorePal.Yarp.ServiceDiscovery/ServiceDiscoveryProxyConfig.cs @@ -1,7 +1,7 @@ using System; using Microsoft.Extensions.Primitives; using Yarp.ReverseProxy.Configuration; -namespace NetCorePal.Extensions.Yarp.ServiceDiscovery +namespace NetCorePal.Yarp.ServiceDiscovery { internal class ServiceDiscoveryProxyConfig : IProxyConfig { diff --git a/src/NetCorePal.Extensions.Yarp.ServiceDiscovery/ServiceDiscoveryProxyConfigProvider.cs b/src/NetCorePal.Yarp.ServiceDiscovery/ServiceDiscoveryProxyConfigProvider.cs similarity index 94% rename from src/NetCorePal.Extensions.Yarp.ServiceDiscovery/ServiceDiscoveryProxyConfigProvider.cs rename to src/NetCorePal.Yarp.ServiceDiscovery/ServiceDiscoveryProxyConfigProvider.cs index 2719c59..2ba5066 100644 --- a/src/NetCorePal.Extensions.Yarp.ServiceDiscovery/ServiceDiscoveryProxyConfigProvider.cs +++ b/src/NetCorePal.Yarp.ServiceDiscovery/ServiceDiscoveryProxyConfigProvider.cs @@ -1,7 +1,7 @@ using NetCorePal.ServiceDiscovery; using Yarp.ReverseProxy.Configuration; -namespace NetCorePal.Extensions.Yarp.ServiceDiscovery +namespace NetCorePal.Yarp.ServiceDiscovery { public class ServiceDiscoveryProxyConfigProvider : IProxyConfigProvider { diff --git a/test/Directory.Build.props b/test/Directory.Build.props new file mode 100644 index 0000000..50ce2f4 --- /dev/null +++ b/test/Directory.Build.props @@ -0,0 +1,9 @@ + + + false + preview + + + + + diff --git a/test/IngressControllerTestWebHost/IngressControllerTestWebHost.csproj b/test/IngressControllerTestWebHost/IngressControllerTestWebHost.csproj new file mode 100644 index 0000000..b80b917 --- /dev/null +++ b/test/IngressControllerTestWebHost/IngressControllerTestWebHost.csproj @@ -0,0 +1,14 @@ + + + + net8.0 + enable + enable + + + + + + + + diff --git a/test/IngressControllerTestWebHost/Program.cs b/test/IngressControllerTestWebHost/Program.cs new file mode 100644 index 0000000..af45c90 --- /dev/null +++ b/test/IngressControllerTestWebHost/Program.cs @@ -0,0 +1,26 @@ +using NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates; +using Microsoft.Extensions.DependencyInjection; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddYarpDashboard(); +builder.Services.AddKubernetesReverseProxy(builder.Configuration) + .UseIngressServerCertificateSelector() + .LoadFromConfig(builder.Configuration.GetSection("ReverseProxy")); + +if (builder.Environment.IsDevelopment()) +{ + builder.WebHost.UseKubernetesReverseProxyCertificateSelector(); +} + +builder.Services.AddCors(options => +{ + options.AddPolicy("apiPolicy", p => p.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()); +}); + +var app = builder.Build(); +app.UseYarpDashboardStaticFiles(); +app.UseRouting(); +app.UseYarpDashboard(); +app.MapGet("/", () => "Hello World!"); +app.MapReverseProxy(); +app.Run(); \ No newline at end of file diff --git a/test/IngressControllerTestWebHost/Properties/launchSettings.json b/test/IngressControllerTestWebHost/Properties/launchSettings.json new file mode 100644 index 0000000..a5ecee0 --- /dev/null +++ b/test/IngressControllerTestWebHost/Properties/launchSettings.json @@ -0,0 +1,38 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:65372", + "sslPort": 44310 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5091", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7031;http://localhost:5091", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/test/IngressControllerTestWebHost/appsettings.Development.json b/test/IngressControllerTestWebHost/appsettings.Development.json new file mode 100644 index 0000000..d528010 --- /dev/null +++ b/test/IngressControllerTestWebHost/appsettings.Development.json @@ -0,0 +1,15 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "Yarp": { + "ControllerClass": "rivtower.com/rivdap", + "ServerCertificates": true, + "DefaultSslCertificate": "app-rivdap-saas/nft-fe-tls", + "ControllerServiceNamespace": "app-rivdap-saas", + "ControllerServiceName": "rivtower-ingress-controller" + } +} diff --git a/test/IngressControllerTestWebHost/appsettings.json b/test/IngressControllerTestWebHost/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/test/IngressControllerTestWebHost/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/test/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.Tests/GlobalUsings.cs b/test/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.Tests/GlobalUsings.cs new file mode 100644 index 0000000..8c927eb --- /dev/null +++ b/test/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.Tests/GlobalUsings.cs @@ -0,0 +1 @@ +global using Xunit; \ No newline at end of file diff --git a/test/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.Tests/IngressServerCertificateSelectorTests.cs b/test/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.Tests/IngressServerCertificateSelectorTests.cs new file mode 100644 index 0000000..2f4ad54 --- /dev/null +++ b/test/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.Tests/IngressServerCertificateSelectorTests.cs @@ -0,0 +1,47 @@ +using k8s; +using k8s.Models; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Moq; +using NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates; +using Yarp.Kubernetes.Controller.Caching; +using Yarp.Kubernetes.Controller.Certificates; +using Yarp.Kubernetes.Controller.Client; + +namespace NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.Tests; + +public class IngressServerCertificateSelectorTests +{ + [Fact] + public void Test1() + { + var cacheMock = new Mock(); + var certificateHelperLoggerMock = new Mock>(); + ICertificateHelper certificateHelper = new CertificateHelper(certificateHelperLoggerMock.Object); + + var secretInformer = new Mock>(); + + ResourceInformerCallback? secretCallback = null; + secretInformer.Setup(p => p.Register(It.IsAny>())) + .Callback((ResourceInformerCallback c) => secretCallback = c); + + ResourceInformerCallback? ingressCallback = null; + var ingressInformer = new Mock>(); + ingressInformer.Setup(p => p.Register(It.IsAny>())) + .Callback((ResourceInformerCallback c) => ingressCallback = c); + + var loggerMock = new Mock>(); + var manager = new IngressServerCertificateManager( + new IngressServerCertificateSelector(), + cacheMock.Object, + certificateHelper, + secretInformer.Object, + ingressInformer.Object, + loggerMock.Object); + + Assert.NotNull(secretCallback); + Assert.NotNull(ingressCallback); + + secretCallback(WatchEventType.Added, new V1Secret()); + } +} \ No newline at end of file diff --git a/test/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.Tests/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.Tests.csproj b/test/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.Tests/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.Tests.csproj new file mode 100644 index 0000000..324e86b --- /dev/null +++ b/test/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.Tests/NetCorePal.Yarp.Kubernetes.Controller.IngressCertificates.Tests.csproj @@ -0,0 +1,30 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + +