eaglelandsonce commited on
Commit
9d94cf5
·
verified ·
1 Parent(s): f7f94f6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +112 -38
app.py CHANGED
@@ -1,56 +1,118 @@
1
  import streamlit as st
2
  import json
 
 
3
 
4
- # Simulate some mock existing resources (you can customize this)
5
  existing_resources = {
6
  "storageAccount1": {
7
  "type": "Microsoft.Storage/storageAccounts",
8
  "location": "East US",
9
- "status": "existing"
 
 
 
10
  }
11
  }
12
 
13
- # Function to simulate ARM template deployment evaluation
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  def simulate_deployment(arm_template):
15
  try:
16
- # Load ARM template from pasted JSON
17
  template = json.loads(arm_template)
18
 
19
- # Initialize lists for tracking resources to be created, updated, or deleted
 
 
 
 
 
 
 
20
  resources_to_create = []
21
  resources_to_update = []
22
  resources_to_delete = []
 
23
 
24
- # Check the resources in the template
25
- for resource in template.get('resources', []):
26
  resource_name = resource.get('name')
27
  resource_type = resource.get('type')
28
  location = resource.get('location')
 
29
 
30
- # Simulate creation or update
31
  if resource_name in existing_resources:
32
- if (existing_resources[resource_name]['type'] == resource_type
33
- and existing_resources[resource_name]['location'] == location):
 
 
34
  resources_to_update.append(resource_name)
35
  else:
36
- resources_to_create.append(resource_name) # Re-create if major properties change
37
  else:
38
  resources_to_create.append(resource_name)
39
 
40
- # Simulate deletion (if something in the template isn't in the mock cloud)
 
 
 
 
 
 
41
  for resource_name in existing_resources:
42
- if resource_name not in [r.get('name') for r in template.get('resources', [])]:
43
  resources_to_delete.append(resource_name)
44
 
45
- # Return results
46
- return resources_to_create, resources_to_update, resources_to_delete
47
-
48
  except json.JSONDecodeError:
49
- st.error("Invalid JSON format. Please check your ARM template.")
50
- return [], [], []
51
 
52
  # Streamlit UI
53
- st.title("ARM Template Simulator")
54
  st.subheader("Paste your ARM template below to simulate its deployment.")
55
 
56
  # Input box for ARM template
@@ -59,27 +121,39 @@ template_input = st.text_area("Paste ARM Template JSON here:", height=300)
59
  # Button to simulate the evaluation
60
  if st.button("Simulate Template"):
61
  if template_input:
62
- resources_to_create, resources_to_update, resources_to_delete = simulate_deployment(template_input)
63
-
64
- # Display results
65
- st.subheader("Simulation Results:")
66
 
67
- st.write("### Resources to be Created:")
68
- if resources_to_create:
69
- st.write(resources_to_create)
70
- else:
71
- st.write("No new resources will be created.")
72
 
73
- st.write("### Resources to be Updated:")
74
- if resources_to_update:
75
- st.write(resources_to_update)
76
- else:
77
- st.write("No resources will be updated.")
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
- st.write("### Resources to be Deleted:")
80
- if resources_to_delete:
81
- st.write(resources_to_delete)
 
 
 
 
 
82
  else:
83
- st.write("No resources will be deleted.")
84
  else:
85
- st.error("Please paste an ARM template to simulate.")
 
1
  import streamlit as st
2
  import json
3
+ from jsonschema import validate, ValidationError
4
+ import re
5
 
6
+ # Mock existing resources (customizable)
7
  existing_resources = {
8
  "storageAccount1": {
9
  "type": "Microsoft.Storage/storageAccounts",
10
  "location": "East US",
11
+ "status": "existing",
12
+ "properties": {
13
+ "accountType": "Standard_LRS"
14
+ }
15
  }
16
  }
17
 
18
+ # ARM template schema (simplified version)
19
+ arm_schema = {
20
+ "type": "object",
21
+ "properties": {
22
+ "$schema": {"type": "string"},
23
+ "contentVersion": {"type": "string"},
24
+ "parameters": {"type": "object"},
25
+ "variables": {"type": "object"},
26
+ "resources": {
27
+ "type": "array",
28
+ "items": {
29
+ "type": "object",
30
+ "required": ["type", "name", "location"],
31
+ "properties": {
32
+ "type": {"type": "string"},
33
+ "name": {"type": "string"},
34
+ "location": {"type": "string"},
35
+ "properties": {"type": "object"}
36
+ }
37
+ }
38
+ },
39
+ "outputs": {"type": "object"}
40
+ },
41
+ "required": ["$schema", "contentVersion", "resources"]
42
+ }
43
+
44
+ def validate_template(template):
45
+ try:
46
+ validate(instance=template, schema=arm_schema)
47
+ return True, "Template is valid."
48
+ except ValidationError as e:
49
+ return False, f"Template validation error: {e.message}"
50
+
51
+ def resolve_template_expressions(template):
52
+ def resolve_expression(match):
53
+ expr = match.group(1)
54
+ parts = expr.split('.')
55
+ if parts[0] == 'parameters':
56
+ return str(template.get('parameters', {}).get(parts[1], {}).get('defaultValue', ''))
57
+ elif parts[0] == 'variables':
58
+ return str(template.get('variables', {}).get(parts[1], ''))
59
+ return match.group(0)
60
+
61
+ template_str = json.dumps(template)
62
+ resolved_str = re.sub(r'\[(\w+\.\w+)\]', resolve_expression, template_str)
63
+ return json.loads(resolved_str)
64
+
65
  def simulate_deployment(arm_template):
66
  try:
 
67
  template = json.loads(arm_template)
68
 
69
+ # Validate template
70
+ is_valid, validation_message = validate_template(template)
71
+ if not is_valid:
72
+ return [], [], [], validation_message
73
+
74
+ # Resolve expressions
75
+ resolved_template = resolve_template_expressions(template)
76
+
77
  resources_to_create = []
78
  resources_to_update = []
79
  resources_to_delete = []
80
+ resource_details = []
81
 
82
+ for resource in resolved_template.get('resources', []):
 
83
  resource_name = resource.get('name')
84
  resource_type = resource.get('type')
85
  location = resource.get('location')
86
+ properties = resource.get('properties', {})
87
 
 
88
  if resource_name in existing_resources:
89
+ existing = existing_resources[resource_name]
90
+ if (existing['type'] == resource_type and
91
+ existing['location'] == location and
92
+ existing['properties'] == properties):
93
  resources_to_update.append(resource_name)
94
  else:
95
+ resources_to_create.append(resource_name)
96
  else:
97
  resources_to_create.append(resource_name)
98
 
99
+ resource_details.append({
100
+ "name": resource_name,
101
+ "type": resource_type,
102
+ "location": location,
103
+ "properties": properties
104
+ })
105
+
106
  for resource_name in existing_resources:
107
+ if resource_name not in [r.get('name') for r in resolved_template.get('resources', [])]:
108
  resources_to_delete.append(resource_name)
109
 
110
+ return resources_to_create, resources_to_update, resources_to_delete, resource_details, "Simulation completed successfully."
 
 
111
  except json.JSONDecodeError:
112
+ return [], [], [], [], "Invalid JSON format. Please check your ARM template."
 
113
 
114
  # Streamlit UI
115
+ st.title("Enhanced ARM Template Simulator")
116
  st.subheader("Paste your ARM template below to simulate its deployment.")
117
 
118
  # Input box for ARM template
 
121
  # Button to simulate the evaluation
122
  if st.button("Simulate Template"):
123
  if template_input:
124
+ resources_to_create, resources_to_update, resources_to_delete, resource_details, message = simulate_deployment(template_input)
 
 
 
125
 
126
+ st.subheader("Simulation Results:")
127
+ st.write(message)
 
 
 
128
 
129
+ if resources_to_create or resources_to_update or resources_to_delete:
130
+ st.write("### Resources to be Created:")
131
+ if resources_to_create:
132
+ st.write(resources_to_create)
133
+ else:
134
+ st.write("No new resources will be created.")
135
+
136
+ st.write("### Resources to be Updated:")
137
+ if resources_to_update:
138
+ st.write(resources_to_update)
139
+ else:
140
+ st.write("No resources will be updated.")
141
+
142
+ st.write("### Resources to be Deleted:")
143
+ if resources_to_delete:
144
+ st.write(resources_to_delete)
145
+ else:
146
+ st.write("No resources will be deleted.")
147
 
148
+ st.write("### Detailed Resource Information:")
149
+ for resource in resource_details:
150
+ st.write(f"**Name:** {resource['name']}")
151
+ st.write(f"**Type:** {resource['type']}")
152
+ st.write(f"**Location:** {resource['location']}")
153
+ st.write("**Properties:**")
154
+ st.json(resource['properties'])
155
+ st.write("---")
156
  else:
157
+ st.write("No changes detected in the simulation.")
158
  else:
159
+ st.error("Please paste an ARM template to simulate.")