-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdevops_exercise1.py
More file actions
209 lines (170 loc) · 9.28 KB
/
devops_exercise1.py
File metadata and controls
209 lines (170 loc) · 9.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
"""
EXERCICE 1 — Décision de déploiement en production
Contexte :
- Une équipe DevOps doit décider si un déploiement peut être effectué en production
- Plusieurs signaux techniques et organisationnels sont disponibles
- Leur fiabilité varie
Question : L'agent doit déterminer s'il est approprié de déployer en production à l'instant T.
Éléments observables :
- Le code a été fusionné dans la branche principale
- Les tests automatisés ont un état partiellement connu
- Les scans de sécurité ont un état partiellement connu
- La stabilité de l'infrastructure n'est pas totalement confirmée
- Une validation humaine peut être présente
"""
from 03_domains.devops.agents.devops_agent import DevOpsAgent
from 03_domains.devops.agents.export import export_devops_decision
from 01_core_engine.reasoning.export import export_to_json_file
from 01_core_engine.graph.types import ReasoningStatus
from datetime import datetime
def format_time():
"""Retourne l'heure actuelle formatée."""
return datetime.now().strftime("%H:%M")
def exercise1_deployment_decision():
"""Exercice 1 : Décision de déploiement en production."""
print("=" * 70)
print("EXERCICE 1 — DECISION DE DEPLOIEMENT EN PRODUCTION")
print("=" * 70)
print("\nContexte :")
print(" - Equipe DevOps doit decider si un deploiement peut etre effectue")
print(" - Plusieurs signaux techniques et organisationnels disponibles")
print(" - Fiabilite des signaux varie")
print("\nQuestion :")
print(" L'agent doit determiner s'il est approprie de deployer en production a l'instant T.")
print("\nElements observables :")
print(" - Code fusionne dans la branche principale")
print(" - Tests automaties : etat partiellement connu")
print(" - Scans de securite : etat partiellement connu")
print(" - Stabilite infrastructure : pas totalement confirmee")
print(" - Validation humaine : peut etre presente")
# Historique des décisions
decisions_history = []
# ============================================================
# SCÉNARIO 1 : État initial (signaux partiellement connus)
# ============================================================
print("\n" + "=" * 70)
print("SCENARIO 1 : ETAT INITIAL (SIGNAUX PARTIELLEMENT CONNUS)")
print("=" * 70)
agent = DevOpsAgent(threshold=0.8, policy="strict")
# Afficher l'état initial
status = agent.get_deployment_status()
print("\nEtat des signaux :")
for node_id, node_info in status.items():
status_icon = "[OK]" if node_info["status"] == "proven" else "[?]"
print(f" {status_icon} {node_id}: {node_info['content']} ({node_info['status']})")
# Évaluer la décision
result1 = agent.can_deploy()
label1 = f"{format_time()} - Initial state"
decisions_history.append({"label": label1, "result": result1})
print(f"\nDecision :")
print(f" - Statut : {result1.get('status', 'unknown')}")
print(f" - Decision : {result1.get('decision', 'No decision')}")
print(f" - Niveau de risque : {result1.get('devops_context', {}).get('risk_level', 'unknown')}")
print(f" - Recommandation : {result1.get('devops_context', {}).get('recommendation', '')}")
print(f" - Justification : {result1.get('justification', '')[:100]}...")
# ============================================================
# SCÉNARIO 2 : Tests confirmés (mais sécurité incertaine)
# ============================================================
print("\n" + "=" * 70)
print("SCENARIO 2 : TESTS CONFIRMES (SECURITE INCERTAINE)")
print("=" * 70)
# Simuler : Tests passés
what_if_result2 = agent.simulate_what_if({"B": ReasoningStatus.PROVEN})
label2 = f"{format_time()} - Tests confirmed"
decisions_history.append({"label": label2, "result": what_if_result2})
print("\nApres confirmation des tests :")
print(f" - Statut : {what_if_result2.get('status', 'unknown')}")
print(f" - Decision : {what_if_result2.get('decision', 'No decision')}")
print(f" - Niveau de risque : {what_if_result2.get('devops_context', {}).get('risk_level', 'unknown')}")
print(f" - Recommandation : {what_if_result2.get('devops_context', {}).get('recommendation', '')}")
# ============================================================
# SCÉNARIO 3 : Tests + Sécurité confirmés (infra incertaine)
# ============================================================
print("\n" + "=" * 70)
print("SCENARIO 3 : TESTS + SECURITE CONFIRMES (INFRA INCERTAINE)")
print("=" * 70)
what_if_result3 = agent.simulate_what_if({
"B": ReasoningStatus.PROVEN,
"C": ReasoningStatus.PROVEN
})
label3 = f"{format_time()} - Tests + Security confirmed"
decisions_history.append({"label": label3, "result": what_if_result3})
print("\nApres confirmation Tests + Securite :")
print(f" - Statut : {what_if_result3.get('status', 'unknown')}")
print(f" - Decision : {what_if_result3.get('decision', 'No decision')}")
print(f" - Niveau de risque : {what_if_result3.get('devops_context', {}).get('risk_level', 'unknown')}")
print(f" - Recommandation : {what_if_result3.get('devops_context', {}).get('recommendation', '')}")
# ============================================================
# SCÉNARIO 4 : Tous les signaux confirmés
# ============================================================
print("\n" + "=" * 70)
print("SCENARIO 4 : TOUS LES SIGNAUX CONFIRMES")
print("=" * 70)
what_if_result4 = agent.simulate_what_if({
"B": ReasoningStatus.PROVEN,
"C": ReasoningStatus.PROVEN,
"D": ReasoningStatus.PROVEN
})
label4 = f"{format_time()} - All signals confirmed"
decisions_history.append({"label": label4, "result": what_if_result4})
print("\nApres confirmation de tous les signaux :")
print(f" - Statut : {what_if_result4.get('status', 'unknown')}")
print(f" - Decision : {what_if_result4.get('decision', 'No decision')}")
print(f" - Niveau de risque : {what_if_result4.get('devops_context', {}).get('risk_level', 'unknown')}")
print(f" - Recommandation : {what_if_result4.get('devops_context', {}).get('recommendation', '')}")
# ============================================================
# SCÉNARIO 5 : Validation humaine seule (sans autres signaux)
# ============================================================
print("\n" + "=" * 70)
print("SCENARIO 5 : VALIDATION HUMAINE SEULE (SANS AUTRES SIGNAUX)")
print("=" * 70)
# Créer un nouvel agent avec seulement l'approbation manuelle
agent2 = DevOpsAgent(threshold=0.8, policy="strict")
# E est déjà PROVEN par défaut, mais B, C, D sont UNCERTAIN
what_if_result5 = agent2.can_deploy() # État initial
label5 = f"{format_time()} - Manual approval only"
decisions_history.append({"label": label5, "result": what_if_result5})
print("\nAvec seulement validation humaine (E PROVEN) :")
print(f" - Statut : {what_if_result5.get('status', 'unknown')}")
print(f" - Decision : {what_if_result5.get('decision', 'No decision')}")
print(f" - Niveau de risque : {what_if_result5.get('devops_context', {}).get('risk_level', 'unknown')}")
print(f" - Justification : {what_if_result5.get('justification', '')[:100]}...")
# ============================================================
# EXPORT POUR VISUALISATION
# ============================================================
print("\n" + "=" * 70)
print("EXPORT POUR VISUALISATION")
print("=" * 70)
try:
from pathlib import Path
# Utiliser le dernier résultat pour l'export principal
export_data = export_devops_decision(agent.graph, what_if_result4, history=decisions_history)
json_path = Path("03_domains/devops/visualizations/devops_exercise1_data.json")
json_path.parent.mkdir(parents=True, exist_ok=True)
export_to_json_file(export_data, str(json_path))
if json_path.exists():
file_size = json_path.stat().st_size
print(f"\n[OK] Donnees exportees vers {json_path}")
print(f" Taille: {file_size} octets")
print(f" Historique: {len(decisions_history)} decisions")
else:
print(f"\n[ERREUR] Le fichier {json_path} n'a pas ete cree")
except Exception as e:
print(f"\n[ERREUR] Impossible d'exporter les donnees: {e}")
import traceback
traceback.print_exc()
# ============================================================
# RÉSUMÉ DES APPRENTISSAGES
# ============================================================
print("\n" + "=" * 70)
print("RESUME DES APPRENTISSAGES")
print("=" * 70)
print("\nL'agent de deploiement :")
print(" [OK] Refuse le deploiement si signaux insuffisants (policy strict)")
print(" [OK] Accepte seulement si au moins 3 signaux decisionnels PROVEN")
print(" [OK] Un seul signal (validation humaine) ne suffit pas")
print(" [OK] Les signaux partiellement connus (UNCERTAIN) bloquent la decision")
print(" [OK] La convergence de plusieurs signaux est necessaire pour deployer")
print("\n" + "=" * 70)
if __name__ == "__main__":
exercise1_deployment_decision()