Ejemplo n.º 1
0
        static int MainCore(string[] args)
        {
            var app = new CommandLineApplication();

            app.Name        = nameof(RelayUtil);
            app.Description = "Azure Relay Utility Commands";
            RelayCommands.CommonSetup(app);

            try
            {
                app.OnExecute(() =>
                {
                    app.ShowHelp();
                    return(0);
                });

                DiagnosticCommands.ConfigureCommands(app);
                WcfRelayCommands.ConfigureCommands(app);
                HybridConnectionCommands.ConfigureCommands(app);
                SharedAccessSignatureCommands.ConfigureCommands(app);

                return(app.Execute(args));
            }
            catch (Exception exception)
            {
                RelayTraceSource.TraceException(exception);
                return(exception.HResult);
            }
        }
Ejemplo n.º 2
0
        internal static int ReportTestResults(List <TestResult> testResults)
        {
            IEnumerable <string> passedTests = testResults.Where(r => r.Passed).Select(r => r.TestName);
            IEnumerable <string> failedTests = testResults.Where(r => !r.Passed).Select(r => r.TestName);

            int passCount = 0;

            foreach (var passedTest in passedTests)
            {
                RelayTraceSource.TraceEvent(TraceEventType.Information, ConsoleColor.Green, $"PASSED: {passedTest}");
                passCount++;
            }

            if (passCount > 0)
            {
                RelayTraceSource.TraceEvent(TraceEventType.Information, ConsoleColor.Green, $"{passCount} tests passed.");
            }

            int failCount = 0;

            foreach (var failedTest in failedTests)
            {
                RelayTraceSource.TraceEvent(TraceEventType.Error, ConsoleColor.Red, $"FAILED: {failedTest}");
                failCount++;
            }

            if (failCount > 0)
            {
                RelayTraceSource.TraceEvent(TraceEventType.Error, ConsoleColor.Red, $"{failCount} tests failed");
            }

            return(failCount);
        }
Ejemplo n.º 3
0
        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);
            }
        }
Ejemplo n.º 4
0
        internal static async Task RunTestAsync(string testName, Regex testNameRegex, IList <TestResult> testResults, Func <Task> testFunc)
        {
            if (testNameRegex != null && !testNameRegex.IsMatch(testName))
            {
                // Filter specified and test name doesn't match
                return;
            }

            TraceCommandHeader(testName);
            try
            {
                await testFunc();

                testResults.Add(new TestResult {
                    Passed = true, TestName = testName
                });
            }
            catch (Exception exception)
            {
                RelayTraceSource.TraceException(exception, testName);
                testResults.Add(new TestResult {
                    Passed = false, TestName = testName
                });
            }
        }
Ejemplo n.º 5
0
        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);
            }
        }
Ejemplo n.º 6
0
        static void ConfigureListCommand(CommandLineApplication hcCommand)
        {
            hcCommand.RelayCommand("list", (listCmd) =>
            {
                listCmd.Description          = "List HybridConnection(s)";
                var connectionStringArgument = listCmd.Argument("connectionString", "Relay ConnectionString");

                listCmd.OnExecute(async() =>
                {
                    string connectionString = ConnectionStringUtility.ResolveConnectionString(connectionStringArgument);
                    if (string.IsNullOrEmpty(connectionString))
                    {
                        TraceMissingArgument(connectionStringArgument.Name);
                        listCmd.ShowHelp();
                        return(1);
                    }

                    var connectionStringBuilder = new RelayConnectionStringBuilder(connectionString);
                    RelayTraceSource.TraceInfo($"Listing HybridConnections for {connectionStringBuilder.Endpoint.Host}");
                    RelayTraceSource.TraceInfo($"{"Path",-38} {"ListenerCount",-15} {"RequiresClientAuth",-20}");
                    var namespaceManager = new RelayNamespaceManager(connectionString);
                    IEnumerable <HybridConnectionDescription> hybridConnections = await namespaceManager.GetHybridConnectionsAsync();
                    foreach (var hybridConnection in hybridConnections)
                    {
                        RelayTraceSource.TraceInfo($"{hybridConnection.Path,-38} {hybridConnection.ListenerCount,-15} {hybridConnection.RequiresClientAuthorization}");
                    }

                    return(0);
                });
            });
        }
Ejemplo n.º 7
0
        static void ConfigureCreateCommand(CommandLineApplication hcCommand)
        {
            hcCommand.RelayCommand("create", (createCmd) =>
            {
                createCmd.Description = "Create a HybridConnection";

                var pathArgument             = createCmd.Argument("path", "HybridConnection path");
                var connectionStringArgument = createCmd.Argument("connectionString", "Relay ConnectionString");

                var requireClientAuthOption = createCmd.Option(
                    CommandStrings.RequiresClientAuthTemplate, CommandStrings.RequiresClientAuthDescription, CommandOptionType.SingleValue);

                createCmd.OnExecute(async() =>
                {
                    string connectionString = ConnectionStringUtility.ResolveConnectionString(connectionStringArgument);
                    if (string.IsNullOrEmpty(connectionString) || string.IsNullOrEmpty(pathArgument.Value))
                    {
                        TraceMissingArgument(string.IsNullOrEmpty(connectionString) ? connectionStringArgument.Name : pathArgument.Name);
                        createCmd.ShowHelp();
                        return(1);
                    }

                    var connectionStringBuilder = new RelayConnectionStringBuilder(connectionString);
                    RelayTraceSource.TraceInfo($"Creating HybridConnection '{pathArgument.Value}' in {connectionStringBuilder.Endpoint.Host}...");
                    var hcDescription = new HybridConnectionDescription(pathArgument.Value);
                    hcDescription.RequiresClientAuthorization = GetBoolOption(requireClientAuthOption, true);
                    var namespaceManager = new RelayNamespaceManager(connectionString);
                    await namespaceManager.CreateHybridConnectionAsync(hcDescription);
                    RelayTraceSource.TraceInfo($"Creating HybridConnection '{pathArgument.Value}' in {connectionStringBuilder.Endpoint.Host} succeeded");
                    return(0);
                });
            });
        }
Ejemplo n.º 8
0
        static void ConfigureCountCommand(CommandLineApplication hcCommand)
        {
            hcCommand.RelayCommand("count", (countCommand) =>
            {
                countCommand.Description = "Get HybridConnection Count";

                var connectionStringArgument = countCommand.Argument("connectionString", "Relay ConnectionString");

                countCommand.OnExecute(async() =>
                {
                    string connectionString = ConnectionStringUtility.ResolveConnectionString(connectionStringArgument);
                    if (string.IsNullOrEmpty(connectionString))
                    {
                        TraceMissingArgument(connectionStringArgument.Name);
                        countCommand.ShowHelp();
                        return(1);
                    }

                    var namespaceManager = Microsoft.ServiceBus.NamespaceManager.CreateFromConnectionString(connectionString);
                    Uri namespaceUri     = namespaceManager.Address;
                    string namespaceHost = namespaceUri.Host;
                    var tokenProvider    = namespaceManager.Settings.TokenProvider;

                    RelayTraceSource.TraceVerbose($"Getting HybridConnection count for '{namespaceUri}");

                    int count = await NamespaceUtility.GetEntityCountAsync(namespaceUri, tokenProvider, "HybridConnections");
                    RelayTraceSource.TraceInfo(string.Format($"{{0,-{namespaceHost.Length}}}  {{1}}", "Namespace", "HybridConnectionCount"));
                    RelayTraceSource.TraceInfo(string.Format($"{{0,-{namespaceHost.Length}}}  {{1}}", namespaceHost, count));

                    return(0);
                });
            });
        }
Ejemplo n.º 9
0
        static void ConfigureDeleteCommand(CommandLineApplication hcCommand)
        {
            hcCommand.RelayCommand("delete", (deleteCmd) =>
            {
                deleteCmd.Description        = "Delete a HybridConnection";
                var pathArgument             = deleteCmd.Argument("path", "HybridConnection path");
                var connectionStringArgument = deleteCmd.Argument("connectionString", "Relay ConnectionString");

                deleteCmd.OnExecute(async() =>
                {
                    string connectionString = ConnectionStringUtility.ResolveConnectionString(connectionStringArgument);
                    if (string.IsNullOrEmpty(connectionString) || string.IsNullOrEmpty(pathArgument.Value))
                    {
                        TraceMissingArgument(string.IsNullOrEmpty(connectionString) ? connectionStringArgument.Name : pathArgument.Name);
                        deleteCmd.ShowHelp();
                        return(1);
                    }

                    var connectionStringBuilder = new RelayConnectionStringBuilder(connectionString);
                    RelayTraceSource.TraceInfo($"Deleting HybridConnection '{pathArgument.Value}' in {connectionStringBuilder.Endpoint.Host}...");
                    var namespaceManager = new RelayNamespaceManager(connectionString);
                    await namespaceManager.DeleteHybridConnectionAsync(pathArgument.Value);
                    RelayTraceSource.TraceInfo($"Deleting HybridConnection '{pathArgument.Value}' in {connectionStringBuilder.Endpoint.Host} succeeded");
                    return(0);
                });
            });
        }
        static void ConfigureCreateCommand(CommandLineApplication sasCommand)
        {
            sasCommand.RelayCommand("create", (createCmd) =>
            {
                createCmd.Description = "Create a Sas Token";

                var pathArgument             = createCmd.Argument("path", "Entity path");
                var connectionStringArgument = createCmd.Argument("connectionString", "The ConnectionString to use");

                createCmd.OnExecute(async() =>
                {
                    string connectionString = ConnectionStringUtility.ResolveConnectionString(connectionStringArgument);
                    if (string.IsNullOrEmpty(connectionString))
                    {
                        TraceMissingArgument(connectionStringArgument.Name);
                        createCmd.ShowHelp();
                        return(1);
                    }

                    var namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);

                    var audience = new UriBuilder(namespaceManager.Address);
                    if (!string.IsNullOrEmpty(pathArgument.Value))
                    {
                        audience.Path = pathArgument.Value;
                    }

                    string token = await namespaceManager.Settings.TokenProvider.GetWebTokenAsync(audience.Uri.AbsoluteUri, string.Empty, true, TimeSpan.FromMinutes(20));
                    RelayTraceSource.TraceInfo($"Token:\r\n{token}");
                    return(0);
                });
            });
        }
Ejemplo n.º 11
0
 static void ExecuteNetStatCommand()
 {
     TraceCommandHeader("NetStat.exe");
     ExecuteProcess(
         "netstat.exe",
         "-ano -p tcp",
         TimeSpan.FromSeconds(30),
         (s) => RelayTraceSource.TraceInfo(s),
         (s) => RelayTraceSource.TraceError("ERROR: " + s),
         throwOnNonZero: true);
 }
Ejemplo n.º 12
0
        static void SetServicePointManagerDefaultSslProtocols(SslProtocols sslProtocols)
        {
            FieldInfo s_defaultSslProtocols = typeof(ServicePointManager).GetField("s_defaultSslProtocols", BindingFlags.Static | BindingFlags.NonPublic);

            if (s_defaultSslProtocols != null)
            {
                s_defaultSslProtocols.SetValue(null, sslProtocols);
            }
            else
            {
                RelayTraceSource.TraceWarning("ServicePointManager.s_defaultSslProtocols field not found.");
            }
        }
Ejemplo n.º 13
0
 static async Task GetCloudServiceTimeAsync(string serviceNamespace)
 {
     try
     {
         var webRequest = WebRequest.CreateHttp(new Uri($"https://{serviceNamespace}"));
         webRequest.Method = "GET";
         using (var response = await webRequest.GetResponseAsync())
         {
             RelayTraceSource.TraceInfo(OutputFormat, "Azure Time:", response.Headers["Date"]); // RFC1123
         }
     }
     catch (Exception exception)
     {
         RelayTraceSource.TraceException(exception, "Getting current time from Relay cloud service");
     }
 }
Ejemplo n.º 14
0
        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
        }
Ejemplo n.º 15
0
 public static void TraceMissingArgument(string argumentName)
 {
     RelayTraceSource.TraceError($"*** Error: {argumentName} is required ***");
 }
Ejemplo n.º 16
0
        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);
                });
            });
        }