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 的构建管道期间下载文件?