cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Upload AG plugin through api

ynias_reynders
Participant

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


1 REPLY 1

piotr_kuchta
Newcomer

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