如何通过 API 将组分配为 VSTS 端点上的用户?

How to assign a group as Users on an endpoint in VSTS via the API?

我正在尝试整理 VSTS 并确保 AzureRM 端点在我们的 40 多个项目中保持一致。我已经编写了一个 Powershell 脚本来调用其余的 API 并确保相同的端点可用于所有项目。这很好用。

我想做的一件事是为每个项目的贡献者组授予非产品端点的用户权限。 似乎不起作用,官方文档 (create or update) 没有提供任何实际指导。

我可以获取该组并将其作为 JSON 调用正文中的 "readersGroup" 传递,然后在响应中回显,暗示它有效,但这不起作用端点本身似乎发生了任何变化。

之前有没有人做过这件事谁能给我一些指导我哪里出错了?

[CmdletBinding()]
Param(
    [ValidateSet("Production","NonProduction","RandD")][string]$Environment,
    [string]$SubscriptionName,
    [string]$SubscriptionDisplayName = $SubscriptionName,
    [string]$SubscriptionId,
    [string]$TenantId,
    [string]$ClientId,
    [string]$ClientKey,
    [string]$Token  #Required Scopes: Graph (read), Project and team (read), Service Endpoints (read, query and manage)
)

#Set up Endpoint data
$EndpointDisplayName = "$Environment ($SubscriptionDisplayName)"
$EndpointConfiguration = @"
{
    "data": {
        "SubscriptionId": "$SubscriptionId",
        "SubscriptionName": "$SubscriptionName",
        "creationMode" : "Manual"
    },
    "name": "$EndpointDisplayName",
    "type": "azurerm",
    "url" : "https://management.azure.com/",
    "authorization": {
        "parameters": {
            "serviceprincipalid" : "$ClientId",
            "serviceprincipalkey" : "$ClientKey",
            "tenantid" : "$TenantId"
        },
        "scheme": "ServicePrincipal"
    }
}
"@

#Set up API data
$Authentication = [Text.Encoding]::ASCII.GetBytes(":$Token")
$Authentication = [System.Convert]::ToBase64String($Authentication)
$Headers = @{
    'Authorization' = "Basic $Authentication"
    'Content-Type' = "application/json"
}
$BaseURI = "https://contoso.visualstudio.com"
$APIVersion = "?api-version=4.1-preview.1"

#get all vsts projects
$ListProjectsURI = "$BaseURI/DefaultCollection/_apis/projects$APIVersion"
$ProjectList = (Invoke-RestMethod -Method GET -Uri $ListProjectsURI -Headers $Headers).value

#Get VSTS Contributor groups for "user" role assignment
$ListGroupsURI = "https://Contoso.vssps.visualstudio.com/_apis/graph/groups$APIVersion" 
$GroupsList = (Invoke-RestMethod -Method GET -Uri $ListGroupsURI -Headers $Headers).value
$AllContributorsGroups = $GroupsList | Where-Object -Property principalName -like "*\Contributors"

foreach($Project in $ProjectList)
{
    $ProjectName = $Project.name
    $ProjectId = $Project.id
    #get all AzureRM SP endpoints
    $ListEndpointsURI = "$BaseURI/$ProjectId/_apis/serviceendpoint/endpoints$APIVersion&type=azurerm&authschemes=ServicePrincipal"
    $EndpointList = (Invoke-RestMethod -Method GET -Uri $ListEndpointsURI -Headers $Headers).value
    $Exists = $false

    #set up the endpoint settings for this project
    if($Environment -eq "Production")
    {
        $EndpointJSON = $EndpointConfiguration
    }
    else #grant devs access to use non-prod/R&D endpoints
    {
        Write-Host "Setting [$ProjectName]\Contributors as Users on $EndpointDisplayName in $ProjectName"
        $ReadersGroup = ($AllContributorsGroups | Where-Object -Property principalName -eq "[$ProjectName]\Contributors") | ConvertTo-Json
        $ReadersConfiguration = @"
    ,"readersGroup" : $ReadersGroup
}
"@
        $EndpointJSON = $EndpointConfiguration.TrimEnd('}') + $ReadersConfiguration #Append the readers role for this project to the base configuration
    }

    #Look for existing matching endpoints
    foreach($Endpoint in $EndpointList)
    {
        $EndpointName = $Endpoint.name
        $EndpointId = $Endpoint.id

        #check if it uses the subscription Id we're updating,
        if($Endpoint.data.subscriptionId -eq $SubscriptionId)
        {
            #if so, update it
            Write-Host "Updating endpoint `"$EndpointName`" in Project `"$ProjectName`" (Endpoint ID: $EndpointId)"
            $UpdateEndpointURI = "$BaseURI/$ProjectId/_apis/serviceendpoint/endpoints/$EndpointId$APIVersion"
            Invoke-RestMethod -Method PUT -Uri $UpdateEndpointURI -Headers $Headers -Body $EndpointJSON
            $Exists = $true
        }
    }
    #if no existing endpoints match, create one
    if(!$Exists)
    {
        Write-Output "No endpoint found for $SubscriptionName in `"$ProjectName`". Creating endpoint `"$EndpointDisplayName`"."
        $CreateEndpointURI = "$BaseURI/$ProjectId/_apis/serviceendpoint/endpoints$APIVersion"
        Invoke-RestMethod -Method POST -Uri $CreateEndpointURI -Headers $Headers -Body $EndpointJSON
    }
}

改用 API:

https://{account}.visualstudio.com/_apis/securityroles/scopes/distributedtask.serviceendpointrole/roleassignments/resources/{project id}_{endpoint id}?api-version=5.0-preview.1

正文 (application/json)

[{"roleName":"User","userId":"{group or user id (originId)"}]