OPSI RPC Call SessionID

Antworten
niebo
Beiträge: 2
Registriert: 10 Jul 2014, 17:02

OPSI RPC Call SessionID

Beitrag von niebo »

Hallo zusammen,

ich bin gerade dabei eine abgespeckte Variante eines OPSI Clients in Python zu programmieren der lediglich ein paar kleine Grundfunktionalitäten enthalten soll (z.b. eine Nachricht an den Client senden oder grundlegende Systeminformationen abfragen).

Das Abfragen der API vom Client zum Server funktioniert soweit ganz gut. Ich kann also mittels Python z.B. prüfen ob ich authentifiziert bin oder nicht. Der umgekehrte Weg macht mir allerdings noch Probleme.

Ich habe den gewünschten Client manuell über das Webinterface mit entsprechender IP und Hostnamen angelegt und mir auf diesem Client einen SSL Socket auf Port 4441 geöffnet. Wenn ich nun den Client im Webinterface auswähle und versuche eine Nachricht zu senden, sehe ich auch problemlos den RPC-Call den der Server an den Client sendet.
b'POST /opsiclientd HTTP/1.1\r\nHost: <IP>:4441\r\nAccept-Encoding: identity\r\ncontent-type: application/json-rpc\r\ncontent-length: 53\r\nAuthorization: Basic OjFjZDkxODYwMDRmZTM4YTUzZWYzMjkwYzhlMWEyMjQy\r\n\r\n'
b'{"params": ["Test123"], "id": 1, "method": "showPopup"}'
Die große Frage ist nun wie antworte ich darauf damit der OPSI Server zufrieden ist. Alles was ich bisher versucht habe endet damit das OPSI nach 20 Sekunden einen Timeout anzeigt, weil er keine passende Rückmeldung bekommen hat.

Nach den Logeinträgen und Wireshark Sniffs zu schlussfolgern, braucht OPSI wohl eine SessionID welche wohl vom Server generiert wird und dann bei der Antwort mitgegeben werden muss. Gibt es irgendwie die Möglichkeit diese SessionID zu erstellen oder abzurufen ?
[4] [Jul 10 15:20:10] Failed to read opsi modules file '/etc/opsi/modules': [Errno 2] No such file or directory: u'/etc/opsi/modules' (Backend.py|365)
[5] [Jul 10 15:20:10] New session created (session.py|75)
[5] [Jul 10 15:20:10] Application 'opsi config editor 4.0.4.1.3' on client '<IP>' supplied non existing session id: RsNKWbQG6G92ZXQnyHSuUroehbulroVn (Worker.py|392)
[5] [Jul 10 15:20:10] Authorization request from <USER>@<IP> (application: opsi config editor 4.0.4.1.3) (workers.py|192)
[4] [Jul 10 15:20:10] Failed to read opsi modules file '/etc/opsi/modules': [Errno 2] No such file or directory: u'/etc/opsi/modules' (Backend.py|365)
[4] [Jul 10 15:20:10] Failed to read opsi modules file '/etc/opsi/modules': [Errno 2] No such file or directory: u'/etc/opsi/modules' (Backend.py|365)
[5] [Jul 10 15:20:10] Disabling mysql backend and license management module: no customer in modules file (MySQL.py|435)
[5] [Jul 10 15:20:10] -----> Executing: hostControl_showPopup(u'Test123', [u'<HOSTNAME>']) (JsonRpc.py|125)
[3] [Jul 10 15:20:30] Rpc to host <HOSTNAME> (address: <IP>) timed out after 20.03 seconds, terminating (HostControl.py|233)
Ich hoffe ihr könnt mir helfen :)
Schon mal vielen Dank im Voraus
Benutzeravatar
n.wenselowski
Ex-uib-Team
Beiträge: 3194
Registriert: 04 Apr 2013, 12:15

Re: OPSI RPC Call SessionID

Beitrag von n.wenselowski »

Hallo,

soweit ich weiss, muss keine Session ID mitgegeben werden und der Client sollte auch ohne entsprechende ID antworten.
Aber ich lasse mich hier gerne von ueluekmen berichtigen ;)

Folgender Curl-Aufruf funktioniert bspw:

Code: Alles auswählen

curl --insecure -X POST --user admin:pw -H "Content-Type: application/json" -d '{"params": [], "id": 1, "method": "backend_info"}' https://testclient.uib.local:4441/rpc
Mit showPopup hatte ich zumindest mit curl auf die Schnelle auch keinen Erfolg.

Antwortet der Client denn sofort auf eine entsprechende Antwort?

Gruß

Niko

Code: Alles auswählen

import OPSI
niebo
Beiträge: 2
Registriert: 10 Jul 2014, 17:02

Re: OPSI RPC Call SessionID

Beitrag von niebo »

Guten Morgen,
n.wenselowski hat geschrieben:
Folgender Curl-Aufruf funktioniert bspw:

Code: Alles auswählen

curl --insecure -X POST --user admin:pw -H "Content-Type: application/json" -d '{"params": [], "id": 1, "method": "backend_info"}' https://testclient.uib.local:4441/rpc
Mit showPopup hatte ich zumindest mit curl auf die Schnelle auch keinen Erfolg.

Antwortet der Client denn sofort auf eine entsprechende Antwort?
also ich habe deinen curl Befehl nun mal vom OPSI-Server zu meinem Client (wo der RPC-Server läuft) geschickt und ich bekomme folgende Rückmeldung:
<?xml version='1.0'?>
<methodResponse>
<fault>
<value><struct>
<member>
<name>faultString</name>
<value><string><class 'xml.parsers.expat.ExpatError'>:not well-formed (invalid token): line 1, column 0</string></value>
</member>
<member>
<name>faultCode</name>
<value><int>1</int></value>
</member>
</struct></value>
</fault>
</methodResponse>
Leider kann ich damit nicht viel anfangen. Google sagt dazu das es sich wohl um ein Sonderzeichen handelt welches Probleme macht. Allerdings sende ich ja nichts außer der Methode und den Parametern.

Wenn ich über das Webinterface von OPSI eine Nachricht an den Client senden will oder sonst eine Aktion ausführen will, bekomme ich die Meldung "No JSON Object could be decoded"
und zusätzlich sagt der RPC-Server "POST /opsiclientd HTTP/1.1" 404 -". Das verwundert mich ein wenig da ich extra "/opsiclientd" als rpc_path angegeben habe.

Hier mal der Python 3 Code vom Server. Vielleicht habe ich ja Tomaten auf den Augen und habe etwas grundlegendes vergessen:

Code: Alles auswählen

import xmlrpc
from xmlrpc.server import SimpleXMLRPCServer as Server
from xmlrpc.server import SimpleXMLRPCRequestHandler as Handler
import ssl

# Paths
Server.rpc_paths = ('/','/opsiclientd')
#Handler.encode_threshold = 1400

def showPopup():
    print("Es wurde ein PopUp angefordert")

context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.load_cert_chain(certfile="cert.pem", keyfile="key.pem")

srv = Server(("<IP-DES-CLIENTS>",4441))
srv.socket = context.wrap_socket(srv.socket)
srv.register_function(showPopup)
#srv.register_instance(showPopup)
srv.serve_forever()
Vielen Dank nochmal für deine/eure Hilfe :)

edit:

So ich habe noch ein wenig rumgespielt und habe nun das Problem mit dem 404 Fehler aus der Welt geschafft. Ebenso kann ich nun mit einem Python-Client beim Server anfragen und bekomme eine "None" Antwort.

Hier der aktuelle Server

Code: Alles auswählen

from xmlrpc.server import SimpleXMLRPCServer
from xmlrpc.server import SimpleXMLRPCRequestHandler
import ssl

# Restrict to a particular path.
class RequestHandler(SimpleXMLRPCRequestHandler):
    rpc_paths = ('/','/opsiclientd',)

# Create server
server = SimpleXMLRPCServer(("<IP_DES_CLIENTS>", 4441),
                            requestHandler=RequestHandler,
                            allow_none=True,
                            encoding='utf-8')

# SSL Stuff - Start
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.load_cert_chain(certfile="cert.pem", keyfile="key.pem")

server.socket = context.wrap_socket(server.socket)
# SSL Stuff - End

#server.register_introspection_functions()


def hostControl_showPopup():
    print("Es wurde ein PopUp angefordert")
    
server.register_function(hostControl_showPopup, 'showPopup')

server.register_instance(hostControl_showPopup)

server.serve_forever()
Nun zeigt das Webinterface von OPSI mir leider immer noch die Meldung "No JSON Object could be decoded". Und ist es möglich Returnwerte für eine Funktion anzugeben, so das nicht nur einfach None ankommt beim Anfragenden ?
Benutzeravatar
n.wenselowski
Ex-uib-Team
Beiträge: 3194
Registriert: 04 Apr 2013, 12:15

Re: OPSI RPC Call SessionID

Beitrag von n.wenselowski »

Hallo,
niebo hat geschrieben:Nun zeigt das Webinterface von OPSI mir leider immer noch die Meldung "No JSON Object could be decoded". Und ist es möglich Returnwerte für eine Funktion anzugeben, so das nicht nur einfach None ankommt beim Anfragenden ?
Das sollte auch möglich sein, hängt aber ab von dem Framework ab, was du verwendest. ;)
Ich würde mal versuchen sowas wie

Code: Alles auswählen

return json.dumps({"foo": "bar"})

Gruß

Niko

Code: Alles auswählen

import OPSI
Antworten