Issues trying to update a stack via API

Hello all,

I’m having serious issues trying to update a stack via the API. The stack that I’m trying to update was created manually on portainer.

I tried to do it following the examples available in Swagger and they’re not working (https://app.swaggerhub.com/apis/deviantony/Portainer/1.23.2/#/stacks/StackUpdate).

So, after a few tries, I came up with a request that works:

http PUT “:9000/api/stacks/$STACK_ID?endpointId=$ENDPOINT_ID”
“Authorization: Bearer $ACCESS_TOKEN”
StackFileContent=“version: ‘3.6’
services:
test:
image: nginx”

But if I tried to include environment variables:

http PUT “:9000/api/stacks/$STACK_ID?endpointId=$ENDPOINT_ID”
“Authorization: Bearer $ACCESS_TOKEN”
Env=[“name: MYSQL_ROOT_PASSWORD”,“value:password]”
StackFileContent=“version: ‘3.6’
services:
test:
image: nginx”

I get this answer:

HTTP/1.1 400 Bad Request
Content-Length: 154
Content-Type: application/json
Date: Thu, 14 May 2020 08:11:25 GMT
X-Content-Type-Options: nosniff
X-Xss-Protection: 1; mode=block
{
“details”: “json: cannot unmarshal string into Go struct field updateSwarmStackPayload.Env of type []portainer.Pair”,
“message”: “Invalid request payload”
}

and a similar issue if I try to set a value for prune:

http PUT “:9000/api/stacks/$STACK_ID?endpointId=$ENDPOINT_ID”
“Authorization: Bearer $ACCESS_TOKEN”
prune=true
StackFileContent=“version: ‘3.6’
services:
test:
image: nginx”

HTTP/1.1 400 Bad Request
Content-Length: 144
Content-Type: application/json
Date: Thu, 14 May 2020 08:23:57 GMT
X-Content-Type-Options: nosniff
X-Xss-Protection: 1; mode=block
{
“details”: “json: cannot unmarshal string into Go struct field updateSwarmStackPayload.Prune of type bool”,
“message”: “Invalid request payload”
}

Could someone give me a hand / provide me a working example about how I can update a stack, the environment variables associated to it and with the option prune enabled?

Regards,

Javier G.

Here is an example of an HTTPie request I made if that helps you:

printf '{"id":1,"StackFileContent":"version: '\''3'\''\\nservices:\\n  test:\\n    image: nginx","Env":[{"name":"test","value":"test"}],"Prune":true}'| http  --follow --timeout 3600 PUT 192.168.1.13:9000/api/stacks/1 'endpointId'=='2' \
 Authorization:'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJhZG1pbiIsInJvbGUiOjEsImV4cCI6MTU4OTU0Njc5N30.hji3KXnY3uQhAGxoA0BYZnr-RjCnMRoRI1ITsaAHsiE' \
 Content-Type:'application/json'
1 Like

I can’t tell what tool you’re using to try the HTTP PUT, but Portainer API requires json. You need to send json formatted data. It would probably help to send a header like “Content-Type: application/json” as well.