在Visual Studio Online的构建/测试任务中连接外部服务

3
我们正在TFS在线上运行构建和测试过程。这很好用,但当我们尝试连接到外部服务时就会出现问题。在我们的情况下是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/端口等都可能被锁定了?有没有办法打开它?如果有,怎么做?

我无法想象我们是第一个尝试这样做的人?从网站下载东西,进行REST调用等等?总该有办法吧?

更新1:
我们对这个问题 在这里 有更详细的问题,但发现这是一个更通用的问题。

当我们连接到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。
更新2: 我们尝试了 @starain-MSFT 的想法,并安装了 Azure SQL 执行查询步骤/任务。安装很好,但似乎缺少一个组件。如下图所示。
"找不到具有以下功能的代理:azureps、sqlps、npm、node.js、msbuild、visualstudio、vstest"
根据已安装应用程序列表(链接),我认为它是 azureps。

enter image description here

解决方案(部分):
好的,所以我们一直走错了路。问题不在防火墙(或任何防火墙上)。问题是我们的 app.config 文件中没有正确的设置。
我们在单元测试内部的 App.config 文件和 Web.config 文件中拥有相同的设置。每个文件都附带了一个 App.Debug.config 和一个 App.Release.config 文件。虽然这对于 Web 应用程序来说很好用,但显然对于我们的单元测试来说并不起作用。
我们仍在寻找一个好的解决方案。我发现 如何在 Visual Studio 中添加转换任务的此解决方案, 但这不是我们正在寻找的,因为我们不需要在本地进行转换,而只需要在 Visual Studio Teams 中进行。

Visual Studio Teams 内的 app.config 转换
所以,我想我们终于搞定了。使用 ConfigTransform,我们现在可以在构建过程中转换我们的 app.config 文件。

enter image description here


什么是ConnectionString?尝试通过SQL Server Management Studio连接并检查结果。 - starian chen-MSFT
是的,那可以。我们可以连接到 SQL Server 而不会遇到任何问题。只是似乎所有与外部的连接都被构建过程阻止了。就像我之前所说的 ping 一样。 - Remy
你如何配置Azure SQL Server,使其可以从任何IP地址访问?关于防火墙规则,您可以添加Azure SQL Execute Query步骤/任务,该步骤可以将构建代理IP地址添加到规则中,因此您可以在进行NUnit测试之前添加此步骤来执行一个简单的脚本以将构建代理IP添加到规则中(取消勾选任务结束后删除规则)。https://marketplace.visualstudio.com/items?itemName=geeklearningio.gl-vsts-tasks-azure&targetId=694f8310-2406-4022-b85e-97dd9106a4e9 - starian chen-MSFT
我更新了我的答案以添加防火墙规则,请检查一下。(Azure SQL执行查询存在问题) - starian chen-MSFT
根据屏幕截图,您正在使用托管构建代理,您还在使用托管构建代理吗?对我来说,使用托管构建代理是有效的。如果您尝试使用我的方式(PowerShell)添加防火墙规则,请提供详细的构建日志。IP地址是否已添加到防火墙规则中? - starian chen-MSFT
显示剩余4条评论
3个回答

2
使用托管代理时,需要从互联网访问SQL Server以便从托管代理连接到您的SQL Server。
解决此问题的方法:
1. 如Giulio所说,设置一个本地构建代理,然后只需确保SQL Server实例可以从该构建代理(可以是内部网络)访问即可。 2. 应用一个在互联网上的SQL Server,例如Azure SQL Server,可以从互联网访问。 3. 配置您的SQL Server和网络,以使您的SQL Server可以从互联网访问。
顺便提一下,关于您的简单ping测试,该IP地址用于其网站,端口为80,您可以使用该IP地址访问其他资源。您可以在服务器上打开另一个端口,并通过IP和端口访问资源。
更新1:
参考此方法添加Azure SQL Server防火墙规则:
  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连接字符串如下:
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;

我们为了测试将Azure SQL服务器对所有IP地址开放,但仍然无法连接。我并不是很理解你关于Ping测试的回答。我相信如果我们自己托管构建服务器,我们肯定能让其正常工作,但我更愿意使用Visual Studio Online提供的服务器。 - Remy
@Remy,当您连接到Azure数据库时,您收到了什么详细的错误消息?您在哪里访问Azure数据库? - starian chen-MSFT
通常连接字符串会指定SQL Server的名称,当SQL数据库没有广告它的名称时,你会看到SQL失败。这类似于DNS故障,但是特定于SQL服务器。 - JWP
除了问题中的证据之外,你有没有任何理由相信Azure SQL DB不会广告/广播它的名称?IP地址不是静态的,因此连接到Azure SQL DB的唯一可靠方法是通过名称。此外,所有查询远程数据库的弹性查询示例都使用数据库名称 (https://azure.microsoft.com/en-us/blog/querying-remote-databases-in-azure-sql-db/)。 - awj

1

Windows托管的构建代理不会阻止1433端口的出站连接。

  1. 如果您想通过托管的构建代理连接到SQL Azure,请确保在SQL Azure防火墙设置中启用了“允许访问Azure服务”。您不需要手动运行脚本。

SQL Azure防火墙设置

  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托管代理进行了快速测试,测试成功。


干杯,汤姆!非常尴尬。问题实际上不是防火墙的问题。问题在于我们的 app.config 文件没有像我们的 web.config 文件那样进行发布转换。现在的问题是,在 TFS 服务器上与本地环境有一个不同的 app.config 文件的通用方法是什么?我看到了很多关于如何在 VS 中本地包括这个转换的帖子,但我们实际上不想在本地调试运行时运行它。只在 VS Online 上运行。 - Remy
我们是在说不需要特定的防火墙规则吗?这是否意味着任何 VSTS 主机都可以访问 Azure SQL 服务器?还是只针对已与该 VSTS 实例关联的 Azure 实例? - Kevin

0

我猜测您正在使用托管代理,这意味着该计算机是许多VSTS帐户(租户)之间共享资源,并由Microsoft进行管理(并锁定)。

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

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


没错,那是一个选项。但如果有绕过锁定的方法,我非常不想这样做。 - Remy
我们现在假设构建代理的端口1433已关闭。但是ps脚本不允许我们更改任何内容。 - Remy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接