private async Task OnEventHandlingError(WatcherEvent e, Exception ex) { var id = KubernetesObjectId.For(e.Item.Metadata()); if (ex is Microsoft.Rest.HttpOperationException httpEx) { _logger.LogError($"Microsoft.Rest.HttpOperationException response: {httpEx.Response.Content}"); } _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(); } _eventQueue.Clear(); _logger.LogTrace("Watchers restarting"); await _secretsWatcher.Start(); foreach (var certificatesWatcher in _certificatesWatchers.Values) { await certificatesWatcher.Start(); } _logger.LogTrace("Watchers restarted"); }
/// <summary> /// 监控所有路径,包括子路径 /// </summary> /// <param name="paths">节点路径</param> /// <param name="delegate">监控</param> /// <param name="isAbsolutePath">是否绝对路径</param> /// <returns>异步,true表示成功,false表示失败</returns> public async Task <bool[]> WatchAllAsync(string[] paths, WatcherEvent @delegate, bool isAbsolutePath = false) { var watcher = new NodeWatcher(); watcher.AllTypeChanged += @delegate; return(await WatchAllAsync(paths, watcher, isAbsolutePath)); }
private async Task OnCrdEventV1(WatcherEvent <V1CustomResourceDefinition> 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 OnEvent(WatcherEvent e) { var id = KubernetesObjectId.For(e.Item.Metadata()); _logger.LogTrace("[{eventType}] {kind} {@id}", e.Type, e.Item.Kind, id); await _mediator.Publish(e); }
/** * Convert a WatcherEvent sent over the wire into a full-fledged WatcherEvent */ internal WatchedEvent(WatcherEvent eventMessage) { keeperState = EnumUtil <Watcher.Event.KeeperState> .DefinedCast(eventMessage.getState()); eventType = EnumUtil <Watcher.Event.EventType> .DefinedCast(eventMessage.get_Type()); path = eventMessage.getPath(); }
private void EnqueueEvent(WatcherEvent watcherEvent) { lock (eventQueueLock) { eventQueue.Enqueue(watcherEvent); Monitor.Pulse(eventQueueLock); } }
public void testConvertingToEventWrapper() { WatchedEvent we = new WatchedEvent(Watcher.Event.EventType.NodeCreated, Watcher.Event.KeeperState.Expired, "blah"); WatcherEvent wew = we.getWrapper(); Assert.assertEquals((int)Watcher.Event.EventType.NodeCreated, wew.get_Type()); Assert.assertEquals((int)Watcher.Event.KeeperState.Expired, wew.getState()); Assert.assertEquals("blah", wew.getPath()); }
public SystemWatcher() { // Watch for changes in LastAccess and LastWrite times, and the renaming of files or directories filter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName; printchanged = null; //printrenamed = null; watcher = null; }
private void ReadTaskMain() { bool keepOnReading = true; StreamReader reader = null; while (keepOnReading) { // If not already reading, find something to read if (reader == null) { reader = GetStreamReader(); } // Check for data on our current reader if (reader != null) { string line; try { while ((line = reader.ReadLine()) != null) { LineWriter.WriteLine(line); } } catch (IOException ex) { LineWriter.WriteLine(string.Format(">>>> {0} <<<<", ex.Message)); reader = null; continue; } } // Check for file system events WatcherEvent watcherEvent = null; lock (eventQueueLock) { if (eventQueue.Count == 0) { Monitor.Wait(eventQueueLock, FilePollingMs); } if (eventQueue.Count > 0) { watcherEvent = eventQueue.Dequeue(); keepOnReading = watcherEvent != null; } } if (watcherEvent != null) { reader = HandleWatcherEvent(reader, watcherEvent); } } }
protected async Task OnResourceWatcherEvent(WatcherEvent <TResource> request) { var item = request.Item; var eventType = request.Type; var metadata = item.Metadata(); var id = KubernetesObjectId.For(metadata); if (await OnResourceIgnoreCheck(item)) { return; } switch (eventType) { case WatchEventType.Added: case WatchEventType.Modified: { //Check if the source for auto reflection is still valid. if (await CheckAutoReflectionSource(item)) { return; } //Ensure auto reflections await CheckAutoReflections(item); //Update current item. If updated, return (Update will be picked up by watcher) if (await ReflectSourceToSelf(item)) { return; } //Update all child reflections await ReflectSelfToReflections(item); } break; case WatchEventType.Deleted: { _reflections.TryRemove(id, out _); _autoReflections.TryRemove(id, out _); //Remove all auto-reflections await UpdateAutoReflections(item, new List <string>()); } break; case WatchEventType.Error: break; default: throw new ArgumentOutOfRangeException(); } }
private async Task OnEventHandlingError(WatcherEvent e, Exception ex) { var id = KubernetesObjectId.For(e.Item.Metadata()); _logger.LogError(ex, "Failed to process {eventType} {kind} {@id} due to exception", e.Type, e.Item.Kind, id); await WatchersStop(); _eventQueue.Clear(); _logger.LogInformation("Restarting watchers "); await WatchersStart(); }
private async Task OnEventHandlingError(WatcherEvent <V1Secret> e, Exception ex) { var id = KubernetesObjectId.For(e.Item.Metadata()); _logger.LogError(ex, "Failed to process {eventType} {kind} {@id} due to exception", e.Type, e.Item.Kind, id); await _secretsWatcher.Stop(); _eventQueue.Clear(); _logger.LogTrace("Watchers restarting"); await _secretsWatcher.Start(); _logger.LogTrace("Watchers restarted"); }
public void testCreatingWatchedEventFromInvalidWrapper() { // Make sure we can't convert from an invalid wrapper try { WatcherEvent wep = new WatcherEvent(-2342, -252352, "foo"); WatchedEvent we = new WatchedEvent(wep); Assert.fail("Was able to create WatchedEvent from bad wrapper"); } catch (Exception) { // we're good } }
private async Task OnEventHandlingError(WatcherEvent e, Exception ex) { var id = KubernetesObjectId.For(e.Item.Metadata()); if (ex is Microsoft.Rest.HttpOperationException httpEx) { _logger.LogError($"Microsoft.Rest.HttpOperationException response: {httpEx.Response.Content}"); } _logger.LogError(ex, "Failed to process {eventType} {kind} {@id} due to exception", e.Type, e.Item.Kind, id); await WatchersStop(); _eventQueue.Clear(); _logger.LogInformation("Restarting watchers "); await WatchersStart(); }
private async Task OnEvent(WatcherEvent e) { var id = KubernetesObjectId.For(e.Item.Metadata()); _logger.LogTrace("[{eventType}] {kind} {@id}", e.Type, e.Item.Kind, id); switch (e) { case WatcherEvent <TResource> resourceEvent: await OnResourceWatcherEvent(resourceEvent); break; case WatcherEvent <V1Namespace> namespaceEvent: await OnNamespaceWatcherEvent(namespaceEvent); break; } }
private void OnChanged(object source, FileSystemEventArgs e) { FileSystemWatcher watcher = source as FileSystemWatcher; DateTime writeTime = File.GetLastWriteTime(e.FullPath); // Avoid duplicate events if (watcher == null || (WatcherEvent.Matches(writeTime) && WatcherEvent.Matches(e))) { return; } // Execute the appropriate action if (_pathActions.ContainsKey(watcher.Path)) { _pathActions[watcher.Path](); } WatcherEvent.Update(e, writeTime); }
private StreamReader HandleWatcherEvent(StreamReader currentStreamReader, WatcherEvent watcherEvent) { StreamReader resultStreamReader = currentStreamReader; var fileSystemEventArgs = watcherEvent.EventArgs as FileSystemEventArgs; var renamedEventArgs = watcherEvent.EventArgs as RenamedEventArgs; Debug.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:dd.fffff") + " " + watcherEvent.EventType); switch (watcherEvent.EventType) { case WatcherEventType.Create: // Do nothing. A new empty file does not interest us. We'll read it once we get a Change event. break; case WatcherEventType.Change: if (!ArePathsEqual(fileSystemEventArgs.FullPath, FullPathOf(currentStreamReader))) { // A change in some other file. Chase that one. resultStreamReader = null; } break; case WatcherEventType.Rename: var currentFullPath = FullPathOf(currentStreamReader); if (ArePathsEqual(renamedEventArgs.FullPath, currentFullPath) || ArePathsEqual(renamedEventArgs.OldFullPath, currentFullPath)) { // File names are changing and our stream reader happily ignores further data. resultStreamReader = null; } break; case WatcherEventType.Delete: if (ArePathsEqual(fileSystemEventArgs.FullPath, FullPathOf(currentStreamReader))) { // We are being deleted. resultStreamReader = null; } break; } return(resultStreamReader); }
public void testCreatingWatchedEventFromWrapper() { // Make sure we can handle any type of correct wrapper IEnumerable <Watcher.Event.EventType> allTypes = EnumUtil <Watcher.Event.EventType> .GetValues(); IEnumerable <Watcher.Event.KeeperState> allStates = EnumUtil <Watcher.Event.KeeperState> .GetValues(); foreach (Watcher.Event.EventType et in allTypes) { foreach (Watcher.Event.KeeperState ks in allStates) { var wep = new WatcherEvent((int)et, (int)ks, "blah"); var we = new WatchedEvent(wep); Assert.assertEquals(et, we.get_Type()); Assert.assertEquals(ks, we.getState()); Assert.assertEquals("blah", we.getPath()); } } }
protected async Task OnNamespaceWatcherEvent(WatcherEvent <V1Namespace> request) { switch (request.Type) { case WatchEventType.Added: { var id = _autoReflections.Keys.ToList(); foreach (var source in id) { var item = await OnResourceGet(_client, source.Name, source.Namespace); await CheckAutoReflections(item); } } break; case WatchEventType.Deleted: { var toRemove = _reflections.Keys .Where(s => s.Namespace.Equals(request.Item.Metadata.Name)) .ToList(); foreach (var id in toRemove) { _reflections.TryRemove(id, out _); } toRemove = _autoReflections.Keys .Where(s => s.Namespace.Equals(request.Item.Metadata.Name)) .ToList(); foreach (var id in toRemove) { _autoReflections.TryRemove(id, out _); } } break; } }
private async Task OnEvent(WatcherEvent <V1Secret> e) { if (e.Item.Type.StartsWith("helm.sh")) { return; } var secretId = KubernetesObjectId.For(e.Item.Metadata()); var item = e.Item; _logger.LogTrace("[{eventType}] {kind} {@id}", e.Type, e.Item.Kind, secretId); if (e.Type != WatchEventType.Added && e.Type != WatchEventType.Modified) { return; } if (!e.Item.Metadata.ReflectionAllowed() || !e.Item.Metadata.VMwareReflectionEnabled()) { return; } 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"]); var hostSecretIds = item.Metadata.VMwareReflectionHosts() .Select(s => new KubernetesObjectId(s)) .ToList(); foreach (var hostSecretId in hostSecretIds) { _logger.LogDebug( "Reflecting {secretId} to VMware ESXi device using host secret {hostSecretId}.", secretId, hostSecretId, hostSecretId); string hostAddress; string username; string password; try { var hostSecret = await _apiClient.ReadNamespacedSecretAsync(hostSecretId.Name, string.IsNullOrWhiteSpace(hostSecretId.Namespace) ?e.Item.Metadata.NamespaceProperty : hostSecretId.Namespace); if (hostSecret.Data is null || !hostSecret.Data.Keys.Any()) { _logger.LogWarning("Cannot reflect {secretId} to {hostSecretId}. " + "Host secret {hostSecretId} has no data.", secretId, hostSecretId, hostSecretId); continue; } hostAddress = hostSecret.Data.ContainsKey("host") ? Encoding.Default.GetString(hostSecret.Data["host"]) : null; username = hostSecret.Data.ContainsKey("username") ? Encoding.Default.GetString(hostSecret.Data["username"]) : null; password = hostSecret.Data.ContainsKey("password") ? Encoding.Default.GetString(hostSecret.Data["password"]) : null; } catch (HttpOperationException ex) when(ex.Response.StatusCode == HttpStatusCode.NotFound) { _logger.LogWarning( "Cannot reflect {secretId} to {hostSecretId}. Host secret {hostSecretId} not found.", secretId, hostSecretId, hostSecretId); continue; } if (string.IsNullOrWhiteSpace(hostAddress) || string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password)) { _logger.LogWarning( "Cannot reflect {secretId} to VMware ESXi device using host secret {hostSecretId}. " + "Host secret {hostSecretId} must contain 'host', 'username' and 'password' values.", secretId, hostSecretId, hostSecretId); continue; } var hostParts = hostAddress.Split(new[] { ":" }, StringSplitOptions.RemoveEmptyEntries) .Select(s => s.Trim()) .Where(s => !string.IsNullOrWhiteSpace(s)).ToList(); if (!hostParts.Any() || hostParts.Count > 2) { _logger.LogWarning( "Cannot reflect {secretId} to VMware ESXi device using host secret {hostSecretId}. " + "Host secret {hostSecretId} contains invalid 'host' data. " + "'host' must be in the format 'host:port' where port is optional.", secretId, hostSecretId, hostSecretId); } var host = hostParts.First(); var port = hostParts.Count < 2 ? 22 : int.TryParse(hostParts.Last(), out var p) ? p : 22; // SSH void HandleKeyEvent(object sender, AuthenticationPromptEventArgs eventArgs) { foreach (var prompt in eventArgs.Prompts) { if (prompt.Request.IndexOf("Password:"******"Cannot reflect {secretId} to VMware ESXi device using host secret {hostSecretId} due to exception.", secretId, hostSecretId); }; _logger.LogDebug("Connecting to VMware ESXi device at {host}", hostAddress); client.Connect(); _logger.LogDebug("Check certificate on VMware ESXi device at {host}", hostAddress); var catCommand = client.RunCommand("cat /etc/vmware/ssl/rui.crt"); if (catCommand.Result.Contains(tlsCrt)) { _logger.LogDebug( "Skip reflecting {secretId} to VMware ESXi device using host secret {hostSecretId}. Already exists.", secretId, hostSecretId); return; } _logger.LogDebug("Configuring new Let's Encrypt certs on VMware ESXi device at {host}", hostAddress); client.RunCommand($"echo \"{tlsCrt}\" > /etc/vmware/ssl/rui.crt"); client.RunCommand($"echo \"{tlsKey}\" > /etc/vmware/ssl/rui.key"); _logger.LogDebug("Restarting on VMware ESXi device at {host}", hostAddress); client.RunCommand("services.sh restart"); client.Disconnect(); _logger.LogInformation("Reflected {secretId} to VMware ESXi device using host secret {hostSecretId}.", secretId, hostSecretId); } }
internal FileEventArgs(VirtualFile file, WatcherEvent @event) { File = file; Event = @event; }
private async Task OnEvent(WatcherEvent <V1Secret> e) { var id = KubernetesObjectId.For(e.Item.Metadata()); var item = e.Item; _logger.LogTrace("[{eventType}] {kind} {@id}", e.Type, e.Item.Kind, id); if (e.Type != WatchEventType.Added && e.Type != WatchEventType.Modified) { return; } if (!e.Item.Metadata.ReflectionAllowed() || !e.Item.Metadata.FortiReflectionEnabled()) { return; } if (!e.Item.Type.Equals("kubernetes.io/tls", StringComparison.InvariantCultureIgnoreCase)) { return; } var caCrt = Encoding.Default.GetString(item.Data["ca.crt"]); var tlsCrt = Encoding.Default.GetString(item.Data["tls.crt"]); var tlsKey = Encoding.Default.GetString(item.Data["tls.key"]); var tlsCerts = tlsCrt.Split(new[] { "-----END CERTIFICATE-----" }, StringSplitOptions.RemoveEmptyEntries) .Select(s => s.TrimStart()) .Where(s => !string.IsNullOrWhiteSpace(s)) .Select(s => $"{s}-----END CERTIFICATE-----") .ToList(); var hostSecretIds = item.Metadata.FortiReflectionHosts().Select(s => new KubernetesObjectId(s)).ToList(); var fortiCertName = item.Metadata.FortiCertificate(); var fortiCertId = !string.IsNullOrWhiteSpace(fortiCertName) ? fortiCertName : item.Metadata.Name.Substring(0, Math.Min(item.Metadata.Name.Length, 30)); foreach (var hostSecretId in hostSecretIds) { _logger.LogDebug( "Reflecting {secretId} to FortiOS device using host secret {hostSecretId}.", id, hostSecretId, hostSecretId); string fortiHost; string fortiUsername; string fortiPassword; try { var hostSecret = await _apiClient.ReadNamespacedSecretAsync(hostSecretId.Name, hostSecretId.Namespace); if (hostSecret.Data is null || !hostSecret.Data.Keys.Any()) { _logger.LogWarning("Cannot reflect {secretId} to {hostSecretId}. " + "Host secret {hostSecretId} has no data.", id, hostSecretId, hostSecretId); continue; } fortiHost = hostSecret.Data.ContainsKey("host") ? Encoding.Default.GetString(hostSecret.Data["host"]) : null; fortiUsername = hostSecret.Data.ContainsKey("username") ? Encoding.Default.GetString(hostSecret.Data["username"]) : null; fortiPassword = hostSecret.Data.ContainsKey("password") ? Encoding.Default.GetString(hostSecret.Data["password"]) : null; } catch (HttpOperationException ex) when(ex.Response.StatusCode == HttpStatusCode.NotFound) { _logger.LogWarning("Cannot reflect {secretId} to {hostSecretId}. Host secret {hostSecretId} not found.", id, hostSecretId, hostSecretId); continue; } if (string.IsNullOrWhiteSpace(fortiHost) || string.IsNullOrWhiteSpace(fortiUsername) || string.IsNullOrWhiteSpace(fortiPassword)) { _logger.LogWarning( "Cannot reflect {secretId} to FortiOS device using host secret {hostSecretId}. " + "Host secret {hostSecretId} must contain 'host', 'username' and 'password' values.", id, hostSecretId, hostSecretId); continue; } var hostParts = fortiHost.Split(new[] { ":" }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()) .Where(s => !string.IsNullOrWhiteSpace(s)).ToList(); if (!hostParts.Any() || hostParts.Count > 2) { _logger.LogWarning( "Cannot reflect {secretId} to FortiOS device using host secret {hostSecretId}. " + "Host secret {hostSecretId} contains invalid 'host' data. " + "'host' must be in the format 'host:port' where port is optional.", id, hostSecretId, hostSecretId); } var hostPort = hostParts.Count < 2 ? 22 : int.TryParse(hostParts.Last(), out var port) ? port : 22; using var client = new SshClient(hostParts.First(), hostPort, fortiUsername, fortiPassword) { ConnectionInfo = { Timeout = TimeSpan.FromSeconds(10) } }; try { _logger.LogDebug("Connecting for FortiOS device at {host}", fortiHost); client.Connect(); } catch (Exception exception) { _logger.LogError(exception, "Cannot reflect {secretId} to FortiOS device using host secret {hostSecretId} due to exception.", id, hostSecretId); continue; } _logger.LogDebug("Checking for certificate {certId} on FortiOS device {host}", fortiCertId, fortiHost); string checkOutput; await using (var shell = client.CreateShellStream(nameof(FortiMirror), 128, 1024, 800, 600, 1024)) { var lastLine = string.Empty; var outputBuilder = new StringBuilder(); shell.WriteLine("config vpn certificate local"); shell.WriteLine($"edit {fortiCertId}"); shell.WriteLine("show full"); shell.WriteLine("end"); while (!(lastLine.Contains("#") && lastLine.Contains("end"))) { lastLine = shell.ReadLine(); outputBuilder.AppendLine(lastLine); } shell.Close(); checkOutput = outputBuilder.ToString(); } var localCertificateUpToDate = true; if (!string.IsNullOrWhiteSpace(tlsKey)) { if (checkOutput.Contains("unset private-key")) { localCertificateUpToDate = false; } } if (!checkOutput.Contains("set certificate", StringComparison.InvariantCultureIgnoreCase)) { localCertificateUpToDate = false; } else { var remoteCertificate = checkOutput.Substring(checkOutput.IndexOf("set certificate \"", StringComparison.InvariantCultureIgnoreCase)); remoteCertificate = remoteCertificate.Replace("set certificate \"", string.Empty, StringComparison.InvariantCultureIgnoreCase); remoteCertificate = remoteCertificate.Substring(0, remoteCertificate.IndexOf("\"", StringComparison.InvariantCultureIgnoreCase)); remoteCertificate = remoteCertificate.Replace("\r", string.Empty); if (!tlsCerts.Select(s => s.Replace("\r", string.Empty)).Contains(remoteCertificate)) { localCertificateUpToDate = false; } } var success = true; if (!localCertificateUpToDate) { var commandBuilder = new StringBuilder(); commandBuilder.AppendLine("config vpn certificate local"); commandBuilder.AppendLine($"edit {fortiCertId}"); commandBuilder.AppendLine($"set private-key \"{tlsKey}\""); commandBuilder.AppendLine($"set certificate \"{tlsCrt}\""); commandBuilder.AppendLine("end"); var command = client.RunCommand(commandBuilder.ToString()); if (command.ExitStatus != 0 || !string.IsNullOrWhiteSpace(command.Error)) { _logger.LogWarning( "Checking for certificate {certId} could not be installed on FortiOS device {host} due to error: {error}", id, fortiHost, command.Error); success = false; } } if (!localCertificateUpToDate && success) { var caCerts = tlsCerts.ToList(); if (!string.IsNullOrWhiteSpace(caCrt)) { caCerts.Add(caCrt); } var caId = 0; for (var i = 0; i < caCerts.Count; i++) { _logger.LogDebug("Installing CA certificate {index} for {certId} on FortiOS device {host}", i + 1, id, fortiHost); var commandBuilder = new StringBuilder(); commandBuilder.AppendLine("config vpn certificate ca"); commandBuilder.AppendLine($"edit {fortiCertId}_CA{(caId == 0 ? string.Empty : caId.ToString())}"); commandBuilder.AppendLine($"set ca \"{tlsCerts[i]}\""); commandBuilder.AppendLine("end"); var command = client.RunCommand(commandBuilder.ToString()); if (command.ExitStatus == 0 && string.IsNullOrWhiteSpace(command.Error)) { caId++; continue; } if (command.Error.Contains("This CA certificate is duplicated.")) { _logger.LogWarning("Skipping CA certificate {index} since it is duplicated by another certificate.", i + i); } else if (command.Error.Contains("Input is not a valid CA certificate.")) { _logger.LogDebug("Skipping CA certificate {index} since it is not a valid CA certificate.", i + i); } else { _logger.LogWarning("Could not install CA {index} certificate due to error: {response}", i + 1, command.Result); success = false; } } } if (!success) { _logger.LogError("Reflecting {secretId} to FortiOS device using host secret {hostSecretId} completed with errors.", id, hostSecretId); } else if (!localCertificateUpToDate) { _logger.LogInformation("Reflected {secretId} to FortiOS device using host secret {hostSecretId}.", id, hostSecretId); } } }
private void ReadResponse(byte[] content) { using (var reader = new EndianBinaryReader(EndianBitConverter.Big, new MemoryStream(content), Encoding.UTF8)) { BinaryInputArchive bbia = BinaryInputArchive.GetArchive(reader); ReplyHeader replyHdr = new ReplyHeader(); replyHdr.Deserialize(bbia, "header"); if (replyHdr.Xid == -2) { // -2 is the xid for pings if (LOG.IsDebugEnabled) { LOG.DebugFormat("Got ping response for sessionid: 0x{0:X} after {1}ms", conn.SessionId, (DateTime.UtcNow.Nanos() - lastPingSentNs) / 1000000); } return; } if (replyHdr.Xid == -4) { // -2 is the xid for AuthPacket // TODO: process AuthPacket here if (LOG.IsDebugEnabled) { LOG.DebugFormat("Got auth sessionid:0x{0:X}", conn.SessionId); } return; } if (replyHdr.Xid == -1) { // -1 means notification if (LOG.IsDebugEnabled) { LOG.DebugFormat("Got notification sessionid:0x{0}", conn.SessionId); } WatcherEvent @event = new WatcherEvent(); @event.Deserialize(bbia, "response"); // convert from a server path to a client path if (conn.ChrootPath != null) { string serverPath = @event.Path; if (serverPath.CompareTo(conn.ChrootPath) == 0) { @event.Path = PathUtils.PathSeparator; } else { @event.Path = serverPath.Substring(conn.ChrootPath.Length); } } WatchedEvent we = new WatchedEvent(@event); if (LOG.IsDebugEnabled) { LOG.DebugFormat("Got {0} for sessionid 0x{1:X}", we, conn.SessionId); } conn.consumer.QueueEvent(we); return; } Packet packet; /* * Since requests are processed in order, we better get a response * to the first request! */ if (pendingQueue.TryDequeue(out packet)) { try { if (packet.header.Xid != replyHdr.Xid) { packet.replyHeader.Err = (int)KeeperException.Code.CONNECTIONLOSS; throw new IOException(new StringBuilder("Xid out of order. Got ").Append(replyHdr.Xid).Append(" expected ").Append(packet.header.Xid).ToString()); } packet.replyHeader.Xid = replyHdr.Xid; packet.replyHeader.Err = replyHdr.Err; packet.replyHeader.Zxid = replyHdr.Zxid; if (replyHdr.Zxid > 0) { lastZxid = replyHdr.Zxid; } if (packet.response != null && replyHdr.Err == 0) { packet.response.Deserialize(bbia, "response"); } if (LOG.IsDebugEnabled) { LOG.DebugFormat("Reading reply sessionid:0x{0:X}, packet:: {1}", conn.SessionId, packet); } } finally { FinishPacket(packet); } } else { throw new IOException(new StringBuilder("Nothing in the queue, but got ").Append(replyHdr.Xid).ToString()); } } }
/// <summary> /// Synchronization based on local filesystem monitoring ("watcher"). /// </summary> /// <param name="remoteFolder">Remote folder.</param> /// <param name="localFolder">Local folder.</param> /// <returns>Whether something has changed in the local folder</returns> private bool WatcherSync(string remoteFolder, string localFolder) { Logger.Debug(remoteFolder + " : " + localFolder); bool locallyModified = false; SleepWhileSuspended(); Queue <WatcherEvent> changeQueue = repo.Watcher.GetChangeQueue(); repo.Watcher.Clear(); if (Logger.IsDebugEnabled) { foreach (WatcherEvent change in changeQueue) { if (change.GetFileSystemEventArgs() is CmisSync.Lib.Watcher.MovedEventArgs) { Logger.DebugFormat("Moved: {0} -> {1}", ((CmisSync.Lib.Watcher.MovedEventArgs)change.GetFileSystemEventArgs()).OldFullPath, change.GetFileSystemEventArgs().FullPath); } else if (change.GetFileSystemEventArgs() is RenamedEventArgs) { Logger.DebugFormat("Renamed: {0} -> {1}", ((RenamedEventArgs)change.GetFileSystemEventArgs()).OldFullPath, change.GetFileSystemEventArgs().FullPath); } else { Logger.DebugFormat("{0}: {1}", change.GetFileSystemEventArgs().ChangeType, change.GetFileSystemEventArgs().FullPath); } } } while (changeQueue.Count > 0) { activityListener.ActivityStarted(); try { WatcherEvent earliestChange = changeQueue.Dequeue(); string pathname = earliestChange.GetFileSystemEventArgs().FullPath; if (!pathname.StartsWith(localFolder)) { Logger.DebugFormat("Path {0} does not apply for target {1}.", pathname, localFolder); activityListener.ActivityStopped(); continue; } if (pathname == localFolder) { continue; } if (earliestChange.GetFileSystemEventArgs() is CmisSync.Lib.Watcher.MovedEventArgs) { // Move CmisSync.Lib.Watcher.MovedEventArgs change = (CmisSync.Lib.Watcher.MovedEventArgs)earliestChange.GetFileSystemEventArgs(); Logger.DebugFormat("Processing 'Moved': {0} -> {1}.", change.OldFullPath, pathname); bool done = WatchSyncMove(remoteFolder, localFolder, change.OldFullPath, pathname, earliestChange.GetGrace()); locallyModified |= !done; } else if (earliestChange.GetFileSystemEventArgs() is RenamedEventArgs) { // Rename RenamedEventArgs change = (RenamedEventArgs)earliestChange.GetFileSystemEventArgs(); Logger.DebugFormat("Processing 'Renamed': {0} -> {1}.", change.OldFullPath, pathname); bool done = WatchSyncMove(remoteFolder, localFolder, change.OldFullPath, pathname, earliestChange.GetGrace()); locallyModified |= !done; } else { Logger.DebugFormat("Processing '{0}': {1}.", earliestChange.GetFileSystemEventArgs().ChangeType, pathname); switch (earliestChange.GetFileSystemEventArgs().ChangeType) { case WatcherChangeTypes.Created: case WatcherChangeTypes.Changed: bool done = WatcherSyncUpdate(remoteFolder, localFolder, pathname); locallyModified |= !done; break; case WatcherChangeTypes.Deleted: done = WatcherSyncDelete(remoteFolder, localFolder, pathname, earliestChange.GetGrace()); locallyModified |= !done; break; default: Logger.ErrorFormat("Ignoring change with unhandled type -> '{0}': {1}.", earliestChange.GetFileSystemEventArgs().ChangeType, pathname); break; } } } catch (Exception ex) { locallyModified = true; } activityListener.ActivityStopped(); } return(locallyModified); }
private async Task OnEvent(WatcherEvent <V1Secret> e) { if (e.Item.Type.StartsWith("helm.sh")) { return; } var secretId = KubernetesObjectId.For(e.Item.Metadata()); var item = e.Item; _logger.LogTrace("[{eventType}] {kind} {@id}", e.Type, e.Item.Kind, secretId); if (e.Type != WatchEventType.Added && e.Type != WatchEventType.Modified) { return; } if (!e.Item.Metadata.ReflectionAllowed() || !e.Item.Metadata.FreeNasReflectionEnabled()) { return; } if (!e.Item.Type.Equals("kubernetes.io/tls", StringComparison.InvariantCultureIgnoreCase)) { return; } _logger.LogDebug("FreeNas enabled using host secret {secretId}.", secretId); var tlsCrt = Encoding.Default.GetString(item.Data["tls.crt"]); var tlsKey = Encoding.Default.GetString(item.Data["tls.key"]); var hostSecretIds = item.Metadata.FreeNasReflectionHosts() .Select(s => new KubernetesObjectId(s)) .ToList(); var certName = item.Metadata.FreeNasCertificate(); foreach (var hostSecretId in hostSecretIds) { _logger.LogDebug( "Reflecting {secretId} to FreeNas device using host secret {hostSecretId}.", secretId, hostSecretId, hostSecretId); string hostAddress; string username; string password; try { var hostSecret = await _apiClient.ReadNamespacedSecretAsync(hostSecretId.Name, string.IsNullOrWhiteSpace(hostSecretId.Namespace) ?e.Item.Metadata.NamespaceProperty : hostSecretId.Namespace); if (hostSecret.Data is null || !hostSecret.Data.Keys.Any()) { _logger.LogWarning("Cannot reflect {secretId} to {hostSecretId}. " + "Host secret {hostSecretId} has no data.", secretId, hostSecretId, hostSecretId); continue; } hostAddress = hostSecret.Data.ContainsKey("host") ? Encoding.Default.GetString(hostSecret.Data["host"]) : null; username = hostSecret.Data.ContainsKey("username") ? Encoding.Default.GetString(hostSecret.Data["username"]) : null; password = hostSecret.Data.ContainsKey("password") ? Encoding.Default.GetString(hostSecret.Data["password"]) : null; } catch (HttpOperationException ex) when(ex.Response.StatusCode == HttpStatusCode.NotFound) { _logger.LogWarning( "Cannot reflect {secretId} to {hostSecretId}. Host secret {hostSecretId} not found.", secretId, hostSecretId, hostSecretId); continue; } if (string.IsNullOrWhiteSpace(hostAddress) || string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password)) { _logger.LogWarning( "Cannot reflect {secretId} to FreeNas device using host secret {hostSecretId}. " + "Host secret {hostSecretId} must contain 'host', 'username' and 'password' values.", secretId, hostSecretId, hostSecretId); continue; } var hostParts = hostAddress.Split(new[] { ":" }, StringSplitOptions.RemoveEmptyEntries) .Select(s => s.Trim()) .Where(s => !string.IsNullOrWhiteSpace(s)).ToList(); if (!hostParts.Any() || hostParts.Count > 2) { _logger.LogWarning( "Cannot reflect {secretId} to FreeNas device using host secret {hostSecretId}. " + "Host secret {hostSecretId} contains invalid 'host' data. " + "'host' must be in the format 'host:port' where port is optional.", secretId, hostSecretId, hostSecretId); } var host = hostParts.First(); // Check if certificate is the same var client = _clientFactory.CreateClient(); client.BaseAddress = new Uri($"https://{host}/api/v2.0/"); client.DefaultRequestHeaders.Clear(); client.DefaultRequestHeaders.ConnectionClose = true; client.DefaultRequestHeaders .Accept .Add(new MediaTypeWithQualityHeaderValue("application/json")); //ACCEPT header client.DefaultRequestHeaders.Add("User-Agent", "Emberstack/Reflector"); var authenticationString = $"{username}:{password}"; var base64EncodedAuthenticationString = Convert.ToBase64String(Encoding.ASCII.GetBytes(authenticationString)); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", base64EncodedAuthenticationString); var response = await client.GetAsync(CertificateUri); var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; await using var responseStream = await response.Content.ReadAsStreamAsync(); using var responseStr = response.Content.ReadAsStringAsync(); var certificates = await JsonSerializer.DeserializeAsync <List <FreeNasCertificate> >(responseStream, options); // var bytes = Encoding.ASCII.GetBytes(tlsCrt); // var x509Certificate2 = new X509Certificate2(bytes); // // var name = $"{certName}-{x509Certificate2.NotAfter:s}"; var name = certName; var cert = certificates .SingleOrDefault(x => x.Name == name); var certExists = !(cert is null); if (certExists) { if (tlsCrt.Contains(cert.Certificate)) { _logger.LogDebug( "Skip reflecting {secretId} to FreeNas device using host secret {hostSecretId}. Already exists.", secretId, hostSecretId); return; } } // Create the certificate var bodyCreate = JsonSerializer.Serialize(new FreeNasCertificateCreateImported { Name = name, Certificate = tlsCrt, Privatekey = tlsKey }, options); await client.PostAsync(CertificateUri, new StringContent(bodyCreate)); // Set the certificate as default var certId = certExists ? cert.Id : certificates.Single(x => x.Name == name).Id; var bodyGeneral = JsonSerializer.Serialize(new FreeNasSystemGeneral { UiCertificate = certId }, options); await client.PutAsync("system/general/", new StringContent(bodyGeneral)); _logger.LogInformation("Reflected {secretId} to FreeNas device using host secret {hostSecretId}.", secretId, hostSecretId); } }
internal void readResponse(ByteBuffer incomingBuffer) { BigEndianBinaryReader bbis = new BigEndianBinaryReader(incomingBuffer.Stream); BinaryInputArchive bbia = BinaryInputArchive.getArchive(bbis); ReplyHeader replyHdr = new ReplyHeader(); ((Record)replyHdr).deserialize(bbia, "header"); if (replyHdr.getXid() == -2) { // -2 is the xid for pings if (LOG.isDebugEnabled()) { LOG.debug("Got ping response for sessionid: 0x" + sessionId.ToHexString() + " after " + ((TimeHelper.ElapsedNanoseconds - lastPingSentNs) / 1000000) + "ms"); } return; } if (replyHdr.getXid() == -4) { // -4 is the xid for AuthPacket if (replyHdr.getErr() == (int)KeeperException.Code.AUTHFAILED) { state.Value = ZooKeeper.States.AUTH_FAILED; queueEvent(new WatchedEvent(Watcher.Event.EventType.None, Watcher.Event.KeeperState.AuthFailed, null)); } if (LOG.isDebugEnabled()) { LOG.debug("Got auth sessionid:0x" + sessionId.ToHexString()); } return; } if (replyHdr.getXid() == -1) { // -1 means notification if (LOG.isDebugEnabled()) { LOG.debug("Got notification sessionid:0x" + sessionId.ToHexString()); } WatcherEvent @event = new WatcherEvent(); ((Record)@event).deserialize(bbia, "response"); // convert from a server path to a client path if (chrootPath != null) { string serverPath = @event.getPath(); if (serverPath == chrootPath) { @event.setPath("/"); } else if (serverPath.Length > chrootPath.Length) { @event.setPath(serverPath.Substring(chrootPath.Length)); } else { LOG.warn("Got server path " + @event.getPath() + " which is too short for chroot path " + chrootPath); } } WatchedEvent we = new WatchedEvent(@event); if (LOG.isDebugEnabled()) { LOG.debug("Got " + we + " for sessionid 0x" + sessionId.ToHexString()); } queueEvent(we); return; } Packet packet; lock (pendingQueue) { if (pendingQueue.size() == 0) { throw new IOException("Nothing in the queue, but got " + replyHdr.getXid()); } packet = pendingQueue.First.Value; pendingQueue.RemoveFirst(); } /* * Since requests are processed in order, we better get a response * to the first request! */ try { if (packet.requestHeader.getXid() != replyHdr.getXid()) { packet.replyHeader.setErr((int)KeeperException.Code.CONNECTIONLOSS); throw new IOException("Xid out of order. Got Xid " + replyHdr.getXid() + " with err " + +replyHdr.getErr() + " expected Xid " + packet.requestHeader.getXid() + " for a packet with details: " + packet); } packet.replyHeader.setXid(replyHdr.getXid()); packet.replyHeader.setErr(replyHdr.getErr()); packet.replyHeader.setZxid(replyHdr.getZxid()); if (replyHdr.getZxid() > 0) { lastZxid.Value = replyHdr.getZxid(); } if (packet.response != null && replyHdr.getErr() == 0) { packet.response.deserialize(bbia, "response"); } if (LOG.isDebugEnabled()) { LOG.debug("Reading reply sessionid:0x" + sessionId.ToHexString() + ", packet:: " + packet); } } finally { finishPacket(packet); } }
public WatchedEvent(WatcherEvent eventMessage) { state = (KeeperState)Enum.ToObject(typeof(KeeperState), eventMessage.State); type = (EventType)Enum.ToObject(typeof(EventType), eventMessage.Type); path = eventMessage.Path; }
private void Watcher_Event(object sender, FileSystemEventArgs e) { WatcherEvent?.Invoke(this, EventArgs.Empty); }
/// <summary> /// 监控当前路径,包括子路径 /// </summary> /// <param name="delegate">监控</param> /// <returns>异步,true表示成功,false表示失败</returns> public async Task <bool> WatchAllAsync(WatcherEvent @delegate) { return(await WatchAllAsync(CurrentPath, @delegate, true)); }
/// <summary> /// 监控指定路径,包括子路径 /// </summary> /// <param name="path">节点路径</param> /// <param name="delegate">监控</param> /// <param name="isAbsolutePath">是否绝对路径</param> /// <returns>异步,true表示成功,false表示失败</returns> public async Task <bool> WatchAllAsync(string path, WatcherEvent @delegate, bool isAbsolutePath = false) { var array = await WatchAllAsync(new string[] { path }, @delegate, isAbsolutePath); return(array.FirstOrDefault()); }
private void Watcher_MessageRaised(object sender, WatcherEvent e) { SetTemporaryStatusMessage(e.Message); }
private StreamReader HandleWatcherEvent(StreamReader currentStreamReader, WatcherEvent watcherEvent) { StreamReader resultStreamReader = currentStreamReader; var fileSystemEventArgs = watcherEvent.EventArgs as FileSystemEventArgs; var renamedEventArgs = watcherEvent.EventArgs as RenamedEventArgs; Debug.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:dd.fffff") + " " + watcherEvent.EventType); switch (watcherEvent.EventType) { case WatcherEventType.Create: // Do nothing. A new empty file does not interest us. We'll read it once we get a Change event. break; case WatcherEventType.Change: if (!ArePathsEqual(fileSystemEventArgs.FullPath, FullPathOf(currentStreamReader))) { // A change in some other file. Chase that one. resultStreamReader = null; } break; case WatcherEventType.Rename: var currentFullPath = FullPathOf(currentStreamReader); if (ArePathsEqual(renamedEventArgs.FullPath, currentFullPath) || ArePathsEqual(renamedEventArgs.OldFullPath, currentFullPath)) { // File names are changing and our stream reader happily ignores further data. resultStreamReader = null; } break; case WatcherEventType.Delete: if (ArePathsEqual(fileSystemEventArgs.FullPath, FullPathOf(currentStreamReader))) { // We are being deleted. resultStreamReader = null; } break; } return resultStreamReader; }