Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,17 @@ class DeploymentStacksWhatIfResultFormatter: # pylint: disable=too-few-public-m
StackModels.DeploymentStacksDiagnosticLevel.ERROR: Color.RED,
})

# These properties are redundant with the overall presentation of the resource
EXCLUDED_RESOURCE_TOP_LEVEL_PROPERTIES_FOR_PROPERTY_CHANGE_RENDERING = [
"apiVersion",
"extension",
"id",
"identifiers",
"name",
"resourceGroup",
"type"
]

def __init__(self, enable_color=True):
self.builder: ColoredStringBuilder = ColoredStringBuilder(enable_color)
self.what_if_result: t.Optional[StackModels.DeploymentStacksWhatIfResult] = None
Expand Down Expand Up @@ -226,7 +237,7 @@ def _format_resource_change(self, resource_change: StackModels.DeploymentStacksW
self._format_change(change, path)

# print resource property changes
self._format_resource_property_changes(resource_change.resource_configuration_changes)
self._format_resource_property_changes(resource_change)
self._pop_indent()

return True
Expand Down Expand Up @@ -296,19 +307,49 @@ def _format_resource_heading_line(self, resource_change: StackModels.DeploymentS
self.builder.append_line(f"{resource_id}{api_version_suffix}", color)

def _format_resource_property_changes(
self, property_changes: t.Optional[StackModels.DeploymentStacksChangeDeltaRecord]
self, resource_change: StackModels.DeploymentStacksWhatIfResourceChange
) -> bool:
if not property_changes or not property_changes.delta:
property_changes = resource_change.resource_configuration_changes

if not property_changes:
return False

printed = False

for property_change in property_changes.delta:
if self._format_change(property_change):
printed = True
before_or_after = None
if str_lower_eq(resource_change.change_type, StackModels.DeploymentStacksWhatIfChangeType.CREATE):
before_or_after = property_changes.after
elif str_lower_eq(resource_change.change_type, StackModels.DeploymentStacksWhatIfChangeType.DELETE):
before_or_after = property_changes.before

if before_or_after:
property_keys = self._get_filtered_resource_top_level_property_keys(before_or_after)

for key in property_keys:
if self._format_inline_json(resource_change.change_type, before_or_after.get(key, None), key):
printed = True
else:
if not property_changes.delta:
return False

for property_change in property_changes.delta:
if self._format_change(property_change):
printed = True

return printed

def _get_filtered_resource_top_level_property_keys(
self,
before_or_after: t.Optional[dict[str, t.Any]]
) -> list[str]:
if not before_or_after:
return []

return sorted([
key for key, value in before_or_after.items()
if key not in self.EXCLUDED_RESOURCE_TOP_LEVEL_PROPERTIES_FOR_PROPERTY_CHANGE_RENDERING
], key=lambda k: (k == "properties", k))

def _format_diagnostics(self) -> bool:
if not self.what_if_props or not self.what_if_props.diagnostics or len(self.what_if_props.diagnostics) == 0:
return False
Expand Down Expand Up @@ -407,16 +448,28 @@ def _format_inline_object_change(
is_array_item: bool = False
) -> bool:
inline_obj = change.after if change.after is not None else change.before
property_path = self._get_change_path(change, parent_path)

return self._format_inline_json(change.change_type, inline_obj, property_path, is_array_item=is_array_item)

def _format_inline_json(
self,
change_type: t.Union[StackModels.DeploymentStacksWhatIfPropertyChangeType, str],
inline_obj: t.Any,
property_path: t.Optional[str] = None,
is_array_item: bool = False
) -> bool:
if inline_obj is None:
return False

symbol, color = self._get_change_type_formatting(change.change_type)
symbol, color = self._get_change_type_formatting(change_type)

if not is_array_item:
property_path = self._get_change_path(change, parent_path)
self.builder.append(symbol, color)
self.builder.append(f" {property_path}: ")
if property_path:
self.builder.append(f" {property_path}: ")
else:
self.builder.append(" ")

self._push_indent()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,6 @@
},
"resourceConfigurationChanges": {
"before": {
"extension": {
Comment thread
kalbert312 marked this conversation as resolved.
"name": "Contoso",
"version": "2.0.0"
},
"identifiers": {
"name": "defResource"
},
"type": "Contoso/example",
"properties": {
"property1": "resourceDef-before"
Expand Down Expand Up @@ -138,11 +131,6 @@
"resourceConfigurationChanges": {
"before": null,
"after": {
"extension": {
"name": "Contoso",
"version": "2.0.0"
},
"identifiers": null,
"type": "Contoso/noPreview",
"properties": {
"property1": "noPreview-after"
Expand Down Expand Up @@ -174,27 +162,13 @@
"resourceConfigurationChanges": {
"before": {
"apiVersion": "v1",
"extension": {
"name": "Contoso",
"version": "2.0.0"
},
"identifiers": {
"name": "abcResource"
},
"type": "Contoso/example",
"properties": {
"property1": "abcResource-before"
}
},
"after": {
"apiVersion": "v1",
"extension": {
"name": "Contoso",
"version": "2.0.0"
},
"identifiers": {
"name": "abcResource"
},
"type": "Contoso/example",
"properties": {
"property1": "abcResource-after"
Expand Down Expand Up @@ -398,11 +372,6 @@
"before": null,
"after": {
"apiVersion": "v1",
"extension": {
"name": "Kubernetes",
"version": "2.0.0",
"configId": "kubeConfigHash"
},
"type": "app/Deployment",
"properties": {
"property1": "kubeAppDeployment-after"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ def _get_stacks_what_if_test_file_path(file_name: str):
{Color.GREEN}+{Color.RESET} {Color.GREEN}/subscriptions/6d41d86d-eb6b-473a-b31d-bbd084e1814d/resourceGroups/503ace4c-9b1c-4059-a3e9-09553d24e9e1/providers/Microsoft.Test/testD/resourceD [2021-05-01]{Color.RESET}
{Color.PURPLE}~{Color.RESET} Management Status: {Color.PURPLE}"NotManaged"{Color.RESET} => {Color.PURPLE}"Managed"{Color.RESET}
{Color.PURPLE}~{Color.RESET} Deny Status: {Color.PURPLE}"None"{Color.RESET} => {Color.PURPLE}"DenyDelete"{Color.RESET}
{Color.GREEN}+{Color.RESET} location: {Color.GREEN}"westus"{Color.RESET}
{Color.GREEN}+{Color.RESET} properties: {Color.GREEN}{{{Color.RESET}
{Color.GREEN} "property1": "resourceD"{Color.RESET}
{Color.GREEN}}}{Color.RESET}

>> {Color.PURPLE}Potential Resource Changes (Learn more at https://aka.ms/whatIfPotentialChanges){Color.RESET}
{Color.CYAN}?{Color.RESET}{Color.PURPLE}~{Color.RESET} {Color.CYAN}[Potential] {Color.RESET}{Color.PURPLE}/subscriptions/6d41d86d-eb6b-473a-b31d-bbd084e1814d/resourceGroups/503ace4c-9b1c-4059-a3e9-09553d24e9e1/providers/Microsoft.Test/testC/resourceC [2021-05-01]{Color.RESET}
Expand Down Expand Up @@ -197,6 +201,9 @@ def _get_stacks_what_if_test_file_path(file_name: str):
{Color.RED}-{Color.RESET} {Color.RED}Contoso/example name="defResource"{Color.RESET}
{Color.PURPLE}~{Color.RESET} Management Status: {Color.PURPLE}"Managed"{Color.RESET} => {Color.PURPLE}"Unmanaged"{Color.RESET}
{Color.PURPLE}~{Color.RESET} Deny Status: {Color.PURPLE}"NotSupported"{Color.RESET} => {Color.PURPLE}"None"{Color.RESET}
{Color.RED}-{Color.RESET} properties: {Color.RED}{{{Color.RESET}
{Color.RED} "property1": "resourceDef-before"{Color.RESET}
{Color.RED}}}{Color.RESET}

>> {Color.PURPLE}Potential Resource Changes (Learn more at https://aka.ms/whatIfPotentialChanges){Color.RESET}
{Color.CYAN}?{Color.RESET}! {Color.CYAN}[Potential] {Color.RESET}Contoso/noPreview
Expand All @@ -207,7 +214,9 @@ def _get_stacks_what_if_test_file_path(file_name: str):
{Color.GREEN}+{Color.RESET} {Color.GREEN}app/Deployment name="kubeAppDeployment" [v1]{Color.RESET}
{Color.PURPLE}~{Color.RESET} Management Status: {Color.PURPLE}null{Color.RESET} => {Color.PURPLE}"Managed"{Color.RESET}
{Color.PURPLE}~{Color.RESET} Deny Status: {Color.PURPLE}null{Color.RESET} => {Color.PURPLE}"NotApplicable"{Color.RESET}
{Color.PURPLE}~{Color.RESET} properties.property1: {Color.PURPLE}"kubeAppDeployment-before"{Color.RESET} => {Color.PURPLE}"kubeAppDeployment-after"{Color.RESET}
{Color.GREEN}+{Color.RESET} properties: {Color.GREEN}{{{Color.RESET}
{Color.GREEN} "property1": "kubeAppDeployment-after"{Color.RESET}
{Color.GREEN}}}{Color.RESET}

{Color.RED}Deleting - {Color.RESET}Resources Marked for Deletion 2 total:

Expand Down Expand Up @@ -293,6 +302,23 @@ def _get_stacks_what_if_test_file_path(file_name: str):
{Color.GREEN}+{Color.RESET} {Color.GREEN}/subscriptions/390ba170-3e2a-41c4-b372-15d9c5ae6e81/resourceGroups/whatif-change-40011/providers/Microsoft.Storage/storageAccounts/wvcreatemjwo5pow6lmvm [2023-05-01]{Color.RESET}
{Color.PURPLE}~{Color.RESET} Management Status: {Color.PURPLE}"notManaged"{Color.RESET} => {Color.PURPLE}"managed"{Color.RESET}
= Deny Status: "none"
{Color.GREEN}+{Color.RESET} kind: {Color.GREEN}"StorageV2"{Color.RESET}
{Color.GREEN}+{Color.RESET} location: {Color.GREEN}"westus2"{Color.RESET}
{Color.GREEN}+{Color.RESET} sku: {Color.GREEN}{{{Color.RESET}
{Color.GREEN} "name": "Standard_LRS"{Color.RESET}
{Color.GREEN}}}{Color.RESET}
{Color.GREEN}+{Color.RESET} tags: {Color.GREEN}{{{Color.RESET}
{Color.GREEN} "owner": "what-if-visual-validation",{Color.RESET}
{Color.GREEN} "scenario": "definite-create"{Color.RESET}
{Color.GREEN}}}{Color.RESET}
{Color.GREEN}+{Color.RESET} properties: {Color.GREEN}{{{Color.RESET}
{Color.GREEN} "allowBlobPublicAccess": false,{Color.RESET}
{Color.GREEN} "allowSharedKeyAccess": false,{Color.RESET}
{Color.GREEN} "defaultToOAuthAuthentication": true,{Color.RESET}
{Color.GREEN} "minimumTlsVersion": "TLS1_2",{Color.RESET}
{Color.GREEN} "publicNetworkAccess": "Disabled",{Color.RESET}
{Color.GREEN} "supportsHttpsTrafficOnly": true{Color.RESET}
{Color.GREEN}}}{Color.RESET}
{Color.PURPLE}~{Color.RESET} {Color.PURPLE}/subscriptions/390ba170-3e2a-41c4-b372-15d9c5ae6e81/resourceGroups/whatif-change-40011/providers/Microsoft.Storage/storageAccounts/wvmodmjwo5pow6lmvm [2023-05-01]{Color.RESET}
= Management Status: "managed"
= Deny Status: "none"
Expand All @@ -309,14 +335,38 @@ def _get_stacks_what_if_test_file_path(file_name: str):
{Color.GREEN}+{Color.RESET} {Color.GREEN}/subscriptions/390ba170-3e2a-41c4-b372-15d9c5ae6e81/resourceGroups/whatif-change-40011/providers/RP.Namespace/widgets/bar [1999-12-31]{Color.RESET}
{Color.PURPLE}~{Color.RESET} Management Status: {Color.PURPLE}"notManaged"{Color.RESET} => {Color.PURPLE}"managed"{Color.RESET}
= Deny Status: "none"
{Color.GREEN}+{Color.RESET} properties: {Color.GREEN}{{{Color.RESET}
{Color.GREEN} "source": "duplicate-diagnostic.bicep"{Color.RESET}
{Color.GREEN}}}{Color.RESET}
{Color.GREEN}+{Color.RESET} {Color.GREEN}/subscriptions/390ba170-3e2a-41c4-b372-15d9c5ae6e81/resourceGroups/whatif-change-40011/providers/RP.Namespace/widgets/foo [1999-12-31]{Color.RESET}
{Color.PURPLE}~{Color.RESET} Management Status: {Color.PURPLE}"notManaged"{Color.RESET} => {Color.PURPLE}"managed"{Color.RESET}
= Deny Status: "none"
{Color.GREEN}+{Color.RESET} properties: {Color.GREEN}{{{Color.RESET}
{Color.GREEN} "source": "duplicate-diagnostic.bicep"{Color.RESET}
{Color.GREEN}}}{Color.RESET}

>> {Color.PURPLE}Potential Resource Changes (Learn more at https://aka.ms/whatIfPotentialChanges){Color.RESET}
{Color.CYAN}?{Color.RESET}{Color.GREEN}+{Color.RESET} {Color.CYAN}[Potential] {Color.RESET}{Color.GREEN}/subscriptions/390ba170-3e2a-41c4-b372-15d9c5ae6e81/resourceGroups/whatif-change-40011/providers/Microsoft.Storage/storageAccounts/wvpotcreatemjwo5pow6lmvm [2023-05-01]{Color.RESET}
{Color.PURPLE}~{Color.RESET} Management Status: {Color.PURPLE}"notManaged"{Color.RESET} => {Color.PURPLE}"managed"{Color.RESET}
= Deny Status: "none"
{Color.GREEN}+{Color.RESET} condition: {Color.GREEN}"[greater(int(utcNow('%f')), 4)]"{Color.RESET}
{Color.GREEN}+{Color.RESET} kind: {Color.GREEN}"StorageV2"{Color.RESET}
{Color.GREEN}+{Color.RESET} location: {Color.GREEN}"westus2"{Color.RESET}
{Color.GREEN}+{Color.RESET} sku: {Color.GREEN}{{{Color.RESET}
{Color.GREEN} "name": "Standard_LRS"{Color.RESET}
{Color.GREEN}}}{Color.RESET}
{Color.GREEN}+{Color.RESET} tags: {Color.GREEN}{{{Color.RESET}
{Color.GREEN} "owner": "what-if-visual-validation",{Color.RESET}
{Color.GREEN} "scenario": "potential-create"{Color.RESET}
{Color.GREEN}}}{Color.RESET}
{Color.GREEN}+{Color.RESET} properties: {Color.GREEN}{{{Color.RESET}
{Color.GREEN} "allowBlobPublicAccess": false,{Color.RESET}
{Color.GREEN} "allowSharedKeyAccess": false,{Color.RESET}
{Color.GREEN} "defaultToOAuthAuthentication": true,{Color.RESET}
{Color.GREEN} "minimumTlsVersion": "TLS1_2",{Color.RESET}
{Color.GREEN} "publicNetworkAccess": "Disabled",{Color.RESET}
{Color.GREEN} "supportsHttpsTrafficOnly": true{Color.RESET}
{Color.GREEN}}}{Color.RESET}
{Color.CYAN}?{Color.RESET}{Color.PURPLE}~{Color.RESET} {Color.CYAN}[Potential] {Color.RESET}{Color.PURPLE}/subscriptions/390ba170-3e2a-41c4-b372-15d9c5ae6e81/resourceGroups/whatif-change-40011/providers/Microsoft.Storage/storageAccounts/wvpotremovemjwo5pow6lmvm [2023-05-01]{Color.RESET}
= Management Status: "managed"
= Deny Status: "none"
Expand Down
Loading