Beide Seiten der vorigen RevisionVorhergehende Überarbeitung | Letzte ÜberarbeitungBeide Seiten der Revision |
debian-kvm-omnivista-labor [2016/09/10 13:54] – [OmniVista RESTful API mit Python ansprechen] benny | debian-kvm-omnivista-labor [2016/09/10 14:06] – benny |
---|
disk1.qcow2 disk2.qcow2 ovnmse-4.2.1.R01-65.0.mf ovnmse-4.2.1.R01-65.0.ovf | disk1.qcow2 disk2.qcow2 ovnmse-4.2.1.R01-65.0.mf ovnmse-4.2.1.R01-65.0.ovf |
benny@n-kvm1:~/OV$ | benny@n-kvm1:~/OV$ |
</code> | |
| |
====== OmniVista RESTful API mit cURL ansprechen ====== | |
| |
Ich empfehle beim Einsatz von "cURL" auch die Installation und Verwendung von [[https://stedolan.github.io/jq/|jq]], da die längeren json-Ausgaben sonst schnell unübersichtlich werden. | |
| |
In den Beispielen habe ich die Ausgabe von cURL reduziert. Für den Fall dass man noch etwas entwickelt, macht es mehr Sinn sich mit "-i" und "-v" zusätzliche Informationen ausgeben zu lassen. | |
| |
Kurze Referenz was sich hinter den Optionen von cURL verbirgt (für alles weitere ''$ man curl''): | |
| |
* -d = Daten die man übertragen möchte | |
* -F = Überträgt die Daten als wenn sie aus einem Formular kommen (<form>) im multipart/form-data Format | |
* -i = HTTP Response Ausgaben anzeigen | |
* -H = Header festlegen (kann mehrfach für mehrere Header verwendet werden) | |
* -k = Unsichere Verbindung ignorieren (https mit self-signed im Labor) | |
* -s = Keine Ausgaben außer dem Ergebnis auf der Console ausgeben (übersichtlicher) | |
* -v = Mehr Details anzeigen (kann mehrfach verwendet werden -vvv) | |
* -X = HTTP Methode (GET, POST, PUT, DELETE) | |
| |
===== Anmeldung an der API von OmniVista 2500 v4.2.1 ===== | |
| |
<code bash> | |
BennyE$ curl -s -k -H "Content-Type: application/json" -H "Ov-App-Version:4.2.1.R01" -X POST -d '{"userName":"admin","password":"PASSWORD"}' https://192.168.40.12/api/login | jq . | |
{ | |
"message": "login.success", | |
"accessToken": "Authorization: 450d7a34-5dc7-4f1e-a01f-29556864eb59" | |
} | |
</code> | |
| |
===== Anlegen einer neuen statischen Map (ohne Hintergrundbild) ===== | |
| |
<WRAP center round tip 60%> | |
Eine neue Map anzulegen ist es umfangreicher. Das folgende Format sorgt dafür dass alle Anforderungen der API, z.B. an multipart/form-data mit korrekter Boundary erfüllt sind. Man muss also die Information zum Hintergrundbild übergeben, obwohl man gar keines haben möchte. | |
</WRAP> | |
| |
<WRAP center round info 60%> | |
Eine Map kann nur vom Benutzer "admin" angelegt werden. | |
</WRAP> | |
| |
| |
<code bash> | |
BennyE$ curl -s -k -H "Authorization: Bearer 450d7a34-5dc7-4f1e-a01f-29556864eb59" -H "Ov-App-Version:4.2.1.R01" -F "file=null" -F map='{ "TopologyMapVO": { "version": 0, "mapName": "Unprovisioned Devices", "backgroundImage": "", "backgroundImageUrl": "", "backgroundColor": "", "filter": null, "dynamicMap": false, "physicalNetworkMap": false, "autoCreatedDynamicMap": false, "ownerInfo": "", "mapNodeCollection": { "nodeList": [ ] } } };type=application/json' https://192.168.40.12/api/topology/maps | jq . | |
{ | |
"status": "SUCCESS", | |
"statusCode": 201, | |
"type": "TopologyBaseResponse", | |
"response": { | |
"multipleResult": false, | |
"resultList": [], | |
"operation": "CREATE", | |
"uniqueName": "57d404d3e4b0d545f07f47db", | |
"displayName": "Unprovisioned Devices", | |
"mapVersion": null, | |
"success": true, | |
"message": { | |
"params": [ | |
"Unprovisioned Devices" | |
], | |
"code": "topology.db.create.map.success" | |
}, | |
"additionParams": {}, | |
"translated": { | |
"additionParams": {}, | |
"operationTranslated": "CREATE", | |
"successTranslated": "Success", | |
"resultList": [], | |
"messageTranslated": "Successfully created map Unprovisioned Devices" | |
} | |
}, | |
"serverVersion": "4.2.1.R01" | |
} | |
</code> | |
| |
===== Anlegen einer neuen statischen Map (mit Hintergrundbild) ===== | |
<WRAP center round tip 60%> | |
Die Datei "Picture1.png" muss natürlich auch für den Upload zur Verfügung stehen, siehe erster -F Eintrag, "file=". Im zweiten -F Eintrag "map=" muss bei backgroundImage der Dateiname auch noch hinzugefügt werden. | |
</WRAP> | |
| |
<WRAP center round info 60%> | |
Eine Map kann nur vom Benutzer "admin" angelegt werden. | |
</WRAP> | |
| |
<code bash> | |
BennyE$ curl -s -k -H "Authorization: Bearer 450d7a34-5dc7-4f1e-a01f-29556864eb59" -H "Ov-App-Version:4.2.1.R01" -F "file=@Picture1.png" -F map='{ "TopologyMapVO": { "version": 0, "mapName": "Unprovisioned Devices Picture", "backgroundImage": "Picture1.png", "backgroundImageUrl": "", "backgroundColor": "", "filter": null, "dynamicMap": false, "physicalNetworkMap": false, "autoCreatedDynamicMap": false, "ownerInfo": "", "mapNodeCollection": { "nodeList": [ ] } } };type=application/json' https://192.168.40.12/api/topology/maps | jq . | |
{ | |
"status": "SUCCESS", | |
"statusCode": 201, | |
"type": "TopologyBaseResponse", | |
"response": { | |
"multipleResult": false, | |
"resultList": [], | |
"operation": "CREATE", | |
"uniqueName": "57d40e32e4b0d545f07f47de", | |
"displayName": "Unprovisioned Devices Picture", | |
"mapVersion": null, | |
"success": true, | |
"message": { | |
"params": [ | |
"Unprovisioned Devices Picture" | |
], | |
"code": "topology.db.create.map.success" | |
}, | |
"additionParams": {}, | |
"translated": { | |
"additionParams": {}, | |
"operationTranslated": "CREATE", | |
"successTranslated": "Success", | |
"resultList": [], | |
"messageTranslated": "Successfully created map Unprovisioned Devices Picture" | |
} | |
}, | |
"serverVersion": "4.2.1.R01" | |
} | |
</code> | |
| |
====== OmniVista RESTful API mit Python ansprechen ====== | |
<WRAP center round important 60%> | |
Meine Versuche mit cURL haben mir gezeigt dass für Python noch einiges anders laufen muss. Kümmere mich bei nächster Gelegenheit darum das zu entwickeln. | |
</WRAP> | |
| |
<code python> | |
import requests | |
import json | |
| |
# Dieser Code geht sicherlich schoener, aber fuer den Moment ist das nur POC | |
| |
ovurl = "https://192.168.5.10" | |
a = requests.Session() | |
| |
# Boese, niemals verify=False in Produktion! | |
#b = a.post(ovurl + "/api/login", verify=False) | |
| |
rbody = { | |
'userName': 'admin', | |
'password': 'your_password' | |
} | |
| |
header = { | |
"content-type": "application/json" | |
} | |
| |
# Boese, niemals verify=False in Produktion! | |
# "data" nur als json-Format uebergeben | |
b = a.post(ovurl + "/api/login", data=json.dumps(rbody), verify=False, headers=header) | |
#>>> b | |
#<Response [200]> | |
| |
#>>> b.text | |
#'{"message":"login.success","accessToken":"dc51d6f3-f8e8-4f66-adbd-c251307714aa"}' | |
| |
c = a.get(ovurl + "/api/devices", verify=False, headers=header) | |
| |
# Wer sich wundert dass dies einfach funktioniert .. | |
# Es gibt einen Cookie mit dem accessToken | |
| |
#>>> a.cookies | |
#<RequestsCookieJar[Cookie(version=0, name='JSESSIONID', value='00AFEF32E0503727756885368419BC17', port=None, port_specified=False, domain='192.168.5.10', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False), Cookie(version=0, name='accessToken', value='dc51d6f3-f8e8-4f66-adbd-c251307714aa', port=None, port_specified=False, domain='192.168.5.10', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False)]> | |
| |
| |
parsed = json.loads(c.text) | |
print(json.dumps(parsed, indent=4)) | |
| |
</code> | </code> |
| |
| |
| |