On Thu, Apr 22, 2021 at 6:24 AM Passerini Marco <marco.passer...@cscs.ch> wrote:
> Hi, > > > I made a python script which authenticates against my Guacamole instance > as guacadmin, lists existing connections and creates a new one. > Authentication and listing works fine, meanwhile creation does not work. > > I used this API specification: > https://github.com/ridvanaltun/guacamole-rest-api-documentation/blob/master/docs/CONNECTIONS.md#create-ssh-connection > > However the API documentation seems to be for 1.1.0 and I'm using 1.3.0. > I couldn't find anything more recent. > Am I missing some parameter? Where can I find a more recent documentation? > At the moment the project does not have any official REST API documentation. There are a couple of efforts going on to produce that documentation, but nothing, yet. So, if someone has documented it (as above), great, but it may not match up with the latest and greatest. That said, I don't think much changed between 1.1.0 and 1.3.0 from the REST API perspective, so, for the purposes of what you're doing, I don't think it should matter much. > The logged error is not very clear: > > > "org.codehaus.jackson.map.JsonMappingException: Can not instantiate value > of type [simple type, class > org.apache.guacamole.rest.connection.APIConnection] from JSON String; no > single-String constructor/factory method" > > > That is a obscure error - it indicates to me that something in the data you've provided is not the format it is expecting. > > > ###################################### > > import requests > from requests.auth import HTTPBasicAuth > import simplejson > > # authenticate > password = "" > with open('guacamole_password', "r") as fd: > password = fd.readline().rstrip() > > result = > requests.post('http://*****myserver******:8080/guacamole-1.3.0/api/tokens', > auth=HTTPBasicAuth('guacadmin', password), verify=False) > > auth_token = result.json()['authToken'] > data_source = result.json()['dataSource'] > > # list the existing connections > params = {'token': auth_token} > response = > requests.get('http://*****myserver******8080/guacamole-1.3.0/api/session/data/'+data_source+'/connections', > params=params, verify=False) > print(response.json()) > > > data = { > "parentIdentifier": "ROOT", > "name": "pythontest", > "protocol": "ssh", > "parameters": { > "port": "22", > "read-only": "", > "swap-red-blue": "", > "cursor": "", > "color-depth": "", > "clipboard-encoding": "", > "disable-copy": "", > "disable-paste": "", > "dest-port": "", > "recording-exclude-output": "", > "recording-exclude-mouse": "", > "recording-include-keys": "", > "create-recording-path": "", > "enable-sftp": "", > "sftp-port": "", > "sftp-server-alive-interval": "", > "enable-audio": "", > "color-scheme": "", > "font-size": "", > "scrollback": "", > "timezone": "", > "server-alive-interval": "", > "backspace": "", > "terminal-type": "", > "create-typescript-path": "", > "hostname": "148.187.98.221", > "host-key": "", > "private-key": "", > "username": "testuser", > "password": "testpassword", > "passphrase": "", > "font-name": "", > "command": "", > "locale": "", > "typescript-path": "", > "typescript-name": "", > "recording-path": "", > "recording-name": "", > "sftp-root-directory": "" > }, > "attributes": { > "max-connections": "", > "max-connections-per-user": "", > "weight": "", > "failover-only": "", > "guacd-port": "", > "guacd-encryption": "", > "guacd-hostname": "" > } > } > > First thing I'd say is you should remove any parameters that you're setting to empty values, unless you actually want an empty value. Otherwise you're just needlessly complicating the code. You do not have to provide a value for every parameter - just the ones you want to have something other than the default, which is NULL or False. > > data_json = simplejson.dumps(data) > headers = {'Content-type': 'application/json'} > response = > requests.post('http://*****myserver******:8080/guacamole-1.3.0/api/session/data/'+data_source+'/connections', > params=params, json=data_json, verify=False, headers=headers) > If I'm reading the Python Requests documentation directly, when you're using "json=data_json" in the post request, you actually do not want to do the "simplejson.dumps(data)" call. The "data" field already contains strict JSON data, and the json= parameter within requests.post is meant to send that directly without form encoding it. Have you tried just passing "json=data", bypassing the simplejson.dumps call? I'm honestly a little out of my league with this - I'm not all that familiar with Python, particularly the requests library, but that's really the only thing I can see. -Nick >