mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-06-19 22:08:17 +08:00
Refactored k8s endpoints PR +semver: major
This commit is contained in:
@ -0,0 +1,38 @@
|
||||
using HTTPlease;
|
||||
using KubeClient;
|
||||
using KubeClient.Models;
|
||||
using KubeClient.ResourceClients;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ocelot.Provider.Kubernetes.KubeApiClientExtensions
|
||||
{
|
||||
public class EndPointClientV1 : KubeResourceClient
|
||||
{
|
||||
private readonly HttpRequest _collection = KubeRequest.Create("api/v1/namespaces/{Namespace}/endpoints/{ServiceName}");
|
||||
|
||||
public EndPointClientV1(IKubeApiClient client) : base(client)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<EndpointsV1> Get(string serviceName, string kubeNamespace = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (string.IsNullOrEmpty(serviceName)) throw new ArgumentNullException(nameof(serviceName));
|
||||
|
||||
var response = await Http.GetAsync(
|
||||
_collection.WithTemplateParameters(new
|
||||
{
|
||||
Namespace = kubeNamespace ?? KubeClient.DefaultNamespace,
|
||||
ServiceName = serviceName
|
||||
}),
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
return await response.ReadContentAsAsync<EndpointsV1>();
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -6,57 +6,52 @@ using Ocelot.Values;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Ocelot.Provider.Kubernetes.KubeApiClientExtensions;
|
||||
|
||||
namespace Ocelot.Provider.Kubernetes
|
||||
{
|
||||
public class Kube : IServiceDiscoveryProvider
|
||||
public class KubernetesServiceDiscoveryProvider : IServiceDiscoveryProvider
|
||||
{
|
||||
private KubeRegistryConfiguration kubeRegistryConfiguration;
|
||||
private IOcelotLogger logger;
|
||||
private IKubeApiClient kubeApi;
|
||||
private readonly KubeRegistryConfiguration _kubeRegistryConfiguration;
|
||||
private readonly IOcelotLogger _logger;
|
||||
private readonly IKubeApiClient _kubeApi;
|
||||
|
||||
public Kube(KubeRegistryConfiguration kubeRegistryConfiguration, IOcelotLoggerFactory factory, IKubeApiClient kubeApi)
|
||||
public KubernetesServiceDiscoveryProvider(KubeRegistryConfiguration kubeRegistryConfiguration, IOcelotLoggerFactory factory, IKubeApiClient kubeApi)
|
||||
{
|
||||
this.kubeRegistryConfiguration = kubeRegistryConfiguration;
|
||||
this.logger = factory.CreateLogger<Kube>();
|
||||
this.kubeApi = kubeApi;
|
||||
_kubeRegistryConfiguration = kubeRegistryConfiguration;
|
||||
_logger = factory.CreateLogger<KubernetesServiceDiscoveryProvider>();
|
||||
_kubeApi = kubeApi;
|
||||
}
|
||||
|
||||
|
||||
public async Task<List<Service>> Get()
|
||||
{
|
||||
var service = await kubeApi.ServicesV1().Get(kubeRegistryConfiguration.KeyOfServiceInK8s, kubeRegistryConfiguration.KubeNamespace);
|
||||
var endpoint = await _kubeApi
|
||||
.ResourceClient(client => new EndPointClientV1(client))
|
||||
.Get(_kubeRegistryConfiguration.KeyOfServiceInK8s, _kubeRegistryConfiguration.KubeNamespace);
|
||||
|
||||
var services = new List<Service>();
|
||||
if (IsValid(service))
|
||||
if (endpoint != null && endpoint.Subsets.Any())
|
||||
{
|
||||
services.Add(BuildService(service));
|
||||
services.AddRange(BuildServices(endpoint));
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogWarning($"namespace:{kubeRegistryConfiguration.KubeNamespace }service:{kubeRegistryConfiguration.KeyOfServiceInK8s} Unable to use ,it is invalid. Address must contain host only e.g. localhost and port must be greater than 0");
|
||||
_logger.LogWarning($"namespace:{_kubeRegistryConfiguration.KubeNamespace }service:{_kubeRegistryConfiguration.KeyOfServiceInK8s} Unable to use ,it is invalid. Address must contain host only e.g. localhost and port must be greater than 0");
|
||||
}
|
||||
return services;
|
||||
}
|
||||
|
||||
private bool IsValid(ServiceV1 service)
|
||||
private List<Service> BuildServices(EndpointsV1 endpoint)
|
||||
{
|
||||
if (string.IsNullOrEmpty(service.Spec.ClusterIP) || service.Spec.Ports.Count <= 0)
|
||||
var services = new List<Service>();
|
||||
|
||||
foreach (var subset in endpoint.Subsets)
|
||||
{
|
||||
return false;
|
||||
services.AddRange(subset.Addresses.Select(address => new Service(endpoint.Metadata.Name,
|
||||
new ServiceHostAndPort(address.Ip, subset.Ports.First().Port),
|
||||
endpoint.Metadata.Uid, string.Empty, Enumerable.Empty<string>())));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private Service BuildService(ServiceV1 serviceEntry)
|
||||
{
|
||||
var servicePort = serviceEntry.Spec.Ports.FirstOrDefault();
|
||||
return new Service(
|
||||
serviceEntry.Metadata.Name,
|
||||
new ServiceHostAndPort(serviceEntry.Spec.ClusterIP, servicePort.Port),
|
||||
serviceEntry.Metadata.Uid,
|
||||
string.Empty,
|
||||
Enumerable.Empty<string>());
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,22 +12,24 @@ namespace Ocelot.Provider.Kubernetes
|
||||
public static ServiceDiscoveryFinderDelegate Get = (provider, config, reRoute) =>
|
||||
{
|
||||
var factory = provider.GetService<IOcelotLoggerFactory>();
|
||||
return GetkubeProvider(provider, config, reRoute, factory);
|
||||
return GetKubeProvider(provider, config, reRoute, factory);
|
||||
};
|
||||
|
||||
private static ServiceDiscovery.Providers.IServiceDiscoveryProvider GetkubeProvider(IServiceProvider provider, Configuration.ServiceProviderConfiguration config, DownstreamReRoute reRoute, IOcelotLoggerFactory factory)
|
||||
private static ServiceDiscovery.Providers.IServiceDiscoveryProvider GetKubeProvider(IServiceProvider provider, ServiceProviderConfiguration config, DownstreamReRoute reRoute, IOcelotLoggerFactory factory)
|
||||
{
|
||||
var kubeClient = provider.GetService<IKubeApiClient>();
|
||||
|
||||
var k8sRegistryConfiguration = new KubeRegistryConfiguration()
|
||||
{
|
||||
KeyOfServiceInK8s = reRoute.ServiceName,
|
||||
KubeNamespace = string.IsNullOrEmpty(reRoute.ServiceNamespace) ? config.Namespace : reRoute.ServiceNamespace
|
||||
};
|
||||
|
||||
var k8sServiceDiscoveryProvider = new Kube(k8sRegistryConfiguration, factory, kubeClient);
|
||||
var k8sServiceDiscoveryProvider = new KubernetesServiceDiscoveryProvider(k8sRegistryConfiguration, factory, kubeClient);
|
||||
|
||||
if (config.Type?.ToLower() == "pollkube")
|
||||
{
|
||||
return new PollKube(config.PollingInterval, factory, k8sServiceDiscoveryProvider);
|
||||
return new PollKubernetes(config.PollingInterval, factory, k8sServiceDiscoveryProvider);
|
||||
}
|
||||
return k8sServiceDiscoveryProvider;
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Ocelot.Provider.Kubernetes
|
||||
{
|
||||
public class PollKube : IServiceDiscoveryProvider
|
||||
public class PollKubernetes : IServiceDiscoveryProvider
|
||||
{
|
||||
private readonly IOcelotLogger _logger;
|
||||
private readonly IServiceDiscoveryProvider _kubeServiceDiscoveryProvider;
|
||||
@ -15,9 +15,9 @@ namespace Ocelot.Provider.Kubernetes
|
||||
private bool _polling;
|
||||
private List<Service> _services;
|
||||
|
||||
public PollKube(int pollingInterval, IOcelotLoggerFactory factory, IServiceDiscoveryProvider kubeServiceDiscoveryProvider)
|
||||
public PollKubernetes(int pollingInterval, IOcelotLoggerFactory factory, IServiceDiscoveryProvider kubeServiceDiscoveryProvider)
|
||||
{
|
||||
_logger = factory.CreateLogger<PollKube>();
|
||||
_logger = factory.CreateLogger<PollKubernetes>();
|
||||
_kubeServiceDiscoveryProvider = kubeServiceDiscoveryProvider;
|
||||
_services = new List<Service>();
|
||||
|
Reference in New Issue
Block a user