在 Visual Studio 在线 build/test 任务中连接到外部服务

Connect to external services inside Visual Studio Online build/test task

我们正在 运行 TFS Online 上的构建和测试过程。这工作正常,直到我们尝试连接到外部服务。在我们的例子中是一个 SQL 数据库。
关于我们应该模拟什么而不应该模拟什么的讨论在这种情况下并没有多大帮助,因为目前我们需要这样做。

我们也尝试了一个简单的 ping,但即使这样也没有成功:

Test-Connection "172.217.18.100" #resolves to www.google.com

Testing connection to computer '172.217.18.100' failed: Error due to lack of resources

所以我们印象中的大部分外IP's/Ports/etc。可以上锁吗? 有没有办法打开这个?如果是,如何?

我无法想象我们是第一个尝试这样的事情的人?从网站下载一些东西,全部制作 REST,等等?应该有可能,不是吗?

更新 1:
我们对这个问题 here 有一个更详细的问题,但认为这是一个更普遍的问题。

当我们连接到 Azure SQL 时的错误消息是

System.Data.SqlClient.SqlException: 
A network-related or instance-specific error occurred while establishing a    connection to SQL Server. 
The server was not found or was not accessible. 
Verify that the instance name is correct and that SQL Server is configured to allow remote connections. 
(provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)`

但命名管道提供程序部分具有误导性。如果您尝试连接到不存在的 IP,您也会在本地收到此消息。

我们通过 C# NUnit 测试访问 Azure SQL。

更新二:
我们尝试了@starain-MSFT 的想法并安装了 Azure SQL 执行查询 step/task。安装工作正常,但似乎缺少一个组件。见下图。

No agent could be found with the following capabilities: azureps, sqlps, npm, node.js, msbuild, visualstudio, vstest

根据 installed apps 列表,我认为它是 azureps。

解法(部分):
好吧,所以我们一路走错了路线。问题不在于防火墙(或与此相关的任何防火墙)。问题是我们的 app.config 文件中没有正确的设置。
我们在单元测试中对 App.config 文件进行了与 Web.config 文件相同的设置。每个都附有一个 App.Debug.config 和一个 App.Release.config 文件。虽然这对 Web 应用程序运行良好,但显然不适用于我们的单元测试。
我们仍在寻找一个好的解决方案。 我找到了 this solution on how to add a transform task inside Visual Studio,但这并不是我们正在搜索的内容,因为我们不需要在本地进行转换,而只需要在 Visual Studio 个团队中进行。

app.config内部转型Visual Studio团队
所以,我想我们终于明白了。使用 ConfigTransform,我们现在可以在构建过程中转换我们的 app.config 文件。

我假设您正在使用 Hosted Agents,这意味着该计算机是许多 VSTS 帐户(租户)之间的共享资源并由 Microsoft 管理(并锁定)。

您可以轻松地在自己的虚拟机上安装代理,然后 运行 在那里构建。 VM 可以在云端或本地,由您选择。您用简单和廉价换取完全控制。

更新: Hosted Agents 允许 HTTP(S) 调用,涵盖了很多方面。虽然有用,但我认为它不能解决连接到 SQL 数据库的原始问题。

使用 Hosted Agents,SQL 服务器需要可从 Internet 访问,以便从 Hosted Agents 连接到您的 SQL 服务器。

这个问题的处理方法:

  1. 正如 Giulio 所说,设置一个本地构建代理,那么你只需要确保 SQL 服务器实例可以从该构建代理(可以是 Intranet)访问。
  2. 在 Internet 上应用 SQL 服务器,例如可以从 Internet 访问的 Azure SQL 服务器。
  3. 配置您的 SQL 服务器和网络,让您的 SQL 服务器可以从互联网访问。

顺便说一句,关于你简单的ping测试,那个IP地址用于它的网站,端口是80,你可以用这个IP访问其他资源。您可以在您的服务器上打开另一个端口并通过IP 和端口访问资源。

更新 1:

参考此方式添加AzureSQL服务器防火墙规则:

  1. 选中允许脚本访问 OAuth 令牌选项(构建定义的选项)
  2. 在测试步骤之前添加 Azure PowerShell 构建步骤(参数:-RestAddress https://[your vsts account].vsdtl.visualstudio.com/DefaultCollection/_apis/vslabs/ipaddress -Token $(System.AccessToken) -RG [资源组] -Server [服务器名称(不带.database.windows.net)]

脚本:

param (
    [string]$RestAddress,
    [string]$Token,
    [string]$RG,
    [string]$Server
    )
$basicAuth = ("{0}:{1}" -f 'test',$Token)
$basicAuth = [System.Text.Encoding]::UTF8.GetBytes($basicAuth)
$basicAuth = [System.Convert]::ToBase64String($basicAuth)
$headers = @{Authorization=("Basic {0}" -f $basicAuth)}
$result = Invoke-RestMethod -Uri $RestAddress -headers $headers -Method Get
Write-Host $result.value
New-AzureRmSqlServerFirewallRule -ResourceGroupName $RG -ServerName $Server -FirewallRuleName "UnitTestRule" -StartIpAddress "$($result.value)" -EndIpAddress "$($result.value)"

顺便说一句,测试后可以参考那个脚本去掉防火墙规则

更新 2:

SQL ConnectionString 是这样的:

Server=tcp:[server name].database.windows.net,1433;Initial Catalog=sqlstarain1;Persist Security Info=False;User ID=[user name];Password=[password];MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;

Windows 托管生成代理不会阻止 1433 出站。

  1. 如果您想通过托管生成代理连接到 SQL Azure,请确保您在 SQL Azure 防火墙设置 "Allow access to Azure services" 中启用。您不需要手动 运行 脚本。

SQL Azure Firewall settings

  1. 确保您在单元测试期间使用正确的连接字符串。例如。在 MSTest 中,您需要将连接字符串添加到 UnitTest 项目 App.config 中 .
<connectionStrings>
  <add name ="TestContext" providerName="System.Data.SqlClient" 
  connectionString="Server=tcp:[ServerName].database.windows.net,1433;Initial Catalog=[DB Name];Persist Security Info=False;User ID=[User];Password=[Password];MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"/>
</connectionStrings>

就是这样。我刚刚使用 EF、SQL Azure 和 VSTS 托管代理进行了快速测试,结果成功了。