From a32280e17312cf998dc7a100e0adb9086430f0c0 Mon Sep 17 00:00:00 2001 From: Riddhi Nilawar Date: Tue, 2 Dec 2025 13:51:52 +0530 Subject: [PATCH 1/7] recordtype cli changes in 2025-03-01 --- .../network/watcher/flow_log/_create.py | 41 ++++++++++++++++--- .../network/watcher/flow_log/_delete.py | 6 +-- .../latest/network/watcher/flow_log/_show.py | 37 +++++++++++++++-- .../network/watcher/flow_log/_update.py | 21 ++++++++-- .../latest/network/watcher/flow_log/_wait.py | 35 +++++++++++++++- 5 files changed, 122 insertions(+), 18 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/watcher/flow_log/_create.py b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/watcher/flow_log/_create.py index 447b2d5f291..f094bdad574 100644 --- a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/watcher/flow_log/_create.py +++ b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/watcher/flow_log/_create.py @@ -43,12 +43,15 @@ class Create(AAZCommand): :example: Create or update flow log az network watcher flow-log create --location westus --resource-group MtRGContainingVNet --name MyVNetName-flowlog --vnet MyVNetName --storage-account MyStorageAccountName --filtering-criteria "dstip=20.252.145.59 || DstPort=443" + + :example: Create flow log with recordtypes filtering + az network watcher flow-log create --resource-group rg1 --network-watcher-name nw1 --name fl --location centraluseuap --target-resource-id /subscriptions/subid/resourceGroups/rg1/providers/Microsoft.Network/networkSecurityGroups/desmondcentral-nsg --storage-account /subscriptions/subid/resourceGroups/rg1/providers/Microsoft.Storage/storageAccounts/nwtest1mgvbfmqsigdxe --filtering-criteria srcIP=158.255.7.8 || dstPort=56891 --record-types B,E --enabled True --format JSON --log-version 1 --identity "{type:UserAssigned,user-assigned-identities:{/subscriptions/subid/resourceGroups/rg1/providers/Microsoft.ManagedIdentity/userAssignedIdentities/id1:{}}}" """ _aaz_info = { - "version": "2024-03-01", + "version": "2025-03-01", "resources": [ - ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2024-03-01"], + ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2025-03-01"], ] } @@ -130,17 +133,29 @@ def _build_arguments_schema(cls, *args, **kwargs): ) identity = cls._args_schema.identity - + identity.mi_system_assigned = AAZStrArg( + options=["system-assigned", "mi-system-assigned"], + help="Set the system managed identity.", + blank="True", + ) identity.type = AAZStrArg( options=["type"], help="The type of identity used for the resource. The type 'SystemAssigned, UserAssigned' includes both an implicitly created identity and a set of user assigned identities. The type 'None' will remove any identities from the virtual machine.", enum={"None": "None", "SystemAssigned": "SystemAssigned", "SystemAssigned, UserAssigned": "SystemAssigned, UserAssigned", "UserAssigned": "UserAssigned"}, ) + identity.mi_user_assigned = AAZListArg( + options=["user-assigned", "mi-user-assigned"], + help="Set the user managed identities.", + blank=[], + ) identity.user_assigned_identities = AAZDictArg( options=["user-assigned-identities"], help="The list of user identities associated with resource. The user identity dictionary key references will be ARM resource ids in the form: '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName}'.", ) + mi_user_assigned = cls._args_schema.identity.mi_user_assigned + mi_user_assigned.Element = AAZStrArg() + user_assigned_identities = cls._args_schema.identity.user_assigned_identities user_assigned_identities.Element = AAZObjectArg( blank={}, @@ -159,6 +174,11 @@ def _build_arguments_schema(cls, *args, **kwargs): arg_group="Properties", help="Parameters that define the configuration of traffic analytics.", ) + _args_schema.record_types = AAZStrArg( + options=["--record-types"], + arg_group="Properties", + help="Optional field to filter network traffic logs based on flow states. Value of this field could be any comma separated combination string of letters B,C,E or D. B represents Begin, when a flow is created. C represents Continue for an ongoing flow generated at every five-minute interval. E represents End, when a flow is terminated. D represents Deny, when a flow is denied. If not specified, all network traffic will be logged.", + ) _args_schema.retention_policy = AAZObjectArg( options=["--retention-policy"], arg_group="Properties", @@ -290,7 +310,7 @@ def url_parameters(self): def query_parameters(self): parameters = { **self.serialize_query_param( - "api-version", "2024-03-01", + "api-version", "2025-03-01", required=True, ), } @@ -315,7 +335,7 @@ def content(self): typ=AAZObjectType, typ_kwargs={"flags": {"required": True, "client_flatten": True}} ) - _builder.set_prop("identity", AAZObjectType, ".identity") + _builder.set_prop("identity", AAZIdentityObjectType, ".identity") _builder.set_prop("location", AAZStrType, ".location") _builder.set_prop("properties", AAZObjectType, typ_kwargs={"flags": {"client_flatten": True}}) _builder.set_prop("tags", AAZDictType, ".tags") @@ -324,11 +344,16 @@ def content(self): if identity is not None: identity.set_prop("type", AAZStrType, ".type") identity.set_prop("userAssignedIdentities", AAZDictType, ".user_assigned_identities") + identity.set_prop("userAssigned", AAZListType, ".mi_user_assigned", typ_kwargs={"flags": {"action": "create"}}) + identity.set_prop("systemAssigned", AAZStrType, ".mi_system_assigned", typ_kwargs={"flags": {"action": "create"}}) user_assigned_identities = _builder.get(".identity.userAssignedIdentities") if user_assigned_identities is not None: user_assigned_identities.set_elements(AAZObjectType, ".") + user_assigned = _builder.get(".identity.userAssigned") + if user_assigned is not None: + user_assigned.set_elements(AAZStrType, ".") properties = _builder.get(".properties") if properties is not None: @@ -336,6 +361,7 @@ def content(self): properties.set_prop("enabledFilteringCriteria", AAZStrType, ".filtering_criteria") properties.set_prop("flowAnalyticsConfiguration", AAZObjectType, ".flow_analytics_configuration") properties.set_prop("format", AAZObjectType) + properties.set_prop("recordTypes", AAZStrType, ".record_types") properties.set_prop("retentionPolicy", AAZObjectType, ".retention_policy") properties.set_prop("storageId", AAZStrType, ".storage_account", typ_kwargs={"flags": {"required": True}}) properties.set_prop("targetResourceId", AAZStrType, ".target_resource_id", typ_kwargs={"flags": {"required": True}}) @@ -390,7 +416,7 @@ def _build_schema_on_200_201(cls): flags={"read_only": True}, ) _schema_on_200_201.id = AAZStrType() - _schema_on_200_201.identity = AAZObjectType() + _schema_on_200_201.identity = AAZIdentityObjectType() _schema_on_200_201.location = AAZStrType() _schema_on_200_201.name = AAZStrType( flags={"read_only": True}, @@ -443,6 +469,9 @@ def _build_schema_on_200_201(cls): serialized_name="provisioningState", flags={"read_only": True}, ) + properties.record_types = AAZStrType( + serialized_name="recordTypes", + ) properties.retention_policy = AAZObjectType( serialized_name="retentionPolicy", ) diff --git a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/watcher/flow_log/_delete.py b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/watcher/flow_log/_delete.py index 925d80abc62..d0252af9918 100644 --- a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/watcher/flow_log/_delete.py +++ b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/watcher/flow_log/_delete.py @@ -22,9 +22,9 @@ class Delete(AAZCommand): """ _aaz_info = { - "version": "2024-03-01", + "version": "2025-03-01", "resources": [ - ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2024-03-01"], + ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2025-03-01"], ] } @@ -152,7 +152,7 @@ def url_parameters(self): def query_parameters(self): parameters = { **self.serialize_query_param( - "api-version", "2024-03-01", + "api-version", "2025-03-01", required=True, ), } diff --git a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/watcher/flow_log/_show.py b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/watcher/flow_log/_show.py index 1de612847db..a9ad98bea25 100644 --- a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/watcher/flow_log/_show.py +++ b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/watcher/flow_log/_show.py @@ -25,9 +25,9 @@ class Show(AAZCommand): """ _aaz_info = { - "version": "2024-03-01", + "version": "2025-03-01", "resources": [ - ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2024-03-01"], + ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2025-03-01"], ] } @@ -133,7 +133,7 @@ def url_parameters(self): def query_parameters(self): parameters = { **self.serialize_query_param( - "api-version", "2024-03-01", + "api-version", "2025-03-01", required=True, ), } @@ -170,6 +170,7 @@ def _build_schema_on_200(cls): flags={"read_only": True}, ) _schema_on_200.id = AAZStrType() + _schema_on_200.identity = AAZIdentityObjectType() _schema_on_200.location = AAZStrType() _schema_on_200.name = AAZStrType( flags={"read_only": True}, @@ -182,6 +183,33 @@ def _build_schema_on_200(cls): flags={"read_only": True}, ) + identity = cls._schema_on_200.identity + identity.principal_id = AAZStrType( + serialized_name="principalId", + flags={"read_only": True}, + ) + identity.tenant_id = AAZStrType( + serialized_name="tenantId", + flags={"read_only": True}, + ) + identity.type = AAZStrType() + identity.user_assigned_identities = AAZDictType( + serialized_name="userAssignedIdentities", + ) + + user_assigned_identities = cls._schema_on_200.identity.user_assigned_identities + user_assigned_identities.Element = AAZObjectType() + + _element = cls._schema_on_200.identity.user_assigned_identities.Element + _element.client_id = AAZStrType( + serialized_name="clientId", + flags={"read_only": True}, + ) + _element.principal_id = AAZStrType( + serialized_name="principalId", + flags={"read_only": True}, + ) + properties = cls._schema_on_200.properties properties.enabled = AAZBoolType() properties.enabled_filtering_criteria = AAZStrType( @@ -195,6 +223,9 @@ def _build_schema_on_200(cls): serialized_name="provisioningState", flags={"read_only": True}, ) + properties.record_types = AAZStrType( + serialized_name="recordTypes", + ) properties.retention_policy = AAZObjectType( serialized_name="retentionPolicy", ) diff --git a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/watcher/flow_log/_update.py b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/watcher/flow_log/_update.py index 23ede57b4a7..6e15cc21643 100644 --- a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/watcher/flow_log/_update.py +++ b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/watcher/flow_log/_update.py @@ -37,12 +37,15 @@ class Update(AAZCommand): :example: Update Workspace on another resource group az network watcher flow-log update --location westus --resource-group MyAnotherResourceGroup --name MyFlowLog --workspace MyAnotherLogAnalyticWorkspace + + :example: Update flowlog with recordtypes filtering + az network watcher flow-log update --resource-group rg1 --network-watcher-name nw1 --name fl --location centraluseuap --target-resource-id /subscriptions/subid/resourceGroups/rg1/providers/Microsoft.Network/networkSecurityGroups/desmondcentral-nsg --storage-account /subscriptions/subid/resourceGroups/rg1/providers/Microsoft.Storage/storageAccounts/nwtest1mgvbfmqsigdxe --filtering-criteria srcIP=158.255.7.8 || dstPort=56891 --record-types B,E --enabled True --format JSON --log-version 1 --identity "{type:UserAssigned,user-assigned-identities:{/subscriptions/subid/resourceGroups/rg1/providers/Microsoft.ManagedIdentity/userAssignedIdentities/id1:{}}}" """ _aaz_info = { - "version": "2024-03-01", + "version": "2025-03-01", "resources": [ - ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2024-03-01"], + ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2025-03-01"], ] } @@ -165,6 +168,12 @@ def _build_arguments_schema(cls, *args, **kwargs): help="Parameters that define the configuration of traffic analytics.", nullable=True, ) + _args_schema.record_types = AAZStrArg( + options=["--record-types"], + arg_group="Properties", + help="Optional field to filter network traffic logs based on flow states. Value of this field could be any comma separated combination string of letters B,C,E or D. B represents Begin, when a flow is created. C represents Continue for an ongoing flow generated at every five-minute interval. E represents End, when a flow is terminated. D represents Deny, when a flow is denied. If not specified, all network traffic will be logged.", + nullable=True, + ) _args_schema.retention_policy = AAZObjectArg( options=["--retention-policy"], arg_group="Properties", @@ -299,7 +308,7 @@ def url_parameters(self): def query_parameters(self): parameters = { **self.serialize_query_param( - "api-version", "2024-03-01", + "api-version", "2025-03-01", required=True, ), } @@ -402,7 +411,7 @@ def url_parameters(self): def query_parameters(self): parameters = { **self.serialize_query_param( - "api-version", "2024-03-01", + "api-version", "2025-03-01", required=True, ), } @@ -480,6 +489,7 @@ def _update_instance(self, instance): properties.set_prop("enabledFilteringCriteria", AAZStrType, ".filtering_criteria") properties.set_prop("flowAnalyticsConfiguration", AAZObjectType, ".flow_analytics_configuration") properties.set_prop("format", AAZObjectType) + properties.set_prop("recordTypes", AAZStrType, ".record_types") properties.set_prop("retentionPolicy", AAZObjectType, ".retention_policy") properties.set_prop("storageId", AAZStrType, ".storage_account", typ_kwargs={"flags": {"required": True}}) properties.set_prop("targetResourceId", AAZStrType, ".target_resource_id", typ_kwargs={"flags": {"required": True}}) @@ -599,6 +609,9 @@ def _build_schema_flow_log_read(cls, _schema): serialized_name="provisioningState", flags={"read_only": True}, ) + properties.record_types = AAZStrType( + serialized_name="recordTypes", + ) properties.retention_policy = AAZObjectType( serialized_name="retentionPolicy", ) diff --git a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/watcher/flow_log/_wait.py b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/watcher/flow_log/_wait.py index c6bf0b3c38e..5284e85cbc0 100644 --- a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/watcher/flow_log/_wait.py +++ b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/watcher/flow_log/_wait.py @@ -20,7 +20,7 @@ class Wait(AAZWaitCommand): _aaz_info = { "resources": [ - ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2024-03-01"], + ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2025-03-01"], ] } @@ -126,7 +126,7 @@ def url_parameters(self): def query_parameters(self): parameters = { **self.serialize_query_param( - "api-version", "2024-03-01", + "api-version", "2025-03-01", required=True, ), } @@ -163,6 +163,7 @@ def _build_schema_on_200(cls): flags={"read_only": True}, ) _schema_on_200.id = AAZStrType() + _schema_on_200.identity = AAZIdentityObjectType() _schema_on_200.location = AAZStrType() _schema_on_200.name = AAZStrType( flags={"read_only": True}, @@ -175,6 +176,33 @@ def _build_schema_on_200(cls): flags={"read_only": True}, ) + identity = cls._schema_on_200.identity + identity.principal_id = AAZStrType( + serialized_name="principalId", + flags={"read_only": True}, + ) + identity.tenant_id = AAZStrType( + serialized_name="tenantId", + flags={"read_only": True}, + ) + identity.type = AAZStrType() + identity.user_assigned_identities = AAZDictType( + serialized_name="userAssignedIdentities", + ) + + user_assigned_identities = cls._schema_on_200.identity.user_assigned_identities + user_assigned_identities.Element = AAZObjectType() + + _element = cls._schema_on_200.identity.user_assigned_identities.Element + _element.client_id = AAZStrType( + serialized_name="clientId", + flags={"read_only": True}, + ) + _element.principal_id = AAZStrType( + serialized_name="principalId", + flags={"read_only": True}, + ) + properties = cls._schema_on_200.properties properties.enabled = AAZBoolType() properties.enabled_filtering_criteria = AAZStrType( @@ -188,6 +216,9 @@ def _build_schema_on_200(cls): serialized_name="provisioningState", flags={"read_only": True}, ) + properties.record_types = AAZStrType( + serialized_name="recordTypes", + ) properties.retention_policy = AAZObjectType( serialized_name="retentionPolicy", ) From 8f2b7a1252689ac84bbff3c4d1870dfb9d188da6 Mon Sep 17 00:00:00 2001 From: Riddhi Nilawar Date: Tue, 2 Dec 2025 14:16:51 +0530 Subject: [PATCH 2/7] added UT --- .../network/tests/latest/test_nw_flow_log.py | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py b/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py index e1df3d3f2f4..5d2a821133c 100644 --- a/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py +++ b/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py @@ -163,6 +163,63 @@ def test_nw_flow_log_create_vnetfl_with_filtering(self, resource_group, resource self.check('retentionPolicy.enabled', False), ]) + @ResourceGroupPreparer(name_prefix='test_nw_flow_log_', location='centraluseuap') + @StorageAccountPreparer(name_prefix='testflowlog', location='centraluseuap', kind='StorageV2') + def test_nw_flow_log_create_vnetfl_with_filtering(self, resource_group, resource_group_location, storage_account): + self.kwargs.update({ + 'rg': resource_group, + 'location': resource_group_location, + 'storage_account': storage_account, + 'vnet': 'vnet1', + 'subnet': 'subnet1', + 'nic': 'nic1', + 'watcher_rg': 'NetworkWatcherRG', + 'watcher_name': 'NetworkWatcher_{}'.format(resource_group_location), + 'flow_log': 'flow_log_test', + 'record_types': 'B,E', + 'workspace': self.create_random_name('clitest', 20), + }) + + # enable network watcher + # self.cmd('network watcher configure -g {rg} --locations {location} --enabled') + + # prepare the target resource + self.cmd('network vnet create -g {rg} -n {vnet}') + self.cmd('network vnet subnet create -g {rg} --vnet-name {vnet} -n {subnet} --address-prefix 10.0.0.0/24') + self.cmd('network nic create -g {rg} -n {nic} --vnet-name {vnet} --subnet {subnet}') + + # prepare workspace + workspace = self.cmd('monitor log-analytics workspace create ' + '--resource-group {rg} ' + '--location eastus ' + '--workspace-name {workspace} ').get_output_in_json() + self.kwargs.update({ + 'workspace_id': workspace['id'] + }) + + #targetId as vnet + self.cmd('network watcher flow-log create ' + '--location {location} ' + '--resource-group {rg} ' + '--vnet {vnet} ' + '--storage-account {storage_account} ' + '--record-types {record_types} ' + '--workspace {workspace_id} ' + '--name {flow_log} ') + + self.cmd('network watcher flow-log list --location {location}') + + # This output is Azure Management Resource formatted. + self.cmd('network watcher flow-log show --location {location} --name {flow_log}', checks=[ + self.check('name', self.kwargs['flow_log']), + self.check('recordTypes', '.*/{record_types}$'), + self.check('flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.workspaceResourceId', + self.kwargs['workspace_id']), + self.check_pattern('targetResourceId', '.*/{vnet}$'), + self.check('retentionPolicy.days', 0), + self.check('retentionPolicy.enabled', False), + ]) + @ResourceGroupPreparer(name_prefix='test_nw_flow_log_', location='centraluseuap') @StorageAccountPreparer(name_prefix='testflowlog', location='centraluseuap', kind='StorageV2') def test_nw_flow_log_create_vnetflWithManagedIdentity(self, resource_group, resource_group_location, storage_account): From 0b36f18b392afa5ee1e1a5949b14e8be00c5812c Mon Sep 17 00:00:00 2001 From: riddhinilawar <62386378+riddhinilawar@users.noreply.github.com> Date: Tue, 2 Dec 2025 16:03:23 +0530 Subject: [PATCH 3/7] Update src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../command_modules/network/tests/latest/test_nw_flow_log.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py b/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py index 5d2a821133c..f579a85321b 100644 --- a/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py +++ b/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py @@ -165,7 +165,7 @@ def test_nw_flow_log_create_vnetfl_with_filtering(self, resource_group, resource @ResourceGroupPreparer(name_prefix='test_nw_flow_log_', location='centraluseuap') @StorageAccountPreparer(name_prefix='testflowlog', location='centraluseuap', kind='StorageV2') - def test_nw_flow_log_create_vnetfl_with_filtering(self, resource_group, resource_group_location, storage_account): + def test_nw_flow_log_create_vnetfl_with_record_types(self, resource_group, resource_group_location, storage_account): self.kwargs.update({ 'rg': resource_group, 'location': resource_group_location, From 0d5326034953976760dcd9d023422d98708ab853 Mon Sep 17 00:00:00 2001 From: riddhinilawar <62386378+riddhinilawar@users.noreply.github.com> Date: Tue, 2 Dec 2025 16:05:03 +0530 Subject: [PATCH 4/7] Update src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../command_modules/network/tests/latest/test_nw_flow_log.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py b/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py index f579a85321b..5b6b1de56ab 100644 --- a/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py +++ b/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py @@ -212,7 +212,7 @@ def test_nw_flow_log_create_vnetfl_with_record_types(self, resource_group, resou # This output is Azure Management Resource formatted. self.cmd('network watcher flow-log show --location {location} --name {flow_log}', checks=[ self.check('name', self.kwargs['flow_log']), - self.check('recordTypes', '.*/{record_types}$'), + self.check('recordTypes', '{record_types}'), self.check('flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.workspaceResourceId', self.kwargs['workspace_id']), self.check_pattern('targetResourceId', '.*/{vnet}$'), From f4e8be5f637936376c065218db478443db81736b Mon Sep 17 00:00:00 2001 From: riddhinilawar <62386378+riddhinilawar@users.noreply.github.com> Date: Wed, 3 Dec 2025 14:21:49 +0530 Subject: [PATCH 5/7] Update src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../command_modules/network/tests/latest/test_nw_flow_log.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py b/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py index 5b6b1de56ab..4eaa0edf0c2 100644 --- a/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py +++ b/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py @@ -197,7 +197,7 @@ def test_nw_flow_log_create_vnetfl_with_record_types(self, resource_group, resou 'workspace_id': workspace['id'] }) - #targetId as vnet + # targetId as vnet self.cmd('network watcher flow-log create ' '--location {location} ' '--resource-group {rg} ' From 72cb064c752e8ffad90b205f7c1ff107c0d2ba49 Mon Sep 17 00:00:00 2001 From: Riddhi Nilawar Date: Wed, 3 Dec 2025 14:39:43 +0530 Subject: [PATCH 6/7] Added more UTs --- .../network/tests/latest/test_nw_flow_log.py | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py b/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py index 4eaa0edf0c2..22541f262d1 100644 --- a/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py +++ b/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py @@ -220,6 +220,81 @@ def test_nw_flow_log_create_vnetfl_with_record_types(self, resource_group, resou self.check('retentionPolicy.enabled', False), ]) + +@ResourceGroupPreparer(name_prefix='test_nw_flow_log_', location='centraluseuap') +@StorageAccountPreparer(name_prefix='testflowlog', location='centraluseuap', kind='StorageV2') +def test_nw_flow_log_update_vnetfl_with_record_types(self, resource_group, resource_group_location, storage_account): + self.kwargs.update({ + 'rg': resource_group, + 'location': resource_group_location, + 'storage_account': storage_account, + 'vnet': 'vnet1', + 'subnet': 'subnet1', + 'nic': 'nic1', + 'watcher_rg': 'NetworkWatcherRG', + 'watcher_name': 'NetworkWatcher_{}'.format(resource_group_location), + 'flow_log': 'flow_log_test_update_rt', + 'workspace': self.create_random_name('clitest', 20), + 'record_types': 'B,E' + }) + + # Prepare target resources + self.cmd('network vnet create -g {rg} -n {vnet}') + self.cmd('network vnet subnet create -g {rg} --vnet-name {vnet} -n {subnet} --address-prefix 10.0.0.0/24') + self.cmd('network nic create -g {rg} -n {nic} --vnet-name {vnet} --subnet {subnet}') + + # Prepare workspace (use eastus for LA workspace) + workspace = self.cmd( + 'monitor log-analytics workspace create ' + '--resource-group {rg} ' + '--location eastus ' + '--workspace-name {workspace} ' + ).get_output_in_json() + self.kwargs.update({'workspace_id': workspace['id']}) + + # Create flow log for VNet (no record-types initially) + self.cmd( + 'network watcher flow-log create ' + '--location {location} ' + '--resource-group {rg} ' + '--vnet {vnet} ' + '--storage-account {storage_account} ' + '--workspace {workspace_id} ' + '--name {flow_log} ' + ) + + # Baseline verification + res1 = self.cmd( + 'network watcher flow-log show --location {location} --name {flow_log}' + ).get_output_in_json() + self.assertEqual(res1['name'], self.kwargs['flow_log']) + self.assertEqual(res1['enabled'], True) + self.assertTrue(res1['targetResourceId'].endswith(self.kwargs['vnet'])) + + # ---- Update: set record types to B,E on the same VNet target ---- + res2 = self.cmd( + 'network watcher flow-log update ' + '--location {location} ' + '--resource-group {rg} ' + '--vnet {vnet} ' + '--name {flow_log} ' + '--record-types {record_types} ' + ).get_output_in_json() + + self.assertEqual(res2['name'], self.kwargs['flow_log']) + self.assertEqual(res2['enabled'], True) + self.assertTrue(res2['targetResourceId'].endswith(self.kwargs['vnet'])) + self.assertEqual(res2['recordTypes'], self.kwargs['record_types']) + # Retention defaults remain unless explicitly changed + self.assertEqual(res2['retentionPolicy']['enabled'], False) + self.assertEqual(res2['retentionPolicy']['days'], 0) + + # Show again and validate persisted update + self.cmd('network watcher flow-log show --location {location} --name {flow_log}', checks=[ + self.check('name', self.kwargs['flow_log']), + self.check('recordTypes', '{record_types}') + ]) + @ResourceGroupPreparer(name_prefix='test_nw_flow_log_', location='centraluseuap') @StorageAccountPreparer(name_prefix='testflowlog', location='centraluseuap', kind='StorageV2') def test_nw_flow_log_create_vnetflWithManagedIdentity(self, resource_group, resource_group_location, storage_account): From 00712d059a99fe595cddfa55f0027d06ef6102bc Mon Sep 17 00:00:00 2001 From: Riddhi Nilawar Date: Fri, 5 Dec 2025 17:11:14 +0530 Subject: [PATCH 7/7] update test fixed --- .../network/tests/latest/test_nw_flow_log.py | 147 +++++++++--------- 1 file changed, 73 insertions(+), 74 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py b/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py index 22541f262d1..c36fa292c12 100644 --- a/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py +++ b/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_flow_log.py @@ -219,81 +219,80 @@ def test_nw_flow_log_create_vnetfl_with_record_types(self, resource_group, resou self.check('retentionPolicy.days', 0), self.check('retentionPolicy.enabled', False), ]) - -@ResourceGroupPreparer(name_prefix='test_nw_flow_log_', location='centraluseuap') -@StorageAccountPreparer(name_prefix='testflowlog', location='centraluseuap', kind='StorageV2') -def test_nw_flow_log_update_vnetfl_with_record_types(self, resource_group, resource_group_location, storage_account): - self.kwargs.update({ - 'rg': resource_group, - 'location': resource_group_location, - 'storage_account': storage_account, - 'vnet': 'vnet1', - 'subnet': 'subnet1', - 'nic': 'nic1', - 'watcher_rg': 'NetworkWatcherRG', - 'watcher_name': 'NetworkWatcher_{}'.format(resource_group_location), - 'flow_log': 'flow_log_test_update_rt', - 'workspace': self.create_random_name('clitest', 20), - 'record_types': 'B,E' - }) - - # Prepare target resources - self.cmd('network vnet create -g {rg} -n {vnet}') - self.cmd('network vnet subnet create -g {rg} --vnet-name {vnet} -n {subnet} --address-prefix 10.0.0.0/24') - self.cmd('network nic create -g {rg} -n {nic} --vnet-name {vnet} --subnet {subnet}') - - # Prepare workspace (use eastus for LA workspace) - workspace = self.cmd( - 'monitor log-analytics workspace create ' - '--resource-group {rg} ' - '--location eastus ' - '--workspace-name {workspace} ' - ).get_output_in_json() - self.kwargs.update({'workspace_id': workspace['id']}) - - # Create flow log for VNet (no record-types initially) - self.cmd( - 'network watcher flow-log create ' - '--location {location} ' - '--resource-group {rg} ' - '--vnet {vnet} ' - '--storage-account {storage_account} ' - '--workspace {workspace_id} ' - '--name {flow_log} ' - ) - - # Baseline verification - res1 = self.cmd( - 'network watcher flow-log show --location {location} --name {flow_log}' - ).get_output_in_json() - self.assertEqual(res1['name'], self.kwargs['flow_log']) - self.assertEqual(res1['enabled'], True) - self.assertTrue(res1['targetResourceId'].endswith(self.kwargs['vnet'])) - - # ---- Update: set record types to B,E on the same VNet target ---- - res2 = self.cmd( - 'network watcher flow-log update ' - '--location {location} ' - '--resource-group {rg} ' - '--vnet {vnet} ' - '--name {flow_log} ' - '--record-types {record_types} ' - ).get_output_in_json() - - self.assertEqual(res2['name'], self.kwargs['flow_log']) - self.assertEqual(res2['enabled'], True) - self.assertTrue(res2['targetResourceId'].endswith(self.kwargs['vnet'])) - self.assertEqual(res2['recordTypes'], self.kwargs['record_types']) - # Retention defaults remain unless explicitly changed - self.assertEqual(res2['retentionPolicy']['enabled'], False) - self.assertEqual(res2['retentionPolicy']['days'], 0) - - # Show again and validate persisted update - self.cmd('network watcher flow-log show --location {location} --name {flow_log}', checks=[ - self.check('name', self.kwargs['flow_log']), - self.check('recordTypes', '{record_types}') - ]) + @ResourceGroupPreparer(name_prefix='test_nw_flow_log_', location='centraluseuap') + @StorageAccountPreparer(name_prefix='testflowlog', location='centraluseuap', kind='StorageV2') + def test_nw_flow_log_update_vnetfl_with_record_types(self, resource_group, resource_group_location, storage_account): + self.kwargs.update({ + 'rg': resource_group, + 'location': resource_group_location, + 'storage_account': storage_account, + 'vnet': 'vnet1', + 'subnet': 'subnet1', + 'nic': 'nic1', + 'watcher_rg': 'NetworkWatcherRG', + 'watcher_name': 'NetworkWatcher_{}'.format(resource_group_location), + 'flow_log': 'flow_log_test_update_rt', + 'workspace': self.create_random_name('clitest', 20), + 'record_types': 'B,E' + }) + + # Prepare target resources + self.cmd('network vnet create -g {rg} -n {vnet}') + self.cmd('network vnet subnet create -g {rg} --vnet-name {vnet} -n {subnet} --address-prefix 10.0.0.0/24') + self.cmd('network nic create -g {rg} -n {nic} --vnet-name {vnet} --subnet {subnet}') + + # Prepare workspace (use eastus for LA workspace) + workspace = self.cmd( + 'monitor log-analytics workspace create ' + '--resource-group {rg} ' + '--location eastus ' + '--workspace-name {workspace} ' + ).get_output_in_json() + self.kwargs.update({'workspace_id': workspace['id']}) + + # Create flow log for VNet (no record-types initially) + self.cmd( + 'network watcher flow-log create ' + '--location {location} ' + '--resource-group {rg} ' + '--vnet {vnet} ' + '--storage-account {storage_account} ' + '--workspace {workspace_id} ' + '--name {flow_log} ' + ) + + # Baseline verification + res1 = self.cmd( + 'network watcher flow-log show --location {location} --name {flow_log}' + ).get_output_in_json() + self.assertEqual(res1['name'], self.kwargs['flow_log']) + self.assertEqual(res1['enabled'], True) + self.assertTrue(res1['targetResourceId'].endswith(self.kwargs['vnet'])) + + # ---- Update: set record types to B,E on the same VNet target ---- + res2 = self.cmd( + 'network watcher flow-log update ' + '--location {location} ' + '--resource-group {rg} ' + '--vnet {vnet} ' + '--name {flow_log} ' + '--record-types {record_types} ' + ).get_output_in_json() + + self.assertEqual(res2['name'], self.kwargs['flow_log']) + self.assertEqual(res2['enabled'], True) + self.assertTrue(res2['targetResourceId'].endswith(self.kwargs['vnet'])) + self.assertEqual(res2['recordTypes'], self.kwargs['record_types']) + # Retention defaults remain unless explicitly changed + self.assertEqual(res2['retentionPolicy']['enabled'], False) + self.assertEqual(res2['retentionPolicy']['days'], 0) + + # Show again and validate persisted update + self.cmd('network watcher flow-log show --location {location} --name {flow_log}', checks=[ + self.check('name', self.kwargs['flow_log']), + self.check('recordTypes', '{record_types}') + ]) @ResourceGroupPreparer(name_prefix='test_nw_flow_log_', location='centraluseuap') @StorageAccountPreparer(name_prefix='testflowlog', location='centraluseuap', kind='StorageV2')