diff --git a/docs/reference/schema.md b/docs/reference/schema.md index 1c3c148a..0b158444 100644 --- a/docs/reference/schema.md +++ b/docs/reference/schema.md @@ -402,6 +402,10 @@ Specifies the protocol used by the binding. The protocol is used in [service dis Specifies the hostname used by the binding. The protocol is used in [service discovery](/docs/reference/service_discovery.md) to construct a URL. It's safe to omit the `host` when localhost should be used for local development. +#### `routes` (`string[]`) + +Specifies the list of additional routes to show in Bindings on the Dashboard for easy access. Example route value: /swagger. + #### `port` (string) Specifies the port used by the binding. The port is used in [service discovery](/docs/reference/service_discovery.md) to construct a URL. diff --git a/src/Microsoft.Tye.Core/ApplicationFactory.cs b/src/Microsoft.Tye.Core/ApplicationFactory.cs index dd126b47..dd8bf1a8 100644 --- a/src/Microsoft.Tye.Core/ApplicationFactory.cs +++ b/src/Microsoft.Tye.Core/ApplicationFactory.cs @@ -376,6 +376,7 @@ namespace Microsoft.Tye ContainerPort = configBinding.ContainerPort, Port = configBinding.Port, Protocol = configBinding.Protocol, + Routes = configBinding.Routes }; // Assume HTTP for projects only (containers may be different) diff --git a/src/Microsoft.Tye.Core/BindingBuilder.cs b/src/Microsoft.Tye.Core/BindingBuilder.cs index 8e795075..3f933eaa 100644 --- a/src/Microsoft.Tye.Core/BindingBuilder.cs +++ b/src/Microsoft.Tye.Core/BindingBuilder.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Collections.Generic; + namespace Microsoft.Tye { public sealed class BindingBuilder @@ -12,5 +14,6 @@ namespace Microsoft.Tye public int? ContainerPort { get; set; } public string? Host { get; set; } public string? Protocol { get; set; } + public List Routes { get; set; } = new List(); } } diff --git a/src/Microsoft.Tye.Core/ConfigModel/ConfigServiceBinding.cs b/src/Microsoft.Tye.Core/ConfigModel/ConfigServiceBinding.cs index 5d6f9bd2..52f6464e 100644 --- a/src/Microsoft.Tye.Core/ConfigModel/ConfigServiceBinding.cs +++ b/src/Microsoft.Tye.Core/ConfigModel/ConfigServiceBinding.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Collections.Generic; + namespace Microsoft.Tye.ConfigModel { public class ConfigServiceBinding @@ -12,5 +14,6 @@ namespace Microsoft.Tye.ConfigModel public int? ContainerPort { get; set; } public string? Host { get; set; } public string? Protocol { get; set; } + public List Routes { get; set; } = new List(); } } diff --git a/src/Microsoft.Tye.Core/Serialization/ConfigServiceParser.cs b/src/Microsoft.Tye.Core/Serialization/ConfigServiceParser.cs index 014bce75..c4f1e4a9 100644 --- a/src/Microsoft.Tye.Core/Serialization/ConfigServiceParser.cs +++ b/src/Microsoft.Tye.Core/Serialization/ConfigServiceParser.cs @@ -218,6 +218,14 @@ namespace Tye.Serialization case "protocol": binding.Protocol = YamlParser.GetScalarValue(key, child.Value); break; + case "routes": + if (child.Value.NodeType != YamlNodeType.Sequence) + { + throw new TyeYamlException(child.Value.Start, CoreStrings.FormatExpectedYamlSequence(key)); + } + + HandleServiceBindingRoutes((child.Value as YamlSequenceNode)!, binding.Routes); + break; default: throw new TyeYamlException(child.Key.Start, CoreStrings.FormatUnrecognizedKey(key)); } @@ -571,6 +579,16 @@ namespace Tye.Serialization tags.Add(tag); } } + + private static void HandleServiceBindingRoutes(YamlSequenceNode yamlSequenceNode, List routes) + { + foreach (var child in yamlSequenceNode!.Children) + { + var route = YamlParser.GetScalarValue(child); + routes.Add(route); + } + } + private static void HandleServiceDockerArgsNameMapping(YamlMappingNode yamlMappingNode, IDictionary dockerArguments) { foreach (var child in yamlMappingNode!.Children) diff --git a/src/Microsoft.Tye.Hosting/Dashboard/Pages/Index.razor b/src/Microsoft.Tye.Hosting/Dashboard/Pages/Index.razor index 15f1ead2..cf06ba18 100644 --- a/src/Microsoft.Tye.Hosting/Dashboard/Pages/Index.razor +++ b/src/Microsoft.Tye.Hosting/Dashboard/Pages/Index.razor @@ -2,6 +2,12 @@ @inject Application application @implements IDisposable + +

Services

@@ -54,16 +60,21 @@ if (b.Protocol == "http" || b.Protocol == "https") { var url = GetUrl(b); - @url + @url + foreach (var r in b.Routes) + { + var routeUrl = url + r; + @routeUrl + } } else { - @GetUrl(b) + @GetUrl(b) } } else { - @b.ConnectionString + @b.ConnectionString } } } diff --git a/src/Microsoft.Tye.Hosting/DockerRunner.cs b/src/Microsoft.Tye.Hosting/DockerRunner.cs index 7c011e36..2284f551 100644 --- a/src/Microsoft.Tye.Hosting/DockerRunner.cs +++ b/src/Microsoft.Tye.Hosting/DockerRunner.cs @@ -94,6 +94,7 @@ namespace Microsoft.Tye.Hosting Protocol = binding.Protocol }; b.ReplicaPorts.Add(b.Port.Value); + b.Routes.AddRange(binding.Routes); proxyDescription.Bindings.Add(b); } var proxyContainerService = new Service(proxyDescription, ServiceSource.Host); diff --git a/src/Microsoft.Tye.Hosting/Model/ServiceBinding.cs b/src/Microsoft.Tye.Hosting/Model/ServiceBinding.cs index 2adaa479..286924f2 100644 --- a/src/Microsoft.Tye.Hosting/Model/ServiceBinding.cs +++ b/src/Microsoft.Tye.Hosting/Model/ServiceBinding.cs @@ -17,5 +17,6 @@ namespace Microsoft.Tye.Hosting.Model public string? IPAddress { get; set; } public string? Protocol { get; set; } public List ReplicaPorts { get; } = new List(); + public List Routes { get; } = new List(); } } diff --git a/src/tye/ApplicationBuilderExtensions.cs b/src/tye/ApplicationBuilderExtensions.cs index 350e860f..0eef6831 100644 --- a/src/tye/ApplicationBuilderExtensions.cs +++ b/src/tye/ApplicationBuilderExtensions.cs @@ -174,7 +174,7 @@ namespace Microsoft.Tye foreach (var binding in service.Bindings) { - description.Bindings.Add(new ServiceBinding() + var sb = new ServiceBinding() { ConnectionString = binding.ConnectionString, Host = binding.Host, @@ -182,7 +182,9 @@ namespace Microsoft.Tye Name = binding.Name, Port = binding.Port, Protocol = binding.Protocol, - }); + }; + sb.Routes.AddRange(binding.Routes); + description.Bindings.Add(sb); } services.Add(service.Name, new Service(description, service.Source)); diff --git a/test/UnitTests/TyeDeserializationTests.cs b/test/UnitTests/TyeDeserializationTests.cs index c03c1713..18966cad 100644 --- a/test/UnitTests/TyeDeserializationTests.cs +++ b/test/UnitTests/TyeDeserializationTests.cs @@ -82,6 +82,9 @@ services: containerPort: 80 host: localhost protocol: http + routes: + - /swagger + - /graphql - name: appB project: ApplicationB/ApplicationB.csproj replicas: 2 @@ -155,6 +158,9 @@ services: containerPort: 80 host: localhost protocol: http + routes: + - /swagger + - /graphql - name: appB project: ApplicationB/ApplicationB.csproj replicas: 2