Methode fireEvent funktioniert nicht in der Client API

Antworten
larsg
Beiträge: 283
Registriert: 16 Dez 2014, 18:06

Methode fireEvent funktioniert nicht in der Client API

Beitrag von larsg »

Hallo zusammen,


kurz was zum Thema:

Wir haben etliche Rechner im HomeOffice und möchten die Clients remote in den WAN-Modus umstellen. Die Rechner sind über ein VPN-Netz erreichbar, jedoch ändert sich häufig die IP-Adresse, weswegen der Server in der Regel den Client nicht erreichen kann, da ihm die aktuell gültige IP nicht bekannt ist. Wir stellen also im ConfigEd den WAN-Modus ein und wollen nun auf dem Client das Event "silent_install" auslösen um so herum die Einstelllungen für den WAN-Modus direkt auf die Rechner zu bringen.

Wir haben ein Powershell Modul, mit dem wir die API von OPSI ansprechen, bislang eigentlich nur gedacht für Anfragen an den Server.
Um die Umstellung der Clients zu automatisieren haben wir das Powershell Modul entsprechend erweitert, so dass wir auch die Client API ansprechen können.

Wir sind davon ausgegangen, das wie auch Im Webinterface des Servers die Bennennung der Methoden 1:1 übernommen werden müssen um die API über die RPC-Schnittstelle ansprechen zu können - im Webinterface haben wir so die Methode "fireEvent" gefunden.

Folgendes haben wir soweit probiert (an Anfragen an die OPSI Client API):



backend_info:

Code: Alles auswählen

Connect-OPSI -Adress client.fqdn -Port 4441
Invoke-OPSIClientBackendInfo

opsiVersion realmodules                                modules
----------- -----------                                -------
4.1.1.58    @{vpn=3000; uefi=3000; mysql_backend=3000} @{local_imaging=False; swondemand=True; wim-capture=False; roaming_profiles=Tru (...)

fireEvent:

Code: Alles auswählen

Connect-OPSI -Adress client.fqdn -Port 4441
Invoke-OPSIClientFireEvent -Event "silent_install"

Opsi rpc error: Method 'fireEvent' is not valid
Es scheint als wäre nur ein Teil der Methoden der Client-API über die RPC-Schnittstelle verfügbar.


Powershell Modul:

Code: Alles auswählen

Function Invoke-OPSIClientFireEvent {
    Param (
		[Parameter(Mandatory=$True)] [System.String] $Event
    )
    $Method = "fireEvent"
    $Params = @(
        $Event
    )
    Return Request-OPSI
}
Function Invoke-OPSIClientBackendInfo {
    $Method = "backend_info"
    $Params = @(
    )
    Return Request-OPSI
}
Function Connect-OPSI {
    Param (
		[Parameter(Mandatory=$True)] [System.String] $Address,
		[Parameter(Mandatory=$False)] [System.String] $Port,
		[Parameter(Mandatory=$False)] [System.Management.Automation.PSCredential] $Credential = (Get-Credential -Message "OPSI Backend")
	)
    #$ErrorActionPreference = "SilentlyContinue"
	$Object = (New-Object PSObject | 
    Add-Member -PassThru NoteProperty method "authenticated" | 
    Add-Member -PassThru NoteProperty params @() | 
    Add-Member -PassThru NoteProperty id '1'
    ) | ConvertTo-Json -depth 3
	[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$True}
	$Global:OPSIService = "https://$($Address):$($Port)/rpc"
    Try {
        $Response = Invoke-WebRequest -URI $Global:OPSIService -SessionVariable 'Session' -Credential $Credential -Body $Object -ContentType "application/json" -Method 'POST'
    }
    Catch [System.Net.WebException] {
        If ($OPSIJson = ($_ | ConvertFrom-Json)) {
            If ($OPSIError = ($OPSIJson | Select-Object -expand error)) { Write-Host $OPSIError.message }
            Else { Write-Host "Unknown Error" }
        }
        Else {
            Write-Host $_.Exception.GetType().FullName+" : "+$_.Exception.Message
        }
    }
    If ($Response) {
        If ($OPSIJson = ($Response | ConvertFrom-Json)) {
            If ($OPSIError = ($OPSIJson | Select-Object -expand error)) { Write-Host $OPSIError.message }
            If (($OPSIJson | Select-Object -expand result) -eq "True") {
                $Global:OPSISession = $Session
                Return "Authentication succeeded!"
            }
            Else {
                Return "Authentication failed!"
            }
        }
    }
}
Function Request-OPSI {
    $Object = (New-Object PSObject | 
    Add-Member -PassThru NoteProperty method $Method | 
    Add-Member -PassThru NoteProperty params $Params | 
    Add-Member -PassThru NoteProperty id '1'
    ) | ConvertTo-Json -depth 3
    Try {
        $Response = Invoke-WebRequest -URI $Global:OPSIService -WebSession $Global:OPSISession -Body $Object -ContentType "application/json" -Method 'POST'
    }
    Catch [System.Net.WebException] {
        If ($OPSIJson = ($_ | ConvertFrom-Json)) {
            If ($OPSIError = ($OPSIJson | Select-Object -expand error)) { Write-Host $OPSIError.message }
            Else { Write-Host "Unknown Error" }
        }
        Else {
            Write-Host $_.Exception.GetType().FullName+" : "+$_.Exception.Message
        }
    }
    If ($Response) {
        If ($OPSIJson = ($Response | ConvertFrom-Json)) {
            If ($OPSIError = ($OPSIJson | Select-Object -expand error)) { Write-Host $OPSIError.message }
            Return $OPSIJson | Select-Object -expand result
        }
    }
}
mattiasmab
Beiträge: 90
Registriert: 29 Jan 2021, 12:17

Re: Methode fireEvent funktioniert nicht in der Client API

Beitrag von mattiasmab »

Vermutlich etwas spät, aber da ich gestern vor dem selben Problem stand, habe ich etwas recherchiert. Da an anderer Stelle die Nutzung des Tools opsiclientd_event_starter als alternative gezeigt wurde, habe ich mir angesehen, was der aufruft (siehe Quellcode bei GitHub).

Im Grunde muss nur das "/rpc" bei der Adresse durch ein "/opsiclientd" ersetzt werden. Dann geht es - übrigens mit Adminlogin oder auch mit OpsiClientID+OpsiKey (beides im opsiConfigEd zu finden), wobei die Admin-Kennung bei den meisten generischer wäre.

Code: Alles auswählen

Invoke-WebRequest -Uri 'https://localhost:4441/opsiclientd' -Method 'POST' -Body $Body -ContentType "application/json-rpc" -Headers $Headers

# Bedeutet im genannten Script muss:
$Global:OPSIService = "https://$($Address):$($Port)/rpc"
# durch folgendes ersetzt werden
$Global:OPSIService = "https://$($Address):$($Port)/opsiclientd"
Zu guter Letzt ist es natürlich auch möglich (wenn auch nicht als wirkliches JSON-RPC) die Methode über die lokale Interface-Seite aufzurufen. Entweder im Browser oder interaktiv durch z.B. ebenfalls die Powershell wie folgt:

Code: Alles auswählen

[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$True}
Invoke-WebRequest -UseBasicParsing -Uri "https://localhost:4441/interface?{%20%22id%22:%201,%20%22method%22:%20%22fireEvent%22,%20%22params%22:%20[%22on_demand%22]%20}" -Credential Administrator
(Optional natürlich mit deaktiviertem Zertifikatscheck wie vielerorts gemacht/angemerkt.)
Antworten