Exemplo n.º 1
0
        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");
        }
Exemplo n.º 2
0
        /// <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));
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 5
0
        /**
         * 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();
        }
Exemplo n.º 6
0
 private void EnqueueEvent(WatcherEvent watcherEvent)
 {
     lock (eventQueueLock)
     {
         eventQueue.Enqueue(watcherEvent);
         Monitor.Pulse(eventQueueLock);
     }
 }
Exemplo n.º 7
0
        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());
        }
Exemplo n.º 8
0
        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;
        }
Exemplo n.º 9
0
        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);
                }
            }
        }
Exemplo n.º 10
0
        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();
        }
Exemplo n.º 12
0
        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");
        }
Exemplo n.º 13
0
        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
            }
        }
Exemplo n.º 14
0
        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;
            }
        }
Exemplo n.º 16
0
        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);
        }
Exemplo n.º 17
0
        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);
        }
Exemplo n.º 18
0
        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;
            }
        }
Exemplo n.º 20
0
 private void EnqueueEvent(WatcherEvent watcherEvent)
 {
     lock (eventQueueLock)
     {
         eventQueue.Enqueue(watcherEvent);
         Monitor.Pulse(eventQueueLock);
     }
 }
Exemplo n.º 21
0
        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);
            }
        }
Exemplo n.º 22
0
 internal FileEventArgs(VirtualFile file, WatcherEvent @event)
 {
     File  = file;
     Event = @event;
 }
Exemplo n.º 23
0
        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);
                }
            }
        }
Exemplo n.º 24
0
        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());
                }
            }
        }
Exemplo n.º 25
0
            /// <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);
            }
Exemplo n.º 26
0
        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);
            }
        }
Exemplo n.º 27
0
        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);
            }
        }
Exemplo n.º 28
0
 public WatchedEvent(WatcherEvent eventMessage)
 {
     state = (KeeperState)Enum.ToObject(typeof(KeeperState), eventMessage.State);
     type  = (EventType)Enum.ToObject(typeof(EventType), eventMessage.Type);
     path  = eventMessage.Path;
 }
Exemplo n.º 29
0
 private void Watcher_Event(object sender, FileSystemEventArgs e)
 {
     WatcherEvent?.Invoke(this, EventArgs.Empty);
 }
Exemplo n.º 30
0
 /// <summary>
 /// 监控当前路径,包括子路径
 /// </summary>
 /// <param name="delegate">监控</param>
 /// <returns>异步,true表示成功,false表示失败</returns>
 public async Task <bool> WatchAllAsync(WatcherEvent @delegate)
 {
     return(await WatchAllAsync(CurrentPath, @delegate, true));
 }
Exemplo n.º 31
0
        /// <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());
        }
Exemplo n.º 32
0
 private void Watcher_MessageRaised(object sender, WatcherEvent e)
 {
     SetTemporaryStatusMessage(e.Message);
 }
Exemplo n.º 33
0
        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;
        }