refactor: rename ScadaLink → ZB.MOM.WW.ScadaBridge (code + projects + namespaces)

Solution + 23 src projects + 26 test projects renamed; folders, csproj,
namespaces, and ScadaLinkDbContext/ScadaBridgeDbContext class updated.
ActorSystem "scadalink" → "scadabridge", Akka seed-node URLs migrated.
SQL roles/logins, LDAP domains, CLI command name, and CLI config dir
(~/.scadalink → ~/.scadabridge) also renamed.

Build green; 5 Host.Tests fail awaiting SQL login rename in next commit.
Pre-existing StaleTagMonitor timing flakes unchanged.

Rename script committed at tools/rename-to-scadabridge.sh.
This commit is contained in:
Joseph Doherty
2026-05-28 09:37:45 -04:00
parent 6d87ee3c3b
commit 7b0b9c7365
1531 changed files with 11180 additions and 11054 deletions
@@ -0,0 +1,190 @@
using System.CommandLine;
using System.CommandLine.Parsing;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
public static class NotificationCommands
{
/// <summary>
/// Builds the <c>notification</c> command group with sub-commands for managing notification lists and SMTP configuration.
/// </summary>
/// <param name="urlOption">Global <c>--url</c> option for the management API endpoint.</param>
/// <param name="formatOption">Global <c>--format</c> option for output format.</param>
/// <param name="usernameOption">Global <c>--username</c> option for authentication.</param>
/// <param name="passwordOption">Global <c>--password</c> option for authentication.</param>
public static Command Build(Option<string> urlOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
{
var command = new Command("notification") { Description = "Manage notification lists" };
command.Add(BuildList(urlOption, formatOption, usernameOption, passwordOption));
command.Add(BuildGet(urlOption, formatOption, usernameOption, passwordOption));
command.Add(BuildCreate(urlOption, formatOption, usernameOption, passwordOption));
command.Add(BuildUpdate(urlOption, formatOption, usernameOption, passwordOption));
command.Add(BuildDelete(urlOption, formatOption, usernameOption, passwordOption));
command.Add(BuildSmtp(urlOption, formatOption, usernameOption, passwordOption));
return command;
}
private static Command BuildGet(Option<string> urlOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
{
var idOption = new Option<int>("--id") { Description = "Notification list ID", Required = true };
var cmd = new Command("get") { Description = "Get a notification list by ID" };
cmd.Add(idOption);
cmd.SetAction(async (ParseResult result) =>
{
var id = result.GetValue(idOption);
return await CommandHelpers.ExecuteCommandAsync(
result, urlOption, formatOption, usernameOption, passwordOption, new GetNotificationListCommand(id));
});
return cmd;
}
private static Command BuildUpdate(Option<string> urlOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
{
var idOption = new Option<int>("--id") { Description = "Notification list ID", Required = true };
var nameOption = new Option<string>("--name") { Description = "List name", Required = true };
var emailsOption = new Option<string>("--emails") { Description = "Comma-separated recipient emails", Required = true };
var cmd = new Command("update") { Description = "Update a notification list" };
cmd.Add(idOption);
cmd.Add(nameOption);
cmd.Add(emailsOption);
cmd.SetAction(async (ParseResult result) =>
{
var id = result.GetValue(idOption);
var name = result.GetValue(nameOption)!;
var emailsRaw = result.GetValue(emailsOption)!;
var emails = emailsRaw.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).ToList();
return await CommandHelpers.ExecuteCommandAsync(
result, urlOption, formatOption, usernameOption, passwordOption,
new UpdateNotificationListCommand(id, name, emails));
});
return cmd;
}
private static Command BuildSmtp(Option<string> urlOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
{
var group = new Command("smtp") { Description = "Manage SMTP configuration" };
var listCmd = new Command("list") { Description = "List SMTP configurations" };
listCmd.SetAction(async (ParseResult result) =>
{
return await CommandHelpers.ExecuteCommandAsync(
result, urlOption, formatOption, usernameOption, passwordOption, new ListSmtpConfigsCommand());
});
group.Add(listCmd);
var updateCmd = new Command("update") { Description = "Update SMTP configuration" };
updateCmd.Add(SmtpIdOption);
updateCmd.Add(SmtpServerOption);
updateCmd.Add(SmtpPortOption);
updateCmd.Add(SmtpAuthModeOption);
updateCmd.Add(SmtpFromOption);
updateCmd.Add(SmtpTlsModeOption);
updateCmd.Add(SmtpCredentialsOption);
updateCmd.SetAction(async (ParseResult result) =>
{
return await CommandHelpers.ExecuteCommandAsync(
result, urlOption, formatOption, usernameOption, passwordOption,
BuildUpdateSmtpConfigCommand(result));
});
group.Add(updateCmd);
return group;
}
// SMTP update options are static so the parsed values can be read back both
// from the SetAction and from BuildUpdateSmtpConfigCommand (used by tests).
private static readonly Option<int> SmtpIdOption =
new("--id") { Description = "SMTP config ID", Required = true };
private static readonly Option<string> SmtpServerOption =
new("--server") { Description = "SMTP server", Required = true };
private static readonly Option<int> SmtpPortOption =
new("--port") { Description = "SMTP port", Required = true };
private static readonly Option<string> SmtpAuthModeOption =
new("--auth-mode") { Description = "Auth mode", Required = true };
private static readonly Option<string> SmtpFromOption =
new("--from-address") { Description = "From email address", Required = true };
private static readonly Option<string?> SmtpTlsModeOption = CreateTlsModeOption();
private static readonly Option<string?> SmtpCredentialsOption =
new("--credentials")
{
Description = "SMTP credentials — 'username:password' for Basic, or client secret " +
"for OAuth2 (optional; preserves existing if omitted)",
};
private static Option<string?> CreateTlsModeOption()
{
var option = new Option<string?>("--tls-mode")
{
Description = "TLS mode: None, StartTLS, or SSL (optional; preserves existing if omitted)",
};
option.AcceptOnlyFromAmong("None", "StartTLS", "SSL");
return option;
}
/// <summary>
/// Builds the <see cref="UpdateSmtpConfigCommand"/> from a parsed <c>smtp update</c>
/// invocation. The optional <c>--tls-mode</c> / <c>--credentials</c> flags map to
/// null when omitted so the server-side handler preserves the existing values.
/// </summary>
/// <param name="result">The parsed command-line result from the <c>smtp update</c> invocation.</param>
internal static UpdateSmtpConfigCommand BuildUpdateSmtpConfigCommand(ParseResult result)
{
var id = result.GetValue(SmtpIdOption);
var server = result.GetValue(SmtpServerOption)!;
var port = result.GetValue(SmtpPortOption);
var authMode = result.GetValue(SmtpAuthModeOption)!;
var from = result.GetValue(SmtpFromOption)!;
var tlsMode = result.GetValue(SmtpTlsModeOption);
var credentials = result.GetValue(SmtpCredentialsOption);
return new UpdateSmtpConfigCommand(id, server, port, authMode, from, tlsMode, credentials);
}
private static Command BuildList(Option<string> urlOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
{
var cmd = new Command("list") { Description = "List all notification lists" };
cmd.SetAction(async (ParseResult result) =>
{
return await CommandHelpers.ExecuteCommandAsync(
result, urlOption, formatOption, usernameOption, passwordOption, new ListNotificationListsCommand());
});
return cmd;
}
private static Command BuildCreate(Option<string> urlOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
{
var nameOption = new Option<string>("--name") { Description = "Notification list name", Required = true };
var emailsOption = new Option<string>("--emails") { Description = "Comma-separated recipient emails", Required = true };
var cmd = new Command("create") { Description = "Create a notification list" };
cmd.Add(nameOption);
cmd.Add(emailsOption);
cmd.SetAction(async (ParseResult result) =>
{
var name = result.GetValue(nameOption)!;
var emailsRaw = result.GetValue(emailsOption)!;
var emails = emailsRaw.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).ToList();
return await CommandHelpers.ExecuteCommandAsync(
result, urlOption, formatOption, usernameOption, passwordOption,
new CreateNotificationListCommand(name, emails));
});
return cmd;
}
private static Command BuildDelete(Option<string> urlOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
{
var idOption = new Option<int>("--id") { Description = "Notification list ID", Required = true };
var cmd = new Command("delete") { Description = "Delete a notification list" };
cmd.Add(idOption);
cmd.SetAction(async (ParseResult result) =>
{
var id = result.GetValue(idOption);
return await CommandHelpers.ExecuteCommandAsync(
result, urlOption, formatOption, usernameOption, passwordOption, new DeleteNotificationListCommand(id));
});
return cmd;
}
}