Compare commits
	
		
			2 Commits
		
	
	
		
			8fbc81cab9
			...
			3310487aba
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 3310487aba | |||
| 21b42b5b21 | 
							
								
								
									
										47
									
								
								DysonNetwork.Gateway/Controllers/WellKnownController.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								DysonNetwork.Gateway/Controllers/WellKnownController.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | |||||||
|  | using Microsoft.AspNetCore.Mvc; | ||||||
|  | using Yarp.ReverseProxy.Configuration; | ||||||
|  |  | ||||||
|  | namespace DysonNetwork.Gateway.Controllers; | ||||||
|  |  | ||||||
|  | [ApiController] | ||||||
|  | [Route("/.well-known")] | ||||||
|  | public class WellKnownController(IConfiguration configuration, IProxyConfigProvider proxyConfigProvider) | ||||||
|  |     : ControllerBase | ||||||
|  | { | ||||||
|  |     [HttpGet("domains")] | ||||||
|  |     public IActionResult GetDomainMappings() | ||||||
|  |     { | ||||||
|  |         var domainMappings = configuration.GetSection("DomainMappings").GetChildren() | ||||||
|  |             .ToDictionary(x => x.Key, x => x.Value); | ||||||
|  |         return Ok(domainMappings); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [HttpGet("routes")] | ||||||
|  |     public IActionResult GetProxyRules() | ||||||
|  |     { | ||||||
|  |         var config = proxyConfigProvider.GetConfig(); | ||||||
|  |         var rules = config.Routes.Select(r => new | ||||||
|  |         { | ||||||
|  |             r.RouteId, | ||||||
|  |             r.ClusterId, | ||||||
|  |             Match = new | ||||||
|  |             { | ||||||
|  |                 r.Match.Path, | ||||||
|  |                 Hosts = r.Match.Hosts != null ? string.Join(", ", r.Match.Hosts) : null | ||||||
|  |             }, | ||||||
|  |             Transforms = r.Transforms?.Select(t => t.Select(kv => $"{kv.Key}: {kv.Value}").ToList()) | ||||||
|  |         }).ToList(); | ||||||
|  |  | ||||||
|  |         var clusters = config.Clusters.Select(c => new | ||||||
|  |         { | ||||||
|  |             c.ClusterId, | ||||||
|  |             Destinations = c.Destinations?.Select(d => new | ||||||
|  |             { | ||||||
|  |                 d.Key, | ||||||
|  |                 d.Value.Address | ||||||
|  |             }).ToList() | ||||||
|  |         }).ToList(); | ||||||
|  |  | ||||||
|  |         return Ok(new { Rules = rules, Clusters = clusters }); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										23
									
								
								DysonNetwork.Gateway/Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								DysonNetwork.Gateway/Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | |||||||
|  | FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base | ||||||
|  | USER $APP_UID | ||||||
|  | WORKDIR /app | ||||||
|  | EXPOSE 8080 | ||||||
|  | EXPOSE 8081 | ||||||
|  |  | ||||||
|  | FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build | ||||||
|  | ARG BUILD_CONFIGURATION=Release | ||||||
|  | WORKDIR /src | ||||||
|  | COPY ["DysonNetwork.Gateway/DysonNetwork.Gateway.csproj", "DysonNetwork.Gateway/"] | ||||||
|  | RUN dotnet restore "DysonNetwork.Gateway/DysonNetwork.Gateway.csproj" | ||||||
|  | COPY . . | ||||||
|  | WORKDIR "/src/DysonNetwork.Gateway" | ||||||
|  | RUN dotnet build "./DysonNetwork.Gateway.csproj" -c $BUILD_CONFIGURATION -o /app/build | ||||||
|  |  | ||||||
|  | FROM build AS publish | ||||||
|  | ARG BUILD_CONFIGURATION=Release | ||||||
|  | RUN dotnet publish "./DysonNetwork.Gateway.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false | ||||||
|  |  | ||||||
|  | FROM base AS final | ||||||
|  | WORKDIR /app | ||||||
|  | COPY --from=publish /app/publish . | ||||||
|  | ENTRYPOINT ["dotnet", "DysonNetwork.Gateway.dll"] | ||||||
							
								
								
									
										19
									
								
								DysonNetwork.Gateway/DysonNetwork.Gateway.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								DysonNetwork.Gateway/DysonNetwork.Gateway.csproj
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | <Project Sdk="Microsoft.NET.Sdk.Web"> | ||||||
|  |  | ||||||
|  |   <PropertyGroup> | ||||||
|  |     <TargetFramework>net9.0</TargetFramework> | ||||||
|  |     <Nullable>enable</Nullable> | ||||||
|  |     <ImplicitUsings>enable</ImplicitUsings> | ||||||
|  |   </PropertyGroup> | ||||||
|  |  | ||||||
|  |   <ItemGroup> | ||||||
|  |     <PackageReference Include="dotnet-etcd" Version="8.0.1" /> | ||||||
|  |     <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.7" /> | ||||||
|  |     <PackageReference Include="Yarp.ReverseProxy" Version="2.3.0" /> | ||||||
|  |   </ItemGroup> | ||||||
|  |  | ||||||
|  |   <ItemGroup> | ||||||
|  |     <ProjectReference Include="..\DysonNetwork.Shared\DysonNetwork.Shared.csproj" /> | ||||||
|  |   </ItemGroup> | ||||||
|  |  | ||||||
|  | </Project> | ||||||
							
								
								
									
										14
									
								
								DysonNetwork.Gateway/Program.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								DysonNetwork.Gateway/Program.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | using DysonNetwork.Gateway.Startup; | ||||||
|  |  | ||||||
|  | var builder = WebApplication.CreateBuilder(args); | ||||||
|  |  | ||||||
|  | // Add services to the container. | ||||||
|  | builder.Services.AddGateway(builder.Configuration); | ||||||
|  | builder.Services.AddControllers(); | ||||||
|  |  | ||||||
|  | var app = builder.Build(); | ||||||
|  |  | ||||||
|  | app.MapControllers(); | ||||||
|  | app.MapReverseProxy(); | ||||||
|  |  | ||||||
|  | app.Run(); | ||||||
							
								
								
									
										23
									
								
								DysonNetwork.Gateway/Properties/launchSettings.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								DysonNetwork.Gateway/Properties/launchSettings.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | |||||||
|  | { | ||||||
|  |   "$schema": "https://json.schemastore.org/launchsettings.json", | ||||||
|  |   "profiles": { | ||||||
|  |     "http": { | ||||||
|  |       "commandName": "Project", | ||||||
|  |       "dotnetRunMessages": true, | ||||||
|  |       "launchBrowser": false, | ||||||
|  |       "applicationUrl": "http://localhost:5094", | ||||||
|  |       "environmentVariables": { | ||||||
|  |         "ASPNETCORE_ENVIRONMENT": "Development" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "https": { | ||||||
|  |       "commandName": "Project", | ||||||
|  |       "dotnetRunMessages": true, | ||||||
|  |       "launchBrowser": false, | ||||||
|  |       "applicationUrl": "https://localhost:7034;http://localhost:5094", | ||||||
|  |       "environmentVariables": { | ||||||
|  |         "ASPNETCORE_ENVIRONMENT": "Development" | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										176
									
								
								DysonNetwork.Gateway/RegistryProxyConfigProvider.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								DysonNetwork.Gateway/RegistryProxyConfigProvider.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,176 @@ | |||||||
|  | using System.Text; | ||||||
|  | using dotnet_etcd.interfaces; | ||||||
|  | using Yarp.ReverseProxy.Configuration; | ||||||
|  |  | ||||||
|  | namespace DysonNetwork.Gateway; | ||||||
|  |  | ||||||
|  | public class RegistryProxyConfigProvider : IProxyConfigProvider, IDisposable | ||||||
|  | { | ||||||
|  |     private readonly IEtcdClient _etcdClient; | ||||||
|  |     private readonly IConfiguration _configuration; | ||||||
|  |     private readonly ILogger<RegistryProxyConfigProvider> _logger; | ||||||
|  |     private readonly CancellationTokenSource _watchCts = new(); | ||||||
|  |     private CancellationTokenSource _cts = new(); | ||||||
|  |  | ||||||
|  |     public RegistryProxyConfigProvider(IEtcdClient etcdClient, IConfiguration configuration, ILogger<RegistryProxyConfigProvider> logger) | ||||||
|  |     { | ||||||
|  |         _etcdClient = etcdClient; | ||||||
|  |         _configuration = configuration; | ||||||
|  |         _logger = logger; | ||||||
|  |  | ||||||
|  |         // Watch for changes in etcd | ||||||
|  |         _etcdClient.WatchRange("/services/", _ => | ||||||
|  |         { | ||||||
|  |             _logger.LogInformation("Etcd configuration changed. Reloading proxy config."); | ||||||
|  |             _cts.Cancel(); | ||||||
|  |             _cts = new CancellationTokenSource(); | ||||||
|  |         }, cancellationToken: _watchCts.Token); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public IProxyConfig GetConfig() | ||||||
|  |     { | ||||||
|  |         // This will be called by YARP when it needs a new config | ||||||
|  |         _logger.LogInformation("Generating new proxy config."); | ||||||
|  |         var response = _etcdClient.GetRange("/services/"); | ||||||
|  |         var kvs = response.Kvs; | ||||||
|  |  | ||||||
|  |         var serviceMap = kvs.ToDictionary( | ||||||
|  |             kv => Encoding.UTF8.GetString(kv.Key.ToByteArray()).Replace("/services/", ""), | ||||||
|  |             kv => Encoding.UTF8.GetString(kv.Value.ToByteArray()) | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         var clusters = new List<ClusterConfig>(); | ||||||
|  |         var routes = new List<RouteConfig>(); | ||||||
|  |  | ||||||
|  |         var domainMappings = _configuration.GetSection("DomainMappings").GetChildren() | ||||||
|  |             .ToDictionary(x => x.Key, x => x.Value); | ||||||
|  |  | ||||||
|  |         var pathAliases = _configuration.GetSection("PathAliases").GetChildren() | ||||||
|  |             .ToDictionary(x => x.Key, x => x.Value); | ||||||
|  |  | ||||||
|  |         var directRoutes = _configuration.GetSection("DirectRoutes").Get<List<DirectRouteConfig>>() ?? new List<DirectRouteConfig>(); | ||||||
|  |  | ||||||
|  |         _logger.LogInformation("Indexing {ServiceCount} services from Etcd.", kvs.Count); | ||||||
|  |  | ||||||
|  |         var gatewayServiceName = _configuration["Service:Name"]; | ||||||
|  |  | ||||||
|  |         // Add direct routes | ||||||
|  |         foreach (var directRoute in directRoutes) | ||||||
|  |         { | ||||||
|  |             if (serviceMap.TryGetValue(directRoute.Service, out var serviceUrl)) | ||||||
|  |             { | ||||||
|  |                 var cluster = new ClusterConfig | ||||||
|  |                 { | ||||||
|  |                     ClusterId = directRoute.Service, | ||||||
|  |                     Destinations = new Dictionary<string, DestinationConfig> | ||||||
|  |                     { | ||||||
|  |                         { "destination1", new DestinationConfig { Address = serviceUrl } } | ||||||
|  |                     } | ||||||
|  |                 }; | ||||||
|  |                 clusters.Add(cluster); | ||||||
|  |  | ||||||
|  |                 var route = new RouteConfig | ||||||
|  |                 { | ||||||
|  |                     RouteId = $"direct-{directRoute.Service}-{directRoute.Path.Replace("/", "-")}", | ||||||
|  |                     ClusterId = directRoute.Service, | ||||||
|  |                     Match = new RouteMatch { Path = directRoute.Path } | ||||||
|  |                 }; | ||||||
|  |                 routes.Add(route); | ||||||
|  |                 _logger.LogInformation("    Added Direct Route: {Path} -> {Service}", directRoute.Path, directRoute.Service); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 _logger.LogWarning("    Direct route service {Service} not found in Etcd.", directRoute.Service); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         foreach (var serviceName in serviceMap.Keys) | ||||||
|  |         { | ||||||
|  |             if (serviceName == gatewayServiceName) | ||||||
|  |             { | ||||||
|  |                 _logger.LogInformation("Skipping gateway service: {ServiceName}", serviceName); | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             var serviceUrl = serviceMap[serviceName]; | ||||||
|  |  | ||||||
|  |             // Determine the path alias | ||||||
|  |             string pathAlias; | ||||||
|  |             if (pathAliases.TryGetValue(serviceName, out var alias)) | ||||||
|  |             { | ||||||
|  |                 pathAlias = alias; | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 pathAlias = serviceName.Split('.').Last().ToLowerInvariant(); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             _logger.LogInformation("  Service: {ServiceName}, URL: {ServiceUrl}, Path Alias: {PathAlias}", serviceName, serviceUrl, pathAlias); | ||||||
|  |  | ||||||
|  |             var cluster = new ClusterConfig | ||||||
|  |             { | ||||||
|  |                 ClusterId = serviceName, | ||||||
|  |                 Destinations = new Dictionary<string, DestinationConfig> | ||||||
|  |                 { | ||||||
|  |                     { "destination1", new DestinationConfig { Address = serviceUrl } } | ||||||
|  |                 } | ||||||
|  |             }; | ||||||
|  |             clusters.Add(cluster); | ||||||
|  |  | ||||||
|  |             // Host-based routing | ||||||
|  |             if (domainMappings.TryGetValue(serviceName, out var domain)) | ||||||
|  |             { | ||||||
|  |                 var hostRoute = new RouteConfig | ||||||
|  |                 { | ||||||
|  |                     RouteId = $"{serviceName}-host", | ||||||
|  |                     ClusterId = serviceName, | ||||||
|  |                     Match = new RouteMatch | ||||||
|  |                     { | ||||||
|  |                         Hosts = new[] { domain }, | ||||||
|  |                         Path = "/{**catch-all}" | ||||||
|  |                     } | ||||||
|  |                 }; | ||||||
|  |                 routes.Add(hostRoute); | ||||||
|  |                 _logger.LogInformation("    Added Host-based Route: {Host}", domain); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             // Path-based routing | ||||||
|  |             var pathRoute = new RouteConfig | ||||||
|  |             { | ||||||
|  |                 RouteId = $"{serviceName}-path", | ||||||
|  |                 ClusterId = serviceName, | ||||||
|  |                 Match = new RouteMatch { Path = $"/{pathAlias}/{{**catch-all}}" }, | ||||||
|  |                 Transforms = new List<Dictionary<string, string>> | ||||||
|  |                 { | ||||||
|  |                     new Dictionary<string, string> { { "PathRemovePrefix", $"/{pathAlias}" } } | ||||||
|  |                 } | ||||||
|  |             }; | ||||||
|  |             routes.Add(pathRoute); | ||||||
|  |             _logger.LogInformation("    Added Path-based Route: {Path}", pathRoute.Match.Path); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return new CustomProxyConfig(routes, clusters); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private class CustomProxyConfig(IReadOnlyList<RouteConfig> routes, IReadOnlyList<ClusterConfig> clusters) | ||||||
|  |         : IProxyConfig | ||||||
|  |     { | ||||||
|  |         public IReadOnlyList<RouteConfig> Routes { get; } = routes; | ||||||
|  |         public IReadOnlyList<ClusterConfig> Clusters { get; } = clusters; | ||||||
|  |         public Microsoft.Extensions.Primitives.IChangeToken ChangeToken { get; } = new Microsoft.Extensions.Primitives.CancellationChangeToken(CancellationToken.None); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private class DirectRouteConfig | ||||||
|  |     { | ||||||
|  |         public string Path { get; set; } | ||||||
|  |         public string Service { get; set; } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void Dispose() | ||||||
|  |     { | ||||||
|  |         _cts.Cancel(); | ||||||
|  |         _cts.Dispose(); | ||||||
|  |         _watchCts.Cancel(); | ||||||
|  |         _watchCts.Dispose(); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								DysonNetwork.Gateway/Startup/ServiceCollectionExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								DysonNetwork.Gateway/Startup/ServiceCollectionExtensions.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | using DysonNetwork.Shared.Registry; | ||||||
|  | using Yarp.ReverseProxy.Configuration; | ||||||
|  |  | ||||||
|  | namespace DysonNetwork.Gateway.Startup; | ||||||
|  |  | ||||||
|  | public static class ServiceCollectionExtensions | ||||||
|  | { | ||||||
|  |     public static IServiceCollection AddGateway(this IServiceCollection services, IConfiguration configuration) | ||||||
|  |     { | ||||||
|  |         services.AddReverseProxy(); | ||||||
|  |         services.AddRegistryService(configuration); | ||||||
|  |         services.AddSingleton<IProxyConfigProvider, RegistryProxyConfigProvider>(); | ||||||
|  |  | ||||||
|  |         return services; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										43
									
								
								DysonNetwork.Gateway/appsettings.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								DysonNetwork.Gateway/appsettings.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | { | ||||||
|  |   "Logging": { | ||||||
|  |     "LogLevel": { | ||||||
|  |       "Default": "Information", | ||||||
|  |       "Microsoft.AspNetCore": "Warning" | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   "AllowedHosts": "*", | ||||||
|  |   "ConnectionStrings": { | ||||||
|  |     "Etcd": "etcd.orb.local:2379" | ||||||
|  |   }, | ||||||
|  |   "Etcd": { | ||||||
|  |     "Insecure": true | ||||||
|  |   }, | ||||||
|  |   "Service": { | ||||||
|  |     "Name": "DysonNetwork.Gateway", | ||||||
|  |     "Url": "https://localhost:7034" | ||||||
|  |   }, | ||||||
|  |   "DomainMappings": { | ||||||
|  |     "DysonNetwork.Pass": "id.solsynth.dev", | ||||||
|  |     "DysonNetwork.Drive": "drive.solsynth.dev", | ||||||
|  |     "DysonNetwork.Pusher": "push.solsynth.dev", | ||||||
|  |     "DysonNetwork.Sphere": "sphere.solsynth.dev" | ||||||
|  |   }, | ||||||
|  |   "PathAliases": { | ||||||
|  |     "DysonNetwork.Pass": "id", | ||||||
|  |     "DysonNetwork.Drive": "drive" | ||||||
|  |   }, | ||||||
|  |   "DirectRoutes": [ | ||||||
|  |     { | ||||||
|  |       "Path": "/ws", | ||||||
|  |       "Service": "DysonNetwork.Pusher" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "Path": "/.well-known/openid-configuration", | ||||||
|  |       "Service": "DysonNetwork.Pass" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "Path": "/.well-known/jwks", | ||||||
|  |       "Service": "DysonNetwork.Pass" | ||||||
|  |     } | ||||||
|  |   ] | ||||||
|  | } | ||||||
| @@ -15,8 +15,8 @@ public static class DysonAuthStartup | |||||||
|         { |         { | ||||||
|             var etcdClient = sp.GetRequiredService<IEtcdClient>(); |             var etcdClient = sp.GetRequiredService<IEtcdClient>(); | ||||||
|             var config = sp.GetRequiredService<IConfiguration>(); |             var config = sp.GetRequiredService<IConfiguration>(); | ||||||
|             var clientCertPath = config["Service:ClientCert"]; |             var clientCertPath = config["Service:ClientCert"]!; | ||||||
|             var clientKeyPath = config["Service:ClientKey"]; |             var clientKeyPath = config["Service:ClientKey"]!; | ||||||
|             var clientCertPassword = config["Service:CertPassword"]; |             var clientCertPassword = config["Service:CertPassword"]; | ||||||
|  |  | ||||||
|             return GrpcClientHelper |             return GrpcClientHelper | ||||||
| @@ -25,6 +25,20 @@ public static class DysonAuthStartup | |||||||
|                 .GetResult(); |                 .GetResult(); | ||||||
|         }); |         }); | ||||||
|          |          | ||||||
|  |         services.AddSingleton<PermissionService.PermissionServiceClient>(sp => | ||||||
|  |         { | ||||||
|  |             var etcdClient = sp.GetRequiredService<IEtcdClient>(); | ||||||
|  |             var config = sp.GetRequiredService<IConfiguration>(); | ||||||
|  |             var clientCertPath = config["Service:ClientCert"]!; | ||||||
|  |             var clientKeyPath = config["Service:ClientKey"]!; | ||||||
|  |             var clientCertPassword = config["Service:CertPassword"]; | ||||||
|  |  | ||||||
|  |             return GrpcClientHelper | ||||||
|  |                 .CreatePermissionServiceClient(etcdClient, clientCertPath, clientKeyPath, clientCertPassword) | ||||||
|  |                 .GetAwaiter() | ||||||
|  |                 .GetResult(); | ||||||
|  |         }); | ||||||
|  |  | ||||||
|         services.AddAuthentication(options => |         services.AddAuthentication(options => | ||||||
|             { |             { | ||||||
|                 options.DefaultAuthenticateScheme = AuthConstants.SchemeName; |                 options.DefaultAuthenticateScheme = AuthConstants.SchemeName; | ||||||
|   | |||||||
| @@ -62,6 +62,18 @@ public static class GrpcClientHelper | |||||||
|             clientCertPassword)); |             clientCertPassword)); | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     public static async Task<PermissionService.PermissionServiceClient> CreatePermissionServiceClient( | ||||||
|  |         IEtcdClient etcdClient, | ||||||
|  |         string clientCertPath, | ||||||
|  |         string clientKeyPath, | ||||||
|  |         string? clientCertPassword = null | ||||||
|  |     ) | ||||||
|  |     { | ||||||
|  |         var url = await GetServiceUrlFromEtcd(etcdClient, "DysonNetwork.Pass"); | ||||||
|  |         return new PermissionService.PermissionServiceClient(CreateCallInvoker(url, clientCertPath, clientKeyPath, | ||||||
|  |             clientCertPassword)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public static async Task<PusherService.PusherServiceClient> CreatePusherServiceClient( |     public static async Task<PusherService.PusherServiceClient> CreatePusherServiceClient( | ||||||
|         IEtcdClient etcdClient, |         IEtcdClient etcdClient, | ||||||
|         string clientCertPath, |         string clientCertPath, | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
|  |  | ||||||
| Microsoft Visual Studio Solution File, Format Version 12.00 | Microsoft Visual Studio Solution File, Format Version 12.00 | ||||||
|  | #  | ||||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DysonNetwork.Sphere", "DysonNetwork.Sphere\DysonNetwork.Sphere.csproj", "{CFF62EFA-F4C2-4FC7-8D97-25570B4DB452}" | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DysonNetwork.Sphere", "DysonNetwork.Sphere\DysonNetwork.Sphere.csproj", "{CFF62EFA-F4C2-4FC7-8D97-25570B4DB452}" | ||||||
| EndProject | EndProject | ||||||
| Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A444D180-5B51-49C3-A35D-AA55832BBC66}" | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A444D180-5B51-49C3-A35D-AA55832BBC66}" | ||||||
| @@ -15,6 +16,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DysonNetwork.Pusher", "Dyso | |||||||
| EndProject | EndProject | ||||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DysonNetwork.Drive", "DysonNetwork.Drive\DysonNetwork.Drive.csproj", "{8DE0B783-8852-494D-B90A-201ABBB71202}" | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DysonNetwork.Drive", "DysonNetwork.Drive\DysonNetwork.Drive.csproj", "{8DE0B783-8852-494D-B90A-201ABBB71202}" | ||||||
| EndProject | EndProject | ||||||
|  | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DysonNetwork.Gateway", "DysonNetwork.Gateway\DysonNetwork.Gateway.csproj", "{19EB0086-4049-4B78-91C4-EAC37130A006}" | ||||||
|  | EndProject | ||||||
| Global | Global | ||||||
| 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||||
| 		Debug|Any CPU = Debug|Any CPU | 		Debug|Any CPU = Debug|Any CPU | ||||||
| @@ -41,5 +44,9 @@ Global | |||||||
| 		{8DE0B783-8852-494D-B90A-201ABBB71202}.Debug|Any CPU.Build.0 = Debug|Any CPU | 		{8DE0B783-8852-494D-B90A-201ABBB71202}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||||
| 		{8DE0B783-8852-494D-B90A-201ABBB71202}.Release|Any CPU.ActiveCfg = Release|Any CPU | 		{8DE0B783-8852-494D-B90A-201ABBB71202}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||||
| 		{8DE0B783-8852-494D-B90A-201ABBB71202}.Release|Any CPU.Build.0 = Release|Any CPU | 		{8DE0B783-8852-494D-B90A-201ABBB71202}.Release|Any CPU.Build.0 = Release|Any CPU | ||||||
|  | 		{19EB0086-4049-4B78-91C4-EAC37130A006}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{19EB0086-4049-4B78-91C4-EAC37130A006}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||||
|  | 		{19EB0086-4049-4B78-91C4-EAC37130A006}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||||
|  | 		{19EB0086-4049-4B78-91C4-EAC37130A006}.Release|Any CPU.Build.0 = Release|Any CPU | ||||||
| 	EndGlobalSection | 	EndGlobalSection | ||||||
| EndGlobal | EndGlobal | ||||||
|   | |||||||
							
								
								
									
										95
									
								
								compose.yaml
									
									
									
									
									
								
							
							
						
						
									
										95
									
								
								compose.yaml
									
									
									
									
									
								
							| @@ -1,7 +1,96 @@ | |||||||
| services: | services: | ||||||
|   sphere: |   etcd: | ||||||
|     image: xsheep2010/dyson-sphere:latest |     image: bitnami/etcd:latest | ||||||
|  |     ports: | ||||||
|  |       - "2379:2379" | ||||||
|  |       - "2380:2380" | ||||||
|  |     environment: | ||||||
|  |       - ETCD_ADVERTISE_CLIENT_URLS=http://etcd:2379 | ||||||
|  |       - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 | ||||||
|  |       - ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380 | ||||||
|  |       - ETCD_INITIAL_ADVERTISE_PEER_URLS=http://etcd:2380 | ||||||
|  |       - ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster | ||||||
|  |       - ETCD_INITIAL_CLUSTER_STATE=new | ||||||
|  |       - ETCD_INITIAL_CLUSTER=etcd=http://etcd:2380 | ||||||
|  |     healthcheck: | ||||||
|  |       test: ["CMD", "etcdctl", "get", "/health"] | ||||||
|  |       interval: 5s | ||||||
|  |       timeout: 5s | ||||||
|  |       retries: 5 | ||||||
|  |  | ||||||
|  |   gateway: | ||||||
|  |     build: | ||||||
|  |       context: . | ||||||
|  |       dockerfile: DysonNetwork.Gateway/Dockerfile | ||||||
|  |     ports: | ||||||
|  |       - "8000:8080" | ||||||
|  |     environment: | ||||||
|  |       - ConnectionStrings__Etcd=http://etcd:2379 | ||||||
|  |       - Etcd__Insecure=true | ||||||
|  |       - Service__Name=DysonNetwork.Gateway | ||||||
|  |       - Service__Url=http://gateway:8080 | ||||||
|  |     depends_on: | ||||||
|  |       etcd: | ||||||
|  |         condition: service_healthy | ||||||
|  |  | ||||||
|  |   drive: | ||||||
|  |     build: | ||||||
|  |       context: . | ||||||
|  |       dockerfile: DysonNetwork.Drive/Dockerfile | ||||||
|     ports: |     ports: | ||||||
|       - "8001:8080" |       - "8001:8080" | ||||||
|  |     environment: | ||||||
|  |       - ConnectionStrings__Etcd=http://etcd:2379 | ||||||
|  |       - Etcd__Insecure=true | ||||||
|  |       - Service__Name=DysonNetwork.Drive | ||||||
|  |       - Service__Url=http://drive:8080 | ||||||
|  |     depends_on: | ||||||
|  |       etcd: | ||||||
|  |         condition: service_healthy | ||||||
|  |  | ||||||
|  |   pass: | ||||||
|  |     build: | ||||||
|  |       context: . | ||||||
|  |       dockerfile: DysonNetwork.Pass/Dockerfile | ||||||
|  |     ports: | ||||||
|  |       - "8002:8080" | ||||||
|  |     environment: | ||||||
|  |       - ConnectionStrings__Etcd=http://etcd:2379 | ||||||
|  |       - Etcd__Insecure=true | ||||||
|  |       - Service__Name=DysonNetwork.Pass | ||||||
|  |       - Service__Url=http://pass:8080 | ||||||
|  |     depends_on: | ||||||
|  |       etcd: | ||||||
|  |         condition: service_healthy | ||||||
|  |  | ||||||
|  |   pusher: | ||||||
|  |     build: | ||||||
|  |       context: . | ||||||
|  |       dockerfile: DysonNetwork.Pusher/Dockerfile | ||||||
|  |     ports: | ||||||
|  |       - "8003:8080" | ||||||
|  |     environment: | ||||||
|  |       - ConnectionStrings__Etcd=http://etcd:2379 | ||||||
|  |       - Etcd__Insecure=true | ||||||
|  |       - Service__Name=DysonNetwork.Pusher | ||||||
|  |       - Service__Url=http://pusher:8080 | ||||||
|  |     depends_on: | ||||||
|  |       etcd: | ||||||
|  |         condition: service_healthy | ||||||
|  |  | ||||||
|  |   sphere: | ||||||
|  |     build: | ||||||
|  |       context: . | ||||||
|  |       dockerfile: DysonNetwork.Sphere/Dockerfile | ||||||
|  |     ports: | ||||||
|  |       - "8004:8080" | ||||||
|  |     environment: | ||||||
|  |       - ConnectionStrings__Etcd=http://etcd:2379 | ||||||
|  |       - Etcd__Insecure=true | ||||||
|  |       - Service__Name=DysonNetwork.Sphere | ||||||
|  |       - Service__Url=http://sphere:8080 | ||||||
|     volumes: |     volumes: | ||||||
|       - "./keys:/app/keys" |       - "./keys:/app/keys" | ||||||
|  |     depends_on: | ||||||
|  |       etcd: | ||||||
|  |         condition: service_healthy | ||||||
		Reference in New Issue
	
	Block a user