Skip to content

Commit 5426733

Browse files
committed
Add diagnostics and potential changes to what-if output
1 parent 1f27224 commit 5426733

File tree

2 files changed

+76
-16
lines changed

2 files changed

+76
-16
lines changed

src/azure-cli/azure/cli/command_modules/resource/_color.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ class Color(Enum):
1313
PURPLE = "\033[38;5;141m"
1414
BLUE = "\033[38;5;39m"
1515
GRAY = "\033[38;5;246m"
16+
RED = "\033[38;5;203m"
17+
DARK_YELLOW = "\033[38;5;136m"
1618
RESET = "\033[0m"
1719

1820
def __str__(self):

src/azure-cli/azure/cli/command_modules/resource/_formatters.py

Lines changed: 74 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from itertools import groupby
77

8-
from azure.mgmt.resource.resources.models import ChangeType, PropertyChangeType
8+
from azure.mgmt.resource.resources.models import ChangeType, PropertyChangeType, Level
99

1010
from ._symbol import Symbol
1111
from ._color import Color, ColoredStringBuilder
@@ -30,6 +30,12 @@
3030
PropertyChangeType.no_effect: Color.GRAY,
3131
}
3232

33+
_diagnostic_level_to_color = {
34+
Level.ERROR: Color.RED,
35+
Level.WARNING: Color.DARK_YELLOW,
36+
Level.INFO: Color.RESET,
37+
}
38+
3339
_change_type_to_symbol = {
3440
ChangeType.create: Symbol.PLUS,
3541
ChangeType.delete: Symbol.MINUS,
@@ -73,8 +79,22 @@ def format_what_if_operation_result(what_if_operation_result, enable_color=True)
7379
builder = ColoredStringBuilder(enable_color)
7480
_format_noise_notice(builder)
7581
_format_change_type_legend(builder, what_if_operation_result.changes)
76-
_format_resource_changes(builder, what_if_operation_result.changes)
77-
_format_resource_changes_stats(builder, what_if_operation_result.changes)
82+
_format_resource_changes(builder,
83+
what_if_operation_result.changes,
84+
definite_changes=True)
85+
_format_resource_changes_stats(builder,
86+
what_if_operation_result.changes,
87+
definite_changes=True)
88+
_format_resource_changes(builder,
89+
what_if_operation_result.potential_changes,
90+
definite_changes=False)
91+
_format_resource_changes_stats(builder,
92+
what_if_operation_result.potential_changes,
93+
definite_changes=False)
94+
_format_diagnostics(builder,
95+
what_if_operation_result.changes,
96+
what_if_operation_result.potential_changes,
97+
what_if_operation_result.diagnostics)
7898
return builder.build()
7999

80100

@@ -120,20 +140,24 @@ def populate_change_type_set(property_changes):
120140
builder.append_line(change_type.title())
121141

122142

123-
def _format_resource_changes_stats(builder, resource_changes):
124-
builder.append_line().append("Resource changes: ")
143+
def _format_resource_changes_stats(builder, resource_changes, definite_changes = True):
144+
if definite_changes:
145+
builder.append_line().append("Resource changes: ")
125146

126-
if not resource_changes:
127-
builder.append("no change.")
128-
return
147+
if not resource_changes:
148+
builder.append("no change.")
149+
return
150+
elif resource_changes:
151+
builder.append_line().append("Potential changes: ")
129152

130-
sorted_resource_changes = sorted(resource_changes, key=lambda x: _change_type_to_weight[x.change_type])
131-
resource_changes_by_change_type = groupby(sorted_resource_changes, lambda x: x.change_type)
132-
count_by_change_type = map(lambda x: (x[0], len(list(x[1]))), resource_changes_by_change_type)
133-
count_by_change_type = filter(lambda x: x[1] > 0, count_by_change_type)
134-
change_type_stats = map(lambda x: _format_change_type_count(x[0], x[1]), count_by_change_type)
153+
if resource_changes:
154+
sorted_resource_changes = sorted(resource_changes, key=lambda x: _change_type_to_weight[x.change_type])
155+
resource_changes_by_change_type = groupby(sorted_resource_changes, lambda x: x.change_type)
156+
count_by_change_type = map(lambda x: (x[0], len(list(x[1]))), resource_changes_by_change_type)
157+
count_by_change_type = filter(lambda x: x[1] > 0, count_by_change_type)
158+
change_type_stats = map(lambda x: _format_change_type_count(x[0], x[1]), count_by_change_type)
135159

136-
builder.append(", ".join(change_type_stats)).append(".")
160+
builder.append(", ".join(change_type_stats)).append(".")
137161

138162

139163
def _format_change_type_count(change_type, count): # pylint: disable=too-many-return-statements
@@ -155,15 +179,49 @@ def _format_change_type_count(change_type, count): # pylint: disable=too-many-r
155179
raise ValueError(f"Invalid ChangeType: {change_type}")
156180

157181

158-
def _format_resource_changes(builder, resource_changes):
182+
def _format_diagnostics(builder, resource_changes, potential_changes, diagnostics):
183+
short_circuited_resources = [r for r in (resource_changes or []) + (potential_changes or [])
184+
if r.change_type == ChangeType.UNSUPPORTED]
185+
186+
diags = diagnostics or []
187+
188+
if len(short_circuited_resources) + len(diags) > 0:
189+
builder.append_line()
190+
builder.append_line()
191+
builder.append(f"Diagnostics ({len(short_circuited_resources) + len(diags)}): ")
192+
builder.append_line()
193+
194+
for change in short_circuited_resources:
195+
with builder.new_color_scope(_diagnostic_level_to_color[Level.WARNING]):
196+
builder.append(change.resource_id)
197+
builder.append(" (Unsupported) ")
198+
builder.append(change.unsupported_reason)
199+
builder.append_line()
200+
201+
for diag in diags:
202+
with builder.new_color_scope(_diagnostic_level_to_color[diag.level]):
203+
builder.append(diag.target)
204+
builder.append(" (")
205+
builder.append(diag.code)
206+
builder.append(") ")
207+
builder.append(diag.message)
208+
builder.append_line()
209+
210+
211+
def _format_resource_changes(builder, resource_changes, definite_changes = True):
159212
if not resource_changes:
160213
return
161214

162215
num_scopes = len(set(map(_get_scope_uppercase, resource_changes)))
163216
resource_changes_by_scope = groupby(sorted(resource_changes, key=_get_scope_uppercase), _get_scope_uppercase)
164217

165218
builder.append_line()
166-
builder.append_line(f"The deployment will update the following {'scope:' if num_scopes == 1 else 'scopes'}")
219+
if definite_changes:
220+
builder.append("The deployment will update the following ")
221+
else:
222+
builder.append("The following change MAY OR MAY NOT be deployed to the following ")
223+
224+
builder.append_line('scope:' if num_scopes == 1 else 'scopes:')
167225

168226
for _, resource_changes_in_scope in resource_changes_by_scope:
169227
resource_changes_in_scope_list = list(resource_changes_in_scope)

0 commit comments

Comments
 (0)