static async Task ExecutePortsCommandAsync(NamespaceDetails namespaceDetails, int gatewayCount)
        {
            TraceCommandHeader("Ports");
            if (string.IsNullOrEmpty(namespaceDetails.ServiceNamespace))
            {
                TraceMissingArgument(NamespaceOrConnectionStringArgumentDescription);
                return;
            }

            RelayTraceSource.TraceInfo(await NetworkUtility.VerifyRelayPortsAsync(namespaceDetails.ServiceNamespace, Enumerable.Range(9400, gatewayCount)));

            var tasks = new List <Task <string> >();

            for (int i = 0; i < gatewayCount; i++)
            {
                // Build the ILPIP DNS name and run it for G0 through G63
                var task = NetworkUtility.VerifyRelayPortsAsync(string.Format(namespaceDetails.GatewayDnsFormat, i));
                tasks.Add(task);
            }

            foreach (Task <string> task in tasks)
            {
                string result = await task;
                RelayTraceSource.TraceInfo(result);
            }
        }
        static void ExecuteNamespaceCommand(NamespaceDetails namespaceDetails)
        {
            TraceCommandHeader("Namespace Details");

            bool foundAny = false;

            void OutputLineIf(bool condition, string name, Func <string> valueSelector)
            {
                if (condition)
                {
                    RelayTraceSource.TraceInfo(OutputFormat, name + ":", valueSelector());
                    foundAny = true;
                }
            }

            OutputLineIf(!string.IsNullOrEmpty(namespaceDetails.ServiceNamespace), "ServiceNamespace", () => namespaceDetails.ServiceNamespace);
            OutputLineIf(namespaceDetails.AddressList?.Length > 0, "Address(VIP)", () => string.Join(",", (IEnumerable <IPAddress>)namespaceDetails.AddressList));
            OutputLineIf(!string.IsNullOrEmpty(namespaceDetails.Deployment), "Deployment", () => namespaceDetails.Deployment);
            OutputLineIf(!string.IsNullOrEmpty(namespaceDetails.HostName), "HostName", () => namespaceDetails.HostName);
            OutputLineIf(!string.IsNullOrEmpty(namespaceDetails.GatewayDnsFormat), "GatewayDnsFormat", () => namespaceDetails.GatewayDnsFormat);

            if (!foundAny)
            {
                TraceMissingArgument(NamespaceOrConnectionStringArgumentDescription);
            }
        }
Beispiel #3
0
        internal static async Task <NamespaceDetails> GetNamespaceDetailsAsync(string serviceNamespace)
        {
            serviceNamespace = serviceNamespace.Trim();

            var   details = new NamespaceDetails();
            Match match   = DeploymentRegex.Match(serviceNamespace);

            if (match != null && match.Success && !serviceNamespace.Contains("."))
            {
                details.Deployment = match.Value.ToUpperInvariant();
            }
            else
            {
                string[] namespaceAndSuffix = serviceNamespace.Split(new[] { '.' }, 2);
                if (namespaceAndSuffix.Length == 1)
                {
                    serviceNamespace = $"{serviceNamespace}.{DefaultSuffix}";
                    details.Suffix   = DefaultSuffix;
                }
                else
                {
                    details.Suffix = namespaceAndSuffix[1];
                }

                details.ServiceNamespace = serviceNamespace;

                IPHostEntry dnsEntry = await Dns.GetHostEntryAsync(serviceNamespace).ConfigureAwait(false);

                details.HostName = dnsEntry.HostName;

                // Get the part up to the first '.' e.g. ns-sb2-prod-by-003, then remove 'ns-sb2' or similar prefixes
                string deployment = dnsEntry.HostName.Split('.')[0];
                deployment         = NamespacePrefixRegex.Replace(deployment, string.Empty);
                details.Deployment = deployment.ToUpperInvariant();

                details.AddressList      = dnsEntry.AddressList;
                details.GatewayDnsFormat = $"g{{0}}-{deployment}-sb.{details.Suffix}";
                details.Aliases          = dnsEntry.Aliases;
            }

            return(details);
        }
        static async Task ExecutePlatformCommandAsync(NamespaceDetails namespaceDetails)
        {
            TraceCommandHeader("OS/Platform");
            RelayTraceSource.TraceInfo(OutputFormat, "OSVersion:", Environment.OSVersion);
            RelayTraceSource.TraceInfo(OutputFormat, "ProcessorCount:", Environment.ProcessorCount);
            RelayTraceSource.TraceInfo(OutputFormat, "Is64BitOperatingSystem:", Environment.Is64BitOperatingSystem);
            RelayTraceSource.TraceInfo(OutputFormat, "CLR Version:", Environment.Version);
            RelayTraceSource.TraceInfo(OutputFormat, "mscorlib AssemblyVersion:", typeof(object).Assembly.GetName().Version);
            RelayTraceSource.TraceInfo(OutputFormat, "mscorlib FileVersion:", FileVersionInfo.GetVersionInfo(typeof(object).Assembly.Location).FileVersion);

            if (!string.IsNullOrEmpty(namespaceDetails.ServiceNamespace))
            {
                await GetCloudServiceTimeAsync(namespaceDetails.ServiceNamespace);
            }

            var utcNow = DateTime.UtcNow;

            RelayTraceSource.TraceInfo(OutputFormat, "Machine Time(UTC):", utcNow.ToString(DateTimeFormatInfo.InvariantInfo.RFC1123Pattern));
            RelayTraceSource.TraceInfo(OutputFormat, "Machine Time(Local):", utcNow.ToLocalTime().ToString("ddd, dd MMM yyyy HH':'mm':'ss '('zzz')'")); // Like RFC1123Pattern but with zzz for timezone offset
        }
        internal static void ConfigureCommands(CommandLineApplication app)
        {
            app.RelayCommand("diag", (diagCommand) =>
            {
                diagCommand.Description = "Operations for diagnosing relay/hc issues (Analyze)";
                var namespaceOrConnectionStringArgument = diagCommand.Argument(NamespaceOrConnectionStringArgumentName, NamespaceOrConnectionStringArgumentDescription);

                CommandOption allOption = diagCommand.Option(
                    "-a|--all",
                    "Show all details",
                    CommandOptionType.NoValue);

                CommandOption namespaceOption = diagCommand.Option(
                    "-n|-ns|--namespace",
                    "Show namespace details",
                    CommandOptionType.NoValue);

                CommandOption netStatOption = diagCommand.Option(
                    "--netstat",
                    "Show netstat output",
                    CommandOptionType.NoValue);

                CommandOption portsOption = diagCommand.Option(
                    "-p|--ports",
                    "Probe Relay Ports",
                    CommandOptionType.NoValue);

                CommandOption instancePortsOption = diagCommand.Option(
                    "-ip|--instance-ports <instanceCount>",
                    "Probe Relay Instance Level Ports",
                    CommandOptionType.SingleValue);

                CommandOption osOption = diagCommand.Option(
                    "-o|--os",
                    "Display Platform/OS/.NET information",
                    CommandOptionType.NoValue);

                CommandOption protocolOption = diagCommand.AddSecurityProtocolOption();

                diagCommand.OnExecute(async() =>
                {
                    ConfigureSecurityProtocol(protocolOption);

                    bool defaultOptions = !allOption.HasValue() && !namespaceOption.HasValue() && !netStatOption.HasValue() &&
                                          !portsOption.HasValue() && !osOption.HasValue();

                    // Run netstat before we try to lookup the namespace to keep ourself out of the results
                    // NetStat output isn't part of the default run, must specify --netstat or --all
                    if (netStatOption.HasValue() || allOption.HasValue())
                    {
                        ExecuteNetStatCommand();
                    }

                    NamespaceDetails namespaceDetails = default;
                    string connectionString           = ConnectionStringUtility.ResolveConnectionString(namespaceOrConnectionStringArgument); // Might not be present
                    if (!string.IsNullOrEmpty(connectionString))
                    {
                        var connectionStringBuilder = new ServiceBusConnectionStringBuilder(connectionString);
                        try
                        {
                            namespaceDetails = await NamespaceUtility.GetNamespaceDetailsAsync(connectionStringBuilder.Endpoints.First().Host);
                        }
                        catch (Exception e)
                        {
                            RelayTraceSource.TraceException(e, "Getting namespace details");
                        }
                    }

                    if (defaultOptions || osOption.HasValue() || allOption.HasValue())
                    {
                        await ExecutePlatformCommandAsync(namespaceDetails);
                    }

                    if (defaultOptions || namespaceOption.HasValue() || allOption.HasValue())
                    {
                        ExecuteNamespaceCommand(namespaceDetails);
                    }

                    if (defaultOptions || portsOption.HasValue() || allOption.HasValue() || instancePortsOption.HasValue())
                    {
                        int gatewayCount = GetIntOption(instancePortsOption, 1);
                        await ExecutePortsCommandAsync(namespaceDetails, gatewayCount);
                    }

                    return(0);
                });
            });
        }