mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-25 23:18:44 -07:00
Split remaining service routes
This commit is contained in:
@@ -6,6 +6,10 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Yarp.ReverseProxy" Version="2.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DorkNet.Contracts\DorkNet.Contracts.csproj" />
|
||||
<ProjectReference Include="..\DorkNet.ServiceDefaults\DorkNet.ServiceDefaults.csproj" />
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using DorkNet.Contracts;
|
||||
using DorkNet.ServiceDefaults;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Yarp.ReverseProxy.Configuration;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
builder.Configuration.AddJsonFile("appsettings.Local.json",
|
||||
@@ -9,6 +10,17 @@ builder.Configuration.AddJsonFile("appsettings.Local.json",
|
||||
builder.AddDorkNetServiceDefaults(ServiceNames.Gateway);
|
||||
builder.Services.Configure<DorkNetServiceMapOptions>(
|
||||
builder.Configuration.GetSection("DorkNet:Services"));
|
||||
var serviceMap = builder.Configuration
|
||||
.GetSection("DorkNet:Services")
|
||||
.Get<DorkNetServiceMapOptions>() ?? new DorkNetServiceMapOptions();
|
||||
var apexDomain = builder.Configuration["Domain:Apex"]
|
||||
?? Environment.GetEnvironmentVariable("DORKNET_DOMAIN")
|
||||
?? "localhost";
|
||||
builder.Services
|
||||
.AddReverseProxy()
|
||||
.LoadFromMemory(
|
||||
BuildRoutes(apexDomain, serviceMap),
|
||||
BuildClusters(serviceMap));
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
@@ -17,6 +29,19 @@ app.MapDorkNetServiceDefaults();
|
||||
app.MapGet("/", () => Results.Redirect("/healthz"));
|
||||
app.MapGet("/internal/services", (IOptions<DorkNetServiceMapOptions> options) =>
|
||||
Results.Ok(options.Value.Endpoints()));
|
||||
app.MapGet("/internal/routes", () =>
|
||||
Results.Ok(new
|
||||
{
|
||||
ApexDomain = apexDomain,
|
||||
Routes = BuildRoutes(apexDomain, serviceMap).Select(r => new
|
||||
{
|
||||
r.RouteId,
|
||||
r.ClusterId,
|
||||
r.Match.Hosts,
|
||||
r.Match.Path,
|
||||
r.Order,
|
||||
}),
|
||||
}));
|
||||
|
||||
app.MapGet("/internal/services/health", async (
|
||||
IOptions<DorkNetServiceMapOptions> options,
|
||||
@@ -34,6 +59,8 @@ app.MapGet("/internal/services/health", async (
|
||||
return Results.Ok(probes);
|
||||
});
|
||||
|
||||
app.MapReverseProxy();
|
||||
|
||||
app.Run();
|
||||
|
||||
static async Task<ServiceProbeResponse> ProbeServiceAsync(
|
||||
@@ -66,3 +93,206 @@ static async Task<ServiceProbeResponse> ProbeServiceAsync(
|
||||
checkedAt);
|
||||
}
|
||||
}
|
||||
|
||||
static IReadOnlyList<RouteConfig> BuildRoutes(
|
||||
string apexDomain,
|
||||
DorkNetServiceMapOptions services)
|
||||
{
|
||||
var routes = new List<RouteConfig>();
|
||||
var order = 0;
|
||||
var webGroup = DorkNetRouteOwnership.RouteGroups
|
||||
.First(group => group.ServiceName == ServiceNames.Web);
|
||||
|
||||
AddHostRoute(
|
||||
routes,
|
||||
ref order,
|
||||
webGroup.ServiceName,
|
||||
BaseUrlFor(services, webGroup.ServiceName),
|
||||
"web-admin-host",
|
||||
[SubdomainHost("admin", apexDomain)]);
|
||||
|
||||
foreach (var group in DorkNetRouteOwnership.RouteGroups.Where(group => group.ServiceName != ServiceNames.Web))
|
||||
{
|
||||
AddHostRoute(
|
||||
routes,
|
||||
ref order,
|
||||
group.ServiceName,
|
||||
BaseUrlFor(services, group.ServiceName),
|
||||
$"{group.ServiceName}-hosts",
|
||||
group.HostSubdomains.Select(subdomain => SubdomainHost(subdomain, apexDomain)).ToArray());
|
||||
}
|
||||
|
||||
foreach (var group in DorkNetRouteOwnership.RouteGroups)
|
||||
{
|
||||
AddPathRoutes(
|
||||
routes,
|
||||
ref order,
|
||||
group.ServiceName,
|
||||
BaseUrlFor(services, group.ServiceName),
|
||||
group.PathPrefixes);
|
||||
}
|
||||
|
||||
AddHostRoute(
|
||||
routes,
|
||||
ref order,
|
||||
webGroup.ServiceName,
|
||||
BaseUrlFor(services, webGroup.ServiceName),
|
||||
"web-hosts",
|
||||
BuildWebHosts(webGroup, apexDomain));
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(services.Monolith))
|
||||
{
|
||||
routes.Add(Route(ServiceNames.Monolith, "monolith-fallback", "/{**catch-all}", order++));
|
||||
}
|
||||
|
||||
return routes;
|
||||
}
|
||||
|
||||
static IReadOnlyList<ClusterConfig> BuildClusters(DorkNetServiceMapOptions services)
|
||||
{
|
||||
var clusters = new List<ClusterConfig>();
|
||||
foreach (var endpoint in services.Endpoints())
|
||||
{
|
||||
AddCluster(clusters, endpoint.Name, endpoint.BaseUrl);
|
||||
}
|
||||
|
||||
return clusters;
|
||||
}
|
||||
|
||||
static void AddHostRoute(
|
||||
List<RouteConfig> routes,
|
||||
ref int order,
|
||||
string serviceName,
|
||||
string baseUrl,
|
||||
string routeId,
|
||||
string[] hosts)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(baseUrl) || hosts.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
routes.Add(Route(
|
||||
serviceName,
|
||||
routeId,
|
||||
"/{**catch-all}",
|
||||
order++,
|
||||
hosts));
|
||||
}
|
||||
|
||||
static void AddPathRoutes(
|
||||
List<RouteConfig> routes,
|
||||
ref int order,
|
||||
string serviceName,
|
||||
string baseUrl,
|
||||
IEnumerable<string> paths)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(baseUrl))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var path in paths)
|
||||
{
|
||||
var routeId = $"{serviceName}-{path.Trim('/').Replace('/', '-').Replace("{**catch-all}", "all")}";
|
||||
var exactPath = NormalizeRoutePrefix(path);
|
||||
routes.Add(Route(serviceName, $"{routeId}-exact", exactPath, order++));
|
||||
routes.Add(Route(serviceName, routeId, $"{exactPath}/{{**catch-all}}", order++));
|
||||
}
|
||||
}
|
||||
|
||||
static string BaseUrlFor(DorkNetServiceMapOptions services, string serviceName)
|
||||
{
|
||||
return serviceName switch
|
||||
{
|
||||
ServiceNames.Identity => services.Identity,
|
||||
ServiceNames.Rooms => services.Rooms,
|
||||
ServiceNames.Notify => services.Notify,
|
||||
ServiceNames.Content => services.Content,
|
||||
ServiceNames.Social => services.Social,
|
||||
ServiceNames.Commerce => services.Commerce,
|
||||
ServiceNames.Platform => services.Platform,
|
||||
ServiceNames.Moderation => services.Moderation,
|
||||
ServiceNames.Web => services.Web,
|
||||
ServiceNames.Monolith => services.Monolith,
|
||||
_ => string.Empty,
|
||||
};
|
||||
}
|
||||
|
||||
static string[] BuildWebHosts(DorkNetRouteGroup group, string apexDomain)
|
||||
{
|
||||
var hosts = new List<string>();
|
||||
if (group.IncludesApexHost)
|
||||
{
|
||||
hosts.Add(apexDomain);
|
||||
}
|
||||
|
||||
hosts.AddRange(group.HostSubdomains
|
||||
.Where(subdomain => !string.Equals(subdomain, "admin", StringComparison.OrdinalIgnoreCase))
|
||||
.Select(subdomain => SubdomainHost(subdomain, apexDomain)));
|
||||
|
||||
return hosts.ToArray();
|
||||
}
|
||||
|
||||
static string SubdomainHost(string subdomain, string apexDomain)
|
||||
{
|
||||
return $"{subdomain}.{apexDomain}";
|
||||
}
|
||||
|
||||
static string NormalizeRoutePrefix(string path)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path) || path == "/")
|
||||
{
|
||||
return "/";
|
||||
}
|
||||
|
||||
return (path[0] == '/' ? path : "/" + path).TrimEnd('/');
|
||||
}
|
||||
|
||||
static RouteConfig Route(
|
||||
string clusterId,
|
||||
string routeId,
|
||||
string path,
|
||||
int order,
|
||||
string[]? hosts = null)
|
||||
{
|
||||
return new RouteConfig
|
||||
{
|
||||
RouteId = routeId,
|
||||
ClusterId = clusterId,
|
||||
Order = order,
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Hosts = hosts,
|
||||
Path = path,
|
||||
},
|
||||
Transforms =
|
||||
[
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
["RequestHeaderOriginalHost"] = "true",
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
static void AddCluster(
|
||||
List<ClusterConfig> clusters,
|
||||
string serviceName,
|
||||
string baseUrl)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(baseUrl))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var address = baseUrl.EndsWith('/') ? baseUrl : baseUrl + "/";
|
||||
clusters.Add(new ClusterConfig
|
||||
{
|
||||
ClusterId = serviceName,
|
||||
Destinations = new Dictionary<string, DestinationConfig>
|
||||
{
|
||||
["primary"] = new() { Address = address },
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -11,7 +11,13 @@
|
||||
"Identity": "http://localhost:8081",
|
||||
"Rooms": "http://localhost:8082",
|
||||
"Notify": "http://localhost:8083",
|
||||
"Monolith": "http://localhost:8084"
|
||||
"Content": "http://localhost:8084",
|
||||
"Social": "http://localhost:8085",
|
||||
"Commerce": "http://localhost:8086",
|
||||
"Platform": "http://localhost:8087",
|
||||
"Moderation": "http://localhost:8088",
|
||||
"Web": "http://localhost:8089",
|
||||
"Monolith": "http://localhost:8090"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user