11 Oct 2019 10:04 AM - last edited on 21 Aug 2024 11:41 AM by Michal_Gebacki
We are currently automating our plugin deployment. But we can't get the POST call right to upload the zip (or plugin.json) file to our managed server.
We tryd it through Invoke-RestMethod with the following config:
$urlPluginAPI = "https://dynatrace.xxxx.be/e/xxx-xxx-xxx-xxx/api/config/v1/plugins?overrideAlerts=false"
$headers = @{
Authorization='Api-Token notArealToken'
}
$FileContent = [IO.File]::ReadAllBytes($zipPath)
$Fields = @{file=$FileContent};
Invoke-RestMethod -Uri $urlPluginAPI -ContentType 'multipart/form-data' -Method Post -Headers $Headers -Body $Fields;
But we got the following result from that:
Invoke-RestMethod : {"error":{"code":400,"message":"HTTP 400 Bad Request"}}
At line:8 char:1
+ Invoke-RestMethod -Uri $urlPluginAPI -ContentType 'multipart/form-dat ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequ
est) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Comma
nds.InvokeRestMethodCommand
We also tryd it through Windows Curl with the following results
C:\Users\REM_Dynatrace01\curl-7.66.0-win64-mingw\bin>curl -X POST 'https://dynatrace.xxxx.be/e/xxx-xxx-xxx-xxx/api/config/v1/plugins' -H 'Authorization: Api-token notArealToken' -H 'content-type: multipart/form-data' -F file=@C:\Users\REM_Dynatrace01\Documents\custom.remote.python.
printbat.zip
curl: (26) Failed to open/read local data from file/application
curl: (26) Failed to open/read local data from file/application
curl: (26) Failed to open/read local data from file/application
curl: (26) Failed to open/read local data from file/application
Anybody that got a working example that we can do through Powershell? Preferably through Invoke-RestMethod
Solved! Go to Solution.
11 Oct 2019 02:47 PM
I would say PowerShell is not the best tool to do that, but it is possible.
There are two problems:
1. PowerShell constructs request as specified in body (so no magic that will fill stuff for you)
2. The way you passed fileContent to body, resulted in having "System.Byte%5B%5D" in request instead of bytes itself.
$zipName = "custom.remote.python.demo.zip"
$zipPath = "your\\path\\to\\plugin\\$zipName"
$urlPluginAPI = "https://dynatrace.xxxx.be/e/xxx-xxx-xxx-xxx/api/config/v1/plugins?overrideAlerts=false"
$headers = @{
'Authorization'='Api-Token some-token'
}
$FileContent = [IO.File]::ReadAllBytes($zipPath)
$ct = [System.Text.Encoding]::GetEncoding("iso-8859-1").GetString($FileContent)
$boundary = [System.Guid]::NewGuid().ToString()
$LF = "`n"
$bodyLines = (
"--$boundary",
"Content-Disposition: form-data; name=`"file`"; filename=`"$zipName`"",
"Content-Type: application/zip$LF",
$ct,
"--$boundary--$LF"
) -join $LF
Invoke-RestMethod -Uri $urlPluginAPI -Body $bodyLines -Headers $Headers -Method Post -ContentType "multipart/form-data; boundary=`"$boundary`"" -TimeoutSec 20
that's the code that worked for me