Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1168cf62f3 | |||
| 73a94c3c50 | |||
| 8e698cfc49 | |||
| e25463ff89 | |||
| 064ecfad43 | |||
| 13bc1f46d7 |
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
cryptography
|
||||||
|
requests
|
||||||
|
toml
|
||||||
@ -2,6 +2,7 @@
|
|||||||
import os
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
import logging
|
import logging
|
||||||
|
import time
|
||||||
from functions import getSettings
|
from functions import getSettings
|
||||||
from includes.airwatchAPI import *
|
from includes.airwatchAPI import *
|
||||||
from includes.GLPIAPI import *
|
from includes.GLPIAPI import *
|
||||||
@ -66,13 +67,21 @@ if(args.staginguser != None):
|
|||||||
stagingUser = args.staginguser
|
stagingUser = args.staginguser
|
||||||
|
|
||||||
# ====================================== #
|
# ====================================== #
|
||||||
|
|
||||||
|
|
||||||
# Vérification de la présence du verrou avant de continuer
|
# Vérification de la présence du verrou avant de continuer
|
||||||
if(os.path.isfile(lockFile) and not args.force):
|
if(os.path.isfile(lockFile) and not args.force):
|
||||||
logger.debug('Lock file exists, exiting...')
|
# Récupération du temps de création de verrou en minutes
|
||||||
exit(0)
|
lockTime = (time.time() - os.path.getmtime(lockFile)) // 60
|
||||||
|
# Recréation du verrou s'il existe depuis plus de 3 heures (crash)
|
||||||
|
# sinon on quitte, une synchro est déjà en cours
|
||||||
|
if(lockTime > 180):
|
||||||
|
os.remove(lockFile)
|
||||||
|
open(lockFile, "w").close()
|
||||||
|
else:
|
||||||
|
logger.debug('Lock file exists, exiting...')
|
||||||
|
exit(0)
|
||||||
else:
|
else:
|
||||||
|
# Création du verrou s'il n'existe pas
|
||||||
open(lockFile, "w").close()
|
open(lockFile, "w").close()
|
||||||
|
|
||||||
# Initialisation de l'api Airwatch
|
# Initialisation de l'api Airwatch
|
||||||
|
|||||||
@ -5,6 +5,7 @@ def getSettings(settingsPath):
|
|||||||
settingsDefault ="""
|
settingsDefault ="""
|
||||||
[AIRWATCH]
|
[AIRWATCH]
|
||||||
Server = "https://airwatchServer"
|
Server = "https://airwatchServer"
|
||||||
|
ConsoleURI = "https://airwatchConsole"
|
||||||
APIKey = "APIKEY"
|
APIKey = "APIKEY"
|
||||||
|
|
||||||
# Méthode d'authentification (CMSURL or PASSWORD)
|
# Méthode d'authentification (CMSURL or PASSWORD)
|
||||||
|
|||||||
@ -61,6 +61,27 @@ class GLPIAPI:
|
|||||||
return None, None, 0
|
return None, None, 0
|
||||||
return None, None, None
|
return None, None, None
|
||||||
|
|
||||||
|
def GetUser(self, username=None, email=None):
|
||||||
|
|
||||||
|
if(username != None):
|
||||||
|
search_parameter = f'is_deleted=0&criteria[0][field]=1&withindexes=true&criteria[0][searchtype]=contains&criteria[0][value]=^{username}$'
|
||||||
|
elif(email != None):
|
||||||
|
search_parameter = f'is_deleted=0&criteria[0][field]=5&withindexes=true&criteria[0][searchtype]=contains&criteria[0][value]=^{email}$'
|
||||||
|
searchUri = f"{self.Server}/apirest.php/search/user?{search_parameter}"
|
||||||
|
search = requests.get(searchUri, headers=self.Headers)
|
||||||
|
if(search.status_code == 200):
|
||||||
|
search = search.json()
|
||||||
|
if(search["totalcount"] == 1):
|
||||||
|
userID = list(search["data"].keys())[0]
|
||||||
|
data = search["data"][userID]
|
||||||
|
|
||||||
|
return userID, data, search["totalcount"]
|
||||||
|
elif(search["totalcount"] > 1):
|
||||||
|
userID = list(search["data"].keys())
|
||||||
|
return userID, search["data"], search["totalcount"]
|
||||||
|
else:
|
||||||
|
return None, None, 0
|
||||||
|
|
||||||
def UpdateInventory(self, inventory):
|
def UpdateInventory(self, inventory):
|
||||||
headers = {
|
headers = {
|
||||||
"Content-Type":"Application/x-compress",
|
"Content-Type":"Application/x-compress",
|
||||||
@ -89,12 +110,23 @@ class GLPIAPI:
|
|||||||
}
|
}
|
||||||
uri = f"{self.Server}/apirest.php/Computer/"
|
uri = f"{self.Server}/apirest.php/Computer/"
|
||||||
return requests.put(uri, headers=self.Headers, json=body)
|
return requests.put(uri, headers=self.Headers, json=body)
|
||||||
|
|
||||||
|
def UpdateAirwatchLink(self, deviceid, airwatchlink):
|
||||||
|
|
||||||
|
body = {
|
||||||
|
"input": {
|
||||||
|
"id": deviceid,
|
||||||
|
"appareilsurmagentafield": airwatchlink
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uri = f"{self.Server}/apirest.php/Computer/"
|
||||||
|
return requests.put(uri, headers=self.Headers, json=body)
|
||||||
|
|
||||||
def CreateInventoryForAirwatchDevice(self, device, deviceName, apps=None):
|
def CreateInventoryForAirwatchDevice(self, device, deviceName, apps=None):
|
||||||
platforms = {
|
platforms = {
|
||||||
2:"Apple iOS",
|
2:"Apple iOS",
|
||||||
5:"Android",
|
5:"Android",
|
||||||
12:"Windows Desktop"
|
12:"Windows"
|
||||||
}
|
}
|
||||||
|
|
||||||
if(device.PlatformId in platforms.keys()):
|
if(device.PlatformId in platforms.keys()):
|
||||||
@ -119,10 +151,28 @@ class GLPIAPI:
|
|||||||
osArch = "Unknown"
|
osArch = "Unknown"
|
||||||
softwareArch = "Unknown"
|
softwareArch = "Unknown"
|
||||||
|
|
||||||
|
windowsOSTranslation = {
|
||||||
|
"10.0.19043":"10 21H1",
|
||||||
|
"10.0.19044":"10 21H2",
|
||||||
|
"10.0.19045":"10 22H2",
|
||||||
|
"10.0.22000":"11 21H2",
|
||||||
|
"10.0.22621":"11 22H2",
|
||||||
|
"10.0.22631":"11 23H2",
|
||||||
|
"10.0.26100":"11 24H2",
|
||||||
|
"10.0.26200":"11 25H2"
|
||||||
|
}
|
||||||
|
|
||||||
logDate = datetime.strptime(device.LastSeen, "%Y-%m-%dT%H:%M:%S.%f").strftime("%Y-%m-%d %H:%M:%S")
|
logDate = datetime.strptime(device.LastSeen, "%Y-%m-%dT%H:%M:%S.%f").strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
|
||||||
inventory = GLPIInventory(logdate=logDate, versionclient=self.UserAgent, tag=device.Group, deviceid=f"{deviceName} - {device.SerialNumber}", itemtype="Computer")
|
inventory = GLPIInventory(logdate=logDate, versionclient=self.UserAgent, tag=device.Group, deviceid=f"{deviceName} - {device.SerialNumber}", itemtype="Computer")
|
||||||
inventory.SetOperatingSystem(platformName, device.OS, osArch)
|
if(platformName == "Windows"):
|
||||||
|
if(device.OS in windowsOSTranslation.keys()):
|
||||||
|
inventory.SetOperatingSystem(platformName, windowsOSTranslation[str(device.OS)], osArch)
|
||||||
|
else:
|
||||||
|
platformName = "Windows Desktop"
|
||||||
|
inventory.SetOperatingSystem(platformName, device.OS, osArch)
|
||||||
|
else:
|
||||||
|
inventory.SetOperatingSystem(platformName, device.OS, osArch)
|
||||||
inventory.SetHardware(deviceName, device.Uuid, device.TotalMemory)
|
inventory.SetHardware(deviceName, device.Uuid, device.TotalMemory)
|
||||||
inventory.AddUser(device.User)
|
inventory.AddUser(device.User)
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
import os
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
import logging
|
import logging
|
||||||
|
import time
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from functions import getSettings
|
from functions import getSettings
|
||||||
from includes.airwatchAPI import *
|
from includes.airwatchAPI import *
|
||||||
@ -22,7 +23,7 @@ args = parser.parse_args()
|
|||||||
if(args.configpath != None and args.configpath != ''):
|
if(args.configpath != None and args.configpath != ''):
|
||||||
settings = getSettings(args.configpath)
|
settings = getSettings(args.configpath)
|
||||||
else:
|
else:
|
||||||
settings = getSettings("{os.path.realpath(os.path.dirname(__file__))}/conf/settings.conf")
|
settings = getSettings(f"{os.path.realpath(os.path.dirname(__file__))}/conf/settings.conf")
|
||||||
|
|
||||||
#=========== Configuration des logs ===========#
|
#=========== Configuration des logs ===========#
|
||||||
|
|
||||||
@ -105,11 +106,21 @@ platformFilterOut = [12]
|
|||||||
|
|
||||||
# ====================================== #
|
# ====================================== #
|
||||||
|
|
||||||
|
|
||||||
# Vérification de la présence du verrou avant de continuer
|
# Vérification de la présence du verrou avant de continuer
|
||||||
if(os.path.isfile(lockFile) and not args.force):
|
if(os.path.isfile(lockFile) and not args.force):
|
||||||
logger.debug('Lock file exists, exiting...')
|
# Récupération du temps de création de verrou en minutes
|
||||||
exit(0)
|
lockTime = (time.time() - os.path.getmtime(lockFile)) // 60
|
||||||
|
# Recréation du verrou s'il existe depuis plus de 3 heures (crash)
|
||||||
|
# sinon on quitte, une synchro est déjà en cours
|
||||||
|
if(lockTime > 180):
|
||||||
|
os.remove(lockFile)
|
||||||
|
open(lockFile, "w").close()
|
||||||
|
else:
|
||||||
|
logger.debug('Lock file exists, exiting...')
|
||||||
|
exit(0)
|
||||||
else:
|
else:
|
||||||
|
# Création du verrou s'il n'existe pas
|
||||||
open(lockFile, "w").close()
|
open(lockFile, "w").close()
|
||||||
|
|
||||||
logger.info("========= Synchronization started =========")
|
logger.info("========= Synchronization started =========")
|
||||||
@ -204,17 +215,29 @@ for device in devices:
|
|||||||
loggerDouble.error(f"{count} devices matching airwatch device {device.FriendlyName} (Airwatch id={device.Id}) in GLPI (GLPI ids = {', '.join(deviceID)}), skipping this device...")
|
loggerDouble.error(f"{count} devices matching airwatch device {device.FriendlyName} (Airwatch id={device.Id}) in GLPI (GLPI ids = {', '.join(deviceID)}), skipping this device...")
|
||||||
continue
|
continue
|
||||||
if(count == 0):
|
if(count == 0):
|
||||||
loggerMissing.error(f"Device {device.FriendlyName} (id={device.Id}) not found in GLPI, is it in the trash bin ? Skipping device...")
|
deviceIDTrash, dataTrash, countTrash = glpiapi.GetDevice(device)
|
||||||
|
if(countTrash > 1):
|
||||||
|
loggerDouble.error(f"{countTrash} devices matching airwatch device {device.FriendlyName} (Airwatch id={device.Id}) in GLPI trashbin (GLPI ids = {', '.join(deviceIDTrash)}), skipping this device...")
|
||||||
|
elif(countTrash == 1):
|
||||||
|
logger.warning(f"Device {device.FriendlyName} (Airwatch id={device.Id}) in GLPI trashbin (GLPI id={deviceIDTrash}), skipping...")
|
||||||
|
else:
|
||||||
|
loggerMissing.error(f"Device {device.FriendlyName} (Airwatch id={device.Id}) not found in GLPI.")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
inventory = glpiapi.CreateInventoryForAirwatchDevice(device, data["1"], apps)
|
inventory = glpiapi.CreateInventoryForAirwatchDevice(device, data["1"], apps)
|
||||||
# Mise à jour du friendly name sur Airwatch
|
# Mise à jour du friendly name sur Airwatch
|
||||||
platformName = inventory.operatingsystem["name"]
|
platformName = inventory.operatingsystem["name"]
|
||||||
if(device.FriendlyName != f"{data['1']} {platformName} {device.OS} - {device.User}"):
|
osVersion = inventory.operatingsystem["version"]
|
||||||
newFriendlyName = f"{data['1']} {platformName} {device.OS} - {device.User}"
|
if(device.FriendlyName != f"{data['1']} {platformName} {osVersion} - {device.User}"):
|
||||||
|
newFriendlyName = f"{data['1']} {platformName} {osVersion} - {device.User}"
|
||||||
logger.info(f"Updating device friendlyname to {newFriendlyName}")
|
logger.info(f"Updating device friendlyname to {newFriendlyName}")
|
||||||
airwatch.SetDeviceFriendlyName(device, newFriendlyName)
|
airwatch.SetDeviceFriendlyName(device, newFriendlyName)
|
||||||
|
|
||||||
|
# Mise à jour de l'url vers la page airwatch de l'appareil sur GLPI
|
||||||
|
airwatchlink = f"{settings['AIRWATCH']['ConsoleURI']}/AirWatch/#/AirWatch/Device/Details/Summary/{device.Id}"
|
||||||
|
if(data['76689'] != airwatchlink):
|
||||||
|
glpiapi.UpdateAirwatchLink(deviceID, airwatchlink)
|
||||||
|
|
||||||
# filtre des plateformes
|
# filtre des plateformes
|
||||||
if(platformFilterEnabled):
|
if(platformFilterEnabled):
|
||||||
if device.PlatformId in platformFilterOut:
|
if device.PlatformId in platformFilterOut:
|
||||||
@ -224,9 +247,11 @@ for device in devices:
|
|||||||
logger.info(f"Updating {deviceID} on GLPI")
|
logger.info(f"Updating {deviceID} on GLPI")
|
||||||
glpiapi.UpdateInventory(inventory.Json())
|
glpiapi.UpdateInventory(inventory.Json())
|
||||||
|
|
||||||
#if(data['70'] == None and device.User != settings["AIRWATCH"]["StagingUser"]):
|
if(data['70'] == None and device.User != settings["AIRWATCH"]["StagingUser"]):
|
||||||
#logger.info(f"Updating user from {data['70']} to {device.User} in GLPI (id={deviceID})")
|
userID, userData, userCount = glpiapi.GetUser(device.User)
|
||||||
#glpiapi.UpdateUser(deviceID, device.User)
|
if(userCount == 1):
|
||||||
|
logger.info(f"Updating user from {data['70']} to {device.User} in GLPI (id={deviceID})")
|
||||||
|
glpiapi.UpdateUser(deviceID, userID)
|
||||||
|
|
||||||
if(data['5'] != device.SerialNumber):
|
if(data['5'] != device.SerialNumber):
|
||||||
logger.info(f"Updating serial number from {data['5']} to {device.SerialNumber} in GLPI (id={deviceID})")
|
logger.info(f"Updating serial number from {data['5']} to {device.SerialNumber} in GLPI (id={deviceID})")
|
||||||
|
|||||||
Reference in New Issue
Block a user