Compare commits
10 Commits
c474ecc4c7
...
8ea3fa0717
| Author | SHA1 | Date | |
|---|---|---|---|
| 8ea3fa0717 | |||
| e1174ce34b | |||
| 21e7736b8d | |||
| 6e288c0b47 | |||
| 3f6a46c345 | |||
| d3727f3c37 | |||
| 2fcb381062 | |||
| d97b4b60f9 | |||
| 6fb48c452e | |||
| a4c5eb7670 |
160
README.md
Normal file
160
README.md
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
# Scripts Airwatch GLPI
|
||||||
|
|
||||||
|
## Explication de l'usage des scripts et de la configuration :
|
||||||
|
|
||||||
|
### Fichier de configuration global settings.json
|
||||||
|
Les scripts prennent les informations de configuration du fichier settings.json, si celui-ci n'existe pas au lancement d'un script, il est automatiquement créé avec des valeurs d'exemples.
|
||||||
|
Voici une liste des paramètres du fichier de configuration et les valeurs attendues (chaque valeur doit être entre " ") :
|
||||||
|
|
||||||
|
- **"airwatchServer"**: l'adresse du serveur Airwatch
|
||||||
|
- **"airwatchAPIKey"**: la clé API récupéré dans Airwatch
|
||||||
|
- **"airwatchAuthMethod"**: défini la méthode d'authentification, peut prendre la valeur ***"CMSURL"*** pour l'authentification par certificat ou ***"password"*** pour l'authentification par mot de passe.
|
||||||
|
- **"airwatchCertPath"**: le chemin vers le certificat si la méthode d'authentification est par certificat.
|
||||||
|
- **"airwatchCertPass"**: le mot de passe du certificat si celui-ci en possède un, laissez une chaîne vide si vous n'avez pas mis de mot de passe.
|
||||||
|
- **"airwatchAPIUser"**: le nom de l'utilisateur pour l'authentification API dans Airwatch.
|
||||||
|
- **"airwatchAPIPassword"**: le mot de passe de l'utilisateur si l'authentification par mot de passe est choisie.
|
||||||
|
- **"glpiServer"**: l'adresse du serveur GLPI avec un / à la fin.
|
||||||
|
- **"glpiAppToken"**: le token d'application GLPI.
|
||||||
|
- **"glpiUserToken"**: le token de l'utilisateur GLPI utilisé pour les requêtes API.
|
||||||
|
- **"stagingUser"**: le nom du compte de staging présent dans Airwatch.
|
||||||
|
- **"userAgent"**: Un nom pour l'user agent tel qu'il sera visible dans GLPI, cela permet d'identifier l'instance Airwatch (Prod / Pré-prod) par exemple.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### syncGLPI.py
|
||||||
|
Le script syncGLPI.py permet de synchroniser les données des appareils présents dans Airwatch avec un inventaire GLPI.
|
||||||
|
|
||||||
|
Au début, le script va vérifier la présence de doublons en fonction du numéro de série et garder seulement le dernier à s'être enrôlé, puis il va procéder à la vérification de la présence des appareils dans l'inventaire GLPI pour procéder à la synchronisation des données.
|
||||||
|
|
||||||
|
#### Synchronisation
|
||||||
|
Les éléments synchronisés de Airwatch vers GLPI :
|
||||||
|
- l'utilisateur de l'appareil
|
||||||
|
- la dernière date de remontée vers le serveur Airwatch
|
||||||
|
- UUID
|
||||||
|
- le nom du système d'exploitation et sa version
|
||||||
|
- les logiciels présents sur la machine
|
||||||
|
|
||||||
|
Les éléments synchronisés de GLPI vers Airwatch :
|
||||||
|
- Le nom d'inventaire de la machine qui est mis pour le friendlyname
|
||||||
|
|
||||||
|
#### Paramètres
|
||||||
|
Ce script possède les paramètres suivants qui sont optionnels pour son exécution :
|
||||||
|
|
||||||
|
- **-debug** : affiche des informations lors de son exécution, utile pour résoudre des problèmes liés à des droits d'accès API ou des problèmes d'ouvertures réseaux
|
||||||
|
- **-searchFilter** : permet de filtrer la recherche des appareils dans airwatch sur un attribut spécifique parmi la liste suivante : "Id", "SerialNumber", "Imei", "UserName"
|
||||||
|
- **-searchValue** : la valeur pour la recherche lorsque -searchFilter est utilisé
|
||||||
|
- **-force** : permet d'outrepasser la vérification du verrou posé par le script lors de son exécution
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### StagingUserAssignation.py
|
||||||
|
Le script StagingUserAssignation.py permet d'assigner les appareils en staging qui sont assignés à un utilisateur de staging à l'utilisateur renseigné dans l'inventaire GLPI.
|
||||||
|
|
||||||
|
Il récupère le nom de l'utilisateur de staging dans le fichier settings.json.
|
||||||
|
|
||||||
|
#### Paramètres
|
||||||
|
- **-debug** : affiche des informations lors de son exécution, utile pour résoudre des problèmes liés à des droits d'accès API ou des problèmes d'ouvertures réseaux
|
||||||
|
- **-force** : permet d'outrepasser la vérification du verrou posé par le script lors de son exécution
|
||||||
|
- **-staginguser** : permet de préciser l'utilisateur de staging pour la recherche des appareils à modifier (override le fichier de paramètres)
|
||||||
|
- **-serialnumber** : permet de filtrer sur un numéro de série précis
|
||||||
|
|
||||||
|
## Dépendances
|
||||||
|
Installation des paquets linux :
|
||||||
|
|
||||||
|
**debian/ubuntu**
|
||||||
|
```
|
||||||
|
apt-get install -y python3 python3-pip git
|
||||||
|
```
|
||||||
|
|
||||||
|
**redhat/centos**
|
||||||
|
```
|
||||||
|
yum install -y python3 python3-pip git
|
||||||
|
```
|
||||||
|
|
||||||
|
**Dépendances python**
|
||||||
|
```
|
||||||
|
python3 -m pip install cryptography requests
|
||||||
|
```
|
||||||
|
|
||||||
|
## Installation des scripts
|
||||||
|
|
||||||
|
Pour installer les scripts :
|
||||||
|
|
||||||
|
1. Télécharger le contenu de ce projet dans un répertoire du serveur :
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://gitlab.forge.education.gouv.fr/jsecula/glpi-airwatch-sync.git
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Modifier le contenu du fichier de configuration global (settings.json) avec les valeurs correspondant à votre infrastructure.
|
||||||
|
Les clés et certificats API se récupèrent aux emplacements suivants :
|
||||||
|
- **Clé API Airwatch**: Groupes et Paramètres > Tous les paramètres > Système > Avancé > Interface de programmation (API) > API REST
|
||||||
|
|
||||||
|
- **Certificat Airwatch**: lors de la création ou la modification d'un utilisateur Admin
|
||||||
|
|
||||||
|
- **Token d'application GLPI**: Configuration > Générale > API
|
||||||
|
|
||||||
|
- **Token utilisateur GLPI**: Administration > Utilisateurs > choisir l'utilisateur > Jeton d'API
|
||||||
|
|
||||||
|
3. Lancement automatique avec systemd :
|
||||||
|
|
||||||
|
Création des services et des timers dans /etc/systemd/system/ :
|
||||||
|
|
||||||
|
**airwatchSync.service**
|
||||||
|
```
|
||||||
|
[Unit]
|
||||||
|
Description=Script Airwatch pour la synchronisation des données Airwatch et GLPI.
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
WorkingDirectory=/opt/airwatchSync
|
||||||
|
ExecStart=/opt/airwatchSync/syncGLPI.py
|
||||||
|
User=root
|
||||||
|
```
|
||||||
|
**airwatchSync.timer** (exécution toutes les heures)
|
||||||
|
```
|
||||||
|
[Unit]
|
||||||
|
Description=Script Airwatch pour la synchronisation des données Airwatch et GLPI.
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnUnitInactiveSec=1h
|
||||||
|
AccuracySec=1us
|
||||||
|
Unit=airwatchSync.service
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
|
```
|
||||||
|
|
||||||
|
**airwatchStaging.service**
|
||||||
|
```
|
||||||
|
[Unit]
|
||||||
|
Description=Script qui assigne les appareils en staging aux utilisateurs en se basant sur GLPI.
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
WorkingDirectory=/opt/airwatchSync
|
||||||
|
ExecStart=/opt/airwatchSync/StagingUserAssignation.py
|
||||||
|
User=root
|
||||||
|
```
|
||||||
|
|
||||||
|
**airwatchStaging.timer** (exécution toutes les minutes)
|
||||||
|
```
|
||||||
|
[Unit]
|
||||||
|
Description=Script qui assigne les appareils en staging aux utilisateurs en se basant sur GLPI.
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnUnitInactiveSec=1m
|
||||||
|
AccuracySec=1us
|
||||||
|
Unit=airwatchSync.service
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
|
```
|
||||||
|
|
||||||
|
Rechargement de systemd et activation des timers
|
||||||
|
```
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable airwatchSync.timer airwatchStaging.timer
|
||||||
|
systemctl start airwatchSync.timer airwatchStaging.timer
|
||||||
|
```
|
||||||
|
|
||||||
@ -10,21 +10,24 @@ from cryptography.hazmat.primitives import hashes, serialization
|
|||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("-debug", action=argparse.BooleanOptionalAction)
|
parser.add_argument("-debug", action=argparse.BooleanOptionalAction)
|
||||||
parser.add_argument("-force", action=argparse.BooleanOptionalAction)
|
parser.add_argument("-force", action=argparse.BooleanOptionalAction)
|
||||||
|
parser.add_argument("-serialnumber")
|
||||||
|
parser.add_argument("-staginguser")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
settingsDefault = {
|
settingsDefault = {
|
||||||
"airwatchServer":"https://airwatchServer/",
|
"airwatchServer":"https://airwatchServer",
|
||||||
"airwatchAPIKey":"APIKEY",
|
"airwatchAPIKey":"APIKEY",
|
||||||
"airwatchAuthMethod":"CMSURL",
|
"airwatchAuthMethod":"CMSURL",
|
||||||
"airwatchCertPath":"/path/to/cert",
|
"airwatchCertPath":"/path/to/cert",
|
||||||
"airwatchCertPass":"certPassword",
|
"airwatchCertPass":"certPassword",
|
||||||
"airwatchAPIUser":"UserAPI",
|
"airwatchAPIUser":"UserAPI",
|
||||||
"airwatchAPIPassword":"PasswordUserAPI",
|
"airwatchAPIPassword":"PasswordUserAPI",
|
||||||
"glpiServer":"http://127.0.0.1/glpi/",
|
"glpiServer":"http://127.0.0.1/glpi",
|
||||||
"glpiAppToken":"GLPIAppToken",
|
"glpiAppToken":"GLPIAppToken",
|
||||||
"glpiUserToken":"GLPIUserToken",
|
"glpiUserToken":"GLPIUserToken",
|
||||||
"stagingUser":"staging-pr"
|
"stagingUser":"staging-pr",
|
||||||
|
"userAgent":"Airwatch Synchronizer"
|
||||||
}
|
}
|
||||||
|
|
||||||
settings = None
|
settings = None
|
||||||
@ -61,6 +64,9 @@ elif(airwatchAuthMethod == 'CMSURL'):
|
|||||||
airwatchCertPass = settings["airwatchCertPass"]
|
airwatchCertPass = settings["airwatchCertPass"]
|
||||||
stagingUser = settings["stagingUser"]
|
stagingUser = settings["stagingUser"]
|
||||||
|
|
||||||
|
if(args.staginguser != None):
|
||||||
|
stagingUser = args.staginguser
|
||||||
|
|
||||||
# Informations du serveur GLPI
|
# Informations du serveur GLPI
|
||||||
GLPIServer = settings["glpiServer"]
|
GLPIServer = settings["glpiServer"]
|
||||||
GLPIAppToken = settings["glpiAppToken"]
|
GLPIAppToken = settings["glpiAppToken"]
|
||||||
@ -172,12 +178,15 @@ GLPIHeaders = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Adresse de recherche des appareils présents dans ordinateurs sur GLPI
|
# Adresse de recherche des appareils présents dans ordinateurs sur GLPI
|
||||||
GLPIAPISearchComputer = 'apirest.php/search/computer?'
|
GLPIAPISearchComputer = '/apirest.php/search/computer?'
|
||||||
|
|
||||||
for device in devices:
|
for device in devices:
|
||||||
if(device["EnrollmentStatus"] != 'Enrolled'):
|
if(device["EnrollmentStatus"] != 'Enrolled'):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if(args.serialnumber != None and device["SerialNumber"] != args.serialnumber):
|
||||||
|
continue
|
||||||
|
|
||||||
if(device["Imei"] != ''):
|
if(device["Imei"] != ''):
|
||||||
if(debug):
|
if(debug):
|
||||||
print(f"Imei = {device['Imei']}")
|
print(f"Imei = {device['Imei']}")
|
||||||
|
|||||||
@ -1,13 +1,14 @@
|
|||||||
{
|
{
|
||||||
"airwatchServer": "https://airwatchServer/",
|
"airwatchServer": "https://airwatchServer",
|
||||||
"airwatchAPIKey": "APIKEY",
|
"airwatchAPIKey": "APIKEY",
|
||||||
"airwatchAuthMethod": "CMSURL",
|
"airwatchAuthMethod": "CMSURL",
|
||||||
"airwatchCertPath": "/path/to/cert",
|
"airwatchCertPath": "/path/to/cert",
|
||||||
"airwatchCertPass": "certPassword",
|
"airwatchCertPass": "certPassword",
|
||||||
"airwatchAPIUser": "UserAPI",
|
"airwatchAPIUser": "UserAPI",
|
||||||
"airwatchAPIPassword": "PasswordUserAPI",
|
"airwatchAPIPassword": "PasswordUserAPI",
|
||||||
"glpiServer": "http://127.0.0.1/glpi/",
|
"glpiServer": "http://127.0.0.1/glpi",
|
||||||
"glpiAppToken": "GLPIAppToken",
|
"glpiAppToken": "GLPIAppToken",
|
||||||
"glpiUserToken": "GLPIUserToken",
|
"glpiUserToken": "GLPIUserToken",
|
||||||
"stagingUser": "staging-pr"
|
"stagingUser": "staging-pr",
|
||||||
|
"userAgent": "Airwatch Synchronizer"
|
||||||
}
|
}
|
||||||
@ -18,17 +18,18 @@ parser.add_argument("-force", action=argparse.BooleanOptionalAction)
|
|||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
settingsDefault = {
|
settingsDefault = {
|
||||||
"airwatchServer":"https://airwatchServer/",
|
"airwatchServer":"https://airwatchServer",
|
||||||
"airwatchAPIKey":"APIKEY",
|
"airwatchAPIKey":"APIKEY",
|
||||||
"airwatchAuthMethod":"CMSURL",
|
"airwatchAuthMethod":"CMSURL",
|
||||||
"airwatchCertPath":"/path/to/cert",
|
"airwatchCertPath":"/path/to/cert",
|
||||||
"airwatchCertPass":"certPassword",
|
"airwatchCertPass":"certPassword",
|
||||||
"airwatchAPIUser":"UserAPI",
|
"airwatchAPIUser":"UserAPI",
|
||||||
"airwatchAPIPassword":"PasswordUserAPI",
|
"airwatchAPIPassword":"PasswordUserAPI",
|
||||||
"glpiServer":"http://127.0.0.1/glpi/",
|
"glpiServer":"http://127.0.0.1/glpi",
|
||||||
"glpiAppToken":"GLPIAppToken",
|
"glpiAppToken":"GLPIAppToken",
|
||||||
"glpiUserToken":"GLPIUserToken",
|
"glpiUserToken":"GLPIUserToken",
|
||||||
"stagingUser":"staging-pr"
|
"stagingUser":"staging-pr",
|
||||||
|
"userAgent":"Airwatch Synchronizer"
|
||||||
}
|
}
|
||||||
|
|
||||||
settings = None
|
settings = None
|
||||||
@ -245,7 +246,7 @@ GLPIHeaders = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Adresse de recherche des appareils présents dans ordinateurs sur GLPI
|
# Adresse de recherche des appareils présents dans ordinateurs sur GLPI
|
||||||
GLPIAPISearchComputer = 'apirest.php/search/computer?'
|
GLPIAPISearchComputer = '/apirest.php/search/computer?'
|
||||||
|
|
||||||
platforms = {
|
platforms = {
|
||||||
2:"Apple iOS",
|
2:"Apple iOS",
|
||||||
@ -320,7 +321,7 @@ for device in devices:
|
|||||||
"accesslog":{
|
"accesslog":{
|
||||||
"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")
|
||||||
},
|
},
|
||||||
"versionclient":"Airwatch Synchronizer",
|
"versionclient":settings["userAgent"],
|
||||||
"users":[
|
"users":[
|
||||||
{
|
{
|
||||||
"login": device["UserName"]
|
"login": device["UserName"]
|
||||||
@ -388,7 +389,7 @@ for device in devices:
|
|||||||
|
|
||||||
headers = {
|
headers = {
|
||||||
"Content-Type":"Application/x-compress",
|
"Content-Type":"Application/x-compress",
|
||||||
"user-agent":"Airwatch Synchronizer"
|
"user-agent":settings["userAgent"]
|
||||||
}
|
}
|
||||||
if(debug):
|
if(debug):
|
||||||
print(f"Updating {device_id} on GLPI")
|
print(f"Updating {device_id} on GLPI")
|
||||||
|
|||||||
Reference in New Issue
Block a user