Reupload (purge)
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
desktop.ini
|
||||
**/__pycache__/
|
||||
**/.venv/
|
||||
**/.vscode/
|
||||
@@ -0,0 +1 @@
|
||||
3.14
|
||||
@@ -0,0 +1,7 @@
|
||||
# Cours LiveCampus
|
||||
|
||||
Par Gauvain Boiché, promotion MCS 2027.2 de LiveCampus. Début des cours 20 octobre 2025.
|
||||
|
||||
## Projet
|
||||
|
||||
Il est privé pour que les réponses ne fuitent pas. Mais il est disponible sur demande pour vérifier... je ne sais pas, mon assiduité ? Mes réponses ? Ma hiérarchistation des dossiers de prises de notes ?
|
||||
@@ -0,0 +1,76 @@
|
||||
# L'infra avancée :
|
||||
|
||||
## Exercice 1
|
||||
|
||||
### Lancer une machine
|
||||
|
||||
`qemu-img create -f qcow2 'C:\Program Files\qemu\testVM.qcow2' 10G`
|
||||
|
||||
`qemu-system-x86_64 -m 2048 -hda 'C:\_VMs\testVM.qcow2' -cdrom 'D:\Users\GaWin\Downloads\_Compressed\debian-13.1.0-amd64-netinst.iso' -boot d`
|
||||
|
||||
Pour lancer une machine depuis le disque :
|
||||
|
||||
`qemu-system-x86_64 -m 4096 -smp 4 -hda 'C:\_VMs\testVM.qcow2' -boot c`
|
||||
|
||||
- -boot d : Boot sur le CD/ROM
|
||||
- -boot c : Boot sur le Disque Dur
|
||||
- m XXXX : Alloue une mémoire RAM fixe
|
||||
- smp X : Alloue un nombre de coeurs virtuels fixe
|
||||
|
||||
Pour convertir le .qcow2 en .vdi, dans l'interface c'est plus clair.
|
||||
|
||||
## Exercice 2
|
||||
|
||||
### Créer une VM
|
||||
|
||||
Pour refaire une VM en CLI :
|
||||
|
||||
```
|
||||
vboxmanage createvm --basefolder="C:\_VMs\VirtualCreationCLI" --register --name "VirtualBoxCLI"
|
||||
|
||||
vboxmanage storagectl "VirtualBoxCLI" --name "sata-controller" --add sata --controller IntelAHCI --portcount 1 --bootable on
|
||||
|
||||
vboxmanage storageattach "VirtualBoxCLI" --storagectl "sata-controller" --port 0 --device 0 --type hdd --medium ".\test_copy.vdi"
|
||||
|
||||
vboxmanage modifyvm "VirtualBoxCLI" --memory 4096 --cpus 4
|
||||
```
|
||||
|
||||
### Convertir un disque virtuel .qcow2 en CLI
|
||||
|
||||
https://github.com/michaelrudy/qemu-img-convert
|
||||
|
||||
D'abord, dans la VM d'origine, il faut préparer la transition :
|
||||
|
||||
```
|
||||
sudo tee /etc/dracut.conf.d/hyperv.conf >/dev/null <<'EOF'
|
||||
add_drivers+=" hv_vmbus hv_storvsc hv_netvsc hv_utils "
|
||||
hostonly="no"
|
||||
EOF
|
||||
|
||||
sudo dracut -f --kver "$(uname -r)"
|
||||
|
||||
ls -lh /boot/initramfs-$(uname -r).img ### pour confirmer
|
||||
|
||||
cat /etc/fstab
|
||||
blkid
|
||||
|
||||
sudo shutdown -h now
|
||||
```
|
||||
|
||||
`qemu-img convert -f qcow2 -O vhdx -o subformat=dynamic .\test.qcow2 .\test_copy.vhdx`
|
||||
|
||||
Bizarrement, pour que la conversion soit prise en compte par Hyper-V, il faut lancer cette commande :
|
||||
|
||||
`fsutil sparse setflag .\test_copy.vhdx 0`
|
||||
|
||||
### Cloner une VM en CLI
|
||||
|
||||
Exporter pour VirtualBox
|
||||
`vboxmanage clonevm "VirtualBoxCLI" --basefolder ".\NewVirtualBoxCLI" --name "NewVirtualBoxCLI" --register`
|
||||
|
||||
Exporter pour HyperV
|
||||
```
|
||||
Export-VM -Name "HyperVCLI" -Path "C:\_VMs\HyperVCLI" -CaptureLiveState CaptureSavedState
|
||||
|
||||
Import-VM -Name "NewHyperVCLI" -Path "C:\_VMs\HyperVCLI\{ID-de-ses-morts}.vmcx" -Copy -GenerateNewId -VirtualMachinePath "C:\_VMs\NewHyperVCLI" -VhdDestinationPath "C:\_VMs\NewHyperVCLI"
|
||||
```
|
||||
@@ -0,0 +1,161 @@
|
||||
# Infra avancée
|
||||
|
||||
## Cours
|
||||
|
||||
### Contenerisation
|
||||
|
||||
- Namespace : les processus ne peuvent pas voir les ressources utilisées par l'hôte ou ses congénères
|
||||
- cgroups : contrôle des ressources allouées à un processus
|
||||
|
||||
#### Solutions :
|
||||
|
||||
- Docker / Podman
|
||||
- OpenVZ
|
||||
- Les zones (Solaris)
|
||||
- Les jails (FreeBSD)
|
||||
- LXC
|
||||
|
||||
### LXC
|
||||
|
||||
```
|
||||
# Avec interactivté
|
||||
sudo lxc-create -n NOM_CONTENEUR -t download
|
||||
|
||||
# Sans interactivité (pour script)
|
||||
sudo lxc-create --template=download --name NOM_CONTENEUR -- --dist NOM_DISTRIBUTION --release NUMERO_VERSION --arch amd64
|
||||
```
|
||||
|
||||
```
|
||||
# Démarrer
|
||||
sudo lxc-start -n NOM_CONTENEUR
|
||||
|
||||
# Entrer dans un conteneur
|
||||
sudo lxc-attach -n NOM_CONTENEUR
|
||||
|
||||
# Stopper
|
||||
sudo lxc-stop -n NOM_CONTENEUR
|
||||
|
||||
# Supprimer
|
||||
sudo lxc-destroy -n NOM_CONTENEUR
|
||||
|
||||
# Lister
|
||||
sudo lxc-ls (--active, --running, --frozen)
|
||||
|
||||
# Info sur conteneur précis
|
||||
sudo lxc-info -n NOM_CONTENEUR
|
||||
```
|
||||
|
||||
Fichier config du conteneur (/var/lib/lxc/xxx) :
|
||||
```
|
||||
# Méthode 1 : Montage d'un dossier de l'hôte
|
||||
lxc.mount.entry = /dossier_hote dossier_interne_conteneur none bind,create=dir 0 0
|
||||
|
||||
# Méthode 2 : Montage d'un disque entier ou partition de l'hôte
|
||||
lxc.mount.entry = /dev/disque_ou_partition dossier_interne_conteneur FS_type defaults,create=dir 0 0
|
||||
```
|
||||
|
||||
## Exercice 1
|
||||
|
||||
https://dl-cdn.alpinelinux.org/alpine/v3.17/releases/x86_64/alpine-xen-3.17.10-x86_64.iso
|
||||
|
||||
```
|
||||
wget https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-13.1.0-amd64-netinst.iso
|
||||
|
||||
mv debian-13.1.0-amd64-netinst.iso debian.iso
|
||||
|
||||
sudo chmod 666 debian.iso
|
||||
```
|
||||
|
||||
Ensuite
|
||||
|
||||
```
|
||||
sudo virt-install \
|
||||
--name test-vm \
|
||||
--os-variant=debiantesting \
|
||||
--ram 2048 \
|
||||
--vcpus 2 \
|
||||
--location ./debian.iso \
|
||||
--disk path=/var/lib/libvirt/images/vm.qcow2,size=15,format=qcow2 \
|
||||
--graphics none \
|
||||
--console pty,target_type=serial \
|
||||
--extra-args "console=ttys0,115200n8 serial"
|
||||
```
|
||||
|
||||
`virsh attach-interface --type bridge --source enp0s3 --model virtio test-vm`
|
||||
|
||||
## Exercice 2
|
||||
|
||||
### Petit A
|
||||
|
||||
C'est installé.
|
||||
|
||||
### Petit B
|
||||
|
||||
```
|
||||
sudo lxc-create -n ConteneurDebian -t download
|
||||
# debian, bullseye, amd64
|
||||
|
||||
sudo lxc-start ConteneurDebian
|
||||
sudo lxc-attach ConteneurDebian
|
||||
|
||||
### In the container ###
|
||||
uname -a
|
||||
|
||||
> Linux ConteneurDebian 6.1.0-40-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.153-1 (2025-09-20) x86_64 GNU/Linux
|
||||
|
||||
cat /proc/version
|
||||
> Linux version 6.1.0-40-amd64 (gcc-12 (Debian 12.2.0-14+deb12u1) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40) #1 SMP PREEMPT_DYNAMIC Debian 6.1.153-1 (2025-09-20)
|
||||
|
||||
exit
|
||||
|
||||
### Outside the container ###
|
||||
|
||||
sudo lxc-ls
|
||||
> ConteneurDebian Test-Linux
|
||||
|
||||
sudo lxc-ls --running
|
||||
> ConteneurDebian
|
||||
|
||||
sudo lxc-stop ConteneurDebian
|
||||
|
||||
sudo lxc-ls --running
|
||||
>
|
||||
```
|
||||
|
||||
### Petit C
|
||||
|
||||
```
|
||||
sudo ls -glAiF /var/lib/lxc/
|
||||
> ConteneurDebian
|
||||
> Test-Linux
|
||||
|
||||
sudo ls -glAiF /var/lib/lxc/ConteneurDebian
|
||||
> -rw-r----- root config
|
||||
> drwxr-xr-x root rootfs/
|
||||
|
||||
sudo du -h -glAiF /var/lib/lxc/ConteneurDebian
|
||||
> ...
|
||||
> 412M
|
||||
|
||||
sudo lxc-copy -n ConteneurDebian -N NewConteneur ### -N pour NewName
|
||||
|
||||
sudo ls -glAiF /var/lib/lxc/
|
||||
> ConteneurDebian
|
||||
> NewConteneur
|
||||
> Test-Linux
|
||||
```
|
||||
|
||||
### Petit D
|
||||
|
||||
```
|
||||
sudo nano /var/lib/lxc/ConteneurDebian/config
|
||||
|
||||
### Dans le fichier config ###
|
||||
|
||||
# Folder Attachment
|
||||
lxc.mount.entry = /mnt/lxc-debian-storage /var/lib/lxc/ConteneurDebian/rootfs/data none bind,create=dir 0 0
|
||||
|
||||
### Fin du fichier config ###
|
||||
|
||||
|
||||
```
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,85 @@
|
||||
# Exos
|
||||
|
||||
Les réponses entre guillements anglais "" sont des corrections.
|
||||
|
||||
## 02.2.2 Questionnaire + Correction sur La containérisation
|
||||
|
||||
1. La virtualisation classique embarque un noyau complet ainsi que les couches micro-logiciels et divers pilotes. Un conteneur n'embarque que la partie applicative et repose sur un noyau principal de la machine hôte
|
||||
2. LXC embarque des conteneurs complets, avec kernels, sorte de VM légèrement allégée et plus flexible. Docker conteneurise à l'ancienne
|
||||
3. "cgroups et namespaces"
|
||||
4. En dur : Librairie C, kernel linux supérieur à 3.8. Recommandé : libcap, libapparmor, libselinux, libseccomp, libgnutls, liblua, python3-dev
|
||||
5. libcap (to allow for capability drops), libapparmor (to set a different apparmor profile for the container), libselinux (to set a different selinux context for the container), libseccomp (to set a seccomp policy for the container), libgnutls (for various checksumming), liblua (for the LUA binding), python3-dev (for the python3 binding)
|
||||
6. Non, Docker a son propre démon
|
||||
7. "Extension de LXC qui apporte des fonctions avancées comme gestion à distance et snapshot"
|
||||
8. Oui. sudo lxc-copy avec l'option --snapshot / "lxc-snapshot"
|
||||
9. "lxc network attach-profile PROFIL RESEAU"
|
||||
10. lxc-cgroup -n NOM_CONTENEUR cpuset.cpus "0,1" #Limite l'usage du conteneur aux coeurs 0 et 1
|
||||
11. lxc-cgroup -n NOM_CONTENEUR memory.limit_in_bytes "8000" #Does 1MB
|
||||
12. "Oui, si le conteneur est éteint, en SCP via SSH"
|
||||
13. "Non, sauf avec des outils tiers pas très fiables"
|
||||
14. /var/lib/lxc/
|
||||
15. /var/lib/lxc/NomDuConteneur/config
|
||||
|
||||
## Infrastructure Avancée . 02.1.2 Virtualiser des machines
|
||||
|
||||
1. Installer un système d'exploitation complet sans avoir à gérer l'hébergement machine par machine "et isolée du système"
|
||||
2. Virtualisation complète, "para-virtualisation, et isolation"
|
||||
3. Ca dépend de ce qu'on recherche. Maintenant la plus "perfomante" au sens gourmandise matérielle, c'est la conteneurisation
|
||||
4. Virtualiser c'est porter un SE sur une grosse bécane. Emulation c'est "convertir" une architecture matérielle (processeur) pour l'adapter à une autre archi
|
||||
5. Le mieux c'est une couche d'abstraction genre QEMU pour émuler
|
||||
6. Mode NAT configuré en sortie routeur (plus standard), mode pont (plus simple), mode Switch interne derrière un VLAN/routeur (plus sécurisé)
|
||||
7. Oracle c'est gratuit mais limité si on veut professionnaliser l'infra. VMWare c'est payant et devenu de la merde
|
||||
8. "virsh (virtual shell)"
|
||||
9. "Le groupe Virtualization Host"
|
||||
10. "vboxdrv, solution obsoilète"
|
||||
11. Lance une VM avec KVM activé, le disque virtuel 'ubuntudisquedur' attaché, une image .iso d'ubuntu en option de boot principale, "1024MB de RAM," avec deux interfaces réseaux et pas d'option ACPI
|
||||
12. vboxmanage
|
||||
13. Gérer plus nativement des déploiements de VM par script sur des serveurs neufs et sans paquets installés / "contrôle total au plus bas-niveau possible"
|
||||
14. "RAW"
|
||||
15. QCOW2
|
||||
16. Oui mais c'est chaud
|
||||
17. Oui, avec qemu-img convert
|
||||
18. "cpu-checker"
|
||||
19. "kvm-ok"
|
||||
20. "Xen, VMWare, Hyper-V"
|
||||
21. Hyper-V
|
||||
22. Hyperviseur de type 1 (et pas 2 comme on pourrait le croire)
|
||||
23. ESXi c'est du type 1 bare-metal, Workstation du type 2
|
||||
24. "Oui, ESXi est compatible AMD et ARM"
|
||||
25. "Client graphique permettant la gestion d'un seul hôte ESXi"
|
||||
26. Passthrough
|
||||
27. Hyperviseur type 1 basé sur un Debian fortement modifié, open-source et gratuit
|
||||
28. .vhdx, historiquement .vhd
|
||||
29. "Non"
|
||||
30. "On peut utiliser Linux Virtual Manager (interface bureau), ou Cockpit (interface web)"
|
||||
|
||||
## Questionnaire 02. Les différents types d_infrastructure avancées
|
||||
|
||||
1. "Centralisée (tout le contenu au même endroit), distribuée (), hybride ()."
|
||||
2. "Infra distribuée"
|
||||
3. Les +, de la résilience, les -, des configs en plus à faire pour rester en sécurité
|
||||
4. "La couche leaf"
|
||||
5. "Elle est évolutive et permet une communication de paquet très rapide, ce qui est idéal pour une infrastructure centralisée/un datacenter"
|
||||
6. "Le middleware est un logiciel intermédiaire se trouvant entre client lourd et machine finale. Il peut se trouver sur une machine client ou intermédiaire dédiée, ou même le serveur final, et parfois sur les trois."
|
||||
7. Network Access Storage. En anglais dans le texte
|
||||
8. Non. Sécurité + RGPD
|
||||
9. "Unité de stockage à distance, 'Logicial Unit in Network' car n'importe quelle techno peut se cacher derrière."
|
||||
10. SAN, Storage Area Network
|
||||
11. "On utilise le nom de 'fabric'"
|
||||
12. Bah, pas forcément... si les données doivent être cloisonnées, c'est un usage pertinent. Au pire on peut ouvrir le SAN pour plus de ressources si besoin
|
||||
13. Moins de latence, moins de déconnexions = moins de corruption dans les transferts
|
||||
14. "Couche coeur réseau, couche Agrégation, couche Accès"
|
||||
15. "Le trafic ne va plus être optimisé et devra passer par plus d'appareils qu'il était autrefois nécessaire"
|
||||
|
||||
## Questionnaire et correction 01. Introductions aux Infrastructures Avancées
|
||||
|
||||
1. ??? Genre l'archi AMD64, les transistors nanométriques, le PCI-E génération 5, la fibre optique, le protocole Wireguard... comment ça ?
|
||||
2. ?????? et bien, multiplier la résilience, les facilités de déploiement, réduire les besoins en gestion matérielle... comment ça ?
|
||||
3. ????????? Gain de productivité à gérer un seul hébergeur, centralisation des factures, interconnexion facilitées dans un VPC donné... comment ça ?
|
||||
4. Le public veut moins attendre et pardonne moins les interruptions de service
|
||||
5. Méthode 1,2,3 et ensuite avoir des CDN locaux réduit la latence en régional
|
||||
6. "Années 50-60"
|
||||
7. "Années 80"
|
||||
8. "Années 2000"
|
||||
9. La prince elle a dit que le stockage, maintenant, ça coûte pas cher
|
||||
10. "Le fait de place les données d'un SI au plus proche du client, à l'extrémité du réseau étendu"
|
||||
@@ -0,0 +1,255 @@
|
||||
# Infra avancée
|
||||
|
||||
## Cours 1
|
||||
|
||||
Redimensionner une partition sur Linux
|
||||
|
||||
```
|
||||
# Pour EXT2/3/4
|
||||
sudo resize2fs
|
||||
# Pour XFS
|
||||
sudo xfs_growfs
|
||||
```
|
||||
|
||||
Traiter les disques sur MDADM
|
||||
```
|
||||
# Déclarer disque défectueux
|
||||
sudo mdadm --fail /dev/
|
||||
# Le retirer
|
||||
sudo mdadm --remove /dev/
|
||||
# Le rajouter
|
||||
sudo mdadm --add /dev/mdx /dev/sdx # AJout comme Hot-Spare
|
||||
```
|
||||
|
||||
Pour enlever les traces du raid :
|
||||
|
||||
```
|
||||
sudo mdadm --zero-superblock /dev/sdx
|
||||
```
|
||||
|
||||
## Exercice 1
|
||||
|
||||
Tuto parfait : https://ruan.dev/blog/2022/06/29/create-a-raid5-array-with-mdadm-on-linux
|
||||
|
||||
```
|
||||
sudo apt install mdadm -y
|
||||
|
||||
lsblk
|
||||
> sde, sdg, sdh
|
||||
|
||||
fdisk /dev/sdx
|
||||
n # ajouter une -n-ouvelle partition
|
||||
p # partition -p-rimaire
|
||||
1 # index de la partition
|
||||
[default] # bloc de début
|
||||
[default] # bloc de fin
|
||||
|
||||
t # modifier le -t-ype d'une partition
|
||||
L # -l-iste tous les codes hexa
|
||||
fd # RAID Linux auto
|
||||
|
||||
w # écrire (-w-rite) la table sur le disque et quitter
|
||||
|
||||
sudo mdadm --create /dev/md127 --level=5 --raid-devices=3 /dev/sde1 /dev/sdg1 /dev/sdh1
|
||||
|
||||
mkfs.ext4 /dev/md127
|
||||
|
||||
sudo mount /dev/md127 /mnt
|
||||
```
|
||||
|
||||
Eteindre, ajouter un disque, étendre la partition
|
||||
```
|
||||
lsblk
|
||||
> sdh
|
||||
|
||||
fdisk /dev/sdh
|
||||
n
|
||||
p
|
||||
1
|
||||
[default]
|
||||
[default]
|
||||
|
||||
t
|
||||
fd
|
||||
|
||||
w
|
||||
|
||||
sudo mdadm --add /dev/md127 /dev/sdh1
|
||||
|
||||
sudo mdadm --detail /dev/md127
|
||||
> Active Devices : 3
|
||||
> Working Devices : 4
|
||||
> Spare Devices : 1
|
||||
|
||||
sudo mdadm --add /dev/md127 --raid-devices=4
|
||||
|
||||
sudo mdadm --detail /dev/md127
|
||||
> Active Devices : 4
|
||||
> Working Devices : 4
|
||||
> Spare Devices : 0
|
||||
|
||||
sudo e2fsck -f /dev/md127
|
||||
|
||||
sudo resize2fs /dev/md127
|
||||
|
||||
sudo mount /dev/md127 /mnt/sauvegarde
|
||||
|
||||
df -h /mnt/sauvegarde
|
||||
> Sys. de fichiers Taille Utilisé Dispo Uti% Monté sur
|
||||
> /dev/md127 3,0G 28K 2,8G 1% /mnt/sauvegarde
|
||||
```
|
||||
|
||||
## Cours 2
|
||||
|
||||
### LVM
|
||||
|
||||
Créer volume LVM depuis disque physique
|
||||
|
||||
```
|
||||
pvcreate /DEVICE1 /DEVICE2 /DEVICE3
|
||||
|
||||
# Intégrer ces volumes à un groupe de volume
|
||||
vgcreate NOM_DU_VG /DEVICE1 /DEVICE2
|
||||
|
||||
# On découpe ces volumes
|
||||
lvcreate -l TAILLE -n NOM_DU_LV NOM_DU_VG
|
||||
```
|
||||
|
||||
VG et LV peuvent être accessibles par plusieurs chemins
|
||||
|
||||
`/dev/mapper/`
|
||||
|
||||
Identifier LV ou VG
|
||||
|
||||
```
|
||||
# Identifier LV ou VG
|
||||
sudo lvdisplay vgdisplay
|
||||
|
||||
sudo lvremove
|
||||
|
||||
sudo
|
||||
```
|
||||
|
||||
Etendre VG
|
||||
|
||||
```
|
||||
sudo vgdisplay
|
||||
|
||||
sudo vgextend NOM_DU_VG/PV_SUPPLEMENTAIRE
|
||||
|
||||
# Pour tester
|
||||
|
||||
```
|
||||
|
||||
Identifier le LV à étendre
|
||||
|
||||
```
|
||||
sudo lvdisplay
|
||||
|
||||
sudo lvextend MON_VG/NOM_DU_LV /PV_SUPPLEMENTAIRE
|
||||
|
||||
# Option pour donner une taille délimitée
|
||||
sudo lvextend -L +00M
|
||||
```
|
||||
|
||||
Il faut redimensionner à chaud après l'extension avec `--resizefs` à chaud, toucher à un LV ne change pas la taille du système de fichiers.
|
||||
|
||||
Réduire un VG
|
||||
|
||||
```
|
||||
sudo vgdisplay
|
||||
|
||||
sudo
|
||||
```
|
||||
|
||||
## Exercice 2
|
||||
|
||||
### Partie 1
|
||||
|
||||
A créer, avec chacun deux disques :
|
||||
```
|
||||
Nom MD Taille Type FS Nom VL1-nom VL1-taille VL1-mnt VL2-nom VL2-taille VL2-mnt
|
||||
-----------------------------------------------------------------------------------------------------------------------------------
|
||||
/dev/md123 2GO RAID1 btrfs "Production" "Current" 50% /mnt/prod/Current - - -
|
||||
/dev/md124 2GO RAID1 XFS "Sauvegarde" "Current" 100% /mnt/sauv/current - - -
|
||||
/dev/md125 2GO RAID1 EXT4 "Développement" "x86_64" 60% /mnt/dev/x86_64 "ARM" 40% /mnt/dev/arm
|
||||
/dev/md126 2GO RAID1 EXT4 "Laboratoire" "Current" 100% /mnt/labo/current - -
|
||||
```
|
||||
|
||||
Maintenant on colle les ressources.
|
||||
|
||||
Pour attribuer des % de taille aux LV :
|
||||
```
|
||||
sudo lvcreate -l 100%FREE # Toute la place restante
|
||||
sudo lvcreate -l 50%VG # 50% de la taille totale du VG
|
||||
sudo lvcreate -l 30%FREE # 30% de la place restante ACTUELLE
|
||||
```
|
||||
|
||||
-
|
||||
```
|
||||
sudo mdadm --create /dev/md12x --level=1/0 --raid-devices=2 /dev/sdx1 /dev/sdy1
|
||||
|
||||
sudo pvcreate /dev/md123
|
||||
sudo vgcreate Production /dev/md123
|
||||
sudo lvcreate -l 50%VG -n Current Production
|
||||
|
||||
sudo pvcreate /dev/md124
|
||||
sudo vgcreate Sauvegarde /dev/md124
|
||||
sudo lvcreate -l 100%VG -n Current Sauvegarde
|
||||
|
||||
sudo pvcreate /dev/md125
|
||||
sudo vgcreate Developpement /dev/md125
|
||||
sudo lvcreate -l 60%VG -n x86_64 Developpement
|
||||
sudo lvcreate -l 100%FREE -n ARM Developpement
|
||||
|
||||
sudo pvcreate /dev/md126
|
||||
sudo vgcreate Laboratoire /dev/md126
|
||||
sudo lvcreate -l 100%VG -n Current Laboratoire
|
||||
|
||||
sudo lvs -o lv_name,vg_name,lv_size,attr
|
||||
|
||||
sudo mkfs.btrfs /dev/mapper/Production-Current
|
||||
sudo mkfs.xfs /dev/mapper/Sauvegarde-Current
|
||||
sudo mkfs.ext4 /dev/mapper/Developpement-x86_64
|
||||
sudo mkfs.ext4 /dev/mapper/Developpement-ARM
|
||||
sudo mkfs.ext4 /dev/mapper/Laboratoire-Current
|
||||
|
||||
sudo mount /dev/mapper/Production-Current /mnt/prod/current
|
||||
sudo mount /dev/mapper/Sauvegarde-Current /mnt/sauv/current
|
||||
sudo mount /dev/mapper/Developpement-x86_64 /mnt/dev/x86_64
|
||||
sudo mount /dev/mapper/Developpement-ARM /mnt/dev/arm
|
||||
sudo mount /dev/mapper/Laboratoire-Current /mnt/labo/current
|
||||
```
|
||||
|
||||
### Partie 2
|
||||
|
||||
```
|
||||
sudo mdadm --manage /dev/md123 --fail /dev/sdh
|
||||
|
||||
sudo mdadm --manage /dev/md123 --remove /dev/sdh
|
||||
|
||||
sudo sgdisk -Z /dev/sdi
|
||||
sudo sgdisk -n1:0:0 -t1:fd00 /dev/sdi
|
||||
|
||||
sudo mdadm --manage /dev/md123 --add /dev/sdq
|
||||
```
|
||||
|
||||
### Partie 3
|
||||
|
||||
```
|
||||
sudo mdadm --add /dev/md126 /dev/sdi
|
||||
|
||||
sudo mdadm --grow /dev/md126 --raid-devices=3
|
||||
|
||||
sudo pvresize /dev/md126
|
||||
|
||||
sudo lvextend -l +100%FREE /dev/mapper/Laboratoire-Current
|
||||
|
||||
sudo resize2fs /dev/mapper/Laboratoire-Current
|
||||
```
|
||||
|
||||
### Partie 4
|
||||
|
||||
```
|
||||
sudo mdadm --add /dev/md123 /dev/sdj
|
||||
```
|
||||
@@ -0,0 +1,353 @@
|
||||
Emmanuel-Joyce Ntsia, Gauvain BOICHÉ, Joris Stavroulakis, Léo Jarry,
|
||||
|
||||
# Virtualisation, Containérisation d'OS, Stockage évolutif & résilient
|
||||
|
||||
Pour démarrer l'évaluation on est parti sur une VM avec ces spécifications :
|
||||
|
||||
- Debian 13.1.0-amd64-netinst
|
||||
- 8 Coeurs Logiques
|
||||
- 8 Go RAM
|
||||
- 20 Go d'espace disque (disque 1, le disque système)
|
||||
|
||||
À partir de là on a commencé par installer toutes les dépendances nécessaires
|
||||
|
||||
## 1.1 Installation des paquets pour libvirt / KVM / Qemu
|
||||
|
||||
On commence par installer et configurer tout ce qui sera nécessaire pour la virtualisation :
|
||||
|
||||
sudo apt install bridge-utils cpu-checker libvirt-clients libvirt-daemon-system virtinst qemu-kvm virt-manager -y
|
||||
|
||||
sudo usermod -aG kvm $USER
|
||||
sudo usermod -aG libvirt $USER
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/9c/9cd72a4f06ae45f9c4064b24287379f1a889a5293c39461a" data-crypto-key="cryptpad:xmYOKRlSW+p/hjbv0OGLGWxFjPQtrrmtlnHODPk4XBU="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/93/93f9e103690570d6f3d02210cf83edfcb736339a4d4b9c8d" data-crypto-key="cryptpad:psh9MPwR6SQLSQ3Al329EqQKAFHne0aCloKUD93F1eY="></media-tag>
|
||||
|
||||
## 1.2 Installation des paquets pour la containérisation LXC
|
||||
|
||||
Ensuite on installe tout ce qui sera nécessaire pour la conteneurisation :
|
||||
|
||||
sudo apt install lxc lxctl lxc-templates -y
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/5d/5df3047ef1e1af7c2d1db5b63a13ef05bd7c64cc12c99643" data-crypto-key="cryptpad:ksu/YqjuaAa+VzX9v4b204UzvB8AE+YwdYt9B0mrZ4Q="></media-tag>
|
||||
|
||||
## 1.3 Installation du paquet mdadm pour le RAID
|
||||
|
||||
Enfin on installe **mdadm** pour créer et gérer le RAID
|
||||
|
||||
sudo apt install mdadm -y
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/14/14b0ac45bb59e5e3129b86c25aca2258f3c4a0c83a9d36e5" data-crypto-key="cryptpad:cBJFqiRkkTMpkGLHfnntFkWHM9oM9w0uskFurA9d6Ec="></media-tag>
|
||||
|
||||
## 2.1 Ajout des 4 disques pour le RAID5 (3 disques actifs + un hotspare)
|
||||
|
||||
On a choisi un RAID de type 5 pour la tolérance de panne **et** les performances, on est parti sur des disques de 4Go, ce qui s'avèrera (voir la suite) ne pas être assez, donc il faudra agrandir par la suite :
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/2b/2b3f74a732f1f3ddcd8b05b3ada85b08f4c916d71ae8ddc9" data-crypto-key="cryptpad:C8bfHXiX9/Tunv2+olxN5HDBlXvqCmzprPxIHthhITs="></media-tag>
|
||||
|
||||
## 2.2 Mise en place du RAID5
|
||||
|
||||
D'abord on repère les disques qu'on va mettre dans le RAID :
|
||||
|
||||
sudo lsblk
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/5c/5c0a911256e37aa48cf61d833c051d450615863e03b97fca" data-crypto-key="cryptpad:d/EpZVHUm8sL/5bxPqFu+cuVqYaknQC+tqYk1fuZhPc="></media-tag>
|
||||
|
||||
Ensuite on créé ce dernier en précisant le type et le nom :
|
||||
|
||||
sudo mdadm --create /dev/md1 --level=5 --raid-devices=3 /dev/sdb /dev/sdc /dev/sdd
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/63/630186676c496c657c4e0f9de90104a721dff9d91f87ad91" data-crypto-key="cryptpad:DxFDrJxMlMk4mmRIokEmtRtFdV1BqJMvv71fFt3DKsU="></media-tag>
|
||||
|
||||
On ajoute le disque ***sde*** en tant que hotspare pour notre RAID :
|
||||
|
||||
sudo mdadm --add /dev/md1 /dev/sde
|
||||
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/9c/9c4835e947ef82ee5c21e28a94f9110f4190ab178320a7a5" data-crypto-key="cryptpad:au7wZjM/DC0U0MPy6t97+s+h4uTc9pE3MztTZZj4aLg="></media-tag>
|
||||
|
||||
On vérifie que tout est en place :
|
||||
|
||||
sudo mdadm --detail /dev/md1
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/c3/c36057cabdd3b5fbe899870d1d1756b40e5d21b13e68984d" data-crypto-key="cryptpad:qBgoCP//ADl6jEjDh1u4DGXfJhzxOwUWJ2nrK54r5UM="></media-tag>
|
||||
|
||||
On voit que le RAID5 avec *hotspare* est bien en place, on peut passer à la partie LVM
|
||||
|
||||
## 2.3 Mise en place du LVM
|
||||
|
||||
Ici on commence par déclarer le pv qu'on va utiliser, notre RAID :
|
||||
|
||||
sudo pvcreate /dev/md1
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/69/69e4a894c430e812a2dc36cfcef6a02c3c018f6703d9364a" data-crypto-key="cryptpad:uf18KubsvRYQMW/Hcnejf2mVew2wtXq4sOqcLMvH99I="></media-tag>
|
||||
|
||||
Ensuite on créé le volume group nommé ***eval*** et les deux logical volume ***vms*** et ***conteneurs*** :
|
||||
|
||||
sudo vgcreate eval /dev/md1
|
||||
|
||||
sudo lvcreate -l 50%FREE -n vms eval
|
||||
|
||||
sudo lvcreate -l 100%FREE -n conteneurs eval
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/0d/0d850ebbbfe9c351926e1f977d4dc7d0f15a5841b71fc709" data-crypto-key="cryptpad:SZn+5Ho1g2eLKOTIlUZkZ8reASiM1OhuYP0W4caPXfU="></media-tag>
|
||||
|
||||
Ensuite on formate les volumes pour mettre le système de fichiers *ext4* :
|
||||
|
||||
sudo mkfs.ext4 /dev/mapper/eval-vms
|
||||
|
||||
sudo mkfs.ext4 /dev/mapper/eval-conteneurs
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/39/3938c6e3c15112a89caa8804381cf3e7ab3177b671da302d" data-crypto-key="cryptpad:pY2ZgfH5v9Yz0mSzVsklX/kN04T4SqNyogZpGsHsmzM="></media-tag>
|
||||
|
||||
Puis on ajoute les labels :
|
||||
|
||||
sudo tune2fs -L vmsfs /dev/mapper/eval-vms
|
||||
|
||||
sudo tune2fs -L conteneursfs /dev/mapper/eval-conteneurs
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/14/14ee8b862cf1fa9775fe8e1269709c0f55238ef4be39e758" data-crypto-key="cryptpad:n8PAhJ64GMaoIk1ypNf7fUvWrpTlQKnZfZ0hjqnCCvQ="></media-tag>
|
||||
|
||||
On vérifie qu'ils sont bien mis :
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/f0/f02fc6dad2118f18802e4c95c9eea665f61d307e36469e40" data-crypto-key="cryptpad:C8stCyVXhksub85vBKoGvBXC1Re7GFbk9En2kvRKgjw="></media-tag>
|
||||
|
||||
## 2.4 Mise en place du montage au démarrage
|
||||
|
||||
On prépare les dossiers pour le montage de nos volumes :
|
||||
|
||||
sudo mkdir -p /mnt/vms /mnt/conteneurs
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/b5/b51ea5967a9435301f7202d81c9f0d5aea45b09574c07ef2" data-crypto-key="cryptpad:59ETfguz+UHjN6sZfe0HTl3FlMZ1JEGnQ+iY+ZeLDSA="></media-tag>
|
||||
|
||||
On modifie le fstab pour que le montage se fasse au démarrage du système :
|
||||
|
||||
sudo nano /etc/fstab
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/dc/dcbdf8ad45ee0ea4758b08bd2c429123b893a26d8dd740fa" data-crypto-key="cryptpad:FJPrymuTZ1TCMYl+TD2+3898XsErQpFCZ4LfaE37EnM="></media-tag>
|
||||
|
||||
### 2.5 Montage des volumes
|
||||
|
||||
Ici on le monte directement (plutôt que de devoir redémarrer), pour ça on oublie pas de relancer le service :
|
||||
|
||||
sudo systemctl daemon-reload
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/ef/efc9365824f907bd8e6f8b19ee289a90d8ef7359d50babd6" data-crypto-key="cryptpad:9/v3TUck5tVTV4vMVTudJfcZ2DfSnG5N4YegOljWMmo="></media-tag>
|
||||
|
||||
On monte les volumes sur les dossiers précédemment créés :
|
||||
|
||||
sudo mount -t ext4 /dev/mapper/eval-vms /mnt/vms
|
||||
sudo mount -t ext4 /dev/mapper/eval-conteneurs /mnt/conteneurs
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/38/3851f0cfe90736849fb40b373e241c21420ee73ecba8f6ea" data-crypto-key="cryptpad:4KfVWIMmBobeulibZiozjFaz7+oNOq93e5u0w3bEM9o="></media-tag>
|
||||
|
||||
## 3.1 Installation des conteneurs LXC
|
||||
|
||||
Maintenant que tout est préparé on peut commencer à faire les conteneurs et les vms, on a décidé de commencer par les conteneurs
|
||||
|
||||
### 3.1.1 Le conteneur Debian
|
||||
|
||||
On installe le conteneur Debian :
|
||||
|
||||
sudo lxc-create -n debianLXC -t download -- -d debian -r bullseye
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/40/40d8ecb2850732611e0ef0f472b6ff6340cc4f479f428362" data-crypto-key="cryptpad:uq8h3EP/n0BHebZbxfA16ZsqGqRluCHuNeQcZ5FtzIE="></media-tag>
|
||||
|
||||
On crée le dossier qui servira de volume rattaché à ce conteneur :
|
||||
|
||||
sudo mkdir /mnt/conteneurs/debianlxc
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/ef/efc44707ee7eabbdbfe23563e57707399f7d5341e339c44c" data-crypto-key="cryptpad:yo1dE2qOV4J+sSacIYPqexRRDLgCSTMPGds5vuxdjQw="></media-tag>
|
||||
|
||||
On va modifier le fichier de config pour le rattacher justement :
|
||||
|
||||
sudo nano /var/lib/lxc/debianLXC/config
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/b5/b5b52a75f1658a40b32e6027d97fff36419f53ce1f6a82db" data-crypto-key="cryptpad:P/ciZg6I12Bi7P4c0W8MLsK2zqJnuhz4DdDoUeXjHOs="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/4d/4d535bd8e670fd9ee89d1a1c5d2f34cb091cb16a475ccda0" data-crypto-key="cryptpad:7t7MXfJyVn7bTWFxCr797j5yyg57ESbQnWZyjLJyWE8="></media-tag>
|
||||
|
||||
### 3.1.2 Le conteneur Ubuntu
|
||||
|
||||
On installe le conteneur Ubuntu :
|
||||
|
||||
sudo lxc-create -n ubuntuLXC -t download -- -d ubuntu -r noble
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/fe/febd60a7eac6310802935ad72199d62113fe1b02e822f619" data-crypto-key="cryptpad:neiBuwyda8neNhYWeHDIftJDnKcr2QMgYhT34wyPMjM="></media-tag>
|
||||
|
||||
On créé le dossier qui servira de volume rattaché à ce conteneur :
|
||||
|
||||
sudo mkdir /mnt/conteneurs/ubuntulxc
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/be/bec36cbc8e80e4e7fa72f74f74bf4782a2db9b7d01746d09" data-crypto-key="cryptpad:dH4/fylYvmuUVr90ev2kwq8QWI11/PAwFPK2zTNGTPA="></media-tag>
|
||||
|
||||
On va modifier le fichier de config pour le rattacher justement :
|
||||
|
||||
sudo nano /var/lib/lxc/ubuntuLXC/config
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/d1/d15272f1b623442f67af27a41e2418373fc551c4f9fe7e18" data-crypto-key="cryptpad:LW9VN4rJDGUyC1NDO7eTamVTJTh/cKLjgE3y1J3agDc="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/62/6281a6155012d3ea8d3efaaf03d801bdaeb8968c6656b703" data-crypto-key="cryptpad:Nzo01YrudSAFpGqlj6Q/CqFEzd4yGbQuv7oadGHXkVc="></media-tag>
|
||||
|
||||
### 3.1.3 Le conteneur Fedora
|
||||
|
||||
On installe le conteneur Fedora :
|
||||
|
||||
sudo lxc-create -n fedoraLXC -t download -- d fedora -r 42
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/de/dec127fcb5f2fef990c9dae7e648a23341d9dcfeebc51dd3" data-crypto-key="cryptpad:Gz4m25ZGx2Ut0l7jy73MX8l4+vsaRVknk3ykfP4nPZE="></media-tag>
|
||||
|
||||
On crée le dossier qui servira de volume rattaché à ce conteneur :
|
||||
|
||||
sudo mkdir /mnt/conteneurs/fedoralxc
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/8e/8ed4e36f2d2567341392aaf844eb7d68125a7214585a539b" data-crypto-key="cryptpad:3oa/1rk1MwadnBkCTD0FsDEtgosOEZAi9iOtVQW07+s="></media-tag>
|
||||
|
||||
On va modifier le fichier de config pour le rattacher justement :
|
||||
|
||||
sudo nano /var/lib/lxc/fedoraLXC/config
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/4a/4a7fda7e748fcfe8065a00545421ef44ad51fd08a571778f" data-crypto-key="cryptpad:xWNDUAad/ZnYdWo5KnJN6Bw7FoG6w0Tz2CUDhMhwJRk="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/5f/5fe86ceb86dc605d6e4534ab71be0f9df6be2a4db77a7a9d" data-crypto-key="cryptpad:hiAh5/oNuJRDlHVAq3w/63iKY1BqYAH+dSvdB1sr1k0="></media-tag>
|
||||
|
||||
## 3.2 Installation des VMS
|
||||
|
||||
Maintenant que les conteneurs sont installés et configurés on passe aux VMs
|
||||
|
||||
### 3.2.1 La VM Debian
|
||||
|
||||
On commence à créer un dossier dans lequel on rangera le disque de la VM (ainsi que son iso au passage) :
|
||||
|
||||
sudo mkdir debian
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/31/31f9dc7e9c0297eed0228692138981218e5c47e4b5bd37ed" data-crypto-key="cryptpad:vTERowwrpitSK7f2DXN5gX/XewVlDrKeZ9hp91Indnw="></media-tag>
|
||||
|
||||
On télécharge le fichier iso :
|
||||
|
||||
sudo wget https://cdimage.debian.org/mirror/cdimage/archive/11.11.0/amd64/iso-cd/debian-11.11.0-amd64-netinst.iso
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/73/7301bcd725e717fa22fe7ed8eac1a1e642d1a6e5b6218e61" data-crypto-key="cryptpad:R2i36nJXlx5IGNyIwZpWG/QKQucsUBATu7BuJIU+F2I="></media-tag>
|
||||
|
||||
On crée le disque (qui s'avèrera trop petit, voir la suite) :
|
||||
|
||||
sudo qemu-img create -f qcow2 debian.qcow2 2G
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/d9/d9baa18e4dc17d4d1a12be63b7c00787fca9640e7be2f52a" data-crypto-key="cryptpad:JsxrbrbfwH0bfenUenvk3KZDswQjcqk5vvPIpmJRUqU="></media-tag>
|
||||
|
||||
On lance l'installation avec ***virt-install*** :
|
||||
|
||||
sudo virt-install \
|
||||
--name debianVM \
|
||||
--os-variant=debian11 \
|
||||
--ram 2048 \
|
||||
--vcpus 2 \
|
||||
--location /mnt/vms/debian/debian-11.11.0-amd64-netinst.iso \
|
||||
--disk debian.qcow2 \
|
||||
--graphics none \
|
||||
--console pty,target_type=serial \
|
||||
--extra-args='console=ttyS0,115200n8 serial'
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/41/4186b87fe73e5996c19a4e44630631c4eefd1d791cc429ef" data-crypto-key="cryptpad:n85CcKoSA02D2icTzUrCeavaAMJ1RXPbigI09mD16U0="></media-tag>
|
||||
|
||||
On a manqué de place pour l'installation, donc on rajoute deux disques de 4Go au raid et au LVM pour recommencer :
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/ba/ba799c916d57a0c60d87413e3d40f4bb045c7395b0c85e5d" data-crypto-key="cryptpad:dIgiQfo8mDCeDWiG0+kl+jFliFqqD3Mg2u2rdAaer2w="></media-tag>
|
||||
|
||||
|
||||
On ajoute nos deux disques au RAID (Après le reboot le md1 a été renommé par le système en md127) :
|
||||
|
||||
sudo mdadm --add /dev/md127 /dev/sdf /dev/sdg
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/78/781ba4595e2eaf843e67e9b011044fed1e56f66e13960f98" data-crypto-key="cryptpad:FnScioCuM2cPk34phyf8kg17xi/LDtZMhR4PZJCdaOM="></media-tag>
|
||||
|
||||
On oublie pas cette commande, sinon nos disques seront juste en spare :
|
||||
|
||||
sudo mdadm --grow /dev/md127 --raid-devices=5
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/d9/d9349cdaaed4b7f69a709fbf2f37419c9c35159d8855b383" data-crypto-key="cryptpad:9VNUEYRjDnIpv0aqsl6e++BsNDMpGI/QVYxeKvdcV1s="></media-tag>
|
||||
|
||||
*Et ensuite il faut bien sûr étendre le LVM (**après avoir attendu que le reshape du RAID ait fini**)*
|
||||
|
||||
On commence par resize le pv :
|
||||
|
||||
sudo pvresize /dev/md127
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/de/de6710544f95f3ed6863d47d7a22c586a6f6f154f919aaee" data-crypto-key="cryptpad:2YOBmZhXlD1DFv1PGsV1MNbbLAxv5jmJPkquMLP0SMA="></media-tag>
|
||||
|
||||
On étend ensuite notre volume dédié au VM pour lui accorde 100% du nouvel espace libre :
|
||||
|
||||
sudo lvextend -l +100%FREE --resizefs /dev/mapper/eval-vms
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/af/af1454927752414639c8583694ccabfff5e151de5ec044e1" data-crypto-key="cryptpad:gyVGn4TWL5w7Tzs0503zfbejDT+sbS1/XhBHBsfBw5E="></media-tag>
|
||||
|
||||
Ensuite on undefine le debianVM créé précédemment pour refaire l'installation à zéro :
|
||||
|
||||
*(Cette étape est nécessaire pour pouvoir utiliser le disque avec le même nom qu'avant, sinon virt croit que le disque est déjà utilisé par une autre VM)*
|
||||
|
||||
sudo virsh undefine debianVM
|
||||
|
||||
Puis on supprime le disque :
|
||||
|
||||
sudo rm debian.qcow2
|
||||
|
||||
Et on le recrée avec une plus grande taille :
|
||||
|
||||
sudo qemu-img create -f qcow2 debian.qcow2 5G
|
||||
|
||||
Et on refait l'installation avec la commande virt-install utilisée au-dessus, voici le résultat :
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/1e/1e4b5cf1dedc44937084cb725f9f7add1b2a6b7551a9b590" data-crypto-key="cryptpad:imkCtErKM8sLwX2TS/GrD2vILyp9ugnvvYEuzjxHpk8="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/fc/fca279a55474fe6d4e68b2eb683cad42b412db3784617b5d" data-crypto-key="cryptpad:RhvA2BEHKPxsCjYv/qfqIs5B4YkPGf1f/HnUzzvGqkI="></media-tag>
|
||||
|
||||
### 3.2.2 La VM Ubuntu
|
||||
|
||||
On commence à créer un dossier dans lequel on rangera le disque de la VM (ainsi que son iso au passage) :
|
||||
|
||||
sudo mkdir /mnt/vms/ubuntu
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/e4/e4d92d09be3a521db140229e5beb0cfea8abf2a0c0c4d412" data-crypto-key="cryptpad:rTGMAPCavmig2pKE/p3n5hyquc1BdwMXifZj75RlXdc="></media-tag>
|
||||
|
||||
On télécharge le fichier iso :
|
||||
|
||||
sudo wget https://cdimage.ubuntu.com/ubuntu-legacy-server/releases/20.04/release/ubuntu-20.04.1-legacy-server-amd64.iso
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/f4/f450926458dac5270e72c6fa79bb6d22803215ffe506cdeb" data-crypto-key="cryptpad:qFDOYX7aL/CAf65jW1bXpD92WIoVbB38KGJ07k9C/Zs="></media-tag>
|
||||
|
||||
On créé notre disque de 6Go :
|
||||
|
||||
sudo qemu-img create -f qcow2 ubuntu.qcow2 6G
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/20/203f8565203dcc2d49323c885d4fcc015b9e514eaa291ca4" data-crypto-key="cryptpad:CsydruhHoV3VKjfGjEjGc88HgJBV5JZHBf3V277dsWU="></media-tag>
|
||||
|
||||
On lance l'installation :
|
||||
|
||||
sudo virt-install \
|
||||
--name ubuntuVM \
|
||||
--os-variant=ubuntu20.04 \
|
||||
--ram 4096 \
|
||||
--vcpus 4 \
|
||||
--location /mnt/vms/ubuntu/ubuntu-20.04.1-legacy-server-amd64.iso \
|
||||
--disk ubuntu.qcow2 \
|
||||
--graphics none \
|
||||
--console pty,target_type=serial \
|
||||
--extra-args='console=ttyS0,115200n8 serial'
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/f0/f0148c74a643715c2b3290ba19a2dfab50226c0296532792" data-crypto-key="cryptpad:b6iZnvO4SW/bT5OcVw4u04BMMBHB/M26VSHtciZMOVw="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/d9/d9ea5dd8171e6e315f39892595286a4154acffbd45255480" data-crypto-key="cryptpad:ryP22LbOuAtRfQakA+miZI0MGeEHowhC6LoRFcoAaeM="></media-tag>
|
||||
|
||||
L'installation du ubuntu va jusqu'au bout, mais après on a un écran "noir" comme mentionné par le formateur, donc impossible d'aller plus loin :
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/b0/b055a09b6a3fa8a7d0eda8d8d9e526579e4538a4828ece0b" data-crypto-key="cryptpad:C27BL+GZSyKOWENfzuW+entS+91eLKtTHhHFMMoLM1I="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/5c/5ccaa2ae0762544b9b5be2d107f942f8673eafd940860dc2" data-crypto-key="cryptpad:z/Gt2mqiT505XOJ5iOl2KdDHhtCQT+a0SKBA9hRjOFY="></media-tag>
|
||||
|
||||
Mais on a réussi à y accéder grâce à SSH et au final tout fonctionne :
|
||||
|
||||
sudo nmap 192.168.122.0/24 -sP # pour trouver l'ip de la VM ubuntu
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/85/8562e2daf46bc7a62282c0a3c48820d76b72846b06a19328" data-crypto-key="cryptpad:K1z83sJcK3K1MyDf6dSw3EahvlVOzSoNwqTknFH9uak="></media-tag>
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,79 @@
|
||||
# CEPH : Architecture générale
|
||||
|
||||
## Programme
|
||||
|
||||
- CEPH
|
||||
- VLAN
|
||||
- Trunking
|
||||
- Routage Inter-VLAN
|
||||
|
||||
## Objectifs
|
||||
|
||||
Nécessité du CEPH, son architecture, le rôle de CRUSH, des Pools, des PG. Distinguer les 3 services de stockage possibles. Connaître les bonnes pratiques.
|
||||
|
||||
### Pourquoi CEPH
|
||||
|
||||
Il peut continuer le stockage en cas de panne de disque/noeud/switch. Plus évolué que le RAID, il trouvera d'autres stockages en :
|
||||
- scalant en ajoutant des machines
|
||||
- ne se concentrant pas sur un SPOF
|
||||
- utilisant du stockage bloc, fichier, ou l'objet
|
||||
- équilibrant le stockage avec ce qu'il a à disposition
|
||||
|
||||
CEPH repose sur une couche logicielle nommée RADOS, composée de 3 daemons :
|
||||
- MON (ceph-mon) : Moniteur, gère la carte du cluster (qui est en vie, où sont les données, quelles règles de placement)
|
||||
- OSD (ceph-osd) : Stocke les données
|
||||
- MGR (ceph-mgr) : Manager, surveille, fournit de la métrique, met de l'orchestration supplémentaire
|
||||
|
||||
Il existe des démons supplémentaires :
|
||||
- MDS (ceph-mds) : Uniquement si on stocke en mode système de fichiers, avec CephFS
|
||||
- RGW (radosgw) : Passerelle (Gateway) pour stockage S3
|
||||
- RBD (radosblocks) : Stockage en mode blocs
|
||||
|
||||
### Où se trouvent les données
|
||||
|
||||
Ceph utilise l'algorithme CRUSH. Il décide où mettre les données en fonction d'une carte décrivant une topologie.
|
||||
- Le placement est déterministe : tout le monde obtient le même résultat chacun de son côté.
|
||||
- Pas de BDD.
|
||||
|
||||
### Nomenclature
|
||||
|
||||
- POOL : zone virtuelle
|
||||
- PG : *Placement Group*, Groupes de placement
|
||||
- OSD : Disque de stockage
|
||||
|
||||
Un Pool est découpé en PGs avec chacun ses OSDs (vous m'suivez ?)
|
||||
|
||||
## Mise en place
|
||||
|
||||
Commande centrale :
|
||||
`cephadm`
|
||||
|
||||
Générer le premier noaud :
|
||||
`cephadm bootstrap --mon-node Noeud1`
|
||||
|
||||
Cela installe :
|
||||
- 1 MON
|
||||
- 1 MGR
|
||||
- 1 shell CEPH
|
||||
|
||||
Vérifier la santé :
|
||||
`ceph status`
|
||||
|
||||
Vérifier la topologie :
|
||||
`ceph osd tree`
|
||||
|
||||
Vérifier l'espace :
|
||||
`ceph df`
|
||||
|
||||
Activer la Web UI (pour un cluster déjà mis en service) :
|
||||
`ceph mgr module enable dashboard`
|
||||
|
||||
## Exercice 1
|
||||
|
||||
1. Quel protocole utilisent les MON et MGR pour communiquer entre eux ?
|
||||
2. Quelle(s) sont le(s) bonne(s) pratique(s) auxquelles cet exercice ne se plie pas ?
|
||||
3. À quoi sert le SSH dans une infrastructure Ceph ?
|
||||
4. La WebUI semble t-elle protéger les communications via un chiffrement SSL/TLS ?
|
||||
5. Quelle est la différence entre le Backfill et le Recovery ?
|
||||
|
||||
## Exercice 2
|
||||
Binary file not shown.
@@ -0,0 +1,274 @@
|
||||
#
|
||||
|
||||
## Exercice 1
|
||||
|
||||
```
|
||||
SW1#
|
||||
SW1#configure terminal
|
||||
SW1(config)#vlan 10
|
||||
SW1(config-vlan)#name VLAN0010
|
||||
SW1(config-vlan)#interface Fa0/1
|
||||
SW1(config-if)#switchport mode access
|
||||
SW1(config-if)#switchport access vlan 10
|
||||
SW1(config-if)#no shutdown
|
||||
SW1(config-if)#end
|
||||
SW1#write memory
|
||||
```
|
||||
|
||||
```
|
||||
SW1#
|
||||
SW1#configure terminal
|
||||
SW1(config)#interface Fa0/3
|
||||
SW1(config-if)#switchport mode trunk
|
||||
SW1(config-if)#switchport trunk native vlan 10
|
||||
SW1(config-if)#switchport nonegotiate
|
||||
SW1(config-if)#end
|
||||
SW1#write memory
|
||||
```
|
||||
|
||||
```
|
||||
SW1#
|
||||
SW1#configure terminal
|
||||
SW1(config)#interface Fa0/3
|
||||
SW1(config-if)#switchport mode trunk
|
||||
SW1(config-if)#switchport trunk native vlan 1
|
||||
SW1(config-if)#switchport trunk allowed vlan 1,10,20
|
||||
SW1(config-if)#end
|
||||
SW1#write memory
|
||||
```
|
||||
|
||||
## Cours
|
||||
|
||||
### Port-Channelling
|
||||
|
||||
Agrégation de liens entre plusieurs switchs : augmenter la bande passante à l'infini.
|
||||
|
||||
- Câble virtuel : nommé LAG (*Link Agregation Group*)
|
||||
Une fois créé, le LAG doit être administré comme une interface physique.
|
||||
|
||||
#### Les standards
|
||||
|
||||
- Le Port-Channel : standard ouvert de l'IEEE
|
||||
- Etherchannel : protocole propriétaire de Cisco
|
||||
|
||||
De 2 à 8 interfaces physiques max par LAG. Uniquement de même type et de débit. Avec un seul destinataire.
|
||||
Maximum 6 LAGs par Switch. (donc 6 LAGs x 8 ports, ça fait un switch de 48 ports).
|
||||
|
||||
Implémentations :
|
||||
- Statiques : l'existence du LAG est décidée par l'admin
|
||||
- Dynamiques : les appareils négocient entre eux l'établissement d'un LAG si besoin, via un protocole.
|
||||
|
||||
Les protocoles d'auto-établissement de LAG :
|
||||
- PAgP : Propriétaire Cisco
|
||||
- LACP : Standard IEEE 803.2ad
|
||||
|
||||
Il suffit pour activer de dire `desirable` en console :
|
||||
- Desirable : *J'initie la négociation du LAG*
|
||||
- Auto : *J'attends qu'on vienne négocier*
|
||||
|
||||
## Exercice 3
|
||||
|
||||
### Liaison entre SW1 et SW2
|
||||
|
||||
```
|
||||
Switch1>enable
|
||||
Switch1#configure terminal
|
||||
Switch1(config)#interface range Fa0/1 - 3
|
||||
Switch1(config-if-range)#channel-group 1 mode active
|
||||
Switch1(config-if-range)#exit
|
||||
Switch1(config)#interface port-channel 1
|
||||
Switch1(config-if)#description LACP-SW1-SW2
|
||||
Switch1(config-if)#switchport mode trunk
|
||||
Switch1(config-if)#exit
|
||||
```
|
||||
|
||||
```
|
||||
Switch2>enable
|
||||
Switch2#configure terminal
|
||||
Switch2(config)#interface range Fa0/4 - 6
|
||||
Switch2(config-if-range)#channel-group 1 mode active
|
||||
Switch2(config-if-range)#exit
|
||||
Switch2(config)#interface port-channel 1
|
||||
Switch2(config-if)#description LACP-SW1-SW2
|
||||
Switch2(config-if)#switchport mode trunk
|
||||
Switch2(config-if)#exit
|
||||
```
|
||||
|
||||
### Liaison entre SW2 et SW3
|
||||
|
||||
```
|
||||
Switch2>enable
|
||||
Switch2#configure terminal
|
||||
Switch2(config)#interface range Fa0/1 - 3
|
||||
Switch2(config-if-range)#channel-group 2 mode active
|
||||
Switch2(config-if-range)#exit
|
||||
Switch2(config)#interface port-channel 2
|
||||
Switch2(config-if)#description LACP-SW2-SW3
|
||||
Switch2(config-if)#switchport mode trunk
|
||||
Switch2(config-if)#exit
|
||||
```
|
||||
|
||||
```
|
||||
Switch3>enable
|
||||
Switch3#configure terminal
|
||||
Switch3(config)#interface range Fa0/4 - 6
|
||||
Switch3(config-if-range)#channel-group 2 mode active
|
||||
Switch3(config-if-range)#exit
|
||||
Switch3(config)#interface port-channel 2
|
||||
Switch3(config-if)#description LACP-SW2-SW3
|
||||
Switch3(config-if)#switchport mode trunk
|
||||
Switch3(config-if)#exit
|
||||
```
|
||||
|
||||
### Liaison entre SW3 et SW1
|
||||
|
||||
```
|
||||
Switch3>enable
|
||||
Switch3#configure terminal
|
||||
Switch3(config)#interface range Fa0/1 - 3
|
||||
Switch3(config-if-range)#channel-group 3 mode active
|
||||
Switch3(config-if-range)#exit
|
||||
Switch3(config)#interface port-channel 3
|
||||
Switch3(config-if)#description LACP-SW3-SW1
|
||||
Switch3(config-if)#switchport mode trunk
|
||||
Switch3(config-if)#exit
|
||||
```
|
||||
|
||||
```
|
||||
Switch1>enable
|
||||
Switch1#configure terminal
|
||||
Switch1(config)#interface range Fa0/4 - 6
|
||||
Switch1(config-if-range)#channel-group 3 mode active
|
||||
Switch1(config-if-range)#exit
|
||||
Switch1(config)#interface port-channel 3
|
||||
Switch1(config-if)#description LACP-SW3-SW1
|
||||
Switch1(config-if)#switchport mode trunk
|
||||
Switch1(config-if)#exit
|
||||
```
|
||||
|
||||
## Exercice 4
|
||||
|
||||
**TP : Mise en œuvre du protocole HSRP dans un réseau redondant**
|
||||
|
||||
*Objectif*
|
||||
Mettre en place une **redondance de passerelle** à l’aide du protocole **HSRP (Hot Standby Router Protocol)**, afin d’assurer la **continuité de service** en cas de défaillance d’un routeur.
|
||||
|
||||
---
|
||||
|
||||
**Réseau partagé** : 192.168.1.0/24
|
||||
**Passerelle virtuelle HSRP** : 192.168.1.1
|
||||
|
||||
### 1 & 2
|
||||
|
||||
```
|
||||
Router1>enable
|
||||
Router1#configure terminal
|
||||
Router1(config)#interface Gig0/0/0
|
||||
Router1(config-if)#ip address 192.168.1.200 255.255.255.0
|
||||
Router1(config-if)#standby 1 ip 192.168.1.1
|
||||
Router1(config-if)#standby 1 priority 150
|
||||
Router1(config-if)#standby 1 preempt
|
||||
Router1(config-if)#no shutdown
|
||||
```
|
||||
|
||||
```
|
||||
Router2>enable
|
||||
Router2#configure terminal
|
||||
Router2(config)#interface Gig0/0/0
|
||||
Router2(config-if)#ip address 192.168.1.201 255.255.255.0
|
||||
Router2(config-if)#standby 1 ip 192.168.1.1
|
||||
Router2(config-if)#standby 1 priority 100
|
||||
Router2(config-if)#standby 1 preempt
|
||||
Router2(config-if)#no shutdown
|
||||
```
|
||||
|
||||
### 3
|
||||
|
||||
```
|
||||
Router1#show standby brief
|
||||
P indicates configured to preempt.
|
||||
|
|
||||
Interface Grp Pri P State Active Standby Virtual IP
|
||||
Gig0/0/0 1 150 P Active local 192.168.1.201 192.168.1.1
|
||||
```
|
||||
|
||||
```
|
||||
Router2#show standby brief
|
||||
P indicates configured to preempt.
|
||||
|
|
||||
Interface Grp Pri P State Active Standby Virtual IP
|
||||
Gig0/0/0 1 100 P Standby 192.168.1.200 local 192.168.1.1
|
||||
```
|
||||
|
||||
### 4
|
||||
|
||||
### 5
|
||||
|
||||
1. HSRP est fermé par Cisco, VRRP est ouvert.
|
||||
2.
|
||||
3. L'adresse IP la plus haute remporterait le rôle Actif.
|
||||
4. HSRP est une passerelle virtuelle avec du matériel en série pour éviter les SPOF. L'agrégation de liens est autre chose
|
||||
|
||||
## Exercice 5
|
||||
|
||||
### Liaison entre SW1 et SW2
|
||||
|
||||
```
|
||||
SW1>enable
|
||||
SW1#configure terminal
|
||||
SW1(config)#interface range Fa0/3 - 4
|
||||
SW1(config-if-range)#channel-group 1 mode active
|
||||
SW1(config-if-range)#exit
|
||||
SW1(config)#interface port-channel 1
|
||||
SW1(config-if)#description LACP-SW1-SW2
|
||||
SW1(config-if)#switchport mode trunk
|
||||
SW1(config-if)#exit
|
||||
```
|
||||
|
||||
```
|
||||
SW2>enable
|
||||
SW2#configure terminal
|
||||
SW2(config)#interface range Fa0/3 - 4
|
||||
SW2(config-if-range)#channel-group 1 mode active
|
||||
SW2(config-if-range)#exit
|
||||
SW2(config)#interface port-channel 1
|
||||
SW2(config-if)#description LACP-SW1-SW2
|
||||
SW2(config-if)#switchport mode trunk
|
||||
SW2(config-if)#exit
|
||||
```
|
||||
|
||||
### HSRP entre MLSW1 et MLSW2
|
||||
|
||||
```
|
||||
MLSW1>enable
|
||||
MLSW1#configure terminal
|
||||
MLSW1(config)#interface vlan 10
|
||||
MLSW1(config-if)#ip address 89.76.0.200 255.255.255.0
|
||||
MLSW1(config-if)#standby 1 ip 89.76.0.1
|
||||
MLSW1(config-if)#standby 1 priority 150
|
||||
MLSW1(config-if)#standby 1 preempt
|
||||
MLSW1(config-if)#no shutdown
|
||||
```
|
||||
|
||||
```
|
||||
MLSW2>enable
|
||||
MLSW2#configure terminal
|
||||
MLSW2(config)#interface vlan 10
|
||||
MLSW2(config-if)#ip address 89.76.0.201 255.255.255.0
|
||||
MLSW2(config-if)#standby 1 ip 89.76.0.1
|
||||
MLSW2(config-if)#standby 1 priority 100
|
||||
MLSW2(config-if)#standby 1 preempt
|
||||
MLSW2(config-if)#no shutdown
|
||||
```
|
||||
|
||||
```
|
||||
Router0>enable
|
||||
Router0#configure terminal
|
||||
Router0(config)#ip routing
|
||||
Router0(config)#interface Gig0/0/0
|
||||
Router0(config-if)#ip address 89.76.0.254 255.255.255.0
|
||||
Router0(config-if)#exit
|
||||
Router0(config)#interface Gig0/0/1
|
||||
Router0(config-if)#ip address 89.76.0.254 255.255.255.0
|
||||
Router0(config-if)#exit
|
||||
```
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,52 @@
|
||||
# TP : Mise en œuvre du protocole HSRP dans un réseau redondant
|
||||
|
||||
## 🎯 Objectif
|
||||
Mettre en place une **redondance de passerelle** à l’aide du protocole **HSRP (Hot Standby Router Protocol)**, afin d’assurer la **continuité de service** en cas de défaillance d’un routeur.
|
||||
|
||||
---
|
||||
|
||||
🧱 **Réseau partagé** : 192.168.1.0/24
|
||||
🎯 **Passerelle virtuelle HSRP** : 192.168.1.1
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Étapes du TP
|
||||
|
||||
### 1️⃣ Configuration IP de base
|
||||
Configurer les adresses IP sur les deux routeurs et le PC selon le schéma ci-dessus.
|
||||
Vérifier la connectivité entre les équipements avec la commande `ping`.
|
||||
|
||||
---
|
||||
|
||||
### 2️⃣ Configuration HSRP
|
||||
Configurer HSRP sur les deux routeurs afin de partager une adresse IP virtuelle (192.168.1.1).
|
||||
Le **Router1** doit être prioritaire.
|
||||
|
||||
---
|
||||
|
||||
### 3️⃣ Vérification
|
||||
Utiliser les commandes de vérification pour observer :
|
||||
- Le routeur **actif**
|
||||
- Le routeur **standby**
|
||||
- L’adresse IP virtuelle et l’adresse MAC virtuelle associée
|
||||
|
||||
---
|
||||
|
||||
### 4️⃣ Test de bascule
|
||||
1. Vérifier le rôle initial de chaque routeur.
|
||||
2. Désactiver l’interface G0/0 de Router1 pour simuler une panne.
|
||||
3. Vérifier le basculement automatique du rôle actif vers Router2.
|
||||
4. Réactiver Router1 et observer le retour automatique à l’état initial.
|
||||
|
||||
---
|
||||
|
||||
### 5️⃣ Questions de réflexion
|
||||
|
||||
1. Quelle est la différence entre HSRP et VRRP ?
|
||||
2. Pourquoi configure-t-on la commande `preempt` ?
|
||||
3. Que se passerait-il si les deux routeurs avaient la même priorité ?
|
||||
4. Quelle est la différence entre HSRP et une agrégation de liens (EtherChannel) ?
|
||||
|
||||
---
|
||||
|
||||
**Fin du TP.**
|
||||
Binary file not shown.
@@ -0,0 +1,207 @@
|
||||
# Sécurité en réseau
|
||||
|
||||
## Cours
|
||||
|
||||
### Travail dirigé
|
||||
|
||||
- Sécuriser le port console
|
||||
- Sécuriser le passage au niveau 2 (*enable*)
|
||||
- Sécuriser les ports réseau (*port-security*)
|
||||
- Metter en place le SSH (*sur VLAN dédié*)
|
||||
|
||||
- BDPU Guard (*protéger le port d'un branchement à un autre switch*)
|
||||
- ACLs (*standard et étendue*)
|
||||
- Théorie des pare-feux
|
||||
|
||||
## Exercices
|
||||
|
||||
### Exercice 1
|
||||
|
||||
### Exercice 2
|
||||
|
||||
#### Partie 1
|
||||
|
||||
**Routeur**
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
interface Gig0/1
|
||||
ip address 192.168.0.1 255.255.255.0
|
||||
no shutdown
|
||||
ip default-gateway 192.168.0.1
|
||||
interface Gig0/1
|
||||
ip address 192.168.1.1 255.255.255.0
|
||||
no shutdown
|
||||
ip default-gateway 192.168.1.1
|
||||
no ip domain-lookup
|
||||
enable secret class
|
||||
line console 0
|
||||
password cisco
|
||||
login
|
||||
line vty 0 4
|
||||
password cisco
|
||||
login
|
||||
transport input all
|
||||
service password-encryption
|
||||
banner motd # You shan't access this very device without permission #
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
**Switch**
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
vlan 10
|
||||
name VLAN10
|
||||
exit
|
||||
interface FastEthernet0/5
|
||||
switchport mode access
|
||||
switchport access vlan 99
|
||||
spanning-tree portfast
|
||||
interface FastEthernet0/6
|
||||
switchport mode access
|
||||
switchport access vlan 99
|
||||
spanning-tree portfast
|
||||
interface vlan 10
|
||||
ip address 192.168.1.2 255.255.255.0
|
||||
no shutdown
|
||||
ip default-gateway 192.168.1.1
|
||||
no ip domain-lookup
|
||||
enable secret class
|
||||
line console 0
|
||||
password cisco
|
||||
login
|
||||
line vty 0 4
|
||||
password cisco
|
||||
login
|
||||
transport input all
|
||||
service password-encryption
|
||||
banner motd # You shan't access this very device without permission #
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
### Exercice 3
|
||||
|
||||
#### Liste des commandes utiles
|
||||
|
||||
| Commandes | Descriptions |
|
||||
|---------------------------------------------------------|------------------------------------------------------------------|
|
||||
| conf t | Activate configuration from terminal |
|
||||
| interface *interface* | Go in interface to configure it properly |
|
||||
| ip access-group *ACL_name* **{in\|out}** | Activate and apply ACL to interface |
|
||||
| **ip access-list extended** *ACL_name* | Define ACL and go into conf mode |
|
||||
| **{permit\|deny}** {test conditions} | Defined apply policy for said ACL |
|
||||
| **show access-lists** *ACL_name* | Display all ACLs content |
|
||||
| **show ip interface** *interface-type interface number* | Display IP infos from specific interface, including applied ACLs |
|
||||
|
||||
####
|
||||
|
||||
```
|
||||
router> enable
|
||||
router# configure terminal
|
||||
router(config)# access-list 10 deny 10.1.1.101 0.0.0.0
|
||||
router(config)# access-list 10 permit any
|
||||
router(config)# line vty 0 4
|
||||
router(config-line)# access-class 10 in
|
||||
router(config-line)# exit
|
||||
router(config)# interface GigabitEthernet0/0
|
||||
router(config-if)# ip access-group 10 in
|
||||
router(config)# exit
|
||||
router# write memory
|
||||
```
|
||||
|
||||
### Exercice 4
|
||||
|
||||
#### Tâche 1
|
||||
|
||||
```
|
||||
ping 172.16.1.100
|
||||
traceroute 172.16.1.100
|
||||
```
|
||||
|
||||
```
|
||||
show interfaces Gig0/1
|
||||
conf t
|
||||
ip route 0.0.0.0 0.0.0.0 209.165.201.2
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
#### Tâche 2
|
||||
|
||||
```
|
||||
telnet 172.16.1.100 23
|
||||
telnet 172.16.1.100 80
|
||||
```
|
||||
|
||||
### Exercice 5
|
||||
|
||||
**R1**
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
interface Gig0/0
|
||||
ip address 192.168.0.5 255.255.255.252
|
||||
no shutdown
|
||||
interface Gig0/1
|
||||
ip address 192.168.0.2 255.255.255.252
|
||||
no shutdown
|
||||
router ospf 21
|
||||
network 192.168.0.0 0.0.0.3 area 0
|
||||
router ospf 13
|
||||
network 192.168.0.4 0.0.0.3 area 0
|
||||
no ip domain-lookup
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
**R2**
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
interface Gig0/0
|
||||
ip address 192.168.0.10 255.255.255.252
|
||||
no shutdown
|
||||
interface Gig0/1
|
||||
ip address 192.168.0.6 255.255.255.252
|
||||
no shutdown
|
||||
interface Gig0/2
|
||||
ip address 192.168.100.254 255.255.255.0
|
||||
no shutdown
|
||||
router ospf 32
|
||||
network 192.168.0.8 0.0.0.3 area 0
|
||||
router ospf 21
|
||||
network 192.168.0.0 0.0.0.3 area 0
|
||||
no ip domain-lookup
|
||||
ip routing
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
**R3**
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
interface Gig0/0
|
||||
ip address 192.168.0.1 255.255.255.252
|
||||
no shutdown
|
||||
interface Gig0/1
|
||||
ip address 192.168.0.9 255.255.255.252
|
||||
no shutdown
|
||||
interface Gig0/2
|
||||
ip address 192.168.200.254 255.255.255.0
|
||||
no shutdown
|
||||
router ospf 13
|
||||
network 192.168.0.4 0.0.0.3 area 0
|
||||
router ospf 32
|
||||
network 192.168.0.8 0.0.0.3 area 0
|
||||
no ip domain-lookup
|
||||
ip routing
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
|
||||
### Exercice 6
|
||||
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,609 @@
|
||||
Emmanuel-Joyce NTSIA, Gauvain BOICHÉ, Joris STAVROULAKIS, Léo JARRY,
|
||||
|
||||
**Nous jurons sur l'honneur que les commandes entre `` sont tapées à la main à partir de nos notes de cours. (Elles sont réfléchies par nous en notre âme et conscience, on boycott openAI)**
|
||||
|
||||
*Pour rigoler on a passé une instruction "Génère moi une capture d'écran de Cisco Packet Tracer en pleine configuration d'un VLAN par la CLI" et voilà le résultat :*
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/54/546a8aa9001c2159072a7baec8264e1a2021d0150b46e9f3" data-crypto-key="cryptpad:SE/opt2PYh11RFDrv+FIqztrWEM8Tbs38Ym2vLUS/0c="></media-tag>
|
||||
|
||||
**Pour ne pas rigoler, ça devrait être illégal de nous mettre du 176 quand on est habitué au 172 en adresse**
|
||||
|
||||
# Mise en place de la Topologie physique:
|
||||
|
||||
Le client a présenté une topologie précise avec des modèles précis, nous avons décidé de garder la topologie d'origine pour des questions de négociations facilitées.
|
||||
|
||||
- Commutateurs 2960-24TT
|
||||
- Routeur ISR4331
|
||||
- Câbles droits pour liaisons routeurs & PC <-> commutateurs
|
||||
- Câbles croisés pour liaisons inter-commutateurs
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/f7/f78a72e3028ac51e664d595fc353f4f55ddd750a13a2ec12" data-crypto-key="cryptpad:cK6ON14fjHlmFIpvwrE4lflB2C0J66a8h0P8XgEm94A="></media-tag>
|
||||
|
||||
## Mise en place des adresses IP pour les pc
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/75/7531c9b9ffcad96cc9698387b13ff1f00d0d515bde067fbe" data-crypto-key="cryptpad:rAHhYAVWjTh1wLOLV7hRBJSv2uPOVEwGSZlNCnVpE2c="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/e1/e167b987d500078f41d11dff37d706b87c83612d2e958640" data-crypto-key="cryptpad:BetJlmk4OBDHo6UKp7/MHjt3tw99MFo749gOOwRJyIU="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/2c/2c25e98d1f3fffd017c272cf71007eb3c86f6b794fad4faf" data-crypto-key="cryptpad:fQDX194rYklfps2SuGWY14GjlB2MGoQO0xkoLmc1mYQ="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/d5/d505baf4fab37899b026d171930b5720a7ce1ed3f13ce0dd" data-crypto-key="cryptpad:AUYlTQAfIQpLCTdjRIxH0JCBBkUb90YUDOwiPUatu24="></media-tag>
|
||||
|
||||
## Mise en place des VLAN
|
||||
|
||||
**À noter qu'à partir de maintenant, des write memory sont fait après chaque étape pour s'assurer que la configuration soit bien sauvegardée**
|
||||
|
||||
### Création des VLANS dans les switch
|
||||
|
||||
**À faire sur tous les Switchs**
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
vlan 10
|
||||
name OSD
|
||||
exit
|
||||
vlan 20
|
||||
name MON-MGR
|
||||
exit
|
||||
vlan 30
|
||||
name Supervision
|
||||
exit
|
||||
vlan 40
|
||||
name Tests
|
||||
exit
|
||||
interface vlan 1
|
||||
no shutdown
|
||||
exit
|
||||
interface vlan 10
|
||||
no shutdown
|
||||
exit
|
||||
interface vlan 20
|
||||
no shutdown
|
||||
exit
|
||||
interface vlan 30
|
||||
no shutdown
|
||||
exit
|
||||
interface vlan 40
|
||||
no shutdown
|
||||
end
|
||||
write memory
|
||||
```
|
||||
<media-tag src="https://files.cryptpad.fr/blob/88/8894ff9fe3ee3c5d596f6b3d90115e31d75026fdc3edc85f" data-crypto-key="cryptpad:LcR3E2Cba1LW3U2/hybbdCFO1gpBFGD+mMu8kfCXvsw="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/6f/6f263259f02dfff0a5a5d47f4fcd7a3f37e583c1b4e4420b" data-crypto-key="cryptpad:Uqj9/FdG1R6mDppsvM6krb+gwiXu57KVirU9lBH2WRQ="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/e6/e6ba75ea5f3203723da30ffa7d449c34a51efae5d8bff21c" data-crypto-key="cryptpad:Ke+JwlWqjOk5hlwUKTIWXALWjuDre5OGi2uTLSd3MBM="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/d1/d1d9973764a3dd22af9c23af7c8357851f1af75bc6b23a55" data-crypto-key="cryptpad:aPx4p+sK7AleLZVdHL0TfgJ61nwTE+d37GcKwraWS30="></media-tag>
|
||||
|
||||
### Mise en place des ports access Switch - PC
|
||||
|
||||
|
||||
**À faire sur tous les Switchs sauf S5 en adaptant le port et la vlan**
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/cb/cbb784c08055c1e65fa452a12a845285dd6f8873beb6b372" data-crypto-key="cryptpad:HUFx2xYyrtDhpblKPxBE1TlM00Mjegg4Jrv+45c8L24="></media-tag>
|
||||
|
||||
|
||||
### Mise en place du port trunk entre S5 et R1 (le routeur)
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/6f/6f4e5d053334f8f74dfec7ea9f2c3ec8d1dbcf3faa8bdf1e" data-crypto-key="cryptpad:FQo7teQskt8L2x2LTcWdnLjpcNArdymgQ44CGhKZ5Q4="></media-tag>
|
||||
|
||||
(Petit oubli) On rajoute le nonegotiate :
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/41/417fe4f0a146622e5f782c9ed0ed2282550eb56a4b83c559" data-crypto-key="cryptpad:azRX27aolDPvYJSSELsl01CgAzLIA5nyX4rNJMS82wA="></media-tag>
|
||||
|
||||
## Mise en place des LAGs
|
||||
|
||||
**Switch 1**
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
interface range Fa0/2 - 4
|
||||
channel-group 1 mode active
|
||||
exit
|
||||
interface range Fa0/5 - 7
|
||||
channel-group 2 mode active
|
||||
exit
|
||||
interface port-channel 1
|
||||
switchport mode trunk
|
||||
switchport trunk native vlan 1
|
||||
switchport trunk allowed vlan 1,10,20,30,40
|
||||
no shutdown
|
||||
exit
|
||||
interface port-channel 2
|
||||
switchport mode trunk
|
||||
switchport trunk native vlan 1
|
||||
switchport trunk allowed vlan 1,10,20,30,40
|
||||
no shutdown
|
||||
exit
|
||||
show interfaces Port-channel [1,2] ! Pour contrôler
|
||||
show interfaces trunk ! Pour contrôler
|
||||
show etherchannel summary ! Pour contrôler
|
||||
end
|
||||
write memory
|
||||
```
|
||||
### Création du LAG en LACP actif
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/81/81fb3e3b3a439b4bbba857d0a30ae130b278c412992fbaeb" data-crypto-key="cryptpad:o+CVdqOL3L0sV9KH/XeY2SfvrUNtxgWbc4Cx5XSwNTo="></media-tag>
|
||||
|
||||
**Il faut faire pareil sur S4 (le switch de l'autre côté des ports concernés) du coup aussi pour que ça fonctionne**
|
||||
|
||||
### Configuration du trunk sur les LAGs
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/e8/e84f77050b2aab28cbd4688052976acaa3f9368178018315" data-crypto-key="cryptpad:d5Vhb8Hi1yXvjcvb0RDdLJKHU9UmgUCsyeAeNdGj12M="></media-tag>
|
||||
|
||||
(Petit oubli) On rajoute le nonegotiate :
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/68/6803b7c93fa4174b7cb1cc9a91ac48b4e310b1c57243b4e2" data-crypto-key="cryptpad:/QHmma0a0HXXtpgsUCRBS7d+NFZgZAGSW8SwW0moXr0="></media-tag>
|
||||
|
||||
**Ensuite il faut recommencer ces deux étapes (création du LAG et mise en place du trunk), sur tous les switchs en adaptant bien sûr les ports et en faisant bien attention de respecter les numéros de channel-group**
|
||||
|
||||
### Vérification du LAG et du trunk dessus
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/a9/a9b0ae6851b909314e12df72105c652d76a27705699b4225" data-crypto-key="cryptpad:ET7sByM10fWyoxFk9wMfpVnDoQ06ziOJjP6kOMvshG4="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/ad/ad485ff672e41bf34ad62b220e3f10b5306130a6efa55152" data-crypto-key="cryptpad:ipjEjM4dhGrcPVI9NzaT08IOrVvkazgkpM5/KsPOR2k="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/34/343a182e5e800bfa3fc53089ff7aa9303e1129dab85f0c72" data-crypto-key="cryptpad:6m1j7C0M3A89PwQ7cUY9SoOe5mrvUYkMJ0bFewG+cuE="></media-tag>
|
||||
|
||||
**Switch 2**
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
interface range Fa0/2 - 4
|
||||
channel-group 3 mode active
|
||||
exit
|
||||
interface range Fa0/5 - 7
|
||||
channel-group 2 mode active
|
||||
exit
|
||||
interface range Fa0/8 - 10
|
||||
channel-group 1 mode active
|
||||
exit
|
||||
interface port-channel 1
|
||||
switchport mode trunk
|
||||
switchport trunk native vlan 1
|
||||
switchport trunk allowed vlan 1,10,20,30,40
|
||||
no shutdown
|
||||
exit
|
||||
interface port-channel 2
|
||||
switchport mode trunk
|
||||
switchport trunk native vlan 1
|
||||
switchport trunk allowed vlan 1,10,20,30,40
|
||||
no shutdown
|
||||
exit
|
||||
interface port-channel 3
|
||||
switchport mode trunk
|
||||
switchport trunk native vlan 1
|
||||
switchport trunk allowed vlan 1,10,20,30,40
|
||||
no shutdown
|
||||
exit
|
||||
show interfaces Port-channel [1,2,3]
|
||||
show interfaces trunk
|
||||
show etherchannel summary
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
**Switch 3**
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
interface range Fa0/5 - 7
|
||||
channel-group 2 mode active
|
||||
exit
|
||||
interface range Fa0/8 - 10
|
||||
channel-group 1 mode active
|
||||
exit
|
||||
interface range Fa0/11 - 13
|
||||
channel-group 4 mode active
|
||||
exit
|
||||
interface port-channel 1
|
||||
switchport mode trunk
|
||||
switchport trunk native vlan 1
|
||||
switchport trunk allowed vlan 1,10,20,30,40
|
||||
no shutdown
|
||||
exit
|
||||
interface port-channel 2
|
||||
switchport mode trunk
|
||||
switchport trunk native vlan 1
|
||||
switchport trunk allowed vlan 1,10,20,30,40
|
||||
no shutdown
|
||||
exit
|
||||
interface port-channel 3
|
||||
switchport mode trunk
|
||||
switchport trunk native vlan 1
|
||||
switchport trunk allowed vlan 1,10,20,30,40
|
||||
no shutdown
|
||||
exit
|
||||
show interfaces Port-channel [1,2,3]
|
||||
show interfaces trunk
|
||||
show etherchannel summary
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
|
||||
**Switch 4**
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
interface range Fa0/2 - 4
|
||||
channel-group 1 mode active
|
||||
exit
|
||||
interface range Fa0/5 - 7
|
||||
channel-group 2 mode active
|
||||
exit
|
||||
interface port-channel 1
|
||||
switchport mode trunk
|
||||
switchport trunk native vlan 1
|
||||
switchport trunk allowed vlan 1,10,20,30,40
|
||||
no shutdown
|
||||
exit
|
||||
interface port-channel 2
|
||||
switchport mode trunk
|
||||
switchport trunk native vlan 1
|
||||
switchport trunk allowed vlan 1,10,20,30,40
|
||||
no shutdown
|
||||
exit
|
||||
show interfaces Port-channel [1,2,3]
|
||||
show interfaces trunk
|
||||
show etherchannel summary
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
|
||||
**Switch 5**
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
interface range Fa0/2 - 4
|
||||
channel-group 3 mode active
|
||||
exit
|
||||
interface range Fa0/11 - 13
|
||||
channel-group 4 mode active
|
||||
exit
|
||||
interface port-channel 1
|
||||
switchport mode trunk
|
||||
switchport trunk native vlan 1
|
||||
switchport trunk allowed vlan 1,10,20,30,40
|
||||
no shutdown
|
||||
exit
|
||||
interface port-channel 2
|
||||
switchport mode trunk
|
||||
switchport trunk native vlan 1
|
||||
switchport trunk allowed vlan 1,10,20,30,40
|
||||
no shutdown
|
||||
exit
|
||||
show interfaces Port-channel [1,2,3]
|
||||
show interfaces trunk
|
||||
show etherchannel summary
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
## Mise en place du routage inter-vlan
|
||||
|
||||
**Routeur**
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
interface Gig0/0/0
|
||||
no shutdown
|
||||
exit
|
||||
interface Gig0/0/0.1
|
||||
encapsulation dot1Q 1 native
|
||||
ip address 176.16.1.254 255.255.255.0
|
||||
no shutdown
|
||||
exit
|
||||
interface Gig0/0/0.10
|
||||
encapsulation dot1Q 10
|
||||
ip address 176.16.10.254 255.255.255.0
|
||||
no shutdown
|
||||
exit
|
||||
interface Gig0/0/0.20
|
||||
encapsulation dot1Q 20
|
||||
ip address 176.16.20.254 255.255.255.0
|
||||
no shutdown
|
||||
exit
|
||||
interface Gig0/0/0.30
|
||||
encapsulation dot1Q 30
|
||||
ip address 176.16.30.254 255.255.255.0
|
||||
no shutdown
|
||||
exit
|
||||
interface Gig0/0/0.40
|
||||
encapsulation dot1Q 40
|
||||
ip address 176.16.40.254 255.255.255.0
|
||||
no shutdown
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
### Interface physique
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/5a/5a56ebdd262aef1b824aa1f532992ad4ede02ff02782d095" data-crypto-key="cryptpad:+0CpOO5cDw/nD8JoR8h8yB3DK0Jqoq1NQ1/jSWsa48w="></media-tag>
|
||||
|
||||
### Interfaces virtuelles
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/2e/2ed9dd7897dfef103aa5155365dfb4a25f68390a89f82afc" data-crypto-key="cryptpad:B8ZapZI+2wsuGkC6Hb2lv4SdolP37dVIuObOI1d45dk="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/f6/f67b5e8972e8b1b11d0a084cdd6205b063292b689dfba9b6" data-crypto-key="cryptpad:fEakil02wX68FSgqtANnNP8BGGl8UCEhuNkzHnKAqMk="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/c3/c30a3872e9cae5ff921a4e421a4b0a11e27b70ccd3616f9b" data-crypto-key="cryptpad:Qf4olHJBX0N1803FkidN3ybBnCijMd5tDHQRqsdeIyc="></media-tag>
|
||||
|
||||
Depuis PC_OSD (vlan 10) :
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/f8/f8a6fc0c6e154b5278a57c42df58f0cfb79038c9ec5400be" data-crypto-key="cryptpad:E6XBGelcO8z3F852KVa0YLmeYejQS4j3s5XVM5czwOo="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/aa/aa081b9b255deb0cfabc6dd3502fb22ad39c23f74bd16e69" data-crypto-key="cryptpad:wcBCg8DG9YCkcZ7OGkSqRWEky3hpDAN6LBu/1UQnmjM="></media-tag>
|
||||
|
||||
**Puis on fait ça pour toutes les autres VLAN**
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/d0/d0a7c14956fc49c021310f8d5e376ea25d4f23c6c33cb8a7" data-crypto-key="cryptpad:0ZsNXijRJTj2oTUcL7nQMxlSVeolDTxzL4+6DRljSdo="></media-tag>
|
||||
|
||||
|
||||
## Sécurisation et accès à distance sur chaque appareil
|
||||
|
||||
### BPDU Guard
|
||||
|
||||
Sur les ports des switchs qui sont connectés aux pc/routeur on active le BPDU guard
|
||||
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
interface Fa0/1
|
||||
spanning-tree bpduguard enable
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/de/de4ce762dbe97acecd2f35d72f7a5bbc9db533bc10126508" data-crypto-key="cryptpad:2bWPavKJoydJarCrup+BQCOoZ3caCFnsR0usDVf1QU8="></media-tag>
|
||||
|
||||
### Sécurisation du port console
|
||||
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
line console 0
|
||||
password root
|
||||
login
|
||||
exit
|
||||
service password-encryption
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/af/afcbc673150c0d18c2a9361230ae530f81380d3792748969" data-crypto-key="cryptpad:4u4DjkTPkeVx4kUA6V05WVjECdeIXdeWHeRVIL96AD4="></media-tag>
|
||||
|
||||
Parce que c'est un exercice on va mettre le même mot de passe partout pour se simplifier la vie, bien sûr en vrai on mettrait des mots de passes forts et différents
|
||||
|
||||
Le service password-encryption servira à empêcher que le mot de passe soit accessible en clair dans la configuration
|
||||
|
||||
**On fait la même chose sur tous les switch et routeur**
|
||||
|
||||
### Activation à distance (ssh)
|
||||
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
ip domain-name fuckssh.com
|
||||
username ssh secret root
|
||||
crypto key generate rsa general-keys modulus 2048
|
||||
line vty 0 15
|
||||
transport input ssh
|
||||
login local
|
||||
exit
|
||||
ip ssh version 2
|
||||
interface vlan 1
|
||||
ip address 176.16.1.1 255.255.255.0
|
||||
exit
|
||||
ip default-gateway 176.16.1.254
|
||||
end
|
||||
write memory
|
||||
```
|
||||
*Le code est adapté pour chaque Switch, donc l'adresse IP sera 176.16.1.[1-5]*
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/e4/e4516c5b4e9d29e5c4eb646975508b04daac845db822c6e8" data-crypto-key="cryptpad:Wqn1O46/ucU/r9fia/XjFGzaCR3rzkIgBt6QUqceGgc="></media-tag>
|
||||
|
||||
**On oublie bien sûr pas d'ajouter une ip au switch dans le vlan 1 pour pouvoir s'y connecter ainsi que l'ip default-gateway**
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/41/416d332606f7a8857995f8037326ab857bffa5870fb7d502" data-crypto-key="cryptpad:loN+qfyLhMjcx4IwoJOlNAB6IHma22mmSzFO6AyRvXs="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/65/656b037fabf64be0b4925ec26bed04c41c4d027dc2233e0b" data-crypto-key="cryptpad:VRLakDpWCSPcpZaO8Ahc+C0YXYCAPYJyezTwSRH5BSs="></media-tag>
|
||||
|
||||
**On fait la même chose sur tous les switch et routeur**
|
||||
|
||||
### Sécurisation du mode enable
|
||||
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
enable secret root
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/b1/b173291a2c5ad33f30b31ce7f278026490136416a640d883" data-crypto-key="cryptpad:WiOgi91Teu6fQkllF6/leGxRuczUvHGAb+nVV1SOuZU="></media-tag>
|
||||
|
||||
<br/>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/05/05a498fafcb76da3fb3d828e58d1dfa04627f08198877cb3" data-crypto-key="cryptpad:RtiXPcHtE1MQY7HjX/0esiHl4p3AD59e0KxByzHe2h4="></media-tag>
|
||||
|
||||
### Vérification accès à distance
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/d4/d4c17ecee3644837f8517197d9f68b92c6224eb6098447e0" data-crypto-key="cryptpad:aAZO8A4u++FP6txk9i1Hd22MtU2jTT6g1txDXcVPkiQ="></media-tag>
|
||||
|
||||
### MOTD + Sécurisation des interfaces inactives
|
||||
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
banner motd # Personnel autorise seulement #
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
**On fait la même chose sur tous les switch et routeur**
|
||||
|
||||
Puis on fait la sécurisation des interfaces inactives en les éteignant et en les mettant sur un vlan 44 créé exprès pour ça
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/e5/e55c4ac8b9b677643da4364ce42aa0b0171d0acb447f8277" data-crypto-key="cryptpad:frkBBUIeRECZOr20nA24micUz2GqLZrWQuOLDfiygGM="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/9d/9d16630905283efe0d88bf62c29f420c9e0c2341316afeff" data-crypto-key="cryptpad:Hkd7WDLqcDkk5cKW2oTdC2AOeJnDQ/Lr+OGh8PjTtWo="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/d0/d08063a58ed877328789e741f6178d8bbebced047aaaadd7" data-crypto-key="cryptpad:x4lZdy9RmK3iMm1GNN+xynMB6xr0L+2Y5qUKbXVZxBE="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/e3/e3b0fc80e8dce3c0bccd883b9012851641f5db7f8f096920" data-crypto-key="cryptpad:SPuLms2t/YNIB7JHpLda0QFlfvB4I4OO2DL0RqywI+k="></media-tag>
|
||||
|
||||
**Switch 1**
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
interface range Gig0/1 - 2
|
||||
switchport mode access
|
||||
switchport access vlan 44
|
||||
shutdown
|
||||
exit
|
||||
interface range Fa0/8 - 24
|
||||
switchport mode access
|
||||
switchport access vlan 44
|
||||
shutdown
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
**Switch 2**
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
interface range Gig0/1 - 2
|
||||
switchport mode access
|
||||
switchport access vlan 44
|
||||
shutdown
|
||||
exit
|
||||
interface range Fa0/11 - 24
|
||||
switchport mode access
|
||||
switchport access vlan 44
|
||||
shutdown
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
**Switch 3**
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
interface range Gig0/1 - 2
|
||||
switchport mode access
|
||||
switchport access vlan 44
|
||||
shutdown
|
||||
exit
|
||||
interface range Fa0/2 - 4
|
||||
switchport mode access
|
||||
switchport access vlan 44
|
||||
shutdown
|
||||
exit
|
||||
interface range Fa0/14 - 24
|
||||
switchport mode access
|
||||
switchport access vlan 44
|
||||
shutdown
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
**Switch 4**
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
interface range Gig0/1 - 2
|
||||
switchport mode access
|
||||
switchport access vlan 44
|
||||
shutdown
|
||||
exit
|
||||
interface range Fa0/8 - 24
|
||||
switchport mode access
|
||||
switchport access vlan 44
|
||||
shutdown
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
**Switch 5**
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
interface range Gig0/1 - 2
|
||||
switchport mode access
|
||||
switchport access vlan 44
|
||||
shutdown
|
||||
exit
|
||||
interface range Fa0/5 - 10
|
||||
switchport mode access
|
||||
switchport access vlan 44
|
||||
shutdown
|
||||
exit
|
||||
interface range Fa0/14 - 24
|
||||
switchport mode access
|
||||
switchport access vlan 44
|
||||
shutdown
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
**Router**
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
interface range Gig0/0/1 - 2
|
||||
shutdown
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
## Mise en place des ACLs
|
||||
|
||||
Pour les ACLs on a décidé deux faire deux listes, une spécifiquement à l'entrée de la gateway du vlan 10 sur le routeur qui bloque uniquement les ports utilisés par les OSD avec les protocoles CEPH
|
||||
|
||||
Et une deuxième à l'entrée de la gateway du vlan 20 sur le routeur pour bloquer les ports utilisés par le monitor / manager de la même façon
|
||||
|
||||
On bloque donc les paquets qui viennent de ces deux vlan sur les ports utilisés par CEPH et qui sont en destination du réseau Tests (vlan 40)
|
||||
|
||||
Tout le reste du traffic est permis entre tous les vlans définis (icmp / ip, etc...)
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/20/20873674c55dab869fec0335d89010ae778864abc2a200ef" data-crypto-key="cryptpad:94ovIdglwHGQdU2B5869FcUHBKJndQi2F7zAUPwll6o="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/e8/e816dec28d2acdfb0a4e5f95cf0b1606fdecd36c852b65b7" data-crypto-key="cryptpad:coqWs73UmRyv58pKl61d0EISuiBP5O4RP9/XI18TFWA="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/93/93d92019644a11a4adb44f0a7c3a1ec32309d7e946999ed5" data-crypto-key="cryptpad:6q3YGerOUSknC5cTG1mfEdh26yLagA6n+HH2/iMZ1ik="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/e2/e2b4da356ab75c565ad72e8cfc5537de129be51743cd008f" data-crypto-key="cryptpad:yhhFgwZqTHny2kjQATW4ajxtH8bwzFhJA3vaGbtB2R4="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/74/7456997263b569403b96c9624909567ff3216edf1c63514f" data-crypto-key="cryptpad:3ltGaqtgUXSzoNbYbzb/NlRBiH6w/CS9yZ6/gO0cXBk="></media-tag>
|
||||
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
ip access-list extended CEPH_EXCLUDE_TESTS_VLAN10
|
||||
deny tcp 176.16.10.0 0.0.0.255 176.16.40.0 0.0.0.255 range 6800 7300
|
||||
permit icmp any any
|
||||
permit ip any any
|
||||
exit
|
||||
ip access-list extended CEPH_EXCLUDE_TESTS_VLAN20
|
||||
deny tcp 176.16.20.0 0.0.0.255 176.16.40.0 0.0.0.255 range 6800 7300
|
||||
deny tcp 176.16.20.0 0.0.0.255 176.16.40.0 0.0.0.255 eq 3300
|
||||
deny tcp 176.16.20.0 0.0.0.255 176.16.40.0 0.0.0.255 eq 6789
|
||||
permit icmp any any
|
||||
permit ip any any
|
||||
exit
|
||||
interface Gig0/0/0.10
|
||||
ip access-group CEPH_EXCLUDE_TESTS_VLAN10 in
|
||||
exit
|
||||
interface Gig0/0/0.20
|
||||
ip access-group CEPH_EXCLUDE_TESTS_VLAN20 in
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
# FIN
|
||||
|
||||
Ps : moins de 20/20 on débarque chez toi Cédric (dans minecraft)
|
||||
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+117
@@ -0,0 +1,117 @@
|
||||
# Mettre en place des VLANs et du trunk
|
||||
|
||||
### Step 2
|
||||
|
||||
- Accédez à Switch 2 en CLI
|
||||
|
||||
### Step 3
|
||||
|
||||
- Configurez le VLAN 1 et affectez lui l'interface 10.1.1.12/24
|
||||
|
||||
```
|
||||
SW1(config)#interface vlan 1
|
||||
SW1(config-if)#ip address 10.1.1.12 255.255.255.0
|
||||
SW1(config-if)#exit
|
||||
```
|
||||
- Créons les VLANs supplémentaire, à faire sur Switch 1 ET Switch 2 !!
|
||||
|
||||
```
|
||||
SW1(config)# vlan 10
|
||||
SW1(config-vlan)#exit
|
||||
SW1(config)# vlan 20
|
||||
SW1(config-vlan)#exit
|
||||
```
|
||||
Attribuez l'interface fa 0/1 de CHAQUE SWITCH à son VLAN :
|
||||
|
||||
SW1#conf t
|
||||
SW1(config-vlan)#int fa0/1
|
||||
SW1(config-if)#switchport mode access
|
||||
SW1(config-if)#switchport access vlan 10
|
||||
|
||||
SW2#conf t
|
||||
SW2(config-vlan)#int fa0/1
|
||||
SW2(config-if)#switchport mode access
|
||||
SW2(config-if)#switchport access vlan 20
|
||||
|
||||
- Configurez l'interface FA 0/3 comme trunk sur **CHAQUE SWITCH**
|
||||
|
||||
|
||||
```
|
||||
SW1(config) interface fastethernet 0/3
|
||||
SW1(config-if)# switchport mode trunk
|
||||
SW1(config-if)#switchport nonegotiate
|
||||
SW1(config-if)# switchport trunk allowed vlan 1,10,20
|
||||
SW1(config-if)# no shutdown
|
||||
|
||||
```
|
||||
- Configurez l'interface FA0/13 comme trunk sur Switch 1 uniquement, puisqu'il
|
||||
fait face au routeur :
|
||||
|
||||
|
||||
```
|
||||
SW1(config-if)#int fa0/13
|
||||
SW1(config-if)#switchport mode trunk
|
||||
SW(config-if)#switchport nonegotiate
|
||||
SW1(config-if)#switchport trunk allowed vlan 1,10,20
|
||||
|
||||
```
|
||||
### Step 7
|
||||
|
||||
- Faites un ping vers l'autre VLAN depuis PC1. Le ping doit échouer, pourquoi ?
|
||||
|
||||
*Parce qu'il n'y a pas de routage entre les VLANs, il faudrait configurer le
|
||||
routeur*
|
||||
|
||||
## TASK 2 : Configurez un Trunk sur le routeur
|
||||
|
||||
### Step 1
|
||||
|
||||
- Accédez au Routeur en CLI
|
||||
|
||||
### Step 2
|
||||
|
||||
- Allez dans l'interface gi 0/0
|
||||
|
||||
|
||||
```
|
||||
R(config)#enable
|
||||
R(config)#conf t
|
||||
R(config)#int gi0/0
|
||||
|
||||
```
|
||||
### Step 3
|
||||
|
||||
- Éteignez l'interface
|
||||
|
||||
|
||||
R(config)#shutdown
|
||||
|
||||
### Step 4
|
||||
|
||||
- Supprimez toutes les adresses IP existantes sur cette interface
|
||||
|
||||
|
||||
R(config-if)#no ip address
|
||||
|
||||
- Créez 3 sous-interfaces sur Gigabit 0/0, chacun avec les IP spécifiées dans
|
||||
l'énoncé, en déclarant ces interfaces comme devant décoder les paquets tagués
|
||||
à la norme 802.1q
|
||||
|
||||
|
||||
R(config)#interface gi 0/0.1
|
||||
R(config)#encapsulation dot1q 1 native
|
||||
R(config)#ip address 10.1.1.1 255.255.255.0
|
||||
R(config)#no shutdown
|
||||
R(config)#interface gi 0/0.10
|
||||
R(config)#encapsulation dot1q 10
|
||||
R(config)#ip address 10.1.10.1 255.255.255.0
|
||||
R(config)#no shutdown
|
||||
R(config)#interface gi 0/0.20
|
||||
R(config)#encapsulation dot1q 20
|
||||
R(config)#ip address 10.1.20.1 255.255.255.0
|
||||
R(config)#no shutdown
|
||||
R(config)#interface giga 0/0
|
||||
R(config)#no shutdown
|
||||
|
||||
**TOUT devrait être fonctionnel à ce stade.**
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+61
@@ -0,0 +1,61 @@
|
||||
# Troubleshooting VLAN
|
||||
|
||||
## TASK 1 : Dépannez la connectivité des VLANs
|
||||
|
||||
### Step 5
|
||||
|
||||
- L'interface se trouve dans le VLAN 10, or, elle est inactive, ce qui veut dire qu'on a oublié de créer le VLAN 10 !
|
||||
|
||||
Sur le switch ou ce vlan est absent, simplement taper "vlan 10" en mode conf terminal
|
||||
|
||||
### Step 7
|
||||
|
||||
- Entrez ces commandes sur le Switch 2 :
|
||||
|
||||
SW2(config)#interface FastEthernet0/3
|
||||
SW2(config-if)#switchport mode trunk
|
||||
SW2(config-if)#switchport nonegociate
|
||||
|
||||
### Step 9
|
||||
|
||||
- Entrez ces commandes sur le Switch 1 :
|
||||
|
||||
SW1(config)#interface FastEthernet0/3
|
||||
SW1(config-if)#switchport mode trunk
|
||||
SW1(config-if)#switchport nonegociate
|
||||
|
||||
### Step 13
|
||||
|
||||
- Entrez ces commandes sur le Switch 1 pour rétablir le bon vlan natif :
|
||||
|
||||
SW1(config)#interface FastEthernet0/3
|
||||
SW1(config-if)#switchport trunk native vlan 1
|
||||
|
||||
### Step 14
|
||||
|
||||
- Entrez ces commandes sur le Switch 2 :
|
||||
|
||||
SW2(config)#interface FastEthernet0/3
|
||||
SW2(config-if)#switchport trunk native vlan 1
|
||||
|
||||
### Step 16
|
||||
|
||||
- Entrez ces commandes sur le Switch 1 :
|
||||
|
||||
SW1(config)#copy running-config startup-config
|
||||
|
||||
- Entrez ces commandes sur le Switch 2 :
|
||||
|
||||
SW2(config)#copy running-config startup-config
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
+52
@@ -0,0 +1,52 @@
|
||||
# TP : Mise en œuvre du protocole HSRP dans un réseau redondant
|
||||
|
||||
## 🎯 Objectif
|
||||
Mettre en place une **redondance de passerelle** à l’aide du protocole **HSRP (Hot Standby Router Protocol)**, afin d’assurer la **continuité de service** en cas de défaillance d’un routeur.
|
||||
|
||||
---
|
||||
|
||||
🧱 **Réseau partagé** : 192.168.1.0/24
|
||||
🎯 **Passerelle virtuelle HSRP** : 192.168.1.1
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Étapes du TP
|
||||
|
||||
### 1️⃣ Configuration IP de base
|
||||
Configurer les adresses IP sur les deux routeurs et le PC selon le schéma ci-dessus.
|
||||
Vérifier la connectivité entre les équipements avec la commande `ping`.
|
||||
|
||||
---
|
||||
|
||||
### 2️⃣ Configuration HSRP
|
||||
Configurer HSRP sur les deux routeurs afin de partager une adresse IP virtuelle (192.168.1.1).
|
||||
Le **Router1** doit être prioritaire.
|
||||
|
||||
---
|
||||
|
||||
### 3️⃣ Vérification
|
||||
Utiliser les commandes de vérification pour observer :
|
||||
- Le routeur **actif**
|
||||
- Le routeur **standby**
|
||||
- L’adresse IP virtuelle et l’adresse MAC virtuelle associée
|
||||
|
||||
---
|
||||
|
||||
### 4️⃣ Test de bascule
|
||||
1. Vérifier le rôle initial de chaque routeur.
|
||||
2. Désactiver l’interface G0/0 de Router1 pour simuler une panne.
|
||||
3. Vérifier le basculement automatique du rôle actif vers Router2.
|
||||
4. Réactiver Router1 et observer le retour automatique à l’état initial.
|
||||
|
||||
---
|
||||
|
||||
### 5️⃣ Questions de réflexion
|
||||
|
||||
1. Quelle est la différence entre HSRP et VRRP ?
|
||||
2. Pourquoi configure-t-on la commande `preempt` ?
|
||||
3. Que se passerait-il si les deux routeurs avaient la même priorité ?
|
||||
4. Quelle est la différence entre HSRP et une agrégation de liens (EtherChannel) ?
|
||||
|
||||
---
|
||||
|
||||
**Fin du TP.**
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
# Correction du TP : Mise en œuvre du protocole HSRP dans un réseau redondant
|
||||
|
||||
## 🎯 Objectif
|
||||
Mettre en œuvre une **redondance de passerelle IP** avec **HSRP**, afin d'assurer une continuité de service réseau en cas de panne d'un routeur.
|
||||
|
||||
---
|
||||
|
||||
## 🧩 Topologie mise en place
|
||||
|
||||
```
|
||||
+-------------------+
|
||||
| Router1 |
|
||||
| G0/0 : 192.168.1.2|
|
||||
+-------------------+
|
||||
|
|
||||
|
|
||||
+-------------+
|
||||
| SW1 |
|
||||
+-------------+
|
||||
|
|
||||
+-------------------+
|
||||
| Router2 |
|
||||
| G0/0 : 192.168.1.3|
|
||||
+-------------------+
|
||||
|
|
||||
+------+
|
||||
| PC1 |
|
||||
|192.168.1.10|
|
||||
+------+
|
||||
```
|
||||
|
||||
🧱 **Réseau partagé** : 192.168.1.0/24
|
||||
🎯 **Passerelle virtuelle HSRP** : 192.168.1.1
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Étapes de configuration
|
||||
|
||||
### 1️⃣ Configuration IP de base
|
||||
|
||||
#### Router1
|
||||
```bash
|
||||
enable
|
||||
conf t
|
||||
interface g0/0
|
||||
ip address 192.168.1.2 255.255.255.0
|
||||
no shutdown
|
||||
exit
|
||||
```
|
||||
|
||||
#### Router2
|
||||
```bash
|
||||
enable
|
||||
conf t
|
||||
interface g0/0
|
||||
ip address 192.168.1.3 255.255.255.0
|
||||
no shutdown
|
||||
exit
|
||||
```
|
||||
|
||||
#### PC1
|
||||
```
|
||||
Adresse IP : 192.168.1.10
|
||||
Masque : 255.255.255.0
|
||||
Passerelle : 192.168.1.1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2️⃣ Configuration HSRP
|
||||
|
||||
#### Sur Router1 (routeur prioritaire)
|
||||
```bash
|
||||
interface g0/0
|
||||
standby 1 ip 192.168.1.1
|
||||
standby 1 priority 110
|
||||
standby 1 preempt
|
||||
no shutdown
|
||||
```
|
||||
|
||||
#### Sur Router2
|
||||
```bash
|
||||
interface g0/0
|
||||
standby 1 ip 192.168.1.1
|
||||
standby 1 priority 90
|
||||
standby 1 preempt
|
||||
no shutdown
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3️⃣ Vérification
|
||||
|
||||
Commande :
|
||||
```bash
|
||||
show standby
|
||||
```
|
||||
|
||||
**Router1 (actif) :**
|
||||
```
|
||||
GigabitEthernet0/0 - Group 1
|
||||
State is Active
|
||||
Virtual IP address is 192.168.1.1
|
||||
Active router is local
|
||||
Standby router is 192.168.1.3
|
||||
Priority 110 (configured 110)
|
||||
```
|
||||
|
||||
**Router2 (standby) :**
|
||||
```
|
||||
GigabitEthernet0/0 - Group 1
|
||||
State is Standby
|
||||
Virtual IP address is 192.168.1.1
|
||||
Active router is 192.168.1.2
|
||||
Priority 90 (configured 90)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4️⃣ Test de bascule (failover)
|
||||
|
||||
1. Depuis le PC, tester la connectivité :
|
||||
```bash
|
||||
PC1> ping 192.168.1.1
|
||||
```
|
||||
|
||||
2. Simuler la panne du routeur actif :
|
||||
```bash
|
||||
Router1(config)# interface g0/0
|
||||
Router1(config-if)# shutdown
|
||||
```
|
||||
|
||||
3. Vérifier que Router2 devient actif :
|
||||
```bash
|
||||
Router2# show standby
|
||||
```
|
||||
|
||||
4. Rétablir Router1 :
|
||||
```bash
|
||||
Router1(config-if)# no shutdown
|
||||
```
|
||||
|
||||
Grâce à la commande `preempt`, Router1 reprend automatiquement le rôle d'actif.
|
||||
|
||||
---
|
||||
|
||||
## 🧭 Réponses aux questions de réflexion
|
||||
|
||||
1. **Différence HSRP / VRRP :**
|
||||
HSRP est propriétaire Cisco, VRRP est standard (RFC 3768). Les deux assurent une redondance de passerelle.
|
||||
|
||||
2. **Commande `preempt` :**
|
||||
Permet à un routeur prioritaire de redevenir actif après un retour en service.
|
||||
|
||||
3. **Même priorité sur les deux routeurs :**
|
||||
En cas d’égalité, le routeur ayant l’adresse IP la plus élevée devient actif.
|
||||
|
||||
4. **HSRP vs EtherChannel :**
|
||||
HSRP redonde des routeurs (couche 3), EtherChannel agrège des liens physiques (couche 2).
|
||||
|
||||
---
|
||||
|
||||
## ✅ Bilan
|
||||
|
||||
- HSRP assure une **redondance de passerelle** sans intervention du poste client.
|
||||
- Une **IP et MAC virtuelles** sont partagées entre deux routeurs.
|
||||
- La **bascule** est transparente pour le réseau local.
|
||||
- **Packet Tracer** supporte parfaitement HSRP (contrairement à VRRP).
|
||||
|
||||
---
|
||||
|
||||
**Fin de la correction.**
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+78
@@ -0,0 +1,78 @@
|
||||
# CORRECTION TP 3 - Filtrage par ACLs
|
||||
|
||||
## Task 1
|
||||
|
||||
### Step 2 :
|
||||
|
||||
Avant toute chose, le 1er réflexe est de vérifier la présence d'ACL sur l'appareil, `show ip access list`.
|
||||
|
||||
Sur le routeur branch, on remarque justement une ACL déjà présente avec cette commande, de type standard, qui permet tout le traffic depuis le réseau 10.1.1.0. Rajouter une règle interdisant l'hôte 10.1.1.101 sera inefficace puisque la règle précédente laissera tout passer !
|
||||
|
||||
Il faut donc l'annuler :
|
||||
|
||||
enable
|
||||
conf t
|
||||
no ip access-list standard 1
|
||||
|
||||
Puis créez l'ACL demandée :
|
||||
|
||||
#### Créer l'ACL :
|
||||
|
||||
enable
|
||||
conf t
|
||||
ip access-list extended Telnet
|
||||
deny tcp host 10.1.1.101 host 172.16.1.100 eq telnet
|
||||
permit ip any any
|
||||
exit
|
||||
|
||||
**Notez l'importance ici du "permit ip any any" en fin d'ACL en tant que dernière règle, il stipule que tout ce qui ne concorde pas avec la 1ère règle peut passer, autrement la politique par défaut sur Cisco, implicite, est de refuser tout ce qui ne matche pas avec les règles précédentes !!! Il est en effet plus logique et rapide de dire ce qu'on autorise, et interdire tout le reste que l'inverse, d'ou le choix par Cisco du "deny ip any any" implicite.**
|
||||
|
||||
#### Attribuer cet ACL à une interface :
|
||||
|
||||
enable
|
||||
conf t
|
||||
interface gi0/0
|
||||
ip access-group Telnet in
|
||||
exit
|
||||
|
||||
## Task 2
|
||||
|
||||
### Step 7
|
||||
|
||||
enable
|
||||
conf t
|
||||
interface gi0/0
|
||||
no ip access-group Telnet out
|
||||
ip access-group Telnet in
|
||||
exit
|
||||
|
||||
### Step 9
|
||||
|
||||
enable
|
||||
conf t
|
||||
no ip access-list extended Telnet
|
||||
ip access-list extended Telnet
|
||||
deny tcp host 10.1.1.101 host 172.16.1.100 eq telnet
|
||||
permit ip any any
|
||||
exit
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+25
@@ -0,0 +1,25 @@
|
||||
# CORRECTION TP 4 - Troubleshoot de connectivité IP ayant pour cause les ACL
|
||||
|
||||
|
||||
## Task 1 – Réparer la route par défaut :
|
||||
|
||||
sur le routeur Branch :
|
||||
|
||||
Branch(config) #ip route 0.0.0.0 0.0.0.0 209.165.201.2
|
||||
|
||||
Ici, toute IP d'un réseau de n'importe quelle taille sera joignable par le biais de l'adresse `209.165.201.2`
|
||||
|
||||
## Task 2 – Réparer une ACL :
|
||||
|
||||
entrer ces commandes (ou équivalent) sur le routeur branch :
|
||||
|
||||
Branch(config) #ip access-list extended Outbound-ACL
|
||||
Branch(config-ext-nacl)#permit tcp any any eq Telnet
|
||||
Branch(config-ext-nacl)#permit tcp any any eq www
|
||||
|
||||
Si vous souhaitez réessayer la commande traceroute, il faut aussi penser à autoriser le trafic UDP
|
||||
|
||||
## Task 3 – Réparer la passerelle par défaut et la résolution de noms :
|
||||
|
||||
Il suffit d’aller dans la configuration de PC1 pour lui passer la bonne passerelle par défaut.
|
||||
Packet Tracer n’émulant pas un système d’exploitation Windows complet, il n’y a pas de fichier Host à rectifier. Il faut simplement rectifier la passerelle par défaut le PC, et refaire un ping test, mais avec l'adresse IP du serveur cette fois, pas le choix !
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,531 @@
|
||||
*Esteban, Floren, Gauvain*
|
||||
|
||||
# Projet 1
|
||||
|
||||
## Génèse
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/01/01967ebf4084a1992b8cb524d00bc243f2601c69c8615881" data-crypto-key="cryptpad:PhVMSz9E3GYukXUfxxVlGcaIA0HBYtDQPC06m3+uP4A="></media-tag>
|
||||
|
||||
### 1. Préparation du projet
|
||||
|
||||
- Floren : l'architecte
|
||||
- Esteban : le soutien moral
|
||||
- Gauvain : la petite secrétaire
|
||||
|
||||
#### Notes
|
||||
|
||||
Il se peut que les lignes de code affichées dans les captures d'écran ne soient pas 100% conformes avec les blocs de code tapés au-dessus. C'est normal : nous expérimentons au fur et à mesure, et quand la capture d'écran est faite, il se peut que nous ne nous apercevions d'une coquille ou d'un oubli que bien plus tard. Et qu'un paquet installé (genre NMAP) soit désinstallé plus tard, faute d'usage. Règle du **"moins de paquet = moins de surface d'attaque"**.
|
||||
|
||||
Le résultat est normalement affiché en capture d'écran, mais en cas de discordance, les blocs de code commentés font foi.
|
||||
|
||||
### 2. Définir l'architecture
|
||||
|
||||
#### A. Les Machines Virtuelles
|
||||
|
||||
[ROCKY_LINUX - Installation](https://docs.rockylinux.org/9/guides/9_6_installation/)
|
||||
|
||||
- Rocky Linux sur Hyperviseur
|
||||
- Deux connexions réseau : en Accès par Pont ou Réseau NAT
|
||||
- Pas de GUI
|
||||
|
||||
Nous avons décidé d'utiliser :
|
||||
- 3 VMs Rocky Linux 9.7 (version Boot), les infos sur la version 10 faisant état d'une version peu stabilisée
|
||||
- sur VirtualBox (par simplicité)
|
||||
- En réseau NAT (pour avoir une plage réseau vraiment isolée)
|
||||
- Pas de GUI
|
||||
|
||||
```
|
||||
sudo dnf update -y
|
||||
sudo dnf install -y firewalld nano curl wget
|
||||
|
||||
sudo systemctl enable --now firewalld
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/b0/b0e3f7b2c5672bcc99c1663edcf15c117a3f17174327a5cf" data-crypto-key="cryptpad:W8ya4WJHC8JFuL91qShLtU5NlcOqTtAY5NhRnDa28Ww="></media-tag>
|
||||
|
||||
Synchronisation des serveurs avec `chrony` :
|
||||
*Sur MON/MR*
|
||||
```
|
||||
nano /etc/chrony.conf
|
||||
|
||||
allow 10.0.10.0/24
|
||||
```
|
||||
|
||||
*Sur OSD1*
|
||||
```
|
||||
nano /etc/chrony.conf
|
||||
|
||||
server 10.0.10.11 iburst
|
||||
peer 10.0.10.13 iburst
|
||||
```
|
||||
|
||||
*Sur OSD2*
|
||||
```
|
||||
nano /etc/chrony.conf
|
||||
|
||||
server 10.0.10.11 iburst
|
||||
peer 10.0.10.12 iburst
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/b7/b7e033a10900c45e580f68f01397eb757d842eec7d93f382" data-crypto-key="cryptpad:bG9old1RTNdNOsmzGAg+COvQIxTE3SfkufJLR4P76ks="></media-tag>
|
||||
|
||||
Et on change les noms des machines :
|
||||
```
|
||||
sudo hostnamectl set-hostname ['monmgr', 'osd1', 'osd2']
|
||||
```
|
||||
|
||||
#### B. Configuration du **bonding**
|
||||
|
||||
[REDHAT - Configure Network Bonding](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/7/html/networking_guide/ch-configure_network_bonding)
|
||||
|
||||
[Bonding in Rocky Linux](https://www.server-world.info/en/note?os=Rocky_Linux_10&p=bonding)
|
||||
|
||||
- Mode [*active-backup*](https://www.ibm.com/docs/en/linux-on-systems?topic=recommendations-bonding-modes)
|
||||
- Bridge dédié au **bond** *active-backup* dans le Ceph
|
||||
|
||||
Ajouter le bond :
|
||||
```
|
||||
sudo nmcli connection add type bond con-name bond0 ifname bond0 mode active-backup
|
||||
|
||||
sudo nmcli connection add type ethernet ifname enp0s3 master bond0
|
||||
sudo nmcli connection add type ethernet ifname enp0s8 master bond0
|
||||
|
||||
sudo nmcli connection modify bond0 \
|
||||
ipv4.method manual \
|
||||
ipv4.addresses 10.0.10.[11,12,13]/24 \
|
||||
ipv4.gateway 10.0.10.1 \
|
||||
ipv4.dns 1.1.1.1
|
||||
|
||||
sudo nmcli connection up bond0
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/52/5279bfcf999a38ee607e1541ddd33f28e66496900d734aec" data-crypto-key="cryptpad:BTUFNaWv3J08TA3JXDprbwITT99IgroCiZHP9jQ2G8k="></media-tag>
|
||||
|
||||
Vérifications :
|
||||
```
|
||||
cat /proc/net/bonding/bond0
|
||||
|
||||
sudo nmcli device
|
||||
sudo nmcli connection
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/2e/2edba240650f6d1e7590f8c9158507e48065fbd90795b6bc" data-crypto-key="cryptpad:6/8X/hK2S2XkS5fa4Ciwg0rBI98BbGaDwxE4FJcjrcs="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/79/791e0bbb425373c202dcf441deb5d8547725b96207a7d000" data-crypto-key="cryptpad:uljqcx6jWwLfyqWPg6ES6ud/LOySsY+Ct4NB9Yv0csw="></media-tag>
|
||||
|
||||
Vérification de la redondance en débranchant une NIC dans la VM :
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/6f/6ffc89e214d2459839bcc46048e0c279bf02f00cca18a1ef" data-crypto-key="cryptpad:C3mIRrhfg0sBPfjiW9tlGHm9QOG2dJaJyexnPz7RMTk="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/4c/4c99131e6dddbe858c608688f6e2cf252f991e2f878986e0" data-crypto-key="cryptpad:Wkw6FmyqY69XxN1p0S18P6Xz1OdABF057EBDdyNjwxQ="></media-tag>
|
||||
|
||||
#### C. Réglages du pare-feu
|
||||
|
||||
[REDHAT - Using and configurind firewalld](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/configuring_firewalls_and_packet_filters/using-and-configuring-firewalld_firewall-packet-filters)
|
||||
|
||||
- Zone personnalisée : `ceph-mcs2025`
|
||||
- Associée à l'interface du **bond0**
|
||||
- [Autorisation des ports nécessaires à CEPH](https://docs.redhat.com/fr/documentation/red_hat_ceph_storage/5/html/configuration_guide/ceph-firewall-ports_conf) et associés
|
||||
|
||||
```
|
||||
sudo firewall-cmd --permanent --new-zone=ceph-mcs2025
|
||||
|
||||
# Pour vérifier
|
||||
sudo firewall-cmd --reload
|
||||
sudo firewall-cmd --get-zones
|
||||
|
||||
sudo firewall-cmd --permanent --zone=ceph-mcs2025 --add-interface=bond0
|
||||
sudo firewall-cmd --permanent --zone=ceph-mcs2025 --add-service=ssh
|
||||
|
||||
sudo firewall-cmd --permanent --zone=ceph-mcs2025 --add-port=80/tcp
|
||||
sudo firewall-cmd --permanent --zone=ceph-mcs2025 --add-port=443/tcp
|
||||
sudo firewall-cmd --permanent --zone=ceph-mcs2025 --add-port=3300-3303/tcp
|
||||
sudo firewall-cmd --permanent --zone=ceph-mcs2025 --add-port=6789/tcp
|
||||
sudo firewall-cmd --permanent --zone=ceph-mcs2025 --add-port=6800-7300/tcp
|
||||
sudo firewall-cmd --permanent --zone=ceph-mcs2025 --add-port=7480/tcp
|
||||
sudo firewall-cmd --permanent --zone=ceph-mcs2025 --add-port=8443/tcp
|
||||
|
||||
sudo firewall-cmd --permanent --zone=ceph-mcs2025 --add-port=123/udp
|
||||
sudo firewall-cmd --permanent --zone=ceph-mcs2025 --add-port=6800-7300/udp
|
||||
|
||||
sudo firewall-cmd --reload
|
||||
```
|
||||
|
||||
Et on vérifie :
|
||||
```
|
||||
sudo firewall-cmd --info-zone=ceph-mcs2025
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/a2/a2ac2b8a91755f1e2f5b8a18bbe32dcc87104db8c402d26f" data-crypto-key="cryptpad:uS+oAUopcYI7IMTpuFEuv5+ZaAQHQPI26N+xYSiROKQ="></media-tag>
|
||||
|
||||
### 3. Installer et configurer Ceph
|
||||
|
||||
#### A. Choix du Ceph
|
||||
|
||||
On a décidé d'utiliser RGW pour diverses raisons :
|
||||
1. c'est celui que nous connaissons le moins (raison éducative)
|
||||
2. c'est un système basé sur une technologie qui devient un standard nuagique (avec AWS S3 repris même par les concurrents)
|
||||
3. parce que pourquoi pas
|
||||
|
||||
#### B. Préparation des noeuds
|
||||
|
||||
[CEPH - cephadm](https://docs.ceph.com/en/squid/cephadm/) | [CEPH - Host Management](https://docs.ceph.com/en/squid/cephadm/host-management/)
|
||||
|
||||
- Installer `cephadm` version **`squid`** (*les deux dernières, `latest` et `tentacles` étant non stabilisées*)
|
||||
- Déployer le moniteur **MON** et gestionnaire **MGR** sur le premier noeud, ajout des deux autres comme **OSD**
|
||||
|
||||
Sur les trois noeuds :
|
||||
```
|
||||
sudo dnf install -y centos-release-ceph-squid
|
||||
sudo dnf install -y cephadm
|
||||
|
||||
# Pour les dépendances liées au déploiement de configurations
|
||||
sudo dnf install -y python3-yaml python3-jinja2
|
||||
```
|
||||
|
||||
Sur les deux noeuds OSD :
|
||||
```
|
||||
sudo cephadm add-repo --release squid
|
||||
sudo cephadm install ceph-common
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/04/04bfeb6849b12b28965abf54e6cc91ddf9125915416f9c25" data-crypto-key="cryptpad:Wjy8vSEIcoiBF0pMfanPIn3XDIHjeMCzKg3xo5akk10="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/66/66c00f924c77439a0dd943f61fad5eda03026d620212dd01" data-crypto-key="cryptpad:z+le7TirXV8Bw8ErK4rzqX2c2RzlRRR6mm3IXRCm+es="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/ae/aed1ef80f77a90b5755d1afac29278c7437b40fcdfeb538c" data-crypto-key="cryptpad:7KlTiZrmMyCgXEXivmt1csEL347pQvnwVkav3OpxVkQ="></media-tag>
|
||||
|
||||
Bootstrap du cluster sur le noeud principal :
|
||||
```
|
||||
sudo cephadm bootstrap \
|
||||
--mon-ip 10.0.10.11 \
|
||||
--allow-fqdn-hostname \
|
||||
--initial-dashboard-user admin \
|
||||
--initial-dashboard-password 'Dashboard123!'
|
||||
|
||||
# Copie de la clef publique du MON/MGR sur les OSD
|
||||
ssh-copy-id -f -i /etc/ceph/ceph.pub root@10.0.10.12
|
||||
ssh-copy-id -f -i /etc/ceph/ceph.pub root@10.0.10.13
|
||||
|
||||
# Vérification
|
||||
sudo ceph orch host ls
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/37/3753d7159bcb3e4a806ed81440e9b68a5153ed77c1dd3178" data-crypto-key="cryptpad:cwb1S464Sg2YC5IlOx1GLuWSyhEjFAKYLwDn02LeiJM="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/05/051b3bf8bc97c29ced6e2cc28505a196a4596b12ce6b2a9c" data-crypto-key="cryptpad:xsWlXVU0+hRImJI3iOr+BzMGnMQFZvq5FzTaj4Zy/eE="></media-tag>
|
||||
|
||||
Copie de la configuration du MON/MGR sur les OSD :
|
||||
```
|
||||
scp /etc/ceph/ceph.conf root@10.0.10.12:/etc/ceph/
|
||||
scp /etc/ceph/ceph.conf root@10.0.10.13:/etc/ceph/
|
||||
scp /etc/ceph/ceph.client.admin.keyring root@10.0.10.12:/etc/ceph/
|
||||
scp /etc/ceph/ceph.client.admin.keyring root@10.0.10.13:/etc/ceph/
|
||||
ssh root@10.0.10.12 "chmod 600 /etc/ceph/*.keyring && chmod 644 /etc/ceph/ceph.conf"
|
||||
ssh root@10.0.10.13 "chmod 600 /etc/ceph/*.keyring && chmod 644 /etc/ceph/ceph.conf"
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/b6/b69984ee1490f1eb4385c1ea4f069680665ae6224ae54d8f" data-crypto-key="cryptpad:420QFw4Et9opABYI8n+pWGVTdcF7OwbvW4ckzJ3i0Jk="></media-tag>
|
||||
|
||||
Ajout des hôtes dans le cluster **Ceph** :
|
||||
```
|
||||
sudo ceph orch host add osd1 10.0.10.12
|
||||
sudo ceph orch host add osd2 10.0.10.13
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/2a/2a21e37f16b7c508b955b0023363e9a113206221b717ac84" data-crypto-key="cryptpad:Xe+iyeh5eB3HySd2PUUjIEWK5TDbX8mf9wls3igXNxI="></media-tag>
|
||||
|
||||
[Ajout des **OSD** dans le cluster :](https://docs.ceph.com/en/squid/cephadm/services/osd/)
|
||||
```
|
||||
sudo ceph orch device ls
|
||||
|
||||
# Si on veut tout asservir sans distinction
|
||||
sudo ceph orch apply osd --all-available-devices
|
||||
|
||||
# Si on veut asservir un panel précis de volumes
|
||||
sudo ceph orch daemon add osd monmgr:/dev/sdb
|
||||
sudo ceph orch daemon add osd osd1:/dev/sdb
|
||||
sudo ceph orch daemon add osd osd2:/dev/sdb
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/43/438c9972b4f3cfbcf1e1ea817e3349feb26db85a85316599" data-crypto-key="cryptpad:BqGJbSrjy4PjKLFx4VoNswvY3yDo0Ed6KSAzkFD0vHU="></media-tag>
|
||||
|
||||
#### C. Déployer le service RGW
|
||||
|
||||
https://docs.ceph.com/en/squid/radosgw/
|
||||
https://docs.ceph.com/en/squid/radosgw/s3/
|
||||
|
||||
- Créer un *daemon* RGW avec `ceph orch apply rgw`
|
||||
- Configurer le domaine S3, clefs d'accès et politiques des seaux
|
||||
|
||||
[Déploiement du service RGW :](https://docs.ceph.com/en/latest/cephadm/services/rgw/)
|
||||
```
|
||||
sudo ceph orch apply rgw rgw-mcs \
|
||||
--realm=realm-mcs \
|
||||
--zone=zone-mcs \
|
||||
--placement="2 osd1 osd2"
|
||||
|
||||
# Ou en version "triviale"
|
||||
sudo ceph orch apply rgw rgw-mcs
|
||||
```
|
||||
|
||||
Vérifier l'intégrité du cluster RGW :
|
||||
```
|
||||
sudo ceph orch ps --daemon_type rgw
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/9d/9d1aadd4922a53bb5121747b354cb4c8d305e1ce91813289" data-crypto-key="cryptpad:kp2Y514w4Q5euJSkYzERMRkhHRlF24G08IudZA597w0="></media-tag>
|
||||
|
||||
[Créer un admin S3 :](https://docs.ceph.com/en/squid/man/8/radosgw-admin/)
|
||||
```
|
||||
sudo dnf install -y epel-release
|
||||
sudo dnf install -y ceph-radosgw
|
||||
|
||||
sudo radosgw-admin user create --uid=egf2025 --display-name="EstGauFlo 2025"
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/d7/d71d32e03c04b6092da7a8a1f282f6f3a5344478806ff089" data-crypto-key="cryptpad:PuJEHV5LYY0an9GXKK2OOi5zF2Kd4IswUW1QXoSg7PQ="></media-tag>
|
||||
|
||||
Modifier le ceph.conf :
|
||||
```
|
||||
sudo nano /etc/ceph/ceph.conf
|
||||
[client.radosgw.gateway]
|
||||
host = [monmgr, osd1, osd2]
|
||||
keyring = /etc/ceph/ceph.client.radosgw.gateway.keyring
|
||||
rgw_frontends = "beast port=7480"
|
||||
|
||||
sudo systemctl start ceph-radosgw@rgw.gateway
|
||||
|
||||
sudo nano /etc/ceph/ceph.client.radosgw.keyring
|
||||
[client.admin]
|
||||
key = *******
|
||||
caps mds = "allow *"
|
||||
caps mgr = "allow *"
|
||||
caps mon = "allow *"
|
||||
caps osd = "allow *"
|
||||
```
|
||||
|
||||
Vérifier la santé du cluster Ceph :
|
||||
```
|
||||
sudo ceph -s
|
||||
sudo ceph health detail
|
||||
```
|
||||
<media-tag src="https://files.cryptpad.fr/blob/00/008175712685740833165d4189973388037dece6e97ca258" data-crypto-key="cryptpad:ETLbKix9PaqPO1JmCAV61rgOmEoKNVpp1ZsH9KZSFoo="></media-tag>
|
||||
|
||||
Configurer l'accès S3 :
|
||||
```
|
||||
sudo dnf install -y awscli
|
||||
|
||||
aws configure set aws_access_key_id XXOKHTFX8OUAW4YEFBVT
|
||||
aws configure set aws_secret_access_key b3Cn2vYARkbnGWlPVdCg16ZYUZ3IczXC4SvtBBMy
|
||||
aws s3 ls --endpoint-url http://10.0.10.11:7480
|
||||
```
|
||||
|
||||
##### Notes sur le précédent bloc
|
||||
Ca ne sert à rien de copier le couple ID-Clef, ce sont des utilisateurs locaux, mais ce sont bien des vraies. On sait ce qu'on fait présentement, mais il est évident qu'on ne fait jamais ça en production.
|
||||
|
||||
La solution de niveau 1 c'est d'utiliser une variable d'environnement temporaire (`AWS_ID="XXOKHTFX8OUAW4YEFBVT"` et ensuite appeler avec un `$AWS_ID` dans le shell pour une expiration à déconnexion), et la solution de niveau 2 serait de déployer un serveur Consul/Vault sur le réseau pour gérer des secrets.
|
||||
|
||||
Vérifications :
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/f5/f57c10f5f901f528d6161d4d4068212ad93682ca281af5c7" data-crypto-key="cryptpad:YBGemuMRbe+2XHP9QCHhpOQkhVytwDubUkZI3SR2E5o="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/a4/a4fc092b1f622e66df15a15038578d0baa96519918acd3f0" data-crypto-key="cryptpad:vUWHK4CoxoVNirRj6IrZwIuuegv0UlciycL+B8Y8Qk0="></media-tag>
|
||||
|
||||
Et ensuite faire un test de téléversement dans un seau S3 avec la [documentation officielle](https://docs.aws.amazon.com/cli/latest/reference/s3/)
|
||||
|
||||
```
|
||||
aws s3 cp ./fichier s3://bucket/ --endpoint-url http://10.0.10.11:7480
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/aa/aa5dbaeb6794883b7e00b8d66d35f76512f605cc5deb26b2" data-crypto-key="cryptpad:1kSGzofa2tLeZC8F7U/f+6eXyN7U9ypJmZ7Ves5rleU="></media-tag>
|
||||
|
||||
#### D. (Bonus) Vérifier sur le Dashboard
|
||||
|
||||
Nous avons rajouté dans le réseau NAT (mais pas le Ceph) une machine tierce avec interface graphique, Rocky Linux ou Debian pour se connecter sur le dashboard :
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/15/15ff2edb30fde6ac61678c0a12459ce0a1e73ec6c03b2df9" data-crypto-key="cryptpad:TfjK9Mvvdxl2s0EnNbmA4o5i+HWP5qRipw2qv/MeJIk="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/73/7349a2e0f870321fc439f01406a04fec1e2153761419e757" data-crypto-key="cryptpad:Lz8yvNg+wuSZHY2+z2ffd0aw3R9equWXoLai67IChnA="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/18/18483faba0aa6472152e2e25004209389f95fb03aa6b79e3" data-crypto-key="cryptpad:wQhByOE8wrLo9VaRw8zGBQF9QKCi6gud35MpIlqmaTs="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/46/46360ecf4ee7840bf56ba19b7c07fdd1c8320d7e8887df93" data-crypto-key="cryptpad:FSxbRr2sEJt5GqipjMVW99t/9BwsrU65HkTOYpiZoEk="></media-tag>
|
||||
|
||||
### 4. Cisco Packet Tracer
|
||||
|
||||
#### A. Créer la topologie en GUI
|
||||
|
||||
- VLAN unique pour les 3
|
||||
- Switchs Layer 2 (un ou plusieurs)
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/f4/f48ef893820e0e9f0e2e0d6d2cd73d82308f65e4eb7b9598" data-crypto-key="cryptpad:a/qRxMjOGyuDXlxG2mmFWi3dkbXG6JrT3KSQ3RqquTI="></media-tag>
|
||||
|
||||
#### B. Créer la topologie en CLI
|
||||
|
||||
Création des LAGs :
|
||||
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
interface range fa0/[1-7]-[3-9]
|
||||
channel-group [1,2,3] mode active
|
||||
no shutdown
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/6a/6a2509b4f6e2a366356a13e288b33f91adec0b78a8ceb857" data-crypto-key="cryptpad:WKXQB4Poov7EL8/82WjJLs235J/qzfAWJIaoXAGi2/I="></media-tag>
|
||||
|
||||
Créer les VLAN :
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
vlan 10
|
||||
name CephCluster
|
||||
exit
|
||||
interface fa0/24
|
||||
switchport mode access
|
||||
switchport access vlan 10
|
||||
no shutdown
|
||||
exit
|
||||
interface port-channel [1,2,3]
|
||||
switchport mode trunk
|
||||
switchport trunk native vlan 1
|
||||
switchport trunk allowed vlan 1,10
|
||||
no shutdown
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/4e/4ebbd4130db94e2c9051ce3f63dedbe02c0d0c96f3874b60" data-crypto-key="cryptpad:ZMyW0x6++/MqFWxH57+l+YJi3L8ORaHU3rhZdzRUGIM="></media-tag>
|
||||
|
||||
[Créer la passerelle HSRP sur les routeurs :](https://routeur.clemanet.com/hsrp-cisco.php)
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
ip routing
|
||||
interface Gig0/0/1.10
|
||||
encapsulation dot1q 10
|
||||
ip address 10.0.10.[2,3] 255.255.255.0
|
||||
standby 1 ip 10.0.10.1
|
||||
standby 1 priority [100, 150]
|
||||
standby 1 preempt
|
||||
no shutdown
|
||||
end
|
||||
show standby
|
||||
write memory
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/c1/c1b0fc95b8db907a0d8b16cf9baab1a88a85807eb1e82f21" data-crypto-key="cryptpad:GW5Jz8ObOkwJRZFeJeQyawDCZzdw2ROwaVZM6SXB77U="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/68/68898c849a7ced544cd2a612db570ab61ef0b8b6da7a0185" data-crypto-key="cryptpad:gNGAPg+atpRGsPz7O2vsAaOHrhAnVIRaRXMcM1P1jzE="></media-tag>
|
||||
|
||||
Et on vérifie par un PING d'un OSD à un autre :
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/2c/2cc0b941a4e1e3fdce2c9475ff3c7e02eb1e172656fec99c" data-crypto-key="cryptpad:vjbMi/mYJ9kYxJb7+1M5g79yTdepCQkA0/sPd8iXaVk="></media-tag>
|
||||
|
||||
Et on teste avec un routeur éteint :
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/7a/7ada1d6e9098e316cf4406bf3a7bc5fe44b91457c7de19f8" data-crypto-key="cryptpad:Rzu93JyAnvomJsPvRxnCX7ixzTlWYl9k/P+6+xuReps="></media-tag>
|
||||
|
||||
#### C. Sécurisation
|
||||
|
||||
https://www.cisco.com/c/deleteme/sec/b_1710_sec_9300_cg/port_security.html
|
||||
|
||||
- Limiter le *MAC-address learning*
|
||||
- Activer *port-security* en mettant 1 dresse MAC maximum
|
||||
- Configurer les ports d'administration (console/VTY) avec authentification locale
|
||||
- Activer le SSH sur les switchs avec restriction aux adresses du VLAN
|
||||
- Autoriser le trafic Ceph, IMCP et SNMP uniquement depuis les adresses de gestion
|
||||
|
||||
Sécurité des ports :
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
interface range fa0/#-# // ports non utilisés
|
||||
shutdown
|
||||
exit
|
||||
interface range fa0/#-# // ports en usage
|
||||
switchport port-security
|
||||
switchport port-security maximum 1
|
||||
switchport port-security violation restrict
|
||||
switchport port-security mac-address sticky
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/19/19fd8194668ad082d5178f227c62b35b07bebbdd8dfa63d3" data-crypto-key="cryptpad:A6jmhR4OuaxQHMm+KbU31knsTnGw2MRaj755o8T51zw="></media-tag>
|
||||
|
||||
Activer le SSH :
|
||||
```
|
||||
ip domain-name mcs2025.local
|
||||
username admin secret mcs2025
|
||||
crypto key generate rsa general-keys modulus 2048
|
||||
ip ssh version 2
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/18/1881a74fa8065efcf42ced3373d7b136cc098dfab1d7db2a" data-crypto-key="cryptpad:3enRu+/ilQvxeyLU+yFdIGZ2b9TyHqycSwKOJE3qHO0="></media-tag>
|
||||
|
||||
Protection par mot de passe :
|
||||
```
|
||||
enable
|
||||
conf t
|
||||
enable password encryption
|
||||
line console 0
|
||||
password CisCanne
|
||||
login local
|
||||
line vty 0 4
|
||||
login local
|
||||
transport input ssh
|
||||
enable secret Conf-Iture
|
||||
end
|
||||
write memory
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/c7/c7489db8ed0d3e567414d3fee430ac312b66ccc0c5a48dd1" data-crypto-key="cryptpad:ozAr3/lNIaY4eBJ3JXGM5jpt92XkuZbk1NcXjrqniTA="></media-tag>
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/50/50e9db450cf23ccaac173476143752a85743a76917af5373" data-crypto-key="cryptpad:tlpugQJH1eSRGkBL1FihnusGElULFGzFj0ggsgTIZqQ="></media-tag>
|
||||
|
||||
ACL pour le trafic Ceph :
|
||||
```
|
||||
ip access-list extended CEPH-ALLOW
|
||||
permit tcp any any eq 80
|
||||
permit tcp any any eq 443
|
||||
permit tcp any any eq 6789
|
||||
permit tcp any any eq 7480
|
||||
permit tcp any any eq 8443
|
||||
permit tcp any any range 3300 3303
|
||||
permit tcp any any range 6800 7300
|
||||
permit udp any any range 6800 7300
|
||||
permit icmp any any
|
||||
permit udp any any eq 161
|
||||
deny ip any any
|
||||
```
|
||||
|
||||
<media-tag src="https://files.cryptpad.fr/blob/35/35b58a27fc74a43af2a5ffd1e81ce446a53b1d632d013459" data-crypto-key="cryptpad:Lu/trK9ciZxIK+6hk476MVpMttad4JY2BndgxC3ouMY="></media-tag>
|
||||
|
||||
# Liens utiles
|
||||
|
||||
## Bibliographie
|
||||
### Ceph
|
||||
[Tutoriel Scaleway d'un cluster Ceph](https://www.scaleway.com/en/docs/tutorials/ceph-cluster/)
|
||||
|
||||
[Tutoriel d'installer Ceph sur Rocky Linux](https://www.linkedin.com/pulse/step-by-step-instructions-install-ceph-rocky-linux-saman-salamat/)
|
||||
|
||||
[Configuration RGW sur RedHat](https://docs.redhat.com/de/documentation/red_hat_ceph_storage/3/html/object_gateway_guide_for_red_hat_enterprise_linux/rgw-configuration-reference-rgw)
|
||||
|
||||
[Cephadm pour RGW](https://docs.ceph.com/en/reef/cephadm/services/rgw/)
|
||||
|
||||
[Déployer Ceph sur Rocky Linux 9](https://random-it-blog.de/ceph/ceph-storage-cluster-deployment-on-rocky-linux-9-centos-9/)
|
||||
|
||||
### Pare-feu Rocky
|
||||
[Mettre en place FirewallD](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-using-firewalld-on-rocky-linux-8)
|
||||
|
||||
[Ports pour cluster Ceph](https://docs.redhat.com/en/documentation/red_hat_ceph_storage/5/html/configuration_guide/ceph-firewall-ports_conf)
|
||||
|
||||
[FirewallD par Stéphane Robert](https://blog.stephane-robert.info/docs/securiser/reseaux/firewalld/)
|
||||
|
||||
### Détails sur la configuration
|
||||
["Beast" pour RadosGW](https://documentation.suse.com/fr-fr/ses/7.1/single-html/ses-admin/book-storage-admin.html#config-ogw)
|
||||
|
||||
## Ressources
|
||||
[Rocky Linux](https://rockylinux.org/fr-FR/download)
|
||||
@@ -0,0 +1,12 @@
|
||||
# Projet 1
|
||||
|
||||
## Enoncé
|
||||
|
||||
Mettre en place une infrastructure :
|
||||
- serveurs sur VirtualBox
|
||||
- appareils réseaux sur Cisco Packet Tracer
|
||||
|
||||
### Système
|
||||
|
||||
- 3 VMs Rocky Linux => 9 faisant un cluster sous CEPH (CephFS, RBD, RGW au choix).
|
||||
- Pare-feu natif à la famille de distribution des règles autorisant les noeuds à se "parler en Ceph", le tout dans une "zone" dédiée, avec interface virtuelle dédiée à cette zone. Cette interface virtuelle est composée de 2 interfaces réseau physiques réunies dans un bonding (avec l'hyperviseur, en accès par pont + réseau NAT, mais PAS en NAT)
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
3.12
|
||||
@@ -0,0 +1,5 @@
|
||||
prenom = "Alice"
|
||||
nom = "Dupont"
|
||||
age = 30
|
||||
|
||||
print(prenom)
|
||||
@@ -0,0 +1,9 @@
|
||||
[project]
|
||||
name = "bases"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = [
|
||||
"requests>=2.32.5",
|
||||
]
|
||||
Generated
+113
@@ -0,0 +1,113 @@
|
||||
version = 1
|
||||
revision = 3
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[[package]]
|
||||
name = "bases"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "requests" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "requests", specifier = ">=2.32.5" }]
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2026.1.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/e0/2d/a891ca51311197f6ad14a7ef42e2399f36cf2f9bd44752b3dc4eab60fdc5/certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120", size = 154268, upload-time = "2026-01-04T02:42:41.825Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c", size = 152900, upload-time = "2026-01-04T02:42:40.15Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "charset-normalizer"
|
||||
version = "3.4.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload-time = "2025-10-14T04:40:57.217Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload-time = "2025-10-14T04:40:58.358Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload-time = "2025-10-14T04:40:59.468Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload-time = "2025-10-14T04:41:00.623Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload-time = "2025-10-14T04:41:01.754Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload-time = "2025-10-14T04:41:03.231Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload-time = "2025-10-14T04:41:04.715Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload-time = "2025-10-14T04:41:05.827Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload-time = "2025-10-14T04:41:06.938Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload-time = "2025-10-14T04:41:08.101Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload-time = "2025-10-14T04:41:09.23Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload-time = "2025-10-14T04:41:16.738Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload-time = "2025-10-14T04:41:17.923Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload-time = "2025-10-14T04:41:19.106Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload-time = "2025-10-14T04:41:20.245Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload-time = "2025-10-14T04:41:21.398Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload-time = "2025-10-14T04:41:22.583Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload-time = "2025-10-14T04:41:23.754Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload-time = "2025-10-14T04:41:25.27Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload-time = "2025-10-14T04:41:26.725Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload-time = "2025-10-14T04:41:28.322Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "3.11"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.32.5"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "certifi" },
|
||||
{ name = "charset-normalizer" },
|
||||
{ name = "idna" },
|
||||
{ name = "urllib3" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.6.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" },
|
||||
]
|
||||
@@ -0,0 +1 @@
|
||||
3.12
|
||||
@@ -0,0 +1,26 @@
|
||||
[
|
||||
{
|
||||
"Title": "LSDA",
|
||||
"Author": "Tolkien"
|
||||
},
|
||||
{
|
||||
"Title": "1984",
|
||||
"Author": "Orwell"
|
||||
},
|
||||
{
|
||||
"Title": "La voie des rois",
|
||||
"Author": "Brendan Sanderson"
|
||||
},
|
||||
{
|
||||
"Title": "Justici\u00e8re",
|
||||
"Author": "Brendan Sanderson"
|
||||
},
|
||||
{
|
||||
"Title": "Jus d'abricot",
|
||||
"Author": "COCKTAILS"
|
||||
},
|
||||
{
|
||||
"Title": "Jugement et trahison",
|
||||
"Author": "Alan O'Reilly"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,92 @@
|
||||
import json
|
||||
|
||||
class Book:
|
||||
def __init__(self, title: str, author: str):
|
||||
self.title = title
|
||||
self.author = author
|
||||
|
||||
def __repr__(self):
|
||||
return f"{self.title} de {self.author}"
|
||||
|
||||
def __eq__(self, other: "Book"):
|
||||
"""Pour comparer un objet de classe à un autre au lieu de l'ID par défaut"""
|
||||
return self.title == other.title and self.author == other.author
|
||||
|
||||
def __gt__(self, other: "Book"):
|
||||
return self.title > other.title
|
||||
|
||||
def __lt__(self, other: "Book"):
|
||||
return self.title.lower() < other.title.lower()
|
||||
|
||||
def serialized(self):
|
||||
"""Converti la classe en dictionnaire JSONable"""
|
||||
return {"Title": self.title, "Author": self.author}
|
||||
|
||||
@classmethod
|
||||
def deserialized(cls, dictionnary):
|
||||
"""Lis un JSON pour le retranscrire en classe Book"""
|
||||
return cls(title= dictionnary["Title"], author= dictionnary["Author"])
|
||||
|
||||
class Library:
|
||||
"""Gère un contenu de livres"""
|
||||
def __init__(self, name: str):
|
||||
self.name = name
|
||||
self.books = self.load()
|
||||
|
||||
def add_new_book(self, book: Book):
|
||||
"""Ajoute un nouveau livre"""
|
||||
if book in self.books:
|
||||
return f"{book.title.capitalize()} y est déjà."
|
||||
self.books.append(book)
|
||||
self.save()
|
||||
return f"{book.title.capitalize()} a été ajouté."
|
||||
|
||||
def take_out_book(self, book_name: str):
|
||||
"""Retire un livre déjà présent"""
|
||||
for book in self.books:
|
||||
if book.title.lower() == book_name.lower():
|
||||
self.books.remove(book)
|
||||
self.save()
|
||||
return f"{book.title.capitalize()} a été retiré."
|
||||
return f"{book.title.capitalize()} n'y est pas."
|
||||
|
||||
def list_books_in_list(self):
|
||||
"""Liste les livres présents"""
|
||||
return self.books
|
||||
|
||||
def sort_books_by_name(self):
|
||||
"""Tri les livres par ordre alphabétique"""
|
||||
self.books.sort()
|
||||
|
||||
def display_number_of_books(self) -> int:
|
||||
"""Donne le nombre de livres présents"""
|
||||
return len(self.books)
|
||||
|
||||
def search_book_by_word(self, word: str):
|
||||
"""Cherche un livre par mot de départ"""
|
||||
results = []
|
||||
for book in self.books:
|
||||
if word.lower() in book.title.lower():
|
||||
results.append(book)
|
||||
return results if len(results) > 0 else "Pas de résultat."
|
||||
|
||||
def search_book_by_letter(self, letter: str):
|
||||
"""Cherche un livre par lettre de départ"""
|
||||
results = []
|
||||
for book in self.books:
|
||||
if book.title.lower().startswith(letter.lower()):
|
||||
results.append(book)
|
||||
return results if len(results) > 0 else "Pas de résultat."
|
||||
|
||||
# Sauvegarde des livres dans un JSON pour persistance des données
|
||||
|
||||
def save(self):
|
||||
"""Inscris dans un fichier JSON le contenu de la bibliothèque"""
|
||||
book_dict = [book.serialized() for book in self.books]
|
||||
with open("books.json", "w", encoding= "utf-8") as json_file: # a pour append, w pour write
|
||||
json.dump(book_dict, json_file, indent= 4)
|
||||
|
||||
def load(self) -> list[Book]:
|
||||
"""Récupère le contenu d'un fichier JSON"""
|
||||
with open("books.json", encoding= "utf-8") as json_file:
|
||||
return json.load(json_file, object_hook= Book.deserialized)
|
||||
@@ -0,0 +1,167 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>520</width>
|
||||
<height>250</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Bibliothèque - Python</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>20</y>
|
||||
<width>480</width>
|
||||
<height>210</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="elideMode">
|
||||
<enum>Qt::ElideNone</enum>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab_add_book">
|
||||
<attribute name="title">
|
||||
<string>Ajouter Livre</string>
|
||||
</attribute>
|
||||
<widget class="QLineEdit" name="title_input">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>140</x>
|
||||
<y>40</y>
|
||||
<width>320</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="title_lb">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>40</y>
|
||||
<width>100</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Titre</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="author_input">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>140</x>
|
||||
<y>80</y>
|
||||
<width>320</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="author_lb">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>80</y>
|
||||
<width>100</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Auteur</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="save_btn">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>140</x>
|
||||
<y>120</y>
|
||||
<width>111</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enregistrer</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_search">
|
||||
<attribute name="title">
|
||||
<string>Recherche</string>
|
||||
</attribute>
|
||||
<widget class="QListView" name="results_view">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>60</y>
|
||||
<width>430</width>
|
||||
<height>100</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="search_lb">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>20</y>
|
||||
<width>181</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Recherche (par mot ou lettre)</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="search_input">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>210</x>
|
||||
<y>20</y>
|
||||
<width>240</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_delete">
|
||||
<attribute name="title">
|
||||
<string>Supprimer</string>
|
||||
</attribute>
|
||||
<widget class="QPushButton" name="delete_btn">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>360</x>
|
||||
<y>50</y>
|
||||
<width>100</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Supprimer</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="title_list">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>60</y>
|
||||
<width>320</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,15 @@
|
||||
from typing import TYPE_CHECKING
|
||||
from PyQt6.QtCore import QObject, pyqtSignal
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from gui.ui_library import Ui_Library
|
||||
|
||||
class SignalManagement(QObject):
|
||||
change_list_signal = pyqtSignal()
|
||||
|
||||
def __init__(self, ui):
|
||||
super().__init__()
|
||||
self.ui = ui
|
||||
|
||||
def connect_signals(self):
|
||||
self.change_list_signal.connect(self.ui.refresh_title_list)
|
||||
@@ -0,0 +1,77 @@
|
||||
# Form implementation generated from reading ui file '.\gui\library.ui'
|
||||
#
|
||||
# Created by: PyQt6 UI code generator 6.10.2
|
||||
#
|
||||
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
|
||||
# run again. Do not edit this file unless you know what you are doing.
|
||||
|
||||
|
||||
from PyQt6 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_MainWindow(object):
|
||||
def setupUi(self, MainWindow):
|
||||
MainWindow.setObjectName("MainWindow")
|
||||
MainWindow.resize(520, 250)
|
||||
self.centralwidget = QtWidgets.QWidget(parent=MainWindow)
|
||||
self.centralwidget.setObjectName("centralwidget")
|
||||
self.tabWidget = QtWidgets.QTabWidget(parent=self.centralwidget)
|
||||
self.tabWidget.setGeometry(QtCore.QRect(20, 20, 480, 210))
|
||||
self.tabWidget.setElideMode(QtCore.Qt.TextElideMode.ElideNone)
|
||||
self.tabWidget.setObjectName("tabWidget")
|
||||
self.tab_add_book = QtWidgets.QWidget()
|
||||
self.tab_add_book.setObjectName("tab_add_book")
|
||||
self.title_input = QtWidgets.QLineEdit(parent=self.tab_add_book)
|
||||
self.title_input.setGeometry(QtCore.QRect(140, 40, 320, 20))
|
||||
self.title_input.setObjectName("title_input")
|
||||
self.title_lb = QtWidgets.QLabel(parent=self.tab_add_book)
|
||||
self.title_lb.setGeometry(QtCore.QRect(20, 40, 100, 20))
|
||||
self.title_lb.setObjectName("title_lb")
|
||||
self.author_input = QtWidgets.QLineEdit(parent=self.tab_add_book)
|
||||
self.author_input.setGeometry(QtCore.QRect(140, 80, 320, 20))
|
||||
self.author_input.setObjectName("author_input")
|
||||
self.author_lb = QtWidgets.QLabel(parent=self.tab_add_book)
|
||||
self.author_lb.setGeometry(QtCore.QRect(20, 80, 100, 20))
|
||||
self.author_lb.setObjectName("author_lb")
|
||||
self.save_btn = QtWidgets.QPushButton(parent=self.tab_add_book)
|
||||
self.save_btn.setGeometry(QtCore.QRect(140, 120, 111, 41))
|
||||
self.save_btn.setObjectName("save_btn")
|
||||
self.tabWidget.addTab(self.tab_add_book, "")
|
||||
self.tab_search = QtWidgets.QWidget()
|
||||
self.tab_search.setObjectName("tab_search")
|
||||
self.results_view = QtWidgets.QListView(parent=self.tab_search)
|
||||
self.results_view.setGeometry(QtCore.QRect(20, 60, 430, 100))
|
||||
self.results_view.setObjectName("results_view")
|
||||
self.search_lb = QtWidgets.QLabel(parent=self.tab_search)
|
||||
self.search_lb.setGeometry(QtCore.QRect(20, 20, 181, 16))
|
||||
self.search_lb.setObjectName("search_lb")
|
||||
self.search_input = QtWidgets.QLineEdit(parent=self.tab_search)
|
||||
self.search_input.setGeometry(QtCore.QRect(210, 20, 240, 20))
|
||||
self.search_input.setObjectName("search_input")
|
||||
self.tabWidget.addTab(self.tab_search, "")
|
||||
self.tab_delete = QtWidgets.QWidget()
|
||||
self.tab_delete.setObjectName("tab_delete")
|
||||
self.delete_btn = QtWidgets.QPushButton(parent=self.tab_delete)
|
||||
self.delete_btn.setGeometry(QtCore.QRect(360, 50, 100, 40))
|
||||
self.delete_btn.setObjectName("delete_btn")
|
||||
self.title_list = QtWidgets.QComboBox(parent=self.tab_delete)
|
||||
self.title_list.setGeometry(QtCore.QRect(20, 60, 320, 20))
|
||||
self.title_list.setObjectName("title_list")
|
||||
self.tabWidget.addTab(self.tab_delete, "")
|
||||
MainWindow.setCentralWidget(self.centralwidget)
|
||||
|
||||
self.retranslateUi(MainWindow)
|
||||
self.tabWidget.setCurrentIndex(0)
|
||||
QtCore.QMetaObject.connectSlotsByName(MainWindow)
|
||||
|
||||
def retranslateUi(self, MainWindow):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
MainWindow.setWindowTitle(_translate("MainWindow", "Bibliothèque - Python"))
|
||||
self.title_lb.setText(_translate("MainWindow", "Titre"))
|
||||
self.author_lb.setText(_translate("MainWindow", "Auteur"))
|
||||
self.save_btn.setText(_translate("MainWindow", "Enregistrer"))
|
||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_add_book), _translate("MainWindow", "Ajouter Livre"))
|
||||
self.search_lb.setText(_translate("MainWindow", "Recherche (par mot ou lettre)"))
|
||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_search), _translate("MainWindow", "Recherche"))
|
||||
self.delete_btn.setText(_translate("MainWindow", "Supprimer"))
|
||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_delete), _translate("MainWindow", "Supprimer"))
|
||||
@@ -0,0 +1,19 @@
|
||||
from typing import TYPE_CHECKING
|
||||
from logic import actions
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from gui.ui_library import Ui_Library
|
||||
|
||||
class Ui_Initialization:
|
||||
def __init__(self, ui: Ui_Library):
|
||||
self.ui = ui
|
||||
|
||||
def connect_button(self):
|
||||
self.ui.save_btn.clicked.connect(self.ui.record_book)
|
||||
self.ui.delete_btn.clicked.connect(self.ui.delete_book)
|
||||
self.ui.change_list_signal.connect(self.ui.refresh_title_list)
|
||||
|
||||
self.ui.search_input.textChanged.connect(self.ui.search_book)
|
||||
|
||||
def fulfill_list(self):
|
||||
self.ui.title_list.addItems(actions.list_titles())
|
||||
@@ -0,0 +1,59 @@
|
||||
from logic import actions
|
||||
|
||||
from gui.signal_mgt import SignalManagement
|
||||
from gui.ui_init import Ui_Initialization
|
||||
from gui.ui_base import Ui_MainWindow
|
||||
|
||||
from PyQt6.QtWidgets import QMessageBox
|
||||
from PyQt6.QtGui import QStandardItemModel, QStandardItem
|
||||
|
||||
class Ui_Library(Ui_MainWindow):
|
||||
##### Méthode de mise à jour de la liste des titres avec QTSignal
|
||||
|
||||
def setupUi(self, MainWindow):
|
||||
super().setupUi(MainWindow)
|
||||
ui_init = Ui_Initialization(self)
|
||||
ui_init.connect_button()
|
||||
ui_init.fulfill_list()
|
||||
|
||||
self.signal_mgt = SignalManagement(self)
|
||||
self.signal_mgt.connect_signals()
|
||||
|
||||
def record_book(self):
|
||||
title = self.title_input.text()
|
||||
author = self.author_input.text()
|
||||
message = actions.register_book(title, author)
|
||||
QMessageBox.information(None, "Nouvel enregistrement", message)
|
||||
# self.refresh_title_list()
|
||||
self.signal_mgt.change_list_signal.emit()
|
||||
|
||||
def delete_book(self):
|
||||
title = self.title_list.currentText()
|
||||
message = actions.delete_book(title)
|
||||
QMessageBox.information(None, "Suppression confirmée", message)
|
||||
# self.refresh_title_list()
|
||||
self.signal_mgt.change_list_signal.emit()
|
||||
|
||||
def refresh_title_list(self):
|
||||
self.title_list.clear()
|
||||
self.title_list.addItems(actions.list_titles())
|
||||
|
||||
def search_book(self):
|
||||
word = self.search_input.text()
|
||||
if len(word) == 1:
|
||||
results = actions.search_by_letter(word)
|
||||
self.display_list_view(results)
|
||||
return
|
||||
if len(word) > 1:
|
||||
results = actions.search_by_word(word)
|
||||
self.display_list_view(results)
|
||||
return
|
||||
|
||||
def display_list_view(self, results):
|
||||
self.model = QStandardItemModel()
|
||||
self.results_view.setModel(self.model)
|
||||
if isinstance(results, str):
|
||||
self.model.appendRow(QStandardItem(results))
|
||||
else:
|
||||
for book in results:
|
||||
self.model.appendRow(QStandardItem(str(book)))
|
||||
@@ -0,0 +1,19 @@
|
||||
from classes import Book, Library
|
||||
|
||||
library = Library("Romanesque")
|
||||
|
||||
def register_book(title: str, author: str):
|
||||
book = Book(title, author)
|
||||
return library.add_new_book(book)
|
||||
|
||||
def list_titles() -> list[str]:
|
||||
return [book.title for book in library.list_books_in_list()]
|
||||
|
||||
def delete_book(title: str):
|
||||
return library.take_out_book(title)
|
||||
|
||||
def search_by_letter(letter: str):
|
||||
return library.search_book_by_letter(letter)
|
||||
|
||||
def search_by_word(word: str):
|
||||
return library.search_book_by_word(word)
|
||||
@@ -0,0 +1,12 @@
|
||||
import sys
|
||||
from PyQt6.QtWidgets import QApplication, QMainWindow
|
||||
from gui.ui_library import Ui_Library
|
||||
|
||||
app = QApplication([])
|
||||
MainWindow = QMainWindow()
|
||||
gui = Ui_Library()
|
||||
gui.setupUi(MainWindow)
|
||||
|
||||
MainWindow.show()
|
||||
|
||||
sys.exit(app.exec())
|
||||
@@ -0,0 +1,16 @@
|
||||
from classes import Book, Library
|
||||
|
||||
library = Library("Romans")
|
||||
|
||||
for i in range(3):
|
||||
new_book_title = input ("Quel livre ajouter ? > ")
|
||||
new_book_author = input ("Qui l'a écrit ? > ")
|
||||
new_book = Book(new_book_title, new_book_author)
|
||||
new_book_added = library.add_new_book(new_book)
|
||||
print(new_book_added)
|
||||
|
||||
print(library.list_books_in_list())
|
||||
|
||||
library.sort_books_by_name()
|
||||
|
||||
print(library.list_books_in_list())
|
||||
@@ -0,0 +1,9 @@
|
||||
[project]
|
||||
name = "bibliotheque"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = [
|
||||
"pyqt6>=6.10.2",
|
||||
]
|
||||
Generated
+67
@@ -0,0 +1,67 @@
|
||||
version = 1
|
||||
revision = 3
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[[package]]
|
||||
name = "bibliotheque"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "pyqt6" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "pyqt6", specifier = ">=6.10.2" }]
|
||||
|
||||
[[package]]
|
||||
name = "pyqt6"
|
||||
version = "6.10.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pyqt6-qt6" },
|
||||
{ name = "pyqt6-sip" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/96/03/e756f52e8b0d7bb5527baf8c46d59af0746391943bdb8655acba22ee4168/pyqt6-6.10.2.tar.gz", hash = "sha256:6c0db5d8cbb9a3e7e2b5b51d0ff3f283121fa27b864db6d2f35b663c9be5cc83", size = 1085573, upload-time = "2026-01-08T16:40:00.244Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/3f/f073a980969aa485ef288eb2e3b94c223ba9c7ac9941543f19b51659b98d/pyqt6-6.10.2-cp39-abi3-macosx_10_14_universal2.whl", hash = "sha256:37ae7c1183fe4dd0c6aefd2006a35731245de1cb6f817bb9e414a3e4848dfd6d", size = 60244482, upload-time = "2026-01-08T16:38:50.837Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/3e/9a015651ec71cea2e2f960c37edeb21623ba96a74956c0827def837f7c6b/pyqt6-6.10.2-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:78e1b3d5763e4cbc84485aef600e0aba5e1932fd263b716f92cd1a40dfa5e924", size = 37899440, upload-time = "2026-01-08T16:39:09.027Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/51/74/a88fec2b99700270ca5d7dc7d650236a4990ed6fc88e055ca0fc8a339ee3/pyqt6-6.10.2-cp39-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:bbc3af541bbecd27301bfe69fe445aa1611a9b490bd3de77306b12df632f7ec6", size = 40748467, upload-time = "2026-01-08T16:39:29.551Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/75/34/be7a55529607b21db00a49ca53cb07c3092d2a5a95ea19bb95cfa0346904/pyqt6-6.10.2-cp39-abi3-win_amd64.whl", hash = "sha256:bd328cb70bc382c48861cd5f0a11b2b8ae6f5692d5a2d6679ba52785dced327b", size = 26015391, upload-time = "2026-01-08T16:39:42.946Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/de/d9c88f976602b7884fec4ad54a4575d48e23e4f390e5357ea83917358846/pyqt6-6.10.2-cp39-abi3-win_arm64.whl", hash = "sha256:7901ba1df024b7ee9fdacfb2b7661aeb3749ae8b0bef65428077de3e0450eabb", size = 26208415, upload-time = "2026-01-08T16:39:57.751Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyqt6-qt6"
|
||||
version = "6.10.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/54/1b/137184632cad83a210e7955226744a77945260ca2e75892fe36299d26ada/pyqt6_qt6-6.10.1-py3-none-macosx_10_14_x86_64.whl", hash = "sha256:4bb2798a95f624b462b70c4f185422235b714b01e55abab32af1740f147948e2", size = 68472463, upload-time = "2025-11-27T14:20:51.694Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/df/ca795ac3d04243ad63499cfedcf92d8b5f6e3585a2a26c09f34cb58c8e44/pyqt6_qt6-6.10.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:0921cc522512cb40dbab673806bc1676924819550e0aec8e3f3fe6907387c5b7", size = 62296168, upload-time = "2025-11-27T14:21:21.232Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/7e/9867361252e2a4717dba95c64a0f3a793603f4a52cb9a46abbb041e960f5/pyqt6_qt6-6.10.1-py3-none-manylinux_2_34_x86_64.whl", hash = "sha256:04069aea421703b1269c8a1bcf017e36463af284a044239a4ebda3bde0a629fb", size = 83829262, upload-time = "2025-11-27T14:22:00.399Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9b/7b/18f4eb2273a92283fe4d87aa740a400eb14a4e41b8f990aaf563e9767db6/pyqt6_qt6-6.10.1-py3-none-manylinux_2_39_aarch64.whl", hash = "sha256:5b9be39e0120e32d0b42cdb844e3ae110ddadd39629c991e511902c06f155aff", size = 82877396, upload-time = "2025-11-27T14:22:36.994Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/53/5c/648c515d57bc82909d0597befb03bbc2f7a570f323dba3ad38629669efcb/pyqt6_qt6-6.10.1-py3-none-win_amd64.whl", hash = "sha256:df564d3dc2863b1fde22b39bea9f56ceb2a3ed7d6f0b76d3f96c2d3bc5d71516", size = 76670151, upload-time = "2025-11-27T14:23:11.172Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0a/13/2d2a9c0559bfa53effea5e2c1ed7aebb430186ce0b64cfba235231a049d9/pyqt6_qt6-6.10.1-py3-none-win_arm64.whl", hash = "sha256:48282e0f99682daf4f1e220cfe9f41255e003af38f7728a30d40c76e55c89816", size = 58276316, upload-time = "2025-11-27T14:23:38.744Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyqt6-sip"
|
||||
version = "13.11.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/e3/7d/d2916048e2e3960f68cb4e93907639844f7b8ff95897dcc98553776ccdfc/pyqt6_sip-13.11.0.tar.gz", hash = "sha256:d463af37738bda1856c9ef513e5620a37b7a005e9d589c986c3304db4a8a14d3", size = 92509, upload-time = "2026-01-13T16:01:32.16Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/53/a6/0e4d8fa7d6deb750bd0fdf89024e39c71fb127efb5eeedfab6830ad6679a/pyqt6_sip-13.11.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:6b3267cd93b7f4da6fdf9a6a26f3baed8faae06e5cdd76235f2acc2116c40a54", size = 112367, upload-time = "2026-01-13T16:01:09.08Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/66/e6/25dc20a03c46000e8b93aaf79347227926b67959283e5aab797daa7f64d8/pyqt6_sip-13.11.0-cp312-cp312-manylinux1_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c30248d9bbe54c46a78e5d549da50295ecd6584b965597f751e272f000fb8527", size = 301150, upload-time = "2026-01-13T16:01:12.385Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/11/9f/e850cd350aade789660cafba38c00777e686040c06b8cd0b45339b80fcba/pyqt6_sip-13.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c367b53a91e575ef66c1375f899713bdaf0a8b2c64b95ac226e9644854a4984", size = 323303, upload-time = "2026-01-13T16:01:10.736Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/26/5261d62108f7579407230f8c1d4dda43c18b5600ce70bf3becb2f997d5cc/pyqt6_sip-13.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:077958105c2ea2f62be2f1a7611ff8bd44cb52fb5ea8fc8c59ea949144acb7b5", size = 53461, upload-time = "2026-01-13T16:01:13.875Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/80/6c88b97eda309d6babb7292200bf51165dc06d0204d891b7bf1fb17a8ed0/pyqt6_sip-13.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:52812471619d3d3750b940d7d124cd0954107656924921ac177e098ba36362fb", size = 48650, upload-time = "2026-01-13T16:01:14.897Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/a0/46abcae4fce175a326185460a02c13ab81332bca7dd55c1e853ba6aee71e/pyqt6_sip-13.11.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:929716eebde1a64ffdb6b1715db6a22aefd5634d6df84858c7deb5e85be84fdf", size = 112353, upload-time = "2026-01-13T16:01:16.152Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/38/27c3aa3f153fcd83a0765fedf8e44a1136f189a322bcc9c494c5b3793cd7/pyqt6_sip-13.11.0-cp313-cp313-manylinux1_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a75144e8a0bcf9d1a9069011890401748af353749f1de1b6a314b880781edf9d", size = 301497, upload-time = "2026-01-13T16:01:20.531Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6f/ac/1053ffce45e4174f0a8174557b88537aa82bf96ba03c7dd208c59de36f69/pyqt6_sip-13.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8082b5f57ffad5dddf5efcf0ef5eaf94841395aa4e7c374c79ef24cf49b0f0ce", size = 323498, upload-time = "2026-01-13T16:01:17.859Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/d3/447b30d1f00cc50ad9e5c53b2e920068606b16857da83f8036b390c79fad/pyqt6_sip-13.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:8d49b5bf3d8d36cd7db93ddc54cd09dbba96a3fd926e445ef75499b41e47b5a3", size = 53469, upload-time = "2026-01-13T16:01:21.762Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/92/67/77e6fafcabd01c0a11166ab7464509896f137929f82c4f2e03aea1bf41b3/pyqt6_sip-13.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:293eac1b53c66c54b03266cc30015ec77454af679043a4f188b9bb80a9656996", size = 48643, upload-time = "2026-01-13T16:01:22.669Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/28/a5178c8e005bafbf9c0fd507f45a3eef619ab582811414a0a461ee75994f/pyqt6_sip-13.11.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:4dc9c4df24af0571423c3e85b5c008bad42ed48558eef80fbc3e5d30274c5abb", size = 112431, upload-time = "2026-01-13T16:01:23.832Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/3c/02770b02b5a05779e26bd02c202c2fd32aa38e225d01f14c06908e33738c/pyqt6_sip-13.11.0-cp314-cp314-manylinux1_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c974d5a193f32e55e746e9b63138503163ac63500dbb1fd67233d8a8d71369bd", size = 301236, upload-time = "2026-01-13T16:01:28.733Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/47/5af493a698cc520581ca1000b4ab09b8182992053ffe2478062dde5e4671/pyqt6_sip-13.11.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4284540ffccd8349763ddce3518264dde62f20556720d4061b9c895e09011ca0", size = 323919, upload-time = "2026-01-13T16:01:25.122Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/2d/64b26e21183a7ff180105871dd5983a8da539d8768921728268dc6d0a73d/pyqt6_sip-13.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:9bd81cb351640abc803ea2fe7262b5adea28615c9b96fd103d1b6f3459937211", size = 55078, upload-time = "2026-01-13T16:01:29.853Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/36/23f699fa8b1c3fcc312ecd12661a1df6057d92e16d4def2399b59cf7bf22/pyqt6_sip-13.11.0-cp314-cp314-win_arm64.whl", hash = "sha256:cd95ec98f8edb15bcea832b8657809f69d758bc4151cc6fd7790c0181949e45f", size = 49465, upload-time = "2026-01-13T16:01:31.174Z" },
|
||||
]
|
||||
@@ -0,0 +1 @@
|
||||
3.12
|
||||
@@ -0,0 +1,91 @@
|
||||
import json
|
||||
|
||||
class Contact:
|
||||
def __init__(self, name: str, phone: str, email: str):
|
||||
self.name = name
|
||||
self.phone = phone
|
||||
self.email = email
|
||||
|
||||
def __iter__(self):
|
||||
yield self.name
|
||||
yield self.phone
|
||||
yield self.email
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"{self.name} - {self.phone} - {self.email}"
|
||||
|
||||
def __eq__(self, other: "Contact"):
|
||||
return self.name == other.name\
|
||||
and self.phone == other.phone\
|
||||
and self.email == other.email
|
||||
|
||||
def serialized(self):
|
||||
"""Converti la classe en dictionnaire JSONable"""
|
||||
return {"Name": self.name, "Phone": self.phone, "Email": self.email}
|
||||
|
||||
@classmethod
|
||||
def deserialized(cls, dictionnary):
|
||||
"""Lis un JSON pour le retranscrire en classe Contact"""
|
||||
return cls(name= dictionnary["Name"], phone= dictionnary["Phone"], email= dictionnary["Email"])
|
||||
|
||||
class Repertory:
|
||||
def __init__(self, name: str):
|
||||
self.name = name
|
||||
self.contacts: list[Contact] = self.load()
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.contacts)
|
||||
|
||||
def __getitem__(self, index: int) -> Contact:
|
||||
return self.contacts[index]
|
||||
|
||||
def add_contact(self, contact: Contact):
|
||||
if contact in self.contacts:
|
||||
return f"{contact.name} est déjà dans le répertoire."
|
||||
self.contacts.append(contact)
|
||||
self.save()
|
||||
return f"Nouveau contact :\nNom : {contact.name}\nNuméro : {contact.phone}\nCourriel : {contact.email}"
|
||||
|
||||
def delete_contact(self, contact_info: str):
|
||||
for contact in self.contacts:
|
||||
if contact.name.lower() == contact_info.lower()\
|
||||
or contact.phone.lower() == contact_info.lower()\
|
||||
or contact.email.lower() == contact_info.lower():
|
||||
self.contacts.remove(contact)
|
||||
self.save()
|
||||
return f"{contact.name} a été supprimé du répertoire."
|
||||
return f"{contact.name} n'est pas dans le répertoire."
|
||||
|
||||
def search_contact(self, research_str: str):
|
||||
results = []
|
||||
for contact in self.contacts:
|
||||
if research_str.lower() in contact.name.lower()\
|
||||
or research_str.lower() in contact.phone.lower()\
|
||||
or research_str.lower() in contact.email.lower():
|
||||
results.append(contact)
|
||||
return results if len(results) > 0 else "Pas de résultat."
|
||||
|
||||
def display_contacts(self):
|
||||
results = []
|
||||
for idx, contact in enumerate(self.contacts):
|
||||
results.append(
|
||||
f"----- Contact n°{idx + 1} -----\n"
|
||||
f"Nom : {contact.name}\n"
|
||||
f"Numéro : {contact.phone}\n"
|
||||
f"Courriel : {contact.email}\n"
|
||||
" "
|
||||
)
|
||||
return "".join(results) if results else "Aucun contact dans le répertoire."
|
||||
|
||||
# Sauvegarde des livres dans un JSON pour persistance des données
|
||||
|
||||
def save(self):
|
||||
"""Inscris dans un fichier JSON le contenu de la bibliothèque"""
|
||||
contact_dict = [contact.serialized() for contact in self.contacts]
|
||||
with open("contacts.json", "w") as json_file: # a pour append, w pour write
|
||||
json.dump(contact_dict, json_file, indent= 4)
|
||||
|
||||
def load(self) -> list[Contact]:
|
||||
"""Récupère le contenu d'un fichier JSON"""
|
||||
with open("contacts.json") as json_file:
|
||||
return json.load(json_file, object_hook= Contact.deserialized)
|
||||
@@ -0,0 +1,27 @@
|
||||
[
|
||||
{
|
||||
"Name": "Alberto",
|
||||
"Phone": "0612345678",
|
||||
"Email": "alberto@courriel.fr"
|
||||
},
|
||||
{
|
||||
"Name": "Alice",
|
||||
"Phone": "0123456789",
|
||||
"Email": "alice@gmail.com"
|
||||
},
|
||||
{
|
||||
"Name": "Alberto",
|
||||
"Phone": "0482764563",
|
||||
"Email": "kfjsbdfg@sdfgj.fr"
|
||||
},
|
||||
{
|
||||
"Name": "Giorgio",
|
||||
"Phone": "857398375493",
|
||||
"Email": "giorgio.armani@armagnac.it"
|
||||
},
|
||||
{
|
||||
"Name": "Fran\u00e7ois LE GUERAND",
|
||||
"Phone": "0145892367",
|
||||
"Email": "fr-le-g@gmail.fr"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
from classes import Contact,Repertory
|
||||
|
||||
repertory = Repertory("Repertoire")
|
||||
|
||||
for i in range(1):
|
||||
new_contact_name = input("Nom > ")
|
||||
new_contact_phone = input("Numéro > ")
|
||||
new_contact_email = input("Courriel > ")
|
||||
|
||||
new_contact = Contact(new_contact_name, new_contact_phone, new_contact_email)
|
||||
new_contact_added = repertory.add_contact(new_contact)
|
||||
|
||||
print(new_contact_added)
|
||||
|
||||
search_criteria = input("Critères de recherche > ")
|
||||
print(repertory.search_contact(search_criteria))
|
||||
|
||||
print(repertory.display_contacts())
|
||||
@@ -0,0 +1,7 @@
|
||||
[project]
|
||||
name = "contacts"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = []
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user