From 88034a5f9f1a95bdea969e3972a852976a87e656 Mon Sep 17 00:00:00 2001 From: WebMed Date: Mon, 10 Feb 2020 23:52:55 +0100 Subject: [PATCH] Updated KubeProvider to use pod endpoints instead of service --- .../EndPointClientV1.cs | 41 +++++++++++++++++++ .../KubeClientExtensions.cs | 12 ++++++ .../KubeProvider.cs | 36 +++++++--------- .../Ocelot.Provider.Kubernetes.csproj | 4 +- 4 files changed, 69 insertions(+), 24 deletions(-) create mode 100644 src/Ocelot.Provider.Kubernetes/KubeApiClientExtensions/EndPointClientV1.cs create mode 100644 src/Ocelot.Provider.Kubernetes/KubeApiClientExtensions/KubeClientExtensions.cs diff --git a/src/Ocelot.Provider.Kubernetes/KubeApiClientExtensions/EndPointClientV1.cs b/src/Ocelot.Provider.Kubernetes/KubeApiClientExtensions/EndPointClientV1.cs new file mode 100644 index 00000000..dfae202b --- /dev/null +++ b/src/Ocelot.Provider.Kubernetes/KubeApiClientExtensions/EndPointClientV1.cs @@ -0,0 +1,41 @@ +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 + { + public EndPointClientV1(IKubeApiClient client) : base(client) + { + } + + public async Task Get(string serviceName, string kubeNamespace = null, CancellationToken cancellationToken = default) + { + if (string.IsNullOrEmpty(serviceName)) throw new ArgumentNullException(nameof(serviceName)); + + var response = await Http.GetAsync( + Requests.Collection.WithTemplateParameters(new + { + Namespace = kubeNamespace ?? KubeClient.DefaultNamespace, + ServiceName = serviceName + }), + cancellationToken: cancellationToken + ); + + if (response.IsSuccessStatusCode) + return await response.ReadContentAsAsync(); + + return null; + } + + public static class Requests + { + public static readonly HttpRequest Collection = KubeRequest.Create("api/v1/namespaces/{Namespace}/endpoints/{ServiceName}"); + } + } +} diff --git a/src/Ocelot.Provider.Kubernetes/KubeApiClientExtensions/KubeClientExtensions.cs b/src/Ocelot.Provider.Kubernetes/KubeApiClientExtensions/KubeClientExtensions.cs new file mode 100644 index 00000000..1985dda8 --- /dev/null +++ b/src/Ocelot.Provider.Kubernetes/KubeApiClientExtensions/KubeClientExtensions.cs @@ -0,0 +1,12 @@ +using KubeClient; + +namespace Ocelot.Provider.Kubernetes.KubeApiClientExtensions +{ + public static class KubeClientExtensions + { + public static EndPointClientV1 EndPointsV1(this IKubeApiClient kubeClient) + { + return kubeClient.ResourceClient(client => new EndPointClientV1(client)); + } + } +} diff --git a/src/Ocelot.Provider.Kubernetes/KubeProvider.cs b/src/Ocelot.Provider.Kubernetes/KubeProvider.cs index 22f5b115..a4615b8c 100644 --- a/src/Ocelot.Provider.Kubernetes/KubeProvider.cs +++ b/src/Ocelot.Provider.Kubernetes/KubeProvider.cs @@ -6,14 +6,15 @@ 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 { private KubeRegistryConfiguration kubeRegistryConfiguration; - private IOcelotLogger logger; - private IKubeApiClient kubeApi; + private readonly IOcelotLogger logger; + private readonly IKubeApiClient kubeApi; public Kube(KubeRegistryConfiguration kubeRegistryConfiguration, IOcelotLoggerFactory factory, IKubeApiClient kubeApi) { @@ -22,14 +23,13 @@ namespace Ocelot.Provider.Kubernetes this.kubeApi = kubeApi; } - public async Task> Get() { - var service = await kubeApi.ServicesV1().Get(kubeRegistryConfiguration.KeyOfServiceInK8s, kubeRegistryConfiguration.KubeNamespace); + var endpoint = await kubeApi.EndPointsV1().Get(kubeRegistryConfiguration.KeyOfServiceInK8s, kubeRegistryConfiguration.KubeNamespace); var services = new List(); - if (IsValid(service)) + if (endpoint != null && endpoint.Subsets.Any()) { - services.Add(BuildService(service)); + services.AddRange(BuildServices(endpoint)); } else { @@ -38,25 +38,17 @@ namespace Ocelot.Provider.Kubernetes return services; } - private bool IsValid(ServiceV1 service) + private List BuildServices(EndpointsV1 endpoint) { - if (string.IsNullOrEmpty(service.Spec.ClusterIP) || service.Spec.Ports.Count <= 0) + var services = new List(); + + 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()))); } - - 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()); + return services; } } } diff --git a/src/Ocelot.Provider.Kubernetes/Ocelot.Provider.Kubernetes.csproj b/src/Ocelot.Provider.Kubernetes/Ocelot.Provider.Kubernetes.csproj index 980cd909..8f342865 100644 --- a/src/Ocelot.Provider.Kubernetes/Ocelot.Provider.Kubernetes.csproj +++ b/src/Ocelot.Provider.Kubernetes/Ocelot.Provider.Kubernetes.csproj @@ -28,8 +28,8 @@ - - + +