mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-08-04 17:28:30 +08:00
feat: Kubernetes ServiceDiscoveryProvider
This commit is contained in:
12
src/Ocelot.Provider.Kubernetes/IKubeApiClientFactory.cs
Normal file
12
src/Ocelot.Provider.Kubernetes/IKubeApiClientFactory.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using KubeClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Ocelot.Provider.Kubernetes
|
||||
{
|
||||
public interface IKubeApiClientFactory
|
||||
{
|
||||
IKubeApiClient Get(KubeRegistryConfiguration config);
|
||||
}
|
||||
}
|
22
src/Ocelot.Provider.Kubernetes/KubeApiClientFactory.cs
Normal file
22
src/Ocelot.Provider.Kubernetes/KubeApiClientFactory.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using KubeClient;
|
||||
|
||||
namespace Ocelot.Provider.Kubernetes
|
||||
{
|
||||
public class KubeApiClientFactory : IKubeApiClientFactory
|
||||
{
|
||||
public IKubeApiClient Get(KubeRegistryConfiguration config)
|
||||
{
|
||||
var option = new KubeClientOptions
|
||||
{
|
||||
ApiEndPoint = config.ApiEndPoint
|
||||
};
|
||||
if(!string.IsNullOrEmpty(config?.AccessToken))
|
||||
{
|
||||
option.AccessToken = config.AccessToken;
|
||||
option.AuthStrategy = config.AuthStrategy;
|
||||
option.AllowInsecure = config.AllowInsecure;
|
||||
}
|
||||
return KubeApiClient.Create(option);
|
||||
}
|
||||
}
|
||||
}
|
59
src/Ocelot.Provider.Kubernetes/KubeProvider.cs
Normal file
59
src/Ocelot.Provider.Kubernetes/KubeProvider.cs
Normal file
@ -0,0 +1,59 @@
|
||||
using KubeClient;
|
||||
using KubeClient.Models;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.ServiceDiscovery.Providers;
|
||||
using Ocelot.Values;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ocelot.Provider.Kubernetes
|
||||
{
|
||||
public class KubeProvider : IServiceDiscoveryProvider
|
||||
{
|
||||
private KubeRegistryConfiguration kubeRegistryConfiguration;
|
||||
private IOcelotLoggerFactory factory;
|
||||
private IKubeApiClient kubeApi;
|
||||
private IKubeApiClientFactory kubeClientFactory;
|
||||
|
||||
public KubeProvider(KubeRegistryConfiguration kubeRegistryConfiguration, IOcelotLoggerFactory factory, IKubeApiClientFactory kubeClientFactory)
|
||||
{
|
||||
this.kubeRegistryConfiguration = kubeRegistryConfiguration;
|
||||
this.factory = factory;
|
||||
this.kubeApi = kubeClientFactory.Get(kubeRegistryConfiguration);
|
||||
}
|
||||
|
||||
public async Task<List<Service>> Get()
|
||||
{
|
||||
var service = await kubeApi.ServicesV1().Get(kubeRegistryConfiguration.KeyOfServiceInK8s, kubeRegistryConfiguration.KubeNamespace);
|
||||
var services = new List<Service>();
|
||||
if (IsValid(service))
|
||||
{
|
||||
services.Add(BuildService(service));
|
||||
}
|
||||
return services;
|
||||
}
|
||||
|
||||
private bool IsValid(ServiceV1 service)
|
||||
{
|
||||
if (string.IsNullOrEmpty(service.Spec.ClusterIP) || service.Spec.Ports.Count <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
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>());
|
||||
}
|
||||
}
|
||||
}
|
22
src/Ocelot.Provider.Kubernetes/KubeRegistryConfiguration.cs
Normal file
22
src/Ocelot.Provider.Kubernetes/KubeRegistryConfiguration.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using KubeClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Ocelot.Provider.Kubernetes
|
||||
{
|
||||
public class KubeRegistryConfiguration
|
||||
{
|
||||
public Uri ApiEndPoint { get; set; }
|
||||
|
||||
public string KubeNamespace { get; set; }
|
||||
|
||||
public string KeyOfServiceInK8s { get; set; }
|
||||
|
||||
public KubeAuthStrategy AuthStrategy { get; set; }
|
||||
|
||||
public string AccessToken { get; set; }
|
||||
|
||||
public bool AllowInsecure { get; set; }
|
||||
}
|
||||
}
|
31
src/Ocelot.Provider.Kubernetes/KubernetesProviderFactory.cs
Normal file
31
src/Ocelot.Provider.Kubernetes/KubernetesProviderFactory.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using KubeClient;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.ServiceDiscovery;
|
||||
using System;
|
||||
|
||||
namespace Ocelot.Provider.Kubernetes
|
||||
{
|
||||
public static class KubernetesProviderFactory
|
||||
{
|
||||
public static ServiceDiscoveryFinderDelegate Get = (provider, config, name) =>
|
||||
{
|
||||
var factory = provider.GetService<IOcelotLoggerFactory>();
|
||||
|
||||
var kubeClientFactory = provider.GetService<IKubeApiClientFactory>();
|
||||
|
||||
var k8sRegistryConfiguration = new KubeRegistryConfiguration() {
|
||||
ApiEndPoint = new Uri($"http://{config.Host}:{config.Port}"),
|
||||
KeyOfServiceInK8s = name,
|
||||
KubeNamespace = config.Namesapce,
|
||||
AuthStrategy = KubeAuthStrategy.BearerToken,
|
||||
AccessToken = config.Token,
|
||||
AllowInsecure = true // Don't validate server certificate
|
||||
};
|
||||
|
||||
var k8sServiceDiscoveryProvider = new KubeProvider(k8sRegistryConfiguration, factory, kubeClientFactory);
|
||||
|
||||
return k8sServiceDiscoveryProvider;
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="KubeClient" Version="2.2.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Ocelot\Ocelot.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
20
src/Ocelot.Provider.Kubernetes/OcelotBuilderExtensions.cs
Normal file
20
src/Ocelot.Provider.Kubernetes/OcelotBuilderExtensions.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using KubeClient;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Ocelot.DependencyInjection;
|
||||
using Ocelot.ServiceDiscovery;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Ocelot.Provider.Kubernetes
|
||||
{
|
||||
public static class OcelotBuilderExtensions
|
||||
{
|
||||
public static IOcelotBuilder AddKubernetes(this IOcelotBuilder builder)
|
||||
{
|
||||
builder.Services.AddSingleton(KubernetesProviderFactory.Get);
|
||||
builder.Services.AddSingleton<IKubeApiClientFactory, KubeApiClientFactory>();
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@ namespace Ocelot.Configuration.Builder
|
||||
private string _token;
|
||||
private string _configurationKey;
|
||||
private int _pollingInterval;
|
||||
private string _namespace;
|
||||
|
||||
public ServiceProviderConfigurationBuilder WithHost(string serviceDiscoveryProviderHost)
|
||||
{
|
||||
@ -45,9 +46,15 @@ namespace Ocelot.Configuration.Builder
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServiceProviderConfigurationBuilder WithNamesapce(string @namesapce)
|
||||
{
|
||||
_namespace = @namesapce;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServiceProviderConfiguration Build()
|
||||
{
|
||||
return new ServiceProviderConfiguration(_type, _serviceDiscoveryProviderHost, _serviceDiscoveryProviderPort, _token, _configurationKey, _pollingInterval);
|
||||
return new ServiceProviderConfiguration(_type, _serviceDiscoveryProviderHost, _serviceDiscoveryProviderPort, _token, _configurationKey, _pollingInterval, _namespace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ namespace Ocelot.Configuration.Creator
|
||||
? globalConfiguration?.ServiceDiscoveryProvider?.Type
|
||||
: "consul";
|
||||
var pollingInterval = globalConfiguration?.ServiceDiscoveryProvider?.PollingInterval ?? 0;
|
||||
var k8snamesapce = globalConfiguration?.ServiceDiscoveryProvider?.Namespace ?? string.Empty;
|
||||
|
||||
return new ServiceProviderConfigurationBuilder()
|
||||
.WithHost(host)
|
||||
@ -21,6 +22,7 @@ namespace Ocelot.Configuration.Creator
|
||||
.WithToken(globalConfiguration?.ServiceDiscoveryProvider?.Token)
|
||||
.WithConfigurationKey(globalConfiguration?.ServiceDiscoveryProvider?.ConfigurationKey)
|
||||
.WithPollingInterval(pollingInterval)
|
||||
.WithNamesapce(k8snamesapce)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
|
@ -8,5 +8,6 @@ namespace Ocelot.Configuration.File
|
||||
public string Token { get; set; }
|
||||
public string ConfigurationKey { get; set; }
|
||||
public int PollingInterval { get; set; }
|
||||
public string Namespace { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
{
|
||||
public class ServiceProviderConfiguration
|
||||
{
|
||||
public ServiceProviderConfiguration(string type, string host, int port, string token, string configurationKey, int pollingInterval)
|
||||
public ServiceProviderConfiguration(string type, string host, int port, string token, string configurationKey, int pollingInterval, string @namespace = "")
|
||||
{
|
||||
ConfigurationKey = configurationKey;
|
||||
Host = host;
|
||||
@ -10,13 +10,21 @@
|
||||
Token = token;
|
||||
Type = type;
|
||||
PollingInterval = pollingInterval;
|
||||
Namesapce = @namespace;
|
||||
}
|
||||
|
||||
public string Host { get; }
|
||||
|
||||
public int Port { get; }
|
||||
|
||||
public string Type { get; }
|
||||
|
||||
public string Token { get; }
|
||||
|
||||
public string ConfigurationKey { get; }
|
||||
|
||||
public int PollingInterval { get; }
|
||||
|
||||
public string Namesapce { get; }
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user