Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# YARP Contribution Guide

We're excited to accept contributions, but like all open source projects need to set some guidelines on how and what to contribute. There can be nothing more frustrating than working on a change for some time, only to have it sitting forever as a PR. The purpose of this doc is to set expectations for how best to contribute so that YARP can benefit from the communities skills and knowlege.
We're excited to accept contributions, but like all open source projects need to set some guidelines on how and what to contribute. There can be nothing more frustrating than working on a change for some time, only to have it sitting forever as a PR. The purpose of this doc is to set expectations for how best to contribute so that YARP can benefit from the communities skills and knowledge.

## General feedback and discussions?
Start a discussion on the [repository issue tracker](https://github.com/dotnet/yarp/issues).
Expand Down
8 changes: 4 additions & 4 deletions docs/designs/yarp-tunneling.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ While many organizations are moving their computing to the cloud, there are occa

If all that the cloud needs to access is resources that are exposed over http, then a simpler solution is to have a gateway that can route traffic to the remote resource. Additionally, outbound connections over http(s) are not usually blocked, so having a on-prem gateway make an outbound connection to the cloud, is the easiest way to establish the route. This is the basis behind the [Azure Relay](https://learn.microsoft.com/azure/azure-relay/relay-what-is-it) service offering.

That is the principle of the tunnel feature for YARP. You operate two instances of the YARP proxy service, configured as a tunnel. The advantage over Azure Relay is that using a reverse proxy as an on-prem gateway means that both cloud and back end services can be used without needing to update the application other than addresses. This is particularly useful for services that may have been written by a 3rd party, or are no longer under active development, and so making changes to the configuration is complicated and expensive. Relay requires the sender and reciever to be updated to use its connection protocol.
That is the principle of the tunnel feature for YARP. You operate two instances of the YARP proxy service, configured as a tunnel. The advantage over Azure Relay is that using a reverse proxy as an on-prem gateway means that both cloud and back end services can be used without needing to update the application other than addresses. This is particularly useful for services that may have been written by a 3rd party, or are no longer under active development, and so making changes to the configuration is complicated and expensive. Relay requires the sender and receiver to be updated to use its connection protocol.

![Tunnel diagram](https://github.com/assets/95136/52d7491b-6e8a-4a2c-a51d-0734b3e41930)

Expand Down Expand Up @@ -42,7 +42,7 @@ The Front End should keep the WSS connection alive by sending pings every 30s if
| back-end | Routes | The back-end needs to have routes defined that will direct traffic to local resources. |

## front-end
The front-end is the proxy that will be called by clients to be able to access resources via the back-end proxy. It will route traffic over a tunnel created using a WSS connection from the back-end proxy. YARP needs a mechanism to know which requests will be routed via the tunnel. This will be achived by extending the existing cluster concept in YARP - The request to create a tunnel will specify the name of a cluster. Once the tunnel is established, it will be treated as a dynmamically created destination for the named cluster. Routes will not need to be changed, they will point at the cluster, and the tunnels will be used in the same way as destinations.
The front-end is the proxy that will be called by clients to be able to access resources via the back-end proxy. It will route traffic over a tunnel created using a WSS connection from the back-end proxy. YARP needs a mechanism to know which requests will be routed via the tunnel. This will be achieved by extending the existing cluster concept in YARP - The request to create a tunnel will specify the name of a cluster. Once the tunnel is established, it will be treated as a dynmamically created destination for the named cluster. Routes will not need to be changed, they will point at the cluster, and the tunnels will be used in the same way as destinations.

Tunnel services must be enabled by the proxy server:

Expand Down Expand Up @@ -188,7 +188,7 @@ In a large deployment, there needs to be the ability to have multiple front-end

## Authentication

The authentcation options for ASP.NET are diverse, and IT departments will likely have their own conditions on what is required to be able to secure a tunnel. So rather than trying to implement the combinatorial matrix of what customers could need, we should use a callback so that the proxy author can decide.
The authentication options for ASP.NET are diverse, and IT departments will likely have their own conditions on what is required to be able to secure a tunnel. So rather than trying to implement the combinatorial matrix of what customers could need, we should use a callback so that the proxy author can decide.

Samples should be created that show best practices using a secure mechanism such as client a certificate.

Expand All @@ -204,7 +204,7 @@ The purpose of the tunnel is to simplify service exposure by creating a tunnel t

## Metrics

? What telemery and events are needed for this?
? What telemetry and events are needed for this?

## Error conditions

Expand Down
6 changes: 3 additions & 3 deletions samples/Prometheus/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ The subsystems are:
- Number of requests started
- Number of request in flight
- Number of requests that have failed
- **Kestrel** which is the web server that handles incomming requests. Metrics include:
- **Kestrel** which is the web server that handles incoming requests. Metrics include:
- Connection Rate - how many connections are opened a second
- Total number of connections
- Number of TLS handshakes
- Incomming queue lengths
- Incoming queue lengths
- **Http** which is the HttpClient which makes outgoing requests to the destination servers. Metrics include:
- Number of outgoing requests started
- Number of Requests failed
Expand All @@ -42,7 +42,7 @@ The subsystems are:
- **HttpLoadApp**
- A simple app that uses HttpClient to create load against the 5 default routes defined by the proxy sample
- **run10destinations**
- Scripts for Windows & Linux that will start the sample server listening to endoints http://localhost:10000 to http://localhost:10009
- Scripts for Windows & Linux that will start the sample server listening to endpoints http://localhost:10000 to http://localhost:10009
- **prometheus.yml**
- A sample config file for Prometheus that includes polling from http://localhost:5000/metrics for the results from the server.

Expand Down
2 changes: 1 addition & 1 deletion samples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The following samples are provided:
| [Basic Yarp Sample](BasicYarpSample) | A simple sample that shows how to add YARP to the empty ASP.NET sample to create a fully functioning reverse proxy. |
| [Configuration](ReverseProxy.Config.Sample) | Shows all the options that are available in the YARP config file |
| [Minimal](ReverseProxy.Minimal.Sample) | Shows a minimal config-based YARP application using .NET 6's [Minimal Hosting for ASP.NET Core](https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-6-preview-4/#introducing-minimal-apis) |
| [Http.sys Delegation](ReverseProxy.HttpSysDelegation.Sample) | Shows an example of using YARP to do Http.sys queue delegation in addtion to proxying. |
| [Http.sys Delegation](ReverseProxy.HttpSysDelegation.Sample) | Shows an example of using YARP to do Http.sys queue delegation in addition to proxying. |
| [Transforms](ReverseProxy.Transforms.Sample) | Shows how to transform headers as part of the proxy operation |
| [Code extensibility](ReverseProxy.Code.Sample) | Shows how you can extend YARP using a custom configuration provider, and a middleware component as part of the YARP pipeline |
| [Authentication & Authorization](ReverseProxy.Auth.Sample) | Shows how to add authentication and authorization for routes to the proxy |
Expand Down
4 changes: 2 additions & 2 deletions samples/ReverseProxy.Code.Sample/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ This sample shows two common customizations via code of the YARP reverse proxy:

- ## Dynamic configuration from code

YARP supports pulling configuration from a config file, but in many scenarios the configuration of the routes to use, and which destinations the requests should be sent to need to be programatically fetched from another source. The extensibility of YARP makes it easy for you to fetch that data from where you need to, and then pass to the proxy as lists of objects.
YARP supports pulling configuration from a config file, but in many scenarios the configuration of the routes to use, and which destinations the requests should be sent to need to be programmatically fetched from another source. The extensibility of YARP makes it easy for you to fetch that data from where you need to, and then pass to the proxy as lists of objects.

This sample shows the routes and destinations being created in code, and then passed to an in-memory provider. The role of the in-memory provider is to give change notifications to YARP for when the config has been changed and needs to be updated. YARP uses a snapshot model for its configuration, so that changes are applied as an atomic action, that will apply to subsequent requests after the change is applied. Existing requests that are already being processed will be completed using the configuration snapshot from the time that they were recieved.
This sample shows the routes and destinations being created in code, and then passed to an in-memory provider. The role of the in-memory provider is to give change notifications to YARP for when the config has been changed and needs to be updated. YARP uses a snapshot model for its configuration, so that changes are applied as an atomic action, that will apply to subsequent requests after the change is applied. Existing requests that are already being processed will be completed using the configuration snapshot from the time that they were received.

The ```IProxyConfig``` interface implemented in InMemoryConfigProvider includes a change token which is used to signal when a batch of changes to the configuration is complete, and the proxy should take a snapshot and update its internal configuration. Part of the snapshot processing is to create an optimized route table in ASP.NET, which can be a CPU intensive operation, for that reason we don't recommend signaling for updates more than once per 15 seconds.

Expand Down
2 changes: 1 addition & 1 deletion samples/ReverseProxy.Config.Sample/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ The configuration shows two routes and two clusters:
- It includes [session affinity](https://learn.microsoft.com/aspnet/core/fundamentals/servers/yarp/session-affinity) using a cookie which will ensure subsequent requests from the same client go to the same host.
- It is configured to have both active and passive [health checks](https://learn.microsoft.com/aspnet/core/fundamentals/servers/yarp/dests-health-checks) - note the second destination will timeout for active checks (unless you have a host with that IP on your network)
- It includes [HttpClient configuration](https://learn.microsoft.com/aspnet/core/fundamentals/servers/yarp/http-client-config) setting outbound connection properties
- HttpRequest properties defaulting to HTTP/2 with a 2min timout
- HttpRequest properties defaulting to HTTP/2 with a 2min timeout

The other files in the sample are the same as the getting started instructions.

Expand Down
4 changes: 2 additions & 2 deletions samples/ReverseProxy.Config.Sample/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"allRouteProps": {
// matches /download/* and routes to "allClusterProps"
"ClusterId": "allClusterProps", // Name of one of the clusters
"Order": 0, // Lower numbers have higher precidence, default is 0
"Order": 0, // Lower numbers have higher precedence, default is 0
"AuthorizationPolicy": "Anonymous", // Name of the policy or "Default", "Anonymous"
"CorsPolicy": "disable", // Name of the CorsPolicy to apply to this route or "default", "disable"
"Match": { // Rules that have to be met for the route to match the request
Expand Down Expand Up @@ -128,7 +128,7 @@
"EnableMultipleHttp2Connections": true,
"RequestHeaderEncoding": "Latin1", // How to interpret non ASCII characters in proxied request's header values
"ResponseHeaderEncoding": "Latin1", // How to interpret non ASCII characters in proxied request's response header values
"WebProxy": { // Optinal proxy configuration for outgoing requests
"WebProxy": { // Optional proxy configuration for outgoing requests
"Address": "http://127.0.0.1",
"BypassOnLocal": true,
"UseDefaultCredentials": false
Expand Down
2 changes: 1 addition & 1 deletion samples/ReverseProxy.Metrics.Sample/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The subsystems are:
- Connection Rate - how many connections are opened a second
- Total number of connections
- Number of TLS handshakes
- Incomming queue length
- Incoming queue length

- **Http** which is the HttpClient which makes outgoing requests to the destination servers.

Expand Down
6 changes: 3 additions & 3 deletions src/Kubernetes.Controller/Caching/NamespaceCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ public bool IngressExists(V1Ingress ingress)

public bool TryLookup(NamespacedName key, out ReconcileData data)
{
var endspointsList = new List<Endpoints>();
var endpointsList = new List<Endpoints>();
var servicesList = new List<ServiceData>();

lock (_sync)
Expand All @@ -229,7 +229,7 @@ public bool TryLookup(NamespacedName key, out ReconcileData data)

if (_endpointsData.TryGetValue(serviceName, out var endpoints))
{
endspointsList.Add(endpoints);
endpointsList.Add(endpoints);
}
}
}
Expand All @@ -240,7 +240,7 @@ public bool TryLookup(NamespacedName key, out ReconcileData data)
return false;
}

data = new ReconcileData(ingress, servicesList, endspointsList);
data = new ReconcileData(ingress, servicesList, endpointsList);
return true;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Kubernetes.Controller/Client/ResourceInformer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public virtual async Task ReadyAsync(CancellationToken cancellationToken)
{
await _ready.WaitAsync(cancellationToken).ConfigureAwait(false);

// Release is called after each WaitAync because
// Release is called after each WaitAsync because
// the semaphore is being used as a manual reset event
_ready.Release();
}
Expand Down
2 changes: 1 addition & 1 deletion src/Kubernetes.Controller/Converters/YarpParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ private static YarpIngressOptions HandleAnnotations(YarpIngressContext context,
// CORS
// GRPC
// HTTP2
// Conneciton limits
// Connection limits
// rate limits

// backend health checks.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public static IServiceCollection AddKubernetesIngressMonitor(this IServiceCollec
/// Adds the dispatching controller that allows a Yarp "Ingress" application to monitor for changes.
/// </summary>
/// <param name="builder">The MVC builder.</param>
/// <returns>Rhe same <see cref="IMvcBuilder"/> for chaining.</returns>
/// <returns>The same <see cref="IMvcBuilder"/> for chaining.</returns>
public static IMvcBuilder AddKubernetesDispatchController(this IMvcBuilder builder)
{
return builder.AddApplicationPart(typeof(DispatchController).Assembly);
Expand Down
3 changes: 1 addition & 2 deletions src/Kubernetes.Controller/Queues/WorkQueue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,8 @@ public void Done(TItem item)
}

/// <summary>
/// Lengthes this instance.
/// Gets the queue length of this instance.
/// </summary>
/// <returns>System.Int32.</returns>
public int Len()
{
lock (_sync)
Expand Down
2 changes: 1 addition & 1 deletion src/Kubernetes.Controller/Services/QueueItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public QueueItem(string change)
}

/// <summary>
/// This identifies that a change has occured and either configuration requires to be rebuilt, or needs to be dispatched.
/// This identifies that a change has occurred and either configuration requires to be rebuilt, or needs to be dispatched.
/// </summary>
public string Change { get; }

Expand Down
4 changes: 2 additions & 2 deletions src/Kubernetes.Controller/Services/Reconciler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public async Task ProcessAsync(CancellationToken cancellationToken)
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Uncaught exception occured while reconciling ingress {IngressNamespace}/{IngressName}", ingress.Metadata.NamespaceProperty, ingress.Metadata.Name);
_logger.LogWarning(ex, "Uncaught exception occurred while reconciling ingress {IngressNamespace}/{IngressName}", ingress.Metadata.NamespaceProperty, ingress.Metadata.Name);
}
}

Expand All @@ -67,7 +67,7 @@ public async Task ProcessAsync(CancellationToken cancellationToken)
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Uncaught exception occured while reconciling");
_logger.LogWarning(ex, "Uncaught exception occurred while reconciling");
throw;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/ReverseProxy/ConfigurationSchema.json
Original file line number Diff line number Diff line change
Expand Up @@ -345,11 +345,11 @@
},
"Set": {
"type": "string",
"description": "Name of the route paramter to set the query parameter to."
"description": "Name of the route parameter to set the query parameter to."
},
"Append": {
"type": "string",
"description": "Name of the route paramter to append to the query parameter."
"description": "Name of the route parameter to append to the query parameter."
}
},
"additionalProperties": false,
Expand Down
10 changes: 5 additions & 5 deletions src/ReverseProxy/Health/ActiveHealthCheckMonitor.Log.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ private static class Log
EventIds.ActiveHealthProbingFailedOnCluster,
"Active health probing failed on cluster `{clusterId}`.");

private static readonly Action<ILogger, string, Exception> _errorOccuredDuringActiveHealthProbingShutdownOnCluster = LoggerMessage.Define<string>(
private static readonly Action<ILogger, string, Exception> _errorOccurredDuringActiveHealthProbingShutdownOnCluster = LoggerMessage.Define<string>(
LogLevel.Error,
EventIds.ErrorOccuredDuringActiveHealthProbingShutdownOnCluster,
"An error occured during shutdown of an active health probing on cluster `{clusterId}`.");
EventIds.ErrorOccurredDuringActiveHealthProbingShutdownOnCluster,
"An error occurred during shutdown of an active health probing on cluster `{clusterId}`.");

private static readonly Action<ILogger, string, string, Exception> _activeHealthProbeConstructionFailedOnCluster = LoggerMessage.Define<string, string>(
LogLevel.Error,
Expand Down Expand Up @@ -65,9 +65,9 @@ public static void ActiveHealthProbingFailedOnCluster(ILogger logger, string clu
_activeHealthProbingFailedOnCluster(logger, clusterId, ex);
}

public static void ErrorOccuredDuringActiveHealthProbingShutdownOnCluster(ILogger logger, string clusterId, Exception ex)
public static void ErrorOccurredDuringActiveHealthProbingShutdownOnCluster(ILogger logger, string clusterId, Exception ex)
{
_errorOccuredDuringActiveHealthProbingShutdownOnCluster(logger, clusterId, ex);
_errorOccurredDuringActiveHealthProbingShutdownOnCluster(logger, clusterId, ex);
}

public static void ActiveHealthProbeConstructionFailedOnCluster(ILogger logger, string destinationId, string clusterId, Exception ex)
Expand Down
2 changes: 1 addition & 1 deletion src/ReverseProxy/Health/ActiveHealthCheckMonitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ private async Task ProbeCluster(ClusterState cluster)
}
catch (Exception ex)
{
Log.ErrorOccuredDuringActiveHealthProbingShutdownOnCluster(_logger, cluster.ClusterId, ex);
Log.ErrorOccurredDuringActiveHealthProbingShutdownOnCluster(_logger, cluster.ClusterId, ex);
}

Log.StoppedActiveHealthProbingOnCluster(_logger, cluster.ClusterId);
Expand Down
Loading
Loading