Azure DevOps 在发布期间获取部署代理状态

Posted

技术标签:

【中文标题】Azure DevOps 在发布期间获取部署代理状态【英文标题】:Azure DevOps get Deployment Agent status during release 【发布时间】:2019-10-07 14:22:57 【问题描述】:

我正在尝试在发布时获取部署池中代理的状态。 用例是我有 2 台带有共享磁盘的服务器,我希望该版本仅在一台服务器上运行。我有两个基于自定义条件运行的部署组:

eq(variables['DeployGroupSelector'], '1')

在确定 DeployGroupSelector var 值的作业之前运行的作业,本质上是一个 case 语句。

在设置 var 的工作中,我正在尝试联系 Azure DevOps REST API:

$headers = @
    Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"


$url = "https://dev.azure.com/$($organization)/_apis/distributedtask/pools/$($poolId)/agents?api-version=5.1"
$response = Invoke-RestMethod $url -Headers $headers -Verbose
write-host "Output: $response"
$status = ($response.value | where $_.name -eq $($env:primaryPoolName)).status
if($status -eq "online")

    Write-Output("##vso[task.setvariable variable=DeployGroupSelector;]1")

else

    Write-Output("##vso[task.setvariable variable=DeployGroupSelector;]2")

对于包含上述脚本的组,选中“允许脚本访问 OAuth 令牌”框。

当我使用 PAT 在本地运行这个 powershell 时,它会返回数据。当我在 ADO 中运行发布时,它会访问服务,但返回一个空数据集:

2019-10-07T14:16:18.8942915Z VERBOSE: GET https://dev.azure.com/xxxxxx/_apis/distributedtask/pools/13/agents?api-version=5.1 with 0-byte payload
2019-10-07T14:16:19.3235204Z VERBOSE: received 22-byte response of content type application/json
2019-10-07T14:16:19.9626359Z VERBOSE: Content encoding: utf-8
2019-10-07T14:16:19.9835101Z Output: @count=0; value=System.Object[]

我已尝试为“项目集合构建服务帐户”组授予对池和组的读取权限,我什至尝试将其授予用户。我尝试添加构建服务帐户组以发布管理员。我什至尝试使用旧的 url 格式以防万一。

添加了powershell返回的数据图片:

更新:为了进一步排除我如何使用令牌的问题,我向相关任务组添加了第二个 powershell 任务。此脚本会命中 AzDO Rest API 的不同部分(如下)。这成功地得到了响应。所以 OAuth 令牌正在工作,它似乎无法访问整个 API。

$标头 = @ 授权 = "承载 $env:SYSTEM_ACCESSTOKEN"

$url = "https://dev.azure.com/$($organization)/$($project)/_apis/git/repositories?api-version=5.1"
$response = Invoke-RestMethod $url -Headers $headers -Verbose
write-host "Output: $($response)"

回复:Output: @value=System.Object[]; count=10

【问题讨论】:

从哪里获得$pooId? 我去了 UI 中的部署池,选择了池,并从 URI 中获取了 ID。也可以通过rest api查询。 我问是因为还有具有不同 id 的代理队列和代理池的 api。我无法重现您的问题,在我的发布中,我得到了响应中的代理。 您能否在此处上传您的 PowerShell 脚本结果的屏幕截图,其 URL 与发布所执行的 URL 相同? 添加图片.. 【参考方案1】:

由于您使用的是 System_AccessToken 变量,您是否还在代理作业中启用了“允许脚本访问 OAuth 令牌”复选框? https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=classic#systemaccesstoken 此链接显示它在构建中的位置,但您会在发布时的代理作业面板底部找到它。如果未选中,这可能就是您得到空响应的原因。

【讨论】:

是的,我启用了这个。 您是否尝试过传入具有池读取权限的 PAT 以尝试隔离是否是权限问题?我知道有时 AzDO 中的某些 API 需要的权限不仅仅是从发布中传入的 PAT(例如某些分布式任务 API 或扩展 API)。 PAT 在作为发布的一部分执行时似乎不起作用。当我在 powershell 中运行它时它工作正常,但是当我将它作为发布的一部分运行时,我得到一些代表登录页面的 html 嗯,很奇怪,即使您将 PAT 作为参数传递给脚本,它也不起作用?您是在私有代理还是托管代理中运行它? 它是一个托管代理(Azure Pipelines)【参考方案2】:

遇到了完全相同的问题。被认为是两个选项,与您一直在尝试的相同。

    System.AccessToken 拍拍

问题已通过将 PAT 放入 KeyVault 并将其用作管道中 REST API 调用的基本身份验证令牌来解决。

我的建议是,这似乎是预期的和正确的行为。为什么我会这么认为?从 Azure DevOps 的角度来看,我们的案例组织级别和项目级别有两个级别。您可以通过使用的 URI 注意到差异:

$url = "https://dev.azure.com/$($organization)/_apis/distributedtask/pools/$($poolId)/agents?api-version=5.1"

$url = "https://dev.azure.com/$($organization)/$($project)/_apis/git/repositories?api-version=5.1

从安全的角度来看,让来自较低层的实体(在我们的案例中是项目)访问和操作较高层(在我们的案例中是组织)是一种不好的做法。

作为结论,我想说 SystemToken 和 PAT 在本质上略有不同,一个是专门用于代理的,另一个是用于个人资料的。

【讨论】:

以上是关于Azure DevOps 在发布期间获取部署代理状态的主要内容,如果未能解决你的问题,请参考以下文章

Azure Devops (VSTS) 代理池和部署池之间的区别

如何在 azure devops YAML 管道中将单个代理用于多个作业/阶段

是否可以在 Azure DevOps 的构建管道期间下载文件?

Azure DevOps - 部署组的权限问题

在windows vm上部署Azure Pipelines Agent

Azure DevOps Server 2020.1.1 API - 如何获取包含运行它的代理的构建