From 76a68d4c8a184f5b466d95f72595fbed55162b72 Mon Sep 17 00:00:00 2001 From: Romeo Dumitrescu Date: Sun, 27 Sep 2020 00:24:27 +0300 Subject: [PATCH] Fix cert-manager stability (#92) * Fixed cert-manager module stability * Code cleanup --- .../CertManagerMonitor.cs | 239 ++++++++---------- .../Events/InternalSecretWatcherEvent.cs | 5 +- .../Resources/Certificate.cs | 8 +- .../SecretEtcher.cs | 28 +- .../Constants/Annotations.cs | 16 +- .../ES.Kubernetes.Reflector.Core.csproj | 12 +- .../Extensions/MetadataExtensions.cs | 4 +- .../Queuing/FeederQueue.cs | 5 +- .../ES.Kubernetes.Reflector.Host.csproj | 4 +- .../FortiMirror.cs | 2 + .../FreeNasMirror.cs | 9 +- .../UbiquitiMirror.cs | 4 +- .../VMwareMirror.cs | 14 +- 13 files changed, 165 insertions(+), 185 deletions(-) diff --git a/src/ES.Kubernetes.Reflector.CertManager/CertManagerMonitor.cs b/src/ES.Kubernetes.Reflector.CertManager/CertManagerMonitor.cs index d726d32..f60c2dd 100644 --- a/src/ES.Kubernetes.Reflector.CertManager/CertManagerMonitor.cs +++ b/src/ES.Kubernetes.Reflector.CertManager/CertManagerMonitor.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Net; using System.Threading; +using System.Threading.Channels; using System.Threading.Tasks; using ES.Kubernetes.Reflector.CertManager.Constants; using ES.Kubernetes.Reflector.CertManager.Events; @@ -15,11 +16,13 @@ using ES.Kubernetes.Reflector.Core.Resources; using k8s; using k8s.Models; +using k8s.Versioning; using MediatR; using Microsoft.Extensions.Diagnostics.HealthChecks; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Rest; +using Newtonsoft.Json.Linq; using Timer = System.Timers.Timer; namespace ES.Kubernetes.Reflector.CertManager @@ -27,31 +30,28 @@ namespace ES.Kubernetes.Reflector.CertManager public class CertManagerMonitor : IHostedService, IHealthCheck { private readonly IKubernetes _apiClient; - private readonly Func> _certificatesWatcherFactory; + private readonly ManagedWatcher _certificateWatcher; - private readonly Dictionary> _certificatesWatchers = - new Dictionary>(); + private readonly Timer _certManagerTimer = new Timer(); - private readonly ManagedWatcher _crdV1Watcher; private readonly FeederQueue _eventQueue; private readonly ILogger _logger; private readonly IMediator _mediator; private readonly ManagedWatcher _secretsWatcher; - private readonly Timer _v1Beta1CrdMonitorTimer = new Timer(); - private bool _v1Beta1CrdMonitorTimerFaulted; + private Channel _monitorTriggerChannel; + + private string _version; public CertManagerMonitor(ILogger logger, - ManagedWatcher crdV1Watcher, - Func> certificatesWatcherFactory, + ManagedWatcher certificateWatcher, ManagedWatcher secretsWatcher, IKubernetes apiClient, IMediator mediator) { _logger = logger; - _crdV1Watcher = crdV1Watcher; - _certificatesWatcherFactory = certificatesWatcherFactory; + _certificateWatcher = certificateWatcher; _secretsWatcher = secretsWatcher; _apiClient = apiClient; _mediator = mediator; @@ -61,117 +61,143 @@ public CertManagerMonitor(ILogger logger, _secretsWatcher.OnStateChanged = OnWatcherStateChanged; _secretsWatcher.EventHandlerFactory = e => - _eventQueue.FeedAsync(new InternalSecretWatcherEvent + { + if (e.Item.Type.StartsWith("helm.sh")) return Task.CompletedTask; + + return _eventQueue.FeedAsync(new InternalSecretWatcherEvent { Item = e.Item, Type = e.Type, - CertificateResourceDefinitionVersions = _certificatesWatchers.Keys.ToList() + CertificateResourceDefinitionVersion = _version }); + }; _secretsWatcher.RequestFactory = async c => await c.ListSecretForAllNamespacesWithHttpMessagesAsync(watch: true, timeoutSeconds: Requests.WatcherTimeout); + _certManagerTimer.Elapsed += (_, __) => _monitorTriggerChannel.Writer.TryWrite(new object()); + _certManagerTimer.Interval = 5_000; - _crdV1Watcher.EventHandlerFactory = OnCrdEventV1; - _crdV1Watcher.RequestFactory = async c => - await c.ListCustomResourceDefinitionWithHttpMessagesAsync(watch: true, - timeoutSeconds: Requests.WatcherTimeout); - _crdV1Watcher.OnStateChanged = OnCrdWatcherStateChanged; - _v1Beta1CrdMonitorTimer.Elapsed += (_, __) => Onv1Beta1CrdRefresh(); - _v1Beta1CrdMonitorTimer.Interval = 30_000; + _certificateWatcher.OnStateChanged = OnWatcherStateChanged; + _certificateWatcher.EventHandlerFactory = e => + _eventQueue.FeedAsync(new InternalCertificateWatcherEvent {Item = e.Item, Type = e.Type}); + _certificateWatcher.RequestFactory = async client => + await client.ListClusterCustomObjectWithHttpMessagesAsync( + CertManagerConstants.CrdGroup, _version, CertManagerConstants.CertificatePlural, watch: true, + timeoutSeconds: Requests.WatcherTimeout); } public Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = new CancellationToken()) { - return Task.FromResult(_crdV1Watcher.IsFaulted || - _v1Beta1CrdMonitorTimerFaulted || - _secretsWatcher.IsFaulted || - _certificatesWatchers.Values.Any(s => s.IsFaulted) + return Task.FromResult(_secretsWatcher.IsFaulted || _certificateWatcher.IsFaulted ? HealthCheckResult.Unhealthy() : HealthCheckResult.Healthy()); } public async Task StartAsync(CancellationToken cancellationToken) { + _logger.LogDebug("Starting"); try { await _apiClient.ListCustomResourceDefinitionAsync(cancellationToken: cancellationToken); - await _crdV1Watcher.Start(); } catch (HttpOperationException exception) when (exception.Response.StatusCode == HttpStatusCode.NotFound) { - _logger.LogWarning( - "Current kubernetes version does not support {type} apiVersion {version}.", + _logger.LogInformation( + "Current kubernetes version does not support {type} apiVersion {version}. `cert-manager` extension disabled.", V1CustomResourceDefinition.KubeKind, V1CustomResourceDefinition.KubeApiVersion); - Onv1Beta1CrdRefresh(); - _v1Beta1CrdMonitorTimer.Start(); + return; } + + var channel = Channel.CreateBounded(new BoundedChannelOptions(1) + {FullMode = BoundedChannelFullMode.DropNewest}); + + async Task ReadChannel() + { + while (await channel.Reader.WaitToReadAsync(cancellationToken)) + { + await channel.Reader.ReadAsync(cancellationToken); + try + { + await OnCertManagerDiscovery(); + } + catch (Exception exception) + { + _logger.LogError(exception, "Exception occured while processing `cert-manager` discovery"); + } + } + } + + var _ = ReadChannel(); + _monitorTriggerChannel = channel; + + await _monitorTriggerChannel.Writer.WriteAsync(new object(), cancellationToken); + _certManagerTimer.Enabled = true; + + _logger.LogDebug("Started"); } public async Task StopAsync(CancellationToken cancellationToken) { - await _crdV1Watcher.Stop(); - foreach (var certificatesWatcher in _certificatesWatchers.Values) await certificatesWatcher.Stop(); + _certManagerTimer.Enabled = false; + await _certificateWatcher.Stop(); await _secretsWatcher.Stop(); + _monitorTriggerChannel?.Writer.Complete(); } - private void Onv1Beta1CrdRefresh() + private async Task OnCertManagerDiscovery() { - try + _logger.LogTrace("Searching for cert-manager CRDs"); + //Get all CRDs in order to check for cert-manager specific CRDs + var customResourceDefinitions = await _apiClient.ListCustomResourceDefinitionAsync(); + + //Find the `Certificate` CRD (if installed) + var certCrd = customResourceDefinitions.Items.FirstOrDefault(s => + s.Spec?.Names != null && s.Spec.Group == CertManagerConstants.CrdGroup && + s.Spec.Names.Kind == CertManagerConstants.CertificateKind); + var versions = new List(); + + //Get Certificate CRD versions + if (!(certCrd is null)) versions = certCrd.Spec.Versions.Select(s => s.Name).ToList(); + + _logger.LogTrace("Cert-manager CRDs versions found: `{versions}`", versions); + + //Check if at least one Certificate exists (regardless of version) so we can start monitoring + var version = versions.OrderBy(s => s, KubernetesVersionComparer.Instance).LastOrDefault(); + var certificatesExit = false; + if (version != null) { - _logger.LogDebug( - "Updating {type} {kind} in group {group}", - nameof(V1beta1CustomResourceDefinition), - CertManagerConstants.CertificateKind, CertManagerConstants.CrdGroup); - - _v1Beta1CrdMonitorTimerFaulted = false; - var crd = _apiClient.ListCustomResourceDefinition1().Items - .FirstOrDefault(s => - s.Spec?.Names != null && s.Spec.Group == CertManagerConstants.CrdGroup && - s.Spec.Names.Kind == CertManagerConstants.CertificateKind); - - if (crd == null) return; - OnCrdVersionUpdate(crd.GetType().Name, crd.Spec.Names.Kind, - crd.Spec.Group, crd.Spec.Names.Plural, crd.Spec.Versions.Select(s => s.Name).ToList()).Wait(); + var certList = ((JObject) await _apiClient.ListClusterCustomObjectAsync(CertManagerConstants.CrdGroup, + version, + CertManagerConstants.CertificatePlural)).ToObject>(); + certificatesExit = certList.Items.Any(); } - catch (HttpOperationException exception) when (exception.Response.StatusCode == HttpStatusCode.NotFound) - { - _logger.LogWarning( - "Current kubernetes version does not support {type} apiVersion {version}.", - V1beta1CustomResourceDefinition.KubeKind, V1beta1CustomResourceDefinition.KubeApiVersion); - _v1Beta1CrdMonitorTimer.Stop(); - } - catch (Exception exception) + + //If no certificate exists, stop everything. Timer will periodically check again + if (!certificatesExit) { - _v1Beta1CrdMonitorTimerFaulted = true; - _v1Beta1CrdMonitorTimer.Stop(); - _logger.LogError(exception, - "Error occured while getting {kind} version {version}", - V1beta1CustomResourceDefinition.KubeKind, V1beta1CustomResourceDefinition.KubeApiVersion); + await _certificateWatcher.Stop(); + await _secretsWatcher.Stop(); + _logger.LogTrace("No {kind} found.", CertManagerConstants.CertificateKind); + return; } - } - private async Task OnCrdWatcherStateChanged( - ManagedWatcher> sender, ManagedWatcherStateUpdate update) - where TResource : class, IKubernetesObject - { - switch (update.State) + if (_version != version) { - case ManagedWatcherState.Closed: - _logger.LogDebug("{type} watcher {state}", typeof(TResource).Name, update.State); - await sender.Start(); - break; - case ManagedWatcherState.Faulted: - _logger.LogError(update.Exception, "{type} watcher {state}", - typeof(TResource).Name, update.State); - break; - default: - _logger.LogDebug("{type} watcher {state}", typeof(TResource).Name, update.State); - break; + _logger.LogDebug("{kind} version is {version}", CertManagerConstants.CertificateKind, version); + + await _certificateWatcher.Stop(); + await _secretsWatcher.Stop(); + _version = version; + if (_version != null) + { + await _certificateWatcher.Start(); + await _secretsWatcher.Start(); + } } } @@ -179,25 +205,24 @@ private async Task OnWatcherStateChanged( ManagedWatcher> sender, ManagedWatcherStateUpdate update) where TResource : class, IKubernetesObject { - var tag = sender.Tag ?? string.Empty; switch (update.State) { case ManagedWatcherState.Closed: - _logger.LogDebug("{type} watcher {tag} {state}", typeof(TResource).Name, tag, update.State); + _logger.LogDebug("{type} watcher {state}", typeof(TResource).Name, update.State); await _secretsWatcher.Stop(); - foreach (var certificatesWatcher in _certificatesWatchers.Values) await certificatesWatcher.Stop(); + await _certificateWatcher.Stop(); await _eventQueue.WaitAndClear(); await _secretsWatcher.Start(); - foreach (var certificatesWatcher in _certificatesWatchers.Values) await certificatesWatcher.Start(); + await _certificateWatcher.Start(); break; case ManagedWatcherState.Faulted: - _logger.LogError(update.Exception, "{type} watcher {tag} {state}", typeof(TResource).Name, tag, + _logger.LogError(update.Exception, "{type} watcher {state}", typeof(TResource).Name, update.State); break; default: - _logger.LogDebug("{type} watcher {tag} {state}", typeof(TResource).Name, tag, update.State); + _logger.LogDebug("{type} watcher {state}", typeof(TResource).Name, update.State); break; } } @@ -215,59 +240,13 @@ private async Task OnEventHandlingError(WatcherEvent e, Exception ex) _logger.LogError(ex, "Failed to process {eventType} {kind} {@id} due to exception", e.Type, e.Item.Kind, id); await _secretsWatcher.Stop(); - foreach (var certificatesWatcher in _certificatesWatchers.Values) await certificatesWatcher.Stop(); + await _certificateWatcher.Stop(); _eventQueue.Clear(); _logger.LogTrace("Watchers restarting"); await _secretsWatcher.Start(); - foreach (var certificatesWatcher in _certificatesWatchers.Values) await certificatesWatcher.Start(); + await _certificateWatcher.Start(); _logger.LogTrace("Watchers restarted"); } - - - private async Task OnCrdEventV1(WatcherEvent request) - { - if (request.Type != WatchEventType.Added && request.Type != WatchEventType.Modified) return; - if (request.Item.Spec?.Names == null) return; - - if (request.Item.Spec.Group != CertManagerConstants.CrdGroup || - request.Item.Spec.Names.Kind != CertManagerConstants.CertificateKind) return; - var versions = request.Item.Spec.Versions.Select(s => s.Name).ToList(); - if (versions.TrueForAll(s => _certificatesWatchers.ContainsKey(s))) return; - - await OnCrdVersionUpdate(request.Item.GetType().Name, request.Item.Spec.Names.Kind, request.Item.Spec.Group, - request.Item.Spec.Names.Plural, versions); - } - - private async Task OnCrdVersionUpdate(string crdType, string crdKind, string crdGroup, string crdPlural, - List versions) - { - if (versions.TrueForAll(s => _certificatesWatchers.ContainsKey(s))) return; - - _logger.LogInformation("{crdType} {kind} in group {group} versions updated to {versions}", - crdType, crdKind, crdGroup, versions); - - foreach (var certificatesWatcher in _certificatesWatchers.Values) await certificatesWatcher.Stop(); - await _secretsWatcher.Stop(); - - _certificatesWatchers.Clear(); - - foreach (var version in versions) - { - var watcher = _certificatesWatcherFactory(); - watcher.Tag = version; - watcher.OnStateChanged = OnWatcherStateChanged; - watcher.EventHandlerFactory = e => - _eventQueue.FeedAsync(new InternalCertificateWatcherEvent {Item = e.Item, Type = e.Type}); - watcher.RequestFactory = async client => await client.ListClusterCustomObjectWithHttpMessagesAsync( - crdGroup, version, crdPlural, watch: true, - timeoutSeconds: Requests.WatcherTimeout); - _certificatesWatchers.Add(version, watcher); - } - - - foreach (var certificatesWatcher in _certificatesWatchers.Values) await certificatesWatcher.Start(); - await _secretsWatcher.Start(); - } } } \ No newline at end of file diff --git a/src/ES.Kubernetes.Reflector.CertManager/Events/InternalSecretWatcherEvent.cs b/src/ES.Kubernetes.Reflector.CertManager/Events/InternalSecretWatcherEvent.cs index 61544cd..09f7d9e 100644 --- a/src/ES.Kubernetes.Reflector.CertManager/Events/InternalSecretWatcherEvent.cs +++ b/src/ES.Kubernetes.Reflector.CertManager/Events/InternalSecretWatcherEvent.cs @@ -1,11 +1,10 @@ -using System.Collections.Generic; -using ES.Kubernetes.Reflector.Core.Events; +using ES.Kubernetes.Reflector.Core.Events; using k8s.Models; namespace ES.Kubernetes.Reflector.CertManager.Events { public class InternalSecretWatcherEvent : WatcherEvent { - public List CertificateResourceDefinitionVersions { get; set; } + public string CertificateResourceDefinitionVersion { get; set; } } } \ No newline at end of file diff --git a/src/ES.Kubernetes.Reflector.CertManager/Resources/Certificate.cs b/src/ES.Kubernetes.Reflector.CertManager/Resources/Certificate.cs index 98ed667..085e694 100644 --- a/src/ES.Kubernetes.Reflector.CertManager/Resources/Certificate.cs +++ b/src/ES.Kubernetes.Reflector.CertManager/Resources/Certificate.cs @@ -4,11 +4,8 @@ namespace ES.Kubernetes.Reflector.CertManager.Resources { - public class Certificate : IKubernetesObject + public class Certificate : IKubernetesObject, IMetadata { - [JsonProperty(PropertyName = "metadata")] - public V1ObjectMeta Metadata { get; set; } - [JsonProperty(PropertyName = "spec")] public SpecDefinition Spec { get; set; } @@ -18,6 +15,9 @@ public class Certificate : IKubernetesObject [JsonProperty(PropertyName = "kind")] public string Kind { get; set; } + [JsonProperty(PropertyName = "metadata")] + public V1ObjectMeta Metadata { get; set; } + public class SpecDefinition { [JsonProperty(PropertyName = "secretName")] diff --git a/src/ES.Kubernetes.Reflector.CertManager/SecretEtcher.cs b/src/ES.Kubernetes.Reflector.CertManager/SecretEtcher.cs index 9804d61..146d16e 100644 --- a/src/ES.Kubernetes.Reflector.CertManager/SecretEtcher.cs +++ b/src/ES.Kubernetes.Reflector.CertManager/SecretEtcher.cs @@ -74,20 +74,20 @@ public async Task Handle(InternalSecretWatcherEvent notification, CancellationTo CertManagerConstants.CertificateKind, certificateId, secretId); Certificate certificate = null; - foreach (var certificateResourceDefinitionVersion in notification.CertificateResourceDefinitionVersions) - try - { - var certificateJObject = await _client.GetNamespacedCustomObjectAsync( - CertManagerConstants.CrdGroup, - certificateResourceDefinitionVersion, metadata.NamespaceProperty, - CertManagerConstants.CertificatePlural, - certificateName, cancellationToken); - certificate = ((JObject) certificateJObject).ToObject(); - } - catch (HttpOperationException exception) when (exception.Response.StatusCode == - HttpStatusCode.NotFound) - { - } + try + { + var certificateJObject = await _client.GetNamespacedCustomObjectAsync( + CertManagerConstants.CrdGroup, + notification.CertificateResourceDefinitionVersion, + metadata.NamespaceProperty, + CertManagerConstants.CertificatePlural, + certificateName, cancellationToken); + certificate = ((JObject) certificateJObject).ToObject(); + } + catch (HttpOperationException exception) when (exception.Response.StatusCode == + HttpStatusCode.NotFound) + { + } if (certificate != null) await Annotate(secret, certificate); diff --git a/src/ES.Kubernetes.Reflector.Core/Constants/Annotations.cs b/src/ES.Kubernetes.Reflector.Core/Constants/Annotations.cs index 12ac40c..e64a2ba 100644 --- a/src/ES.Kubernetes.Reflector.Core/Constants/Annotations.cs +++ b/src/ES.Kubernetes.Reflector.Core/Constants/Annotations.cs @@ -18,6 +18,11 @@ public static class Reflection public static string FortiHosts => $"{Prefix}/reflection-forti-hosts"; public static string FortiCertificate => $"{Prefix}/reflection-forti-certificate"; + public static string AutoReflects => $"{Prefix}/auto-reflects"; + public static string Reflects => $"{Prefix}/reflects"; + public static string ReflectedVersion => $"{Prefix}/reflected-version"; + public static string ReflectedAt => $"{Prefix}/reflected-at"; + #region Ubiquiti public static string UbiquitiEnabled => $"{Prefix}/reflection-ubiquiti-enabled"; @@ -25,7 +30,7 @@ public static class Reflection public static string UbiquitiCertificate => $"{Prefix}/reflection-ubiquiti-certificate"; #endregion - + #region VMware public static string VMwareEnabled => $"{Prefix}/reflection-vmware-enabled"; @@ -41,11 +46,6 @@ public static class Reflection public static string FreeNasCertificate => $"{Prefix}/reflection-freenas-certificate"; #endregion - - public static string AutoReflects => $"{Prefix}/auto-reflects"; - public static string Reflects => $"{Prefix}/reflects"; - public static string ReflectedVersion => $"{Prefix}/reflected-version"; - public static string ReflectedAt => $"{Prefix}/reflected-at"; } public static class CertManagerCertificate @@ -67,7 +67,7 @@ public static class CertManagerCertificate public static string SecretUbiquitiCertificate => $"{Prefix}/secret-reflection-ubiquiti-certificate"; #endregion - + #region VMware public static string SecretVMwareEnabled => $"{Prefix}/secret-reflection-vmware-enabled"; @@ -75,7 +75,7 @@ public static class CertManagerCertificate public static string SecretVMwareCertificate => $"{Prefix}/secret-reflection-vmware-certificate"; #endregion - + #region FreeNAS public static string SecretFreeNasEnabled => $"{Prefix}/secret-reflection-freenas-enabled"; diff --git a/src/ES.Kubernetes.Reflector.Core/ES.Kubernetes.Reflector.Core.csproj b/src/ES.Kubernetes.Reflector.Core/ES.Kubernetes.Reflector.Core.csproj index b069d06..c7d9364 100644 --- a/src/ES.Kubernetes.Reflector.Core/ES.Kubernetes.Reflector.Core.csproj +++ b/src/ES.Kubernetes.Reflector.Core/ES.Kubernetes.Reflector.Core.csproj @@ -6,13 +6,13 @@ - + - - - - - + + + + + diff --git a/src/ES.Kubernetes.Reflector.Core/Extensions/MetadataExtensions.cs b/src/ES.Kubernetes.Reflector.Core/Extensions/MetadataExtensions.cs index d27a3c0..7890859 100644 --- a/src/ES.Kubernetes.Reflector.Core/Extensions/MetadataExtensions.cs +++ b/src/ES.Kubernetes.Reflector.Core/Extensions/MetadataExtensions.cs @@ -166,7 +166,7 @@ public static string UbiquitiCertificate(this V1ObjectMeta metadata) } #endregion - + #region VMware public static bool VMwareReflectionEnabled(this V1ObjectMeta metadata) @@ -195,7 +195,7 @@ public static string VMwareCertificate(this V1ObjectMeta metadata) } #endregion - + #region FreeNAS public static bool FreeNasReflectionEnabled(this V1ObjectMeta metadata) diff --git a/src/ES.Kubernetes.Reflector.Core/Queuing/FeederQueue.cs b/src/ES.Kubernetes.Reflector.Core/Queuing/FeederQueue.cs index e7c7a8c..0504ef2 100644 --- a/src/ES.Kubernetes.Reflector.Core/Queuing/FeederQueue.cs +++ b/src/ES.Kubernetes.Reflector.Core/Queuing/FeederQueue.cs @@ -8,8 +8,8 @@ public class FeederQueue { private readonly Func _handler; private readonly Func _onError; - private Task _currentHandler; private Channel _channel; + private Task _currentHandler; public FeederQueue(Func handler, Func onError = null) { @@ -37,7 +37,7 @@ public void Clear() private void InitializeAndStart() { var channel = Channel.CreateUnbounded(new UnboundedChannelOptions - { SingleReader = true, SingleWriter = false }); + {SingleReader = true, SingleWriter = false}); async Task ReadChannel() { @@ -55,6 +55,7 @@ async Task ReadChannel() } } } + var _ = ReadChannel(); _channel = channel; } diff --git a/src/ES.Kubernetes.Reflector.Host/ES.Kubernetes.Reflector.Host.csproj b/src/ES.Kubernetes.Reflector.Host/ES.Kubernetes.Reflector.Host.csproj index db98c03..ae21a11 100644 --- a/src/ES.Kubernetes.Reflector.Host/ES.Kubernetes.Reflector.Host.csproj +++ b/src/ES.Kubernetes.Reflector.Host/ES.Kubernetes.Reflector.Host.csproj @@ -9,10 +9,10 @@ - + - + diff --git a/src/ES.Kubernetes.Reflector.Secrets/FortiMirror.cs b/src/ES.Kubernetes.Reflector.Secrets/FortiMirror.cs index 21d2281..e9c64b6 100644 --- a/src/ES.Kubernetes.Reflector.Secrets/FortiMirror.cs +++ b/src/ES.Kubernetes.Reflector.Secrets/FortiMirror.cs @@ -90,6 +90,8 @@ private async Task OnWatcherStateChanged(ManagedWatcher e) { + if (e.Item.Type.StartsWith("helm.sh")) return; + var id = KubernetesObjectId.For(e.Item.Metadata()); var item = e.Item; diff --git a/src/ES.Kubernetes.Reflector.Secrets/FreeNasMirror.cs b/src/ES.Kubernetes.Reflector.Secrets/FreeNasMirror.cs index a489658..74e9e13 100644 --- a/src/ES.Kubernetes.Reflector.Secrets/FreeNasMirror.cs +++ b/src/ES.Kubernetes.Reflector.Secrets/FreeNasMirror.cs @@ -4,7 +4,6 @@ using System.Net; using System.Net.Http; using System.Net.Http.Headers; -using System.Security.Cryptography.X509Certificates; using System.Text; using System.Text.Json; using System.Threading; @@ -106,6 +105,8 @@ private async Task OnWatcherStateChanged(ManagedWatcher e) { + if (e.Item.Type.StartsWith("helm.sh")) return; + var secretId = KubernetesObjectId.For(e.Item.Metadata()); var item = e.Item; @@ -223,7 +224,6 @@ private async Task OnEvent(WatcherEvent e) .SingleOrDefault(x => x.Name == name); var certExists = !(cert is null); if (certExists) - { if (tlsCrt.Contains(cert.Certificate)) { _logger.LogDebug( @@ -231,7 +231,6 @@ private async Task OnEvent(WatcherEvent e) secretId, hostSecretId); return; } - } // Create the certificate var bodyCreate = JsonSerializer.Serialize(new FreeNasCertificateCreateImported @@ -246,11 +245,11 @@ private async Task OnEvent(WatcherEvent e) var certId = certExists ? cert.Id : certificates.Single(x => x.Name == name).Id; - + var bodyGeneral = JsonSerializer.Serialize(new FreeNasSystemGeneral {Ui_certificate = certId}, options); await client.PutAsync("system/general/", new StringContent(bodyGeneral)); - + _logger.LogInformation("Reflected {secretId} to FreeNas device using host secret {hostSecretId}.", secretId, hostSecretId); } diff --git a/src/ES.Kubernetes.Reflector.Secrets/UbiquitiMirror.cs b/src/ES.Kubernetes.Reflector.Secrets/UbiquitiMirror.cs index 9b34f57..ef7abe8 100644 --- a/src/ES.Kubernetes.Reflector.Secrets/UbiquitiMirror.cs +++ b/src/ES.Kubernetes.Reflector.Secrets/UbiquitiMirror.cs @@ -98,6 +98,8 @@ private async Task OnWatcherStateChanged(ManagedWatcher e) { + if (e.Item.Type.StartsWith("helm.sh")) return; + var secretId = KubernetesObjectId.For(e.Item.Metadata()); var item = e.Item; @@ -108,7 +110,7 @@ private async Task OnEvent(WatcherEvent e) if (!e.Item.Type.Equals("kubernetes.io/tls", StringComparison.InvariantCultureIgnoreCase)) return; _logger.LogDebug("Ubiquiti enabled using host secret {secretId}.", secretId); - + var tlsCrt = Encoding.Default.GetString(item.Data["tls.crt"]); var tlsKey = Encoding.Default.GetString(item.Data["tls.key"]); diff --git a/src/ES.Kubernetes.Reflector.Secrets/VMwareMirror.cs b/src/ES.Kubernetes.Reflector.Secrets/VMwareMirror.cs index 6832568..7b8bd3b 100644 --- a/src/ES.Kubernetes.Reflector.Secrets/VMwareMirror.cs +++ b/src/ES.Kubernetes.Reflector.Secrets/VMwareMirror.cs @@ -98,6 +98,8 @@ private async Task OnWatcherStateChanged(ManagedWatcher e) { + if (e.Item.Type.StartsWith("helm.sh")) return; + var secretId = KubernetesObjectId.For(e.Item.Metadata()); var item = e.Item; @@ -108,7 +110,7 @@ private async Task OnEvent(WatcherEvent e) if (!e.Item.Type.Equals("kubernetes.io/tls", StringComparison.InvariantCultureIgnoreCase)) return; _logger.LogDebug("VMware enabled using host secret {secretId}.", secretId); - + var tlsCrt = Encoding.Default.GetString(item.Data["tls.crt"]); var tlsKey = Encoding.Default.GetString(item.Data["tls.key"]); @@ -188,20 +190,16 @@ private async Task OnEvent(WatcherEvent e) // SSH void HandleKeyEvent(object sender, AuthenticationPromptEventArgs eventArgs) - { + { foreach (var prompt in eventArgs.Prompts) - { if (prompt.Request.IndexOf("Password:", StringComparison.InvariantCultureIgnoreCase) != -1) - { prompt.Response = password; - } - } } - + var keyboardAuth = new KeyboardInteractiveAuthenticationMethod(username); keyboardAuth.AuthenticationPrompt += HandleKeyEvent; var connectionInfo = new ConnectionInfo(host, port, username, keyboardAuth); - + using var client = new SshClient(connectionInfo); client.ErrorOccurred += delegate(object sender, ExceptionEventArgs exceptionEventArgs) {