Add sane defaults to SetupWizard yes/no prompts

This commit is contained in:
Jordan Dominion
2023-06-25 21:32:10 -04:00
parent 3861d2db8d
commit 52fdaf3955
2 changed files with 59 additions and 22 deletions
+56 -19
View File
@@ -5,6 +5,7 @@ using System.Data.SqlClient;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
@@ -141,19 +142,29 @@ namespace Tgstation.Server.Host.Setup
/// A prompt for a yes or no value.
/// </summary>
/// <param name="question">The question <see cref="string"/>.</param>
/// <param name="defaultResponse">The optional default response if the user doesn't enter anything.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task"/> resulting in <see langword="true"/> if the user replied yes, <see langword="false"/> otherwise.</returns>
async Task<bool> PromptYesNo(string question, CancellationToken cancellationToken)
async Task<bool> PromptYesNo(string question, bool? defaultResponse, CancellationToken cancellationToken)
{
do
{
await console.WriteAsync(question, false, cancellationToken);
await console.WriteAsync($"{question} ({(defaultResponse == true ? 'Y' : 'y')}/{(defaultResponse == false ? 'N' : 'n')}): ", false, cancellationToken);
var responseString = await console.ReadLineAsync(false, cancellationToken);
var upperResponse = responseString.ToUpperInvariant();
if (upperResponse == "Y" || upperResponse == "YES")
return true;
else if (upperResponse == "N" || upperResponse == "NO")
return false;
if (responseString.Length == 0)
{
if (defaultResponse.HasValue)
return defaultResponse.Value;
}
else
{
var upperResponse = responseString.ToUpperInvariant();
if (upperResponse == "Y" || upperResponse == "YES")
return true;
else if (upperResponse == "N" || upperResponse == "NO")
return false;
}
await console.WriteAsync("Invalid response!", true, cancellationToken);
}
while (true);
@@ -316,7 +327,8 @@ namespace Tgstation.Server.Host.Setup
await console.WriteAsync("Note, this relative path (currently) resolves to the following:", true, cancellationToken);
await console.WriteAsync(resolvedPath, true, cancellationToken);
bool writeResolved = await PromptYesNo(
"Would you like to save the relative path in the configuration? If not, the full path will be saved. (y/n): ",
"Would you like to save the relative path in the configuration? If not, the full path will be saved.",
null,
cancellationToken);
if (writeResolved)
@@ -405,6 +417,7 @@ namespace Tgstation.Server.Host.Setup
ushort? serverPort = null;
bool isSqliteDB = databaseConfiguration.DatabaseType == DatabaseType.Sqlite;
IPHostEntry serverAddressEntry = null;
if (!isSqliteDB)
do
{
@@ -430,7 +443,20 @@ namespace Tgstation.Server.Host.Setup
}
}
break;
try
{
if (serverAddress != null)
{
await console.WriteAsync("Attempting to resolve address...", true, cancellationToken);
serverAddressEntry = await Dns.GetHostEntryAsync(serverAddress, cancellationToken);
}
break;
}
catch (Exception ex)
{
await console.WriteAsync($"Unable to resolve address: {ex.Message}", true, cancellationToken);
}
}
while (true);
@@ -451,7 +477,10 @@ namespace Tgstation.Server.Host.Setup
databaseName = await ValidateNonExistantSqliteDBName(databaseName, cancellationToken);
}
else
dbExists = await PromptYesNo("Does this database already exist? If not, we will attempt to CREATE it. (y/n): ", cancellationToken);
dbExists = await PromptYesNo(
"Does this database already exist? If not, we will attempt to CREATE it.",
null,
cancellationToken);
}
if (String.IsNullOrWhiteSpace(databaseName))
@@ -463,7 +492,12 @@ namespace Tgstation.Server.Host.Setup
bool useWinAuth;
if (databaseConfiguration.DatabaseType == DatabaseType.SqlServer && platformIdentifier.IsWindows)
useWinAuth = await PromptYesNo("Use Windows Authentication? (y/n): ", cancellationToken);
{
var defaultResponse = serverAddressEntry.AddressList.Any(IPAddress.IsLoopback)
? (bool?)true
: null;
useWinAuth = await PromptYesNo("Use Windows Authentication?", defaultResponse, cancellationToken);
}
else
useWinAuth = false;
@@ -648,7 +682,7 @@ namespace Tgstation.Server.Host.Setup
if (String.IsNullOrWhiteSpace(newGeneralConfiguration.GitHubAccessToken))
newGeneralConfiguration.GitHubAccessToken = null;
newGeneralConfiguration.HostApiDocumentation = await PromptYesNo("Host API Documentation? (y/n): ", cancellationToken);
newGeneralConfiguration.HostApiDocumentation = await PromptYesNo("Host API Documentation?", false, cancellationToken);
return newGeneralConfiguration;
}
@@ -662,7 +696,7 @@ namespace Tgstation.Server.Host.Setup
{
var fileLoggingConfiguration = new FileLoggingConfiguration();
await console.WriteAsync(null, true, cancellationToken);
fileLoggingConfiguration.Disable = !await PromptYesNo("Enable file logging? (y/n): ", cancellationToken);
fileLoggingConfiguration.Disable = !await PromptYesNo("Enable file logging?", true, cancellationToken);
if (!fileLoggingConfiguration.Disable)
{
@@ -747,7 +781,7 @@ namespace Tgstation.Server.Host.Setup
{
var elasticsearchConfiguration = new ElasticsearchConfiguration();
await console.WriteAsync(null, true, cancellationToken);
elasticsearchConfiguration.Enable = await PromptYesNo("Enable logging to an external ElasticSearch server? (y/n): ", cancellationToken);
elasticsearchConfiguration.Enable = await PromptYesNo("Enable logging to an external ElasticSearch server?", false, cancellationToken);
if (elasticsearchConfiguration.Enable)
{
@@ -797,8 +831,11 @@ namespace Tgstation.Server.Host.Setup
{
var config = new ControlPanelConfiguration
{
Enable = await PromptYesNo("Enable the web control panel? (y/n): ", cancellationToken),
AllowAnyOrigin = await PromptYesNo("Allow web control panels hosted elsewhere to access the server? (Access-Control-Allow-Origin: *) (y/n): ", cancellationToken),
Enable = await PromptYesNo("Enable the web control panel?", true, cancellationToken),
AllowAnyOrigin = await PromptYesNo(
"Allow web control panels hosted elsewhere to access the server? (Access-Control-Allow-Origin: *)",
true,
cancellationToken),
};
if (!config.AllowAnyOrigin)
@@ -822,7 +859,7 @@ namespace Tgstation.Server.Host.Setup
/// <returns>A <see cref="Task{TResult}"/> resulting in the new <see cref="SwarmConfiguration"/>.</returns>
async Task<SwarmConfiguration> ConfigureSwarm(CancellationToken cancellationToken)
{
var enable = await PromptYesNo("Enable swarm mode? (y/n): ", cancellationToken);
var enable = await PromptYesNo("Enable swarm mode?", false, cancellationToken);
if (!enable)
return null;
@@ -860,7 +897,7 @@ namespace Tgstation.Server.Host.Setup
}
while (String.IsNullOrWhiteSpace(privateKey));
var controller = await PromptYesNo("Is this server the swarm's controller? (y/n): ", cancellationToken);
var controller = await PromptYesNo("Is this server the swarm's controller? (y/n): ", null, cancellationToken);
Uri controllerAddress = null;
if (!controller)
controllerAddress = await ParseAddress("Enter the swarm controller's HTTP(S) address: ");
@@ -1065,7 +1102,7 @@ namespace Tgstation.Server.Host.Setup
{
await console.WriteAsync(String.Format(CultureInfo.InvariantCulture, "The configuration settings are requesting the setup wizard be run, but you already appear to have a configuration file ({0})!", userConfigFileName), true, cancellationToken);
forceRun = await PromptYesNo("Continue running setup wizard? (y/n): ", cancellationToken);
forceRun = await PromptYesNo("Continue running setup wizard?", false, cancellationToken);
}
if (!forceRun)
@@ -152,14 +152,14 @@ namespace Tgstation.Server.Host.Setup.Tests
"666",
"FakeDBType",
nameof(DatabaseType.SqlServer),
"this isn't validated",
"localhost",
"nor is this",
"no",
//test winauth
"yes",
//sql server will always fail so reconfigure with maria
nameof(DatabaseType.MariaDB),
"bleh",
"127.0.0.1",
"blah",
"NO",
"user",
@@ -187,7 +187,7 @@ namespace Tgstation.Server.Host.Setup.Tests
String.Empty,
//test MySQL errors
nameof(DatabaseType.MySql),
String.Empty,
"::1",
String.Empty,
"DbName",
"n",