Bash on Azure Pipeline running windows agent - bash

I'm trying to get a build number from a secondary Azure pipeline. I'm using bash on a windows agent, already enabled developer mode, and installed the Linux feature. When I test this locally it works, I'm able to connect and get the build number but from the pipeline, I get the error...
Enhanced Security Configuration is currently enabled on your environment. This enhanced level of security prevents our web integration experiences from displaying or performing correctly. To continue with your operation please disable this configuration or contact your administrator
Could it be related to the Auth system token? I have also enabled "Allow scripts to access the OAuth token"
Bash code that I'm trying to use on the pipeline:
#!/bin/bash
echo $TAG
echo $VER
echo $SYSTEM_ACCESSTOKEN
echo "Executing call to get latest build from a pipeline definition Id"
echo "$URL-7.1"
export RESPONSE=`curl -u username":$SYSTEM_ACCESSTOKEN" --location --request GET "$URLapi-version=7.1-preview.1"`
echo $RESPONSE
export BUILD_NUMBER=`echo $RESPONSE | jq -r '.["buildNumber"]'`
echo $BUILD_NUMBER
Powershell script working locally, but if I use this form, the access token is not recognized.
$connectionToken= $(System.AccessToken)
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
$BuildPipelineUrl = "$url`$top=1&api-version=6.0"
Write-Host "URL: $BuildPipelineUrl"
$BuildPipelineInfo = (Invoke-RestMethod -Uri $BuildPipelineUrl -Method Get -UseDefaultCredential -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)})
$ver = $BuildPipelineInfo.value.buildnumber
Write-Host "$ver"
Is there another way to use the Sys auth token, Do I have to convert it?
Thanks, everyone!.

You could try to use the following powershell script to check if it works.
$Token = $env:SYSTEM_ACCESSTOKEN
$BuildPipelineUrl = "$url`$top=1&api-version=6.0"
Write-Host "URL: $BuildPipelineUrl"
$BuildPipelineInfo = (Invoke-RestMethod -Uri $BuildPipelineUrl -Method Get -Headers #{ Authorization = "Bearer $Token" })

Related

How do I query Azure DevOps (TFS) using curl.exe or PowerShell directly without additional support libraries?

Azure DevOps has a REST API: https://learn.microsoft.com/en-us/rest/api/azure/devops/?view=azure-devops-rest-7.1
How do I access it using curl.exe or PowerShell without additional support libraries?
This instructions are for Windows, although they can be used in other platforms with slight modification.
Below, replace with your own values for:
{organization}
{project}
{team}
{pat}
You can create a PAT in your organization's portal. Using your browser, go to: (replace {organization}):
https://dev.azure.com/{organization}/_usersSettings/tokens
Using Command Prompt
If using Command Prompt (cmd.exe), curl.exe can be used. It is part of Windows (10+). Also works in PowerShell, but you have to spell out curl.exe, not just curl. The commands below output the results to the console. You can pipe it to a file, or use the -o option in curl to specify a file to output to.
Using PoowerShell
If using PowerShell, you use the Invoke-RestMethod command. In the below commands, the result of the command is placed in a variable, $result, which you can use after the invocation.
The commands below also assume variables $pat and $header are initialized as follows:
$pat = "{pat}"
$header = #{authorization = "Basic $([System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($pat)")))"}
Example getting a work item by ID (Work Items - Get Work Item):
Using curl:
curl.exe -u :{pat} -H "Content-Type: application/json" https://dev.azure.com/{organization}/_apis/wit/workItems/{id}
Using PowerShell:
$url = "https://dev.azure.com/{organization}/_apis/wit/workItems/{id}"
$entries = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers $header
Quick display of the above output:
$entries.Fields | Format-Table system.workitemtype, system.title

gcloud auth print-access-token gives permission denied error

I have a shell script trying to download some secrets from secret manager inside dataproc cluster.
GetAuthJson() {
authjson=$(curl "https://secretmanager.googleapis.com/v1/projects/$PROJECT_ID/secrets/$AUTH_JSON/versions/1:access" \
--request "GET" \
--header "authorization: Bearer $(gcloud auth print-access-token)" \
--header "content-type: application/json")
if [ $? -ne 0 ]; then
Error "Unable to extract the $PIPENAME Auth json details from GCP Secret Manager"
fi
echo $authjson | grep -o '"data": "[^"]*' | grep -o '[^"]*$' >$BASE_DIR/encodedauth.json
if [ $? -ne 0 ]; then
Error "Unable to save the $PIPENAME auth.json server secret to auth.json"
fi
auth_json=$(base64 -d $BASE_DIR/encodedauth.json)
base64 -d $BASE_DIR/encodedauth.json >/etc/secrets/auth.json
if [ $? -ne 0 ]; then
Error "Unable to decode the $PIPENAME auth.json server secret"
fi
Log "auth.json secret extraction done"
}
when i run this curl it generates an error
authjson='{
"error": {
"code": 403,
"message": "Permission '\''secretmanager.versions.access'\'' denied for resource '\''projects/**-**-dev/secrets/**_AUTH_JSON/versions/1'\'' (or it may not exist).",
"status": "PERMISSION_DENIED"
}
}'
the same curl with same service account is working in local meachine. and more over if i copy the CURL from local and run it in dataproc cluster it works as well.
But the curl generated from dataproc fails in local .
whats more weird is if i run gcloud auth print-access-token separately and paste it in curl command it works in both meachine.
so my question is why gcloud auth print-access-token generated as part of curl in dataproc cluster is not working ?
It would be useful if you could capture the value of the curl command or, at least the value of gcloud auth print-access-token that's failing in the script.
I suspect (I'm unfamiliar with Dataproc) that the Dataproc instance does not have gcloud installed and the gcloud auth print-access-token is failing.
If the instance does have gcloud installed, since it's running then it must have a Service Account and so should permit authenticating. There may (!?) be a more nuanced issue with getting an access token as a Dataproc instance, unclear.
Please consider using either gcloud secrets versions access directly or one of Google's client libraries to access the secret.
You're making the process more complex than it need be by curl'ing the endpoint; you're having to use gcloud anyway to get the auth token.
The issue was i ran the script as sudo user. When i ran normally it worked.

create basic auth token from cloudformation userdata (which is already in base64)

I am trying to create a Basic auth token from username & password from the userdata of cloudformation.
The script is creating the token but it is not the right one as it is adding a line before the substitution. What is the possible problem/solution ?
code is something like this -
username=test
password=password
export AUTH=$(echo -ne "$username:$password" | base64)
echo $AUTH
If I run this script locally it works absolutely fine.

trying to convert simple curl command to invoke-webrequest but not working

I have a very simple curl command, this works for me (not using basic auth- the service just expects the token to be in URL):
curl -v -X POST https://Dkdjhf928hfDJFSDFJSK#sonarcloud.io/api/projects/create -d "name=sdfsdfsdf&project=sdfsdfdsf&organization=zzzzz"
This does not work:
Invoke-WebRequest -Method POST `
-Body 'name=sdfsdfsdf&project=sdfsdfdsf&organization=zzzzz' `
-Uri 'https://Dkdjhf928hfDJFSDFJSK#sonarcloud.io/api/projects/create'
powershell must be mangling something because I get this error:
Invoke-WebRequest : {"errors":[{"msg":"Insufficient privileges"}]}
Is there some default way curl sends body or data that powershell does not?

PowerShell equivalent for cURL command uploading file

I am able to send HTTP POST a text file to my server using the following cURL command:
curl -i -F file=#file.txt http://www.website.com/put_file
The server is expecting a file from $_FILES['file'].
I have the following so far but it is not working:
$url = http://www.website.com/put_file
$file = "c:\file.txt"
$wc = new-object System.Net.WebClient
$wc.UploadFile($url, $file.FullName)
it returns 0, and it did not upload to the server
How can I send the file as $_FILES['file']? Also, how can I see the response from the server?
I think it should be something like this:
$body = "file=$(get-content file.txt -raw)"
Invoke-RestMethod -uri http://www.websetite.com/put_file -method POST -body $body
Note: this does require PowerShell V3. Also, you might need to specify the -ContentType parameter as "application/x-www-form-urlencoded". I recommend getting Fiddler2 and use it to inspect the request in both the curl and Inovke-RestMethod cases to help get the irm parameters correct. This is assuming the file contents are fairly small and non-binary. If not, you probably need to go to content type multipart/form-data.
In Powershell you can use curl.exe instead of curl (yes, are different commands: http://get-cmd.com/?p=5181)
curl.exe -i -F file=#file.txt http://www.website.com/put_file
Or you can use Invoke-RestMethod from powershell 3
More details about Invoke-RestMethod from powershell 3 at: https://superuser.com/questions/344927/powershell-equivalent-of-curl
To solve this, I download curl.exe for windows, and still used curl.
After a couple hours of using fiddler to try to match curl, I gave up and just used this guy's function (See link below). Worked like a charm.
http://blog.majcica.com/2016/01/13/powershell-tips-and-tricks-multipartform-data-requests/

Resources