Ajout du support API v2 (package de diagnostic) et du log fichier
- AuditLogCLI.ps1 : detection auto V1/V2 avec fallback sur erreur HTTP - Téléchargement/extraction du zip de diagnostic - Extraction des événements connexion/déconnexion (logs eclypse_*.log et karaf.log) - Nettoyage automatique des fichiers temporaires - Écriture d'un fichier .log horodate en complement de la console - README.md : documentation FR/EN de la détection V1/V2
This commit is contained in:
+122
-9
@@ -3,11 +3,18 @@
|
||||
CLI d'export des journaux d'audit pour automates Distech Controls Eclypse.
|
||||
|
||||
.DESCRIPTION
|
||||
AuditLogCLI recupere les journaux d'audit (audit-logs) de chaque automate
|
||||
Distech Controls Eclypse liste dans un CSV d'entree, via leur API REST,
|
||||
et les enregistre au format CSV (un fichier par automate, ou un fichier
|
||||
AuditLogCLI recupere les journaux d'audit de chaque automate Distech
|
||||
Controls Eclypse liste dans un CSV d'entree, via leur API REST, et les
|
||||
enregistre au format CSV (un fichier par automate, ou un fichier
|
||||
consolide unique).
|
||||
|
||||
Detection automatique de la version d'API par automate :
|
||||
- API v2 (package de diagnostic) essayee en premier. Le zip retourne
|
||||
est extrait et les evenements connexion/deconnexion (logger
|
||||
DConnection) des logs eclypse_*.log et karaf.log sont convertis en CSV.
|
||||
- En cas d'erreur HTTP sur l'appel v2, bascule automatique sur
|
||||
l'API v1 (audit-logs), qui retourne directement un CSV.
|
||||
|
||||
.PARAMETER CsvInput
|
||||
Chemin vers le fichier CSV d'entree (separateur point-virgule).
|
||||
Colonnes obligatoires : Hostname, Current Ip, HttpPort, HttpsPort.
|
||||
@@ -46,9 +53,10 @@
|
||||
|
||||
.NOTES
|
||||
Prerequis : PowerShell 5.1+ (inclus dans Windows 10/11)
|
||||
API : Distech Controls Eclypse REST API v1
|
||||
Securite : TLS 1.2, certificats auto-signes acceptes
|
||||
Important : les noms de query params "startDate"/"endDate" sont une
|
||||
API : Distech Controls Eclypse REST API v1 (audit-logs) et v2
|
||||
(package de diagnostic), detection automatique par automate
|
||||
Securite : TLS 1.0/1.1/1.2, certificats auto-signes acceptes
|
||||
Important : les noms de query params "startDate"/"endDate" (v1) sont une
|
||||
hypothese non validee contre la documentation officielle de
|
||||
l'API audit-logs. A verifier avant utilisation en production.
|
||||
#>
|
||||
@@ -76,6 +84,8 @@ $ProgressPreference = 'SilentlyContinue'
|
||||
# UTILITAIRES
|
||||
# =====================================================================
|
||||
|
||||
$script:LogFilePath = Join-Path (Get-Location) "AuditLogCLI_$(Get-Date -Format 'yyyy-MM-dd_HH-mm').log"
|
||||
|
||||
function Write-Log {
|
||||
param(
|
||||
[string]$Message,
|
||||
@@ -86,6 +96,7 @@ function Write-Log {
|
||||
$tag = switch ($Level) { "INFO" {"[INFO ]"} "WARN" {"[WARN ]"} "ERROR" {"[ERR ]"} "OK" {"[ OK ]"} }
|
||||
$color = switch ($Level) { "INFO" {"Cyan"} "WARN" {"Yellow"} "ERROR" {"Red"} "OK" {"Green"} }
|
||||
Write-Host "$ts $tag $Message" -ForegroundColor $color
|
||||
Add-Content -Path $script:LogFilePath -Value "$ts $tag $Message" -Encoding UTF8
|
||||
}
|
||||
|
||||
# =====================================================================
|
||||
@@ -238,6 +249,81 @@ function Invoke-AuditLogGet {
|
||||
}
|
||||
}
|
||||
|
||||
# =====================================================================
|
||||
# FONCTIONS : API v2 (package de diagnostic)
|
||||
# =====================================================================
|
||||
function Get-DiagnosticPackageUrl {
|
||||
param([string]$BaseUrl)
|
||||
return "$BaseUrl/api/rest/v2/services/packages/diagnostic"
|
||||
}
|
||||
|
||||
function Invoke-DiagnosticGet {
|
||||
param(
|
||||
[string]$Url,
|
||||
[string]$Username,
|
||||
[AllowEmptyString()][string]$Password
|
||||
)
|
||||
$headers = Get-AuthHeader -Username $Username -Password $Password
|
||||
$zipPath = Join-Path $env:TEMP "AuditLogCLI_diag_$(Get-Random).zip"
|
||||
Invoke-WebRequest -Uri $Url -Method GET -Headers $headers -UseBasicParsing -TimeoutSec 120 -OutFile $zipPath
|
||||
return $zipPath
|
||||
}
|
||||
|
||||
function Expand-DiagnosticPackage {
|
||||
param(
|
||||
[string]$ZipPath,
|
||||
[string]$DestinationDir
|
||||
)
|
||||
Expand-Archive -Path $ZipPath -DestinationPath $DestinationDir -Force
|
||||
}
|
||||
|
||||
# =====================================================================
|
||||
# FONCTION : Get-ConnectionEvents
|
||||
# Extrait les evenements connexion/deconnexion (logger DConnection) des
|
||||
# logs eclypse_*.log et karaf.log d'un package de diagnostic V2 extrait
|
||||
# =====================================================================
|
||||
function Get-ConnectionEvents {
|
||||
param(
|
||||
[string]$LogDir,
|
||||
[string]$StartDate,
|
||||
[string]$EndDate
|
||||
)
|
||||
$logFiles = @(Get-ChildItem -Path $LogDir -Filter "eclypse_*.log" -ErrorAction SilentlyContinue)
|
||||
$karafLog = @(Get-ChildItem -Path $LogDir -Filter "karaf.log" -ErrorAction SilentlyContinue)
|
||||
$logFiles += $karafLog
|
||||
|
||||
$startDt = if ($StartDate) { [DateTime]::ParseExact($StartDate, "yyyy-MM-dd", $null) } else { $null }
|
||||
$endDt = if ($EndDate) { [DateTime]::ParseExact($EndDate, "yyyy-MM-dd", $null).AddDays(1) } else { $null }
|
||||
|
||||
$events = @()
|
||||
foreach ($logFile in $logFiles) {
|
||||
$hits = Select-String -Path $logFile.FullName -Pattern "DConnection.*'(.+?)' (connected|disconnected)"
|
||||
foreach ($hit in $hits) {
|
||||
$tsPart = $hit.Line.Split('|')[0].Trim()
|
||||
$ts = [DateTime]::MinValue
|
||||
if (-not [DateTime]::TryParseExact($tsPart, "yyyy-MM-ddTHH:mm:ss,fff", $null, [System.Globalization.DateTimeStyles]::None, [ref]$ts)) {
|
||||
continue
|
||||
}
|
||||
if ($startDt -and $ts -lt $startDt) { continue }
|
||||
if ($endDt -and $ts -ge $endDt) { continue }
|
||||
|
||||
$events += [PSCustomObject]@{
|
||||
Timestamp = $ts
|
||||
User = $hit.Matches[0].Groups[1].Value
|
||||
Action = $hit.Matches[0].Groups[2].Value
|
||||
SourceFile = $logFile.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
return @($events | Sort-Object Timestamp)
|
||||
}
|
||||
|
||||
function ConvertTo-DiagnosticCsv {
|
||||
param([array]$Events)
|
||||
if ($Events.Count -eq 0) { return "" }
|
||||
return ($Events | ConvertTo-Csv -NoTypeInformation | Out-String)
|
||||
}
|
||||
|
||||
# =====================================================================
|
||||
# VALIDATION DES PARAMETRES DE DATE
|
||||
# =====================================================================
|
||||
@@ -290,11 +376,38 @@ foreach ($automate in $automates) {
|
||||
}
|
||||
|
||||
$creds = Get-Credentials -Automate $automate -DefaultUsername $Username -DefaultPassword $Password
|
||||
$url = Get-AuditLogUrl -BaseUrl $baseUrl -StartDate $StartDate -EndDate $EndDate
|
||||
|
||||
Write-Log -Message "[$hostname] GET $url (user: $($creds.Username))" -Level INFO
|
||||
$content = $null
|
||||
$isV2 = $false
|
||||
$diagUrl = Get-DiagnosticPackageUrl -BaseUrl $baseUrl
|
||||
$zipPath = $null
|
||||
try {
|
||||
Write-Log -Message "[$hostname] GET $diagUrl (V2, user: $($creds.Username))" -Level INFO
|
||||
$zipPath = Invoke-DiagnosticGet -Url $diagUrl -Username $creds.Username -Password $creds.Password
|
||||
$isV2 = $true
|
||||
}
|
||||
catch {
|
||||
Write-Log -Message "[$hostname] V2 indisponible ($($_.Exception.Message)), bascule V1" -Level WARN
|
||||
}
|
||||
|
||||
$content = Invoke-AuditLogGet -Url $url -Username $creds.Username -Password $creds.Password
|
||||
if ($isV2) {
|
||||
$tempDir = Join-Path $env:TEMP "AuditLogCLI_$($ip)_$(Get-Random)"
|
||||
try {
|
||||
Expand-DiagnosticPackage -ZipPath $zipPath -DestinationDir $tempDir
|
||||
$events = Get-ConnectionEvents -LogDir (Join-Path $tempDir "logs") -StartDate $StartDate -EndDate $EndDate
|
||||
$content = ConvertTo-DiagnosticCsv -Events $events
|
||||
Write-Log -Message "[$hostname] $($events.Count) evenement(s) connexion/deconnexion extrait(s) (V2)" -Level OK
|
||||
}
|
||||
finally {
|
||||
Remove-Item -Path $zipPath -Force -ErrorAction SilentlyContinue
|
||||
Remove-Item -Path $tempDir -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
else {
|
||||
$url = Get-AuditLogUrl -BaseUrl $baseUrl -StartDate $StartDate -EndDate $EndDate
|
||||
Write-Log -Message "[$hostname] GET $url (V1, user: $($creds.Username))" -Level INFO
|
||||
$content = Invoke-AuditLogGet -Url $url -Username $creds.Username -Password $creds.Password
|
||||
}
|
||||
|
||||
if ($OutputFormat -eq "PerAutomate") {
|
||||
$filePath = Join-Path $outputDir "$ip.csv"
|
||||
|
||||
Reference in New Issue
Block a user