diff --git a/README.md b/README.md index e69de29..00332f2 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,65 @@ +# Usage + +Ce script Powershell permet de créer un point d'écoute pour permettre un check agent via un serveur HAProxy. +Le script calcule automatiquement le poids de la machine sur lequel il tourne en vérifiant l'usage RAM et / ou CPU selon des critères de facteur d'importance, de valeur de réference pour le calcul ou de limite haute forçant le mode drain (aucune nouvelle connexion depuis haproxy) + + + +# Fonctionnement + +Ce script créé un point d'écoute TCP sur un port donné. +Lorsqu'un client s'y connecte, il lance le calcul du poids puis renvoie l'information sous un format de tableau de bytes suivi d'un retour à la ligne. +Lorsqu'un calcul RAM ou CPU dépasse la limite définie dans CPU_THRESHOLD ou RAM_THRESHOLD, il envoie l'information "drain 0%`n" au serveur HAProxy. Dès que la valeur revient sous la limite, elle envoie une valeur calculée toujours précédée de up (ex : "up 12%`n") + +# Fichier de configuration + +L'emplacement du fichier de configuration est défini en début de script. Si ce fichier n'existe pas, il est créé en utilisant des valeurs par défaut. +Il est chargé au démarrage du script et un changement de valeur nécessite un arrêt de celui ci. + +## Activation / désactivation de vérification RAM ou CPU +RAM_ENABLED et CPU_ENABLED sont à 1 si actifs, 0 si inactifs. +S'ils sont absents ou à une valeur autre, ils sont désactivés. + +## VALUE et THRESHOLD + +CPU_THRESHOLD ou RAM_THRESHOLD correspond à une valeur maximale en pourcent à laquelle l'agent renverra forcément une demande de mise en drain (plus de nouvelle ouverture de session). +Exemple : CPU_THRESHOLD = 80 > la machine passe en mode drain si le processeur est détecté à 81% d'utilisation ou plus + +CPU_VALUE ou RAM_VALUE définit le pourcentage d'usage de réference utilisé pour le calcul du poids, selon le facteur d'importance de la valeur. +Le calcul de poids se base sur une valeur de départ de 100, et chaque élément calculé se soustrait à cette valeur de départ +Exemple : CPU_VALUE = 50 et CPU_IMPORTANCEFACTOR à 100 +Si l'usage du CPU est à 10, la valeur calculée sera : +10/50*100 = 20 +100 - 20 = 80 + +Le script renverra à HAProxy la valeur "up 80%" + +La valeur de THRESHOLD peut être inférieure à VALUE. +Ainsi, si on créé un CPU_THRESHOLD à 80 et un CPU_VALUE à 90, le poids de la machine va diminuer progressivement jusqu'à arriver à 80% d'utilisation CPU, mais prendra en compte dans le calcul 90% de son utilisation. + +## IMPORTANCEFACTOR + +Le facteur d'importance permet de réduire le calcul du score pour une métrique afin de la rendre moins importante. +Un IMPORTANCEFACTOR à 100 veut dire que la valeur est prise en compte à 100% de son calcul initial. +Un IMPORTANCEFACTOR à 50 ne prendra que la moitié de la valeur dans le calcul initial de poids. + +### Exemples pour l'IMPORTANCEFACTOR + +> avec un RAM_VALUE à 80 et un RAM_IMPORTANCEFACTOR à 100 + +Ram utilisée : 60% + +60 / 80 * 100 = 75 +100 - 75 = 25 + +Poids de la machine renvoyé : 25% + +> avec un RAM_VALUE à 80 et un RAM_IMPORTANCEFACTOR à 50 + +Ram utilisée : 60% + +60 / 80 * 50 = 37.5 (arrondi à 37) +100 - 37 = 63 + +Poids de la machine renvoyé : 63% + diff --git a/TCP_listener.ps1 b/TCP_listener.ps1 new file mode 100644 index 0000000..22b365e --- /dev/null +++ b/TCP_listener.ps1 @@ -0,0 +1,173 @@ +$VerbosePreference = 'Continue' +$configfilepath = "C:\temp\config.xml" +try { + $configfile = Import-clixml $configfilepath -ErrorAction Stop +} +catch { + Write-host "Aucun fichier de configuration" + try { + New-Item -ItemType file -Path $configfilepath -force -ErrorAction Stop + } + catch { + Write-Error "Impossible de créer le fichier. Vérifiez que le chemin existe pour $configfilepath" + Start-Sleep -seconds 15 + Exit 1 + } + $Config = New-object PSCUSTOMOBJECT @{ + "RAM_ENABLED" = 1 + "RAM_VALUE" = 80 + "RAM_THRESHOLD" = 90 + "RAM_IMPORTANCEFACTOR" = 50 + "CPU_ENABLED" = 1 + "CPU_VALUE" = 50 + "CPU_THRESHOLD" = 60 + "CPU_IMPORTANCEFACTOR" = 50 + } + $config | Export-Clixml $configfilepath -Force + exit 0 + +} + +$config = Import-Clixml $configfilepath -ErrorAction Stop + +####################### +# CONFIGURATION CHECK # +####################### + +# Check de valeur. Si int autre que 1 on considère comme désactivé. Une valeur absente sera considérée comme 0 et donc désactivée + +if ($config.RAM_ENABLED -as [int] -is [int]) +{ + if ($config.RAM_ENABLED -ne 1) + { + $config.RAM_ENABLED = 0 + } +} + # Si ça n'est pas un int, on désactive +else +{ + $config.RAM_ENABLED = 0 +} + +# Si valeur RAM_VALUE absente, n'est pas un entier ou est à 0 et que RAM_ENABLED est actif on désactive +if ($config.RAM_VALUE -as [int] -is [int] -and ($config.RAM_ENABLED -eq 1)) +{ + if ($config.RAM_VALUE -eq 0) + { + Write-host "Valeur RAM_VALUE absente, incorrecte ou à 0, désactivation" + $config.RAM_ENABLED = 0 + + } +} + +# Pareil pour RAM_THRESHOLD +if ($config.RAM_THRESHOLD -as [int] -is [int] -and ($config.RAM_ENABLED -eq 1)) +{ + if ($config.RAM_THRESHOLD -eq 0) + { + Write-host "Valeur RAM_THRESHOLD absente, incorrecte ou à 0, désactivation" + $config.RAM_ENABLED = 0 + + } +} + +if ($config.CPU_ENABLED -as [int] -is [int]) +{ + if ($config.CPU_ENABLED -ne 1) + { + $config.CPU_ENABLED = 0 + } +} +else +{ + $config.CPU_ENABLED = 0 +} + +if ($config.CPU_VALUE -as [int] -is [int] -and ($config.CPU_ENABLED -eq 1)) +{ + if ($config.CPU_VALUE -eq 0) + { + Write-host "Valeur CPU_VALUE absente, à 0 ou incorrecte. Désactivation check CPU" + } +} + +if ($config.CPU_THRESHOLD -as [int] -is [int] -and ($config.CPU_ENABLED -eq 1)) +{ + if ($config.CPU_THRESHOLD -eq 0) + { + Write-host "Valeur CPU_THRESHOLD absente, à 0 ou incorrecte. Désactivation check CPU" + } +} + +$endpoint = New-Object System.Net.IPEndPoint([ipaddress]::Any,8000) +$listener = New-Object System.Net.Sockets.TcpListener $endpoint + +$listener.Start() + + + + +function Get-ServerHAProxyLoad() +{ + # Usage : état initial, 100% de poids + $usage = 100 + # Threshold : Si une valeur dépasse, on passe à true et force l'usage à 0 après les calculs (drain mode) + $threshold = $false + + + if ($config.RAM_ENABLED -eq 1) + { + $raminfos = Get-WmiObject -Class WIN32_OperatingSystem + $ram = [math]::Floor( 100 - ($raminfos.FreePhysicalMemory / $raminfos.TotalVisibleMemorySize) * 100) + # usage - ( ( pourcentage de ram libre / limite de ram ) * IF ) + $usage = [math]::Floor($usage - (( $ram / $Config.RAM_VALUE ) * $config.RAM_IMPORTANCEFACTOR ) ) + Write-verbose "Ram : $ram`n`tUsage : $usage" + + if ($ram -ge $config.RAM_THRESHOLD) + { + $threshold = $true + Write-verbose "Limite THRESHOLD sur RAM" + } + } + + if ($config.CPU_ENABLED -eq 1) + { + $cpuusage = $(Get-WmiObject -Class Win32_Processor).loadpercentage + $usage = [math]::Floor( $usage - (( $cpuusage / $config.CPU_VALUE ) * $config.CPU_IMPORTANCEFACTOR) ) + Write-verbose "CPU : $cpuusage`n`tUsage : $usage" + if ($cpuusage -ge $config.CPU_THRESHOLD) + { + $threshold = $true + Write-verbose "Limite THRESHOLD sur CPU" + } + } + + if ($threshold -or $usage -lt 0) + { + $usage = "drain 0" + + } + + return "ready $usage" + +} + + +while ($true) +{ + # AcceptTcpClient() va bloquer le script en attente de connexion + $client = $listener.AcceptTcpClient() + # GetStream() va permettre d'écrire et lire. On ne vérifie pas ce qui est envoyé, on renvoie les infos + $tcpnetworkstream = $client.GetStream() + + # Récupération de la stat + $value = Get-ServerHAProxyLoad + + + $data = [text.Encoding]::Ascii.GetBytes("$value%`n") + Write-Verbose "Envoi $value sous format : $data" + $tcpnetworkstream.Write($data,0,$data.Length) + $tcpnetworkstream.close() + + +} \ No newline at end of file