first commit
This commit is contained in:
134
Tui/KeyManagerTui.cs
Normal file
134
Tui/KeyManagerTui.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
using HanaToolbox.Config;
|
||||
using HanaToolbox.Logging;
|
||||
using HanaToolbox.Services;
|
||||
using HanaToolbox.Services.Interfaces;
|
||||
using Spectre.Console;
|
||||
|
||||
namespace HanaToolbox.Tui;
|
||||
|
||||
/// <summary>
|
||||
/// Interactive TUI for managing hdbuserstore keys.
|
||||
/// Mirrors keymanager.sh flow: Create / Delete / Test.
|
||||
/// </summary>
|
||||
public sealed class KeyManagerTui(
|
||||
KeyManagerService keyService,
|
||||
IHdbClientLocator locator,
|
||||
AppLogger _logger)
|
||||
{
|
||||
public async Task RunAsync(HanaConfig hana, string sid, CancellationToken ct = default)
|
||||
{
|
||||
var hdbsql = locator.LocateHdbsql(hana.HdbsqlPath, sid, hana.InstanceNumber);
|
||||
|
||||
while (true)
|
||||
{
|
||||
AnsiConsole.Clear();
|
||||
AnsiConsole.Write(new Rule("[blue]SAP HANA Secure User Store Key Manager[/]").RuleStyle("blue"));
|
||||
AnsiConsole.WriteLine();
|
||||
|
||||
var choice = AnsiConsole.Prompt(
|
||||
new SelectionPrompt<string>()
|
||||
.Title("Select an action:")
|
||||
.AddChoices("Create a New Key", "Delete an Existing Key",
|
||||
"Test an Existing Key", "Exit")
|
||||
.HighlightStyle("cyan"));
|
||||
|
||||
switch (choice)
|
||||
{
|
||||
case "Create a New Key":
|
||||
await CreateKeyAsync(hdbsql, hana, sid, ct);
|
||||
break;
|
||||
case "Delete an Existing Key":
|
||||
await DeleteKeyAsync(sid, ct);
|
||||
break;
|
||||
case "Test an Existing Key":
|
||||
await TestKeyAsync(hdbsql, sid, ct);
|
||||
break;
|
||||
case "Exit":
|
||||
return;
|
||||
}
|
||||
|
||||
AnsiConsole.MarkupLine("\n[grey]Press any key to continue...[/]");
|
||||
Console.ReadKey(intercept: true);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CreateKeyAsync(
|
||||
string hdbsql, HanaConfig hana, string sid, CancellationToken ct)
|
||||
{
|
||||
AnsiConsole.Write(new Rule("[blue]Create New Key[/]").RuleStyle("blue"));
|
||||
|
||||
var keyName = AnsiConsole.Prompt(new TextPrompt<string>("Key name:").DefaultValue("CRONKEY"));
|
||||
var host = AnsiConsole.Prompt(new TextPrompt<string>("HANA host:").DefaultValue(System.Net.Dns.GetHostName()));
|
||||
var instance = AnsiConsole.Prompt(new TextPrompt<string>("Instance number:").DefaultValue(hana.InstanceNumber));
|
||||
var isSystemDb = AnsiConsole.Confirm("Connecting to SYSTEMDB?", defaultValue: false);
|
||||
|
||||
string connStr;
|
||||
if (isSystemDb)
|
||||
{
|
||||
connStr = $"{host}:3{instance}13";
|
||||
}
|
||||
else
|
||||
{
|
||||
var tenant = AnsiConsole.Prompt(new TextPrompt<string>("Tenant DB name:").DefaultValue(sid.ToUpperInvariant()));
|
||||
connStr = $"{host}:3{instance}15@{tenant}";
|
||||
}
|
||||
|
||||
var user = AnsiConsole.Prompt(new TextPrompt<string>("Database user:").DefaultValue("SYSTEM"));
|
||||
var pass = AnsiConsole.Prompt(new TextPrompt<string>("Password:").Secret());
|
||||
|
||||
AnsiConsole.MarkupLine($"\n[yellow]Command preview:[/] hdbuserstore SET \"{keyName}\" \"{connStr}\" \"{user}\" <password>");
|
||||
if (!AnsiConsole.Confirm("Execute?", defaultValue: true)) return;
|
||||
|
||||
var created = await keyService.CreateKeyAsync(keyName, connStr, user, pass, sid, ct);
|
||||
if (!created) return;
|
||||
|
||||
// Auto-test and rollback on failure
|
||||
var ok = await keyService.TestKeyAsync(hdbsql, keyName, sid, ct);
|
||||
if (!ok)
|
||||
{
|
||||
AnsiConsole.MarkupLine("[yellow]Rolling back: deleting key due to connection failure...[/]");
|
||||
await keyService.DeleteKeyAsync(keyName, sid, ct);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DeleteKeyAsync(string sid, CancellationToken ct)
|
||||
{
|
||||
AnsiConsole.Write(new Rule("[red]Delete Key[/]").RuleStyle("red"));
|
||||
|
||||
var keys = await keyService.ListKeysAsync(sid, ct);
|
||||
if (keys.Count == 0)
|
||||
{
|
||||
AnsiConsole.MarkupLine("[yellow]No keys found.[/]");
|
||||
return;
|
||||
}
|
||||
|
||||
var key = AnsiConsole.Prompt(
|
||||
new SelectionPrompt<string>()
|
||||
.Title("Select key to delete:")
|
||||
.AddChoices(keys)
|
||||
.HighlightStyle("red"));
|
||||
|
||||
if (!AnsiConsole.Confirm($"Permanently delete '{key}'?", defaultValue: false)) return;
|
||||
await keyService.DeleteKeyAsync(key, sid, ct);
|
||||
}
|
||||
|
||||
private async Task TestKeyAsync(string hdbsql, string sid, CancellationToken ct)
|
||||
{
|
||||
AnsiConsole.Write(new Rule("[blue]Test Key[/]").RuleStyle("blue"));
|
||||
|
||||
var keys = await keyService.ListKeysAsync(sid, ct);
|
||||
if (keys.Count == 0)
|
||||
{
|
||||
AnsiConsole.MarkupLine("[yellow]No keys found.[/]");
|
||||
return;
|
||||
}
|
||||
|
||||
var key = AnsiConsole.Prompt(
|
||||
new SelectionPrompt<string>()
|
||||
.Title("Select key to test:")
|
||||
.AddChoices(keys)
|
||||
.HighlightStyle("cyan"));
|
||||
|
||||
await keyService.TestKeyAsync(hdbsql, key, sid, ct);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user