Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9e90b1b26f | |||
| d37227592b | |||
| 472dd4feb1 | |||
| 562d1f3596 | |||
| 4accbfc708 | |||
| a01b1eb764 | |||
| d7d3ee014a | |||
| a40cf5d050 | |||
| 20b7995761 | |||
| 571c9e9120 | |||
| 582268744b | |||
| 2965573551 | |||
| 9c430b9523 | |||
| 8743403f4c | |||
| a129217889 |
@@ -61,23 +61,23 @@ La partie systèmes et réseaux consiste à déployer une infrastructure virtual
|
||||
|
||||
---
|
||||
|
||||
# Mission I2 - Supervision des serveurs ap31-prod et ap31-test
|
||||
## Mission I2 - Supervision des serveurs ap31-prod et ap31-test
|
||||
|
||||
## Objectifs de la mission
|
||||
### Objectifs de la mission
|
||||
|
||||
- Superviser les serveurs `ap31-prod` et `ap31-test` avec Zabbix installé sur `ap31-mon`.
|
||||
- Vérifier la connectivité (ping), accès SSH, et service web pour `ap31-test`.
|
||||
- Utiliser les agents `zabbix_agent2` et associer les templates `linux-server`.
|
||||
- Envoyer des notifications en cas d’incident (non réalisé via Zabbix mais avec Uptime Kuma).
|
||||
|
||||
## Installation et configuration
|
||||
### Installation et configuration
|
||||
|
||||
- Installation via `apt` des paquets Zabbix serveur, frontend, agent2, et MariaDB.
|
||||
- Création d’une base MariaDB dédiée à Zabbix avec utilisateur spécifique et import du schéma initial.
|
||||
- Configuration de l’interface web Zabbix avec connexion à la base MariaDB locale.
|
||||
- Activation automatique et vérification des services Zabbix.
|
||||
|
||||
## Déploiement et supervision
|
||||
### Déploiement et supervision
|
||||
|
||||
- Utilisation du wizard agent avec clés PSK pour déployer les agents sur `ap31-prod` et `ap31-test`.
|
||||
- Association des templates `linux-server` aux agents.
|
||||
@@ -87,15 +87,15 @@ La partie systèmes et réseaux consiste à déployer une infrastructure virtual
|
||||
|
||||
---
|
||||
|
||||
# Mission I3 - Mise en place d'une infrastructure de gestion centralisée des logs
|
||||
## Mission I3 - Mise en place d'une infrastructure de gestion centralisée des logs
|
||||
|
||||
## Objectifs de la mission
|
||||
### Objectifs de la mission
|
||||
|
||||
- Centraliser les logs de plusieurs serveurs (`ap31-prod`, `ap31-test`, `gwsiox`) sur une machine dédiée (`ap31-mon`) via `systemd-journal-remote`.
|
||||
- Mettre en place une politique de rotation et de rétention des logs syslog, avec une rotation hebdomadaire sur 4 semaines.
|
||||
- Garantir la cohérence temporelle entre toutes les machines impliquées grâce à une synchronisation horaire fiable.
|
||||
|
||||
## Mise en œuvre
|
||||
### Mise en œuvre
|
||||
|
||||
### Sur la machine centrale (réceptrice `ap31-mon`)
|
||||
|
||||
@@ -116,3 +116,35 @@ La partie systèmes et réseaux consiste à déployer une infrastructure virtual
|
||||
|
||||
---
|
||||
|
||||
## Mission I4 – Sécurisation et sauvegarde de la base de données
|
||||
|
||||
### Objectifs de la mission
|
||||
|
||||
- Sécuriser l'accès SSH aux machines via authentification par clé publique uniquement.
|
||||
- Mettre en place une **sauvegarde automatique, compressée et quotidienne** de la base MariaDB sur `ap31-test`.
|
||||
- Conserver un **historique de 7 jours** de ces sauvegardes.
|
||||
- Fournir un script permettant de **restaurer la dernière sauvegarde** sur `ap31-prod`.
|
||||
|
||||
### Sécurisation de l'accès SSH
|
||||
|
||||
- Utilisation exclusive de l’**authentification par clé publique** :
|
||||
- Ajout des clés des administrateurs dans le fichier `~/.ssh/authorized_keys`.
|
||||
- Désactivation de l’authentification par mot de passe dans `/etc/ssh/sshd_config` (`PasswordAuthentication no`).
|
||||
- Configuration du fichier `~/.ssh/config` pour permettre la connexion via **nom de domaine personnalisé**, avec des alias pour simplifier l'accès aux serveurs (ex. : `ssh ap31-prod`).
|
||||
- Redémarrage du service SSH pour prise en compte des modifications.
|
||||
|
||||
### Sauvegarde automatisée de MariaDB sur `ap31-test`
|
||||
|
||||
- Mise en place d’un **script bash exécuté quotidiennement** (via cron) pour :
|
||||
- Effectuer un **dump** de la base `sdis29` avec l’utilisateur `adminBDsdis`.
|
||||
- Compresser la sauvegarde (`gzip`).
|
||||
- La stocker dans `/var/backups/mariadb` avec un nom de fichier horodaté.
|
||||
- Supprimer les sauvegardes plus anciennes que 7 jours.
|
||||
|
||||
### Restauration de la dernière sauvegarde sur `ap31-prod`
|
||||
|
||||
- Un script permet de :
|
||||
- **Décompresser** la dernière sauvegarde disponible.
|
||||
- **Restaurer automatiquement** le fichier SQL dans la base `sdis29` sur `ap31-prod` à l’aide des identifiants fournis.
|
||||
|
||||
|
||||
21
partie1/configs/backup_mariadb.sh
Normal file
21
partie1/configs/backup_mariadb.sh
Normal file
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Variables
|
||||
DATE=$(date +'%Y-%m-%d_%H-%M-%S')
|
||||
BACKUP_DIR="/var/backups/mariadb"
|
||||
DB_NAME="sdis29"
|
||||
DB_USER="adminBDsdis"
|
||||
DB_PASS="u@4xKH@X"
|
||||
|
||||
|
||||
# Créer le dossier de backup s'il n'existe pas
|
||||
mkdir -p $BACKUP_DIR
|
||||
|
||||
# Exécuter la sauvegarde
|
||||
mysqldump -u $DB_USER -p$DB_PASS $DB_NAME > $BACKUP_DIR/${DB_NAME}_backup_$DATE.sql
|
||||
|
||||
# Optionnel : compresser la sauvegarde
|
||||
gzip $BACKUP_DIR/${DB_NAME}_backup_$DATE.sql
|
||||
|
||||
# Nettoyer les anciennes sauvegardes (plus de 7 jours dans notre cas)
|
||||
find $BACKUP_DIR -type f -name "*.gz" -mtime +7 -exec rm {} \;
|
||||
25
partie1/configs/docker-compose.yml
Normal file
25
partie1/configs/docker-compose.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
services:
|
||||
payara:
|
||||
image: payara/server-full:6.2025.9-jdk17
|
||||
container_name: payara
|
||||
ports:
|
||||
- "8080:8080"
|
||||
- "4848:4848"
|
||||
env_file:
|
||||
- "variables.env"
|
||||
volumes:
|
||||
- ./mariadb-java-client-3.5.6.jar:/opt/payara/glassfish/domains/domain1/lib/mariadb-java-client-3.5.6.jar:ro
|
||||
restart: unless-stopped
|
||||
|
||||
db:
|
||||
image: mariadb:latest
|
||||
container_name: db
|
||||
ports:
|
||||
- "3306:3306"
|
||||
env_file:
|
||||
- "variables.env"
|
||||
volumes:
|
||||
- ./data/db_data:/var/lib/mysql
|
||||
- ./init:/docker-entrypoint-initdb.d
|
||||
restart: unless-stopped
|
||||
|
||||
@@ -10,17 +10,17 @@ interface:
|
||||
eth0:
|
||||
exists: true
|
||||
addrs:
|
||||
- 172.16.0.101/24
|
||||
- 172.16.0.100/24
|
||||
- fe80::be24:11ff:fed2:d5ff/64
|
||||
mtu: 1500
|
||||
http:
|
||||
http://ap31-test.sio.lan:8080/:
|
||||
http://ap31-prod.sio.lan:8080/:
|
||||
status: 200
|
||||
allow-insecure: false
|
||||
no-follow-redirects: false
|
||||
timeout: 10000
|
||||
body: []
|
||||
https://ap31-test.sio.lan:4848/:
|
||||
https://ap31-prod.sio.lan:4848/:
|
||||
status: 200
|
||||
allow-insecure: true
|
||||
no-follow-redirects: false
|
||||
2
partie1/configs/http-proxy.conf
Normal file
2
partie1/configs/http-proxy.conf
Normal file
@@ -0,0 +1,2 @@
|
||||
[Service]
|
||||
Environment="HTTP_PROXY=http://10.121.38.1:8080/" "HTTPS_PROXY=http://10.121.38.1:8080/" "NO_PROXY=localhost,127.0.0.0/8"
|
||||
@@ -1,7 +1,7 @@
|
||||
MYSQL_DATABASE=bdclient
|
||||
MYSQL_DATABASE=sdis29
|
||||
MYSQL_HOST=db
|
||||
MYSQL_PORT=3306
|
||||
MYSQL_USER=adminBDCli
|
||||
MYSQL_USER=adminBDsdis
|
||||
MYSQL_PASSWORD=u@4xKH@X
|
||||
MYSQL_ROOT_PASSWORD=2Fc#$9Fn
|
||||
|
||||
0
partie2/README.md
Normal file
0
partie2/README.md
Normal file
5
partie2/ansible/.env
Normal file
5
partie2/ansible/.env
Normal file
@@ -0,0 +1,5 @@
|
||||
GLPI_DB_HOST=db
|
||||
GLPI_DB_PORT=3306
|
||||
GLPI_DB_NAME=glpi
|
||||
GLPI_DB_USER=glpi
|
||||
GLPI_DB_PASSWORD=9Z8&i9zWUeOi
|
||||
BIN
partie2/ansible/files/SDIS29MedhiEmile-1.0-SNAPSHOT.war
Normal file
BIN
partie2/ansible/files/SDIS29MedhiEmile-1.0-SNAPSHOT.war
Normal file
Binary file not shown.
26
partie2/ansible/files/compose.yml
Normal file
26
partie2/ansible/files/compose.yml
Normal file
@@ -0,0 +1,26 @@
|
||||
services:
|
||||
payara:
|
||||
image: payara/server-full:6.2025.9-jdk17
|
||||
container_name: payara
|
||||
ports:
|
||||
- "8080:8080"
|
||||
- "4848:4848"
|
||||
env_file:
|
||||
- "variables.env"
|
||||
volumes:
|
||||
- ./mariadb-java-client-3.5.6.jar:/opt/payara/glassfish/domains/domain1/lib/mariadb-java-client-3.5.6.jar:ro
|
||||
- ./SDIS29MedhiEmile-1.0-SNAPSHOT.war:/opt/payara/glassfish/domains/domain1/autodeploy/SDIS29MedhiEmile-1.0-SNAPSHOT.war
|
||||
restart: unless-stopped
|
||||
|
||||
db:
|
||||
image: mariadb:latest
|
||||
container_name: db
|
||||
ports:
|
||||
- "3306:3306"
|
||||
env_file:
|
||||
- "variables.env"
|
||||
volumes:
|
||||
- ./data/db_data:/var/lib/mysql
|
||||
- ./init:/docker-entrypoint-initdb.d
|
||||
restart: unless-stopped
|
||||
|
||||
33
partie2/ansible/files/docker-compose.yml
Normal file
33
partie2/ansible/files/docker-compose.yml
Normal file
@@ -0,0 +1,33 @@
|
||||
services:
|
||||
glpi:
|
||||
image: "glpi/glpi:latest"
|
||||
restart: "unless-stopped"
|
||||
volumes:
|
||||
- "./storage/glpi:/var/glpi:rw"
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
env_file: .env
|
||||
environment:
|
||||
TZ: Europe/Paris
|
||||
ports:
|
||||
- "4000:80"
|
||||
|
||||
db:
|
||||
image: mariadb:latest
|
||||
restart: "unless-stopped"
|
||||
volumes:
|
||||
- ./storage/mariadb:/var/lib/mysql
|
||||
environment:
|
||||
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
|
||||
MYSQL_DATABASE: ${GLPI_DB_NAME}
|
||||
MYSQL_USER: ${GLPI_DB_USER}
|
||||
MYSQL_PASSWORD: ${GLPI_DB_PASSWORD}
|
||||
healthcheck:
|
||||
test: [ "CMD", "healthcheck.sh", "--su-mysql", "--connect", "--innodb_initialized" ]
|
||||
start_period: 5s
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
expose:
|
||||
- "3306"
|
||||
2
partie2/ansible/files/http-proxy.conf
Normal file
2
partie2/ansible/files/http-proxy.conf
Normal file
@@ -0,0 +1,2 @@
|
||||
[Service]
|
||||
Environment="HTTP_PROXY=http://10.121.38.1:8080/" "HTTPS_PROXY=http://10.121.38.1:8080/" "NO_PROXY=localhost,127.0.0.0/8"
|
||||
BIN
partie2/ansible/files/mariadb-java-client-3.5.6.jar
Normal file
BIN
partie2/ansible/files/mariadb-java-client-3.5.6.jar
Normal file
Binary file not shown.
BIN
partie2/ansible/files/sdis29.sql.gz
Normal file
BIN
partie2/ansible/files/sdis29.sql.gz
Normal file
Binary file not shown.
7
partie2/ansible/files/variables.env
Normal file
7
partie2/ansible/files/variables.env
Normal file
@@ -0,0 +1,7 @@
|
||||
MYSQL_DATABASE=sdis29
|
||||
MYSQL_HOST=db
|
||||
MYSQL_PORT=3306
|
||||
MYSQL_USER=adminBDsdis
|
||||
MYSQL_PASSWORD=u@4xKH@X
|
||||
MYSQL_ROOT_PASSWORD=2Fc#$9Fn
|
||||
|
||||
4
partie2/ansible/hosts
Normal file
4
partie2/ansible/hosts
Normal file
@@ -0,0 +1,4 @@
|
||||
[ap31-srv]
|
||||
ap31-pt
|
||||
#ap31-test #ansible_host=172.16.0.101
|
||||
#ap31-prod ansible_host=172.16.0.100
|
||||
29
partie2/ansible/install-glpi.yml
Normal file
29
partie2/ansible/install-glpi.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
- name: Installation de GLPI avec Docker
|
||||
hosts: ap31-pt
|
||||
become: yes
|
||||
|
||||
tasks:
|
||||
- name: Création du dossier glpi
|
||||
ansible.builtin.file:
|
||||
path: /root/glpi
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Importation du fichier docker-compose.yml
|
||||
ansible.builtin.copy:
|
||||
src: ./files/docker-compose.yml
|
||||
dest: /root/glpi/docker-compose.yml
|
||||
mode: '0644'
|
||||
|
||||
- name: Importation du fichier .env
|
||||
ansible.builtin.copy:
|
||||
src: .env
|
||||
dest: /root/glpi/.env
|
||||
mode: '0600'
|
||||
|
||||
- name: Pull et lancement du conteneur GLPI
|
||||
ansible.builtin.shell:
|
||||
cmd: docker compose pull && docker compose up -d
|
||||
chdir: /root/glpi
|
||||
|
||||
91
partie2/ansible/mkwgconf-p2p.sh
Normal file
91
partie2/ansible/mkwgconf-p2p.sh
Normal file
@@ -0,0 +1,91 @@
|
||||
è-#!/bin/bash
|
||||
set -u
|
||||
set -e
|
||||
|
||||
AddressAwg=10.0.0.1/32 # Adresse VPN Wireguard extremite A
|
||||
EndpointA=172.16.0.101 # Adresse extremite A
|
||||
PortA=51820 # Port ecoute extremite A
|
||||
AddressBwg=10.0.0.2/32 # Adresse VPN Wireguard extremite B
|
||||
EndpointB=172.16.0.102 # Adresse extremite B
|
||||
PortB=51820 # Port ecoute extremite B
|
||||
AddressCwg=10.0.0.3/32 # Adresse VPN Wireguard extremite C
|
||||
EndpointC=172.0.0.103 # Adresse extremite C
|
||||
PortC=51820 # Port ecoute extremite C
|
||||
|
||||
umask 077 ;
|
||||
wg genkey > endpoint-a.key
|
||||
wg pubkey < endpoint-a.key > endpoint-a.pub
|
||||
|
||||
wg genkey > endpoint-b.key
|
||||
wg pubkey < endpoint-b.key > endpoint-b.pub
|
||||
|
||||
wg genkey > endpoint-c.key
|
||||
wg pubkey < endpoint-c.key > endpoint-c.pub
|
||||
|
||||
PKA=$(cat endpoint-a.key)
|
||||
pKA=$(cat endpoint-a.pub)
|
||||
PKB=$(cat endpoint-b.key)
|
||||
pKB=$(cat endpoint-b.pub)
|
||||
PKC=$(cat endpoint-c.key)
|
||||
pKC=$(cat endpoint-c.pub)
|
||||
|
||||
cat <<FINI > wg0-a.conf
|
||||
# local settings for Endpoint A
|
||||
[Interface]
|
||||
PrivateKey = $PKA
|
||||
Address = $AddressAwg
|
||||
ListenPort = $PortA
|
||||
|
||||
# remote settings for Endpoint B
|
||||
[Peer]
|
||||
PublicKey = $pKB
|
||||
Endpoint = ${EndpointB}:$PortB
|
||||
AllowedIPs = $AddressBwg
|
||||
|
||||
# remote settings for Endpoint C
|
||||
[Peer]
|
||||
PublicKey = $pKC
|
||||
Endpoint = ${EndpointC}:$PortC
|
||||
AllowedIPs = $AddressCwg
|
||||
FINI
|
||||
|
||||
|
||||
cat <<FINI > wg0-b.conf
|
||||
# local settings for Endpoint B
|
||||
[Interface]
|
||||
PrivateKey = $PKB
|
||||
Address = $AddressBwg
|
||||
ListenPort = $PortB
|
||||
|
||||
# remote settings for Endpoint A
|
||||
[Peer]
|
||||
PublicKey = $pKA
|
||||
Endpoint = ${EndpointA}:$PortA
|
||||
AllowedIPs = $AddressAwg
|
||||
|
||||
# remote settings for Endpoint C
|
||||
[Peer]
|
||||
PublicKey = $pKC
|
||||
Endpoint = ${EndpointC}:$PortC
|
||||
AllowedIPs = $AddressCwg
|
||||
FINI
|
||||
|
||||
cat <<FINI > wg0-c.conf
|
||||
# local settings for Endpoint C
|
||||
[Interface]
|
||||
PrivateKey = $PKC
|
||||
Address = $AddressBwg
|
||||
ListenPort = $PortB
|
||||
|
||||
# remote settings for Endpoint A
|
||||
[Peer]
|
||||
PublicKey = $pKA
|
||||
Endpoint = ${EndpointA}:$PortA
|
||||
AllowedIPs = $AddressAwg
|
||||
|
||||
# remote settings for Endpoint B
|
||||
[Peer]
|
||||
PublicKey = $pKB
|
||||
Endpoint = ${EndpointB}:$PortB
|
||||
AllowedIPs = $AddressBwg
|
||||
FINI
|
||||
62
partie2/ansible/payara.yml
Normal file
62
partie2/ansible/payara.yml
Normal file
@@ -0,0 +1,62 @@
|
||||
---
|
||||
- name: Installation de docker et payara dockerisé
|
||||
hosts: ap31-pt
|
||||
become: yes
|
||||
|
||||
tasks:
|
||||
- name: Téléchargement docker
|
||||
ansible.builtin.get_url:
|
||||
url: http://depl.sio.lan/store/get-docker.sh
|
||||
dest: /tmp
|
||||
|
||||
- name: Execution du script get-docker.sh
|
||||
ansible.builtin.shell:
|
||||
cmd: export https_proxy=http://10.121.38.1:8080 ; bash /tmp/get-docker.sh
|
||||
|
||||
- name: Création d'un dossier payara
|
||||
ansible.builtin.file:
|
||||
path: ~/payara
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Importation du fichier compose.yml
|
||||
ansible.builtin.copy:
|
||||
src: ./files/compose.yml
|
||||
dest: ~/payara/compose.yml
|
||||
mode: '0755'
|
||||
|
||||
- name: Création du répertoire docker.service.d
|
||||
ansible.builtin.file:
|
||||
path: /etc/systemd/system/docker.service.d
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
|
||||
- name: Importation du fichier http-proxy.conf pour docker
|
||||
ansible.builtin.copy:
|
||||
src: ./files/http-proxy.conf
|
||||
dest: /etc/systemd/system/docker.service.d/http-proxy.conf
|
||||
mode: '0755'
|
||||
|
||||
- name: Importation du fichier variables.env
|
||||
ansible.builtin.copy:
|
||||
src: ./files/variables.env
|
||||
dest: /root/payara/
|
||||
mode: '0755'
|
||||
|
||||
- name: Importation de la base de données compréssée
|
||||
ansible.builtin.copy:
|
||||
src: ./files/sdis29.sql.gz
|
||||
dest: /root/payara/init/
|
||||
mode: '0755'
|
||||
|
||||
- name: Importation du fichier war
|
||||
ansible.builtin.copy:
|
||||
src: ./files/SDIS29MedhiEmile-1.0-SNAPSHOT.war
|
||||
dest: /root/payara
|
||||
|
||||
- name: Docker pull et docker compose up -d
|
||||
ansible.builtin.shell:
|
||||
cmd: usermod -aG docker debian ; systemctl daemon-reload ; systemctl restart docker ; cd ~/payara ; docker compose pull && docker compose up -d ; docker compose down -v ; rm -rf ./data/ ; docker compose up -d
|
||||
|
||||
|
||||
60
partie2/ansible/wg.yml
Normal file
60
partie2/ansible/wg.yml
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
- name: WireGuard pour apx31-prod et apx31-test
|
||||
hosts:
|
||||
- ap31-test
|
||||
- ap31-prod
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
|
||||
- name: Installer WireGuard
|
||||
apt:
|
||||
name:
|
||||
- wireguard
|
||||
- wireguard-tools
|
||||
state: present
|
||||
update_cache: true
|
||||
|
||||
- name: Copier le script mkwgconf-p2p.sh dans /tmp
|
||||
ansible.builtin.copy:
|
||||
src: mkwgconf-p2p.sh
|
||||
dest: /tmp/mkwgconf-p2p.sh
|
||||
mode: '0755'
|
||||
|
||||
- name: Executer le script mkwgconf
|
||||
ansible.builtin.shell:
|
||||
cmd: cd /tmp && /tmp/mkwgconf-p2p.sh
|
||||
when: inventory_hostname == "ap31-test"
|
||||
|
||||
- name: Recupere wg0-a.conf
|
||||
ansible.builtin.fetch:
|
||||
src: /tmp/wg0-a.conf
|
||||
dest: /tmp/
|
||||
# mode: '0600'
|
||||
flat: yes
|
||||
when: inventory_hostname == "ap31-test"
|
||||
|
||||
- name: Recupere wg0-b.conf
|
||||
ansible.builtin.fetch:
|
||||
src: /tmp/wg0-b.conf
|
||||
dest: /tmp/
|
||||
# mode: '0600'
|
||||
flat: yes
|
||||
when: inventory_hostname == "ap31-test"
|
||||
|
||||
- name: Renvoi wg0-a.conf
|
||||
ansible.builtin.copy:
|
||||
src: /tmp/wg0-a.conf
|
||||
dest: /etc/wireguard/wg0.conf
|
||||
# mode: '0600'
|
||||
when: inventory_hostname == "ap31-test"
|
||||
|
||||
- name: Renvoi wg0-b.conf
|
||||
ansible.builtin.copy:
|
||||
src: /tmp/wg0-b.conf
|
||||
dest: /etc/wireguard/wg0.conf
|
||||
#mode: '0600'
|
||||
when: inventory_hostname == "ap31-prod"
|
||||
|
||||
|
||||
|
||||
0
partie2/test
Normal file
0
partie2/test
Normal file
Reference in New Issue
Block a user