tordvd
July 15, 2020, 1:35pm
1
Has anyone had any luck with Ignition and portainer API?
I have been trying to connect to the Portainer API, with no luck. I have never used HTTP bindings before(which might be my real problem here).
The procedure for the portainer API should be quite simple:
https://gist.github.com/deviantony/77026d402366b4b43fa5918d41bc42f8
Http bindings aren’t going to work well for this purpose - they’re not very good at authentication right now.
I’d recommend system.net.httpClient()
. You could wrap things in a class to make accessing the API a little friendlier:
class PortainerClient(object):
def __init__(self, baseUrl, username, password, **kwargs):
self.baseUrl = baseUrl
self.client = system.net.httpClient(**kwargs)
response = self.client.post(baseUrl + "auth", data={"Username": username, "Password": password})
self.token = response.json["jwt"]
def call(self, endpoint, method="GET", **kwargs):
headers = kwargs.get("headers", {})
headers["Authorization"] = "Bearer {}".format(self.token)
response = self.client.request(self.baseUrl + endpoint, method, headers=headers, **kwargs)
return response.json
client = PortainerClient("https://docker.ia.local/api/", "admin", "password", bypass_cert_validation=True)
print client.call("endpoints/1/docker/containers/json")
1 Like
tordvd
July 16, 2020, 8:53pm
3
That look very neat, I cant wait to thinker with that. Thanks alot @PGriffith !
I will post again when tested
tordvd
July 18, 2020, 7:14pm
4
Works great!
How would you use this in perspective to show live status of containers(?):
I am thinking a gateway event timer script. Then write to a dataset tag. But then the script would init every time, which is unnecessary since the token is valid for 8 hours?
Parallel to the status being updated. If I make buttons in perspective to start/stop containers. Should I run this script directly, or use the already obtained token. In the latter case I must store the token somewhere; normal tag database, or session custom props?
tordvd
July 19, 2020, 11:08am
5
I used a responsive view and made a (crude) interface:
Would be nice to get those state into the tag database for alarming though.
Maybe I will also add an interface for creating containers, maybe based on git repos.
1 Like
tordvd
July 22, 2020, 7:26pm
6
@PGriffith , do you have any idea why this wont work?
class PortainerClient(object):
def __init__(self, baseUrl, username, password, **kwargs):
self.baseUrl = baseUrl
self.client = system.net.httpClient(**kwargs)
response = self.client.post(baseUrl + "auth", data={"Username": username, "Password": password})
self.token = response.json["jwt"]
def call(self, endpoint, method="GET", **kwargs):
headers = kwargs.get("headers", {})
headers["Authorization"] = "Bearer {}".format(self.token)
response = self.client.request(self.baseUrl + endpoint, method, headers=headers, **kwargs)
return response.json
def post(self, endpoint, **kwargs):
headers = kwargs.get("headers", {})
headers["Authorization"] = "Bearer {}".format(self.token)
response=self.client.post(self.baseUrl + endpoint, headers=headers, **kwargs)
print response
return response.json
client = PortainerClient("http://MYIP:9000/api/", "admin", "password", bypass_cert_validation=True)
#create an exec instance
endpoint="endpoints/1/docker/containers/ba376d6b670b8aa946d1a26f28c781349be7b15753266aaf4dd78bcd85108dc5/exec"
data={ "AttachStdin":False,
"AttachStdout":True,
"AttachStderr":True,
"Tty":False,
"Cmd":['/bin/date'] }
returned=client.post(endpoint, data=data)
#Start the exec instance created above
endpoint="endpoints/1/docker/exec/"+str(returned['Id'])+"/start"
data = {"Detach": False,"Tty": False}
returned=client.post(endpoint,data=data)
print returned
print "\n"
I am always getting this error when running the last client.post()
Caused by: java.io.IOException: protocol error: Frame type(80) length(4740180) exceeds MAX_FRAME_SIZE(16384)
Try setting a -Djdk.httpclient.maxframesize=524288
in the JVM arguments of wherever you’re running the http client - if it’s on the gateway, it’ll be in ignition.conf
, in the wrapper.java.additional
parameters section.
tordvd
July 25, 2020, 9:37pm
8
Thanks, but i get exactly the same error.
I did like below, and rebooted the gateway. Im running in docker, but I guess it should not matter…
You mentioned where i run the http client, thats in the designer on a different computer. Where can I change the framesize for a client?
In the JVM arguments of the designer launcher configuration - the same argument without the wrapper.java.additional
; the entire remainder of the line starting with -D
should do it.