Compare commits
13 Commits
79710cf66b
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 1abcfc9c4c | |||
| d052ad4b52 | |||
| 5d81b0dbb0 | |||
| 6e5f833d57 | |||
| f36f645e8c | |||
| ace040a012 | |||
| f56a2e7fb6 | |||
| 5228365299 | |||
| d79cf4c160 | |||
| 608508a155 | |||
| e8610c0033 | |||
| b47b173b94 | |||
| c41a9289c7 |
+14
-2
@@ -90,5 +90,17 @@ Soutenange-creation-entreprise : Mise en place des groupe et création des compt
|
||||
- UE2.33 - Analyse des vulnérabilités, menaces logicielles et sécurisation : Préparation oral et présentation oral de projet
|
||||
- UE2.11 - Mathématiques : Présentation projet R
|
||||
- UE2.34 - Analyse de la securite des reseaux : Webinaire et continuité du cours
|
||||
- UE2.12 - Managements_des_projets_risque : Initiation a Google console pour la gestion des lab DevOps
|
||||
- UE2.35 - Analyse_de_la_securite_des_accès : 2 Examens sur le lab de l'AD Windows server 2022
|
||||
- UE2.12 - Managements_des_projets_risque : Initiation a Google console pour la gestion des lab DevOps, Mise en place du repo GitHub build d'une image docker et push sur docker hub, Mise en place des branch et pull request qui declanche un CI (action.yml).
|
||||
- UE2.35 - Analyse_de_la_securite_des_accès : 2 Examens sur le lab de l'AD Windows server 2022, TP Sécurisation Avancée AD DS
|
||||
- UE2.16 - Droit, Propriété industrielle : Droit et propriété industrielle, brevet etc cas pratique AutoTech, Controle de fin de module.
|
||||
|
||||
# Juin
|
||||
|
||||
- UE2.14_Management_interculturel : Cours Magitral Notions clés, Enjeux, Prise en compte du MI dans les pratiques manageriales de l’entreprise. Exercice pratique de groupe poir deja appréhender l’examen qui est deja en approche.
|
||||
- UE2.35 - Suite et fin TP Sécurisation Avancée AD DS, Les protocole RADIUS.
|
||||
- UE2.34 - Analyse de la securite des reseaux : TP SNORT, installation, utilisation envoie de paquet avec scapy.
|
||||
- UE2.10 - Anglais : Exercice sur le travail en groupe et cas pratique sur la gestion d'équipe.
|
||||
- UE2.18 - Communication Marketing : Etude de marché, offre et demande.
|
||||
- UE2.6 - Activités Professionnelles : HACHATON.
|
||||
- UE2.24 - Systèmes distribués et applications sous Windows et Linux : TP1 Mise en place d'un systeme distribués simple pour trouver un hash md5. TP2 Mise en place d’un Load Balancer avec Nginx
|
||||
|
||||
|
||||
@@ -22,6 +22,18 @@ Sept 2025 Setp 2026 -> Contrôle continu, pas de partiel
|
||||
- Juillet : entrepreneuriat (en Groupe, orienté technique en français)
|
||||
- Septembre : activité Pro (individuelle en français)
|
||||
|
||||
## Accès proxmox :
|
||||
|
||||
[https://10.25.32.74:8006](https://10.25.32.74:8006)
|
||||
|
||||
## Organisation Année pro :
|
||||
|
||||
- 21 Septembre 2026 reprise des cours
|
||||
- 24 ou 25 septembre 2026 soutenance
|
||||
- Partiel semaine du 1er février 2027
|
||||
- Semaine du 28 juin 2027 toeic partiel soutenance
|
||||
- Septembre 16 et 17 septembre 2027 2 soutenances
|
||||
|
||||
## Connexion à Pedagogie CCI sur Linux Récent
|
||||
|
||||
Pour ce connecter avec un linux à la Wifi Pedagogie CCI
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
# UE2.14_Management_interculturel
|
||||
|
||||
## Introdcution
|
||||
|
||||
- Le management culturel :
|
||||
|
||||
C'est parce que l'homme se déplace, et il se déplace mtn vite.
|
||||
La mondialisation / globalisation -> c'est le procéssus qui consiste grace à **l'accélération des echanges**, du à **la modernisation des moyens de transport et de communication** de rendre intéligents les economies.
|
||||
|
||||
L'entreprise avait des habitudes de fonctionnement, des habitudes de management et désormais, il faut prendre en compte les cultures multiples dans le management qui est executé en entreprise.
|
||||
|
||||
- Notions clé :
|
||||
|
||||
-> Management
|
||||
-> Management interculturel
|
||||
-> culture / cultures
|
||||
-> Mondiaisation
|
||||
-> Captiliste
|
||||
-> Civilisation
|
||||
|
||||
### I - Le concepte management culturel (MI)
|
||||
|
||||
C'est la manière dont on va gérer, diriger, accompagner des colaborateurs, des équipes en tenant compte de leur différences d'origine, de leur echelles de valeur, de manière général de leur culture afin d'en faire une force pour bien former l'entreprise.
|
||||
|
||||
#### A - L'appréention de la notion
|
||||
|
||||
Qu'est ce qui fait de nous un être culturel :
|
||||
- les origines
|
||||
- la position
|
||||
- Faculté d'adaptation
|
||||
- Je pense donc je suis
|
||||
- Le contact avec les autres
|
||||
- l'éduction
|
||||
- L'inteligence
|
||||
- Aquerir des compétences
|
||||
- La langue
|
||||
- l'age
|
||||
|
||||
Une entreprise multiculturel l'est car elle à pour vocation de souvrir à l'internationnal.
|
||||
Le management interculturel trouve son encrage des les entreprise à vocation international.
|
||||
|
||||
Qu'est ce qui fait faire qu'une entreprise pratique un MI
|
||||
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
|
||||
|
||||
#### B - Les enjeux du management interculturel
|
||||
|
||||
| Enjeux | Crarctéristiques | Illustrations |
|
||||
|:---:|:---|:---|
|
||||
| Organisation | Le fait que l'on puisse devoir s'adapter à des différents et aux quel les salariés sur place pratiquent et qui peuvent "choquer" des salariés étrangés.| Les horraires |
|
||||
| Performance | Les attentes peuvent être beaucoup plus élevés dans certains pays. | La chine |
|
||||
| D'innovation | Avec le MI la course à l'innovation est un aspect prononcé car le groupe interculturel doit tiers vers l'augmentation en matière de R&D | Département d'inovation des entreprise des jeux vidéos |
|
||||
| Communication | 1. Savoir adapter sa communication idividuelle et collective. 2. Savoir prévenir et gérer les conflit interculturels. 3. Une communication inadapter peut etre source de conflit et de tention au sein des équipes entre des membres des équipes | Le fait de ne pas manier une langue commune (Notamment l'anglais) donc de ne pas transmettre les informations correctement pour tous les menbres de l'équipe. Autre exemple les dommes de chaleur ou de froid (srilanca ou alasca)|
|
||||
| Managearial des ressources humaines | 1. Optimisation des compétences avec des collaborateurs / équipe multiculturelles 2. Savoir faire de la bonne écoute 3. Anticiper d'éventelle malaises. 4. Assurer la bonne cohésion d'équipe | Team bulding, |
|
||||
|
||||
Définition de l'Arousée
|
||||
|
||||
Enjeux gains et que l'on connait l'art d'une
|
||||
|
||||
|
||||
#### étude de cas : A faire :
|
||||
|
||||
- Une étude analytique du management dans le pays, la region retenu.
|
||||
- Faire un comparatif avec le management Français.
|
||||
- Combienez les 2 et proposer des améliorations en vue d'un MI Pour cela -> création d'une multinational sous banière française, lesp oint négatifs et les difficultés, les solutions managearial faire du multiculturaliseme un ett pour la société.
|
||||
|
||||
Pays retenu, la Turiquie :
|
||||
|
||||
|
||||
https://www.inter-ligere.fr/reseaux-humains-interculturel-la-turquie/
|
||||
https://cadran.pro/management-interculturel-turquie/
|
||||
@@ -0,0 +1,25 @@
|
||||
# 1)
|
||||
|
||||
Pour bénéficier de cette protection des droits d'auteur DataStream doit remplir 2 conditions :
|
||||
Originalité grâce à son architecture modulaire originale
|
||||
Mise en forme il faut que l'oeuvre soit concrétisée fixer sur un support (code source écrit par les devs)
|
||||
|
||||
# 2)
|
||||
|
||||
Dans le cas de TechCloud les développeurs de datastream ne possèdent pas les droits patrimoniaux sur le logiciel techcloud détient automatiquement tous les droits patrimoniaux sur datastream
|
||||
|
||||
# 3)
|
||||
|
||||
Les dev conservent 4 prérogatives essentielles
|
||||
Le droit à la paternité
|
||||
Le droit à la divulgation
|
||||
Le droit au respect de l'œuvre
|
||||
Le droit de retrait ou de repentir
|
||||
|
||||
# 4)
|
||||
|
||||
TechCloud peut commercialiser sans l'accord des dev car il possède les droits patrimoniaux, Techcloud devrait faire signer une clause de confidentialité et de préciser que toute création intellectuelle réalisée dans le cadre de leur fonction appartient à l'entreprise
|
||||
|
||||
# 5)
|
||||
|
||||
TechCloud devrait déposer le nom de domaine ou la marque de datastream à l'INPI
|
||||
@@ -0,0 +1,17 @@
|
||||
# étude de cas section 5 autoTech
|
||||
|
||||
## 1)
|
||||
|
||||
L'invention de Sophie doit être qualifié d'invention or mission attribuable à l'entreprise, en raison du lien mnifeste avec le dommaine d'activité d'AutoTech et de l'utilisation problable des connaissance technique aquise dans le cadre de son emploie.
|
||||
Sophie à conçu et développé son invention or de sa mission.
|
||||
## 2)
|
||||
|
||||
Sophie est la titulaire initiale de l'invention mais son employeur autotech peut exercer son droit d'attribution des droits d'exploitation, autotech devra verser à Sophie une contrepartie d'un montant équivalent à 2 à 6 mois du salaire brut
|
||||
|
||||
## 3)
|
||||
|
||||
Si Sophie dépose un brevet à son nom sans avoir préalablement déclaré cela autotech cela mènera à plusieurs fautes la première étant la violation de l'obligation légale de déclaration, seconde faute étant le risque d'usurpation du titre c'est à dire que l'employeur peut revendiquer le brevet et contester la titularité du titre
|
||||
|
||||
## 4)
|
||||
|
||||
Il y a 3 forme de rémunération potentielles, il y a la forme forfaitaire unique (prime), un pourcentage sur le chiffre d'affaire généré (royalties), la combinaison des payements échelonnés scénario 2 si autotech ne manifeste pas son droit d'attribution dans un délai de 4 mois Sophie conserve la pleine titularité de l'invention.
|
||||
Binary file not shown.
@@ -1,7 +0,0 @@
|
||||
# 03 04 2026
|
||||
|
||||
<details><summary>Info prof</summary>
|
||||
<pre>
|
||||
Mr Kalonji Jean.Claude - jean-claude.Kalonji@seineetmarne.cci.fr</pre>
|
||||
</details>
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# UE2.18 Communication Marketing
|
||||
|
||||
## 03 04 2026
|
||||
|
||||
<details><summary>Info prof</summary>
|
||||
<pre>
|
||||
Mr Kalonji Jean.Claude - jean-claude.kalonji@seineetmarne.cci.fr</pre>
|
||||
</details>
|
||||
|
||||
## 04 06 2026
|
||||
|
||||
> Etude de marché, offre et demande
|
||||
|
||||
## 24 06 2026
|
||||
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,4 @@
|
||||
import xmlrpc.client
|
||||
proxy = xmlrpc.client.ServerProxy("http://192.168.1.210:9000/")
|
||||
num = int(input("Entrez un nombre : "))
|
||||
print("Résultat : ", proxy.square(num))
|
||||
@@ -0,0 +1,7 @@
|
||||
from xmlrpc.server import SimpleXMLRPCServer
|
||||
def square(x):
|
||||
return x * x
|
||||
server = SimpleXMLRPCServer(("0.0.0.0", 9000))
|
||||
print("Server listening on port 9000...")
|
||||
server.register_function(square, "square")
|
||||
server.serve_forever()
|
||||
@@ -0,0 +1,64 @@
|
||||
from xmlrpc.server import SimpleXMLRPCServer
|
||||
import itertools
|
||||
import string
|
||||
|
||||
class HashCrackerServer:
|
||||
def __init__(self, target_hash, algo):
|
||||
self.target_hash = target_hash
|
||||
self.algo = algo
|
||||
self.workers = []
|
||||
self.password_found = False
|
||||
|
||||
print("Génération de l'espace de recherche (1 à 4 lettres)...")
|
||||
self.blocks = self._generate_blocks()
|
||||
print(f"Espace divisé en {len(self.blocks)} blocs de travail.")
|
||||
|
||||
def _generate_blocks(self, block_size=5000):
|
||||
chars = string.ascii_lowercase
|
||||
all_combinations = []
|
||||
# Génère les mots de 1 à 4 lettres
|
||||
for length in range(1, 5):
|
||||
for p in itertools.product(chars, repeat=length):
|
||||
all_combinations.append("".join(p))
|
||||
|
||||
# Découpage de la liste globale en sous-listes (blocs)
|
||||
return [all_combinations[i:i + block_size] for i in range(0, len(all_combinations), block_size)]
|
||||
|
||||
def register_worker(self, worker_name):
|
||||
if worker_name not in self.workers:
|
||||
self.workers.append(worker_name)
|
||||
print(f"[INFO] Nouveau Worker enregistré : {worker_name}")
|
||||
return True
|
||||
|
||||
def get_work_block(self):
|
||||
if self.password_found:
|
||||
return {"status": "STOP"} # Quelqu'un a déjà trouvé
|
||||
if not self.blocks:
|
||||
return {"status": "DONE"} # Plus de travail disponible
|
||||
|
||||
# On retire le premier bloc de la liste et on l'envoie
|
||||
return {
|
||||
"status": "WORK",
|
||||
"algo": self.algo,
|
||||
"target": self.target_hash,
|
||||
"words": self.blocks.pop(0)
|
||||
}
|
||||
|
||||
def submit_result(self, worker_name, password):
|
||||
if password:
|
||||
self.password_found = True
|
||||
print(f"\n[SUCCÈS] Le worker '{worker_name}' a cracké le hash ! Mot de passe : {password}")
|
||||
return True
|
||||
|
||||
# Hash MD5 pour le mot "chat"
|
||||
TARGET_HASH = "aa8af3ebe14831a7cd1b6d1383a03755"
|
||||
ALGO = "md5"
|
||||
|
||||
server = SimpleXMLRPCServer(("0.0.0.0", 9000), allow_none=True)
|
||||
cracker_instance = HashCrackerServer(TARGET_HASH, ALGO)
|
||||
|
||||
# Enregistrement de l'instance entière (expose toutes ses méthodes publiques)
|
||||
server.register_instance(cracker_instance)
|
||||
|
||||
print("Serveur Maître RPC en écoute sur le port 9000...")
|
||||
server.serve_forever()
|
||||
@@ -0,0 +1,54 @@
|
||||
import xmlrpc.client
|
||||
import hashlib
|
||||
import sys
|
||||
|
||||
# Pense à remplacer par l'IP de ta VM1
|
||||
PROXY_URL = "http://192.168.1.210:9000/"
|
||||
WORKER_NAME = "UE2-24-worker1"
|
||||
#WORKER_NAME = "UE2-24-worker2"
|
||||
|
||||
try:
|
||||
proxy = xmlrpc.client.ServerProxy(PROXY_URL, allow_none=True)
|
||||
proxy.register_worker(WORKER_NAME)
|
||||
print(f"Connecté au serveur en tant que {WORKER_NAME}")
|
||||
except Exception as e:
|
||||
print(f"Impossible de se connecter au serveur : {e}")
|
||||
sys.exit(1)
|
||||
|
||||
while True:
|
||||
try:
|
||||
job = proxy.get_work_block()
|
||||
except Exception as e:
|
||||
print(f"Erreur de communication avec le serveur : {e}")
|
||||
break
|
||||
|
||||
if job["status"] == "STOP":
|
||||
print("Un autre worker a trouvé le mot de passe. Fin du programme.")
|
||||
break
|
||||
elif job["status"] == "DONE":
|
||||
print("L'espace de recherche est épuisé. Le mot de passe n'a pas été trouvé.")
|
||||
break
|
||||
|
||||
words = job["words"]
|
||||
target = job["target"]
|
||||
algo = job["algo"]
|
||||
|
||||
print(f"Réception d'un bloc de {len(words)} mots à tester...")
|
||||
found_password = None
|
||||
|
||||
# Boucle de force brute sur le bloc
|
||||
for word in words:
|
||||
h = hashlib.new(algo)
|
||||
h.update(word.encode('utf-8'))
|
||||
|
||||
if h.hexdigest() == target:
|
||||
found_password = word
|
||||
break
|
||||
|
||||
# Soumission du résultat (mot de passe ou None si échec sur ce bloc)
|
||||
if found_password:
|
||||
proxy.submit_result(WORKER_NAME, found_password)
|
||||
print(f">>> MOT DE PASSE TROUVÉ : {found_password} <<<")
|
||||
break
|
||||
else:
|
||||
proxy.submit_result(WORKER_NAME, None)
|
||||
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.
BIN
Binary file not shown.
+58
@@ -0,0 +1,58 @@
|
||||
services:
|
||||
db:
|
||||
image: mariadb:latest
|
||||
container_name: db_container
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=rootpassword
|
||||
- MYSQL_DATABASE=mydb
|
||||
- MYSQL_USER=user
|
||||
- MYSQL_PASSWORD=userpassword
|
||||
volumes:
|
||||
- db_data:/var/lib/mysql
|
||||
networks:
|
||||
- app-network
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "mariadb -uroot -prootpassword -e 'SELECT 1' || exit 1"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
||||
web:
|
||||
image: nginx:alpine
|
||||
container_name: web_container
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8080:80"
|
||||
volumes:
|
||||
- ./html:/usr/share/nginx/html:ro
|
||||
networks:
|
||||
- app-network
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl -f http://localhost || exit 1"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
||||
phpmyadmin:
|
||||
image: phpmyadmin:latest
|
||||
container_name: phpmyadmin_container
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- PMA_HOST=db
|
||||
ports:
|
||||
- "8081:80"
|
||||
networks:
|
||||
- app-network
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl -f http://localhost || exit 1"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
||||
volumes:
|
||||
db_data:
|
||||
|
||||
networks:
|
||||
app-network:
|
||||
driver: bridge
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+7
@@ -0,0 +1,7 @@
|
||||
FROM node:18-alpine
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
COPY . .
|
||||
EXPOSE 3000
|
||||
CMD ["node", "server.js"]
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "api-stock-it",
|
||||
"version": "1.0.0",
|
||||
"main": "server.js",
|
||||
"dependencies": {
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.18.2",
|
||||
"mysql2": "^3.6.0"
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
const express = require('express');
|
||||
const mysql = require('mysql2');
|
||||
const cors = require('cors');
|
||||
|
||||
const app = express();
|
||||
app.use(cors());
|
||||
app.use(express.json());
|
||||
|
||||
// Connexion à la base de données via variables d'environnement
|
||||
const db = mysql.createPool({
|
||||
host: process.env.DB_HOST || 'localhost',
|
||||
user: process.env.DB_USER || 'root',
|
||||
password: process.env.DB_PASSWORD || 'password',
|
||||
database: process.env.DB_NAME || 'stock_it'
|
||||
});
|
||||
|
||||
// Route GET à la racine : Health Check
|
||||
app.get('/', (req, res) => {
|
||||
res.json({
|
||||
status: 'OK',
|
||||
message: 'L\'API de gestion de stock est bien en ligne et fonctionnelle !',
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
});
|
||||
|
||||
// Route GET : Récupérer tout le stock
|
||||
app.get('/api/materiel', (req, res) => {
|
||||
db.query('SELECT * FROM materiel', (err, results) => {
|
||||
if (err) return res.status(500).json({ error: err.message });
|
||||
res.json(results);
|
||||
});
|
||||
});
|
||||
|
||||
// Route POST : Ajouter un nouvel équipement
|
||||
app.post('/api/materiel', (req, res) => {
|
||||
const { nom, quantite } = req.body;
|
||||
db.query('INSERT INTO materiel (nom, quantite) VALUES (?, ?)', [nom, quantite], (err, results) => {
|
||||
if (err) return res.status(500).json({ error: err.message });
|
||||
res.status(201).json({ id: results.insertId, nom, quantite });
|
||||
});
|
||||
});
|
||||
|
||||
// Route PUT : Mettre à jour la quantité d'un équipement
|
||||
app.put('/api/materiel/:id', (req, res) => {
|
||||
const { quantite } = req.body;
|
||||
db.query('UPDATE materiel SET quantite = ? WHERE id = ?', [quantite, req.params.id], (err, results) => {
|
||||
if (err) return res.status(500).json({ error: err.message });
|
||||
res.json({ message: 'Quantité mise à jour avec succès' });
|
||||
});
|
||||
});
|
||||
|
||||
// Route DELETE : Supprimer un équipement
|
||||
app.delete('/api/materiel/:id', (req, res) => {
|
||||
db.query('DELETE FROM materiel WHERE id = ?', [req.params.id], (err, results) => {
|
||||
if (err) return res.status(500).json({ error: err.message });
|
||||
res.json({ message: 'Équipement supprimé avec succès' });
|
||||
});
|
||||
});
|
||||
|
||||
const PORT = 3000;
|
||||
app.listen(PORT, () => {
|
||||
console.log(`API Backend démarrée sur le port ${PORT}`);
|
||||
});
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: mariadb-pvc
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: db-init-script
|
||||
data:
|
||||
init.sql: |
|
||||
CREATE DATABASE IF NOT EXISTS stock_it;
|
||||
USE stock_it;
|
||||
CREATE TABLE IF NOT EXISTS materiel (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
nom VARCHAR(255) NOT NULL,
|
||||
quantite INT NOT NULL
|
||||
);
|
||||
INSERT INTO materiel (nom, quantite) VALUES
|
||||
('Serveur Dell PowerEdge', 3),
|
||||
('Switch Cisco 24 ports', 5),
|
||||
('Baie de brassage', 2);
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: db-backend
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mariadb
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mariadb
|
||||
spec:
|
||||
containers:
|
||||
- name: mariadb
|
||||
image: mariadb:10.11
|
||||
resources:
|
||||
requests:
|
||||
memory: "128Mi"
|
||||
cpu: "100m"
|
||||
limits:
|
||||
memory: "256Mi"
|
||||
cpu: "250m"
|
||||
env:
|
||||
- name: MYSQL_ROOT_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-credentials
|
||||
key: root-password
|
||||
- name: MYSQL_DATABASE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: app-config
|
||||
key: db-name
|
||||
ports:
|
||||
- containerPort: 3306
|
||||
volumeMounts:
|
||||
- name: init-script-volume
|
||||
mountPath: /docker-entrypoint-initdb.d/init.sql
|
||||
subPath: init.sql
|
||||
- name: mariadb-storage
|
||||
mountPath: /var/lib/mysql
|
||||
volumes:
|
||||
- name: init-script-volume
|
||||
configMap:
|
||||
name: db-init-script
|
||||
- name: mariadb-storage
|
||||
persistentVolumeClaim:
|
||||
claimName: mariadb-pvc
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: db-service
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: mariadb
|
||||
ports:
|
||||
- port: 3306
|
||||
targetPort: 3306
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: api-backend
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: node-api
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: node-api
|
||||
spec:
|
||||
containers:
|
||||
- name: node-api
|
||||
image: gsz116/api-stock:v2
|
||||
imagePullPolicy: Always
|
||||
resources:
|
||||
requests:
|
||||
memory: "64Mi"
|
||||
cpu: "50m"
|
||||
limits:
|
||||
memory: "128Mi"
|
||||
cpu: "100m"
|
||||
env:
|
||||
- name: DB_HOST
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: app-config
|
||||
key: db-host
|
||||
- name: DB_USER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: app-config
|
||||
key: db-user
|
||||
- name: DB_NAME
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: app-config
|
||||
key: db-name
|
||||
- name: PORT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: app-config
|
||||
key: backend-port
|
||||
# Variable issue du Secret
|
||||
- name: DB_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-credentials
|
||||
key: root-password
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: api-service
|
||||
spec:
|
||||
type: NodePort
|
||||
selector:
|
||||
app: node-api
|
||||
ports:
|
||||
- port: 3000
|
||||
targetPort: 3000
|
||||
nodePort: 30001
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: web-frontend
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx-front
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx-front
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx-front
|
||||
image: gsz116/front-stock:v2
|
||||
imagePullPolicy: Always
|
||||
resources:
|
||||
requests:
|
||||
memory: "32Mi"
|
||||
cpu: "50m"
|
||||
limits:
|
||||
memory: "64Mi"
|
||||
cpu: "100m"
|
||||
env:
|
||||
- name: API_URL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: app-config
|
||||
key: api-url
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: frontend-service
|
||||
spec:
|
||||
type: NodePort
|
||||
selector:
|
||||
app: nginx-front
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 80
|
||||
nodePort: 30002
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
FROM nginx:alpine
|
||||
COPY index.html /usr/share/nginx/html/index.html
|
||||
EXPOSE 80
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Gestion de Stock IT</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
margin: 40px;
|
||||
background-color: #f4f4f9;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.container {
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
max-width: 600px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
input,
|
||||
button {
|
||||
padding: 10px;
|
||||
margin: 5px 0;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
background: #eee;
|
||||
margin: 5px 0;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>Gestion de Stock Informatique</h1>
|
||||
|
||||
<div class="container">
|
||||
<h2>Ajouter un équipement</h2>
|
||||
<form id="addForm">
|
||||
<input type="text" id="nom" placeholder="Nom du matériel (ex: Routeur MicroTik)" required>
|
||||
<input type="number" id="quantite" placeholder="Quantité" required min="1">
|
||||
<button type="submit">Ajouter au stock</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<h2>Inventaire actuel</h2>
|
||||
<ul id="stockList">Chargement du stock...</ul>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const API_URL = 'http://192.168.1.15:30001/api/materiel';
|
||||
|
||||
async function fetchStock() {
|
||||
try {
|
||||
const response = await fetch(API_URL);
|
||||
const data = await response.json();
|
||||
const list = document.getElementById('stockList');
|
||||
list.innerHTML = '';
|
||||
data.forEach(item => {
|
||||
const li = document.createElement('li');
|
||||
li.innerHTML = `
|
||||
<span><strong>${item.nom}</strong></span>
|
||||
<span>Quantité: ${item.quantite}</span>
|
||||
<div>
|
||||
<button onclick="modifierQuantite(${item.id}, ${item.quantite})" style="background-color: #ffc107; color: black; margin-right: 5px; width: auto;">Modifier</button>
|
||||
<button onclick="supprimerMateriel(${item.id})" style="background-color: #dc3545; width: auto;">Supprimer</button>
|
||||
</div>
|
||||
`;
|
||||
list.appendChild(li);
|
||||
});
|
||||
} catch (error) {
|
||||
document.getElementById('stockList').innerHTML = '<li style="color:red;">Erreur de connexion à l\'API</li>';
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('addForm').addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
const nom = document.getElementById('nom').value;
|
||||
const quantite = document.getElementById('quantite').value;
|
||||
|
||||
await fetch(API_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ nom, quantite })
|
||||
});
|
||||
|
||||
document.getElementById('nom').value = '';
|
||||
document.getElementById('quantite').value = '';
|
||||
fetchStock();
|
||||
});
|
||||
|
||||
// Nouvelle fonction : Modifier la quantité
|
||||
window.modifierQuantite = async (id, ancienneQuantite) => {
|
||||
const nouvelleQuantite = prompt("Entrez la nouvelle quantité :", ancienneQuantite);
|
||||
|
||||
// Si l'utilisateur n'a pas annulé et a entré un nombre valide
|
||||
if (nouvelleQuantite !== null && nouvelleQuantite !== "" && !isNaN(nouvelleQuantite)) {
|
||||
await fetch(`${API_URL}/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ quantite: nouvelleQuantite })
|
||||
});
|
||||
fetchStock(); // Rafraîchit la liste
|
||||
}
|
||||
};
|
||||
|
||||
// Nouvelle fonction : Supprimer un matériel
|
||||
window.supprimerMateriel = async (id) => {
|
||||
if (confirm("Êtes-vous sûr de vouloir supprimer ce matériel de l'inventaire ?")) {
|
||||
await fetch(`${API_URL}/${id}`, {
|
||||
method: 'DELETE'
|
||||
});
|
||||
fetchStock(); // Rafraîchit la liste
|
||||
}
|
||||
};
|
||||
|
||||
// Charger le stock au démarrage
|
||||
fetchStock();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
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.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user