Exemple #1
0
        /// <summary>
        /// Pings one or more hostnames or IP addresses in parallel to identify one that
        /// appears to be online and reachable via the network (because it answers a ping).
        /// </summary>
        /// <param name="hosts">The hostname or IP addresses to be tested.</param>
        /// <param name="failureMode">
        /// Specifies what should happen when there are no reachable hosts.
        /// This defaults to <see cref="ReachableHostMode.ReturnFirst"/>.
        /// </param>
        /// <returns>A <see cref="ReachableHost"/> instance describing the host or <c>null</c>.</returns>
        /// <exception cref="NetworkException">
        /// Thrown if no hosts are reachable and <paramref name="failureMode"/> is
        /// passed as <see cref="ReachableHostMode.Throw"/>.
        /// </exception>
        public static ReachableHost GetReachableHost(IEnumerable <string> hosts, ReachableHostMode failureMode = ReachableHostMode.ReturnFirst)
        {
            Covenant.Requires <ArgumentNullException>(hosts != null, nameof(hosts));
            Covenant.Requires <ArgumentNullException>(hosts.Count() > 0, nameof(hosts));

            var reachableHosts = GetReachableHosts(hosts);

            // We want to favor reachable hosts that appear earlier in the
            // hosts list passed over hosts that appear later.

            if (!reachableHosts.IsEmpty())
            {
                foreach (var host in hosts)
                {
                    foreach (var reachableHost in reachableHosts)
                    {
                        if (host == reachableHost.Host)
                        {
                            return(reachableHost);
                        }
                    }
                }
            }

            // None of the hosts responded so the result is determined by the
            // failure mode.

            switch (failureMode)
            {
            case ReachableHostMode.ReturnFirst:

                var firstHost = hosts.First();

                return(new ReachableHost(firstHost, null, TimeSpan.Zero, unreachable: true));

            case ReachableHostMode.ReturnNull:

                return(null);

            case ReachableHostMode.Throw:

                throw new NetworkException("None of the hosts responded.");

            default:

                throw new NotImplementedException($"Unexpected failure [mode={failureMode}].");
            }
        }
Exemple #2
0
        /// <summary>
        /// Returns a master node that is reachable via the network because it answers a ping.
        /// </summary>
        /// <param name="failureMode">Specifies what should happen when there are no reachable masters.</param>
        /// <returns>The reachable master node or <c>null</c>.</returns>
        /// <exception cref="KubeException">
        /// Thrown if no masters are reachable and <paramref name="failureMode"/>
        /// is passed as <see cref="ReachableHostMode.Throw"/>.
        /// </exception>
        public SshProxy <NodeDefinition> GetReachableMaster(ReachableHostMode failureMode = ReachableHostMode.ReturnFirst)
        {
            var masterAddresses = Nodes
                                  .Where(n => n.Metadata.IsMaster)
                                  .Select(n => n.PrivateAddress.ToString())
                                  .ToList();

            var reachableHost = NetHelper.GetReachableHost(masterAddresses, failureMode);

            if (reachableHost == null)
            {
                return(null);
            }

            // Return the node that is assigned the reachable address.

            return(Nodes.Where(n => n.PrivateAddress.ToString() == reachableHost.Host).First());
        }
Exemple #3
0
        /// <summary>
        /// Selects a cluster node from the set of nodes that match a predicate that is
        /// reachable via the network because it answers a ping.
        /// </summary>
        /// <param name="predicate">Predicate used to select the candidate nodes.</param>
        /// <param name="failureMode">Specifies what should happen when there are no reachable nodes.</param>
        /// <returns>The reachable node or <c>null</c>.</returns>
        /// <exception cref="KubeException">
        /// Thrown if no nodes matching the predicate are reachable and <paramref name="failureMode"/>
        /// is passed as <see cref="ReachableHostMode.Throw"/>.
        /// </exception>
        public SshProxy <NodeDefinition> GetReachableNode(Func <SshProxy <NodeDefinition>, bool> predicate, ReachableHostMode failureMode = ReachableHostMode.ReturnFirst)
        {
            var nodeAddresses = Nodes
                                .Where(predicate)
                                .Select(n => n.PrivateAddress.ToString())
                                .ToList();

            var reachableHost = NetHelper.GetReachableHost(nodeAddresses, failureMode);

            if (reachableHost == null)
            {
                return(null);
            }

            // Return the node that is assigned the reachable address.

            return(Nodes.Where(n => n.PrivateAddress.ToString() == reachableHost.Host).First());
        }