Skip to content

Commit

Permalink
{cli} Changes for adding an optional field for Filtering to Azure Cli…
Browse files Browse the repository at this point in the history
… commands for flowlogs resource creation and updation (#30581)

* Changes in create and update

* changes in _list, _show and _wait

* Changes in _delete

* adding UT

---------

Co-authored-by: Mansi Verma <[email protected]>
  • Loading branch information
mansi-verma-1510 and Mansi Verma authored Dec 30, 2024
1 parent ff7d0fd commit 665a4fc
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,15 @@ class Create(AAZCommand):
:example: Create a flow log with Network Interface ID (could be in other resource group)
az network watcher flow-log create --location westus --name MyFlowLog --nic MyNetworkInterfaceID --storage-account account
: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"
"""

_aaz_info = {
"version": "2023-11-01",
"version": "2024-03-01",
"resources": [
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2023-11-01"],
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2024-03-01"],
]
}

Expand Down Expand Up @@ -127,6 +130,7 @@ def _build_arguments_schema(cls, *args, **kwargs):
)

identity = cls._args_schema.identity

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.",
Expand All @@ -145,6 +149,11 @@ def _build_arguments_schema(cls, *args, **kwargs):
# define Arg Group "Properties"

_args_schema = cls._args_schema
_args_schema.filtering_criteria = AAZStrArg(
options=["--filtering-criteria"],
arg_group="Properties",
help="Optional field to filter flowlogs based on SrcIP, SrcPort, DstIP, DstPort, Protocol, Encryption, Direction and Action. If not specified, all flowlogs will be logged.",
)
_args_schema.flow_analytics_configuration = AAZObjectArg(
options=["--flow-analytics-configuration"],
arg_group="Properties",
Expand Down Expand Up @@ -281,7 +290,7 @@ def url_parameters(self):
def query_parameters(self):
parameters = {
**self.serialize_query_param(
"api-version", "2023-11-01",
"api-version", "2024-03-01",
required=True,
),
}
Expand Down Expand Up @@ -320,9 +329,11 @@ def content(self):
if user_assigned_identities is not None:
user_assigned_identities.set_elements(AAZObjectType, ".")


properties = _builder.get(".properties")
if properties is not None:
properties.set_prop("enabled", AAZBoolType, ".enabled")
properties.set_prop("enabledFilteringCriteria", AAZStrType, ".filtering_criteria")
properties.set_prop("flowAnalyticsConfiguration", AAZObjectType, ".flow_analytics_configuration")
properties.set_prop("format", AAZObjectType)
properties.set_prop("retentionPolicy", AAZObjectType, ".retention_policy")
Expand Down Expand Up @@ -421,6 +432,9 @@ def _build_schema_on_200_201(cls):

properties = cls._schema_on_200_201.properties
properties.enabled = AAZBoolType()
properties.enabled_filtering_criteria = AAZStrType(
serialized_name="enabledFilteringCriteria",
)
properties.flow_analytics_configuration = AAZObjectType(
serialized_name="flowAnalyticsConfiguration",
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ class Delete(AAZCommand):
"""

_aaz_info = {
"version": "2022-01-01",
"version": "2024-03-01",
"resources": [
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2022-01-01"],
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2024-03-01"],
]
}

Expand Down Expand Up @@ -85,7 +85,7 @@ def __call__(self, *args, **kwargs):
return self.client.build_lro_polling(
self.ctx.args.no_wait,
session,
None,
self.on_200_201,
self.on_error,
lro_options={"final-state-via": "location"},
path_format_arguments=self.url_parameters,
Expand All @@ -99,6 +99,15 @@ def __call__(self, *args, **kwargs):
lro_options={"final-state-via": "location"},
path_format_arguments=self.url_parameters,
)
if session.http_response.status_code in [200, 201]:
return self.client.build_lro_polling(
self.ctx.args.no_wait,
session,
self.on_200_201,
self.on_error,
lro_options={"final-state-via": "location"},
path_format_arguments=self.url_parameters,
)

return self.on_error(session.http_response)

Expand Down Expand Up @@ -143,7 +152,7 @@ def url_parameters(self):
def query_parameters(self):
parameters = {
**self.serialize_query_param(
"api-version", "2022-01-01",
"api-version", "2024-03-01",
required=True,
),
}
Expand All @@ -152,6 +161,9 @@ def query_parameters(self):
def on_204(self, session):
pass

def on_200_201(self, session):
pass


class _DeleteHelper:
"""Helper class for Delete"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class List(AAZCommand):
]
}

AZ_SUPPORT_PAGINATION = True

def _handler(self, command_args):
super()._handler(command_args)
return self.build_paging(self._execute_operations, self._output)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ class Show(AAZCommand):
"""

_aaz_info = {
"version": "2022-01-01",
"version": "2024-03-01",
"resources": [
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2022-01-01"],
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2024-03-01"],
]
}

Expand Down Expand Up @@ -133,7 +133,7 @@ def url_parameters(self):
def query_parameters(self):
parameters = {
**self.serialize_query_param(
"api-version", "2022-01-01",
"api-version", "2024-03-01",
required=True,
),
}
Expand Down Expand Up @@ -184,6 +184,9 @@ def _build_schema_on_200(cls):

properties = cls._schema_on_200.properties
properties.enabled = AAZBoolType()
properties.enabled_filtering_criteria = AAZStrType(
serialized_name="enabledFilteringCriteria",
)
properties.flow_analytics_configuration = AAZObjectType(
serialized_name="flowAnalyticsConfiguration",
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ class Update(AAZCommand):
"""

_aaz_info = {
"version": "2023-11-01",
"version": "2024-03-01",
"resources": [
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2023-11-01"],
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2024-03-01"],
]
}

Expand Down Expand Up @@ -83,9 +83,6 @@ def _build_arguments_schema(cls, *args, **kwargs):
_args_schema.location = AAZResourceLocationArg(
help="Location to identify the exclusive Network Watcher under a region. Only one Network Watcher can be existed per subscription and region.",
nullable=True,
fmt=AAZResourceLocationArgFormat(
resource_group_arg="resource_group",
),
)
_args_schema.enabled = AAZBoolArg(
options=["--enabled"],
Expand Down Expand Up @@ -156,6 +153,12 @@ def _build_arguments_schema(cls, *args, **kwargs):
# define Arg Group "Properties"

_args_schema = cls._args_schema
_args_schema.filtering_criteria = AAZStrArg(
options=["--filtering-criteria"],
arg_group="Properties",
help="Update condition to filter flowlogs based on SrcIP, SrcPort, DstIP, DstPort, Protocol, Encryption, Direction and Action. If not specified, all flowlogs will be logged.",
nullable=True,
)
_args_schema.flow_analytics_configuration = AAZObjectArg(
options=["--flow-analytics-configuration"],
arg_group="Properties",
Expand Down Expand Up @@ -296,7 +299,7 @@ def url_parameters(self):
def query_parameters(self):
parameters = {
**self.serialize_query_param(
"api-version", "2023-11-01",
"api-version", "2024-03-01",
required=True,
),
}
Expand Down Expand Up @@ -399,7 +402,7 @@ def url_parameters(self):
def query_parameters(self):
parameters = {
**self.serialize_query_param(
"api-version", "2023-11-01",
"api-version", "2024-03-01",
required=True,
),
}
Expand Down Expand Up @@ -457,7 +460,7 @@ def _update_instance(self, instance):
value=instance,
typ=AAZObjectType
)
_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")
Expand All @@ -474,6 +477,7 @@ def _update_instance(self, instance):
properties = _builder.get(".properties")
if properties is not None:
properties.set_prop("enabled", AAZBoolType, ".enabled")
properties.set_prop("enabledFilteringCriteria", AAZStrType, ".filtering_criteria")
properties.set_prop("flowAnalyticsConfiguration", AAZObjectType, ".flow_analytics_configuration")
properties.set_prop("format", AAZObjectType)
properties.set_prop("retentionPolicy", AAZObjectType, ".retention_policy")
Expand Down Expand Up @@ -542,7 +546,7 @@ def _build_schema_flow_log_read(cls, _schema):
flags={"read_only": True},
)
flow_log_read.id = AAZStrType()
flow_log_read.identity = AAZObjectType()
flow_log_read.identity = AAZIdentityObjectType()
flow_log_read.location = AAZStrType()
flow_log_read.name = AAZStrType(
flags={"read_only": True},
Expand Down Expand Up @@ -584,6 +588,9 @@ def _build_schema_flow_log_read(cls, _schema):

properties = _schema_flow_log_read.properties
properties.enabled = AAZBoolType()
properties.enabled_filtering_criteria = AAZStrType(
serialized_name="enabledFilteringCriteria",
)
properties.flow_analytics_configuration = AAZObjectType(
serialized_name="flowAnalyticsConfiguration",
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class Wait(AAZWaitCommand):

_aaz_info = {
"resources": [
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2022-01-01"],
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2024-03-01"],
]
}

Expand Down Expand Up @@ -126,7 +126,7 @@ def url_parameters(self):
def query_parameters(self):
parameters = {
**self.serialize_query_param(
"api-version", "2022-01-01",
"api-version", "2024-03-01",
required=True,
),
}
Expand Down Expand Up @@ -177,6 +177,9 @@ def _build_schema_on_200(cls):

properties = cls._schema_on_200.properties
properties.enabled = AAZBoolType()
properties.enabled_filtering_criteria = AAZStrType(
serialized_name="enabledFilteringCriteria",
)
properties.flow_analytics_configuration = AAZObjectType(
serialized_name="flowAnalyticsConfiguration",
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,63 @@ def test_nw_flow_log_create_vnetfl(self, resource_group, resource_group_location
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',
'filtering_criteria': 'dstip=20.252.145.59 || DstPort=8080',
'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} '
'--filtering-criteria {filtering_criteria} '
'--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('enabledFilteringCriteria', '.*/{filtering_criteria}$'),
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):
Expand Down

0 comments on commit 665a4fc

Please sign in to comment.