From df5ae60cfcfb4b373fcd137b4585cf0850ec4af7 Mon Sep 17 00:00:00 2001 From: Sakthi-Maheswari Date: Wed, 16 Mar 2022 18:55:51 +0530 Subject: [PATCH 1/2] initial commit --- .vscode/launch.json | 2 +- .../cli/command_modules/network/_params.py | 4 + .../command_modules/network/_validators.py | 60 +++++++++++ .../cli/command_modules/network/commands.py | 2 +- .../cli/command_modules/network/custom.py | 102 ++++++++++++++++-- 5 files changed, 159 insertions(+), 11 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index c2a47d74891..6d0ed521ee0 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -54,4 +54,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/src/azure-cli/azure/cli/command_modules/network/_params.py b/src/azure-cli/azure/cli/command_modules/network/_params.py index 989a9dbb0e7..4edc8ec8f3a 100644 --- a/src/azure-cli/azure/cli/command_modules/network/_params.py +++ b/src/azure-cli/azure/cli/command_modules/network/_params.py @@ -1694,6 +1694,10 @@ def load_arguments(self, _): c.argument('retention', type=int, help='Number of days to retain logs') c.argument('storage_account', help='Name or ID of the storage account in which to save the flow logs. ' 'Must be in the same region of flow log.') + + c.argument('virtual_network',options_list=['--vnet'],help='Name or ID of the Virtual Network Resource.') + c.argument('subnet',options_list=['--subnet'], help='Name or ID of Subnet') + c.argument('nic', options_list=['--nic'],help='Name or ID of the Network Interface (NIC) Resource.') # temporary solution for compatible with old show command's parameter # after old show command's parameter is deprecated and removed, diff --git a/src/azure-cli/azure/cli/command_modules/network/_validators.py b/src/azure-cli/azure/cli/command_modules/network/_validators.py index 5a58ebe905e..61c48d94894 100644 --- a/src/azure-cli/azure/cli/command_modules/network/_validators.py +++ b/src/azure-cli/azure/cli/command_modules/network/_validators.py @@ -1498,6 +1498,15 @@ def process_nw_flow_log_create_namespace(cmd, namespace): if namespace.traffic_analytics_workspace and not is_valid_resource_id(namespace.traffic_analytics_workspace): err_body = '--workspace ID / --workspace NAME --resource-group WORKSPACE_RESOURCE_GROUP' + if namespace.vnet and not is_valid_resource_id(namespace.vnet): + err_body = '--vnet ID / --vnet NAME --resource-group VNET_RESOURCE_GROUP' + + if namespace.subnet and not is_valid_resource_id(namespace.subnet): + err_body = '--subnet ID / --subnet NAME --resource-group SUBNET_RESOURCE_GROUP' + + if namespace.nic and not is_valid_resource_id(namespace.nic): + err_body = '--nic ID / --nic NAME --resource-group NIC_RESOURCE_GROUP' + if err_body is not None: raise CLIError(err_tpl.format(err_body)) @@ -1533,6 +1542,33 @@ def process_nw_flow_log_create_namespace(cmd, namespace): 'name': namespace.traffic_analytics_workspace } namespace.traffic_analytics_workspace = resource_id(**kwargs) + + if namespace.vnet and not is_valid_resource_id(namespace.vnet): + kwargs = { + 'subscription': get_subscription_id(cmd.cli_ctx), + 'resource_group': namespace.resource_group_name, + 'namespace': 'Microsoft.Network', + 'type': 'virtualNetworks', + 'name': namespace.vnet + } + + if namespace.subnet and not is_valid_resource_id(namespace.subnet): + kwargs = { + 'subscription': get_subscription_id(cmd.cli_ctx), + 'resource_group': namespace.resource_group_name, + 'namespace': 'Microsoft.Network', + 'type': 'virtualNetworks', + 'name': namespace.subnet + } + + if namespace.nic and not is_valid_resource_id(namespace.nic): + kwargs = { + 'subscription': get_subscription_id(cmd.cli_ctx), + 'resource_group': namespace.resource_group_name, + 'namespace': 'Microsoft.Network', + 'type': 'networkInterfaces', + 'name': namespace.nic + } get_network_watcher_from_location(remove=False)(cmd, namespace) @@ -1541,6 +1577,30 @@ def process_nw_flow_log_create_namespace(cmd, namespace): def process_nw_flow_log_set_namespace(cmd, namespace): from msrestazure.tools import is_valid_resource_id, resource_id + if namespace.vnet and not is_valid_resource_id(namespace.vnet): + namespace.vnet = resource_id( + subscription=get_subscription_id(cmd.cli_ctx), + resource_group=namespace.resource_group_name, + namespace='Microsoft.Network', + type='virtualNetworks', + name=namespace.vnet) + + if namespace.subnet and not is_valid_resource_id(namespace.subnet): + namespace.subnet = resource_id( + subscription=get_subscription_id(cmd.cli_ctx), + resource_group=namespace.resource_group_name, + namespace='Microsoft.Network', + type='virtualNetworks', + name=namespace.subnet) + + if namespace.nic and not is_valid_resource_id(namespace.nic): + namespace.nic = resource_id( + subscription=get_subscription_id(cmd.cli_ctx), + resource_group=namespace.resource_group_name, + namespace='Microsoft.Network', + type='networkInterfaces', + name=namespace.nic) + if namespace.storage_account and not is_valid_resource_id(namespace.storage_account): namespace.storage_account = resource_id( subscription=get_subscription_id(cmd.cli_ctx), diff --git a/src/azure-cli/azure/cli/command_modules/network/commands.py b/src/azure-cli/azure/cli/command_modules/network/commands.py index a2987165653..9ee0a5d39fc 100644 --- a/src/azure-cli/azure/cli/command_modules/network/commands.py +++ b/src/azure-cli/azure/cli/command_modules/network/commands.py @@ -1213,7 +1213,7 @@ def _make_singular(value): with self.command_group('network watcher flow-log', client_factory=cf_network_watcher, min_api='2016-09-01') as g: g.custom_command('configure', - 'set_nsg_flow_logging', + 'set_nw_flow_logging', validator=process_nw_flow_log_set_namespace, deprecate_info=self.deprecate(redirect='network watcher flow-log create', hide=False)) g.custom_show_command('show', 'show_nsg_flow_logging', validator=process_nw_flow_log_show_namespace) diff --git a/src/azure-cli/azure/cli/command_modules/network/custom.py b/src/azure-cli/azure/cli/command_modules/network/custom.py index 559d46ff82a..43935d93dea 100644 --- a/src/azure-cli/azure/cli/command_modules/network/custom.py +++ b/src/azure-cli/azure/cli/command_modules/network/custom.py @@ -3,6 +3,7 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- from collections import Counter, OrderedDict +import logging from msrestazure.tools import parse_resource_id, is_valid_resource_id, resource_id @@ -6038,16 +6039,51 @@ def create_nw_packet_capture(cmd, client, resource_group_name, capture_name, vm, return client.begin_create(watcher_rg, watcher_name, capture_name, capture_params) -def set_nsg_flow_logging(cmd, client, watcher_rg, watcher_name, nsg, storage_account=None, +def set_vnet_flow_logging(cmd, client, watcher_rg, watcher_name, vnet, resource_group_name=None): + vnet_id=_process_vnet_name_and_id(vnet,cmd,resource_group_name) + #logging.error("vnetid from setFL %s",vnet_id) + flowlog_status_parameters = cmd.get_models('FlowLogStatusParameters')(target_resource_id=vnet_id) + print("vnet",flowlog_status_parameters) + return flowlog_status_parameters + +def set_subnet_flow_logging(cmd, subnet, resource_group_name=None): + subnet_id=_process_subnet_name_and_id(subnet,cmd,resource_group_name) + flowlog_status_parameters = cmd.get_models('FlowLogStatusParameters')(target_resource_id=subnet_id) + print("subnet",flowlog_status_parameters) + return flowlog_status_parameters + +def set_nic_flow_logging(cmd, nic): + flowlog_status_parameters = cmd.get_models('FlowLogStatusParameters')(target_resource_id=nic) + print("nic",flowlog_status_parameters) + return flowlog_status_parameters + +def set_nsg_flow_logging(cmd, nsg): + flowlog_status_parameters = cmd.get_models('FlowLogStatusParameters')(target_resource_id=nsg) + logging.error("nsgId from setFL %s",nsg) + print(nsg,flowlog_status_parameters) + return flowlog_status_parameters + + +def set_nw_flow_logging(cmd, client, watcher_rg, watcher_name, nsg, vnet=None, subnet=None, nic=None, storage_account=None, resource_group_name=None, enabled=None, retention=0, log_format=None, log_version=None, traffic_analytics_workspace=None, traffic_analytics_interval=None, traffic_analytics_enabled=None): from azure.cli.core.commands import LongRunningOperation - flowlog_status_parameters = cmd.get_models('FlowLogStatusParameters')(target_resource_id=nsg) + flowlog_status_parameters = set_nsg_flow_logging(cmd, nsg) + + if vnet!=None: + flowlog_status_parameters = set_vnet_flow_logging(cmd,client,watcher_rg,watcher_name,vnet,resource_group_name) + elif subnet!=None: + flowlog_status_parameters = set_subnet_flow_logging(cmd,client,watcher_rg,watcher_name,subnet,resource_group_name) + elif nic!=None: + flowlog_status_parameters = set_nic_flow_logging(cmd,client,watcher_rg,watcher_name,nic,resource_group_name) + #print("FLPARAMS: after", flowlog_status_parameters) + logging.error("FLPARAMS after %s", flowlog_status_parameters) + print(client.begin_get_flow_log_status(watcher_rg,watcher_name,flowlog_status_parameters)) config = LongRunningOperation(cmd.cli_ctx)(client.begin_get_flow_log_status(watcher_rg, watcher_name, flowlog_status_parameters)) - + print("setNSG config:",config) try: if not config.flow_analytics_configuration.network_watcher_flow_analytics_configuration.workspace_id: config.flow_analytics_configuration = None @@ -6122,6 +6158,46 @@ def show_nsg_flow_logging(cmd, client, watcher_rg, watcher_name, location=None, client = cf_flow_logs(cmd.cli_ctx, None) return client.get(watcher_rg, watcher_name, flow_log_name) +def create_vnet_flow_log(cmd, location, vnet, storage_account, resource_group_name, enabled, tags): + vnet_id=_process_vnet_name_and_id(vnet,cmd,resource_group_name) + FlowLog = cmd.get_models('FlowLog') + flow_log = FlowLog(location=location, + target_resource_id=vnet_id, + storage_id=storage_account, + enabled=enabled, + tags=tags) + print("vnet createFL", flow_log) + return flow_log + +def create_subnet_flow_log(cmd, location, subnet, storage_account, enabled, tags): + FlowLog = cmd.get_models('FlowLog') + flow_log = FlowLog(location=location, + target_resource_id=subnet, + storage_id=storage_account, + enabled=enabled, + tags=tags) + print("subnet createFL",flow_log) + return flow_log + +def create_nic_flow_log(cmd, location, nic, storage_account, enabled, tags): + FlowLog = cmd.get_models('FlowLog') + flow_log = FlowLog(location=location, + target_resource_id=nic, + storage_id=storage_account, + enabled=enabled, + tags=tags) + print("nic create FL",flow_log) + return flow_log + +def create_nsg_flow_log(cmd, location, nsg, storage_account, enabled, tags): + FlowLog = cmd.get_models('FlowLog') + flow_log = FlowLog(location=location, + target_resource_id=nsg, + storage_id=storage_account, + enabled=enabled, + tags=tags) + print("nsg createFL",flow_log) + return flow_log def create_nw_flow_log(cmd, client, @@ -6130,6 +6206,9 @@ def create_nw_flow_log(cmd, watcher_name, flow_log_name, nsg, + vnet=None, + subnet=None, + nic=None, storage_account=None, resource_group_name=None, enabled=None, @@ -6140,12 +6219,14 @@ def create_nw_flow_log(cmd, traffic_analytics_interval=60, traffic_analytics_enabled=None, tags=None): - FlowLog = cmd.get_models('FlowLog') - flow_log = FlowLog(location=location, - target_resource_id=nsg, - storage_id=storage_account, - enabled=enabled, - tags=tags) + flow_log = create_nsg_flow_log(cmd, location, nsg, storage_account, enabled, tags) + + if vnet != None: + flow_log = create_vnet_flow_log(cmd, location, vnet, storage_account, resource_group_name, enabled, tags) + elif subnet != None: + flow_log = create_vnet_flow_log(cmd,client,watcher_rg,watcher_name,vnet,resource_group_name) + elif nic != None: + flow_log = create_vnet_flow_log(cmd,client,watcher_rg,watcher_name,vnet,resource_group_name) if retention > 0: RetentionPolicyParameters = cmd.get_models('RetentionPolicyParameters') @@ -6196,6 +6277,9 @@ def update_nw_flow_log(cmd, resource_group_name=None, # dummy parameter to let it appear in command enabled=None, nsg=None, + vnet=None, + subnet=None, + nic=None, storage_account=None, retention=0, log_format=None, From 2242bf72bdde8ebc91dbe50b34137d828cd81c40 Mon Sep 17 00:00:00 2001 From: Sakthi-Maheswari Date: Tue, 22 Mar 2022 02:23:42 +0530 Subject: [PATCH 2/2] Adding support for flow logging feature on VNET, SUBNET and NIC level --- loa1.pdf | Bin 0 -> 73 bytes .../cli/command_modules/network/_help.py | 8 ++++- .../cli/command_modules/network/_params.py | 2 +- .../cli/command_modules/network/custom.py | 33 +++++++----------- .../network/tests/latest/test_nw_flow_log.py | 12 +++++++ 5 files changed, 33 insertions(+), 22 deletions(-) create mode 100644 loa1.pdf diff --git a/loa1.pdf b/loa1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..4e5df79d8982429672d64ff342c283b0aa08aa5f GIT binary patch literal 73 zcmWGaELTXXEJ-a^$WK#9R0wc!Q%KIwD@n~OQ7B3+$Vp62O##X)xK diff --git a/src/azure-cli/azure/cli/command_modules/network/_params.py b/src/azure-cli/azure/cli/command_modules/network/_params.py index 4edc8ec8f3a..972395510ee 100644 --- a/src/azure-cli/azure/cli/command_modules/network/_params.py +++ b/src/azure-cli/azure/cli/command_modules/network/_params.py @@ -1695,7 +1695,7 @@ def load_arguments(self, _): c.argument('storage_account', help='Name or ID of the storage account in which to save the flow logs. ' 'Must be in the same region of flow log.') - c.argument('virtual_network',options_list=['--vnet'],help='Name or ID of the Virtual Network Resource.') + c.argument('vnet',options_list=['--vnet'],help='Name or ID of the Virtual Network Resource.') c.argument('subnet',options_list=['--subnet'], help='Name or ID of Subnet') c.argument('nic', options_list=['--nic'],help='Name or ID of the Network Interface (NIC) Resource.') diff --git a/src/azure-cli/azure/cli/command_modules/network/custom.py b/src/azure-cli/azure/cli/command_modules/network/custom.py index 43935d93dea..3d1a2f928cc 100644 --- a/src/azure-cli/azure/cli/command_modules/network/custom.py +++ b/src/azure-cli/azure/cli/command_modules/network/custom.py @@ -3,7 +3,7 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- from collections import Counter, OrderedDict -import logging + from msrestazure.tools import parse_resource_id, is_valid_resource_id, resource_id @@ -6040,27 +6040,21 @@ def create_nw_packet_capture(cmd, client, resource_group_name, capture_name, vm, def set_vnet_flow_logging(cmd, client, watcher_rg, watcher_name, vnet, resource_group_name=None): - vnet_id=_process_vnet_name_and_id(vnet,cmd,resource_group_name) - #logging.error("vnetid from setFL %s",vnet_id) + vnet_id = _process_vnet_name_and_id(vnet,cmd,resource_group_name) flowlog_status_parameters = cmd.get_models('FlowLogStatusParameters')(target_resource_id=vnet_id) - print("vnet",flowlog_status_parameters) return flowlog_status_parameters def set_subnet_flow_logging(cmd, subnet, resource_group_name=None): - subnet_id=_process_subnet_name_and_id(subnet,cmd,resource_group_name) + subnet_id = _process_subnet_name_and_id(subnet,cmd,resource_group_name) flowlog_status_parameters = cmd.get_models('FlowLogStatusParameters')(target_resource_id=subnet_id) - print("subnet",flowlog_status_parameters) return flowlog_status_parameters def set_nic_flow_logging(cmd, nic): flowlog_status_parameters = cmd.get_models('FlowLogStatusParameters')(target_resource_id=nic) - print("nic",flowlog_status_parameters) return flowlog_status_parameters def set_nsg_flow_logging(cmd, nsg): flowlog_status_parameters = cmd.get_models('FlowLogStatusParameters')(target_resource_id=nsg) - logging.error("nsgId from setFL %s",nsg) - print(nsg,flowlog_status_parameters) return flowlog_status_parameters @@ -6077,13 +6071,9 @@ def set_nw_flow_logging(cmd, client, watcher_rg, watcher_name, nsg, vnet=None, s flowlog_status_parameters = set_subnet_flow_logging(cmd,client,watcher_rg,watcher_name,subnet,resource_group_name) elif nic!=None: flowlog_status_parameters = set_nic_flow_logging(cmd,client,watcher_rg,watcher_name,nic,resource_group_name) - #print("FLPARAMS: after", flowlog_status_parameters) - logging.error("FLPARAMS after %s", flowlog_status_parameters) - print(client.begin_get_flow_log_status(watcher_rg,watcher_name,flowlog_status_parameters)) config = LongRunningOperation(cmd.cli_ctx)(client.begin_get_flow_log_status(watcher_rg, watcher_name, flowlog_status_parameters)) - print("setNSG config:",config) try: if not config.flow_analytics_configuration.network_watcher_flow_analytics_configuration.workspace_id: config.flow_analytics_configuration = None @@ -6166,7 +6156,6 @@ def create_vnet_flow_log(cmd, location, vnet, storage_account, resource_group_na storage_id=storage_account, enabled=enabled, tags=tags) - print("vnet createFL", flow_log) return flow_log def create_subnet_flow_log(cmd, location, subnet, storage_account, enabled, tags): @@ -6176,7 +6165,6 @@ def create_subnet_flow_log(cmd, location, subnet, storage_account, enabled, tags storage_id=storage_account, enabled=enabled, tags=tags) - print("subnet createFL",flow_log) return flow_log def create_nic_flow_log(cmd, location, nic, storage_account, enabled, tags): @@ -6186,7 +6174,6 @@ def create_nic_flow_log(cmd, location, nic, storage_account, enabled, tags): storage_id=storage_account, enabled=enabled, tags=tags) - print("nic create FL",flow_log) return flow_log def create_nsg_flow_log(cmd, location, nsg, storage_account, enabled, tags): @@ -6196,7 +6183,6 @@ def create_nsg_flow_log(cmd, location, nsg, storage_account, enabled, tags): storage_id=storage_account, enabled=enabled, tags=tags) - print("nsg createFL",flow_log) return flow_log def create_nw_flow_log(cmd, @@ -6224,9 +6210,9 @@ def create_nw_flow_log(cmd, if vnet != None: flow_log = create_vnet_flow_log(cmd, location, vnet, storage_account, resource_group_name, enabled, tags) elif subnet != None: - flow_log = create_vnet_flow_log(cmd,client,watcher_rg,watcher_name,vnet,resource_group_name) + flow_log = create_subnet_flow_log(cmd,client,watcher_rg,watcher_name,subnet,resource_group_name) elif nic != None: - flow_log = create_vnet_flow_log(cmd,client,watcher_rg,watcher_name,vnet,resource_group_name) + flow_log = create_nic_flow_log(cmd,client,watcher_rg,watcher_name,nic,resource_group_name) if retention > 0: RetentionPolicyParameters = cmd.get_models('RetentionPolicyParameters') @@ -6292,7 +6278,14 @@ def update_nw_flow_log(cmd, c.set_param('enabled', enabled) c.set_param('tags', tags) c.set_param('storage_id', storage_account) - c.set_param('target_resource_id', nsg) + if vnet!=None: + c.set_param('target_resource_id', vnet) + elif subnet!=None: + c.set_param('target_resource_id', subnet) + elif nic!=None: + c.set_param('target_resource_id', nic) + else: + c.set_param('target_resource_id', nsg) with cmd.update_context(instance.retention_policy) as c: c.set_param('days', retention) 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 e850468fdc7..0e037bfdb00 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 @@ -17,6 +17,9 @@ def test_nw_flow_log_create(self, resource_group, resource_group_location, stora 'location': resource_group_location, 'storage_account': storage_account, 'nsg': 'nsg1', + 'vnet': 'vnet1', + 'subnet': 'subnet1', + 'nic': 'nic1', 'watcher_rg': 'NetworkWatcherRG', 'watcher_name': 'NetworkWatcher_{}'.format(resource_group_location), 'flow_log': 'flow_log_test', @@ -42,6 +45,9 @@ def test_nw_flow_log_create(self, resource_group, resource_group_location, stora '--location {location} ' '--resource-group {rg} ' '--nsg {nsg} ' + '--vnet {vnet} ' + '--subnet {subnet} ' + '--nic {nic} ' '--storage-account {storage_account} ' '--workspace {workspace_id} ' '--name {flow_log} ') @@ -67,6 +73,9 @@ def test_nw_flow_log_delete(self, resource_group, resource_group_location, stora 'location': resource_group_location, 'storage_account': storage_account, 'nsg': 'nsg1', + 'vnet': 'vnet1', + 'subnet': 'subnet1', + 'nic': 'nic1', 'watcher_rg': 'NetworkWatcherRG', 'watcher_name': 'NetworkWatcher_{}'.format(resource_group_location), 'flow_log': 'flow_log_test2', @@ -185,6 +194,9 @@ def test_nw_flow_log_update(self, resource_group, resource_group_location, stora 'storage_account': storage_account, 'storage_account_2': 'storageaccount0395', 'nsg': 'nsg1', + 'vnet': 'vnet1', + 'subnet': 'subnet1', + 'nic': 'nic1', 'watcher_rg': 'NetworkWatcherRG', 'watcher_name': 'NetworkWatcher_{}'.format(resource_group_location), 'flow_log': 'flow_log_test2',