OPSI API

hawaii
Beiträge: 77
Registriert: 03 Dez 2013, 13:32

Re: OPSI API

Beitrag von hawaii »

So, irgendwo im requests Modul von python scheint da irgendwas schief zu gehen oder ich mach irgendwas bei der Nutzung falsch.
Hab das ganze jetzt mal mit httplib von Hand gebaut und siehe da, es funktioniert:

Code: Alles auswählen

import httplib
import json
import base64
import string

def main():
	payload = {"method": "authenticated","params": [],"id": 1,}
	auth = "Basic "+base64.encodestring('username:password')
	headers={'Content-type': 'application/json','Authorization':auth}
	conn = httplib.HTTPSConnection('opsi',4447)
	conn.request("POST", "/rpc",json.dumps(payload),headers)
	response = conn.getresponse()
	print response.status, response.reason
	data = json.loads(response.read())
	print data
	conn.close()

if __name__ == "__main__":
    main()
Und siehe da:

Code: Alles auswählen

200 OK
{"id": 1, "result": true, "error": null}
Benutzeravatar
n.wenselowski
Ex-uib-Team
Beiträge: 3194
Registriert: 04 Apr 2013, 12:15

Re: [Gelöst] OPSI API

Beitrag von n.wenselowski »

Aloha,

wenn du sowieso in Python programmierst, kannst du versuchen einfach mit einem der bereits vorhandenen Backends arbeiten - bspw. JSONRPC. Das spart das manuelle implementieren ;)
Aber dann hast du eben die Abhängigkeit zu python-opsi, welches momentan noch nicht standalone als Lib eingebunden werden kann.

Ich habe ganz kurz mit requests rumgespielt, man kann das automatische Entpacken scheinbar mit dem kwarg stream=True unterbinden, dann muss man sich aber manuell darum kümmern.


Gruß

Niko

Code: Alles auswählen

import OPSI
hawaii
Beiträge: 77
Registriert: 03 Dez 2013, 13:32

Re: [Gelöst] OPSI API

Beitrag von hawaii »

Danke für den Hinweis. Die Abhängigkeit zur python-opsi ist in diesem Fall leider schlecht, weil ich die Anfrage von einem anderen Server starten muss und somit auf eine Lib angewiesen bin.
Hab die Sache mit dem kwarg stream=True und die von "requests" empfohlene Methode den raw Stream in ein File zu schreiben getestet (http://docs.python-requests.org/en/late ... se-content). Raw Data kommt jetzt tatsächlich auch an und ich kann sie mit

Code: Alles auswählen

repr(response.raw.read())
auch sehen, aber es besteht dann trotzdem ein Problem mit dem encoding.

Aber ich verzichte für den Fall dann einfach auf "requests" und bau mir das selbst, funtkioniert ja jetzt auch und für meinen Einsatzzweck reicht es dann auch ;-)

Danke noch mal!
Benutzeravatar
ueluekmen
uib-Team
Beiträge: 1939
Registriert: 28 Mai 2008, 10:53

Re: [Gelöst] OPSI API

Beitrag von ueluekmen »

Kleiner Tip. Wir haben für den opsi-nagios-connector ein plugin geschrieben, welches du als Basis nutzen kannst. Dort haben wir auch keine Abhängigkeit zu python-opsi drin, weil man auf dem Monitoring-Server in der Regel kein OPSI einspielt.

Leider haben wir den Code nicht im öffentlichen svn, du kannst dir aber das Paket installieren und dir danach den Code vom Plugin anschauen.

Das Paket findest du zum Beispiel hier:
http://download.opensuse.org/repositori ... -1_all.deb
opsi support - uib gmbh
For productive opsi installations we recommend support contracts.
http://www.uib.de
hawaii
Beiträge: 77
Registriert: 03 Dez 2013, 13:32

Re: [Gelöst] OPSI API

Beitrag von hawaii »

Danke für den Tipp!

So und nun hätte ich doch noch eine hoffentlich letzte Frage. Ich will die rpc Abfragen ungern mit einem Admin Account laufen lassen, sonder am liebsten mit einem Read-only-Account.
Ich hab im Interface auch eine Abfragemethode

Code: Alles auswählen

{ "method": "userIsReadOnlyUser",
   "params": [],
   "id": 1 }
gefunden, also geh ich davon aus das geht.

Allerdings wo und wie muss ich den User anlegen?
Benutzeravatar
n.wenselowski
Ex-uib-Team
Beiträge: 3194
Registriert: 04 Apr 2013, 12:15

Re: OPSI API

Beitrag von n.wenselowski »

Hallo,

das ist ein zu recht undokumentiertes Feature, da es nicht durchgängig implementiert ist.
Deshalb ist das folgende ohne Gewähr, dass es wie gewünscht funktioniert!
Wer sein Glück trotzdem versuchen will, kann den Namen der Gruppe mit Read-Only-Usern in die opsi.conf unter groups mit dem Schlüssel readonly eintragen.
Der Benutzer ist ein normaler Linux-User, der dann in dieser Gruppe sein muss.


Gruß

Niko

PS: Um Mark Twain zu zitieren: Explore dream discover. :)

Code: Alles auswählen

import OPSI
hawaii
Beiträge: 77
Registriert: 03 Dez 2013, 13:32

Re: OPSI API

Beitrag von hawaii »

Und ich hab wie es aussieht genau die Methode erwischt bei der es nicht funktioniert :D
Wenn ich die Methode "getMacAddresses_list" verwende bekomme ich keine Daten aber "userIsReadOnlyUser" gibt True zurück, so dass es an sich auf jeden Fall funktioniert.

Auf jeden Fall vielen Dank für den Hinweis und vielleicht kann ich es ja mal noch an anderer Stelle gebrauchen. Trotzdem muss ich loswerden, dass es sicherheitstechnisch natürlich schon "leicht katastrophal" ist, dass
man keinen reinen API User mit eingeschränkten Methoden anlegen kann, denn Methoden wie "deleteServer" können einem da auch mal ganz schnell zum Verhängnis werden....
Vielleicht mag man sich ja da bei Gelegenheit mal Gedanken zu machen :-)

Trotzdem mag ich OPSI, also seht es als konstruktive Kritik ;-)

Grüßle,
Kai
Benutzeravatar
ueluekmen
uib-Team
Beiträge: 1939
Registriert: 28 Mai 2008, 10:53

Re: OPSI API

Beitrag von ueluekmen »

Hallo Kai,

deine Kritik ist berechtigt. Zu unserer Verteidigung muss ich allerdings sagen/schreiben, dass opsi nicht wirklich ein Rollenkonzept hat. Wir haben das Konzept dazu schon vor Jahren geschrieben und bepreist. Wie es aber so häufig ist, war dieses Konzept, wenn es um das Thema Geld geht, gar nicht mehr so wichtig. :roll:

WIr haben das readOnlyUser Konstrukt für den configed implementiert. Das ist mehr safety als security. Es sollte nicht als Schutz der API angesehen werden.

Wir planen demnächst wieder eine neue Anwenderbefragung, dort werden auch nochmal die ganzen geplanten Implementierungen abgefragt. Das Rollenkonzept wird wahrscheinlich auch hier wieder mit aufgeführt. Also, sobald die Befragung wieder startet, bitte alle mitmachen, damit wir wieder ein möglichst genaues Bild der Anforderung unserer Anwender bekommen und unserer Priorisierungen dementsprechend anpassen.
opsi support - uib gmbh
For productive opsi installations we recommend support contracts.
http://www.uib.de
justcoding
Beiträge: 4
Registriert: 10 Apr 2015, 14:15

Re: OPSI API

Beitrag von justcoding »

dkoch hat geschrieben:Schuss ins Blaue ohne es genau zu wissen:

Lass mal

Code: Alles auswählen

'Content-Encoding': 'gzip'
weg.

Sieht so aus als würde hier versucht werden etwas zu decomprimieren, was nicht comprimiert ist
Guter Schuss - und fast das Blaue getroffen! Sorry, daß ich mich erst jetzt melde, aber dafür mit einer Lösung.

Die Schnittstelle

Code: Alles auswählen

/rpc?{methoden und parameter} 
antwortet dem Browser tatsächlich komprimiert. Allerdings gibt es einen kleinen bug on Worker.py: die Kompression wird als gzip angekündigt, tatsächlich wird zlib.compress verwendet:

Code: Alles auswählen

 result.stream = stream.IByteStream(zlib.compress(toJson(response).encode('utf-8'), level)) 
(use the source, luke :-)
zlib.compress kann indes nur deflate, und nicht gzip.

Weiter vorn werden die Browser capabilities abgefragt, und zwar erst deflate, und dann gzip. Kann der Browser beides, wird gzip gemeldet, und das finden die Browser (alle) nicht witzig.
Nebenbei bemerkt scheint es sowohl dem OPSI Client Agent als auch dem Winst sch...egal zu sein, ob deflate, gzip oder nix angemeldet wird - sie rechnen mir deflate und basta. Wird nämlich die Kompression ganz abgeschaltet, kommen die Browser klar, aber der Winst bricht ab. Nich gut :-)

Mein Patch also:

Code: Alles auswählen

--- a/Service/Worker.py
+++ b/Service/Worker.py
@@ -561,10 +561,11 @@ class WorkerOpsiJsonRpc(WorkerOpsi):
                
                encoding = None
                try:
-                       if ('deflate' in self.request.headers.getHeader('Accept-Encoding')):
-                               encoding = 'deflate'
+                       # UH 2015-04 the encoding done by zlib below does deflate OLNY - so please answer "deflate"
                        if ('gzip' in self.request.headers.getHeader('Accept-Encoding')):
                                encoding = 'gzip'
+                       if ('deflate' in self.request.headers.getHeader('Accept-Encoding')):
+                               encoding = 'deflate'
                except Exception, e:
                        pass
                if not encoding:
Die Erkennung der Accept-Encoding Header wird umgekehrt. Jetzt wird (korrekt) deflate gemeldet, wenn deflate akzeptiert wird. Der Browser kommt klar, Winst auch.
(Ungelöst: wenn der Browser nur gzip akzeptiert, wird weiter gzip gemeldet, aber deflate gesendet. Vielleicht sollte man gzip ganz streichen - was Winst dan macht, habe ich nicht getestet.)

happy patching!
hawaii
Beiträge: 77
Registriert: 03 Dez 2013, 13:32

Re: OPSI API

Beitrag von hawaii »

Danke für den Hinweis, hat mir gestern geholfen, dass ganze nach dem Update auf 4.0.6 wieder zum laufen zu kriegen.
Antworten