how to resolve error while creating work items using Azure devops API - azure-devops-rest-api

I need help in creating a work item with the following PowerShell script, however I get this error:
Invoke-RestMethod : The remote server returned an error: (401) Unauthorized.
At C:\AutoWICreate1.PS1:64 char:11
$result = Invoke-RestMethod -Uri $uri -Method Patch -Body $json -Cont ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebEx
ception
FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
Below is the script:
param(
[string]$baseurl = "http://tfs.com:8080/tfs/collection",
[string]$projectName = "teamproject",
[string]$keepForever = "true",
[string]$user = "user-name",
[string]$token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
[string]$title = "POCAutoCreation"
)
Base64-encodes the Personal Access Token (PAT) appropriately
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
function CreateJsonBody
{
$value = #"
[
{
"op": "add",
"path": "/fields/System.Title",
"value": $title
},
{
"op": "add",
"path": "/fields/System.Tags",
"value": "Tag0921;Tag0926;Tag0927;Tag0928"
},
{
"op": "add",
"path": "/fields/Microsoft.VSTS.Common.Activity",
"value": "Development"
},
{
"op": "add",
"path": "/fields/Microsoft.VSTS.Scheduling.Effort",
"value": "8"
},
{
"op": "add",
"path": "/fields/Microsoft.VSTS.Common.ValueArea",
"value": "Business"
},
{
"op": "add",
"path": "/fields/Microsoft.VSTS.Common.Severity",
"value": "3 - Medium"
},
]
"#
return $value
}
$json = CreateJsonBody
$uri = "$baseurl/$($projectName)/_apis/wit/workitems/"+"$"+"bug?api-version=5.0"
Write-Host $uri
$result = Invoke-RestMethod -Uri $uri -Method Patch -Body $json -ContentType "application/json-patch+json" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}

Related

Query parameters are not percent-encoded for curl with OpenAPI

I generate open api documentation with springdoc 1.6.7 .
When i want to test an endpoint with following query parameter on swagger ui:
{
"page": 0,
"size": 0,
"sort": "string",
"order": "asc",
"q": {
"any": "string",
"firstName": "string",
"lastName": "string",
"email": "string",
"company": "string",
"login": "string",
"noSubscription": true
}
}
It generate following curl request:
curl -X 'GET'
'https://myEndpoint?page=0&size=0&sort=string&order=asc&q[any]=string&q[firstName]=string&q[lastName]=string&q[email]=string&q[company]=string&q[login]=string&q[noSubscription]=true'
-H 'accept: application/json'
The character '[' and ']' are not encoded, so curl request doesn't work.
Here java code from swagger is generated:
#Operation(summary = "XXXX", description = "XXX")
#ApiResponses(value = {
#ApiResponse(responseCode = "200", description = "Success",
content = { #Content(mediaType = "application/json",
schema = #Schema(implementation = PageCollectionContact.class)) }),
#ApiResponse(responseCode = "400", description = "Invalid query parameters",
content = { #Content(
schema = #Schema(implementation = ApiErrorsDTO.class))})})
PageCollectionDTO<AddressBookUserDTO> getContacts(#EffectivePrincipaleUserInfo EffectiveUserInfo userInfo,
#Parameter(description = "Contains parameter to filter response",in = ParameterIn.QUERY) #ModelAttribute AddressBookFilterDTO filterDTO,
HttpServletResponse response,
HttpServletRequest request);

Invoke-WebRequest and Invoke-RestMethod Not Returning Values in System.Object[]

I'm hitting an endpoint with this data:
{
"Id": "variableset-Projects-922",
"Variables": [
{
"Id": "30bf54b6-2e07-100f-d9f4-26879b3e9462",
"Name": "test",
"Value": "blah blah",
"Description": null,
"Scope": {},
"IsEditable": true,
"Prompt": null,
"Type": "String",
"IsSensitive": false
}
]
}
Command:
$spaces = Invoke-RestMethod -Method 'Get' -Uri $uri -Headers $header
Result:
#{Id=variableset-Projects-922; Variables=System.Object[];}
Command:
$response = Invoke-WebRequest -URI $uri -Headers $header -Method 'Get' -UseBasicParsing
Result:
{
"Id": "variableset-Projects-922",
"Variables": []
}
Despite testing with | ConvertToJson -Depth 20 the results for the Variables is always coming back as an empty array, what am I missing here?
I am also writing this script inside of a Groovy script in the Jenkins pipeline.
Well I figured it out if anyone else comes across a niche problem like this. The API key I was passing had permissions to some of the data, but not all the data.

Create issue with custom field by JIRA API

I want to create an issue using Jira REST API. Below code will works to create simple issue:
curl --request POST \
--url 'https://company_name.atlassian.net/rest/api/3/issue' \
--user 'user:token' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data {
"fields": {
"summary": "Remote test with request type",
"issuetype": {
"id": "12542"
},
"project": {
"key": "Test"
},
"description": {
"type": "doc",
"version": 1,
"content": [
{
"type": "paragraph",
"content": [
{
"text": "Second remote test",
"type": "text"
}
]
}
]
}
}
}
The thing is I want to create an issue with custom field - customfield_10029. By default it's set as nil but when I changed it manually in my board I saw something few more things inside of it:
"customfield_10029":
{"_links": {"jiraRest": "https://company_name.atlassian.net/rest/api/2/issue/241495", "web": "https://company_name.atlassian.net/servicedesk/customer/portal/19/SUP-11", "self": "https://company_name.atlassian.net/rest/servicedeskapi/request/241495"},
"requestType":
{"_expands": ["field"],
"id": "358",
"_links": {"self": "https://company_name.atlassian.net/rest/servicedeskapi/servicedesk/19/requesttype/358"},
"name": "Add Colaborator / Team Member",
"description": "e.g. external dev",
"helpText": "you can find github nicks down here https://github.com/some_url",
"issueTypeId": "12542",
"serviceDeskId": "19",
"groupIds": ["70"],
"icon":
{"id": "19558",
"_links":
{"iconUrls":
{"48x48": "https://company_name.atlassian.net/secure/viewavatar?avatarType=SD_REQTYPE&avatarId=19558&size=large",
"24x24": "https://company_name.atlassian.net/secure/viewavatar?avatarType=SD_REQTYPE&avatarId=19558&size=small",
"16x16": "https://company_name.atlassian.net/secure/viewavatar?avatarType=SD_REQTYPE&avatarId=19558&size=xsmall",
"32x32": "https://company_name.atlassian.net/secure/viewavatar?avatarType=SD_REQTYPE&avatarId=19558&size=medium"}}}}
So I thought the only thing I need to do is to add above code to the first POST request, like below:
curl --request POST \
--url 'https://company_name.atlassian.net/rest/api/3/issue' \
--user 'user:token' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data {
"fields": {
"summary": "Remote test with request type",
"issuetype": {
"id": "12542"
},
"project": {
"key": "SUP"
},
"description": {
"type": "doc",
"version": 1,
"content": [
{
"type": "paragraph",
"content": [
{
"text": "Second remote test",
"type": "text"
}
]
}
]
},
"customfield_10029":
{"_links": {"jiraRest": "https://company_name.atlassian.net/rest/api/2/issue/241495", "web": "https://company_name.atlassian.net/servicedesk/customer/portal/19/SUP-11", "self": "https://company_name.atlassian.net/rest/servicedeskapi/request/241495"},
"requestType":
{"_expands": ["field"],
"id": "358",
"_links": {"self": "https://company_name.atlassian.net/rest/servicedeskapi/servicedesk/19/requesttype/358"},
"name": "Add Colaborator / Team Member",
"description": "e.g. external dev",
"helpText": "you can find github nicks down here https://github.com/some_url",
"issueTypeId": "12542",
"serviceDeskId": "19",
"groupIds": ["70"],
"icon":
{"id": "19558",
"_links":
{"iconUrls":
{"48x48": "https://company_name.atlassian.net/secure/viewavatar?avatarType=SD_REQTYPE&avatarId=19558&size=large",
"24x24": "https://company_name.atlassian.net/secure/viewavatar?avatarType=SD_REQTYPE&avatarId=19558&size=small",
"16x16": "https://company_name.atlassian.net/secure/viewavatar?avatarType=SD_REQTYPE&avatarId=19558&size=xsmall",
"32x32": "https://company_name.atlassian.net/secure/viewavatar?avatarType=SD_REQTYPE&avatarId=19558&size=medium"}}}}
}
}
But I'm getting an error:
{"errorMessages":["Unexpected end-of-input: expected close marker for OBJECT (from [Source: org.apache.catalina.connector.CoyoteInputStream#2e2743e7; line: 1, column: 0])\n at [Source: org.apache.catalina.connector.CoyoteInputStream#2e2743e7; line: 46, column: 1863]"]}
Is there any logic behind that? how to create such an issue with customfield?
Looks like you're missing a brace.
--data { #<- This brace has no closing brace
"fields": { #<- This brace closes with the very last brace

How to add schedule on a TFS Build definition from Powershell?

I would like to add a schedule on a build definition taken from TFS REST API using PowerShell (add schedule to $buildDef variable on code example).
I get the build definition doing an API request but I'm not able to create a schedule for each week as trigger. I have used below Api for updating the trigger schedule.
$buildDef = Invoke-RestMethod -Method Get -UseDefaultCredentials -ContentType application/json -Uri $TfsBuildDefinitionUri
Any help would be appreciated as I am not able to get it done. Thanks!!
First of all , you have to get the build definition of the ADO build by utilizing below method:
GET https://dev.azure.com/{organization}/{project}/_apis/build/definitions/{definitionId}?api-version=5.1
With additional parameters:
GET https://dev.azure.com/{organization}/{project}/_apis/build/definitions/{definitionId}?revision={revision}&minMetricsTime={minMetricsTime}&propertyFilters={propertyFilters}&includeLatestBuilds={includeLatestBuilds}&api-version=5.1
Then it would give you an array of **[BuildTrigger][1]** then you have to update the schedule of DefinitionTriggerType.
schedule
A build should be started on a specified schedule whether or not changesets exist.
Here is a sample code for updating triggers of a build:
$definitionToUpdate = Invoke-RestMethod -Uri "$($collection)$($project.name)/_apis/build/definitions/$($definition.id)" -Method GET -Header $header
$trigger = $definitionToUpdate.triggers | Where {$_.triggerType -eq 'continuousIntegration'}
if ($trigger) {
$trigger.branchFilters = $branchNames | % {"+refs/heads/$_/*"}
Invoke-RestMethod -Uri "https://devops.domain.com/Collection/Project/_apis/build/definitions/$($definition.id)?api-version=5.0" -Method PUT -ContentType application/json -Body ($definitionToUpdate | ConvertTo-Json -Depth 10) -Header $header
}
You can refer this thread for further reference, Hope it helps.
Since you already got the build definition. Then you just need to use Definitions - Update Rest API to update
PUT https://dev.azure.com/{organization}/{project}/_apis/build/definitions/{definitionId}?secretsSourceDefinitionId={secretsSourceDefinitionId}&secretsSourceDefinitionRevision={secretsSourceDefinitionRevision}&api-version=5.0
In the request body, there is a BuildTrigger represents a trigger for a buld definition. Which is an array[]. It contain the schedule
string : A build should be started on a specified schedule whether or not changesets exist.
Body sample for your reference:
Content-Type: application/json
{
"id": 29,
"revision": 1,
"name": "myFavoriteDefinition",
"definitionType": "build",
"documentQuality": "definition",
"queue": {
"id": 1
},
"build": [
{
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Build solution **\\*.sln",
"task": {
"id": "71a9a2d3-a98a-4caa-96ab-affca411ecda",
"versionSpec": "*"
},
"inputs": {
"solution": "**\\*.sln",
"msbuildArgs": "",
"platform": "$(platform)",
"configuration": "$(config)",
"clean": "false",
"restoreNugetPackages": "true",
"vsLocationMethod": "version",
"vsVersion": "latest",
"vsLocation": "",
"msbuildLocationMethod": "version",
"msbuildVersion": "latest",
"msbuildArchitecture": "x86",
"msbuildLocation": "",
"logProjectEvents": "true"
}
},
{
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Test Assemblies **\\*test*.dll;-:**\\obj\\**",
"task": {
"id": "ef087383-ee5e-42c7-9a53-ab56c98420f9",
"versionSpec": "*"
},
"inputs": {
"testAssembly": "**\\*test*.dll;-:**\\obj\\**",
"testFiltercriteria": "",
"runSettingsFile": "",
"codeCoverageEnabled": "true",
"otherConsoleOptions": "",
"vsTestVersion": "14.0",
"pathtoCustomTestAdapters": ""
}
}
],
"repository": {
"id": "278d5cd2-584d-4b63-824a-2ba458937249",
"type": "tfsgit",
"name": "Fabrikam-Fiber-Git",
"localPath": "$(sys.sourceFolder)/MyGitProject",
"defaultBranch": "refs/heads/master",
"url": "https://fabrikam.visualstudio.com/DefaultCollection/_git/Fabrikam-Fiber-Git",
"clean": "false"
},
"options": [
{
"enabled": true,
"definition": {
"id": "7c555368-ca64-4199-add6-9ebaf0b0137d"
},
"inputs": {
"parallel": "false",
"multipliers": "[\"config\",\"platform\"]"
}
}
],
"variables": {
"forceClean": {
"value": "false",
"allowOverride": true
},
"config": {
"value": "debug, release",
"allowOverride": true
},
"platform": {
"value": "any cpu",
"allowOverride": true
}
},
"triggers": [],
"comment": "renamed"
}
As how to invoke Rest API in powershell, there are multiple samples in google, you could also take a look at this one:
$body = '
{
...
}
'
$bodyJson=$body | ConvertFrom-Json
Write-Output $bodyJson
$bodyString=$bodyJson | ConvertTo-Json -Depth 100
Write-Output $bodyString
$user="name"
$token="PAT"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
$Uri = "rest api url"
$buildresponse = Invoke-RestMethod -Method Post -UseDefaultCredentials -ContentType application/json -Uri $Uri -Body $bodyString -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}
write-host ....
Finally I created / added an scheduled trigger to my build definition. When the build definition has not any trigger, the property (build object) or json array (build object convert to an array) doesn't exist. So, we've to add it. Here is the solution:
$triggerValue = #"
[
{
"schedules":[
{
"branchFilters":[
"+$/FilterName"
],
"timeZoneId":"W. Europe Standard Time",
"startHours":$startHoursNB,
"startMinutes":$startMinutesNB,
"daysToBuild":"all"
}
],
"triggerType":"schedule"
}
]
"#
$buildDef | add-member -Name "triggers" -value (Convertfrom-Json $triggerValue) -MemberType NoteProperty
Thanks also for help.

ARM template integration with Azure Key Vault

I am trying to retrieve keyVault values within my ARM template
I have enabled my keyVault for ARM template retrieval
My parameter file looks like this
"postleadrequesturl": {
"reference": {
"keyVault": {
"id": "/subscriptions/e0f18fe9-181d-4a38-90bc-f2e0101f8f05/resourceGroups/RG-DEV-SHAREDSERVICES/providers/Microsoft.KeyVault/vaults/MMSG-APIManagement"
},
"secretName": "DEV-POSTLEADREQUEST-URL"
}
}
My deploy file looks like this
{
"properties": {
"authenticationSettings": {
"subscriptionKeyRequired": false
},
"subscriptionKeyParameterNames": {
"header": "Ocp-Apim-Subscription-Key",
"query": "subscription-key"
},
"apiRevision": "1",
"isCurrent": true,
"subscriptionRequired": true,
"displayName": "MMS.CRM.PostLeadRequest",
"serviceUrl": "[parameters('postleadrequesturl')]",
"path": "CRMAPI/PostLeadRequest",
"protocols": [
"https"
]
},
"name": "[concat(variables('ApimServiceName'), '/mms-crm-postleadrequest')]",
"type": "Microsoft.ApiManagement/service/apis",
"apiVersion": "2019-01-01",
"dependsOn": []
},
The error I recieve is
Error converting value "#{keyVault=; secretName=DEV-POSTLEADREQUEST-URL}" to type 'Microsoft.WindowsAzure.ResourceStack.Frontdoor.Data.Entities.Deployments.KeyVaultParameterReference
Any thoughts?
According to my test, If we want to integrate Azure Key Vault in your Resource Manager template deployment, please refer to the following steps
Create Azure Key vault
New-AzResourceGroup -Name $resourceGroupName -Location $location
New-AzKeyVault `
-VaultName $keyVaultName `
-resourceGroupName $resourceGroupName `
-Location $location `
-EnabledForTemplateDeployment
$secretvalue = ConvertTo-SecureString 'hVFkk965BuUv' -AsPlainText -Force
$secret = Set-AzKeyVaultSecret -VaultName $keyVaultName -Name 'ExamplePassword' -SecretValue $secretvalue
$userPrincipalName = "<Email Address of the deployment operator>"
Set-AzKeyVaultAccessPolicy `
-VaultName $keyVaultName `
-UserPrincipalName $userPrincipalName `
-PermissionsToSecrets set,delete,get,list
Grant access to the key vault
The user who deploys the template must have the Microsoft.KeyVault/vaults/deploy/action permission for the scope of the resource group and key vault. The Owner and Contributor roles both grant this access.
a. Create a custom role definition JSON file
{
"Name": "Key Vault resource manager template deployment operator",
"IsCustom": true,
"Description": "Lets you deploy a resource manager template with the access to the secrets in the Key Vault.",
"Actions": [
"Microsoft.KeyVault/vaults/deploy/action"
],
"NotActions": [],
"DataActions": [],
"NotDataActions": [],
"AssignableScopes": [
"/subscriptions/00000000-0000-0000-0000-000000000000"
]
}
b. Create the new role using the JSON file:
New-AzRoleDefinition -InputFile "<PathToRoleFile>"
New-AzRoleAssignment `
-ResourceGroupName $resourceGroupName `
-RoleDefinitionName "Key Vault resource manager template deployment operator" `
-SignInName $userPrincipalName
Create ARM template
template.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"service_testapi068_name": {
"defaultValue": "testapi068",
"type": "String"
},
"postleadrequesturl": {
"type": "String"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.ApiManagement/service",
"apiVersion": "2019-01-01",
"name": "[parameters('service_testapi068_name')]",
"location": "Southeast Asia",
"sku": {
"name": "Developer",
"capacity": 1
},
"properties": {
"publisherEmail": "v-wenxu#microsoft.com",
"publisherName": "test",
"notificationSenderEmail": "apimgmt-noreply#mail.windowsazure.com",
"hostnameConfigurations": [
{
"type": "Proxy",
"hostName": "[concat(parameters('service_testapi068_name'), '.azure-api.net')]",
"negotiateClientCertificate": false,
"defaultSslBinding": true
}
],
"customProperties": {
"Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Tls10": "False",
"Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Tls11": "False",
"Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Ssl30": "False",
"Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TripleDes168": "False",
"Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Backend.Protocols.Tls10": "False",
"Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Backend.Protocols.Tls11": "False",
"Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Backend.Protocols.Ssl30": "False",
"Microsoft.WindowsAzure.ApiManagement.Gateway.Protocols.Server.Http2": "False"
},
"virtualNetworkType": "None"
}
},
{
"type": "Microsoft.ApiManagement/service/apis",
"apiVersion": "2019-01-01",
"name": "[concat(parameters('service_testapi068_name'), '/demo-conference-api')]",
"dependsOn": [
"[resourceId('Microsoft.ApiManagement/service', parameters('service_testapi068_name'))]"
],
"properties": {
"displayName": "Demo Conference API",
"apiRevision": "1",
"description": "A sample API with information related to a technical conference. The available resources include *Speakers*, *Sessions* and *Topics*. A single write operation is available to provide feedback on a session.",
"serviceUrl": "[parameters('postleadrequesturl')]",
"path": "conference",
"protocols": [
"http",
"https"
],
"isCurrent": true
}
}
],
"outputs":{
"postleadrequesturl" :{
"type":"String",
"value":"[parameters('postleadrequesturl')]"
}
}
}
paramaters.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"postleadrequesturl": {
"reference": {
"keyVault": {
"id": "/subscriptions/e5b0fcfa-e859-43f3-8d84-5e5fe29f4c68/resourceGroups/testkeyandstorage/providers/Microsoft.KeyVault/vaults/testkey08"
},
"secretName": "postleadrequesturl"
}
}
}
}
Deploy
$name = ""
$password = ""
$secpasswd = ConvertTo-SecureString $password -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ($name, $secpasswd)
Connect-AzAccount -Credential $mycreds
New-AzResourceGroupDeployment -ResourceGroupName "testapi06" -TemplateFile "E:\template.json" -TemplateParameterFile "E:\parameters.json"
For more details, please refer to
https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-keyvault-parameter#grant-access-to-the-secrets
https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-tutorial-use-key-vault

Resources