mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 20:30:50 +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