Fix issue #936: Kubernetes service discovery provider doesn't allow cross-namespace discovery (#938)

* Allow default k8s namespace to be overridden

* Add ServiceNamespace to ReRoute configuration

* Remove debug comments

* Update unit tests

* Unit tests (Eureka)

* Update docs

* Re-run build
This commit is contained in:
Jason Morton
2019-06-25 04:08:18 +01:00
committed by Thiago Loureiro
parent 959a92ec6a
commit e1d7f28951
13 changed files with 65 additions and 20 deletions

View File

@ -6,13 +6,13 @@
public static class ConsulProviderFactory
{
public static ServiceDiscoveryFinderDelegate Get = (provider, config, name) =>
public static ServiceDiscoveryFinderDelegate Get = (provider, config, reRoute) =>
{
var factory = provider.GetService<IOcelotLoggerFactory>();
var consulFactory = provider.GetService<IConsulClientFactory>();
var consulRegistryConfiguration = new ConsulRegistryConfiguration(config.Host, config.Port, name, config.Token);
var consulRegistryConfiguration = new ConsulRegistryConfiguration(config.Host, config.Port, reRoute.ServiceName, config.Token);
var consulServiceDiscoveryProvider = new Consul(consulRegistryConfiguration, factory, consulFactory);

View File

@ -6,13 +6,13 @@
public static class EurekaProviderFactory
{
public static ServiceDiscoveryFinderDelegate Get = (provider, config, name) =>
public static ServiceDiscoveryFinderDelegate Get = (provider, config, reRoute) =>
{
var client = provider.GetService<IDiscoveryClient>();
if (config.Type?.ToLower() == "eureka" && client != null)
{
return new Eureka(name, client);
return new Eureka(reRoute.ServiceName, client);
}
return null;

View File

@ -24,8 +24,7 @@ namespace Ocelot.Provider.Kubernetes
public async Task<List<Service>> Get()
{
var service = await kubeApi.ServicesV1()
.Get(kubeRegistryConfiguration.KeyOfServiceInK8s, kubeRegistryConfiguration.KubeNamespace);
var service = await kubeApi.ServicesV1().Get(kubeRegistryConfiguration.KeyOfServiceInK8s, kubeRegistryConfiguration.KubeNamespace);
var services = new List<Service>();
if (IsValid(service))
{

View File

@ -3,24 +3,25 @@ using Microsoft.Extensions.DependencyInjection;
using Ocelot.Logging;
using Ocelot.ServiceDiscovery;
using System;
using Ocelot.Configuration;
namespace Ocelot.Provider.Kubernetes
{
public static class KubernetesProviderFactory
{
public static ServiceDiscoveryFinderDelegate Get = (provider, config, name) =>
public static ServiceDiscoveryFinderDelegate Get = (provider, config, reRoute) =>
{
var factory = provider.GetService<IOcelotLoggerFactory>();
return GetkubeProvider(provider, config, name, factory);
return GetkubeProvider(provider, config, reRoute, factory);
};
private static ServiceDiscovery.Providers.IServiceDiscoveryProvider GetkubeProvider(IServiceProvider provider, Configuration.ServiceProviderConfiguration config, string name, IOcelotLoggerFactory factory)
private static ServiceDiscovery.Providers.IServiceDiscoveryProvider GetkubeProvider(IServiceProvider provider, Configuration.ServiceProviderConfiguration config, DownstreamReRoute reRoute, IOcelotLoggerFactory factory)
{
var kubeClient = provider.GetService<IKubeApiClient>();
var k8sRegistryConfiguration = new KubeRegistryConfiguration()
{
KeyOfServiceInK8s = name,
KubeNamespace = config.Namespace,
KeyOfServiceInK8s = reRoute.ServiceName,
KubeNamespace = string.IsNullOrEmpty(reRoute.ServiceNamespace) ? config.Namespace : reRoute.ServiceNamespace
};
var k8sServiceDiscoveryProvider = new Kube(k8sRegistryConfiguration, factory, kubeClient);

View File

@ -30,6 +30,7 @@ namespace Ocelot.Configuration.Builder
private RateLimitOptions _rateLimitOptions;
private bool _useServiceDiscovery;
private string _serviceName;
private string _serviceNamespace;
private List<HeaderFindAndReplace> _upstreamHeaderFindAndReplace;
private List<HeaderFindAndReplace> _downstreamHeaderFindAndReplace;
private readonly List<DownstreamHostAndPort> _downstreamAddresses;
@ -185,6 +186,12 @@ namespace Ocelot.Configuration.Builder
_serviceName = serviceName;
return this;
}
public DownstreamReRouteBuilder WithServiceNamespace(string serviceNamespace)
{
_serviceNamespace = serviceNamespace;
return this;
}
public DownstreamReRouteBuilder WithUpstreamHeaderFindAndReplace(List<HeaderFindAndReplace> upstreamHeaderFindAndReplace)
{
@ -243,6 +250,7 @@ namespace Ocelot.Configuration.Builder
_downstreamHeaderFindAndReplace,
_downstreamAddresses,
_serviceName,
_serviceNamespace,
_httpHandlerOptions,
_useServiceDiscovery,
_enableRateLimiting,

View File

@ -126,6 +126,7 @@ namespace Ocelot.Configuration.Creator
.WithRateLimitOptions(rateLimitOption)
.WithHttpHandlerOptions(httpHandlerOptions)
.WithServiceName(fileReRoute.ServiceName)
.WithServiceNamespace(fileReRoute.ServiceNamespace)
.WithUseServiceDiscovery(fileReRouteOptions.UseServiceDiscovery)
.WithUpstreamHeaderFindAndReplace(hAndRs.Upstream)
.WithDownstreamHeaderFindAndReplace(hAndRs.Downstream)

View File

@ -13,6 +13,7 @@ namespace Ocelot.Configuration
List<HeaderFindAndReplace> downstreamHeadersFindAndReplace,
List<DownstreamHostAndPort> downstreamAddresses,
string serviceName,
string serviceNamespace,
HttpHandlerOptions httpHandlerOptions,
bool useServiceDiscovery,
bool enableEndpointEndpointRateLimiting,
@ -47,6 +48,7 @@ namespace Ocelot.Configuration
DownstreamHeadersFindAndReplace = downstreamHeadersFindAndReplace ?? new List<HeaderFindAndReplace>();
DownstreamAddresses = downstreamAddresses ?? new List<DownstreamHostAndPort>();
ServiceName = serviceName;
ServiceNamespace = serviceNamespace;
HttpHandlerOptions = httpHandlerOptions;
UseServiceDiscovery = useServiceDiscovery;
EnableEndpointEndpointRateLimiting = enableEndpointEndpointRateLimiting;
@ -76,6 +78,7 @@ namespace Ocelot.Configuration
public List<HeaderFindAndReplace> DownstreamHeadersFindAndReplace { get; }
public List<DownstreamHostAndPort> DownstreamAddresses { get; }
public string ServiceName { get; }
public string ServiceNamespace { get; }
public HttpHandlerOptions HttpHandlerOptions { get; }
public bool UseServiceDiscovery { get; }
public bool EnableEndpointEndpointRateLimiting { get; }

View File

@ -38,6 +38,7 @@ namespace Ocelot.Configuration.File
public FileCacheOptions FileCacheOptions { get; set; }
public bool ReRouteIsCaseSensitive { get; set; }
public string ServiceName { get; set; }
public string ServiceNamespace { get; set; }
public string DownstreamScheme { get; set; }
public FileQoSOptions QoSOptions { get; set; }
public FileLoadBalancerOptions LoadBalancerOptions { get; set; }

View File

@ -4,5 +4,5 @@ namespace Ocelot.ServiceDiscovery
using Providers;
using System;
public delegate IServiceDiscoveryProvider ServiceDiscoveryFinderDelegate(IServiceProvider provider, ServiceProviderConfiguration config, string key);
public delegate IServiceDiscoveryProvider ServiceDiscoveryFinderDelegate(IServiceProvider provider, ServiceProviderConfiguration config, DownstreamReRoute reRoute);
}

View File

@ -27,7 +27,7 @@ namespace Ocelot.ServiceDiscovery
{
if (reRoute.UseServiceDiscovery)
{
return GetServiceDiscoveryProvider(serviceConfig, reRoute.ServiceName);
return GetServiceDiscoveryProvider(serviceConfig, reRoute);
}
var services = new List<Service>();
@ -42,17 +42,17 @@ namespace Ocelot.ServiceDiscovery
return new OkResponse<IServiceDiscoveryProvider>(new ConfigurationServiceProvider(services));
}
private Response<IServiceDiscoveryProvider> GetServiceDiscoveryProvider(ServiceProviderConfiguration config, string key)
private Response<IServiceDiscoveryProvider> GetServiceDiscoveryProvider(ServiceProviderConfiguration config, DownstreamReRoute reRoute)
{
if (config.Type?.ToLower() == "servicefabric")
{
var sfConfig = new ServiceFabricConfiguration(config.Host, config.Port, key);
var sfConfig = new ServiceFabricConfiguration(config.Host, config.Port, reRoute.ServiceName);
return new OkResponse<IServiceDiscoveryProvider>(new ServiceFabricServiceDiscoveryProvider(sfConfig));
}
if (_delegates != null)
{
var provider = _delegates?.Invoke(_provider, config, key);
var provider = _delegates?.Invoke(_provider, config, reRoute);
if (provider.GetType().Name.ToLower() == config.Type.ToLower())
{