eaglelandsonce commited on
Commit
9e86e95
·
verified ·
1 Parent(s): ded2f07

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +24 -13
app.py CHANGED
@@ -5,6 +5,7 @@ import re
5
  import networkx as nx
6
  import matplotlib.pyplot as plt
7
  import io
 
8
 
9
  # Mock existing resources (customizable)
10
  existing_resources = {
@@ -45,6 +46,7 @@ arm_schema = {
45
  "required": ["$schema", "contentVersion", "resources"]
46
  }
47
 
 
48
  def validate_template(template):
49
  try:
50
  validate(instance=template, schema=arm_schema)
@@ -52,6 +54,7 @@ def validate_template(template):
52
  except ValidationError as e:
53
  return False, f"Template validation error: {e.message}"
54
 
 
55
  def resolve_template_expressions(template):
56
  def resolve_expression(match):
57
  expr = match.group(1)
@@ -66,6 +69,7 @@ def resolve_template_expressions(template):
66
  resolved_str = re.sub(r'\[(\w+\.\w+)\]', resolve_expression, template_str)
67
  return json.loads(resolved_str)
68
 
 
69
  def estimate_cost(resources):
70
  # This is a simplified cost estimation. In a real scenario, you'd need to
71
  # integrate with Azure's pricing API or use a more comprehensive pricing model.
@@ -87,6 +91,7 @@ def estimate_cost(resources):
87
 
88
  return total_cost
89
 
 
90
  def create_dependency_graph(resources):
91
  G = nx.DiGraph()
92
  for resource in resources:
@@ -97,6 +102,7 @@ def create_dependency_graph(resources):
97
  G.add_edge(dep, resource_name)
98
  return G
99
 
 
100
  def plot_dependency_graph(G):
101
  plt.figure(figsize=(12, 8))
102
  pos = nx.spring_layout(G)
@@ -107,6 +113,7 @@ def plot_dependency_graph(G):
107
  plt.title("Resource Dependency Graph")
108
  return plt
109
 
 
110
  def lint_template(template):
111
  lint_results = []
112
 
@@ -128,26 +135,30 @@ def lint_template(template):
128
 
129
  return lint_results
130
 
 
131
  def generate_system_diagram(resources):
132
- diagram = ["graph TD"]
133
- resource_nodes = {}
134
-
 
135
  # Create nodes for each resource
136
  for i, resource in enumerate(resources):
137
  resource_type = resource['type'].split('/')[-1]
138
  node_id = f"R{i}"
139
- resource_nodes[resource['name']] = node_id
140
- diagram.append(f"{node_id}[{resource_type}<br/>{resource['name']}]")
141
-
142
  # Create connections based on dependencies
143
  for resource in resources:
144
  if 'dependsOn' in resource:
145
  for dependency in resource['dependsOn']:
146
- if dependency in resource_nodes:
147
- diagram.append(f"{resource_nodes[dependency]} --> {resource_nodes[resource['name']]}")
148
-
149
- return "\n".join(diagram)
 
 
150
 
 
151
  def simulate_deployment(arm_template):
152
  try:
153
  template = json.loads(arm_template)
@@ -155,7 +166,7 @@ def simulate_deployment(arm_template):
155
  # Validate template
156
  is_valid, validation_message = validate_template(template)
157
  if not is_valid:
158
- return [], [], [], [], 0, None, [], "", validation_message
159
 
160
  # Resolve expressions
161
  resolved_template = resolve_template_expressions(template)
@@ -208,7 +219,7 @@ def simulate_deployment(arm_template):
208
 
209
  return resources_to_create, resources_to_update, resources_to_delete, resource_details, estimated_cost, dependency_graph, lint_results, system_diagram, "Simulation completed successfully."
210
  except json.JSONDecodeError:
211
- return [], [], [], [], 0, None, [], "", "Invalid JSON format. Please check your ARM template."
212
 
213
  # Streamlit UI
214
  st.title("Comprehensive ARM Template Simulator")
@@ -284,7 +295,7 @@ if st.button("Simulate Template"):
284
 
285
  st.write("### System Diagram:")
286
  if system_diagram:
287
- st.mermaid(system_diagram)
288
  else:
289
  st.write("Unable to generate system diagram.")
290
 
 
5
  import networkx as nx
6
  import matplotlib.pyplot as plt
7
  import io
8
+ import graphviz
9
 
10
  # Mock existing resources (customizable)
11
  existing_resources = {
 
46
  "required": ["$schema", "contentVersion", "resources"]
47
  }
48
 
49
+ # Function to validate the ARM template against the schema
50
  def validate_template(template):
51
  try:
52
  validate(instance=template, schema=arm_schema)
 
54
  except ValidationError as e:
55
  return False, f"Template validation error: {e.message}"
56
 
57
+ # Function to resolve template expressions (like parameters and variables)
58
  def resolve_template_expressions(template):
59
  def resolve_expression(match):
60
  expr = match.group(1)
 
69
  resolved_str = re.sub(r'\[(\w+\.\w+)\]', resolve_expression, template_str)
70
  return json.loads(resolved_str)
71
 
72
+ # Function to estimate the cost of resources
73
  def estimate_cost(resources):
74
  # This is a simplified cost estimation. In a real scenario, you'd need to
75
  # integrate with Azure's pricing API or use a more comprehensive pricing model.
 
91
 
92
  return total_cost
93
 
94
+ # Function to create a dependency graph of resources
95
  def create_dependency_graph(resources):
96
  G = nx.DiGraph()
97
  for resource in resources:
 
102
  G.add_edge(dep, resource_name)
103
  return G
104
 
105
+ # Function to plot the dependency graph
106
  def plot_dependency_graph(G):
107
  plt.figure(figsize=(12, 8))
108
  pos = nx.spring_layout(G)
 
113
  plt.title("Resource Dependency Graph")
114
  return plt
115
 
116
+ # Function to lint the ARM template
117
  def lint_template(template):
118
  lint_results = []
119
 
 
135
 
136
  return lint_results
137
 
138
+ # Function to generate a system diagram
139
  def generate_system_diagram(resources):
140
+ # Create a new Graphviz graph
141
+ dot = graphviz.Digraph()
142
+ dot.attr(rankdir='TB') # Top to bottom layout
143
+
144
  # Create nodes for each resource
145
  for i, resource in enumerate(resources):
146
  resource_type = resource['type'].split('/')[-1]
147
  node_id = f"R{i}"
148
+ dot.node(node_id, f"{resource_type}\n{resource['name']}")
149
+
 
150
  # Create connections based on dependencies
151
  for resource in resources:
152
  if 'dependsOn' in resource:
153
  for dependency in resource['dependsOn']:
154
+ # Find the node id for the dependency
155
+ dep_id = next((f"R{j}" for j, r in enumerate(resources) if r['name'] == dependency), None)
156
+ if dep_id:
157
+ dot.edge(dep_id, f"R{resources.index(resource)}")
158
+
159
+ return dot
160
 
161
+ # Main function to simulate the deployment
162
  def simulate_deployment(arm_template):
163
  try:
164
  template = json.loads(arm_template)
 
166
  # Validate template
167
  is_valid, validation_message = validate_template(template)
168
  if not is_valid:
169
+ return [], [], [], [], 0, None, [], None, validation_message
170
 
171
  # Resolve expressions
172
  resolved_template = resolve_template_expressions(template)
 
219
 
220
  return resources_to_create, resources_to_update, resources_to_delete, resource_details, estimated_cost, dependency_graph, lint_results, system_diagram, "Simulation completed successfully."
221
  except json.JSONDecodeError:
222
+ return [], [], [], [], 0, None, [], None, "Invalid JSON format. Please check your ARM template."
223
 
224
  # Streamlit UI
225
  st.title("Comprehensive ARM Template Simulator")
 
295
 
296
  st.write("### System Diagram:")
297
  if system_diagram:
298
+ st.graphviz_chart(system_diagram)
299
  else:
300
  st.write("Unable to generate system diagram.")
301