Some checks failed
deploy community / deploy (push) Successful in 1s
deploy hub / deploy (push) Successful in 19s
CI / Build og unit tests (push) Successful in 8s
CI / MSI-installer (push) Successful in 15s
CI / Integration (mcr.microsoft.com/mssql/server:2017-latest) (push) Has been cancelled
CI / Integration (mcr.microsoft.com/mssql/server:2019-latest) (push) Has been cancelled
CI / Integration (mcr.microsoft.com/mssql/server:2022-latest) (push) Has been cancelled
CI / Integration (mcr.microsoft.com/mssql/server:2025-latest) (push) Has been cancelled
Entering a connection string in the installer is now enough: the new command `SQLInsight.Agent.exe setup-repository` runs as a deferred custom action after the services exist and sqlinsight.ini is written, and before they start. It runs as the installing user on purpose (SQL Server must see a person with rights, not SYSTEM) and: - creates the database from Database=... if it is missing - creates logins/users for the service accounts: agent db_owner, web db_datareader. NT SERVICE\... accounts arrive at another computer as DOMAIN\COMPUTER$, which then gets the login instead - runs the schema migrations - with MONITOR_SERVER: creates the agent's login there and applies grant-least-privilege.sql (embedded). A failure there is a warning only A repository failure stops the installation; the reason goes to the Application event log with a Danish hint (login, rights, certificate, unreachable). SKIP_REPOSITORY_SETUP=1 leaves it to a DBA. Safe to rerun. verify-msi.py allows this one action to impersonate and checks its placement, Return=check and condition. Tested against a local SQL Express (twice, idempotent) and with an unreachable server. Version 1.0.1. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
49 lines
1.9 KiB
C#
49 lines
1.9 KiB
C#
using SQLInsight.Agent.Setup;
|
|
|
|
namespace SQLInsight.Agent.Tests;
|
|
|
|
public sealed class RepositorySetupTests
|
|
{
|
|
[Theory]
|
|
[InlineData(".")]
|
|
[InlineData(@".\SQLEXPRESS")]
|
|
[InlineData("(local)")]
|
|
[InlineData("localhost,1433")]
|
|
[InlineData(@"tcp:localhost\SQLEXPRESS")]
|
|
[InlineData("SQLMON01")]
|
|
[InlineData(@"sqlmon01\SQLEXPRESS")]
|
|
[InlineData("sqlmon01.kunde.local,1433")]
|
|
public void Recognises_this_computer(string server) => Assert.True(RepositorySetup.IsLocal(server, "SQLMON01"));
|
|
|
|
[Theory]
|
|
[InlineData("sql02")]
|
|
[InlineData(@"sql02\PROD")]
|
|
[InlineData("sqlmon011")]
|
|
[InlineData("tcp:10.0.0.5,1433")]
|
|
public void Recognises_other_computers(string server) => Assert.False(RepositorySetup.IsLocal(server, "SQLMON01"));
|
|
|
|
[Fact]
|
|
public void Virtual_account_keeps_its_name_on_the_same_computer() =>
|
|
Assert.Equal(@"NT SERVICE\SQLInsight Agent", RepositorySetup.LoginFor(@"NT SERVICE\SQLInsight Agent", @".\SQLEXPRESS", "SQLMON01", "KUNDE"));
|
|
|
|
[Theory]
|
|
[InlineData(@"NT SERVICE\SQLInsight Agent")]
|
|
[InlineData(@"NT AUTHORITY\NETWORK SERVICE")]
|
|
[InlineData("LocalSystem")]
|
|
public void Machine_accounts_arrive_as_the_computer_account_on_another_server(string account) =>
|
|
Assert.Equal(@"KUNDE\SQLMON01$", RepositorySetup.LoginFor(account, "sql02", "SQLMON01", "KUNDE"));
|
|
|
|
[Fact]
|
|
public void Domain_accounts_and_gmsas_are_the_same_everywhere() =>
|
|
Assert.Equal(@"KUNDE\svc-sqlinsight$", RepositorySetup.LoginFor(@"KUNDE\svc-sqlinsight$", "sql02", "SQLMON01", "KUNDE"));
|
|
|
|
[Fact]
|
|
public void Grant_script_takes_the_login_as_a_parameter()
|
|
{
|
|
var script = RepositorySetup.GrantScript();
|
|
|
|
Assert.Contains("SET @LoginName = @login;", script, StringComparison.Ordinal);
|
|
Assert.DoesNotContain("SET @LoginName = N'", script, StringComparison.Ordinal);
|
|
Assert.Contains("VIEW ANY DEFINITION", script, StringComparison.Ordinal);
|
|
}
|
|
}
|