create Folder latest / move Update out of Version to rename

main
sebastian.serfling 2024-08-12 15:00:01 +02:00
parent 172fe23f65
commit 601f86e2e7
27 changed files with 39 additions and 593 deletions

3
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

8
.idea/Agents.iml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
.idea/misc.xml Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.11" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/Agents.iml" filepath="$PROJECT_DIR$/.idea/Agents.iml" />
</modules>
</component>
</project>

7
.idea/vcs.xml Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$/latest" vcs="Git" />
</component>
</project>

View File

@ -1,8 +0,0 @@
1. Prüfen der IP Adresse
2. Abfrage am API Server welcher Service
3. Ping aller 10sec senden
4. Controller für Service aller 60sec
Fragen ?
Wie die Daten der Controller bereitgestllt werden -> Einheitliche Definitionen

View File

@ -1,34 +0,0 @@
### Das ist das Tool für die Agents auf Windows und Linux Basis zum bereitstellen von Lizenzen zur Datenbanl über den API-Server Das Tool soll auf Basis von Python entwickelt werden und immer auf neue Versione testen bevor es los läuft
### Für die Betriebsystem Agents werden seperate Controller für jede Art von Services erstellt, dazu gehören:
- Exchange
- Terminal-Server
- AD-Controller
- Samba
- Nextcloud
- SOGo
- Bitwarden
- Office365 (Must Have)
- Ticketsystem
#### Aufbau ####
1. update_check.py
Kontrolliert ob eine neue Version im Git vorhanden ist, und startet danach das Script neu
2. main.py
Ist das Hauptscript, was die Abfrage macht welches System vorhanden ist und startet dann den Controller -> das wird nur einmal ausgeführt nach jedem Update -> danach wird ID, Services, IP in einer Datei auf dem System abgelegt
3. controller/
Beinhaltet die Controller die für die Services zuständig sind, da jeder Service eine andere Verarbeitung von Daten hat
4. system_checks/
Beinhaltet die Scripte zum kontrollieren der Service Zustände, CPU, RAM, Festplattenbelgung, Ping
### Das System wird als ENV aufgebaut & immer innerhalb diese ENV ausgeführt
#### Überlegungen ####
- Wie auführen auf Windows Servern (Service vs Aufgabe)

View File

@ -1,84 +0,0 @@
# Definieren Sie den Pfad zur Ergebnisdatei
$timestamp = (Get-Date).ToString("yyyyMMdd_HHmmss")
$outputFile = "C:\Scripte\MailboxLastLogins_$timestamp.csv"
# Definieren Sie den API-Endpoint
$apiUrl = "http://api.stines.de:8001/report"
# Your API key
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Content-Type", "application/json")
$headers.Add("access_token", "^YWUbG7yX*V!tV^KBSd*2c&vdN3wV9a2i7f3hfGFMBYFxi6#mMiJGiaA5KEHE%B*miK%qb7rQ67gmcYP@gqmux8")
$ipaddress = Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.InterfaceAlias -like "*Ethernet*" } | Select-Object -ExpandProperty IPAddress
# Fügen Sie das Exchange-Management-Snap-In hinzu
if (-not (Get-PSSnapin -Name Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction SilentlyContinue)) {
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
}
# Ermitteln Sie alle Benutzerpostfächer
$mailboxes = Get-Mailbox -RecipientTypeDetails UserMailbox -ResultSize Unlimited
# Initialisieren Sie eine leere Liste für die Ergebnisse
$results = @()
# Zeitstempel für eine Stunde zuvor
$oneHourAgo = (Get-Date).AddHours(-1)
# Durchlaufen Sie alle Postfächer und sammeln Sie die letzten Login-Informationen
foreach ($mailbox in $mailboxes) {
# Überprüfen, ob das Konto deaktiviert ist
$exchangeUserAccountControl = $mailbox.ExchangeUserAccountControl
if ($exchangeUserAccountControl -eq "AccountDisabled") {
continue
}
# Filter für Admin- und Journalpostfächer
if ($mailbox.UserPrincipalName -eq "$" -or
$mailbox.UserPrincipalName -match "Journal" -or
$mailbox.UserPrincipalName -match "admin") {
continue
}
$mailboxStats = Get-MailboxStatistics -Identity $mailbox.UserPrincipalName
$lastLoginTime = $mailboxStats.LastLogonTime
# Prüfen, ob der letzte Login in der letzten Stunde war
if ($lastLoginTime -ge $oneHourAgo) {
$username = $mailbox.UserPrincipalName.Split('@')[0]
$result = [PSCustomObject]@{
Mailbox = $username
LastLogon = $lastLoginTime
}
$results += $result
# Daten für die API-Anfrage vorbereiten
$data = @{
username = $result.Mailbox
lastaccess = $result.LastLogon.ToString("yyyy-MM-dd HH:mm:ss")
ipaddress = $ipaddress
}
# POST-Anfrage an den API-Server senden
$jsonData = ($data | ConvertTo-Json -Depth 3 | Out-String).Trim()
$utf8Json = [System.Text.Encoding]::UTF8.GetBytes($jsonData)
$response = Invoke-RestMethod -Uri $apiUrl -Method Post -Body $utf8Json -ContentType "application/json; charset=utf-8" -Headers $headers
if ($response -eq "True") {
Write-Output "Successfully sent data for $($result.Mailbox)"
} else {
Write-Output "Failed to send data for $($result.Mailbox): $response"
}
}
}
# Ergebnisse in CSV exportieren
$results | Export-Csv -Path $outputFile -NoTypeInformation
# Ergebnisse anzeigen
$results | Format-Table -AutoSize

View File

@ -1,117 +0,0 @@
import msal
import requests
import pandas as pd
from datetime import datetime
# Konfigurationsvariablen
client_id = '90571c9b-d407-4d2a-aadd-4a523ff85296'
client_secret = 'ryp8Q~qr6LBOUL2G333a.mf-vg5V..ONl7qJTdza'
tenant_id = '9e449aaa-285c-4572-a132-58db027026d0'
api_server_endpoint = "http://api.stines.de:8001/office/post"
# headers = 'access_token':'^YWUbG7yX*V!tV^KBSd*2c&vdN3wV9a2i7f3hfGFMBYFxi6#mMiJGiaA5KEHE%B*miK%qb7rQ67gmcYP@gqmux8'
# Die URL für das Token
authority = f'https://login.microsoftonline.com/{tenant_id}'
# Der Scope für die Microsoft Graph API
scope = ['https://graph.microsoft.com/.default']
# MSAL-Instanz erstellen
app = msal.ConfidentialClientApplication(
client_id,
authority=authority,
client_credential=client_secret,
)
# Token erhalten
result = None
result = app.acquire_token_silent(scope, account=None)
if not result:
print("Kein Caching vorhanden, holen Sie ein neues Token.")
result = app.acquire_token_for_client(scopes=scope)
print(result)
if "access_token" in result:
# Token erfolgreich erhalten
access_token = result['access_token']
print(access_token)
# API-Endpunkt für aktive Office-Pakete
endpoint = "https://graph.microsoft.com/v1.0/users?$select=userPrincipalName,assignedLicenses,signInActivity"
headers = {
'Authorization': f'Bearer {access_token}',
'Content-Type': 'application/json'
}
response = requests.get(endpoint, headers=headers)
if response.status_code == 200:
# Die Antwort als JSON behandeln
data = response.json()
# Extrahieren der Benutzerdaten aus dem JSON
users = data.get('value', [])
# Die `skuId` und `lastNonInteractiveSignInDateTime` extrahieren und hinzufügen
user_list = []
for user in users:
if 'assignedLicenses' in user:
for license in user['assignedLicenses']:
if 'skuId' in license:
user_copy = user.copy()
user_copy['skuId'] = license['skuId']
if user_copy.get('signInActivity'):
sign_in_time = user_copy['signInActivity'].get('lastNonInteractiveSignInDateTime')
if sign_in_time:
user_copy['lastNonInteractiveSignInDateTime'] = datetime.strptime(sign_in_time,'%Y-%m-%dT%H:%M:%SZ').strftime('%Y-%m-%d %H:%M:%S')
else:
user_copy['lastNonInteractiveSignInDateTime'] = None
else:
user_copy['lastNonInteractiveSignInDateTime'] = None
user_list.append(user_copy)
# Filtern der Benutzer, die eine `skuId` haben
users_with_skuId = [user for user in user_list if user['skuId']]
# Konvertieren der Benutzerdaten in ein DataFrame
df = pd.DataFrame(users_with_skuId)
# Pandas Anzeigeoptionen anpassen
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)
pd.set_option('display.max_colwidth', None)
pd.set_option('display.width', 1000)
# Alles nach dem @ im "User Principal Name" entfernen
if 'userPrincipalName' in df.columns:
df['userPrincipalName'] = df['userPrincipalName'].str.split('@').str[0]
# Nur die gewünschten Spalten auswählen und an die API-Server übergeben
selected_columns = df[["userPrincipalName", "skuId", "lastNonInteractiveSignInDateTime"]]
reporting_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
for index, row in selected_columns.iterrows():
payload = {
"itemkey": row["skuId"],
"username": row["userPrincipalName"],
"reportingdate": reporting_date,
"lastaccess": row["lastNonInteractiveSignInDateTime"]
}
api_response = requests.post(api_server_endpoint, json=payload, headers= {'access_token':'^YWUbG7yX*V!tV^KBSd*2c&vdN3wV9a2i7f3hfGFMBYFxi6#mMiJGiaA5KEHE%B*miK%qb7rQ67gmcYP@gqmux8'})
if api_response.status_code == 200:
print(f"Erfolgreich gesendet: {payload}")
else:
print(f"Fehler beim Senden von {payload}: {api_response.status_code} - {api_response.text}")
else:
print(f"Fehler beim Abrufen der Daten: {response.status_code}")
print(f"Antwort: {response.text}")
else:
print("Fehler beim Abrufen des Tokens")
print(result.get("error"))
print(result.get("error_description"))
print(result.get("correlation_id"))

View File

@ -1,88 +0,0 @@
# Define the time range for the last 1 day
$startTime = (Get-Date).AddHours(-1)
$endTime = Get-Date
# Define the filter hashtable with the time range
$filterHashTable = @{
LogName = 'Security'
Id = 4624
StartTime = $startTime
EndTime = $endTime
}
# Get all events with ID 4624 from the Security log within the defined time range
$events = Get-WinEvent -FilterHashtable $filterHashTable
# Create a hash table to store the last login event for each user
$userLogins = @{}
# Loop through each event
foreach ($event in $events) {
$eventDetails = [xml]$event.ToXml()
# Extract relevant information
$timeCreated = $event.TimeCreated
$username = $eventDetails.Event.EventData.Data | Where-Object { $_.Name -eq 'TargetUserName' } | Select-Object -ExpandProperty '#text'
$ipaddress = Get-NetIPAddress -AddressFamily IPv4 -InterfaceAlias Ethernet | Select-Object -ExpandProperty IPAddress
$logonType = $eventDetails.Event.EventData.Data | Where-Object { $_.Name -eq 'LogonType' } | Select-Object -ExpandProperty '#text'
# Exclude events not related to remote logins and HealthMailbox
if ($logonType -ne "10" -or $username -like "DWM*" -or $username -like "*UMFD*") {
continue
}
$formattedTimeCreated = $timeCreated.ToString("yyyy-MM-dd HH:mm:ss")
# Store the event if it's the latest one for the user
if (-not $userLogins.ContainsKey($username) -or $userLogins[$username].TimeCreated -lt $timeCreated) {
$userLogins[$username] = [PSCustomObject]@{
lastaccess = $formattedTimeCreated
username = $username
ipaddress = $ipaddress
LogonType = $logonType
}
}
}
# Define the JSON file path with current date and hour
$dateString = (Get-Date).ToString("yyyyMMdd_HH-mm")
$jsonPath = "C:\Scripte\LastLogins_$dateString.json"
# Output the last login event for each user to the JSON file
$userLoginsArray = $userLogins.GetEnumerator() | ForEach-Object {
$_.Value
}
$userLoginsArray | ConvertTo-Json | Set-Content -Path $jsonPath -Encoding UTF8
Write-Output "JSON file created at $jsonPath"
# API endpoint URL
$apiUrl = "http://api.stines.de:8001/report"
# Your API key
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Content-Type", "application/json")
$headers.Add("access_token", "^YWUbG7yX*V!tV^KBSd*2c&vdN3wV9a2i7f3hfGFMBYFxi6#mMiJGiaA5KEHE%B*miK%qb7rQ67gmcYP@gqmux8")
# Loop through the collected user logins and send each as a JSON payload to the API
foreach ($userLogin in $userLoginsArray) {
$userLoginObject = $userLogin | Select-Object username, lastaccess, ipaddress
# Convert the user login object to JSON
$jsonPayload = $userLoginObject | ConvertTo-Json -Depth 3
# Encode JSON payload in UTF-8
$utf8JsonPayload = [System.Text.Encoding]::UTF8.GetBytes($jsonPayload)
# Send the JSON payload to the API
try {
$response = Invoke-RestMethod -Uri $apiUrl -Method Post -Body $utf8JsonPayload -ContentType 'application/json' -Headers $headers
Write-Output "Sent login data for user $($userLoginObject.Username) to the API. Response: $response"
} catch {
Write-Error "Failed to send login data for user $($userLoginObject.Username). Error: $_"
}
}
Write-Output "Finished sending login data to the API"

View File

@ -1,7 +0,0 @@
### Beschreibt den Vorgang eines Nextcloud Servers
1. Vorhanden User
2. Vorhanden Gruppen
3. Letzer User Login
4. Belegter Speicher
5. Nextcloud Version

View File

@ -1,7 +0,0 @@
### Beschreibt den Vorgang eines Exchange Servers
1. Vorhanden Postfächer
2. Verbundene Postfächer (lastaccess)
3. Datenbank Größe / Blegung auf Festplatte
4. Exchange Server Version
5. Zertifikat Ablaufdatum

View File

@ -1,7 +0,0 @@
### Beschreibt den Vorgang eines Mailcow Servers
1. Vorhanden User
2. Vorhanden Alias
3. Letzer User Login
4. Belegter Speicher
5. Mailcow Version

View File

@ -1,6 +0,0 @@
### Beschreibt den Vorgang eines RDS Servers
1. Kontroller der User die Online waren / sind
2. Kontrolle der Festplatten Belegung
3. Kontrolle der Profile Belgung der User
4. Update Status

View File

@ -1,25 +0,0 @@
## Controller sind für jeden Service speziele Abfragen von Daten
### RDS
- User Online
- Profile Order Größen
### Exchange Server
- Postfächer verbunden
- Datenbank Größe
- Zertifikat Ablaufdatum
### AD-Controller
- User vorhanden
- Gruppen vorhanden
### Cloud
- Cloud User
- Cloud Gruppen
- Cloud Speicher belegt
### Mailcow
- E-Mail Accounts vorhanden
- E-Mail Postfach belegung

View File

@ -1,96 +0,0 @@
# Funktion zum Konvertieren des LastLogonTimestamp in Datum
function Convert-LastLogonTimestamp {
param (
[Parameter(Mandatory = $true)]
[long]$Timestamp
)
$DateTime = [DateTime]::FromFileTime($Timestamp)
return $DateTime
}
# Funktion zum Abrufen der lokalen IP-Adresse
function Get-LocalIPAddress {
$ipAddress = [System.Net.Dns]::GetHostAddresses([System.Net.Dns]::GetHostName()) |
Where-Object { $_.AddressFamily -eq 'InterNetwork' } |
Select-Object -First 1
return $ipAddress.IPAddressToString
}
# Gruppe "Users" abrufen
$groupName = "Reporting"
$group = Get-ADGroup -Filter { Name -eq $groupName }
if ($group -eq $null) {
Write-Error "Gruppe '$groupName' wurde nicht gefunden."
exit
}
# Mitglieder der Gruppe abrufen
$groupMembers = Get-ADGroupMember -Identity $group -Recursive | Where-Object { $_.objectClass -eq 'user' }
# Abrufen der lokalen IP-Adresse
$localIPAddress = Get-LocalIPAddress
# Erstellen einer Hash-Tabelle zum Speichern der letzten Anmeldeinformationen für jeden Benutzer
$userLogins = @{}
# Umwandeln der Benutzerinformationen und Ausgabe zur Konsole
foreach ($member in $groupMembers) {
$user = Get-ADUser -Identity $member.SamAccountName -Properties LastLogonTimestamp,createTimeStamp
$lastLogonDateTime = if ($user.LastLogonTimestamp) { (Convert-LastLogonTimestamp -Timestamp $user.LastLogonTimestamp).ToString("yyyy-MM-dd HH:mm:ss") } else { ($user.createTimeStamp).ToString("yyyy-MM-dd HH:mm:ss") }
$convertedUser = [PSCustomObject]@{
username = $user.SamAccountName
lastaccess = $lastLogonDateTime
ipaddress = $localIPAddress
}
# Ausgabe des konvertierten Benutzers zur Konsole
Write-Output $convertedUser
# Rückgabe des konvertierten Benutzers für JSON-Umwandlung
$userLogins[$user.SamAccountName] = $convertedUser
}
# Define the JSON file path with current date and hour
$dateString = (Get-Date).ToString("yyyyMMdd_HH-mm")
$jsonPath = "C:\Scripte\LastLogins_$dateString.json"
# Output the last login event for each user to the JSON file
$userLoginsArray = $userLogins.GetEnumerator() | ForEach-Object {
$_.Value
}
$userLoginsArray | ConvertTo-Json | Set-Content -Path $jsonPath -Encoding UTF8
Write-Output "JSON file created at $jsonPath"
# API endpoint URL
$apiUrl = "http://api.stines.de:8001/report"
# Your API key
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Content-Type", "application/json")
$headers.Add("access_token", "^YWUbG7yX*V!tV^KBSd*2c&vdN3wV9a2i7f3hfGFMBYFxi6#mMiJGiaA5KEHE%B*miK%qb7rQ67gmcYP@gqmux8")
# Loop through the collected user logins and send each as a JSON payload to the API
foreach ($userLogin in $userLoginsArray) {
$userLoginObject = $userLogin | Select-Object username, lastaccess, ipaddress
# Convert the user login object to JSON
$jsonPayload = $userLoginObject | ConvertTo-Json -Depth 3
# Encode JSON payload in UTF-8
$utf8JsonPayload = [System.Text.Encoding]::UTF8.GetBytes($jsonPayload)
# Send the JSON payload to the API
try {
$response = Invoke-RestMethod -Uri $apiUrl -Method Post -Body $utf8JsonPayload -ContentType 'application/json' -Headers $headers
Write-Output "Sent login data for user $($userLoginObject.username) to the API. Response: $response"
} catch {
Write-Error "Failed to send login data for user $($userLoginObject.username). Error: $_"
}
}
Write-Output "Finished sending login data to the API"

View File

@ -1,9 +0,0 @@
## Abfrage des Eregniss für Userlogin (lastacces)
## Abfrage Gruppen (groups)
## Abfrage Festplatten Belegung (space_used)
## Abfrage Profile Ordner Belegung (services_space_used) -> übergabe item & spaceused
## Abfrage Updates (updates = yes/no)

View File

@ -1,7 +0,0 @@
## Abfrage des Eregniss für Userlogin (lastacces)
## Abfrage Festplatten Belegung (space_used)
## Abfrage Profile Ordner Belegung (services_space_used) -> übergabe item & spaceused
## Abfrage Updates (updates = yes/no)

View File

@ -1,9 +0,0 @@
## Abfrage des Eregniss für Userlogin (lastacces)
## Abfrage Gruppen (groups)
## Abfrage Festplatten Belegung (space_used)
## Abfrage Profile Ordner Belegung (services_space_used) -> übergabe item & spaceused
## Abfrage Updates (updates = yes/no)

View File

@ -1,7 +0,0 @@
## Abfrage des Eregniss für Userlogin (lastacces)
## Abfrage Festplatten Belegung (space_used)
## Abfrage Profile Ordner Belegung (services_space_used) -> übergabe item & spaceused
## Abfrage Updates (updates = yes/no)

View File

@ -1,64 +0,0 @@
import datetime
import requests
import re
import socket
def get_local_ip():
try:
# Ein temporärer Socket erstellen, um die lokale IP-Adresse zu ermitteln
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Verbindung zu einem öffentlichen DNS-Server herstellen
s.connect(("8.8.8.8", 80))
# Die lokale IP-Adresse aus dem Socket abrufen
local_ip = s.getsockname()[0]
s.close()
return local_ip
except Exception as e:
print(f"Fehler beim Ermitteln der lokalen IP-Adresse: {e}")
return None
# URL des API-Servers
sogo_server = "http://172.19.1.4/api/v1/get/logs/sogo/1000"
sogo_headers = {"x-api-key":"6A039F-CED4C3-D69E9E-A6C713-7EBB6A"}
api_server = "http://api.stines.de:8001/report"
api_headers = {"access_token":"^YWUbG7yX*V!tV^KBSd*2c&vdN3wV9a2i7f3hfGFMBYFxi6#mMiJGiaA5KEHE%B*miK%qb7rQ67gmcYP@gqmux8"}
def extract_email_username(log_entry):
# Regex für das Finden der E-Mail-Adresse in der Log-Zeile
match = re.search(r"for user '([^']+)'", log_entry)
if match:
email = match.group(1)
# Entfernen des '@' Zeichens aus der E-Mail-Adresse
username = email.split('@')[0]
return username
else:
return None
# Funktion zum Abrufen von Daten vom API-Server
def fetch_data_from_api(url):
response = requests.get(url,headers=sogo_headers)
if response.status_code == 200:
return response.json()
else:
print(f"Fehler beim Abrufen der Daten: {response.status_code}")
return None
# Abrufen der Daten
data = fetch_data_from_api(sogo_server)
if data:
for entry in data:
log_line = entry.get('message')
if log_line and "successful login" in log_line:
username = extract_email_username(log_line)
if username:
payload ={
"ipaddress": "172.19.1.4",
"username": username,
"lastaccess": datetime.datetime.fromtimestamp(int(entry.get('time'))).strftime('%Y-%m-%d %H:%M:%S')
}
api_response = requests.post(api_server, json=payload, headers=api_headers)
print(api_response.status_code)
print(f"Extrahierter Benutzername: {payload}")
else:
print("Keine Daten gefunden.")

View File

@ -1,6 +0,0 @@
## Services Abfrage am API Server mit IP-Adresse
## Ping 10sec
## Service Abfrage aller 60sec
## time = 10
## for i in time

View File

@ -1,12 +0,0 @@
import os
import sys
import requests
current_version = []
new_version = []
# Get Current Version of Files -> Verionfile txt on /opt/agents/version.txt
# Check Verison on Github by Curl http://172.17.1.251/sebastian.serfling/Agents/src/branch/main/version
# IF Version same ->