Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Discovery.KubernetesApi to support multi-config #2596

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,6 @@ public static AkkaConfigurationBuilder WithKubernetesDiscovery(
KubernetesDiscoveryOptions options)
{
options.Apply(builder);
builder.AddHocon($"akka.discovery.method = {options.ConfigPath}", HoconAddMode.Prepend);
builder.AddHocon(KubernetesDiscovery.DefaultConfiguration(), HoconAddMode.Append);

// Force start the module
builder.AddStartup((system, _) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
// </copyright>
//-----------------------------------------------------------------------

using System.Linq;
using Akka.Configuration.Hocon;
using Akka.Util.Internal;

namespace Akka.Discovery.KubernetesApi
{
internal static class ConfigExtensions
Expand All @@ -14,6 +18,31 @@ internal static class ConfigExtensions
var value = config.GetString(key);
return string.IsNullOrWhiteSpace(value) || value.Equals($"<{key}>") ? null : value;
}

internal static Configuration.Config MoveTo(this Configuration.Config config, string path)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the same method from the Azure plugin you were working on?

{
var rootObj = new HoconObject();
var rootValue = new HoconValue();
rootValue.Values.Add(rootObj);

var lastObject = rootObj;

var keys = path.SplitDottedPathHonouringQuotes().ToArray();
for (var i = 0; i < keys.Length - 1; i++)
{
var key = keys[i];
var innerObject = new HoconObject();
var innerValue = new HoconValue();
innerValue.Values.Add(innerObject);

lastObject.GetOrCreateKey(key);
lastObject.Items[key] = innerValue;
lastObject = innerObject;
}
lastObject.Items[keys[keys.Length - 1]] = config.Root;

return new Configuration.Config(new HoconRoot(rootValue));
}
}

internal static class ObjectExtensions
Expand Down
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using k8s.Authentication;
using k8s.Models;
using Newtonsoft.Json;
using Debug = System.Diagnostics.Debug;

#if !NET6_0_OR_GREATER
using Microsoft.Rest;
Expand All @@ -40,6 +41,10 @@ public KubernetesApiException(string message, Exception innerException) : base(m
{ }
}

internal const string DefaultPath = "kubernetes-api";
internal const string DefaultConfigPath = "akka.discovery." + DefaultPath;
internal static string FullPath(string path) => $"akka.discovery.{path}";

private readonly ILoggingAdapter _log;
private readonly KubernetesDiscoverySettings _settings;
private readonly Kubernetes? _client;
Expand All @@ -50,10 +55,16 @@ public KubernetesApiException(string message, Exception innerException) : base(m
.DefaultIfNullOrWhitespace(ReadConfigVarFromFileSystem(_settings.PodNamespacePath, "pod-namespace"))
.DefaultIfNullOrWhitespace("default")!;

// Backward compatible constructor
public KubernetesApiServiceDiscovery(ExtendedActorSystem system)
: this(system, system.Settings.Config.GetConfig(FullPath(DefaultPath)))
{
}

public KubernetesApiServiceDiscovery(ExtendedActorSystem system, Configuration.Config config)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

{
_log = Logging.GetLogger(system, this);
_settings = KubernetesDiscovery.Get(system).Settings;
_settings = KubernetesDiscoverySettings.Create(config);

if(_log.IsDebugEnabled)
_log.Debug("Settings {0}", _settings);
Expand All @@ -69,12 +80,12 @@ public KubernetesApiServiceDiscovery(ExtendedActorSystem system)
}
else
{
var config = KubernetesClientConfiguration.BuildDefaultConfig();
config.TokenProvider = new TokenFileAuth(_settings.ApiTokenPath);
config.ClientCertificateFilePath = _settings.ApiCaPath;
config.Namespace = PodNamespace;
_host = config.Host = $"https://{host}:{port}";
_client = new Kubernetes(config);
var clientConfig = KubernetesClientConfiguration.BuildDefaultConfig();
clientConfig.TokenProvider = new TokenFileAuth(_settings.ApiTokenPath);
clientConfig.ClientCertificateFilePath = _settings.ApiCaPath;
clientConfig.Namespace = PodNamespace;
_host = clientConfig.Host = $"https://{host}:{port}";
_client = new Kubernetes(clientConfig);
}
}

Expand Down Expand Up @@ -172,7 +183,8 @@ private async Task<V1PodList> ListNamespacedPod(string labelSelector, Cancellati
{
V1PodList podList;
#if !NET6_0_OR_GREATER
var result = await _client.ListNamespacedPodWithHttpMessagesAsync(
Debug.Assert(_client != null, nameof(_client) + " != null");
var result = await _client!.ListNamespacedPodWithHttpMessagesAsync(
namespaceParameter: PodNamespace,
labelSelector: labelSelector,
cancellationToken: cts.Token)
Expand All @@ -192,7 +204,8 @@ private async Task<V1PodList> ListPodForAllNamespaces(string labelSelector, Canc
{
V1PodList podList;
#if !NET6_0_OR_GREATER
var result = await _client.ListPodForAllNamespacesWithHttpMessagesAsync(
Debug.Assert(_client != null, nameof(_client) + " != null");
var result = await _client!.ListPodForAllNamespacesWithHttpMessagesAsync(
labelSelector: labelSelector,
cancellationToken: cts.Token)
.ConfigureAwait(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// </copyright>
//-----------------------------------------------------------------------

using System;
using Akka.Actor;
using Akka.Configuration;

Expand All @@ -18,8 +19,10 @@ public static Configuration.Config DefaultConfiguration()
public static KubernetesDiscovery Get(ActorSystem system)
=> system.WithExtension<KubernetesDiscovery, KubernetesDiscoveryProvider>();

[Obsolete("The Settings property is now deprecated. Since 1.5.26")]
public readonly KubernetesDiscoverySettings Settings;

#pragma warning disable CS0618 // Type or member is obsolete
public KubernetesDiscovery(ExtendedActorSystem system)
{
system.Settings.InjectTopLevelFallback(DefaultConfiguration());
Expand All @@ -29,6 +32,7 @@ public KubernetesDiscovery(ExtendedActorSystem system)
if (setup.HasValue)
Settings = setup.Value.Apply(Settings);
}
#pragma warning restore CS0618 // Type or member is obsolete
}

public class KubernetesDiscoveryProvider : ExtensionIdProvider<KubernetesDiscovery>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@ namespace Akka.Discovery.KubernetesApi;

public class KubernetesDiscoveryOptions: IHoconOption
{
private const string FullPath = "akka.discovery.kubernetes-api";

public string ConfigPath { get; } = "kubernetes-api";
public string ConfigPath { get; set; } = KubernetesApiServiceDiscovery.DefaultPath;
public Type Class { get; } = typeof(KubernetesApiServiceDiscovery);

public bool IsDefaultPlugin { get; set; } = true;
public string? ApiCaPath { get; set; }
public string? ApiTokenPath { get; set; }
public string? ApiServiceHostEnvName { get; set; }
Expand All @@ -35,7 +34,7 @@ public class KubernetesDiscoveryOptions: IHoconOption
public void Apply(AkkaConfigurationBuilder builder, Setup? setup = null)
{
var sb = new StringBuilder();
sb.AppendLine($"{FullPath} {{");
sb.AppendLine($"{KubernetesApiServiceDiscovery.FullPath(ConfigPath)} {{");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - looks like we made the pathing more dynamic all-around here.

sb.AppendLine($"class = {Class.AssemblyQualifiedName!.ToHocon()}");

if (ApiCaPath is { })
Expand All @@ -62,8 +61,15 @@ public void Apply(AkkaConfigurationBuilder builder, Setup? setup = null)
sb.AppendLine($"container-name = {ContainerName.ToHocon()}");

sb.AppendLine("}");

if(IsDefaultPlugin)
sb.AppendLine($"akka.discovery.method = {ConfigPath}");

builder.AddHocon(sb.ToString(), HoconAddMode.Prepend);
builder.AddHocon(KubernetesDiscovery.DefaultConfiguration(), HoconAddMode.Append);

var fallback = KubernetesDiscovery.DefaultConfiguration()
.GetConfig(KubernetesApiServiceDiscovery.FullPath(KubernetesApiServiceDiscovery.DefaultPath))
.MoveTo(KubernetesApiServiceDiscovery.FullPath(ConfigPath));
builder.AddHocon(fallback, HoconAddMode.Append);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ namespace Akka.Discovery.KubernetesApi
public sealed class KubernetesDiscoverySettings
{
public static readonly KubernetesDiscoverySettings Empty =
Create(KubernetesDiscovery.DefaultConfiguration().GetConfig("akka.discovery.kubernetes-api"));
Create(KubernetesDiscovery.DefaultConfiguration().GetConfig(KubernetesApiServiceDiscovery.DefaultConfigPath));

public static KubernetesDiscoverySettings Create(ActorSystem system)
=> Create(system.Settings.Config.GetConfig("akka.discovery.kubernetes-api"));
=> Create(system.Settings.Config.GetConfig(KubernetesApiServiceDiscovery.DefaultConfigPath));

public static KubernetesDiscoverySettings Create(Configuration.Config config)
=> new (
Expand Down